Explorar o código

Modules updates.

AntonLV %!s(int64=7) %!d(string=hai) anos
pai
achega
4d33c241d6
Modificáronse 100 ficheiros con 12725 adicións e 0 borrados
  1. 95 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/classes/BxAccntConfig.php
  2. 396 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/classes/BxAccntGridAdministration.php
  3. 96 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/classes/BxAccntModule.php
  4. 72 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/install/config.php
  5. 78 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/install/langs/en.xml
  6. 80 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/install/sql/enable.sql
  7. 35 0
      modules/boonex/accounts/updates/9.0.10_10.0.0/source/template/images/icons/std-icon.svg
  8. 51 0
      modules/boonex/acl/updates/9.0.11_10.0.0/install/config.php
  9. 13 0
      modules/boonex/acl/updates/9.0.11_10.0.0/install/installer.php
  10. 70 0
      modules/boonex/acl/updates/9.0.11_10.0.0/source/install/config.php
  11. 11 0
      modules/boonex/acl/updates/9.0.11_10.0.0/source/template/images/icons/std-icon.svg
  12. 34 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsAlertsResponse.php
  13. 200 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsConfig.php
  14. 186 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsDb.php
  15. 31 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsMenuSnippetMeta.php
  16. 37 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsMenuView.php
  17. 161 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsMenuViewActionsMedia.php
  18. 842 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsModule.php
  19. 120 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsPageMedia.php
  20. 471 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsTemplate.php
  21. 38 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsUploaderCrop.php
  22. 38 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsUploaderHTML5.php
  23. 38 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsUploaderSimple.php
  24. 143 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/install/config.php
  25. 271 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/install/langs/en.xml
  26. 511 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/install/sql/enable.sql
  27. 503 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/install/sql/install.sql
  28. 64 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/install/sql/uninstall.sql
  29. 69 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/js/main.js
  30. 241 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/css/main.css
  31. 25 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/form_ghost_template.html
  32. 37 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/images/icons/std-icon.svg
  33. 20 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/media-edit.html
  34. 31 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/media-view.html
  35. 24 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/unit.html
  36. 15 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/unit_gallery.html
  37. 24 0
      modules/boonex/albums/updates/9.0.12_10.0.0/source/template/unit_media.html
  38. 469 0
      modules/boonex/analytics/updates/9.0.1_10.0.0/source/classes/BxAnalyticsModule.php
  39. 77 0
      modules/boonex/analytics/updates/9.0.1_10.0.0/source/install/config.php
  40. 39 0
      modules/boonex/analytics/updates/9.0.1_10.0.0/source/install/langs/en.xml
  41. 151 0
      modules/boonex/analytics/updates/9.0.1_10.0.0/source/js/analytics.js
  42. 67 0
      modules/boonex/analytics/updates/9.0.1_10.0.0/source/template/css/main.css
  43. 11 0
      modules/boonex/analytics/updates/9.0.1_10.0.0/source/template/images/icons/std-icon.svg
  44. 43 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamAlertsResponse.php
  45. 75 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamConfig.php
  46. 348 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamModule.php
  47. 86 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamProfanityFilter.php
  48. 68 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/install/config.php
  49. 170 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/install/langs/en.xml
  50. 227 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/install/sql/enable.sql
  51. 37 0
      modules/boonex/antispam/updates/9.0.6_10.0.0/source/template/images/icons/std-icon.svg
  52. 64 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlAlertsResponse.php
  53. 184 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlConfig.php
  54. 105 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlDb.php
  55. 40 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlFormEntry.php
  56. 29 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlFormsEntryHelper.php
  57. 25 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlMenuView.php
  58. 24 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlMenuViewActions.php
  59. 374 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlModule.php
  60. 122 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlTemplate.php
  61. 153 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/install/config.php
  62. 236 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/install/langs/en.xml
  63. 56 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/disable.sql
  64. 426 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/enable.sql
  65. 294 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/install.sql
  66. 59 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/uninstall.sql
  67. 1 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/template/breadcrumb.html
  68. 1 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/template/entry-childs.html
  69. 1 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/template/entry-parent.html
  70. 37 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/template/images/icons/std-icon.svg
  71. 1 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/template/menu_main_submenu.html
  72. 1 0
      modules/boonex/channels/updates/9.0.3_10.0.0/source/template/unit_wo_cover.html
  73. 51 0
      modules/boonex/charts/updates/9.0.2_10.0.0/install/config.php
  74. 13 0
      modules/boonex/charts/updates/9.0.2_10.0.0/install/installer.php
  75. 77 0
      modules/boonex/charts/updates/9.0.2_10.0.0/source/install/config.php
  76. 37 0
      modules/boonex/charts/updates/9.0.2_10.0.0/source/template/images/icons/std-icon.svg
  77. 51 0
      modules/boonex/contact/updates/9.0.9_10.0.0/install/config.php
  78. 13 0
      modules/boonex/contact/updates/9.0.9_10.0.0/install/installer.php
  79. 72 0
      modules/boonex/contact/updates/9.0.9_10.0.0/source/install/config.php
  80. 37 0
      modules/boonex/contact/updates/9.0.9_10.0.0/source/template/images/icons/std-icon.svg
  81. 108 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvConfig.php
  82. 150 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvDb.php
  83. 208 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvFormEntry.php
  84. 168 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvGrid.php
  85. 466 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvModule.php
  86. 104 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/install/config.php
  87. 139 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/install/langs/en.xml
  88. 40 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/disable.sql
  89. 205 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/enable.sql
  90. 200 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/install.sql
  91. 35 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/uninstall.sql
  92. 57 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/js/manage_tools.js
  93. 1 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/template/css/manage_tools.css
  94. 46 0
      modules/boonex/convos/updates/9.0.14_10.0.0/source/template/images/icons/std-icon.svg
  95. 128 0
      modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/studio/scripts/BxTemplStudioFormsField.php
  96. 19 0
      modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/studio/scripts/BxTemplStudioFormsLabels.php
  97. 42 0
      modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/_header_js_custom.html
  98. 45 0
      modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/_sub_footer.html
  99. 52 0
      modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/_sub_header.html
  100. 889 0
      modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/css/default.less

+ 95 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/classes/BxAccntConfig.php

@@ -0,0 +1,95 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Accounts Accounts
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAccntConfig extends BxBaseModGeneralConfig
+{
+    protected $_oDb;
+    protected $_aHtmlIds;
+
+    /**
+     * Constructor
+     */
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->CNF = array (
+        	// page URIs
+        	'URL_MANAGE_ADMINISTRATION' => 'page.php?i=accounts-administration',
+
+	        // objects
+	        'OBJECT_FORM_ACCOUNT' => 'bx_accounts_account',
+            'OBJECT_FORM_ACCOUNT_DISPLAY_SETTINGS_EMAIL' => 'bx_accounts_account_settings_email',
+	        'OBJECT_MENU_MANAGE_TOOLS' => 'bx_accounts_menu_manage_tools', //manage menu in content administration tools
+        	'OBJECT_GRID_ADMINISTRATION' => 'bx_accounts_administration',
+        	'OBJECT_GRID_MODERATION' => 'bx_accounts_moderation',
+
+        	// some language keys
+            'T' => array (
+        		'grid_action_err_delete' => '_bx_accnt_grid_action_err_delete',
+        		'grid_action_err_perform' => '_bx_accnt_grid_action_err_perform',
+            	'filter_item_active' => '_bx_accnt_grid_filter_item_title_adm_active',
+                'filter_item_operators' => '_bx_accnt_grid_filter_item_title_adm_operators',
+            	'filter_item_pending' => '_bx_accnt_grid_filter_item_title_adm_pending',
+            	'filter_item_suspended' => '_bx_accnt_grid_filter_item_title_adm_suspended',
+                'filter_item_unconfirmed' => '_bx_accnt_grid_filter_item_title_adm_unconfirmed',
+                'filter_item_locked' => '_bx_accnt_grid_filter_item_title_adm_locked',
+            	'filter_item_select_one_filter1' => '_bx_accnt_grid_filter_item_title_adm_select_one_filter1',
+                'filter_item_select_one_filter2' => '_bx_accnt_grid_filter_item_title_adm_select_one_filter2',
+        	)
+        );
+
+        $this->_aObjects = array(
+        	'alert' => $this->_sName,
+        );
+
+        $this->_aJsClasses = array(
+        	'main' => 'BxAccntMain',
+        	'manage_tools' => 'BxAccntManageTools'
+        );
+
+        $this->_aJsObjects = array(
+        	'main' => 'oBxAccntMain',
+        	'manage_tools' => 'oBxAccntManageTools'
+        );
+
+        $this->_aGridObjects = array(
+        	'moderation' => $this->CNF['OBJECT_GRID_MODERATION'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        	
+        );
+
+        $sHtmlPrefix = str_replace('_', '-', $this->_sName);
+        $this->_aHtmlIds = array(
+        	'profile' => $sHtmlPrefix . '-profile-',
+        	'profile_more_popup' => $sHtmlPrefix . '-profile-more-popup-',
+
+        	'password_text' => $sHtmlPrefix . '-txt-password',
+            'password_button' => $sHtmlPrefix . '-btn-copy',
+        	'password_popup' => $sHtmlPrefix . '-password-popup',
+        );
+    }
+
+    public function init(&$oDb)
+    {
+        $this->_oDb = &$oDb;
+    }
+
+	public function getHtmlIds($sKey = '')
+    {
+        if(empty($sKey))
+            return $this->_aHtmlIds;
+
+        return isset($this->_aHtmlIds[$sKey]) ? $this->_aHtmlIds[$sKey] : '';
+    }
+}
+
+/** @} */

+ 396 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/classes/BxAccntGridAdministration.php

@@ -0,0 +1,396 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Accounts Accounts
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
+{
+    protected $_sFilter2Name;
+	protected $_sFilter2Value;
+	protected $_aFilter2Values;
+    
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_accounts';
+        parent::__construct ($aOptions, $oTemplate);
+
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $this->_aFilter1Values = array_merge($this->_aFilter1Values, array(
+            'unconfirmed' => $CNF['T']['filter_item_unconfirmed'],
+            'locked' => $CNF['T']['filter_item_locked'],
+        ));
+
+        $this->_sFilter2Name = 'filter2';
+        $this->_aFilter2Values = array(
+            'operators' => $CNF['T']['filter_item_operators']
+        );
+
+        $sFilter2 = bx_get($this->_sFilter2Name);
+        if(!empty($sFilter2)) {
+            $this->_sFilter2Value = bx_process_input($sFilter2);
+            $this->_aQueryAppend[$this->_sFilter2Name] = $this->_sFilter2Value;
+        }
+    }
+
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        if(strpos($sFilter, $this->_sParamsDivider) !== false)
+            list($this->_sFilter1Value, $this->_sFilter2Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
+
+    	if(!empty($this->_sFilter1Value))
+            switch($this->_sFilter1Value) {
+                case 'unconfirmed':
+                    $sCnfnType = getParam('sys_account_confirmation_type');
+                    switch($sCnfnType) {
+                        case 'email':
+                            $this->_aOptions['source'] .= " AND `ta`.`email_confirmed`='0'";
+                            break;
+                        case 'phone':
+                            $this->_aOptions['source'] .= " AND `ta`.`phone_confirmed`='0'";
+                            break;
+                        case 'email_and_phone':
+                            $this->_aOptions['source'] .= " AND (`ta`.`email_confirmed`='0' OR `ta`.`phone_confirmed`='0')";
+                            break;
+                    }
+                    break;
+
+                case 'locked':
+                    $this->_aOptions['source'] .= " AND `ta`.`locked` = 1";
+                    break;
+
+                default:
+        	    $this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `tp`.`status`=?", $this->_sFilter1Value);
+            }
+
+        if(!empty($this->_sFilter2Value))
+        	$this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" AND `ta`.`role` & " . BX_DOL_ROLE_ADMIN ." = " . BX_DOL_ROLE_ADMIN);
+
+        return parent::_getDataSqlInner($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+    
+    protected function _getFilterControls()
+    {
+        parent::_getFilterControls();
+
+        return  $this->_getFilterSelectOne($this->_sFilter1Name, $this->_sFilter1Value, $this->_aFilter1Values) . $this->_getFilterSelectOne($this->_sFilter2Name, $this->_sFilter2Value, $this->_aFilter2Values) . $this->_getSearchInput();
+    }
+    
+    public function getCode($isDisplayHeader = true)
+    {
+        return $this->_oModule->_oTemplate->getJsCode('main', array(
+        	'aHtmlIds' => $this->_oModule->_oConfig->getHtmlIds()
+        )) . parent::getCode($isDisplayHeader);
+    }
+
+    public function performActionActivate()
+    {
+    	$this->_performActionEnable(true);
+    }
+
+	public function performActionSuspend()
+    {
+    	$this->_performActionEnable(false);
+    }
+
+    public function performActionEditEmail()
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            $iId = (int)bx_get('id');
+            if(!$iId)
+                return echoJson(array());
+
+            $aIds = array($iId);
+        }
+
+        $iId = $aIds[0];
+        $oAccount = BxDolAccount::getInstance($iId);
+        if(!$oAccount)
+            return echoJson(array());
+
+        $aAccount = $oAccount->getInfo();
+        $sAction = 'edit_email';
+
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ACCOUNT'], $CNF['OBJECT_FORM_ACCOUNT_DISPLAY_SETTINGS_EMAIL']);
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . 'grid.php?o=' . $this->_sObject . '&a=' . $sAction . '&id=' . $iId;
+        $oForm->initChecker($aAccount);
+
+        if($oForm->isSubmittedAndValid()) {
+            $sEmail = $oForm->getCleanValue('email');
+            if(strcmp($aAccount['email'], $sEmail) !== 0 && BxDolAccountQuery::getInstance()->getIdByEmail($sEmail))
+                return echoJson(array('msg' => _t('_sys_form_account_input_email_uniq_error_loggedin')));
+
+            if($oForm->update($aAccount['id'])) {
+                bx_alert('account', 'edited', $aAccount['id'], BxDolAccount::getInstance()->id(), array('display' => $CNF['OBJECT_FORM_ACCOUNT_DISPLAY_SETTINGS_EMAIL']));
+
+                $aRes = array('grid' => $this->getCode(false), 'blink' => $iId);
+            }
+            else
+                $aRes = array('msg' => _t('_sys_txt_error_account_update'));
+
+            echoJson($aRes);
+        }
+        else {
+            $sContent = BxTemplStudioFunctions::getInstance()->popupBox('bx-account-edit-email-popup', _t('_bx_accounts_form_display_account_settings_email_popup'), $this->_oModule->_oTemplate->parseHtmlByName('edit_email.html', array(
+                'form_id' => $oForm->id,
+                'form' => $oForm->getCode(true),
+                'object' => $this->_sObject,
+                'action' => $sAction
+            )));
+
+            echoJson(array('popup' => array('html' => $sContent, 'options' => array())));
+        }
+    }
+
+    public function performActionResendCemail()
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
+
+        $oAccount = BxDolAccount::getInstance();
+
+        $iAffected = 0;
+        $aIdsAffected = array();
+        foreach($aIds as $iId)
+			if($oAccount->sendConfirmationEmail($iId)) {
+				$aIdsAffected[] = $iId;
+        		$iAffected++;
+			}
+
+		echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
+    }
+
+    public function performActionResetPassword()
+    {
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
+
+        $iId = $aIds[0];
+        $oAccount = BxDolAccount::getInstance($iId);
+        if(!$oAccount)
+            return echoJson(array());
+
+        $sPwd = genRndPwd();
+        $sSalt = genRndSalt();
+        $sPasswordHash = encryptUserPwd($sPwd, $sSalt);
+
+        $aRes = array();
+        if((int)BxDolAccountQuery::getInstance()->updatePassword($sPasswordHash, $sSalt, $iId) > 0) {
+            bx_alert('account', 'edited', $iId, BxDolAccount::getInstance()->id(), array('action' => 'reset_password'));
+
+            $sPopupId = $this->_oModule->_oConfig->getHtmlIds('password_popup');
+            $sPopupTitle = _t('_bx_accounts_form_display_account_settings_password_popup');
+            $sPopupContent = $this->_oModule->_oTemplate->parseHtmlByName('reset_password.html', array(
+                'js_object' => $this->_oModule->_oConfig->getJsObject('main'),
+                'html_id_text' => $this->_oModule->_oConfig->getHtmlIds('password_text'),
+                'html_id_button' => $this->_oModule->_oConfig->getHtmlIds('password_button'),
+                'password' => $sPwd,
+            ));
+
+            $aRes = array('popup' => BxTemplStudioFunctions::getInstance()->popupBox($sPopupId, $sPopupTitle, $sPopupContent));
+        }
+        else 
+            $aRes = array('msg' => _t('_bx_accnt_grid_action_err_perform'));
+
+        return echoJson($aRes);
+    }
+    
+    public function performActionUnlockAccount()
+    {
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
+		$oAccountQuery = BxDolAccountQuery::getInstance();
+		foreach($aIds as $iId){
+			$oAccount = BxDolAccount::getInstance($iId);
+			if(!$oAccount)
+				continue;
+			if ($oAccount->isLocked()){
+				$oAccountQuery->unlockAccount($iId);
+			}
+		}
+		$aRes = array('grid' => $this->getCode(false), 'blink' => $aIds);
+        return echoJson($aRes);
+    }
+
+	public function performActionMakeOperator()
+    {
+    	$this->_performActionChangeRole(3);
+    }
+
+	public function performActionUnmakeOperator()
+    {
+    	$this->_performActionChangeRole(1);
+    }
+
+	protected function _performActionChangeRole($iRole)
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
+
+        $iAffected = 0;
+        $aIdsAffected = array();
+        foreach($aIds as $iId)
+			if($this->_oModule->_oDb->updateAccount(array('role' => $iRole), array('id' => $iId))) {
+				$aIdsAffected[] = $iId;
+        		$iAffected++;
+			}
+
+		echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
+    }
+
+	protected function _performActionEnable($isChecked)
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
+
+        $iAffected = 0;
+        $aIdsAffected = array();
+        foreach($aIds as $iId)
+        	if($this->_enable($iId, $isChecked)) {
+        		$aIdsAffected[] = $iId;
+        		$iAffected++;
+        	}
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
+    }
+
+    protected function _enable($mixedId, $isChecked)
+    {
+    	$oProfile = BxDolProfile::getInstanceAccountProfile($mixedId);
+    	if(!$oProfile)
+    	    return false;
+
+        $iAction = BX_PROFILE_ACTION_MANUAL;
+        $sMethod = $isChecked ? 'activate' : 'suspend';
+        if(!$oProfile->$sMethod($iAction))
+            return false;
+
+        $aProfiles = $oProfile->getAccountObject()->getProfiles();
+        foreach($aProfiles as $aProfile)
+            BxDolProfile::getInstance($aProfile['id'])->$sMethod($iAction);
+
+    	return true;
+    }
+
+    //--- Layout methods ---//
+    protected function _getActionEditEmail($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+    
+    protected function _getCellEmailConfirmed($mixedValue, $sKey, $aField, $aRow)
+    {
+    	$mixedValue = (int)$mixedValue == 1 ? '_Yes' : '_No';
+        return parent::_getCellDefault(_t($mixedValue), $sKey, $aField, $aRow);
+    }
+
+    protected function _getActionResetPassword($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+    
+    protected function _getActionUnlockAccount($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+
+    protected function _getCellName($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oAccount = BxDolAccount::getInstance($aRow['id']);
+        if ($oAccount)
+            $s = ($aRow['locked'] == 1 ? $this->_oTemplate->parseIcon("lock col-red1") . ' ' : '') . $oAccount->getDisplayName();
+        return parent::_getCellDefault ($s, $sKey, $aField, $aRow);
+    }
+    
+	protected function _getCellProfiles($mixedValue, $sKey, $aField, $aRow)
+    {
+        $s = $this->_oModule->_oTemplate->getProfilesByAccount($aRow);
+
+        return parent::_getCellDefault ($s, $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellLogged($mixedValue, $sKey, $aField, $aRow)
+    {
+        $mixedValue = !empty($mixedValue) ? bx_time_js($mixedValue) : _t('_sys_not_available');
+
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }    
+    
+    protected function _getCellIsConfirmed($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oAccount = BxDolAccount::getInstance($aRow['id']);
+        $s = "";
+        if ($oAccount)
+            $s = $oAccount->getCurrentConfirmationStatusValue();
+        return parent::_getCellDefault(_t('_bx_accnt_grid_confirmation_status_' . $s), $sKey, $aField, $aRow);
+    }
+
+    protected function _isCheckboxDisabled($aRow)
+    {
+        return false;
+    }
+
+	protected function _getContentInfo($iId)
+    {
+    	return BxDolAccountQuery::getInstance()->getInfoById($iId);
+    }
+
+	protected function _doDelete($iId, $aParams = array())
+    {
+    	return BxDolAccount::getInstance($iId)->delete(isset($aParams['with_content']) && $aParams['with_content'] === true);
+    }
+
+    protected function _addJsCss()
+    {
+        parent::_addJsCss();
+        
+        $this->_oTemplate->addJs(array(
+            'main.css'
+        ));
+
+        $this->_oTemplate->addJs(array(
+        	'jquery.form.min.js',
+            'clipboard.min.js',
+            'main.js'
+        ));
+    }
+
+    protected function _isVisibleGrid($a)
+    {
+        if(isAdmin())
+            return true;
+        
+        return parent::_isVisibleGrid($a);
+    }
+}
+
+/** @} */

+ 96 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/classes/BxAccntModule.php

@@ -0,0 +1,96 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Accounts Accounts
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAccntModule extends BxBaseModGeneralModule
+{
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_oConfig->init($this->_oDb);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_accounts Accounts
+     * @subsection bx_accounts-other Other
+     * @subsubsection bx_accounts-get_menu_addon_manage_tools get_menu_addon_manage_tools
+     * 
+     * @code bx_srv('bx_accounts', 'get_menu_addon_manage_tools', [...]); @endcode
+     * 
+     * Get number of 'unconfirmed' accounts for User End -> Dasboard page -> Manage block.
+     *
+     * @return integer number of 'unconfirmed' accounts
+     * 
+     * @see BxAccntModule::serviceGetMenuAddonManageTools
+     */
+    /** 
+     * @ref bx_accounts-get_menu_addon_manage_tools "get_menu_addon_manage_tools"
+     */
+	public function serviceGetMenuAddonManageTools()
+	{
+		bx_import('SearchResult', $this->_aModule);
+        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';
+        $o = new $sClass();
+        $o->unsetPaginate();
+        $iNumTotal = $o->getNum();
+        
+        $o->fillFilters(array(
+			'unconfirmed' => 1
+        ));
+      
+        return array('counter1_value' => $o->getNum(),'counter3_value' => $iNumTotal, 'counter1_caption' => _t('_bx_accnt_menu_dashboard_manage_tools_addon_counter1_caption'));
+	}
+
+    public function checkAllowedDelete(&$aDataEntry, $isPerformAction = false)
+    {
+    	if(isAdmin() && (int)$aDataEntry['id'] == getLoggedId())
+    		return _t('_sys_txt_access_denied');
+
+        // check ACL
+        $aCheck = checkActionModule($this->_iProfileId, 'delete account', 'system', $isPerformAction);
+        if($aCheck[CHECK_ACTION_RESULT] != CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedMakeOperator(&$aDataEntry, $isPerformAction = false)
+    {
+    	$bAdmin = isAdmin();
+    	if(!$bAdmin || (int)$aDataEntry['id'] == getLoggedId() || (int)$aDataEntry['role'] == 3)
+    		return _t('_sys_txt_access_denied');
+
+    	return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+	public function checkAllowedUnmakeOperator(&$aDataEntry, $isPerformAction = false)
+    {
+    	$bAdmin = isAdmin();
+    	if(!$bAdmin || (int)$aDataEntry['id'] == getLoggedId() || (int)$aDataEntry['role'] != 3)
+    		return _t('_sys_txt_access_denied');
+
+    	return CHECK_ACTION_RESULT_ALLOWED;
+    }
+    
+    public function checkAllowedUnlockAccount(&$aDataEntry, $isPerformAction = false)
+    {
+    	if((int)$aDataEntry['locked'] != 1)
+    		return _t('_sys_txt_access_denied');
+
+    	return CHECK_ACTION_RESULT_ALLOWED;
+    }
+}
+
+/** @} */

+ 72 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/install/config.php

@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Accounts Accounts
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_accounts',
+    'title' => 'Accounts Manager',
+    'note' => 'Accounts Manager module.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+    
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/accounts/',
+    'home_uri' => 'accounts',
+
+    'db_prefix' => 'bx_accnt_',
+    'class_prefix' => 'BxAccnt',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Accounts',
+
+    /**
+     * 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(),
+
+);
+
+/** @} */

+ 78 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/install/langs/en.xml

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string name="_bx_accnt"><![CDATA[Accounts]]></string>
+    <string name="_bx_accounts"><![CDATA[Accounts]]></string>
+
+    <string name="_bx_accounts_form_display_account_settings_email_popup"><![CDATA[Edit Email]]></string>
+    <string name="_bx_accounts_form_display_account_settings_password_popup"><![CDATA[Reset Password]]></string>
+
+    <string name="_bx_accnt_page_title_sys_manage_administration"><![CDATA[Manage All Accounts]]></string>
+    <string name="_bx_accnt_page_title_manage"><![CDATA[Manage Accounts]]></string>
+    <string name="_bx_accnt_page_title_browse"><![CDATA[Accounts]]></string>
+
+    <string name="_bx_accnt_page_block_title_system_manage_administration"><![CDATA[Manage All Accounts]]></string>
+    <string name="_bx_accnt_page_block_title_manage"><![CDATA[Manage Accounts]]></string>
+
+    <string name="_bx_accnt_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_accnt_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_accnt_menu_item_title_system_resend_cemail"><![CDATA[Resend Confirmation]]></string>
+    <string name="_bx_accnt_menu_item_title_resend_cemail"><![CDATA[Resend Confirmation]]></string>
+    <string name="_bx_accnt_menu_item_title_system_edit_email"><![CDATA[Edit Email]]></string>
+    <string name="_bx_accnt_menu_item_title_edit_email"><![CDATA[Edit Email]]></string>
+    <string name="_bx_accnt_menu_item_title_system_reset_password"><![CDATA[Reset Password]]></string>
+    <string name="_bx_accnt_menu_item_title_reset_password"><![CDATA[Reset Password]]></string>
+    <string name="_bx_accnt_menu_item_title_system_unlock_account"><![CDATA[Unlock]]></string>
+    <string name="_bx_accnt_menu_item_title_unlock_account"><![CDATA[Unlock]]></string>
+    <string name="_bx_accnt_menu_item_title_system_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_accnt_menu_item_title_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_accnt_menu_item_title_system_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_accnt_menu_item_title_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_accnt_menu_item_title_system_make_operator"><![CDATA[Make Operator]]></string>
+    <string name="_bx_accnt_menu_item_title_make_operator"><![CDATA[Make Operator]]></string>
+    <string name="_bx_accnt_menu_item_title_system_unmake_operator"><![CDATA[Unmake Operator]]></string>
+    <string name="_bx_accnt_menu_item_title_unmake_operator"><![CDATA[Unmake Operator]]></string>
+    <string name="_bx_accnt_menu_item_title_system_admt_accounts"><![CDATA[Accounts]]></string>
+    <string name="_bx_accnt_menu_item_title_admt_accounts"><![CDATA[Accounts]]></string>
+    <string name="_bx_accnt_menu_item_title_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_accnt_menu_dashboard_manage_tools_addon_counter1_caption"><![CDATA[unconfirmed]]></string>
+
+    <string name="_bx_accnt_acl_action_edit_any_account"><![CDATA[Edit Any Account]]></string>
+
+    <string name="_bx_accnt_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+    <string name="_bx_accnt_grid_filter_item_title_adm_select_one_filter2"><![CDATA[All]]></string>
+    <string name="_bx_accnt_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_accnt_grid_filter_item_title_adm_operators"><![CDATA[Operators]]></string>
+    <string name="_bx_accnt_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
+    <string name="_bx_accnt_grid_filter_item_title_adm_suspended"><![CDATA[Suspended]]></string>    
+    <string name="_bx_accnt_grid_filter_item_title_adm_unconfirmed"><![CDATA[Unconfirmed]]></string>
+    <string name="_bx_accnt_grid_filter_item_title_adm_locked"><![CDATA[Locked]]></string>
+    <string name="_bx_accnt_grid_column_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_accnt_grid_column_title_adm_name"><![CDATA[Name]]></string>
+    <string name="_bx_accnt_grid_column_title_adm_email"><![CDATA[Email]]></string>
+    <string name="_bx_accnt_grid_column_title_adm_ip"><![CDATA[IP]]></string>
+
+    <string name="_bx_accnt_grid_column_title_adm_is_confirmed"><![CDATA[Confirmed]]></string>
+    <string name="_bx_accnt_grid_column_title_adm_profiles"><![CDATA[Profiles]]></string>
+    <string name="_bx_accnt_grid_column_title_adm_logged"><![CDATA[Last Logged]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_activate"><![CDATA[Activate]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_suspend"><![CDATA[Suspend]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_edit_email"><![CDATA[Edit Email]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_resend_cemail"><![CDATA[Resend Confirmation]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_reset_password"><![CDATA[Reset Password]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_unlock_account"><![CDATA[Unlock]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_delete_with_content"><![CDATA[Delete With Content]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_accnt_grid_action_err_delete"><![CDATA[Cannot delete the selected account(s).]]></string>
+    <string name="_bx_accnt_grid_action_err_perform"><![CDATA[Cannot perform the action for selected account(s).]]></string>
+    <string name="_bx_accnt_grid_action_unlock_successed"><![CDATA[Successfully unlocked]]></string>
+    <string name="_bx_accnt_grid_action_unlock_error"><![CDATA[Account is not blocked]]></string>
+    <string name="_bx_accnt_grid_confirmation_status_none"><![CDATA[No]]></string>
+    <string name="_bx_accnt_grid_confirmation_status_email"><![CDATA[Email]]></string>
+    <string name="_bx_accnt_grid_confirmation_status_phone"><![CDATA[Phone]]></string>
+    <string name="_bx_accnt_grid_confirmation_status_email_and_phone"><![CDATA[All]]></string>
+
+    <string name="_bx_accnt_txt_more"><![CDATA[{0} more]]></string>
+    <string name="_bx_accnt_txt_see_more"><![CDATA[See more]]></string>
+    <string name="_bx_accnt_txt_copy_to_clipboard"><![CDATA[Copy to Clipboard]]></string>
+</resources>

+ 80 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/install/sql/enable.sql

@@ -0,0 +1,80 @@
+SET @sName = 'bx_accounts';
+
+
+-- PAGE: module 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_accounts_administration', '_bx_accnt_page_title_sys_manage_administration', '_bx_accnt_page_title_manage', @sName, 5, 192, 1, 'accounts-administration', 'page.php?i=accounts-administration', '', '', '', 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_accounts_administration', 1, @sName, '_bx_accnt_page_block_title_system_manage_administration', '_bx_accnt_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_accounts\";s:6:\"method\";s:12:\"manage_tools\";s:6:\"params\";a:1:{i:0;s:14:\"administration\";}}', 0, 1, 0);
+
+
+-- 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_accounts_menu_manage_tools', '_bx_accnt_menu_title_manage_tools', 'bx_accounts_menu_manage_tools', @sName, 6, 0, 1, 'BxAccntMenuManageTools', 'modules/boonex/accounts/classes/BxAccntMenuManageTools.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_accounts_menu_manage_tools', @sName, '_bx_accnt_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_accounts_menu_manage_tools', @sName, 'edit-email', '_bx_accnt_menu_item_title_system_edit_email', '_bx_accnt_menu_item_title_edit_email', 'javascript:void(0)', 'javascript:{js_object}.onClickEditEmail({content_id}, this);', '_self', 'at', '', 192, 1, 0, 1),
+('bx_accounts_menu_manage_tools', @sName, 'resend-cemail', '_bx_accnt_menu_item_title_system_resend_cemail', '_bx_accnt_menu_item_title_resend_cemail', 'javascript:void(0)', 'javascript:{js_object}.onClickResendCemail({content_id}, this);', '_self', 'far envelope', '', 192, 1, 0, 2),
+('bx_accounts_menu_manage_tools', @sName, 'reset-password', '_bx_accnt_menu_item_title_system_reset_password', '_bx_accnt_menu_item_title_reset_password', 'javascript:void(0)', 'javascript:{js_object}.onClickResetPassword({content_id}, this);', '_self', 'eraser', '', 192, 1, 0, 3),
+('bx_accounts_menu_manage_tools', @sName, 'unlock-account', '_bx_accnt_menu_item_title_system_unlock_account', '_bx_accnt_menu_item_title_unlock_account', 'javascript:void(0)', 'javascript:{js_object}.onClickUnlockAccount({content_id}, this);', '_self', 'unlock', '', 192, 1, 0, 4),
+('bx_accounts_menu_manage_tools', @sName, 'delete', '_bx_accnt_menu_item_title_system_delete', '_bx_accnt_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id}, this);', '_self', 'far trash-alt', '', 192, 1, 0, 5),
+('bx_accounts_menu_manage_tools', @sName, 'delete-with-content', '_bx_accnt_menu_item_title_system_delete_with_content', '_bx_accnt_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id}, this);', '_self', 'far trash-alt', '', 192, 1, 0, 6),
+('bx_accounts_menu_manage_tools', @sName, 'make-operator', '_bx_accnt_menu_item_title_system_make_operator', '_bx_accnt_menu_item_title_make_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickMakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 7),
+('bx_accounts_menu_manage_tools', @sName, 'unmake-operator', '_bx_accnt_menu_item_title_system_unmake_operator', '_bx_accnt_menu_item_title_unmake_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickUnmakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 8);
+
+-- 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, 'accounts-administration', '_bx_accnt_menu_item_title_system_admt_accounts', '_bx_accnt_menu_item_title_admt_accounts', 'page.php?i=accounts-administration', '', '_self', 'at', 'a:2:{s:6:"module";s:11:"bx_accounts";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
+(@sName, 'edit any entry', NULL, '_bx_accnt_acl_action_edit_any_account', '', 1, 3);
+SET @iIdActionProfileEditAny = LAST_INSERT_ID();
+
+SET @iUnauthenticated = 1;
+SET @iAccount = 2;
+SET @iStandard = 3;
+SET @iUnconfirmed = 4;
+SET @iPending = 5;
+SET @iSuspended = 6;
+SET @iModerator = 7;
+SET @iAdministrator = 8;
+SET @iPremium = 9;
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
+
+-- edit any entry 
+(@iModerator, @iIdActionProfileEditAny),
+(@iAdministrator, @iIdActionProfileEditAny);
+
+
+-- 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_accounts_administration', 'Sql', 'SELECT `ta`.*, `tp`.`status` AS `status` FROM `sys_accounts` AS `ta` LEFT JOIN `sys_profiles` AS `tp` ON `ta`.`id`=`tp`.`account_id` AND `tp`.`type`=''system'' WHERE 1 ', 'sys_accounts', 'id', 'logged', 'status', '', 20, NULL, 'start', '', 'name,email,ip,phone', '', 'like', 'email_confirmed,logged', '', 192, 'BxAccntGridAdministration', 'modules/boonex/accounts/classes/BxAccntGridAdministration.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_accounts_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_accounts_administration', 'switcher', '_bx_accnt_grid_column_title_adm_active', '6%', 0, '', '', 2),
+('bx_accounts_administration', 'name', '_bx_accnt_grid_column_title_adm_name', '22%', 0, '22', '', 3),
+('bx_accounts_administration', 'email', '_bx_accnt_grid_column_title_adm_email', '22%', 0, '22', '', 4),
+('bx_accounts_administration', 'is_confirmed', '_bx_accnt_grid_column_title_adm_is_confirmed', '5%', 0, '', '', 5),
+('bx_accounts_administration', 'profiles', '_bx_accnt_grid_column_title_adm_profiles', '22%', 0, '22', '', 5),
+('bx_accounts_administration', 'logged', '_bx_accnt_grid_column_title_adm_logged', '15%', 0, '15', '', 7),
+('bx_accounts_administration', 'actions', '', '6%', 0, '', '', 8);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_accounts_administration', 'bulk', 'activate', '_bx_accnt_grid_action_title_adm_activate', '', 0, 0, 1),
+('bx_accounts_administration', 'bulk', 'suspend', '_bx_accnt_grid_action_title_adm_suspend', '', 0, 0, 2),
+('bx_accounts_administration', 'bulk', 'resend_cemail', '_bx_accnt_grid_action_title_adm_resend_cemail', '', 0, 0, 3),
+('bx_accounts_administration', 'bulk', 'delete', '_bx_accnt_grid_action_title_adm_delete', '', 0, 1, 4),
+('bx_accounts_administration', 'bulk', 'delete_with_content', '_bx_accnt_grid_action_title_adm_delete_with_content', '', 0, 1, 5),
+('bx_accounts_administration', 'single', 'edit_email', '_bx_accnt_grid_action_title_adm_edit_email', '', 0, 0, 0),
+('bx_accounts_administration', 'single', 'reset_password', '_bx_accnt_grid_action_title_adm_reset_password', '', 0, 0, 0),
+('bx_accounts_administration', 'single', 'unlock_account', '_bx_accnt_grid_action_title_adm_unlock_account', '', 0, 0, 0),
+('bx_accounts_administration', 'single', 'settings', '_bx_accnt_grid_action_title_adm_more_actions', 'cog', 1, 0, 2);

+ 35 - 0
modules/boonex/accounts/updates/9.0.10_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
+    <title>accounts</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <path d="M20,0 C8.94685484,0 0,8.94508065 0,20 C0,31.0531452 8.94508065,40 20,40 C23.8833871,40 27.688871,38.8596774 30.92,36.7562097 C31.8881452,36.1259677 32.0994355,34.7975 31.3677419,33.903629 L30.5470161,32.9009677 C29.9283871,32.1452419 28.8390323,31.9600806 28.0169355,32.4873387 C25.6387097,34.0126613 22.8479032,34.8387097 20,34.8387097 C11.8179032,34.8387097 5.16129032,28.1820968 5.16129032,20 C5.16129032,11.8179032 11.8179032,5.16129032 20,5.16129032 C28.0757258,5.16129032 34.8387097,9.80798387 34.8387097,18.0645161 C34.8387097,21.1924194 33.1376613,24.4953226 30.1475806,24.8139516 C28.7484677,24.7773387 28.783871,23.7770968 29.0608065,22.3926613 L30.9505645,12.6257258 C31.1816935,11.4314516 30.2667742,10.3225806 29.0504032,10.3225806 L25.4229032,10.3225806 C24.8684009,10.3225685 24.4022322,10.7387955 24.3396774,11.2897581 L24.338871,11.2971774 C23.153629,9.85354839 21.0769355,9.54112903 19.5025,9.54112903 C13.4879839,9.54112903 8.38709677,14.56 8.38709677,21.7556452 C8.38709677,27.0220161 11.353629,30.2935484 16.1290323,30.2935484 C18.3051613,30.2935484 20.7555645,29.0325 22.1766935,27.2021774 C22.9445968,29.9525 25.4519355,29.9524194 27.8791129,29.9524194 C36.6620161,29.9524194 40,24.1772581 40,18.0645161 C40,7.06879032 31.1308871,0 20,0 Z M18.2516129,24.5508065 C16.4573387,24.5508065 15.3427419,23.2908871 15.3427419,21.2628226 C15.3427419,17.6343548 17.8249194,15.3975806 20.0709677,15.3975806 C21.8687097,15.3975806 22.9420161,16.6266935 22.9420161,18.6854839 C22.9420161,22.3194355 20.2101613,24.5508065 18.2516129,24.5508065 Z" id="path-4"></path>
+        <filter x="-5.0%" y="-2.5%" width="110.0%" height="110.0%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="accounts">
+            <mask id="mask-2" fill="white">
+                <use xlink:href="#path-1"></use>
+            </mask>
+            <use id="Path" fill="#FF3B38" xlink:href="#path-1"></use>
+            <g id="at" mask="url(#mask-2)" fill-rule="nonzero">
+                <g transform="translate(12.000000, 12.000000)" id="Shape">
+                    <g>
+                        <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
+                        <use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 51 - 0
modules/boonex/acl/updates/9.0.11_10.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' => 'Paid Levels',
+    'version_from' => '9.0.11',
+    'version_to' => '10.0.0',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/acl/updates/update_9.0.11_10.0.0/',
+    'home_uri' => 'acl_update_9011_1000',
+
+    'module_dir' => 'boonex/acl/',
+    'module_uri' => 'acl',
+
+    'db_prefix' => 'bx_acl_',
+    'class_prefix' => 'BxAcl',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Paid Levels',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/acl/updates/9.0.11_10.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 BxAclUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 70 - 0
modules/boonex/acl/updates/9.0.11_10.0.0/source/install/config.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    PaidLevels Paid Levels
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_acl',
+    'title' => 'Paid Levels',
+    'note' => 'Paid Levels module.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/acl/',
+    'home_uri' => 'acl',
+
+    'db_prefix' => 'bx_acl_',
+    'class_prefix' => 'BxAcl',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Paid Levels',
+
+    /**
+     * 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(),
+);
+
+/** @} */

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 11 - 0
modules/boonex/acl/updates/9.0.11_10.0.0/source/template/images/icons/std-icon.svg


+ 34 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsAlertsResponse.php

@@ -0,0 +1,34 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAlbumsAlertsResponse extends BxBaseModTextAlertsResponse
+{
+    public function __construct()
+    {
+        $this->MODULE = 'bx_albums';
+        parent::__construct();
+    }
+
+    public function response($oAlert)
+    {
+        if ('bx_albums_files' == $oAlert->sUnit && 'file_deleted' == $oAlert->sAction)
+            BxDolService::call($this->MODULE, 'delete_file_associations', array($oAlert->iObject));
+
+        parent::response($oAlert);
+    }
+
+    protected function _onVideoTranscoded($iGhostId, $bResult, $aParams = array())
+    {
+        return parent::_onVideoTranscoded($iGhostId, $bResult, array('storage' => $this->_oModule->_oConfig->CNF['OBJECT_STORAGE']));
+    }
+}
+
+/** @} */

+ 200 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsConfig.php

@@ -0,0 +1,200 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolInformer');
+
+class BxAlbumsConfig extends BxBaseModTextConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $aMenuItems2Methods = array (
+            'add-images-to-album' => 'checkAllowedEdit',
+            'edit-album' => 'checkAllowedEdit',
+            'delete-album' => 'checkAllowedDelete',
+        );
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'far image col-blue1',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'albums',
+            'TABLE_ENTRIES_FULLTEXT' => 'title_text',
+            'TABLE_FILES2ENTRIES' => $aModule['db_prefix'] . 'files2albums',
+            'TABLE_FILES' => $aModule['db_prefix'] . 'files',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_TITLE' => 'title',
+            'FIELD_TEXT' => 'text',
+            'FIELD_TEXT_ID' => 'album-desc',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+            'FIELD_PHOTO' => 'pictures',
+            'FIELD_THUMB' => 'thumb',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELD_STATUS' => 'status',
+            'FIELD_STATUS_ADMIN' => 'status_admin',
+            '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
+            'FIELDS_DELAYED_PROCESSING' => 'pictures', // can be array of fields or comma separated string of field names
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-album',
+            'URI_VIEW_MEDIA' => 'view-album-media',
+            'URI_AUTHOR_ENTRIES' => 'albums-author',
+            'URI_ENTRIES_BY_CONTEXT' => 'albums-context',
+            'URI_ADD_ENTRY' => 'create-album',
+        	'URI_EDIT_ENTRY' => 'edit-album',
+        	'URI_MANAGE_COMMON' => 'albums-manage',
+
+            'URL_HOME' => 'page.php?i=albums-home',
+            'URL_POPULAR' => 'page.php?i=albums-popular',
+            'URL_UPDATED' => 'page.php?i=albums-home',
+            'URL_POPULAR_MEDIA' => 'page.php?i=albums-popular-media',
+            'URL_RECENT_MEDIA' => 'page.php?i=albums-recent-media', // TODO: add page
+        	'URL_MANAGE_COMMON' => 'page.php?i=albums-manage',
+        	'URL_MANAGE_ADMINISTRATION' => 'page.php?i=albums-administration',
+
+            // some params
+            'PARAM_CHARS_SUMMARY' => 'bx_albums_summary_chars',
+            'PARAM_CHARS_SUMMARY_PLAIN' => 'bx_albums_plain_summary_chars',
+            'PARAM_NUM_RSS' => 'bx_albums_rss_num',
+            'PARAM_SEARCHABLE_FIELDS' => 'bx_albums_searchable_fields',
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_albums_files',
+            'OBJECT_IMAGES_TRANSCODER_PREVIEW' => 'bx_albums_proxy_preview',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => '',
+            'OBJECT_IMAGES_TRANSCODER_BIG' => 'bx_albums_big',
+            'OBJECT_VIDEOS_TRANSCODERS' => array(
+                'poster' => 'bx_albums_video_poster_big', 
+                'poster_preview' => 'bx_albums_video_poster_preview', 
+                'mp4' => 'bx_albums_video_mp4', 
+                'mp4_hd' => 'bx_albums_video_mp4_hd'
+            ),
+            'OBJECT_VIDEO_TRANSCODER_HEIGHT' => '480px',
+            'OBJECT_TRANSCODER_BROWSE' => 'bx_albums_proxy_browse',
+            'OBJECT_TRANSCODER_COVER' => 'bx_albums_proxy_cover',
+            'OBJECT_REPORTS' => 'bx_albums',
+            'OBJECT_VIEWS' => 'bx_albums',
+            'OBJECT_VIEWS_MEDIA' => 'bx_albums_media',
+            'OBJECT_VOTES' => 'bx_albums',
+            'OBJECT_VOTES_MEDIA' => 'bx_albums_media',
+            'OBJECT_REACTIONS' => 'bx_albums_reactions',
+            'OBJECT_SCORES' => 'bx_albums',
+            'OBJECT_SCORES_MEDIA' => 'bx_albums_media',
+            'OBJECT_FAVORITES' => 'bx_albums',
+            'OBJECT_FAVORITES_MEDIA' => 'bx_albums_media',
+            'OBJECT_FEATURED' => 'bx_albums',
+            'OBJECT_FEATURED_MEDIA' => 'bx_albums_media',
+            'OBJECT_METATAGS' => 'bx_albums',
+            'OBJECT_METATAGS_MEDIA' => 'bx_albums_media',
+            'OBJECT_METATAGS_MEDIA_CAMERA' => 'bx_albums_media_camera',
+            'OBJECT_COMMENTS' => 'bx_albums',
+            'OBJECT_COMMENTS_MEDIA' => 'bx_albums_media',
+            'OBJECT_PRIVACY_VIEW' => 'bx_albums_allow_view_to',
+            'OBJECT_FORM_ENTRY' => 'bx_albums',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_albums_entry_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_albums_entry_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_albums_entry_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_albums_entry_delete',
+            'OBJECT_FORM_MEDIA' => 'bx_albums_media',
+            'OBJECT_FORM_MEDIA_DISPLAY_EDIT' => 'bx_albums_media_edit',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_albums_view', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_albums_view_actions', // all actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_MEDIA' => 'bx_albums_view_media', // actions menu on view media page
+            'OBJECT_MENU_ACTIONS_VIEW_MEDIA_ALL' => 'bx_albums_view_actions_media', // all actions menu on view media page
+            'OBJECT_MENU_ACTIONS_VIEW_MEDIA_UNIT' => 'bx_albums_view_actions_media_unit', // actions menu on media unit
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_albums_my', // actions menu on my entries page
+            'OBJECT_MENU_SUBMENU' => 'bx_albums_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_albums_view_submenu', // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'albums-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_SNIPPET_META' => 'bx_albums_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_albums_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_albums_administration',
+        	'OBJECT_GRID_COMMON' => 'bx_albums_common',
+        	'OBJECT_UPLOADERS' => array('bx_albums_simple', 'bx_albums_html5', 'bx_albums_crop'),
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_albums_my' => array (
+                    'create-album' => 'checkAllowedAdd',
+                ),
+                'bx_albums_view' => $aMenuItems2Methods,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'processing' => array (
+                    'name' => 'bx_albums-processing',
+                    'map' => array (
+                        'awaiting' => array('msg' => '_bx_albums_txt_processing_awaiting', 'type' => BX_INFORMER_ALERT),
+                        'failed' => array('msg' => '_bx_albums_txt_processing_failed', 'type' => BX_INFORMER_ERROR)
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_albums_txt_sample_single',
+            	'txt_sample_single_with_article' => '_bx_albums_txt_sample_single_with_article',
+            	'txt_sample_comment_single' => '_bx_albums_txt_sample_comment_single',
+            	'txt_sample_vote_single' => '_bx_albums_txt_sample_vote_single',
+                'txt_sample_score_up_single' => '_bx_albums_txt_sample_score_up_single',
+                'txt_sample_score_down_single' => '_bx_albums_txt_sample_score_down_single',
+                'txt_sample_action_changed' => '_bx_albums_txt_sample_action_changed',
+                'txt_media_single' => '_bx_albums_txt_media_single',
+                'txt_media_comment_single' => '_bx_albums_txt_media_comment_single',
+            	'txt_media_vote_single' => '_bx_albums_txt_media_vote_single',
+                'txt_media_score_up_single' => '_bx_albums_txt_media_score_up_single',
+                'txt_media_score_down_single' => '_bx_albums_txt_media_score_down_single',
+            	'form_field_author' => '_bx_albums_form_entry_input_author',
+            	'grid_action_err_delete' => '_bx_albums_grid_action_err_delete',
+            	'grid_txt_account_manager' => '_bx_albums_grid_txt_account_manager',
+                'filter_item_active' => '_bx_albums_grid_filter_item_title_adm_active',
+            	'filter_item_hidden' => '_bx_albums_grid_filter_item_title_adm_hidden',
+            	'filter_item_select_one_filter1' => '_bx_albums_grid_filter_item_title_adm_select_one_filter1',
+            	'menu_item_manage_my' => '_bx_albums_menu_item_title_manage_my',
+            	'menu_item_manage_all' => '_bx_albums_menu_item_title_manage_all',
+                'txt_all_entries_by' => '_bx_albums_txt_all_entries_by',
+                'txt_all_entries_in' => '_bx_albums_txt_all_entries_in',
+            	'txt_all_entries_by_author' => '_bx_albums_page_title_browse_by_author',
+                'txt_all_entries_by_context' => '_bx_albums_page_title_browse_by_context',
+            ),
+        );
+
+        $this->_aJsClasses = array(
+        	'main' => 'BxAlbumsMain',
+        	'manage_tools' => 'BxAlbumsManageTools'
+        );
+
+        $this->_aJsObjects = array(
+        	'main' => 'oBxAlbumsMain',
+        	'manage_tools' => 'oBxAlbumsManageTools'
+        );
+
+        $this->_aGridObjects = array(
+        	'common' => $this->CNF['OBJECT_GRID_COMMON'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        	
+        );
+    }
+}
+
+/** @} */

+ 186 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsDb.php

@@ -0,0 +1,186 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Module database queries
+ */
+class BxAlbumsDb extends BxBaseModTextDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+
+    public function associateFileWithContent($iContentId, $iFileId, $iProfileId, $sTitle, $sData = '', $sExif = '')
+    {
+        $sQuery = $this->prepare ("SELECT MAX(`order`) FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `content_id` = ?", $iContentId);
+        $iOrder = 1 + (int)$this->getOne($sQuery);
+
+        $sQuery = $this->prepare ("INSERT INTO `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` SET `content_id` = ?, `file_id` = ?, `author` = ?, `title` = ?, `data` = ?, `exif` = ?, `order` = ? ON DUPLICATE KEY UPDATE `title` = ?, `data` = ?, `exif` = ?", $iContentId, $iFileId, $iProfileId, $sTitle, $sData, $sExif, $iOrder, $sTitle, $sData, $sExif);
+        return $this->res($sQuery);
+    }
+
+    public function deassociateFileWithContent($iContentId, $iFileId)
+    {
+    	$aBindings = array();
+
+        $sWhere = '';
+        if ($iContentId) {
+        	$aBindings['content_id'] = $iContentId;
+
+            $sWhere .= " AND `content_id` = :content_id";
+        }
+
+        if ($iFileId) {
+        	$aBindings['file_id'] = $iFileId;
+
+            $sWhere .= " AND `file_id` = :file_id";
+        }
+
+        $sQuery = "DELETE FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE 1 " . $sWhere;
+        return $this->query($sQuery, $aBindings);
+    }
+
+    public function getFileTitle($iFileId)
+    {
+        $sQuery = $this->prepare ("SELECT `title` FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `file_id` = ?", $iFileId);
+        return $this->getOne($sQuery);
+    }
+
+    public function getMediaInfoById($iMediaId)
+    {
+        $sQuery = $this->prepare ("SELECT `f2e`.*, `f`.`added` FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` AS `f2e` INNER JOIN `" . $this->_oConfig->CNF['TABLE_FILES'] . "` AS `f` ON (`f`.`id` = `f2e`.`file_id`) INNER JOIN `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` AS `e` ON (`e`.`id` = `f2e`.`content_id`) WHERE `f2e`.`id` = ?", $iMediaId);
+        return $this->getRow($sQuery);
+    }
+
+    public function getMediaInfoSimpleByFileId($iFileId)
+    {
+        $sQuery = $this->prepare ("SELECT * FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `file_id` = ?", $iFileId);
+        return $this->getRow($sQuery);
+    }
+
+    public function getMediaCountByContentId($iContentId)
+    {
+        $sQuery = $this->prepare ("SELECT COUNT(*) FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `content_id` = ? LIMIT 1", $iContentId);
+        return $this->getOne($sQuery);
+    }
+
+    public function getMediaListByContentId($iContentId, $iLimit = false)
+    {
+        $sLimitQuery = '';
+        $aBindings = array('id' => $iContentId);
+        if ((int)$iLimit) {
+            $sLimitQuery = ' LIMIT :limit';
+            $aBindings = array_merge($aBindings, array('limit' => (int)$iLimit));
+        }
+            
+        $sQuery = "SELECT * FROM `" . $this->_oConfig->CNF['TABLE_FILES2ENTRIES'] . "` WHERE `content_id` = :id ORDER BY `order`" . $sLimitQuery;
+        return $this->getAll($sQuery, $aBindings);
+    }
+
+    function getMediaBy($aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query', 1 => array()));
+        $sSelectClause = $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+
+        $sSelectClause = "`{$CNF['TABLE_FILES2ENTRIES']}`.*";
+
+        switch($aParams['type']) {
+            case 'id':
+                $aMethod['name'] = 'getRow';
+                $aMethod['params'][1]['id'] = (int)$aParams['id'];
+
+                $sWhereClause .= " AND `{$CNF['TABLE_FILES2ENTRIES']}`.`id` = :id";
+                break;
+
+            case 'search_ids':
+                $aMethod['name'] = 'getColumn';
+                
+                $sSelectClause = "`{$CNF['TABLE_FILES2ENTRIES']}`.`id`";
+
+                if (!empty($aParams['start']) && !empty($aParams['per_page']))
+                    $sLimitClause = $this->prepareAsString("?, ?", $aParams['start'], $aParams['per_page']);
+                elseif (!empty($aParams['per_page']))
+                    $sLimitClause = $this->prepareAsString("?", $aParams['per_page']);
+
+                $sWhereConditions = "1";
+                foreach($aParams['search_params'] as $sSearchParam => $aSearchParam) {
+                    $sSearchValue = "";
+                    switch ($aSearchParam['operator']) {
+                        case 'like':
+                            $sSearchValue = " LIKE " . $this->escape("%" . $aSearchParam['value'] . "%");
+                            break;
+
+                        case 'in':
+                            $sSearchValue = " IN (" . $this->implode_escape($aSearchParam['value']) . ")";
+                            break;
+
+                        case 'and':
+                            $iResult = 0;
+                            if (is_array($aSearchParam['value']))
+                                foreach ($aSearchParam['value'] as $iValue)
+                                    $iResult |= pow (2, $iValue - 1);
+                            else 
+                                $iResult = (int)$aSearchParam['value'];
+
+                            $sSearchValue = " & " . $iResult . "";
+                            break;
+
+                        default:
+                             $sSearchValue = " " . $aSearchParam['operator'] . " :" . $sSearchParam;
+                             $aMethod['params'][1][$sSearchParam] = $aSearchParam['value'];                             
+                    }
+
+                    $sWhereConditions .= " AND `{$CNF['TABLE_FILES2ENTRIES']}`.`" . $sSearchParam . "`" . $sSearchValue;
+                }
+
+                $sWhereClause .= " AND (" . $sWhereConditions . ")"; 
+
+                $sOrderClause .=  "`{$CNF['TABLE_FILES2ENTRIES']}`.`id` ASC";
+                break;
+
+            case 'all_ids':
+                $aMethod['name'] = 'getColumn';
+
+                $sSelectClause = "`{$CNF['TABLE_FILES2ENTRIES']}`.`id`";
+                $sOrderClause .=  "`{$CNF['TABLE_FILES2ENTRIES']}`.`id` ASC";
+                break;
+
+            case 'all':
+                $sOrderClause .=  "`{$CNF['TABLE_FILES2ENTRIES']}`.`id` ASC";
+                break;
+        }
+
+        if(!empty($sOrderClause))
+            $sOrderClause = 'ORDER BY ' . $sOrderClause;
+
+        if(!empty($sLimitClause))
+            $sLimitClause = 'LIMIT ' . $sLimitClause;
+
+        $aMethod['params'][0] = "SELECT " . $sSelectClause . " FROM `{$CNF['TABLE_FILES2ENTRIES']}` " . $sJoinClause . " WHERE 1 " . $sWhereClause . " " . $sOrderClause . " " . $sLimitClause;
+		return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+    
+    public function updateMedia($aParamsSet, $aParamsWhere)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($aParamsSet) || empty($aParamsWhere))
+            return false;
+
+        $sSql = "UPDATE `" . $CNF['TABLE_FILES'] . "` SET " . $this->arrayToSQL($aParamsSet) . " WHERE " . $this->arrayToSQL($aParamsWhere, " AND ");
+        return $this->query($sSql);
+    }
+}
+
+/** @} */

+ 31 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsMenuSnippetMeta.php

@@ -0,0 +1,31 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAlbumsMenuSnippetMeta extends BxBaseModTextMenuSnippetMeta
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_albums';
+
+        parent::__construct($aObject, $oTemplate);
+    }
+
+    protected function _getMenuItemItems($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iCount = $this->_oModule->_oDb->getMediaCountByContentId($this->_aContentInfo[$CNF['FIELD_ID']]);
+
+        return $this->getUnitMetaItemText(_t($aItem['title'], $iCount));
+    }
+}
+
+/** @} */

+ 37 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsMenuView.php

@@ -0,0 +1,37 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * View entry menu
+ */
+class BxAlbumsMenuView extends BxBaseModTextMenuView
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_albums';
+        parent::__construct($aObject, $oTemplate);
+
+        $this->addMarkers(array('js_object' => $this->_oModule->_oConfig->getJsObject('main')));
+
+        $sURI = bx_process_input(bx_get('i'));
+        if ($sURI == 'view-album-media') {
+            $iMediaId = (int)bx_get('id');
+            $aMediaInfo = $this->_oModule->_oDb->getMediaInfoById($iMediaId);
+            $this->addMarkers(array('media_id' => $iMediaId));
+
+            $this->_aContentInfo = $aMediaInfo ? $this->_oModule->_oDb->getContentInfoById($aMediaInfo['content_id']) : false;
+            if ($this->_aContentInfo)
+                $this->addMarkers(array('content_id' => (int)$aMediaInfo['content_id']));
+        }
+    }
+}
+
+/** @} */

+ 161 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsMenuViewActionsMedia.php

@@ -0,0 +1,161 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once('BxAlbumsMenuViewActions.php');
+
+/**
+ * View media actions menu
+ */
+class BxAlbumsMenuViewActionsMedia extends BxAlbumsMenuViewActions
+{
+    protected $_iMediaId;
+    protected $_aMediaInfo;
+
+    public function __construct($aObject, $oTemplate = false)
+    {
+        parent::__construct($aObject, $oTemplate);
+    }
+
+    public function setContentId($iMediaId)
+    {
+        $this->_iMediaId = (int)$iMediaId;
+        $this->_aMediaInfo = $this->_oModule->_oDb->getMediaInfoById($this->_iMediaId);
+        if($this->_aMediaInfo) {
+            $this->addMarkers(array('media_id' => (int)$this->_iMediaId));
+
+            $this->_iContentId = (int)$this->_aMediaInfo['content_id'];
+            $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_iContentId);
+            if($this->_aContentInfo)
+                $this->addMarkers(array('content_id' => (int)$this->_iContentId));
+        }
+    }
+
+    protected function _isContentPublic($iMediaId)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(empty($CNF['FIELD_ALLOW_VIEW_TO'])) 
+            return true;
+
+        $aContentInfo = array();
+        if($iMediaId != $this->_iMediaId) {
+            $aMediaInfo = $this->_oModule->_oDb->getMediaInfoById($iMediaId);
+            if(!empty($aMediaInfo['content_id']))
+                $aContentInfo = (int)$aMediaInfo['content_id'] == $this->_iContentId ? $this->_aContentInfo : $this->_oModule->_oDb->getContentInfoById((int)$aMediaInfo['content_id']);
+        }
+        else 
+            $aContentInfo = $this->_aContentInfo;
+
+        if(!isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]))
+            return true;
+
+        return in_array($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']], array(BX_DOL_PG_ALL, BX_DOL_PG_MEMBERS));
+    }
+
+    protected function _getMenuItemAddImagesToAlbum($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return $this->_getMenuItemByNameActions($aItem, array(
+            'object_menu' => $CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA']
+        ));
+    }
+
+    protected function _getMenuItemEditAlbum($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return $this->_getMenuItemByNameActions($aItem, array(
+            'object_menu' => $CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA']
+        ));
+    }
+
+    protected function _getMenuItemEditImage($aItem)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return $this->_getMenuItemByNameActions($aItem, array(
+            'object_menu' => $CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA']
+        ));
+    }
+
+    protected function _getMenuItemView($aItem, $aParams = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getMenuItemView($aItem, array(
+            'object' => $CNF['OBJECT_VIEWS_MEDIA'],
+            'id' => $this->_iMediaId
+        ));
+    }
+
+    protected function _getMenuItemComment($aItem, $aParams = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getMenuItemComment($aItem, array(
+            'object' => $CNF['OBJECT_COMMENTS_MEDIA'],
+            'id' => $this->_iMediaId
+        ));
+    }
+
+    protected function _getMenuItemVote($aItem, $aParams = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getMenuItemVote($aItem, array(
+            'object' => $CNF['OBJECT_VOTES_MEDIA'],
+            'id' => $this->_iMediaId
+        ));
+    }
+
+    protected function _getMenuItemScore($aItem, $aParams = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getMenuItemScore($aItem, array(
+            'object' => $CNF['OBJECT_SCORES_MEDIA'],
+            'id' => $this->_iMediaId
+        ));
+    }
+
+    protected function _getMenuItemFavorite($aItem, $aParams = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getMenuItemFavorite($aItem, array(
+            'object' => $CNF['OBJECT_FAVORITES_MEDIA'],
+            'id' => $this->_iMediaId
+        ));
+    }
+
+    protected function _getMenuItemFeature($aItem, $aParams = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        return parent::_getMenuItemFeature($aItem, array(
+            'object' => $CNF['OBJECT_FEATURED_MEDIA'],
+            'id' => $this->_iMediaId
+        ));
+    }
+
+    protected function _getMenuItemRepost($aItem, $aParams = array())
+    {
+        return '';
+    }
+
+    protected function _getMenuItemReport($aItem, $aParams = array())
+    {
+        return '';
+    }
+}
+
+/** @} */

+ 842 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsModule.php

@@ -0,0 +1,842 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAcl');
+
+/**
+ * Albums module
+ */
+class BxAlbumsModule extends BxBaseModTextModule
+{
+    protected $_aContexts = array('popular', 'public', 'author');
+
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    /**
+     * Entry actions and social sharing block
+     */
+    public function serviceEntityAllActions ($mixedContent = false, $aParams = array())
+    {
+        if(!empty($mixedContent)) {
+            if(!is_array($mixedContent))
+               $mixedContent = array((int)$mixedContent, array());
+        }
+        else {
+            $mixedContent = $this->_getContent();
+            if($mixedContent === false)
+                return false;
+        }
+        
+        list($iContentId, $aContentInfo) = $mixedContent;
+
+        $aMedias = $this->_oDb->getMediaListByContentId($iContentId);
+        if(!empty($aMedias) && is_array($aMedias)) {
+            $aMedia = array_shift($aMedias);
+            if(!empty($aMedia['file_id']))
+                $aParams = array_merge(array(
+                    'entry_thumb' => $aMedia['file_id']
+                ), $aParams);
+        }
+
+        return parent::serviceEntityAllActions(array($iContentId, $aContentInfo), $aParams);
+    }
+    
+    /**
+     * Display form for adding media to the album.
+     * @param $iContentId album content id where media will be added, if it's not provided then it's determined from 'id' GET variable
+     * @return HTML string with form, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML. On error false or empty string is returned.
+     */ 
+    public function serviceEntityAddFiles ($iContentId = 0)
+    {
+        return $this->_serviceEntityForm ('editDataForm', $iContentId, 'bx_albums_entry_add_images');
+    }
+
+    /**
+     * Delete file and album association, also file views, votes, comments, meta data are also deleted
+     * @param $iFileId file ID
+     * @return true on success of false on error
+     */ 
+    public function serviceDeleteFileAssociations($iFileId)
+    {        
+        $CNF = &$this->_oConfig->CNF;
+
+        if (!($aMediaInfo = $this->_oDb->getMediaInfoSimpleByFileId($iFileId))) // file is already deleted
+            return true; 
+    
+        if (!$this->_oDb->deassociateFileWithContent(0, $iFileId))
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($aMediaInfo['content_id']);
+        $iSender = isLogged() ? bx_get_logged_profile_id() : $aMediaInfo['author'];
+        $iAuthor = isset($aContentInfo[$CNF['FIELD_AUTHOR']]) ? $aContentInfo[$CNF['FIELD_AUTHOR']] : $aMediaInfo['author'];
+        bx_alert($this->getName(), 'media_deleted', $aMediaInfo['content_id'], $iSender, array(
+            'object_author_id' => $iAuthor,
+
+            'subobject_id' => $aMediaInfo['id'],
+
+            'media_id' => $aMediaInfo['id'], 
+            'media_info' => $aMediaInfo,
+        ));
+
+        bx_alert($this->getName() . '_media', 'deleted', $aMediaInfo['id'], $iSender, array(
+            'object_id' => $aMediaInfo['content_id'],
+            'object_author_id' => $iAuthor,
+
+            'media_info' => $aMediaInfo,
+        ));        
+
+        if (!empty($CNF['OBJECT_VIEWS_MEDIA'])) {
+            $o = BxDolView::getObjectInstance($CNF['OBJECT_VIEWS_MEDIA'], $aMediaInfo['id']);
+            if ($o) $o->onObjectDelete();
+        }
+
+        if (!empty($CNF['OBJECT_VOTES_MEDIA'])) {
+            $o = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES_MEDIA'], $aMediaInfo['id']);
+            if ($o) $o->onObjectDelete();
+        }
+
+        if (!empty($CNF['OBJECT_SCORES_MEDIA'])) {
+            $o = BxDolScore::getObjectInstance($CNF['OBJECT_SCORES_MEDIA'], $aMediaInfo['id']);
+            if ($o) $o->onObjectDelete();
+        }
+
+        if (!empty($CNF['OBJECT_COMMENTS_MEDIA'])) {
+            $o = BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS_MEDIA'], $aMediaInfo['id']);
+            if ($o) $o->onObjectDelete();
+        }
+
+        if (!empty($CNF['OBJECT_METATAGS_MEDIA'])) {
+            $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS_MEDIA']);
+            $oMetatags->onDeleteContent($aMediaInfo['id']);
+        }
+
+        if (!empty($CNF['OBJECT_METATAGS_MEDIA_CAMERA'])) {
+            $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS_MEDIA_CAMERA']);
+            $oMetatags->onDeleteContent($aMediaInfo['id']);
+        }
+
+        return true;
+    }
+
+    /**
+     * Display media EXIF information.
+     * @param $iMediaId media ID, if it's omitted then it's taken from 'id' GET variable.
+     * @return HTML string with EXIF info. On error empty string is returned.
+     */ 
+    public function serviceMediaExif ($iMediaId = 0)
+    {
+        return $this->_serviceTemplateFunc ('mediaExif', $iMediaId, 'getMediaInfoById');
+    }
+
+    /**
+     * Display media comments block.
+     * @param $iMediaId media ID, if it's omitted then it's taken from 'id' GET variable.
+     * @return HTML string with comments. On error false or empty string is returned.
+     */
+    public function serviceMediaComments ($iMediaId = 0)
+    {
+        return $this->_entityComments($this->_oConfig->CNF['OBJECT_COMMENTS_MEDIA'], $iMediaId);
+    }
+
+    /**
+     * Display media author block.
+     * @param $iMediaId media ID, if it's omitted then it's taken from 'id' GET variable.
+     * @return HTML string with block content. On error false or empty string is returned.
+     */
+    public function serviceMediaAuthor ($iMediaId = 0)
+    {
+        return $this->_serviceTemplateFunc ('mediaAuthor', $iMediaId, 'getMediaInfoById');
+    }
+
+    /**
+     * Entry actions and social sharing block
+     */
+    public function serviceMediaAllActions ($mixedContent = false, $aParams = array())
+    {
+        $iMediaId = 0;
+        $aMediaInfo = array();
+
+        $bContent = !empty($mixedContent);
+        if($bContent && is_array($mixedContent))
+            list($iMediaId, $aMediaInfo) = $mixedContent;
+        else {
+            if($bContent)
+                $iMediaId = (int)$mixedContent;
+            else
+                $iMediaId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+            if(!$iMediaId)
+                return false;
+
+            $aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+        }
+
+        if(!$iMediaId || !$aMediaInfo)
+            return false;
+
+        $CNF = &$this->_oConfig->CNF;
+
+        return parent::serviceEntityAllActions (array($iMediaId, $aMediaInfo), array_merge(array(
+            'object_menu' => $CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA_ALL'],
+            'object_transcoder' => $CNF['OBJECT_IMAGES_TRANSCODER_BIG'],
+            'entry_url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_MEDIA'] . '&id=' . $iMediaId),
+            'entry_title' => $aMediaInfo['title'],
+            'entry_thumb' => $aMediaInfo['file_id']
+        ), $aParams));
+    }
+
+    /**
+     * Entry actions block
+     */
+    public function serviceMediaActions ($iContentId = 0)
+    {
+        $iContentId = $this->_getContent($iContentId, false);
+        if($iContentId === false)
+            return false;
+
+        $oMenu = BxTemplMenu::getObjectInstance($this->_oConfig->CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA']);
+        return $oMenu ? $oMenu->getCode() : false;
+    }
+
+    /**
+     * Display media social sharing buttons block.
+     * @param $iMediaId media ID, if it's omitted then it's taken from 'id' GET variable.
+     * @return HTML string with block content. On error false or empty string is returned.
+     */
+    public function serviceMediaSocialSharing ($iMediaId = 0)
+    {
+        if(!$iMediaId)
+            $iMediaId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(!$iMediaId)
+            return false;
+
+        $aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+        if(!$aMediaInfo)
+            return false;
+
+        $CNF = &$this->_oConfig->CNF;
+
+        return $this->serviceEntitySocialSharing(array($iMediaId, $aMediaInfo), array(
+            'uri' => $CNF['URI_VIEW_MEDIA'],
+            'title' => $aMediaInfo['title'],
+            'id_thumb' => $aMediaInfo['file_id'],
+            'object_transcoder' => $CNF['OBJECT_IMAGES_TRANSCODER_BIG']
+        ));
+    }
+
+    /**
+     * Display media preview block.
+     * @param $iMediaId media ID, if it's omitted then it's taken from 'id' GET variable.
+     * @param $mixedContext current context to navigate to next and previous file, possible values: popular, public, author. If omitted then value from 'context' GTE variable is taken. Default context is 'album' - when nothin is specified.
+     * @param $aParams array of additional params. 
+     * @return HTML string with block content. On error false or empty string is returned.
+     */
+    public function serviceMediaView ($iMediaId = 0, $mixedContext = false, $aParams = array())
+    {
+        if(!$iMediaId)
+            $iMediaId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(!$iMediaId)
+            return false;
+
+        if(!$mixedContext) {
+            $mixedContext = bx_process_input(bx_get('context'));
+            if(!in_array($mixedContext, $this->_aContexts)) // when no context specified, it is assumed that it is an album context
+                $mixedContext = bx_process_input($mixedContext, BX_DATA_INT); // numeric context is reserved for future use
+        }
+        $aParams['context'] = $mixedContext;
+
+        $iAutoplay = 0;
+        if(!isset($aParams['autoplay']) && ($iAutoplay = bx_get('autoplay')) !== false)
+            $aParams['autoplay'] = (int)$iAutoplay;
+
+        return $this->_oTemplate->entryMediaView ($iMediaId, $aParams);
+    }
+
+    public function checkAllowedSetThumb ($iContentId = 0)
+    {
+        return CHECK_ACTION_RESULT_NOT_ALLOWED;
+    }
+
+    /**
+     * Display block for browsing recently uploaded media files.
+     * @param $sUnitView unit view mode: gallery
+     * @param $bDisplayEmptyMsg display 'empty' message when nothing to browse, or return empty string.
+     * @param $bAjaxPaginate use AJAX or regular paginate.
+     * @return HTML string with block content. On error false or empty string is returned.
+     */    
+    public function serviceBrowseRecentMedia ($sUnitView = false, $bDisplayEmptyMsg = true, $bAjaxPaginate = true)
+    {
+        return $this->_serviceBrowse ('recent', array('unit_view' => $sUnitView), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate, 'SearchResultMedia');
+    }
+
+    /**
+     * Display featured media. 
+     * For the list of params @see BxAlbumsModule::serviceBrowseRecentMedia
+     */ 
+    public function serviceBrowseFeaturedMedia ($sUnitView = false, $bDisplayEmptyMsg = false, $bAjaxPaginate = true)
+    {
+        return $this->_serviceBrowse ('featured', array('unit_view' => $sUnitView), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate, 'SearchResultMedia');
+    }
+
+    /**
+     * Display popular media. 
+     * For the list of params @see BxAlbumsModule::serviceBrowseRecentMedia
+     */     
+    public function serviceBrowsePopularMedia ($sUnitView = false, $bDisplayEmptyMsg = true, $bAjaxPaginate = true)
+    {
+        return $this->_serviceBrowse ('popular', array('unit_view' => $sUnitView), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate, 'SearchResultMedia');
+    }
+
+    /**
+     * Display favorite media for particular profile. 
+     * @param $iProfileId profile ID, if omitted then 'profile_id' GET variable is used 
+     * @param $aParams additional params for browsing such as 'unit_view'
+     */         
+    public function serviceBrowseFavoriteMedia ($iProfileId = 0, $aParams = array())
+    {
+        $oProfile = null;
+        if((int)$iProfileId)
+            $oProfile = BxDolProfile::getInstance($iProfileId);
+        if(!$oProfile && bx_get('profile_id') !== false)
+            $oProfile = BxDolProfile:: getInstance(bx_process_input(bx_get('profile_id'), BX_DATA_INT));
+        if(!$oProfile)
+            $oProfile = BxDolProfile::getInstance();
+        if(!$oProfile)
+            return '';
+
+        $bEmptyMessage = false;
+        if(isset($aParams['empty_message'])) {
+            $bEmptyMessage = (bool)$aParams['empty_message'];
+            unset($aParams['empty_message']);
+        }
+
+        return $this->_serviceBrowse ('favorite', array_merge(array('user' => $oProfile->id()), $aParams), BX_DB_PADDING_DEF, $bEmptyMessage, true, 'SearchResultMedia');
+    }
+
+    public function serviceGetTimelineData()
+    {
+    	$sModule = $this->_aModule['name'];
+
+        $aResult = parent::serviceGetTimelineData();
+        $aResult['handlers'] = array_merge($aResult['handlers'], array(
+            array('group' => $sModule . '_object_media', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'medias_added', 'module_name' => $sModule, 'module_method' => 'get_timeline_media', 'module_class' => 'Module',  'groupable' => 0, 'group_by' => ''),
+        ));
+        $aResult['alerts'] = array_merge($aResult['alerts'], array(
+            array('unit' => $sModule, 'action' => 'medias_added')
+        ));
+
+        return $aResult;
+    }
+
+    public function serviceGetTimelineMedia($aEvent, $aBrowseParams = array())
+    {
+        if(empty($aEvent['content']))
+            return false;
+
+        $aEvent['content'] = unserialize($aEvent['content']);
+        if(empty($aEvent['content']['medias_added']) || !is_array($aEvent['content']['medias_added']))
+            return false;
+
+        $iContentId = (int)$aEvent['object_id'];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return false;
+
+        $CNF = &$this->_oConfig->CNF;
+        
+        //--- Views
+        $oViews = isset($CNF['OBJECT_VIEWS']) ? BxDolView::getObjectInstance($CNF['OBJECT_VIEWS'], $iContentId) : null;
+
+        $aViews = array();
+        if ($oViews && $oViews->isEnabled())
+            $aViews = array(
+                'system' => $CNF['OBJECT_VIEWS'],
+                'object_id' => $iContentId,
+                'count' => $aContentInfo['views']
+            );
+
+        //--- Votes
+        $oVotes = isset($CNF['OBJECT_VOTES']) ? BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $iContentId) : null;
+
+        $aVotes = array();
+        if ($oVotes && $oVotes->isEnabled())
+            $aVotes = array(
+                'system' => $CNF['OBJECT_VOTES'],
+                'object_id' => $iContentId,
+                'count' => $aContentInfo['votes']
+            );
+
+        //--- Scores
+        $oScores = isset($CNF['OBJECT_SCORES']) ? BxDolScore::getObjectInstance($CNF['OBJECT_SCORES'], $iContentId) : null;
+
+        $aScores = array();
+        if ($oScores && $oScores->isEnabled())
+            $aScores = array(
+                'system' => $CNF['OBJECT_SCORES'],
+                'object_id' => $iContentId,
+                'score' => $aContentInfo['score']
+            );
+
+        //--- Reports
+        $oReports = isset($CNF['OBJECT_REPORTS']) ? BxDolReport::getObjectInstance($CNF['OBJECT_REPORTS'], $aEvent['object_id']) : null;
+
+        $aReports = array();
+        if ($oReports && $oReports->isEnabled())
+            $aReports = array(
+                'system' => $CNF['OBJECT_REPORTS'],
+                'object_id' => $iContentId,
+                'count' => $aContentInfo['reports']
+            );
+
+        //--- Comments
+        $oCmts = isset($CNF['OBJECT_COMMENTS']) ? BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $iContentId) : null;
+
+        $aComments = array();
+        if($oCmts && $oCmts->isEnabled())
+            $aComments = array(
+                'system' => $CNF['OBJECT_COMMENTS'],
+                'object_id' => $iContentId,
+                'count' => $aContentInfo['comments']
+            );
+
+        //--- Title & Description
+        $sTitle = isset($CNF['FIELD_TITLE']) && isset($aContentInfo[$CNF['FIELD_TITLE']]) ? $aContentInfo[$CNF['FIELD_TITLE']] : (isset($CNF['FIELD_TEXT']) && isset($aContentInfo[$CNF['FIELD_TEXT']]) ? strmaxtextlen($aContentInfo[$CNF['FIELD_TEXT']], 20, '...') : '');
+
+        return array(
+            'owner_id' => $aEvent['owner_id'],
+            'object_owner_id' => $aContentInfo['author'],
+            'icon' => !empty($CNF['ICON']) ? $CNF['ICON'] : '',
+            'sample' => isset($CNF['T']['txt_sample_single_with_article']) ? $CNF['T']['txt_sample_single_with_article'] : $CNF['T']['txt_sample_single'],
+            'sample_wo_article' => $CNF['T']['txt_sample_single'],
+    	    'sample_action' => $CNF['T']['txt_sample_action_changed'],
+            'url' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId),
+            'content' => $this->_getContentForTimelineMedia($aEvent, $aContentInfo, $aBrowseParams), //a string to display or array to parse default template before displaying.
+            'date' => $aContentInfo[$CNF['FIELD_ADDED']],
+            'views' => $aViews,
+            'votes' => $aVotes,
+            'scores' => $aScores,
+            'reports' => $aReports,
+            'comments' => $aComments,
+            'title' => $sTitle, //may be empty.
+            'description' => '' //may be empty.
+        );
+    }
+
+    public function serviceGetNotificationsData()
+    {
+        $sModule = $this->_aModule['name'];
+
+        $sEventPrivacy = $sModule . '_allow_view_event_to';
+        if(BxDolPrivacy::getObjectInstance($sEventPrivacy) === false)
+                $sEventPrivacy = '';
+
+        $aResult = parent::serviceGetNotificationsData();
+        $aResult['handlers'] = array_merge($aResult['handlers'], array(
+            array('group' => $sModule . '_object_media', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'medias_added', 'module_name' => $sModule, 'module_method' => 'get_notifications_media', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            array('group' => $sModule . '_object_media', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'media_deleted'),
+
+            array('group' => $sModule . '_comment_media', 'type' => 'insert', 'alert_unit' => $sModule . '_media', 'alert_action' => 'commentPost', 'module_name' => $sModule, 'module_method' => 'get_notifications_comment_media', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            array('group' => $sModule . '_comment_media', 'type' => 'delete', 'alert_unit' => $sModule . '_media', 'alert_action' => 'commentRemoved'),
+
+            array('group' => $sModule . '_vote_media', 'type' => 'insert', 'alert_unit' => $sModule . '_media', 'alert_action' => 'doVote', 'module_name' => $sModule, 'module_method' => 'get_notifications_vote_media', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+            array('group' => $sModule . '_vote_media', 'type' => 'delete', 'alert_unit' => $sModule . '_media', 'alert_action' => 'undoVote'),
+            
+            array('group' => $sModule . '_score_up_media', 'type' => 'insert', 'alert_unit' => $sModule . '_media', 'alert_action' => 'doVoteUp', 'module_name' => $sModule, 'module_method' => 'get_notifications_score_up_media', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+
+            array('group' => $sModule . '_score_down_media', 'type' => 'insert', 'alert_unit' => $sModule . '_media', 'alert_action' => 'doVoteDown', 'module_name' => $sModule, 'module_method' => 'get_notifications_score_down_media', 'module_class' => 'Module', 'module_event_privacy' => $sEventPrivacy),
+        ));
+
+        $aResult['settings'] = array_merge($aResult['settings'], array(
+            array('group' => 'content', 'unit' => $sModule, 'action' => 'medias_added', 'types' => array('follow_member', 'follow_context')),
+            array('group' => 'comment', 'unit' => $sModule . '_media', 'action' => 'commentPost', 'types' => array('personal', 'follow_member', 'follow_context')),
+            array('group' => 'vote', 'unit' => $sModule . '_media', 'action' => 'doVote', 'types' => array('personal', 'follow_member', 'follow_context')),
+            array('group' => 'score_up', 'unit' => $sModule . '_media', 'action' => 'doVoteUp', 'types' => array('personal', 'follow_member', 'follow_context')),
+            array('group' => 'score_down', 'unit' => $sModule . '_media', 'action' => 'doVoteDown', 'types' => array('personal', 'follow_member', 'follow_context'))
+        ));
+
+        $aResult['alerts'] = array_merge($aResult['alerts'], array(
+            array('unit' => $sModule, 'action' => 'medias_added'),
+            array('unit' => $sModule, 'action' => 'media_deleted'),
+
+            array('unit' => $sModule . '_media', 'action' => 'commentPost'),
+            array('unit' => $sModule . '_media', 'action' => 'commentRemoved'),
+
+            array('unit' => $sModule . '_media', 'action' => 'doVote'),
+            array('unit' => $sModule . '_media', 'action' => 'undoVote'),
+
+            array('unit' => $sModule . '_media', 'action' => 'doVoteUp'),
+            array('unit' => $sModule . '_media', 'action' => 'doVoteDown'),
+        ));
+
+        return $aResult; 
+    }
+
+    public function serviceGetNotificationsMedia($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $iContentId = (int)$aEvent['object_id'];
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(empty($aContentInfo) || !is_array($aContentInfo))
+            return array();
+
+    	$iMediaId = (int)$aEvent['subobject_id'];
+    	$aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+        if(empty($aMediaInfo) || !is_array($aMediaInfo))
+            return array();
+
+        $oPermalinks = BxDolPermalinks::getInstance();
+        $sEntryUrl = BX_DOL_URL_ROOT . $oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId);
+        $sSubentryUrl = BX_DOL_URL_ROOT . $oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_MEDIA'] . '&id=' . $iMediaId);
+        $sEntryCaption = isset($aMediaInfo['title']) ? $aMediaInfo['title'] : _t('_bx_albums_media');
+
+        return array(
+            'entry_sample' => $CNF['T']['txt_sample_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $sEntryCaption,
+            'entry_author' => $aMediaInfo['author'],
+            'subentry_sample' => $CNF['T']['txt_media_single'],
+            'subentry_url' => $sSubentryUrl,
+            'lang_key' => '', //may be empty or not specified. In this case the default one from Notification module will be used.
+        );
+    }
+
+    public function serviceGetNotificationsCommentMedia($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iMediaId = (int)$aEvent['object_id'];
+    	$aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+        if(empty($aMediaInfo) || !is_array($aMediaInfo))
+            return array();
+
+        $oComment = BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS_MEDIA'], $iMediaId);
+        if(!$oComment || !$oComment->isEnabled())
+            return array();
+
+        $sEntryUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_MEDIA'] . '&id=' . $aMediaInfo['id']);
+        $sEntryCaption = isset($aMediaInfo['title']) ? $aMediaInfo['title'] : _t('_bx_albums_media');
+
+        return array(
+            'entry_sample' => $CNF['T']['txt_media_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $sEntryCaption,
+            'entry_author' => $aMediaInfo['author'],
+            'subentry_sample' => $CNF['T']['txt_media_comment_single'],
+            'subentry_url' => $oComment->getViewUrl((int)$aEvent['subobject_id']),
+            'lang_key' => '', //may be empty or not specified. In this case the default one from Notification module will be used.
+        );
+    }
+
+    public function serviceGetNotificationsVoteMedia($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iMediaId = (int)$aEvent['object_id'];
+    	$aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+        if(empty($aMediaInfo) || !is_array($aMediaInfo))
+            return array();
+
+        $oVote = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES_MEDIA'], $iMediaId);
+        if(!$oVote || !$oVote->isEnabled())
+            return array();
+
+        $sEntryUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_MEDIA'] . '&id=' . $aMediaInfo['id']);
+        $sEntryCaption = isset($aMediaInfo['title']) ? $aMediaInfo['title'] : _t('_bx_albums_media');
+
+        return array(
+            'entry_sample' => $CNF['T']['txt_media_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $sEntryCaption,
+            'entry_author' => $aMediaInfo['author'],
+            'subentry_sample' => $CNF['T']['txt_media_vote_single'],
+            'subentry_url' => '',
+            'lang_key' => '', //may be empty or not specified. In this case the default one from Notification module will be used.
+        );
+    }
+
+    public function serviceGetNotificationsScoreUpMedia($aEvent)
+    {
+    	return $this->_serviceGetNotificationsScoreMedia('up', $aEvent);
+    }
+
+    public function serviceGetNotificationsScoreDownMedia($aEvent)
+    {
+    	return $this->_serviceGetNotificationsScoreMedia('down', $aEvent);
+    }
+
+    protected function _serviceGetNotificationsScoreMedia($sType, $aEvent)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$iMediaId = (int)$aEvent['object_id'];
+    	$aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+        if(empty($aMediaInfo) || !is_array($aMediaInfo))
+            return array();
+
+        $oVote = BxDolScore::getObjectInstance($CNF['OBJECT_SCORES_MEDIA'], $iMediaId);
+        if(!$oVote || !$oVote->isEnabled())
+            return array();
+
+        $sEntryUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_MEDIA'] . '&id=' . $aMediaInfo['id']);
+        $sEntryCaption = isset($aMediaInfo['title']) ? $aMediaInfo['title'] : _t('_bx_albums_media');
+
+        return array(
+            'entry_sample' => $CNF['T']['txt_media_single'],
+            'entry_url' => $sEntryUrl,
+            'entry_caption' => $sEntryCaption,
+            'entry_author' => $aMediaInfo['author'],
+            'subentry_sample' => $CNF['T']['txt_media_score_' . $sType . '_single'],
+            'subentry_url' => '',
+            'lang_key' => '', //may be empty or not specified. In this case the default one from Notification module will be used.
+        );
+    }
+
+    public function actionEditMedia($iMediaId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $iMediaId = (int)$iMediaId;
+    	$aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_MEDIA'], $CNF['OBJECT_FORM_MEDIA_DISPLAY_EDIT']);
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'edit_media/' . $iMediaId;
+        $oForm->initChecker($aMediaInfo);
+
+        if($oForm->isSubmittedAndValid()) {
+            if($oForm->update($iMediaId) !== false)
+                $aRes = array('reload' => 1);
+            else
+                $aRes = array('msg' => _t('_bx_albums_txt_err_cannot_perform_action'));
+
+            return echoJson($aRes);
+        }
+
+        $sContent = BxTemplStudioFunctions::getInstance()->transBox('bx-albums-edit-media-popup', $this->_oTemplate->parseHtmlByName('media-edit.html', array(
+            'form_id' => $oForm->aFormAttrs['id'],
+            'form' => $oForm->getCode(true)
+        )));
+
+        echoJson(array('popup' => array('html' => $sContent, 'options' => array('closeOnOuterClick' => false))));
+    }
+
+    public function actionGetSiblingMedia($iMediaId, $mixedContext)
+    {
+        $aSiblings = false;
+        $sErrorMsg = false;
+        if (!($aMediaInfo = $this->_oDb->getMediaInfoById((int)$iMediaId))) 
+            $sErrorMsg = _t('_sys_txt_error_occured');
+
+        if (empty($sErrorMsg) && !($aContentInfo = $this->_oDb->getContentInfoById($aMediaInfo['content_id'])))
+            $sErrorMsg = _t('_sys_txt_error_occured');
+
+        if (empty($sErrorMsg) && (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedView($aContentInfo))))
+            $sErrorMsg = $sMsg;
+
+        if (empty($sErrorMsg)) {
+            $aSiblings = array (
+                'next' => $this->_oTemplate->getNextPrevMedia($aMediaInfo, true, $mixedContext),
+                'prev' => $this->_oTemplate->getNextPrevMedia($aMediaInfo, false, $mixedContext),
+            );
+        }
+    
+        $a = $sErrorMsg ? array('error' => $sErrorMsg) : array('next' => $aSiblings['next'], 'prev' => $aSiblings['prev']);
+
+        $s = json_encode($a);
+
+        header('Content-type: text/html; charset=utf-8');
+        echo $s;
+    }
+
+    public function actionRssMedia ()
+    {
+        $aArgs = func_get_args();
+        $this->_rss($aArgs, 'SearchResultMedia');
+    }
+
+    public function getMediaDuration($aMediaInfo) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($aMediaInfo) || !is_array($aMediaInfo))
+            return 0;
+
+        $sField = 'duration';
+        if(!empty($aMediaInfo[$sField]))
+            return (int)$aMediaInfo[$sField];
+
+        $iMedia = $aMediaInfo['id'];
+        $sMedia = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4'])->getFileUrl($iMedia);
+        if(empty($sMedia))
+            return 0;
+
+        $iDuration = (int)BxDolTranscoderVideo::getDuration($sMedia);
+        if(!empty($iDuration))
+            $this->_oDb->updateMedia(array($sField => $iDuration), array('id' => $iMedia));
+
+        return $iDuration;
+    }
+
+    protected function _buildRssParams($sMode, $aArgs)
+    {        
+        if ($aParams = parent::_buildRssParams($sMode, $aArgs))
+            return $aParams;
+
+        $sMode = bx_process_input($sMode);
+        switch ($sMode) {
+            case 'album':
+                $aParams = array('album_id' => isset($aArgs[0]) ? (int)$aArgs[0] : '');
+                break;
+        }
+
+        return $aParams;
+    }
+
+    protected function _getImagesForTimelinePostAttach($aEvent, $aContentInfo, $sUrl, $aBrowseParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']))
+            return array();
+
+        $aMediaList = $this->_oDb->getMediaListByContentId($aContentInfo[$CNF['FIELD_ID']]);
+        if(empty($aMediaList) || !is_array($aMediaList))
+            return array();
+
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+        $oTcPoster = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['poster']);
+        $oTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']);
+        
+        $aOutput = array();
+        foreach ($aMediaList as $aMedia) {
+            $aFileInfo = $oStorage->getFile($aMedia['file_id']);
+
+            $bVideo = $oTcPoster && strncmp('video/', $aFileInfo['mime_type'], 6) === 0 && $oTcPoster->isMimeTypeSupported($aFileInfo['mime_type']);
+            if($bVideo)
+                continue;
+
+            $aOutput[$aMedia['id']] = array (
+                'url' => $this->_oTemplate->getViewMediaUrl($CNF, $aMedia['id']), 
+                'src' => $oTranscoder->getFileUrl($aMedia['file_id']),
+            );
+        }
+
+        return count($aOutput) > 3 ? array_slice($aOutput, 0, 3) : $aOutput;
+    }
+
+    protected function _getVideosForTimelinePostAttach($aEvent, $aContentInfo, $sUrl, $aBrowseParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($CNF['OBJECT_VIDEOS_TRANSCODERS']))
+            return array();
+
+        $aMediaList = $this->_oDb->getMediaListByContentId($aContentInfo[$CNF['FIELD_ID']]);
+        if(empty($aMediaList) || !is_array($aMediaList))
+            return array();
+
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+        $oTcPoster = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['poster']);
+        $oTcMp4 = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4']);
+        $oTcMp4Hd = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4_hd']);
+        if(!$oTcPoster || !$oTcMp4 || !$oTcMp4Hd)
+            return $aResults;
+
+        $aOutput = array();
+        foreach($aMediaList as $k => $aMedia) {
+            $aFileInfo = $oStorage->getFile($aMedia['file_id']);
+
+            $bVideo = $oTcPoster && strncmp('video/', $aFileInfo['mime_type'], 6) === 0 && $oTcPoster->isMimeTypeSupported($aFileInfo['mime_type']);
+            if(!$bVideo)
+                continue;
+
+            $sVideoUrl = $oStorage->getFileUrlById($aMedia['file_id']);
+            $aVideoSize = $oTcMp4Hd->getVideoSize($sVideoUrl);
+
+            $sVideoUrlHd = '';
+            if(!empty($aVideoSize) && is_array($aVideoSize) && (int)$aVideoSize['h'] >= 720)
+                $sVideoUrlHd = $oTcMp4Hd->getFileUrl($aMedia['file_id']);
+
+            $aOutput[$aMedia['id']] = array(
+                'id' => $aMedia['id'],
+                'src_poster' => $oTcPoster->getFileUrl($aMedia['file_id']),
+                'src_mp4' => $oTcMp4->getFileUrl($aMedia['file_id']),
+                'src_mp4_hd' => $sVideoUrlHd,
+            );
+        }
+
+        return count($aOutput) > 3 ? array_slice($aOutput, 0, 3) : $aOutput;
+    }
+
+    protected function _getContentForTimelineMedia($aEvent, $aContentInfo, $aBrowseParams = array())
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
+        $sTitle = isset($CNF['FIELD_TITLE']) && isset($aContentInfo[$CNF['FIELD_TITLE']]) ? $aContentInfo[$CNF['FIELD_TITLE']] : (isset($CNF['FIELD_TEXT']) && isset($aContentInfo[$CNF['FIELD_TEXT']]) ? strmaxtextlen($aContentInfo[$CNF['FIELD_TEXT']], 20, '...') : '');
+
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+        $oTcPoster = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['poster']);
+        $oTcMp4 = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4']);
+        $oTcMp4Hd = BxDolTranscoderVideo::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4_hd']);
+        $oTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']);
+
+    	//--- Image(s) and Video(s)
+        $aImages = $aVideos = array();
+        foreach($aEvent['content']['medias_added'] as $iMediaId) {
+            $aMediaInfo = $this->_oDb->getMediaInfoById($iMediaId);
+            if(empty($aMediaInfo) || !is_array($aMediaInfo))
+                continue;
+
+            $aFileInfo = $oStorage->getFile($aMediaInfo['file_id']);
+            $bVideo = $oTcPoster && strncmp('video/', $aFileInfo['mime_type'], 6) === 0 && $oTcPoster->isMimeTypeSupported($aFileInfo['mime_type']);
+            if($bVideo)
+                $aVideos[$iMediaId] = array(
+                    'id' => $aMediaInfo['id'],
+                    'src_poster' => $oTcPoster->getFileUrl($aMediaInfo['file_id']),
+                    'src_mp4' => $oTcMp4->getFileUrl($aMediaInfo['file_id']),
+                    'src_mp4_hd' => $oTcMp4Hd->getFileUrl($aMediaInfo['file_id']),
+                );
+            else
+                $aImages[$iMediaId] = array(
+                    'url' => $this->_oTemplate->getViewMediaUrl($CNF, $aMediaInfo['id']), 
+                    'src' => $oTranscoder->getFileUrl($aMediaInfo['file_id']),
+                );
+        }
+
+    	return array(
+            'sample' => isset($CNF['T']['txt_sample_single_with_article']) ? $CNF['T']['txt_sample_single_with_article'] : $CNF['T']['txt_sample_single'],
+            'sample_wo_article' => $CNF['T']['txt_sample_single'],
+            'sample_action' => isset($CNF['T']['txt_sample_action_changed']),
+            'url' => $sUrl,
+            'title' => $sTitle,
+            'text' => '',
+            'images_attach' => $aImages,
+            'videos_attach' => $aVideos
+        );
+    }
+
+    protected function _getImagesForTimelineMedia($aEvent, $aMediaInfo, $sUrl, $aBrowseParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aImages = array();
+
+        
+
+        return $aImages;
+    }
+}
+
+/** @} */

+ 120 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsPageMedia.php

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

+ 471 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsTemplate.php

@@ -0,0 +1,471 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Module representation.
+ */
+class BxAlbumsTemplate extends BxBaseModTextTemplate
+{
+    /**
+     * Constructor
+     */
+    function __construct(&$oConfig, &$oDb)
+    {
+        $this->MODULE = 'bx_albums';
+        parent::__construct($oConfig, $oDb);
+
+        $this->addCss(array(BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flickity/|flickity.css'));
+        $this->addJs(array('flickity/flickity.pkgd.min.js', 'main.js'));
+    }
+
+    function unit ($aData, $isCheckPrivateContent = true, $sTemplateName = 'unit.html', $aParams = array())
+    {
+        if ('unit_media.html' == $sTemplateName || 'unit_media_live_search.html' == $sTemplateName || 'unit_showcase.html' == $sTemplateName)
+            return $this->unitMedia($aData, $isCheckPrivateContent, $sTemplateName, $aParams);
+
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        if ($s = $this->checkPrivacy ($aData, $isCheckPrivateContent, $oModule))
+            return $s;
+
+        // get entry url        
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
+
+        $oProfile = BxDolProfile::getInstance($aData[$CNF['FIELD_AUTHOR']]);
+        if (!$oProfile) 
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+        $oTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_TRANSCODER_BROWSE']);
+        $oTranscoderPoster = $CNF['OBJECT_VIDEOS_TRANSCODERS'] ? BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['poster']) : false;
+
+        $aBrowseUnits = array ();
+        $aMediaList = $oModule->_oDb->getMediaListByContentId($aData[$CNF['FIELD_ID']], getParam('bx_albums_album_browsing_unit'));
+        foreach ($aMediaList as $k => $a) {
+            $aFileInfo = $oStorage->getFile($a['file_id']);
+
+            $bVideo = $oTranscoderPoster && strncmp('video/', $aFileInfo['mime_type'], 6) === 0 && $oTranscoderPoster->isMimeTypeSupported($aFileInfo['mime_type']);            
+            $iVideoDuration = $bVideo ? $oModule->getMediaDuration($aFileInfo) : 0;
+
+            $aBrowseUnits[] = array (
+                'img_url' => $oTranscoder->getFileUrl($a['file_id']),
+                'url' => $this->getViewMediaUrl($CNF, $a['id']),
+                'title_attr' => bx_html_attribute($a['title']),
+                'bx_if:show_play' => array(
+                    'condition' => $bVideo,
+                    'content' => array()
+                ),
+                'bx_if:show_duration' => array(
+                    'condition' => $iVideoDuration > 0,
+                    'content' => array(
+                        'duration' => _t_format_duration($iVideoDuration)
+                    )
+                )
+
+            );
+        }
+
+        // get summary
+        $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']));
+
+        $sMeta = '';
+        if(!empty($CNF['OBJECT_MENU_SNIPPET_META'])) {
+            $oMenuMeta = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_SNIPPET_META'], $this);
+            if($oMenuMeta) {
+                $oMenuMeta->setContentId($aData[$CNF['FIELD_ID']]);
+                $aTmplVarsMeta = array(
+                    'meta' => $oMenuMeta->getCode()
+                );
+            }
+        }
+
+        // generate html
+        $aVars = array (
+            'id' => $aData[$CNF['FIELD_ID']],
+            'content_url' => $sUrl,
+            'title' => bx_process_output($aData[$CNF['FIELD_TITLE']]),
+        	'summary' => $sSummary,
+            'author' => $oProfile->getDisplayName(),
+            'author_url' => $oProfile->getUrl(),
+            'entry_posting_date' => bx_time_js($aData[$CNF['FIELD_ADDED']], BX_FORMAT_DATE),
+            'module_name' => _t($CNF['T']['txt_sample_single']),
+            'ts' => $aData[$CNF['FIELD_ADDED']],
+        	'bx_if:meta' => array(
+                'condition' => !empty($aTmplVarsMeta),
+                'content' => $aTmplVarsMeta
+            ),
+            'bx_repeat:browse' => $aBrowseUnits,
+            'bx_if:thumb' => array (
+                'condition' => $aBrowseUnits,
+                'content' => array (
+                    'title' => bx_process_output($aData[$CNF['FIELD_TITLE']]),
+                    'summary_attr' => '',
+                    'content_url' => $sUrl,
+                    'thumb_url' => $aBrowseUnits ? $aBrowseUnits[0]['img_url'] : '',
+                    'gallery_url' => '',
+                    'strecher' => '',
+                ),
+            ),
+            'bx_if:no_thumb' => array (
+                'condition' => !$aBrowseUnits,
+                'content' => array (
+                    'content_url' => $sUrl,
+                    'summary_plain' => '',
+                    'strecher' => '',
+                ),
+            ),
+
+        );
+
+        return $this->parseHtmlByName($sTemplateName, $aVars);
+    }
+
+    function unitMedia ($aData, $isCheckPrivateContent = true, $sTemplateName = 'unit.html', $aParams = array())
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        if (!($aMediaInfo = $oModule->_oDb->getMediaInfoById($aData['id'])))
+            return '';
+
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+        if (!($aFile = $oStorage->getFile($aMediaInfo['file_id'])))
+            return '';
+
+        $aVars = $this->mediaVars($aMediaInfo, $CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW'], $CNF['OBJECT_VIDEOS_TRANSCODERS']['poster_preview'], $aParams);
+
+        $aVarsTmp = $aVars['bx_if:image']['condition'] ? $aVars['bx_if:image']['content'] : $aVars['bx_if:video']['content'];
+
+        $aVars = array_merge($aVars, array (
+            'class' => $this->_getUnitClass($aData, $sTemplateName),
+            'module_name' => _t($CNF['T']['txt_media_single']),
+            'content_url' => $aVars['url'],
+            'ts' => $aFile['added'],
+            'actions' => $oModule->serviceMediaAllActions(array($aData['id'], $aMediaInfo), array(
+                'object_menu' => $CNF['OBJECT_MENU_ACTIONS_VIEW_MEDIA_UNIT']
+            )),
+            'bx_if:thumb' => array (
+                'condition' => $aData['file_id'],
+                'content' => array (
+                    'title' => bx_process_output($aData['title']),
+                    'summary_attr' => '',
+                    'content_url' => $aVarsTmp['url'],
+                    'thumb_url' => $aVarsTmp['url_img'],
+                    'gallery_url' => '',
+                    'strecher' => '',
+                ),
+            ),
+            'bx_if:no_thumb' => array (
+                'condition' => false,
+                'content' => array (),
+            ),
+        ));
+
+        return $this->parseHtmlByName($sTemplateName, $aVars);
+    }
+
+    public function entryText ($aData, $sTemplateName = 'entry-text.html')
+    {
+        $CNF = &$this->getModule()->_oConfig->CNF;
+
+        $aVars = $this->getTmplVarsText($aData);
+        if(empty($aVars[$CNF['FIELD_TITLE']]) && empty($aVars[$CNF['FIELD_TEXT']]))
+            return false;
+
+        return $this->parseHtmlByName($sTemplateName, $aVars);
+    }
+
+    function entryMediaView ($iMediaId, $aParams = array())
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        if (!($aMediaInfo = $oModule->_oDb->getMediaInfoById($iMediaId)))
+            return '';
+
+        if (!($aAlbumInfo = $oModule->_oDb->getContentInfoById($aMediaInfo['content_id'])))
+            return '';        
+
+        $sUrlAlbum = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aAlbumInfo[$CNF['FIELD_ID']]);
+
+        $iProfileId = $aAlbumInfo[$CNF['FIELD_AUTHOR']];
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+        if (!$oProfile) 
+            $oProfile = BxDolProfileUndefined::getInstance();
+
+        $aVars = array(
+            'album' => _t('_bx_albums_txt_media_album_link', $sUrlAlbum,  bx_process_output($aAlbumInfo[$CNF['FIELD_TITLE']]), $oProfile->getUrl(), $oProfile->getDisplayName()),
+            'js_code' => $this->getJsCode('main')
+        );
+
+        $mixedContext = isset($aParams['context']) ? $aParams['context'] : false;
+
+        $aNextPrev = array (
+            'next' => $this->getNextPrevMedia($aMediaInfo, true, $mixedContext),
+            'prev' => $this->getNextPrevMedia($aMediaInfo, false, $mixedContext),
+        );
+
+        foreach ($aNextPrev as $k => $a) {
+            $aVars['bx_if:' . $k] = array (
+                'condition' => $a,
+                'content' => $a,
+            );
+            $aVars['bx_if:' . $k . '-na'] = array (
+                'condition' => !$a,
+                'content' => array(),
+            );
+        }
+
+        $aVars = array_merge($aVars, $this->mediaVars($aMediaInfo, $CNF['OBJECT_IMAGES_TRANSCODER_BIG'], $CNF['OBJECT_VIDEOS_TRANSCODERS']['poster'], $aParams));
+
+        return $this->parseHtmlByName('media-view.html', $aVars);
+    }
+
+    protected function mediaVars ($aMediaInfo, $sImageTranscoder = false, $sVideoPosterTranscoder = false, $aParams = array())
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
+        $oTranscoder = BxDolTranscoderImage::getObjectInstance($sImageTranscoder);
+        $aTranscodersVideo = false;
+
+        if ($CNF['OBJECT_VIDEOS_TRANSCODERS'])
+            $aTranscodersVideo = array (
+                'poster' => BxDolTranscoderImage::getObjectInstance($sVideoPosterTranscoder),
+                'mp4' => BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4']),
+                'mp4_hd' => BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_VIDEOS_TRANSCODERS']['mp4_hd']),
+            );
+        
+        $aFileInfo = $oStorage->getFile ($aMediaInfo['file_id']);
+        if (!$aFileInfo)
+            return '';
+
+        $isImage = 0 === strncmp('image/', $aFileInfo['mime_type'], 6) && $oTranscoder->isMimeTypeSupported($aFileInfo['mime_type']); // preview for images, transcoder object for preview must be defined
+        $isVideo = $aTranscodersVideo && (0 === strncmp('video/', $aFileInfo['mime_type'], 6)) && $aTranscodersVideo['poster']->isMimeTypeSupported($aFileInfo['mime_type']); // preview for videos, transcoder object for video must be defined
+
+        $sMediaTitle = $this->getMediaTitle($aMediaInfo);
+        $sMediaTitleAttr = bx_html_attribute($sMediaTitle);
+        $mixedContext = isset($aParams['context']) ? $aParams['context'] : '';
+        $sUrl = $this->getViewMediaUrl($CNF, $aMediaInfo['id'], $mixedContext);
+
+        $aTmplVarsImage = array();
+        if($isImage) {
+            $aSize = $aMediaInfo['data'] ? explode('x', $aMediaInfo['data']) : array(0, 0);
+
+            $aTmplVarsImage = array (
+                'title_attr' => $sMediaTitleAttr,
+                'title' => $sMediaTitle,
+                'url' => $sUrl,
+                'url_img' => $oTranscoder ? $oTranscoder->getFileUrl($aFileInfo['id']) : $oStorage->getFileUrlById($aFileInfo['id']),
+                'media_id' => $aMediaInfo['id'],
+                'w' => $aSize[0],
+                'h' => $aSize[1],
+                'context' => $mixedContext,
+            );
+        }
+
+        $aTmplVarsVideo = array();
+        if($isVideo) {
+            $mixedAttrs = false;
+            if(!empty($aParams['autoplay']))
+                $mixedAttrs = array('autoplay' => 'autoplay');
+
+            $iVideoDuration = $oModule->getMediaDuration($aFileInfo);
+            $sVideoDuration = _t_format_duration($iVideoDuration);
+
+            $sVideoUrl = $oStorage->getFileUrlById($aMediaInfo['file_id']);
+            $aVideoSize = $aTranscodersVideo['mp4_hd']->getVideoSize($sVideoUrl);
+
+            $sVideoUrlHd = '';
+            if(!empty($aVideoSize) && is_array($aVideoSize) && (int)$aVideoSize['h'] >= 720)
+                $sVideoUrlHd = $aTranscodersVideo['mp4_hd']->getFileUrl($aMediaInfo['file_id']);
+
+            $aTmplVarsVideo = array (
+                'title_attr' => $sMediaTitleAttr,
+                'title' => $sMediaTitle,
+                'url' => bx_append_url_params($sUrl, array('autoplay' => 1)),
+                'url_img' => $isVideo ? $aTranscodersVideo['poster']->getFileUrl($aMediaInfo['file_id']) : '',
+                'video' => $isVideo && $aTranscodersVideo ? BxTemplFunctions::getInstance()->videoPlayer(
+                    $aTranscodersVideo['poster']->getFileUrl($aMediaInfo['file_id']), 
+                    $aTranscodersVideo['mp4']->getFileUrl($aMediaInfo['file_id']), 
+                    $sVideoUrlHd, $mixedAttrs, 'max-height:' . $CNF['OBJECT_VIDEO_TRANSCODER_HEIGHT']
+                ) : '',
+                'duration' => $sVideoDuration,
+                'bx_if:show_duration' => array(
+                    'condition' => $iVideoDuration > 0,
+                    'content' => array(
+                        'duration' => $sVideoDuration
+                    )
+                )
+            );
+        }
+
+        $aVars = array(
+            'bx_if:image' => array (
+                'condition' => $isImage,
+                'content' => $aTmplVarsImage,
+            ),
+            'bx_if:video' => array (
+                'condition' => $isVideo,
+                'content' => $aTmplVarsVideo,
+            ),
+            'title_attr' => $sMediaTitleAttr,
+            'title' => $sMediaTitle,
+            'url' => $sUrl,
+        );
+
+        return $aVars;
+    }
+
+    public function getViewMediaUrl($CNF, $iMediaId, $sContext = '')
+    {
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_MEDIA'] . '&id=' . $iMediaId . (!empty($sContext) ? '&context=' . $sContext : ''));
+    }
+
+    public function getNextPrevMedia($aMediaInfo, $isNext, $sContext, $aParamsSearchResult = array())
+    {
+        if (!$sContext) {
+            $sContext = 'album';
+            $aParamsSearchResult = array('album_id' => $aMediaInfo['content_id']);
+        }
+
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        bx_import('SearchResultMedia', $oModule->_aModule);
+        $sClass = $oModule->_aModule['class_prefix'] . 'SearchResultMedia';
+        $o = new $sClass($sContext, $aParamsSearchResult);
+        if ($o->isError)
+            return false;
+
+        $o->setUnitParams(array('context' => $sContext));
+
+        $a = $o->getNextPrevItem($aMediaInfo, $isNext);
+    
+        if ($a) {
+
+            $aVars = $this->mediaVars($a, $CNF['OBJECT_IMAGES_TRANSCODER_BIG'], $CNF['OBJECT_VIDEOS_TRANSCODERS']['poster'], array('context' => $sContext));
+            $aMedia = $aVars['bx_if:image']['condition'] ? $aVars['bx_if:image']['content'] : $aVars['bx_if:video']['content'];
+
+            $a['url'] = $aMedia['url'];
+            $a['url_img'] = $aMedia['url_img'];
+            $a['title_attr'] = $aMedia['title_attr'];
+            $a['title_js_string'] = bx_js_string($aMedia['title']);
+            $a['w'] = $aVars['bx_if:image']['condition'] ? $aVars['bx_if:image']['content']['w'] : 0;
+            $a['h'] = $aVars['bx_if:image']['condition'] ? $aVars['bx_if:image']['content']['h'] : 0;
+            $a['html'] = $aVars['bx_if:video']['condition'] ? '<div class="pswp__video">' . $aVars['bx_if:video']['content']['video'] . '</div>': 0;
+        }
+
+        return $a;
+    }
+
+    function entryAttachments ($aData, $aParams = array())
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        return $oModule->_serviceBrowse ('album', array('unit_view' => 'gallery', 'album_id' => $aData[$CNF['FIELD_ID']], 'author' => $aData[$CNF['FIELD_AUTHOR']]), BX_DB_PADDING_DEF, true, true, 'SearchResultMedia');
+    }
+
+    function mediaAuthor ($aMediaInfo, $iProfileId = false, $sFuncAuthorDesc = '', $sTemplateName = '') 
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        if (!($aAlbumInfo = $oModule->_oDb->getContentInfoById($aMediaInfo['content_id'])))
+            return '';
+
+        return $this->entryAuthor ($aMediaInfo, $aAlbumInfo[$CNF['FIELD_AUTHOR']]);
+    }
+
+    function getMediaTitle ($aMediaInfo)
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        if(!empty($aMediaInfo['title'])) {
+            $sText = bx_process_output($aMediaInfo['title']);
+            if(!empty($CNF['OBJECT_METATAGS_MEDIA'])) {
+                $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS_MEDIA']);
+                if($oMetatags && $oMetatags->keywordsIsEnabled())
+                    $sText = $oMetatags->keywordsParse($aMediaInfo['id'], $sText);
+            }
+        }
+        else 
+            $sText = _t('_bx_albums_txt_media_title_empty');
+
+        return $sText;
+    }
+
+    function mediaExif ($aMediaInfo, $iProfileId = false, $sFuncAuthorDesc = '', $sTemplateName = 'media-exif.html') 
+    {
+        if (!$aMediaInfo['exif'])
+            return '';
+
+        $a = unserialize($aMediaInfo['exif']);
+
+        $s = '';
+        if (!empty($a['Make'])) {
+            $oModule = BxDolModule::getInstance($this->MODULE);
+            $CNF = &$oModule->_oConfig->CNF;
+
+            $sCamera = BxDolMetatags::keywordsCameraModel($a);
+            if (!empty($CNF['OBJECT_METATAGS_MEDIA_CAMERA'])) {
+                $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS_MEDIA_CAMERA']);
+                if ($oMetatags->keywordsIsEnabled()) {
+                    $sCamera = $oMetatags->keywordsParseOne($aMediaInfo['id'], $sCamera);
+                }
+            }
+
+            if (!empty($sCamera))
+                $s .= $this->parseHtmlByName('media-exif-value.html', array(
+                    'key' => _t('_bx_albums_txt_media_album_camera'), 
+                    'val' => $sCamera,
+                ));
+        }
+
+        if (!empty($a['FocalLength']))
+            $s .= $this->parseHtmlByName('media-exif-value.html', array(
+                'key' => _t('_bx_albums_txt_media_album_focal_length'),
+                'val' => _t('_bx_albums_txt_media_album_focal_length_value', $a['FocalLength']),
+            ));
+
+        if (!empty($a['COMPUTED']['ApertureFNumber']))
+            $s .= $this->parseHtmlByName('media-exif-value.html', array(
+                'key' => _t('_bx_albums_txt_media_album_aperture'),
+                'val' => $a['COMPUTED']['ApertureFNumber'],
+            ));
+
+        if (!empty($a['ExposureTime']))
+            $s .= $this->parseHtmlByName('media-exif-value.html', array(
+                'key' => _t('_bx_albums_txt_media_album_shutter_speed'),
+                'val' => _t('_bx_albums_txt_media_album_shutter_speed_value', $a['ExposureTime']),
+            ));
+
+        if (!empty($a['ISOSpeedRatings']))
+            $s .= $this->parseHtmlByName('media-exif-value.html', array(
+                'key' => _t('_bx_albums_txt_media_album_iso'),
+                'val' => $a['ISOSpeedRatings'],
+            ));
+
+        if (empty($s))
+            return '';
+
+        return $this->parseHtmlByName($sTemplateName, array('content' => $s));
+    }
+
+}
+
+/** @} */

+ 38 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsUploaderCrop.php

@@ -0,0 +1,38 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAlbumsUploaderCrop extends BxTemplUploaderCrop
+{
+    protected $_oModule;
+
+    public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
+    {
+        parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+        $this->_oModule = BxDolModule::getInstance('bx_albums');
+    }
+
+    protected function getGhostTemplateVars($aFile, $iProfileId, $iContentId, $oStorage, $oImagesTranscoder)
+    {
+        $sTitle = $this->_oModule->_oDb->getFileTitle($aFile['id']);
+        $a = array(
+            'file_title' => $sTitle ? $sTitle : ''
+        );
+        $a['file_title_attr'] = bx_html_attribute($a['file_title']);
+        return $a;
+    }
+
+    protected function isAdmin ($iContentId = 0)
+    {
+        return $this->_oModule->_isModerator (false);
+    }
+}
+
+/** @} */

+ 38 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsUploaderHTML5.php

@@ -0,0 +1,38 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAlbumsUploaderHTML5 extends BxTemplUploaderHTML5
+{
+    protected $_oModule;
+
+    public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
+    {
+        parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+        $this->_oModule = BxDolModule::getInstance('bx_albums');
+    }
+
+    protected function getGhostTemplateVars($aFile, $iProfileId, $iContentId, $oStorage, $oImagesTranscoder)
+    {
+        $sTitle = $this->_oModule->_oDb->getFileTitle($aFile['id']);
+        $a = array(
+            'file_title' => $sTitle ? $sTitle : ''
+        );
+        $a['file_title_attr'] = bx_html_attribute($a['file_title']);
+        return $a;
+    }
+
+    protected function isAdmin ($iContentId = 0)
+    {
+        return $this->_oModule->_isModerator (false);
+    }
+}
+
+/** @} */

+ 38 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/classes/BxAlbumsUploaderSimple.php

@@ -0,0 +1,38 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAlbumsUploaderSimple extends BxTemplUploaderSimple
+{
+    protected $_oModule;
+
+    public function __construct ($aObject, $sStorageObject, $sUniqId, $oTemplate)
+    {
+        parent::__construct($aObject, $sStorageObject, $sUniqId, $oTemplate);
+        $this->_oModule = BxDolModule::getInstance('bx_albums');
+    }
+
+    protected function getGhostTemplateVars($aFile, $iProfileId, $iContentId, $oStorage, $oImagesTranscoder)
+    {
+        $sTitle = $this->_oModule->_oDb->getFileTitle($aFile['id']);
+        $a = array(
+            'file_title' => $sTitle ? $sTitle : ''
+        );
+        $a['file_title_attr'] = bx_html_attribute($a['file_title']);
+        return $a;
+    }
+
+    protected function isAdmin ($iContentId = 0)
+    {
+        return $this->_oModule->_isModerator (false);
+    }
+}
+
+/** @} */

+ 143 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/install/config.php

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

+ 271 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/install/langs/en.xml

@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_albums"><![CDATA[Albums]]></string>
+	<string name="_bx_albums_cmts"><![CDATA[Albums' Comments]]></string>
+	<string name="_bx_albums_media"><![CDATA[Images]]></string>
+	<string name="_bx_albums_media_cmts"><![CDATA[Images' Comments]]></string>
+
+	<string name="_bx_albums_option_summary_chars"><![CDATA[Number of characters in auto-cropped album summary]]></string>
+	<string name="_bx_albums_option_plain_summary_chars"><![CDATA[Number of characters in plain album description when album hasn't thumb]]></string>
+	<string name="_bx_albums_option_per_page_browse"><![CDATA[Number of items per page]]></string>
+	<string name="_bx_albums_option_per_page_profile"><![CDATA[Number of items on profile page]]></string>
+	<string name="_bx_albums_option_album_browsing_unit"><![CDATA[Number of items in album card]]></string>
+	<string name="_bx_albums_option_rss_num"><![CDATA[Number of items in RSS feed]]></string>
+	<string name="_bx_albums_option_searchable_fields"><![CDATA[Searchable fields for keyword search]]></string>
+
+	<string name="_bx_albums_form_entry"><![CDATA[Albums]]></string>
+	<string name="_bx_albums_form_entry_display_add"><![CDATA[Add Album]]></string>
+    <string name="_bx_albums_form_entry_display_edit"><![CDATA[Edit Album]]></string>
+	<string name="_bx_albums_form_entry_display_add_images"><![CDATA[Add Images To Album]]></string>
+	<string name="_bx_albums_form_entry_display_delete"><![CDATA[Delete Album]]></string>
+	<string name="_bx_albums_form_entry_display_view"><![CDATA[View Album]]></string>
+	<string name="_bx_albums_form_entry_input_author"><![CDATA[Author]]></string>
+	<string name="_bx_albums_form_entry_input_sys_do_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_albums_form_entry_input_do_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_albums_form_entry_input_sys_title"><![CDATA[Caption]]></string>
+	<string name="_bx_albums_form_entry_input_title"><![CDATA[Caption]]></string>
+	<string name="_bx_albums_form_entry_input_title_err"><![CDATA[Caption is essential. Please, fill in this field]]></string>
+	<string name="_bx_albums_form_entry_input_sys_text"><![CDATA[Album Description]]></string>
+	<string name="_bx_albums_form_entry_input_text"><![CDATA[Album Description]]></string>
+	<string name="_bx_albums_form_entry_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+	<string name="_bx_albums_form_entry_input_delete_confirm"><![CDATA[I am sure I want to delete this album]]></string>
+	<string name="_bx_albums_form_entry_input_delete_confirm_info"><![CDATA[This action can not be undone]]></string>
+	<string name="_bx_albums_form_entry_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete the album]]></string>
+	<string name="_bx_albums_form_entry_input_sys_pictures"><![CDATA[Pictures]]></string>
+	<string name="_bx_albums_form_entry_input_pictures"><![CDATA[Pictures]]></string>
+    <string name="_bx_albums_form_entry_input_sys_allow_view_to"><![CDATA[Visibility]]></string>
+    <string name="_bx_albums_form_entry_input_allow_view_to"><![CDATA[Visibility]]></string>
+    <string name="_bx_albums_form_entry_file_title"><![CDATA[Caption]]></string>
+	<string name="_bx_albums_form_entry_input_sys_date_added"><![CDATA[Created]]></string>
+	<string name="_bx_albums_form_entry_input_date_added"><![CDATA[Created]]></string>
+	<string name="_bx_albums_form_entry_input_sys_date_changed"><![CDATA[Updated]]></string>
+    <string name="_bx_albums_form_entry_input_date_changed"><![CDATA[Updated]]></string>
+
+        <string name="_bx_albums_form_media"><![CDATA[Medias]]></string>
+        <string name="_bx_albums_form_media_display_edit"><![CDATA[Edit Media]]></string>
+        <string name="_bx_albums_form_media_input_sys_title"><![CDATA[Caption]]></string>
+	<string name="_bx_albums_form_media_input_title"><![CDATA[Caption]]></string>
+        <string name="_bx_albums_form_media_input_sys_do_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_albums_form_media_input_do_submit"><![CDATA[Submit]]></string>
+        <string name="_bx_albums_form_media_input_sys_do_cancel"><![CDATA[Cancel]]></string>
+	<string name="_bx_albums_form_media_input_do_cancel"><![CDATA[Cancel]]></string>
+
+	<string name="_bx_albums_acl_action_create_entry"><![CDATA[Create Album]]></string>
+	<string name="_bx_albums_acl_action_delete_entry"><![CDATA[Delete Album]]></string>
+	<string name="_bx_albums_acl_action_view_entry"><![CDATA[View Album]]></string>
+	<string name="_bx_albums_acl_action_set_thumb"><![CDATA[Set Album Cover]]></string>
+	<string name="_bx_albums_acl_action_edit_any_entry"><![CDATA[Edit Any Album]]></string>
+
+	<string name="_bx_albums_page_title_sys_create_entry"><![CDATA[New Album]]></string>
+	<string name="_bx_albums_page_title_create_entry"><![CDATA[New Album]]></string>
+	<string name="_bx_albums_page_block_title_create_entry"><![CDATA[New Album]]></string>
+	<string name="_bx_albums_page_title_sys_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_albums_page_title_edit_entry"><![CDATA[Edit]]></string>
+	<string name="_bx_albums_page_title_sys_add_images"><![CDATA[Add/Edit Pictures]]></string>
+	<string name="_bx_albums_page_title_add_images"><![CDATA[Add/Edit Pictures]]></string>
+    <string name="_bx_albums_page_block_title_edit_entry"><![CDATA[Edit]]></string>
+	<string name="_bx_albums_page_block_title_add_images"><![CDATA[Add/Edit Pictures]]></string>
+    <string name="_bx_albums_page_title_sys_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_albums_page_title_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_albums_page_block_title_delete_entry"><![CDATA[Delete]]></string>
+	<string name="_bx_albums_page_title_sys_view_entry"><![CDATA[View Album]]></string>
+	<string name="_bx_albums_page_title_view_entry"><![CDATA[{title}]]></string>
+	<string name="_bx_albums_page_title_sys_view_media"><![CDATA[View Image]]></string>
+	<string name="_bx_albums_page_title_view_media"><![CDATA[{title}]]></string>
+	<string name="_bx_albums_page_block_title_entry_view_media"><![CDATA[View Image]]></string>
+	<string name="_bx_albums_page_block_title_entry_view_media_exif"><![CDATA[EXIF]]></string>
+	<string name="_bx_albums_page_block_title_entry_attachments"><![CDATA[Attachments]]></string>
+	<string name="_bx_albums_page_block_title_entry_text"><![CDATA[Album Description]]></string>
+	<string name="_bx_albums_page_title_browse"><![CDATA[Albums]]></string>
+	<string name="_bx_albums_page_title_search_results"><![CDATA[Albums matching "{0}"]]></string>
+	<string name="_bx_albums_page_title_browse_by_author"><![CDATA[{display_name}'s Albums]]></string>
+  <string name="_bx_albums_page_title_browse_by_context"><![CDATA[Albums in {display_name}]]></string>
+	<string name="_bx_albums_page_title_browse_featured"><![CDATA[Featured Albums]]></string>
+	<string name="_bx_albums_page_title_browse_featured_media"><![CDATA[Featured Media]]></string>
+    <string name="_bx_albums_page_title_browse_recent"><![CDATA[Latest Albums]]></string>
+    <string name="_bx_albums_page_title_browse_popular"><![CDATA[Popular Albums]]></string>
+    <string name="_bx_albums_page_title_browse_popular_media"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_page_title_browse_recent_media"><![CDATA[Recent Images]]></string>
+    <string name="_bx_albums_page_title_browse_media_in_album"><![CDATA[Images]]></string>
+    <string name="_bx_albums_page_title_browse_updated"><![CDATA[Updated Albums]]></string>
+    <string name="_bx_albums_page_title_sys_home"><![CDATA[Albums Home]]></string>
+    <string name="_bx_albums_page_title_home"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_page_block_title_featured_entries_view_extended"><![CDATA[Featured Albums]]></string>
+    <string name="_bx_albums_page_block_title_featured_entries_view_gallery_media"><![CDATA[Featured Media]]></string>
+    <string name="_bx_albums_page_block_title_recent_entries"><![CDATA[Latest Albums]]></string>
+    <string name="_bx_albums_page_block_title_entry_all_actions"><![CDATA[All Actions]]></string>
+    <string name="_bx_albums_page_block_title_entry_social_sharing"><![CDATA[Share]]></string>
+    <string name="_bx_albums_page_block_title_entry_author"><![CDATA[Author]]></string>
+    <string name="_bx_albums_page_block_title_entry_info"><![CDATA[Info]]></string>
+    <string name="_bx_albums_page_block_title_entry_actions"><![CDATA[Actions]]></string>
+    <string name="_bx_albums_page_block_title_entry_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_albums_page_block_title_entry_comments_link"><![CDATA[Comments to <a href="{entry_link}">{title}</a>]]></string>
+    <string name="_bx_albums_page_block_title_entry_location"><![CDATA[Location]]></string>
+    <string name="_bx_albums_page_title_sys_entries_popular"><![CDATA[Popular]]></string>
+    <string name="_bx_albums_page_title_entries_popular"><![CDATA[Popular]]></string>
+    <string name="_bx_albums_page_title_sys_entries_popular_media"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_page_title_entries_popular_media"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_page_block_title_popular_entries"><![CDATA[Popular]]></string>
+    <string name="_bx_albums_page_block_title_popular_media"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_page_block_title_recent_media"><![CDATA[Recent Images]]></string>
+    <string name="_bx_albums_page_block_title_updated_entries"><![CDATA[Updated Albums]]></string>
+    <string name="_bx_albums_page_title_sys_view_entry_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_albums_page_title_view_entry_comments"><![CDATA[Comments to {title}]]></string>
+    <string name="_bx_albums_page_title_sys_entries_of_author"><![CDATA[Albums of author]]></string>
+    <string name="_bx_albums_page_title_entries_of_author"><![CDATA[{display_name}'s albums]]></string>
+    <string name="_bx_albums_page_title_sys_entries_in_context"><![CDATA[Albums in context]]></string>
+    <string name="_bx_albums_page_title_entries_in_context"><![CDATA[Albums in {display_name}]]></string>
+    <string name="_bx_albums_page_block_title_favorites_of_author"><![CDATA[Favorite albums by <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_albums_page_block_title_sys_favorites_of_author"><![CDATA[Favorite albums of author]]></string>
+    <string name="_bx_albums_page_block_title_favorites_of_author_media"><![CDATA[Favorite media by <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_albums_page_block_title_sys_favorites_of_author_media"><![CDATA[Favorite media of author]]></string>
+    <string name="_bx_albums_page_block_title_entries_of_author"><![CDATA[Albums by <a href="{profile_link}">{display_name}</a>]]></string>   
+    <string name="_bx_albums_page_block_title_sys_entries_of_author"><![CDATA[Albums of author]]></string>
+    <string name="_bx_albums_page_block_title_entries_in_context"><![CDATA[Albums in <a href="{profile_link}">{display_name}</a>]]></string>
+    <string name="_bx_albums_page_block_title_sys_entries_in_context"><![CDATA[Albums in context]]></string>
+    <string name="_bx_albums_page_block_title_entries_actions"><![CDATA[Albums actions]]></string>
+    <string name="_bx_albums_page_block_title_browse_cmts"><![CDATA[Albums' Comments]]></string>
+    <string name="_bx_albums_page_block_title_browse_cmts_media"><![CDATA[Images Comments]]></string>
+	<string name="_bx_albums_page_title_sys_manage"><![CDATA[Manage Own Albums]]></string>
+	<string name="_bx_albums_page_title_sys_manage_administration"><![CDATA[Manage All Albums]]></string>
+	<string name="_bx_albums_page_title_manage"><![CDATA[Manage]]></string>
+	<string name="_bx_albums_page_block_title_system_manage"><![CDATA[Manage Own Albums]]></string>
+	<string name="_bx_albums_page_block_title_system_manage_administration"><![CDATA[Manage All Albums]]></string>  
+	<string name="_bx_albums_page_block_title_manage"><![CDATA[Manage]]></string>
+	<string name="_bx_albums_page_block_title_popular_keywords_albums"><![CDATA[Popular Albums Hashtags]]></string>
+	<string name="_bx_albums_page_block_title_popular_keywords_media"><![CDATA[Popular Media Hashtags]]></string>
+	<string name="_bx_albums_page_block_title_popular_keywords_media_camera"><![CDATA[Popular Cameras]]></string>
+	<string name="_bx_albums_page_block_title_my_entries"><![CDATA[My Albums]]></string>
+  	<string name="_bx_albums_page_title_sys_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_albums_page_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_albums_page_block_title_search_form"><![CDATA[Search Form]]></string>
+    <string name="_bx_albums_page_block_title_search_results"><![CDATA[Search Results]]></string>
+    <string name="_bx_albums_page_block_title_search_form_media"><![CDATA[Images Search Form]]></string>
+    <string name="_bx_albums_page_block_title_search_results_media"><![CDATA[Images Search Results]]></string>
+    <string name="_bx_albums_page_block_title_search_form_cmts"><![CDATA[Comments Search Form]]></string>
+    <string name="_bx_albums_page_block_title_search_results_cmts"><![CDATA[Comments Search Results]]></string>
+    <string name="_bx_albums_page_block_title_search_form_media_cmts"><![CDATA[Images Comments Search Form]]></string>
+    <string name="_bx_albums_page_block_title_search_results_media_cmts"><![CDATA[Images Comments Search Results]]></string>
+    <string name="_bx_albums_page_block_title_sys_recent_media_view_showcase"><![CDATA[Recent Images (Showcase View)]]></string>
+    <string name="_bx_albums_page_block_title_recent_media_view_showcase"><![CDATA[Recent Images]]></string>
+    <string name="_bx_albums_page_block_title_sys_popular_media_view_showcase"><![CDATA[Top Images (Showcase View)]]></string>
+    <string name="_bx_albums_page_block_title_popular_media_view_showcase"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_page_block_title_sys_featured_media_view_showcase"><![CDATA[Featured Images (Showcase View)]]></string>
+    <string name="_bx_albums_page_block_title_featured_media_view_showcase"><![CDATA[Featured Images]]></string>
+	<string name="_bx_albums_page_block_title_sys_entry_context"><![CDATA[Posted in]]></string>
+  	<string name="_bx_albums_page_block_title_entry_context"><![CDATA[Posted in]]></string>
+
+    <string name="_bx_albums_menu_set_title_view_entry"><![CDATA[Album Actions]]></string>
+    <string name="_bx_albums_menu_title_view_entry"><![CDATA[Album Actions]]></string>
+    <string name="_bx_albums_menu_set_title_view_media"><![CDATA[Media Actions]]></string>
+    <string name="_bx_albums_menu_title_view_media"><![CDATA[Media Actions]]></string>
+    <string name="_bx_albums_menu_set_title_view_actions_media"><![CDATA[Media All Actions]]></string>
+    <string name="_bx_albums_menu_title_view_actions_media"><![CDATA[Media All Actions]]></string>
+    <string name="_bx_albums_menu_set_title_view_actions_media_unit"><![CDATA[Media Card Actions]]></string>
+    <string name="_bx_albums_menu_title_view_actions_media_unit"><![CDATA[Media Card Actions]]></string>
+    <string name="_bx_albums_menu_title_submenu"><![CDATA[Albums Submenu]]></string>
+    <string name="_bx_albums_menu_set_title_submenu"><![CDATA[Albums Submenu]]></string>
+    <string name="_bx_albums_menu_item_title_system_create_entry"><![CDATA[Album]]></string>
+    <string name="_bx_albums_menu_item_title_create_entry"><![CDATA[Album]]></string>
+    <string name="_bx_albums_menu_item_title_system_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_albums_menu_item_title_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_albums_menu_item_title_system_edit_album"><![CDATA[Edit Album]]></string>
+    <string name="_bx_albums_menu_item_title_edit_album"><![CDATA[Edit Album]]></string>
+    <string name="_bx_albums_menu_item_title_system_add_images"><![CDATA[Add/Edit Pictures]]></string>
+    <string name="_bx_albums_menu_item_title_add_images"><![CDATA[Add/Edit Pictures]]></string>
+    <string name="_bx_albums_menu_item_title_system_edit_image"><![CDATA[Edit Image]]></string>
+    <string name="_bx_albums_menu_item_title_edit_image"><![CDATA[Edit Image]]></string>
+    <string name="_bx_albums_menu_item_title_system_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_albums_menu_item_title_delete_entry"><![CDATA[Delete]]></string>
+    <string name="_bx_albums_menu_item_title_system_view_entry"><![CDATA[View Album]]></string>
+    <string name="_bx_albums_menu_item_title_system_entries_home"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_item_title_entries_home"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_item_title_system_entries_recent"><![CDATA[Latest]]></string>
+    <string name="_bx_albums_menu_item_title_entries_recent"><![CDATA[Latest]]></string>
+    <string name="_bx_albums_menu_item_title_system_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_albums_menu_item_title_entries_search"><![CDATA[Search]]></string>
+    <string name="_bx_albums_menu_item_title_system_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_albums_menu_item_title_entries_manage"><![CDATA[Manage]]></string>
+    <string name="_bx_albums_menu_item_title_system_entries_popular"><![CDATA[Popular]]></string>
+    <string name="_bx_albums_menu_item_title_entries_popular"><![CDATA[Popular]]></string>
+    <string name="_bx_albums_menu_item_title_system_entries_popular_media"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_menu_item_title_entries_popular_media"><![CDATA[Top Images]]></string>
+    <string name="_bx_albums_menu_title_view_entry_submenu"><![CDATA[View Album Submenu]]></string>
+    <string name="_bx_albums_menu_set_title_view_entry_submenu"><![CDATA[View Album Submenu]]></string>
+    <string name="_bx_albums_menu_item_title_view_entry_submenu_entry"><![CDATA[Album]]></string>
+    <string name="_bx_albums_menu_item_title_view_entry_submenu_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_albums_menu_item_title_system_view_entry_comments"><![CDATA[Comments]]></string>
+    <string name="_bx_albums_menu_item_title_system_view_entries_author"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_item_title_view_entries_author"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_item_title_system_view_entries_in_context"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_item_title_view_entries_in_context"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_title_entries_my"><![CDATA[My Albums Action Menu]]></string>
+    <string name="_bx_albums_menu_set_title_entries_my"><![CDATA[My Albums Menu]]></string>
+	<string name="_bx_albums_menu_item_title_system_manage_my_albums"><![CDATA[My albums]]></string>
+    <string name="_bx_albums_menu_item_title_manage_my_albums"><![CDATA[Albums]]></string>
+    <string name="_bx_albums_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+    <string name="_bx_albums_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+	<string name="_bx_albums_menu_item_title_system_admt_albums"><![CDATA[Albums]]></string>
+	<string name="_bx_albums_menu_item_title_admt_albums"><![CDATA[Albums]]></string>
+	<string name="_bx_albums_menu_item_title_manage_my"><![CDATA[My Albums]]></string>
+	<string name="_bx_albums_menu_item_title_manage_all"><![CDATA[All Albums]]></string>
+        <string name="_bx_albums_menu_item_title_system_sm_items"><![CDATA[Items]]></string>
+        <string name="_bx_albums_menu_item_title_sm_items"><![CDATA[{0} items]]></string>
+
+	<string name="_bx_albums_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+	<string name="_bx_albums_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+	<string name="_bx_albums_grid_filter_item_title_adm_hidden"><![CDATA[Hidden]]></string>
+	<string name="_bx_albums_grid_column_title_adm_active"><![CDATA[Active]]></string>
+    <string name="_bx_albums_grid_column_title_adm_title"><![CDATA[Caption]]></string>
+    <string name="_bx_albums_grid_column_title_adm_added"><![CDATA[Added]]></string>
+    <string name="_bx_albums_grid_column_title_adm_author"><![CDATA[Author]]></string>
+    <string name="_bx_albums_grid_action_title_adm_edit"><![CDATA[Edit]]></string>
+    <string name="_bx_albums_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_albums_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+    <string name="_bx_albums_grid_action_err_delete"><![CDATA[Cannot delete the selected album(s).]]></string>
+    <string name="_bx_albums_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+
+    <string name="_bx_albums_chart_growth"><![CDATA[Albums: Growth]]></string>
+    <string name="_bx_albums_chart_growth_speed"><![CDATA[Albums: Growth Speed]]></string>
+    <string name="_bx_albums_chart_growth_media"><![CDATA[Images: Growth]]></string>
+    <string name="_bx_albums_chart_growth_speed_media"><![CDATA[Images: Growth Speed]]></string>
+
+    <string name="_bx_albums_search_extended"><![CDATA[Albums Search]]></string>
+    <string name="_bx_albums_search_extended_media"><![CDATA[Images Search]]></string>
+    <string name="_bx_albums_search_extended_cmts"><![CDATA[Albums Comments Search]]></string>
+    <string name="_bx_albums_search_extended_media_cmts"><![CDATA[Images Comments Search]]></string>
+
+    <string name="_bx_albums_txt_all_entries_by"><![CDATA[<a href="{0}">All Albums by {1} ({2})</a>]]></string>
+    <string name="_bx_albums_txt_all_entries_in"><![CDATA[<a href="{0}">All Albums in {1} ({2})</a>]]></string>
+    <string name="_bx_albums_txt_sample_single"><![CDATA[album]]></string>
+    <string name="_bx_albums_txt_sample_single_with_article"><![CDATA[an album]]></string>
+    <string name="_bx_albums_txt_sample_comment_single"><![CDATA[comment to album]]></string>
+    <string name="_bx_albums_txt_sample_vote_single"><![CDATA[vote to album]]></string>
+    <string name="_bx_albums_txt_sample_score_up_single"><![CDATA[score up vote to album]]></string>
+    <string name="_bx_albums_txt_sample_score_down_single"><![CDATA[score down vote to album]]></string>
+    <string name="_bx_albums_txt_sample_action_changed"><![CDATA[changed {0}]]></string>
+    <string name="_bx_albums_txt_media_single"><![CDATA[image]]></string>
+    <string name="_bx_albums_txt_media_comment_single"><![CDATA[image's comment]]></string>
+    <string name="_bx_albums_txt_media_vote_single"><![CDATA[image's vote]]></string>
+    <string name="_bx_albums_txt_media_score_up_single"><![CDATA[image's score up vote]]></string>
+    <string name="_bx_albums_txt_media_score_down_single"><![CDATA[image's score down vote]]></string>
+    <string name="_bx_albums_txt_media_title_alt"><![CDATA[{0}'s media]]></string>
+    <string name="_bx_albums_txt_media_title_empty"><![CDATA[No Caption]]></string>
+    <string name="_bx_albums_txt_media_album_link"><![CDATA[<a href="{0}">{1}</a> album by <a href="{2}">{3}</a>]]></string>
+    <string name="_bx_albums_txt_media_album_camera"><![CDATA[Camera]]></string>
+    <string name="_bx_albums_txt_media_album_focal_length"><![CDATA[Focal length]]></string>
+    <string name="_bx_albums_txt_media_album_focal_length_value"><![CDATA[{0}mm]]></string>
+    <string name="_bx_albums_txt_media_album_aperture"><![CDATA[Aperture]]></string>
+    <string name="_bx_albums_txt_media_album_shutter_speed"><![CDATA[Exposure time]]></string>
+    <string name="_bx_albums_txt_media_album_shutter_speed_value"><![CDATA[{0}s]]></string>
+    <string name="_bx_albums_txt_media_album_iso"><![CDATA[ISO]]></string>
+    <string name="_bx_albums_txt_processing_awaiting"><![CDATA[Scheduled for publishing as soon as video conversion is complete.]]></string>
+    <string name="_bx_albums_txt_processing_failed"><![CDATA[Album isn't published because video conversion failed, edit video to fix the issue.]]></string>
+
+    <string name="_bx_albums_txt_err_cannot_perform_action"><![CDATA[Cannot perform the action. Please report.]]></string>
+
+    <string name="_bx_albums_alert_action_medias_added"><![CDATA[add images]]></string>
+    <string name="_bx_albums_alert_action_medias_added_follow_member"><![CDATA[New media]]></string>
+    <string name="_bx_albums_alert_action_medias_added_follow_context"><![CDATA[New media]]></string>
+</resources>

+ 511 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/install/sql/enable.sql

@@ -0,0 +1,511 @@
+
+-- 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_albums', '_bx_albums', 'bx_albums@modules/boonex/albums/|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_albums', '_bx_albums', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_albums_summary_chars', '700', @iCategId, '_bx_albums_option_summary_chars', 'digit', '', '', '', 1),
+('bx_albums_plain_summary_chars', '200', @iCategId, '_bx_albums_option_plain_summary_chars', 'digit', '', '', '', 2),
+('bx_albums_per_page_browse', '12', @iCategId, '_bx_albums_option_per_page_browse', 'digit', '', '', '', 10),
+('bx_albums_per_page_profile', '6', @iCategId, '_bx_albums_option_per_page_profile', 'digit', '', '', '', 12),
+('bx_albums_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 15),
+('bx_albums_album_browsing_unit', '10', @iCategId, '_bx_albums_option_album_browsing_unit', 'digit', '', '', '', 20),
+('bx_albums_rss_num', '10', @iCategId, '_bx_albums_option_rss_num', 'digit', '', '', '', 20),
+('bx_albums_searchable_fields', 'title,text', @iCategId, '_bx_albums_option_searchable_fields', 'list', '', '', 'a:2:{s:6:"module";s:9:"bx_albums";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_albums_create_entry', '_bx_albums_page_title_sys_create_entry', '_bx_albums_page_title_create_entry', 'bx_albums', 5, 2147483647, 1, 'create-album', 'page.php?i=create-album', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowse', 'modules/boonex/albums/classes/BxAlbumsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_albums_create_entry', 1, 'bx_albums', '_bx_albums_page_block_title_create_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_albums";s:6:"method";s:13:"entity_create";}', 0, 1, 1);
+
+-- PAGE: add images
+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_albums_add_images', '_bx_albums_page_title_sys_add_images', '_bx_albums_page_title_add_images', 'bx_albums', 5, 2147483647, 1, 'add-images', '', '', '', '', 0, 1, 0, 'BxAlbumsPageEntry', 'modules/boonex/albums/classes/BxAlbumsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_albums_add_images', 1, 'bx_albums', '_bx_albums_page_block_title_add_images', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_albums";s:6:"method";s:16:"entity_add_files";}', 0, 0, 0);
+
+-- 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_albums_edit_entry', '_bx_albums_page_title_sys_edit_entry', '_bx_albums_page_title_edit_entry', 'bx_albums', 5, 2147483647, 1, 'edit-album', '', '', '', '', 0, 1, 0, 'BxAlbumsPageEntry', 'modules/boonex/albums/classes/BxAlbumsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_albums_edit_entry', 1, 'bx_albums', '_bx_albums_page_block_title_edit_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_albums";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_albums_delete_entry', '_bx_albums_page_title_sys_delete_entry', '_bx_albums_page_title_delete_entry', 'bx_albums', 5, 2147483647, 1, 'delete-album', '', '', '', '', 0, 1, 0, 'BxAlbumsPageEntry', 'modules/boonex/albums/classes/BxAlbumsPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_albums_delete_entry', 1, 'bx_albums', '_bx_albums_page_block_title_delete_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_albums";s:6:"method";s:13:"entity_delete";}', 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_albums_view_entry', '_bx_albums_page_title_sys_view_entry', '_bx_albums_page_title_view_entry', 'bx_albums', 12, 2147483647, 1, 'view-album', '', '', '', '', 0, 1, 0, 'BxAlbumsPageEntry', 'modules/boonex/albums/classes/BxAlbumsPageEntry.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_albums_view_entry', 2, 'bx_albums','' , '_bx_albums_page_block_title_entry_text', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:17:\"entity_text_block\";}', 0, 0, 1, 1),
+('bx_albums_view_entry', 2, 'bx_albums','' , '_bx_albums_page_block_title_entry_attachments', 0, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:18:\"entity_attachments\";}', 0, 0, 1, 3),
+('bx_albums_view_entry', 4, 'bx_albums','' , '_bx_albums_page_block_title_entry_social_sharing', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:21:\"entity_social_sharing\";}', 0, 0, 0, 0),
+('bx_albums_view_entry', 2, 'bx_albums','' , '_bx_albums_page_block_title_entry_comments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 1, 4),
+('bx_albums_view_entry', 3, 'bx_albums','' , '_bx_albums_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_albums\";i:1;s:4:\"{id}\";}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', 0, 0, 1, 4),
+('bx_albums_view_entry', 3, 'bx_albums','' , '_bx_albums_page_block_title_entry_author', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:13:\"entity_author\";}', 0, 0, 1, 2),
+('bx_albums_view_entry', 3, 'bx_albums', '_bx_albums_page_block_title_sys_entry_context', '_bx_albums_page_block_title_entry_context', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:14:\"entity_context\";}', 0, 0, 1, 1),
+('bx_albums_view_entry', 3, 'bx_albums','' , '_bx_albums_page_block_title_entry_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:11:\"entity_info\";}', 0, 0, 1, 3),
+('bx_albums_view_entry', 3, 'bx_albums', '', '_bx_albums_page_block_title_entry_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:14:\"entity_actions\";}', 0, 0, 0, 0),
+('bx_albums_view_entry', 2, 'bx_albums','' , '_bx_albums_page_block_title_entry_all_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:18:\"entity_all_actions\";}', 0, 0, 1, 2);
+
+-- PAGE: view media
+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_albums_view_media', 'view-album-media', '_bx_albums_page_title_sys_view_media', '_bx_albums_page_title_view_media', 'bx_albums', 12, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxAlbumsPageMedia', 'modules/boonex/albums/classes/BxAlbumsPageMedia.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_albums_view_media', 2, 'bx_albums', '', '_bx_albums_page_block_title_entry_view_media', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:10:\"media_view\";}', 0, 0, 1, 1),
+('bx_albums_view_media', 3, 'bx_albums', '', '_bx_albums_page_block_title_entry_author', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:12:\"media_author\";}', 0, 0, 1, 1),
+('bx_albums_view_media', 3, 'bx_albums', '', '_bx_albums_page_block_title_entry_social_sharing', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:20:\"media_social_sharing\";}', 0, 0, 0, 0),
+('bx_albums_view_media', 2, 'bx_albums', '', '_bx_albums_page_block_title_entry_comments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:14:\"media_comments\";}', 0, 0, 1, 3),
+('bx_albums_view_media', 3, 'bx_albums', '', '_bx_albums_page_block_title_entry_view_media_exif', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:10:\"media_exif\";}', 0, 0, 1, 2),
+('bx_albums_view_media', 3, 'bx_albums', '', '_bx_albums_page_block_title_entry_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:13:\"media_actions\";}', 0, 0, 0, 0),
+('bx_albums_view_media', 2, 'bx_albums', '', '_bx_albums_page_block_title_entry_all_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:17:\"media_all_actions\";}', 0, 0, 1, 2),
+('bx_albums_view_media', 3, 'bx_albums', '', '_bx_albums_page_block_title_featured_entries_view_gallery_media', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:21:"browse_featured_media";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 1, 3);
+
+-- 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_albums_view_entry_comments', '_bx_albums_page_title_sys_view_entry_comments', '_bx_albums_page_title_view_entry_comments', 'bx_albums', 5, 2147483647, 1, 'view-album-comments', '', '', '', '', 0, 1, 0, 'BxAlbumsPageEntry', 'modules/boonex/albums/classes/BxAlbumsPageEntry.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_albums_view_entry_comments', 1, 'bx_albums', '_bx_albums_page_block_title_entry_comments', '_bx_albums_page_block_title_entry_comments_link', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 1);
+
+-- PAGE: popular albums
+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_albums_popular', '_bx_albums_page_title_sys_entries_popular', '_bx_albums_page_title_entries_popular', 'bx_albums', 5, 2147483647, 1, 'albums-popular', 'page.php?i=albums-popular', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowse', 'modules/boonex/albums/classes/BxAlbumsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_albums_popular', 1, 'bx_albums', '_bx_albums_page_block_title_popular_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";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, 1, 1);
+
+-- PAGE: popular media
+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_albums_popular_media', '_bx_albums_page_title_sys_entries_popular_media', '_bx_albums_page_title_entries_popular_media', 'bx_albums', 5, 2147483647, 1, 'albums-popular-media', 'page.php?i=albums-popular-media', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowseMedia', 'modules/boonex/albums/classes/BxAlbumsPageBrowseMedia.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_albums_popular_media', 1, 'bx_albums', '_bx_albums_page_block_title_popular_media', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:20:"browse_popular_media";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, 1, 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_albums_author', 'albums-author', '_bx_albums_page_title_sys_entries_of_author', '_bx_albums_page_title_entries_of_author', 'bx_albums', 5, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxAlbumsPageAuthor', 'modules/boonex/albums/classes/BxAlbumsPageAuthor.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_albums_author', 1, 'bx_albums', '', '_bx_albums_page_block_title_entries_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:18:\"my_entries_actions\";}', 0, 0, 1, 1),
+('bx_albums_author', 1, 'bx_albums', '_bx_albums_page_block_title_sys_favorites_of_author', '_bx_albums_page_block_title_favorites_of_author', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:15:\"browse_favorite\";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 1, 1, 2),
+('bx_albums_author', 1, 'bx_albums', '_bx_albums_page_block_title_sys_favorites_of_author_media', '_bx_albums_page_block_title_favorites_of_author_media', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:21:\"browse_favorite_media\";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 1, 1, 3),
+('bx_albums_author', 1, 'bx_albums', '_bx_albums_page_block_title_sys_entries_of_author', '_bx_albums_page_block_title_entries_of_author', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:13:\"browse_author\";}', 0, 0, 1, 4);
+
+-- 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_albums_context', 'albums-context', '_bx_albums_page_title_sys_entries_in_context', '_bx_albums_page_title_entries_in_context', 'bx_albums', 5, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxAlbumsPageAuthor', 'modules/boonex/albums/classes/BxAlbumsPageAuthor.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_albums_context', 1, 'bx_albums', '_bx_albums_page_block_title_sys_entries_in_context', '_bx_albums_page_block_title_entries_in_context', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";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_albums_home', 'albums-home', '_bx_albums_page_title_sys_home', '_bx_albums_page_title_home', 'bx_albums', 2, 2147483647, 1, 'page.php?i=albums-home', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowse', 'modules/boonex/albums/classes/BxAlbumsPageBrowse.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_albums_home', 1, 'bx_albums', '', '_bx_albums_page_block_title_featured_entries_view_extended', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{i:0;s:8:"extended";}}', 0, 1, 1, 0),
+('bx_albums_home', 1, 'bx_albums', '', '_bx_albums_page_block_title_featured_entries_view_gallery_media', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:21:"browse_featured_media";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 1, 1),
+('bx_albums_home', 1, 'bx_albums', '', '_bx_albums_page_block_title_updated_entries', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:9:\"bx_albums\";s:6:\"method\";s:14:\"browse_updated\";s:6:\"params\";a:3:{s:9:\"unit_view\";s:8:\"extended\";s:13:\"empty_message\";b:1;s:13:\"ajax_paginate\";b:0;}}', 0, 1, 1, 2),
+('bx_albums_home', 2, 'bx_albums', '', '_bx_albums_page_block_title_popular_keywords_albums', 11, 2147483647, 'service', 'a:4:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:14:\"keywords_cloud\";s:6:\"params\";a:3:{i:0;s:9:\"bx_albums\";i:1;s:9:\"bx_albums\";i:2;a:1:{s:10:\"show_empty\";b:1;}}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', 1, 0, 1, 0),
+('bx_albums_home', 2, 'bx_albums', '', '_bx_albums_page_block_title_popular_keywords_media', 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:15:\"bx_albums_media\";i:1;s:15:\"bx_albums_media\";}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', 1, 0, 1, 1),
+('bx_albums_home', 2, 'bx_albums', '', '_bx_albums_page_block_title_popular_keywords_media_camera', 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:22:\"bx_albums_media_camera\";i:1;s:22:\"bx_albums_media_camera\";}s:5:\"class\";s:20:\"TemplServiceMetatags\";}', 1, 0, 1, 2);
+
+-- 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_albums_search', '_bx_albums_page_title_sys_entries_search', '_bx_albums_page_title_entries_search', 'bx_albums', 11, 2147483647, 1, 'albums-search', 'page.php?i=albums-search', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowse', 'modules/boonex/albums/classes/BxAlbumsPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_albums_search', 2, 'bx_albums', '_bx_albums_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_albums";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_albums_search', 1, 'bx_albums', '_bx_albums_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_albums";s:10:"show_empty";b:0;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_albums_search', 3, 'bx_albums', '_bx_albums_page_block_title_search_form_media', 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_albums_media";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_albums_search', 1, 'bx_albums', '_bx_albums_page_block_title_search_results_media', 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_albums_media";s:10:"show_empty";b:0;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 2),
+('bx_albums_search', 2, 'bx_albums', '_bx_albums_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_albums_cmts";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 2),
+('bx_albums_search', 1, 'bx_albums', '_bx_albums_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_albums_cmts";s:10:"show_empty";b:0;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 3),
+('bx_albums_search', 3, 'bx_albums', '_bx_albums_page_block_title_search_form_media_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:20:"bx_albums_media_cmts";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 2),
+('bx_albums_search', 1, 'bx_albums', '_bx_albums_page_block_title_search_results_media_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:20:"bx_albums_media_cmts";s:10:"show_empty";b:0;}}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_albums_manage', '_bx_albums_page_title_sys_manage', '_bx_albums_page_title_manage', 'bx_albums', 5, 2147483647, 1, 'albums-manage', 'page.php?i=albums-manage', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowse', 'modules/boonex/albums/classes/BxAlbumsPageBrowse.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_albums_manage', 1, 'bx_albums', '_bx_albums_page_block_title_system_manage', '_bx_albums_page_block_title_manage', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_albums\";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_albums_administration', '_bx_albums_page_title_sys_manage_administration', '_bx_albums_page_title_manage', 'bx_albums', 5, 192, 1, 'albums-administration', 'page.php?i=albums-administration', '', '', '', 0, 1, 0, 'BxAlbumsPageBrowse', 'modules/boonex/albums/classes/BxAlbumsPageBrowse.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_albums_administration', 1, 'bx_albums', '_bx_albums_page_block_title_system_manage_administration', '_bx_albums_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:9:\"bx_albums\";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_albums', '_bx_albums_page_block_title_recent_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";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),
+('sys_home', 1, 'bx_albums', '_bx_albums_page_block_title_updated_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:14:"browse_updated";s:6:"params";a:2:{i:0;b:0;i:1;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 = 3;
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_albums', '_bx_albums_page_block_title_my_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";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_albums_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`, `active`, `order`) VALUES
+('', 0, 'bx_albums', '', '_bx_albums_page_block_title_recent_media', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:19:"browse_recent_media";s:6:"params";a:3:{s:9:"unit_view";s:7:"gallery";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:1;}}', 0, 1, 1, @iBlockOrder + 1),
+('', 0, 'bx_albums', '', '_bx_albums_page_block_title_popular_keywords_albums', 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_albums";i:1;s:9:"bx_albums";}s:5:"class";s:20:"TemplServiceMetatags";}', 0, 1, 1, @iBlockOrder + 2),
+('', 0, 'bx_albums', '', '_bx_albums_page_block_title_popular_keywords_media', 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:15:"bx_albums_media";i:1;s:15:"bx_albums_media";}s:5:"class";s:20:"TemplServiceMetatags";}', 0, 1, 1, @iBlockOrder + 3),
+('', 0, 'bx_albums', '', '_bx_albums_page_block_title_popular_keywords_media_camera', 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:22:"bx_albums_media_camera";i:1;s:22:"bx_albums_media_camera";}s:5:"class";s:20:"TemplServiceMetatags";}', 0, 1, 1, @iBlockOrder + 4),
+('', 0, 'bx_albums', '', '_bx_albums_page_block_title_recent_entries', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:13:"browse_public";s:6:"params";a:3:{s:9:"unit_view";s:8:"extended";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 1, 1, @iBlockOrder + 5),
+('', 0, 'bx_albums', '_bx_albums_page_block_title_sys_recent_media_view_showcase', '_bx_albums_page_block_title_recent_media_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:19:"browse_recent_media";s:6:"params";a:3:{s:9:"unit_view";s:8:"showcase";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 1, 1, @iBlockOrder + 6),
+('', 0, 'bx_albums', '_bx_albums_page_block_title_sys_popular_media_view_showcase', '_bx_albums_page_block_title_popular_media_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:20:"browse_popular_media";s:6:"params";a:3:{s:9:"unit_view";s:8:"showcase";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 1, 1,@iBlockOrder + 7),
+('', 0, 'bx_albums', '_bx_albums_page_block_title_sys_featured_media_view_showcase', '_bx_albums_page_block_title_featured_media_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_albums";s:6:"method";s:21:"browse_featured_media";s:6:"params";a:3:{s:9:"unit_view";s:8:"showcase";s:13:"empty_message";b:1;s:13:"ajax_paginate";b:0;}}', 0, 1, 1,@iBlockOrder + 8);
+
+-- MENU: add to site menu
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_site', 'bx_albums', 'albums-home', '_bx_albums_menu_item_title_system_entries_home', '_bx_albums_menu_item_title_entries_home', 'page.php?i=albums-home', '', '', 'far image col-blue1', 'bx_albums_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_albums', 'albums-home', '_bx_albums_menu_item_title_system_entries_home', '_bx_albums_menu_item_title_entries_home', 'page.php?i=albums-home', '', '', 'far image col-blue1', 'bx_albums_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_albums', 'create-album', '_bx_albums_menu_item_title_system_create_entry', '_bx_albums_menu_item_title_create_entry', 'page.php?i=create-album', '', '', 'far image col-blue1', '', 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_albums_view', '_bx_albums_menu_title_view_entry', 'bx_albums_view', 'bx_albums', 9, 0, 1, 'BxAlbumsMenuView', 'modules/boonex/albums/classes/BxAlbumsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_view', 'bx_albums', '_bx_albums_menu_set_title_view_entry', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('bx_albums_view', 'bx_albums', 'add-images-to-album', '_bx_albums_menu_item_title_system_add_images', '_bx_albums_menu_item_title_add_images', 'page.php?i=add-images&id={content_id}', '', '', 'plus', '', 2147483647, 1, 0, 10),
+('bx_albums_view', 'bx_albums', 'edit-album', '_bx_albums_menu_item_title_system_edit_entry', '_bx_albums_menu_item_title_edit_entry', 'page.php?i=edit-album&id={content_id}', '', '', 'pencil-alt', '', 2147483647, 1, 0, 20),
+('bx_albums_view', 'bx_albums', 'delete-album', '_bx_albums_menu_item_title_system_delete_entry', '_bx_albums_menu_item_title_delete_entry', 'page.php?i=delete-album&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_albums_view_actions', '_sys_menu_title_view_actions', 'bx_albums_view_actions', 'bx_albums', 15, 0, 1, 'BxAlbumsMenuViewActions', 'modules/boonex/albums/classes/BxAlbumsMenuViewActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_view_actions', 'bx_albums', '_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`, `active`, `copyable`, `order`) VALUES 
+('bx_albums_view_actions', 'bx_albums', 'add-images-to-album', '_bx_albums_menu_item_title_system_add_images', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 10),
+('bx_albums_view_actions', 'bx_albums', 'edit-album', '_bx_albums_menu_item_title_system_edit_entry', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 20),
+('bx_albums_view_actions', 'bx_albums', 'delete-album', '_bx_albums_menu_item_title_system_delete_entry', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 30),
+('bx_albums_view_actions', 'bx_albums', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 200),
+('bx_albums_view_actions', 'bx_albums', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 210),
+('bx_albums_view_actions', 'bx_albums', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 220),
+('bx_albums_view_actions', 'bx_albums', 'reaction', '_sys_menu_item_title_system_va_reaction', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 225),
+('bx_albums_view_actions', 'bx_albums', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 230),
+('bx_albums_view_actions', 'bx_albums', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 240),
+('bx_albums_view_actions', 'bx_albums', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 250),
+('bx_albums_view_actions', 'bx_albums', 'repost', '_sys_menu_item_title_system_va_repost', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 260),
+('bx_albums_view_actions', 'bx_albums', 'report', '_sys_menu_item_title_system_va_report', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 270),
+('bx_albums_view_actions', 'bx_albums', 'social-sharing-facebook', '_sys_menu_item_title_system_social_sharing_facebook', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 300),
+('bx_albums_view_actions', 'bx_albums', 'social-sharing-twitter', '_sys_menu_item_title_system_social_sharing_twitter', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 320),
+('bx_albums_view_actions', 'bx_albums', 'social-sharing-pinterest', '_sys_menu_item_title_system_social_sharing_pinterest', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 330),
+('bx_albums_view_actions', 'bx_albums', '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 view media
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_albums_view_media', '_bx_albums_menu_title_view_media', 'bx_albums_view_media', 'bx_albums', 9, 0, 1, 'BxAlbumsMenuView', 'modules/boonex/albums/classes/BxAlbumsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_view_media', 'bx_albums', '_bx_albums_menu_set_title_view_media', 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_albums_view_media', 'bx_albums', 'add-images-to-album', '_bx_albums_menu_item_title_system_add_images', '_bx_albums_menu_item_title_add_images', 'page.php?i=add-images&id={content_id}', '', '', 'plus', '', 2147483647, 1, 0, 10),
+('bx_albums_view_media', 'bx_albums', 'edit-album', '_bx_albums_menu_item_title_system_edit_album', '_bx_albums_menu_item_title_edit_album', 'page.php?i=edit-album&id={content_id}', '', '', 'pencil-alt', '', 2147483647, 1, 0, 20),
+('bx_albums_view_media', 'bx_albums', 'edit-image', '_bx_albums_menu_item_title_system_edit_image', '_bx_albums_menu_item_title_edit_image', 'javascript:void(0)', 'javascript:{js_object}.editMedia(this, {media_id});', '', 'pencil-alt', '', 2147483647, 1, 0, 30);
+
+-- MENU: all actions menu for view media page 
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_albums_view_actions_media', '_bx_albums_menu_title_view_actions_media', 'bx_albums_view_actions_media', 'bx_albums', 15, 0, 1, 'BxAlbumsMenuViewActionsMedia', 'modules/boonex/albums/classes/BxAlbumsMenuViewActionsMedia.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_view_actions_media', 'bx_albums', '_bx_albums_menu_set_title_view_actions_media', 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_albums_view_actions_media', 'bx_albums', 'add-images-to-album', '_bx_albums_menu_item_title_system_add_images', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 10),
+('bx_albums_view_actions_media', 'bx_albums', 'edit-album', '_bx_albums_menu_item_title_system_edit_album', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 20),
+('bx_albums_view_actions_media', 'bx_albums', 'edit-image', '_bx_albums_menu_item_title_system_edit_image', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 30),
+('bx_albums_view_actions_media', 'bx_albums', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 200),
+('bx_albums_view_actions_media', 'bx_albums', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 210),
+('bx_albums_view_actions_media', 'bx_albums', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 220),
+('bx_albums_view_actions_media', 'bx_albums', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 230),
+('bx_albums_view_actions_media', 'bx_albums', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 240),
+('bx_albums_view_actions_media', 'bx_albums', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 250),
+('bx_albums_view_actions_media', 'bx_albums', 'social-sharing-facebook', '_sys_menu_item_title_system_social_sharing_facebook', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 300),
+('bx_albums_view_actions_media', 'bx_albums', 'social-sharing-twitter', '_sys_menu_item_title_system_social_sharing_twitter', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 320),
+('bx_albums_view_actions_media', 'bx_albums', 'social-sharing-pinterest', '_sys_menu_item_title_system_social_sharing_pinterest', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 330),
+('bx_albums_view_actions_media', 'bx_albums', '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 media unit
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_albums_view_actions_media_unit', '_bx_albums_menu_title_view_actions_media_unit', 'bx_albums_view_actions_media_unit', 'bx_albums', 15, 0, 1, 'BxAlbumsMenuViewActionsMedia', 'modules/boonex/albums/classes/BxAlbumsMenuViewActionsMedia.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_view_actions_media_unit', 'bx_albums', '_bx_albums_menu_set_title_view_actions_media_unit', 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_albums_view_actions_media_unit', 'bx_albums', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 200),
+('bx_albums_view_actions_media_unit', 'bx_albums', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 210),
+('bx_albums_view_actions_media_unit', 'bx_albums', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 220),
+('bx_albums_view_actions_media_unit', 'bx_albums', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 230),
+('bx_albums_view_actions_media_unit', 'bx_albums', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 240),
+('bx_albums_view_actions_media_unit', 'bx_albums', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 250),
+('bx_albums_view_actions_media_unit', 'bx_albums', '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_albums_my', '_bx_albums_menu_title_entries_my', 'bx_albums_my', 'bx_albums', 9, 0, 1, 'BxAlbumsMenu', 'modules/boonex/albums/classes/BxAlbumsMenu.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_my', 'bx_albums', '_bx_albums_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_albums_my', 'bx_albums', 'create-album', '_bx_albums_menu_item_title_system_create_entry', '_bx_albums_menu_item_title_create_entry', 'page.php?i=create-album', '', '', '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_albums_submenu', '_bx_albums_menu_title_submenu', 'bx_albums_submenu', 'bx_albums', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_submenu', 'bx_albums', '_bx_albums_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_albums_submenu', 'bx_albums', 'albums-home', '_bx_albums_menu_item_title_system_entries_recent', '_bx_albums_menu_item_title_entries_recent', 'page.php?i=albums-home', '', '', '', '', 2147483647, 1, 1, 1),
+('bx_albums_submenu', 'bx_albums', 'albums-popular', '_bx_albums_menu_item_title_system_entries_popular', '_bx_albums_menu_item_title_entries_popular', 'page.php?i=albums-popular', '', '', '', '', 2147483647, 1, 1, 2),
+('bx_albums_submenu', 'bx_albums', 'albums-popular-media', '_bx_albums_menu_item_title_system_entries_popular_media', '_bx_albums_menu_item_title_entries_popular_media', 'page.php?i=albums-popular-media', '', '', '', '', 2147483647, 1, 1, 3),
+('bx_albums_submenu', 'bx_albums', 'albums-search', '_bx_albums_menu_item_title_system_entries_search', '_bx_albums_menu_item_title_entries_search', 'page.php?i=albums-search', '', '', '', '', 2147483647, 1, 1, 4),
+('bx_albums_submenu', 'bx_albums', 'albums-manage', '_bx_albums_menu_item_title_system_entries_manage', '_bx_albums_menu_item_title_entries_manage', 'page.php?i=albums-manage', '', '', '', '', 2147483646, 1, 1, 5);
+
+-- 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_albums_view_submenu', '_bx_albums_menu_title_view_entry_submenu', 'bx_albums_view_submenu', 'bx_albums', 8, 0, 1, 'BxAlbumsMenuView', 'modules/boonex/albums/classes/BxAlbumsMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_view_submenu', 'bx_albums', '_bx_albums_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_albums_view_submenu', 'bx_albums', 'view-album', '_bx_albums_menu_item_title_system_view_entry', '_bx_albums_menu_item_title_view_entry_submenu_entry', 'page.php?i=view-album&id={content_id}', '', '', '', '', 2147483647, 1, 0, 1),
+('bx_albums_view_submenu', 'bx_albums', 'view-album-comments', '_bx_albums_menu_item_title_system_view_entry_comments', '_bx_albums_menu_item_title_view_entry_submenu_comments', 'page.php?i=view-album-comments&id={content_id}', '', '', '', '', 2147483647, 1, 0, 2);
+
+-- 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_albums_snippet_meta', '_sys_menu_title_snippet_meta', 'bx_albums_snippet_meta', 'bx_albums', 15, 0, 1, 'BxAlbumsMenuSnippetMeta', 'modules/boonex/albums/classes/BxAlbumsMenuSnippetMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_snippet_meta', 'bx_albums', '_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_albums_snippet_meta', 'bx_albums', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', 2147483647, 1, 0, 1, 1),
+('bx_albums_snippet_meta', 'bx_albums', 'author', '_sys_menu_item_title_system_sm_author', '_sys_menu_item_title_sm_author', '', '', '', '', '', 2147483647, 1, 0, 1, 2),
+('bx_albums_snippet_meta', 'bx_albums', 'tags', '_sys_menu_item_title_system_sm_tags', '_sys_menu_item_title_sm_tags', '', '', '', '', '', 2147483647, 0, 0, 1, 3),
+('bx_albums_snippet_meta', 'bx_albums', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 2147483647, 0, 0, 1, 4),
+('bx_albums_snippet_meta', 'bx_albums', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 2147483647, 0, 0, 1, 5),
+('bx_albums_snippet_meta', 'bx_albums', 'items', '_bx_albums_menu_item_title_system_sm_items', '_bx_albums_menu_item_title_sm_items', '', '', '', '', '', 2147483647, 0, 0, 1, 6);
+
+-- 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_albums', 'profile-stats-manage-albums', '_bx_albums_menu_item_title_system_manage_my_albums', '_bx_albums_menu_item_title_manage_my_albums', 'page.php?i=albums-manage', '', '_self', 'far image col-blue1', 'a:2:{s:6:"module";s:9:"bx_albums";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_albums_menu_manage_tools', '_bx_albums_menu_title_manage_tools', 'bx_albums_menu_manage_tools', 'bx_albums', 6, 0, 1, 'BxAlbumsMenuManageTools', 'modules/boonex/albums/classes/BxAlbumsMenuManageTools.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_albums_menu_manage_tools', 'bx_albums', '_bx_albums_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_albums_menu_manage_tools', 'bx_albums', 'delete-with-content', '_bx_albums_menu_item_title_system_delete_with_content', '_bx_albums_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_albums', 'albums-administration', '_bx_albums_menu_item_title_system_admt_albums', '_bx_albums_menu_item_title_admt_albums', 'page.php?i=albums-administration', '', '_self', 'far image', 'a:2:{s:6:"module";s:9:"bx_albums";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_albums', 'albums-author', '_bx_albums_menu_item_title_system_view_entries_author', '_bx_albums_menu_item_title_view_entries_author', 'page.php?i=albums-author&profile_id={profile_id}', '', '', 'far image col-blue1', '', 2147483647, 1, 0, 0),
+('trigger_group_view_submenu', 'bx_albums', 'albums-context', '_bx_albums_menu_item_title_system_view_entries_in_context', '_bx_albums_menu_item_title_view_entries_in_context', 'page.php?i=albums-context&profile_id={profile_id}', '', '', 'far image col-blue1', '', 2147483647, 1, 0, 0);
+
+
+-- PRIVACY 
+INSERT INTO `sys_objects_privacy` (`object`, `module`, `action`, `title`, `default_group`, `table`, `table_field_id`, `table_field_author`, `override_class_name`, `override_class_file`) VALUES
+('bx_albums_allow_view_to', 'bx_albums', 'view', '_bx_albums_form_entry_input_allow_view_to', '3', 'bx_albums_albums', 'id', 'author', '', '');
+
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_albums', 'create entry', NULL, '_bx_albums_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_albums', 'delete entry', NULL, '_bx_albums_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_albums', 'view entry', NULL, '_bx_albums_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_albums', 'set thumb', NULL, '_bx_albums_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_albums', 'edit any entry', NULL, '_bx_albums_acl_action_edit_any_entry', '', 1, 3);
+SET @iIdActionEntryEditAny = LAST_INSERT_ID();
+
+SET @iUnauthenticated = 1;
+SET @iAccount = 2;
+SET @iStandard = 3;
+SET @iUnconfirmed = 4;
+SET @iPending = 5;
+SET @iSuspended = 6;
+SET @iModerator = 7;
+SET @iAdministrator = 8;
+SET @iPremium = 9;
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
+
+-- entry create
+(@iStandard, @iIdActionEntryCreate),
+(@iModerator, @iIdActionEntryCreate),
+(@iAdministrator, @iIdActionEntryCreate),
+(@iPremium, @iIdActionEntryCreate),
+
+-- entry delete
+(@iStandard, @iIdActionEntryDelete),
+(@iModerator, @iIdActionEntryDelete),
+(@iAdministrator, @iIdActionEntryDelete),
+(@iPremium, @iIdActionEntryDelete),
+
+-- entry 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),
+
+-- edit any entry
+(@iModerator, @iIdActionEntryEditAny),
+(@iAdministrator, @iIdActionEntryEditAny);
+
+
+-- SEARCH
+SET @iSearchOrder = (SELECT IFNULL(MAX(`Order`), 0) FROM `sys_objects_search`);
+INSERT INTO `sys_objects_search` (`ObjectName`, `Title`, `Order`, `GlobalSearch`, `ClassName`, `ClassPath`) VALUES
+('bx_albums', '_bx_albums', @iSearchOrder + 1, 1, 'BxAlbumsSearchResult', 'modules/boonex/albums/classes/BxAlbumsSearchResult.php'),
+('bx_albums_cmts', '_bx_albums_cmts', @iSearchOrder + 2, 1, 'BxAlbumsCmtsSearchResult', 'modules/boonex/albums/classes/BxAlbumsCmtsSearchResult.php'),
+('bx_albums_media', '_bx_albums_media', @iSearchOrder + 3, 1, 'BxAlbumsSearchResultMedia', 'modules/boonex/albums/classes/BxAlbumsSearchResultMedia.php'),
+('bx_albums_media_cmts', '_bx_albums_media_cmts', @iSearchOrder + 4, 1, 'BxAlbumsCmtsSearchResultMedia', 'modules/boonex/albums/classes/BxAlbumsCmtsSearchResultMedia.php'),
+('bx_albums_media_camera', '_bx_albums_media', @iSearchOrder + 5, 0, 'BxAlbumsSearchResultMediaCamera', 'modules/boonex/albums/classes/BxAlbumsSearchResultMediaCamera.php');
+
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_albums', 'bx_albums_meta_keywords', 'bx_albums_meta_locations', 'bx_albums_meta_mentions', '', ''),
+('bx_albums_media', 'bx_albums_meta_keywords_media', '', '', '', ''),
+('bx_albums_media_camera', 'bx_albums_meta_keywords_media_camera', '', '', '', '');
+
+
+-- STATS
+SET @iMaxOrderStats = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_statistics`);
+INSERT INTO `sys_statistics` (`module`, `name`, `title`, `link`, `icon`, `query`, `order`) VALUES 
+('bx_albums', 'bx_albums', '_bx_albums', 'page.php?i=albums-home', 'far image col-blue1', 'SELECT COUNT(*) FROM `bx_albums_albums` WHERE 1 AND `status` = ''active'' AND `status_admin` = ''active''', @iMaxOrderStats + 1),
+('bx_albums', 'bx_albums_media', '_bx_albums_media', '', 'far image col-blue1', 'SELECT COUNT(*) FROM `bx_albums_files` WHERE 1', @iMaxOrderStats + 2);
+
+
+-- 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_albums_growth', '_bx_albums_chart_growth', 'bx_albums_albums', 'added', '', 'status,status_admin', '', 1, @iMaxOrderCharts + 1, 'BxDolChartGrowth', ''),
+('bx_albums_growth_speed', '_bx_albums_chart_growth_speed', 'bx_albums_albums', 'added', '', 'status,status_admin', '', 1, @iMaxOrderCharts + 2, 'BxDolChartGrowthSpeed', ''),
+('bx_albums_growth_media', '_bx_albums_chart_growth_media', 'bx_albums_files', 'added', '', '', '', 1, @iMaxOrderCharts + 3, 'BxDolChartGrowth', ''),
+('bx_albums_growth_speed_media', '_bx_albums_chart_growth_speed_media', 'bx_albums_files', 'added', '', '', '', 1, @iMaxOrderCharts + 4, '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_albums_administration', 'Sql', 'SELECT * FROM `bx_albums_albums` WHERE 1 ', 'bx_albums_albums', 'id', 'added', 'status_admin', '', 20, NULL, 'start', '', 'title,text', '', 'like', 'reports', '', 192, 'BxAlbumsGridAdministration', 'modules/boonex/albums/classes/BxAlbumsGridAdministration.php'),
+('bx_albums_common', 'Sql', 'SELECT * FROM `bx_albums_albums` WHERE 1 ', 'bx_albums_albums', 'id', 'added', 'status', '', 20, NULL, 'start', '', 'title,text', '', 'like', '', '', 2147483647, 'BxAlbumsGridCommon', 'modules/boonex/albums/classes/BxAlbumsGridCommon.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_albums_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_albums_administration', 'switcher', '_bx_albums_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_albums_administration', 'reports', '_sys_txt_reports_title', '5%', 0, '', '', 3),
+('bx_albums_administration', 'title', '_bx_albums_grid_column_title_adm_title', '25%', 0, '', '', 4),
+('bx_albums_administration', 'added', '_bx_albums_grid_column_title_adm_added', '20%', 1, '25', '', 5),
+('bx_albums_administration', 'author', '_bx_albums_grid_column_title_adm_author', '20%', 0, '25', '', 6),
+('bx_albums_administration', 'actions', '', '20%', 0, '', '', 7),
+('bx_albums_common', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_albums_common', 'switcher', '', '8%', 0, '', '', 2),
+('bx_albums_common', 'title', '_bx_albums_grid_column_title_adm_title', '40%', 0, '', '', 3),
+('bx_albums_common', 'added', '_bx_albums_grid_column_title_adm_added', '30%', 1, '25', '', 4),
+('bx_albums_common', 'actions', '', '20%', 0, '', '', 5);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_albums_administration', 'bulk', 'delete', '_bx_albums_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_albums_administration', 'single', 'edit', '_bx_albums_grid_action_title_adm_edit', 'pencil-alt', 1, 0, 1),
+('bx_albums_administration', 'single', 'delete', '_bx_albums_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_albums_administration', 'single', 'settings', '_bx_albums_grid_action_title_adm_more_actions', 'cog', 1, 0, 3),
+('bx_albums_common', 'bulk', 'delete', '_bx_albums_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_albums_common', 'single', 'edit', '_bx_albums_grid_action_title_adm_edit', 'pencil-alt', 1, 0, 1),
+('bx_albums_common', 'single', 'delete', '_bx_albums_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_albums_common', 'single', 'settings', '_bx_albums_grid_action_title_adm_more_actions', 'cog', 1, 0, 3);
+
+
+-- UPLOADERS
+INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_albums_simple', 1, 'BxAlbumsUploaderSimple', 'modules/boonex/albums/classes/BxAlbumsUploaderSimple.php'),
+('bx_albums_html5', 1, 'BxAlbumsUploaderHTML5', 'modules/boonex/albums/classes/BxAlbumsUploaderHTML5.php'),
+('bx_albums_crop', 1, 'BxAlbumsUploaderCrop', 'modules/boonex/albums/classes/BxAlbumsUploaderCrop.php');
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_albums', 'BxAlbumsAlertsResponse', 'modules/boonex/albums/classes/BxAlbumsAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'save_setting', @iHandler),
+('profile', 'delete', @iHandler),
+
+('bx_albums_files', 'file_deleted', @iHandler),
+('bx_albums_video_mp4', 'transcoded', @iHandler);

+ 503 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/install/sql/install.sql

@@ -0,0 +1,503 @@
+
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: entries
+CREATE TABLE IF NOT EXISTS `bx_albums_albums` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `author` int(10) unsigned NOT NULL,
+  `added` int(11) NOT NULL,
+  `changed` int(11) NOT NULL,
+  `thumb` int(11) NOT NULL,
+  `title` varchar(255) NOT NULL,
+  `text` 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',
+  `allow_view_to` varchar(16) NOT NULL DEFAULT '3',
+  `status` enum('active','awaiting','failed','hidden') NOT NULL DEFAULT 'active',
+  `status_admin` enum('active','hidden') NOT NULL DEFAULT 'active',
+  PRIMARY KEY (`id`),
+  FULLTEXT KEY `title_text` (`title`,`text`)
+);
+
+-- TABLE: storages & transcoders
+CREATE TABLE IF NOT EXISTS `bx_albums_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` int(11) NOT NULL,
+  `duration` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_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` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_files2albums` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `content_id` int(10) unsigned NOT NULL,
+  `file_id` int(11) NOT NULL,
+  `author` int(10) unsigned NOT NULL,
+  `title` varchar(255) NOT NULL,
+  `views` int(11) NOT NULL,
+  `rate` float NOT NULL,
+  `votes` int(11) NOT NULL,
+  `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,
+  `featured` int(11) NOT NULL default '0',
+  `data` text NOT NULL,
+  `exif` text NOT NULL,
+  `order` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `file_content` (`file_id`,`content_id`),
+  KEY `content_id` (`content_id`),
+  FULLTEXT KEY `search_fields` (`title`)
+);
+
+-- TABLE: comments
+CREATE TABLE IF NOT EXISTS `bx_albums_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',
+  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_albums_cmts_media` (
+  `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',
+  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_albums_votes` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_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_albums_votes_media` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_votes_media_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_albums_reactions` (
+  `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',
+  UNIQUE KEY `reaction` (`object_id`, `reaction`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_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_albums_views_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+CREATE TABLE `bx_albums_views_media_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- TABLE: metas
+CREATE TABLE `bx_albums_meta_keywords` (
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE `bx_albums_meta_keywords_media` (
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE `bx_albums_meta_keywords_media_camera` (
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE `bx_albums_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_albums_meta_mentions` (
+  `object_id` int(10) unsigned NOT NULL,
+  `profile_id` int(10) unsigned NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `profile_id` (`profile_id`)
+);
+
+-- TABLE: reports
+CREATE TABLE IF NOT EXISTS `bx_albums_reports` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_reports_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(32) NOT NULL default '',
+  `text` text NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+);
+
+-- TABLE: favorites
+CREATE TABLE `bx_albums_favorites_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`author_id`)
+);
+
+CREATE TABLE `bx_albums_favorites_media_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`author_id`)
+);
+
+-- TABLE: scores
+CREATE TABLE IF NOT EXISTS `bx_albums_scores` (
+  `object_id` int(11) NOT NULL default '0',
+  `count_up` int(11) NOT NULL default '0',
+  `count_down` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_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 IF NOT EXISTS `bx_albums_scores_media` (
+  `object_id` int(11) NOT NULL default '0',
+  `count_up` int(11) NOT NULL default '0',
+  `count_down` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_albums_scores_media_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_albums_files', @sStorageEngine, '', 360, 2592000, 3, 'bx_albums_files', 'allow-deny', 'jpg,jpeg,jpe,gif,png,avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,qt,divx,xvid,3gp,3g2,webm,mkv,ogv,ogg,rm,rmvb,asf,drc', '', 0, 0, 0, 0, 0, 0),
+('bx_albums_photos_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_albums_photos_resized', 'allow-deny', 'jpg,jpeg,jpe,gif,png,avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,qt,divx,xvid,3gp,3g2,webm,mkv,ogv,ogg,rm,rmvb,asf,drc', '', 0, 0, 0, 0, 0, 0);
+
+INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`, `override_class_name`, `override_class_file`) VALUES
+('bx_albums_preview', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', '1', '2592000', '0', '', ''),
+('bx_albums_browse', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', '1', '2592000', '0', '', ''),
+('bx_albums_big', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', '1', '2592000', '0', '', ''),
+('bx_albums_video_poster_browse', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', 0, 0, 0, 'BxDolTranscoderVideo', ''),
+('bx_albums_video_poster_preview', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', 0, 0, 0, 'BxDolTranscoderVideo', ''),
+('bx_albums_video_poster_big', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', 0, 0, 0, 'BxDolTranscoderVideo', ''),
+('bx_albums_video_mp4', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', 0, 0, 0, 'BxDolTranscoderVideo', ''),
+('bx_albums_video_mp4_hd', 'bx_albums_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_albums_files";}', 'no', 0, 0, 0, 'BxDolTranscoderVideo', ''),
+('bx_albums_proxy_preview', 'bx_albums_photos_resized', 'Proxy', 'a:4:{s:6:"object";s:15:"bx_albums_files";s:5:"image";s:17:"bx_albums_preview";s:12:"video_poster";s:30:"bx_albums_video_poster_preview";s:5:"video";a:4:{i:0;s:19:"bx_albums_video_mp4";i:1;s:22:"bx_albums_video_mp4_hd";i:2;s:29:"bx_albums_video_poster_browse";i:3;s:26:"bx_albums_video_poster_big";}}', 'no', 0, 0, 0, 'BxDolTranscoderProxy', ''),
+('bx_albums_proxy_browse', 'bx_albums_photos_resized', 'Proxy', 'a:4:{s:6:"object";s:15:"bx_albums_files";s:5:"image";s:16:"bx_albums_browse";s:12:"video_poster";s:29:"bx_albums_video_poster_browse";s:5:"video";a:2:{i:0;s:19:"bx_albums_video_mp4";i:1;s:22:"bx_albums_video_mp4_hd";}}', 'no', 0, 0, 0, 'BxDolTranscoderProxy', ''),
+('bx_albums_proxy_cover', 'bx_albums_photos_resized', 'Proxy', 'a:4:{s:6:"object";s:15:"bx_albums_files";s:5:"image";s:13:"bx_albums_big";s:12:"video_poster";s:26:"bx_albums_video_poster_big";s:5:"video";a:2:{i:0;s:19:"bx_albums_video_mp4";i:1;s:22:"bx_albums_video_mp4_hd";}}', 'no', 0, 0, 0, 'BxDolTranscoderProxy', '');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_albums_preview', 'Resize', 'a:3:{s:1:"w";s:3:"300";s:1:"h";s:3:"300";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_albums_browse', 'Resize', 'a:1:{s:1:"h";s:3:"180";}', '0'),
+('bx_albums_big', 'Resize', 'a:2:{s:1:"w";s:4:"1280";s:1:"h";s:4:"1280";}', '0'),
+('bx_albums_video_poster_browse', 'Poster', 'a:2:{s:1:"h";s:3:"180";s:10:"force_type";s:3:"jpg";}', 0),
+('bx_albums_video_poster_preview', 'Poster', 'a:2:{s:1:"h";s:3:"480";s:10:"force_type";s:3:"jpg";}', 0),
+('bx_albums_video_poster_preview', 'Resize', 'a:3:{s:1:"w";s:3:"300";s:1:"h";s:3:"300";s:13:"square_resize";s:1:"1";}', 10),
+('bx_albums_video_poster_big', 'Poster', 'a:2:{s:1:"h";s:3:"480";s:10:"force_type";s:3:"jpg";}', 0),
+('bx_albums_video_mp4', 'Mp4', 'a:2:{s:1:"h";s:3:"480";s:10:"force_type";s:3:"mp4";}', 0),
+('bx_albums_video_mp4_hd', 'Mp4', 'a:3:{s:1:"h";s:3:"720";s:13:"video_bitrate";s:4:"1536";s:10:"force_type";s:3:"mp4";}', 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_albums', 'bx_albums', '_bx_albums_form_entry', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_albums_albums', 'id', '', '', 'do_submit', '', 0, 1, 'BxAlbumsFormEntry', 'modules/boonex/albums/classes/BxAlbumsFormEntry.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_albums', 'bx_albums_entry_add', 'bx_albums', 0, '_bx_albums_form_entry_display_add'),
+('bx_albums', 'bx_albums_entry_edit', 'bx_albums', 0, '_bx_albums_form_entry_display_edit'),
+('bx_albums', 'bx_albums_entry_add_images', 'bx_albums', 0, '_bx_albums_form_entry_display_add_images'),
+('bx_albums', 'bx_albums_entry_delete', 'bx_albums', 0, '_bx_albums_form_entry_display_delete'),
+('bx_albums', 'bx_albums_entry_view', 'bx_albums', 1, '_bx_albums_form_entry_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`) VALUES 
+('bx_albums', 'bx_albums', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_albums_form_entry_input_sys_delete_confirm', '_bx_albums_form_entry_input_delete_confirm', '_bx_albums_form_entry_input_delete_confirm_info', 1, 0, 0, '', '', '', 'Avail', '', '_bx_albums_form_entry_input_delete_confirm_error', '', '', 1, 0),
+('bx_albums', 'bx_albums', 'do_submit', '_bx_albums_form_entry_input_do_submit', '', 0, 'submit', '_bx_albums_form_entry_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums', 'bx_albums', 'title', '', '', 0, 'text', '_bx_albums_form_entry_input_sys_title', '_bx_albums_form_entry_input_title', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_albums_form_entry_input_title_err', 'Xss', '', 1, 0),
+('bx_albums', 'bx_albums', 'text', '', '', 0, 'textarea', '_bx_albums_form_entry_input_sys_text', '_bx_albums_form_entry_input_text', '', 0, 0, 2, '', '', '', '', '', '', 'XssHtml', '', 1, 0),
+('bx_albums', 'bx_albums', 'pictures', 'a:2:{i:0;s:15:"bx_albums_html5";i:1;s:14:"bx_albums_crop";}', 'a:3:{s:16:"bx_albums_simple";s:26:"_sys_uploader_simple_title";s:15:"bx_albums_html5";s:25:"_sys_uploader_html5_title";s:14:"bx_albums_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_albums_form_entry_input_sys_pictures', '_bx_albums_form_entry_input_pictures', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums', 'bx_albums', 'allow_view_to', '', '', 0, 'custom', '_bx_albums_form_entry_input_sys_allow_view_to', '_bx_albums_form_entry_input_allow_view_to', '', 1, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums', 'bx_albums', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums', 'bx_albums', 'added', '', '', 0, 'datetime', '_bx_albums_form_entry_input_sys_date_added', '_bx_albums_form_entry_input_date_added', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums', 'bx_albums', 'changed', '', '', 0, 'datetime', '_bx_albums_form_entry_input_sys_date_changed', '_bx_albums_form_entry_input_date_changed', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums', 'bx_albums', '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_albums_entry_add', 'delete_confirm', 2147483647, 0, 1),
+('bx_albums_entry_add', 'title', 2147483647, 1, 2),
+('bx_albums_entry_add', 'text', 2147483647, 1, 3),
+('bx_albums_entry_add', 'pictures', 2147483647, 1, 4),
+('bx_albums_entry_add', 'allow_view_to', 2147483647, 1, 5),
+('bx_albums_entry_add', 'location', 2147483647, 1, 6),
+('bx_albums_entry_add', 'do_submit', 2147483647, 1, 7),
+
+('bx_albums_entry_edit', 'delete_confirm', 2147483647, 0, 1),
+('bx_albums_entry_edit', 'title', 2147483647, 1, 2),
+('bx_albums_entry_edit', 'text', 2147483647, 1, 3),
+('bx_albums_entry_edit', 'pictures', 2147483647, 1, 4),
+('bx_albums_entry_edit', 'allow_view_to', 2147483647, 1, 5),
+('bx_albums_entry_edit', 'location', 2147483647, 1, 6),
+('bx_albums_entry_edit', 'do_submit', 2147483647, 1, 7),
+
+('bx_albums_entry_add_images', 'delete_confirm', 2147483647, 0, 1),
+('bx_albums_entry_add_images', 'title', 2147483647, 0, 2),
+('bx_albums_entry_add_images', 'text', 2147483647, 0, 3),
+('bx_albums_entry_add_images', 'allow_view_to', 2147483647, 0, 4),
+('bx_albums_entry_add_images', 'location', 2147483647, 0, 5),
+('bx_albums_entry_add_images', 'pictures', 2147483647, 1, 6),
+('bx_albums_entry_add_images', 'do_submit', 2147483647, 1, 7),
+
+('bx_albums_entry_view', 'delete_confirm', 2147483647, 0, 0),
+('bx_albums_entry_view', 'allow_view_to', 2147483647, 0, 0),
+('bx_albums_entry_view', 'do_submit', 2147483647, 0, 0),
+('bx_albums_entry_view', 'text', 2147483647, 0, 0),
+('bx_albums_entry_view', 'title', 2147483647, 0, 0),
+('bx_albums_entry_view', 'pictures', 2147483647, 0, 0),
+('bx_albums_entry_view', 'added', 2147483647, 1, 1),
+('bx_albums_entry_view', 'changed', 2147483647, 1, 2),
+
+('bx_albums_entry_delete', 'delete_confirm', 2147483647, 1, 1),
+('bx_albums_entry_delete', 'do_submit', 2147483647, 1, 2),
+('bx_albums_entry_delete', 'allow_view_to', 2147483647, 0, 0),
+('bx_albums_entry_delete', 'pictures', 2147483647, 0, 0),
+('bx_albums_entry_delete', 'text', 2147483647, 0, 0),
+('bx_albums_entry_delete', 'title', 2147483647, 0, 0);
+
+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_albums_media', 'bx_albums', '_bx_albums_form_media', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_albums_files2albums', 'id', '', '', 'do_submit', '', 0, 1, '', '');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_albums_media', 'bx_albums_media_edit', 'bx_albums', 0, '_bx_albums_form_media_display_edit');
+
+INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
+('bx_albums_media', 'bx_albums', 'title', '', '', 0, 'text', '_bx_albums_form_media_input_sys_title', '_bx_albums_form_media_input_title', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_albums_media', 'bx_albums', 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_albums_media', 'bx_albums', 'do_submit', '_bx_albums_form_media_input_do_submit', '', 0, 'submit', '_bx_albums_form_media_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_albums_media', 'bx_albums', 'do_cancel', '_bx_albums_form_media_input_do_cancel', '', 0, 'button', '_bx_albums_form_media_input_sys_do_cancel', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0);
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_albums_media_edit', 'title', 2147483647, 1, 1),
+('bx_albums_media_edit', 'controls', 2147483647, 1, 2),
+('bx_albums_media_edit', 'do_submit', 2147483647, 1, 3),
+('bx_albums_media_edit', 'do_cancel', 2147483647, 1, 4);
+
+
+-- 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_albums', 'bx_albums', 'bx_albums_cmts', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-album&id={object_id}', '', 'bx_albums_albums', 'id', 'author', 'title', 'comments', '', ''),
+('bx_albums_media', 'bx_albums', 'bx_albums_cmts_media', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-album-media&id={object_id}', '', 'bx_albums_files2albums', 'id', 'author', 'title', 'comments', 'BxAlbumsCmtsMedia', 'modules/boonex/albums/classes/BxAlbumsCmtsMedia.php');
+
+
+-- VOTES
+INSERT INTO `sys_objects_vote` (`Name`, `TableMain`, `TableTrack`, `PostTimeout`, `MinValue`, `MaxValue`, `IsUndo`, `IsOn`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldRate`, `TriggerFieldRateCount`, `ClassName`, `ClassFile`) VALUES 
+('bx_albums', 'bx_albums_votes', 'bx_albums_votes_track', '604800', '1', '1', '0', '1', 'bx_albums_albums', 'id', 'author', 'rate', 'votes', '', ''),
+('bx_albums_media', 'bx_albums_votes_media', 'bx_albums_votes_media_track', '604800', '1', '1', '0', '1', 'bx_albums_files2albums', 'id', 'author', 'rate', 'votes', '', ''),
+
+('bx_albums_reactions', 'bx_albums_reactions', 'bx_albums_reactions_track', '604800', '1', '1', '1', '1', 'bx_albums_albums', 'id', 'author', 'rrate', 'rvotes', 'BxTemplVoteReactions', '');
+
+
+-- 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_albums', 'bx_albums', 'bx_albums_scores', 'bx_albums_scores_track', '604800', '0', 'bx_albums_albums', 'id', 'author', 'score', 'sc_up', 'sc_down', '', ''),
+('bx_albums_media', 'bx_albums', 'bx_albums_scores_media', 'bx_albums_scores_media_track', '604800', '0', 'bx_albums_files2albums', 'id', 'author', 'score', 'sc_up', 'sc_down', '', '');
+
+
+-- REPORTS
+INSERT INTO `sys_objects_report` (`name`, `table_main`, `table_track`, `is_on`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_albums', 'bx_albums_reports', 'bx_albums_reports_track', '1', 'page.php?i=view-album&id={object_id}', 'bx_albums_albums', '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_albums', 'bx_albums_views_track', '86400', '1', 'bx_albums_albums', 'id', '', 'views', '', ''),
+('bx_albums_media', 'bx_albums_views_media_track', '86400', '1', 'bx_albums_files2albums', 'id', 'author', 'views', '', '');
+
+
+-- FAFORITES
+INSERT INTO `sys_objects_favorite` (`name`, `table_track`, `is_on`, `is_undo`, `is_public`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_albums', 'bx_albums_favorites_track', '1', '1', '1', 'page.php?i=view-album&id={object_id}', 'bx_albums_albums', 'id', 'author', 'favorites', '', ''),
+('bx_albums_media', 'bx_albums_favorites_media_track', '1', '1', '1', 'page.php?i=view-album-media&id={object_id}', 'bx_albums_files2albums', 'id', '', 'favorites', '', '');
+
+
+-- FEATURED
+INSERT INTO `sys_objects_feature` (`name`, `is_on`, `is_undo`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_flag`, `class_name`, `class_file`) VALUES 
+('bx_albums', '1', '1', 'page.php?i=view-album&id={object_id}', 'bx_albums_albums', 'id', 'author', 'featured', '', ''),
+('bx_albums_media', '1', '1', 'page.php?i=view-album-media&id={object_id}', 'bx_albums_files2albums', 'id', '', '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_albums', '_bx_albums', 'bx_albums', 'added', 'edited', 'deleted', '', ''),
+('bx_albums_media', '_bx_albums_media', 'bx_albums', 'media_added', '', 'media_deleted', 'BxAlbumsContentInfoMedia', 'modules/boonex/albums/classes/BxAlbumsContentInfoMedia.php'),
+('bx_albums_cmts', '_bx_albums_cmts', 'bx_albums', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', ''),
+('bx_albums_media_cmts', '_bx_albums_media_cmts', 'bx_albums_media', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+INSERT INTO `sys_content_info_grids` (`object`, `grid_object`, `grid_field_id`, `condition`, `selection`) VALUES
+('bx_albums', 'bx_albums_administration', 'id', '', ''),
+('bx_albums', 'bx_albums_common', 'id', '', '');
+
+
+-- SEARCH EXTENDED
+INSERT INTO `sys_objects_search_extended` (`object`, `object_content_info`, `module`, `title`, `active`, `class_name`, `class_file`) VALUES
+('bx_albums', 'bx_albums', 'bx_albums', '_bx_albums_search_extended', 1, '', ''),
+('bx_albums_media', 'bx_albums_media', 'bx_albums', '_bx_albums_search_extended_media', 1, '', ''),
+('bx_albums_cmts', 'bx_albums_cmts', 'bx_albums', '_bx_albums_search_extended_cmts', 1, 'BxTemplSearchExtendedCmts', ''),
+('bx_albums_media_cmts', 'bx_albums_media_cmts', 'bx_albums', '_bx_albums_search_extended_media_cmts', 1, 'BxTemplSearchExtendedCmts', '');
+
+
+-- STUDIO: page & widget
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_albums', '_bx_albums', '_bx_albums', 'bx_albums@modules/boonex/albums/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_albums', '{url_studio}module.php?name=bx_albums', '', 'bx_albums@modules/boonex/albums/|std-icon.svg', '_bx_albums', '', '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));
+

+ 64 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/install/sql/uninstall.sql

@@ -0,0 +1,64 @@
+
+-- TABLES
+DROP TABLE IF EXISTS `bx_albums_albums`, `bx_albums_files`, `bx_albums_photos_resized`, `bx_albums_files2albums`, `bx_albums_cmts`, `bx_albums_cmts_media`, `bx_albums_votes`, `bx_albums_votes_track`, `bx_albums_votes_media`, `bx_albums_votes_media_track`, `bx_albums_reactions`, `bx_albums_reactions_track`, `bx_albums_views_track`, `bx_albums_views_media_track`, `bx_albums_meta_keywords`, `bx_albums_meta_keywords_media`, `bx_albums_meta_keywords_media_camera`, `bx_albums_meta_locations`, `bx_albums_meta_mentions`, `bx_albums_reports`, `bx_albums_reports_track`, `bx_albums_favorites_track`, `bx_albums_favorites_media_track`, `bx_albums_scores`, `bx_albums_scores_track`, `bx_albums_scores_media`, `bx_albums_scores_media_track`;
+
+
+-- STORAGES & TRANSCODERS
+DELETE FROM `sys_objects_storage` WHERE `object` = 'bx_albums_files' OR `object` = 'bx_albums_photos_resized';
+DELETE FROM `sys_storage_tokens` WHERE `object` = 'bx_albums_files' OR `object` = 'bx_albums_photos_resized';
+
+DELETE FROM `sys_objects_transcoder` WHERE `object` IN('bx_albums_preview', 'bx_albums_browse', 'bx_albums_big', 'bx_albums_video_poster_browse', 'bx_albums_video_poster_preview', 'bx_albums_video_poster_big', 'bx_albums_video_mp4', 'bx_albums_video_mp4_hd', 'bx_albums_proxy_preview', 'bx_albums_proxy_browse', 'bx_albums_proxy_cover');
+DELETE FROM `sys_transcoder_filters` WHERE `transcoder_object` IN('bx_albums_preview', 'bx_albums_browse', 'bx_albums_big', 'bx_albums_video_poster_browse', 'bx_albums_video_poster_preview', 'bx_albums_video_poster_big', 'bx_albums_video_mp4', 'bx_albums_video_mp4_hd');
+DELETE FROM `sys_transcoder_images_files` WHERE `transcoder_object` IN('bx_albums_preview', 'bx_albums_browse', 'bx_albums_big', 'bx_albums_video_poster_browse', 'bx_albums_video_poster_preview', 'bx_albums_video_poster_big', 'bx_albums_video_mp4', 'bx_albums_video_mp4_hd');
+DELETE FROM `sys_transcoder_videos_files` WHERE `transcoder_object` IN('bx_albums_video_mp4', 'bx_albums_video_mp4_hd');
+
+
+-- FORMS
+DELETE FROM `sys_objects_form` WHERE `module` = 'bx_albums';
+DELETE FROM `sys_form_displays` WHERE `module` = 'bx_albums';
+DELETE FROM `sys_form_inputs` WHERE `module` = 'bx_albums';
+DELETE FROM `sys_form_display_inputs` WHERE `display_name` LIKE 'bx_albums%';
+
+
+-- COMMENTS
+DELETE FROM `sys_objects_cmts` WHERE `Name` = 'bx_albums' OR `Name` = 'bx_albums_media';
+
+
+-- VOTES
+DELETE FROM `sys_objects_vote` WHERE `Name` IN ('bx_albums', 'bx_albums_media', 'bx_albums_reactions');
+
+
+-- SCORES
+DELETE FROM `sys_objects_score` WHERE `name` = 'bx_albums' OR `name` = 'bx_albums_media';
+
+
+-- REPORTS
+DELETE FROM `sys_objects_report` WHERE `name` = 'bx_albums';
+
+
+-- VIEWS
+DELETE FROM `sys_objects_view` WHERE `name` = 'bx_albums' OR `Name` = 'bx_albums_media';
+
+
+-- FAFORITES
+DELETE FROM `sys_objects_favorite` WHERE `name` IN ('bx_albums', 'bx_albums_media');
+
+
+-- FEATURED
+DELETE FROM `sys_objects_feature` WHERE `name` IN ('bx_albums', 'bx_albums_media');
+
+
+-- CONTENT INFO
+DELETE FROM `sys_objects_content_info` WHERE `name` IN ('bx_albums', 'bx_albums_media', 'bx_albums_cmts', 'bx_albums_media_cmts');
+
+DELETE FROM `sys_content_info_grids` WHERE `object` IN ('bx_albums');
+
+
+-- SEARCH EXTENDED
+DELETE FROM `sys_objects_search_extended` WHERE `module` = 'bx_albums';
+
+
+-- STUDIO: page & widget
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = 'bx_albums';

+ 69 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/js/main.js

@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Albums Albums
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxAlbumsMain(oOptions) {
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oBxAlbumsMain' : oOptions.sObjName;
+
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+
+    var $this = this;
+    $(document).ready(function() {
+    	$this.init();
+    });
+}
+
+BxAlbumsMain.prototype.init = function() {
+    $('.bx-albums-unit-images').flickity({
+        cellSelector: '.bx-albums-unit-image',
+        cellAlign: 'center',
+        imagesLoaded: true,
+        wrapAround: true,
+        pageDots: false
+    });
+};
+
+BxAlbumsMain.prototype.editMedia = function(oButton, iId) {
+    var $this = this;
+    var oDate = new Date();
+
+    this.loadingInButton(oButton, true);
+
+    $.get(
+        this._sActionsUrl + 'edit_media/' + iId, 
+        {
+            _t: oDate.getTime()
+        },
+        function(oData) {
+            $this.loadingInButton(oButton, false);
+
+            processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxAlbumsMain.prototype.onEditMedia = function(oData) {
+    if(oData && oData.content != undefined)
+        $('#' + this._oHtmlIds['subentry_votes'] + oData.content.subentry_id).html(oData.content.votes_formated);
+};
+
+BxAlbumsMain.prototype.loadingInButton = function(e, bShow) {
+    if($(e).length)
+        bx_loading_btn($(e), bShow);
+    else
+        bx_loading($('body'), bShow);
+};
+
+/** @} */

+ 241 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/css/main.css

@@ -0,0 +1,241 @@
+
+@import url(../../../../base/text/template/css/main.css);
+
+
+/* flexbox */
+.bx-albums-medias-wrapper {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+
+    /* makes all items on a row equal height */
+    -webkit-box-align: stretch;
+    -webkit-align-items: stretch;
+    -ms-flex-align: stretch;
+    align-items: stretch;
+
+    /* wrap onto the next line rather than stretching or shrinking */
+    -webkit-flex-wrap: wrap;
+    -ms-flex-wrap: wrap;
+    flex-wrap: wrap;
+
+    /* tells flexbox to start items from the left */
+    -webkit-box-pack: start;
+    -ms-flex-pack: start;
+    plex-pack: start;
+    -webkit-justify-content: flex-start;
+    justify-content: flex-start;
+}
+
+.bx-albums-medias-wrapper .bx-albums-media-wrapper {
+    -webkit-box-flex: 0;
+
+    -webkit-flex: 0 0 100%;
+    -ms-flex: 0 0 100%;
+    flex: 0 0 100%;
+
+    max-width: 100%;
+}
+
+.bx-albums-media-wrapper .bx-albums-unit-size {
+    width: 100%;
+    height: auto;
+    min-height: 10rem;
+    object-fit: cover;
+}
+	
+/* MEDIA: phone2 */
+
+.bx-media-phone2 .bx-layout-column-half .bx-albums-medias-wrapper .bx-albums-media-wrapper,
+.bx-media-phone2 .bx-layout-column-thin .bx-albums-medias-wrapper .bx-albums-media-wrapper {
+    -webkit-flex: 0 0 49.8%;
+    -ms-flex: 0 0 49.8%;
+    flex: 0 0 49.8%;
+    
+    max-width: 49.8%;
+}
+
+/* MEDIA: tablet2 */
+
+.bx-media-tablet2 #sys_search_results .bx-albums-medias-wrapper .bx-albums-media-wrapper,
+.bx-media-tablet2 .bx-layout-column-wide .bx-albums-medias-wrapper .bx-albums-media-wrapper,
+.bx-media-tablet2 .bx-layout-column-fullwidth .bx-albums-medias-wrapper .bx-albums-media-wrapper {
+    -webkit-flex: 0 0 49.8%;
+    -ms-flex: 0 0 49.8%;
+    flex: 0 0 49.8%;
+    
+    max-width: 49.8%;
+}
+
+.bx-media-tablet2 .bx-layout-column-wide .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size {
+    width: 100%;
+    height: auto;
+}
+
+.bx-media-tablet2 #sys_search_results .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size,
+.bx-media-tablet2 .bx-layout-column-fullwidth .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size {
+    height: 18.0rem;
+}
+
+/* MEDIA: desktop */
+
+.bx-media-desktop .bx-layout-column-wide .bx-albums-medias-wrapper .bx-albums-media-wrapper {
+    -webkit-flex: 0 0 49.8%;
+    -ms-flex: 0 0 49.8%;
+    flex: 0 0 49.8%;
+    
+    max-width: 49.8%;
+}
+
+.bx-media-desktop .bx-layout-column-wide .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size {
+    width: 100%;
+    height: auto;
+}
+    
+.bx-media-desktop #sys_search_results .bx-albums-medias-wrapper .bx-albums-media-wrapper,
+.bx-media-desktop .bx-layout-column-fullwidth .bx-albums-medias-wrapper .bx-albums-media-wrapper {
+    -webkit-flex: 0 0 33.25%;
+    -ms-flex: 0 0 33.25%;
+    flex: 0 0 33.25%;
+    
+    max-width: 33.25%;
+}
+
+.bx-media-desktop #sys_search_results .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size,
+.bx-media-desktop .bx-layout-column-half .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size,
+.bx-media-desktop .bx-layout-column-fullwidth .bx-albums-medias-wrapper .bx-albums-media-wrapper .bx-albums-unit-size {
+    height: 18.0rem;
+}
+
+.bx-search-result-block .bx-base-text-unit-gallery-wrapper {
+	display: block;
+}
+.bx-search-result-block.bx-base-text-unit-gallery-wrapper .bx-base-text-unit.bx-base-text-unit-gallery {
+	display: inline-block;
+}
+
+.bx-albums-media-thumb {
+    position: relative;    
+}
+.bx-albums-media-thumb a {
+    position: relative;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-justify-content: center;
+    justify-content: center;
+    -webkit-align-items: center;
+    align-items: center;
+}
+.bx-albums-media-play {
+    position: absolute;
+
+    width: 3rem;
+    height: 3rem;
+
+    background-color: rgba(255, 255, 255, 0.3);
+
+    text-align: center;
+    line-height: 3rem;
+    font-size: 1.5rem;
+}
+.bx-albums-media-duration {
+    position: absolute;
+    right: 10px;
+    bottom: 10px;
+
+    background-color: rgba(255, 255, 255, 0.9);
+}
+.bx-albums-media-caption {
+    white-space:nowrap;
+    overflow:hidden;
+    text-overflow:ellipsis;
+}
+.bx-albums-media-actions {
+    text-align: center;
+}
+.bx-base-text-unit-ext .bx-albums-unit-text-cont {
+    text-align: left;
+}
+.bx-albums-unit-images {
+    white-space:nowrap;
+    width:100%;
+    overflow: hidden;
+}
+
+.bx-albums-unit-image {
+    display: inline-block;
+    margin-right: 0.125rem;
+}
+
+.bx-albums-unit-image,
+.bx-albums-unit-image img {
+    height: 11.25rem;
+}
+.bx-albums-unit-image {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-justify-content: center;
+    justify-content: center;
+    -webkit-align-items: center;
+    align-items: center;
+}
+.bx-base-text-unit-gallery .bx-albums-unit-images-cont {
+    padding: 0.125rem 0.125rem 0 0.125rem;
+}
+.bx-base-text-unit-gallery .bx-albums-unit-text-cont {
+    line-height: 150%;
+}
+.bx-base-text-unit-gallery .bx-albums-unit-text-cont .bx-base-text-unit-title {
+    text-align: left;
+}
+
+.bx-albums-media-file {
+    text-align: center;    
+}
+
+.bx-albums-media-file img,
+.bx-albums-media-file video {
+    max-width:100%;
+}
+
+.bx-albums-media-title {
+    position:relative;
+    padding-right:6rem;
+}
+
+.bx-albums-media-title h1, 
+.bx-albums-media-title h2, 
+.bx-albums-media-title p {
+    margin:0;
+}
+
+.bx-albums-media-controls {
+    position:absolute;
+    top:0;
+    right:0;
+}
+
+.pswp__caption .pswp__caption__center {
+    text-align: center;
+}
+
+.pswp__video {
+    position:absolute;
+    text-align: center;
+    top:0;
+    bottom:0;
+    left:0;
+    right:0;
+}
+
+.pswp__video:before {
+  content: "";
+  display: inline-block;
+  vertical-align: middle;
+  height: 100%;
+}
+
+.pswp__video video {
+    vertical-align: middle;    
+}

+ 25 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/form_ghost_template.html

@@ -0,0 +1,25 @@
+<div id="bx-uploader-file-{storage_object}-{file_id}" class="bx-uploader-ghost bx-def-margin-sec-top bx-clearfix">
+    <a class="bx-anchor-invisible" name="album-media-{file_id}"></a>
+    <input type="hidden" name="__name__[]" value="{file_id}" />
+    <div class="bx-base-general-icon-wrapper bx-def-margin-sec-right">
+        <img src="{file_icon}" class="bx-def-round-corners bx-base-general-icon bx-base-general-icon-{file_id}" />
+    </div>
+    <span class="bx-base-general-uploader-ghost">
+        <b><bx_text:_bx_albums_form_entry_file_title /></b>
+        <br />
+        <input class="bx-def-font-inputs bx-form-input-text bx-def-margin-sec-bottom" type="text" value="{file_title_attr}" name="title-{file_id}" /> <br />
+
+        <a class="bx-btn bx-btn-small bx-def-margin-sec-right" href="javascript:void(0);" onclick="bx_base_general_delete_ghost('{file_id}', '{file_url}', '{file_icon}', ['__editor_id__'], {js_instance_name});"><bx_text:_sys_txt_form_entry_input_picture_delete /></a>
+
+        <bx_if:set_thumb>
+            <span class="bx-base-general-use-as-thumb">
+                <input type="checkbox" name="__name_thumb__[]" value="{file_id}" onclick="bx_base_general_select_thumb(this)" id="__name_thumb__-{file_id}" /> 
+                <label for="__name_thumb__-{file_id}"><bx_text:_sys_txt_form_entry_input_picture_use_as_thumb /></label>
+            </span>
+        </bx_if:set_thumb>
+
+    </span>
+</div>
+<script>
+    $('#bx-uploader-file-{storage_object}-{file_id} .bx-base-general-use-as-thumb input[value="__thumb_id__"]').attr('checked', true);
+</script>

+ 37 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 55 (78076) - https://sketchapp.com -->
+    <title>conversations copy 2</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <path d="M35.8333333,27.6428571 L35.8333333,28.7946429 C35.8333333,30.7030078 34.2290451,32.25 32.25,32.25 L3.58333333,32.25 C1.60428819,32.25 0,30.7030078 0,28.7946429 L0,10.3660714 C0,8.45770647 1.60428819,6.91071429 3.58333333,6.91071429 L4.77777778,6.91071429 L4.77777778,21.8839286 C4.77777778,25.0594018 7.45691667,27.6428571 10.75,27.6428571 L35.8333333,27.6428571 Z M43,21.8839286 L43,3.45535714 C43,1.54699219 41.3957118,0 39.4166667,0 L10.75,0 C8.77095486,0 7.16666667,1.54699219 7.16666667,3.45535714 L7.16666667,21.8839286 C7.16666667,23.7922935 8.77095486,25.3392857 10.75,25.3392857 L39.4166667,25.3392857 C41.3957118,25.3392857 43,23.7922935 43,21.8839286 Z M19.1111111,6.91071429 C19.1111111,8.81907924 17.5068229,10.3660714 15.5277778,10.3660714 C13.5487326,10.3660714 11.9444444,8.81907924 11.9444444,6.91071429 C11.9444444,5.00234933 13.5487326,3.45535714 15.5277778,3.45535714 C17.5068229,3.45535714 19.1111111,5.00234933 19.1111111,6.91071429 Z M11.9444444,17.2767857 L16.0887934,13.2804492 C16.4386163,12.94312 17.0058281,12.94312 17.3557257,13.2804492 L20.3055556,16.125 L30.4221267,6.36973493 C30.7719497,6.03240569 31.3391615,6.03240569 31.689059,6.36973493 L38.2222222,12.6696429 L38.2222222,20.7321429 L11.9444444,20.7321429 L11.9444444,17.2767857 Z" id="path-4"></path>
+        <filter x="-4.7%" y="-3.1%" width="109.3%" height="112.4%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Artboard" transform="translate(-1312.000000, -430.000000)">
+            <g id="conversations-copy-2" transform="translate(1312.000000, 430.000000)">
+                <mask id="mask-2" fill="white">
+                    <use xlink:href="#path-1"></use>
+                </mask>
+                <use id="Path" fill="#00B356" xlink:href="#path-1"></use>
+                <g id="images" mask="url(#mask-2)" fill-rule="nonzero">
+                    <g transform="translate(11.000000, 16.000000)" id="Shape">
+                        <g>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
+                            <use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 20 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/media-edit.html

@@ -0,0 +1,20 @@
+<div class="bx-albums-media-edit bx-def-color-bg-block">
+    <div class="bx-albums-media-edit-cnt bx-def-padding">
+        __form__
+        <script type="text/javascript">
+            $(document).ready(function () {
+                $("#__form_id__").ajaxForm({ 
+                    dataType: "json",
+                    beforeSubmit: function (formData, jqForm, options) {
+                        bx_loading($("#__form_id__"), true);
+                    },
+                    success: function (oData) {
+                        $(".bx-popup-applied:visible").dolPopupHide();
+
+                        processJsonData(oData);
+                    }
+                });
+            });
+        </script>
+    </div>
+</div>

+ 31 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/media-view.html

@@ -0,0 +1,31 @@
+<div class="bx-albums-media-view">
+    <div class="bx-albums-media-title bx-def-margin-sec-bottom">
+        <h2>__album__</h2>
+        <p>__title__</p>
+        <div class="bx-albums-media-controls bx-btn-group">
+            <bx_if:prev>
+                <a class="bx-btn" onclick="bx_albums_reload_page('__url__', '__title_js_string__'); return false;" href="__url__" title="__title_attr__"><i class="sys-icon angle-double-left"></i></a>
+            </bx_if:prev>
+            <bx_if:prev-na>
+                <a class="bx-btn bx-btn-disabled" href="javascript:void(0);"><i class="sys-icon angle-double-left"></i></a>
+            </bx_if:prev-na>
+            <bx_if:next>
+                <a class="bx-btn" onclick="bx_albums_reload_page('__url__', '__title_js_string__'); return false;" href="__url__" title="__title_attr__"><i class="sys-icon angle-double-right"></i></a>
+            </bx_if:next>
+            <bx_if:next-na>
+                <a class="bx-btn bx-btn-disabled" href="javascript:void(0);"><i class="sys-icon angle-double-right"></i></a>
+            </bx_if:next-na>
+        </div>
+    </div>
+    <div class="bx-albums-media-file">
+        <bx_if:image>
+            <a href="javascript:void(0);"  onclick="bx_albums_open_gallery(event || window.event, this, '__context__')" data-media-id="__media_id__" data-url="__url__" data-src="__url_img__" data-w="__w__" data-h="__h__" data-title="__title_attr__">
+                <img src="__url_img__" alt="__title_attr__" />
+            </a>
+        </bx_if:image>
+        <bx_if:video>
+            __video__
+        </bx_if:video>
+    </div>
+</div>
+__js_code__

+ 24 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/unit.html

@@ -0,0 +1,24 @@
+<div class="bx-base-text-unit bx-base-text-unit-ext bx-def-box bx-def-round-corners bx-def-color-bg-box bx-def-margin-bottom">
+	<div class="bx-albums-unit-text-cont bx-def-padding-top bx-def-padding-sec-bottom bx-def-padding-leftright">
+	    <h2 class="bx-base-text-unit-title"><a href="__content_url__">__title__</a></h2>
+	    <div class="bx-base-text-unit-info bx-def-margin-thd-top bx-def-margin-sec-bottom">
+            <bx_if:meta><div class="bx-base-general-unit-meta">__meta__</div></bx_if:meta>
+        </div>
+	    <div class="bx-base-text-unit-summary bx-clearfix">__summary__</div> 
+	</div>
+    <div class="bx-albums-unit-images-cont bx-def-padding-thd-leftright bx-def-padding-bottom">
+        <div class="bx-albums-unit-images bx-clearfix">
+            <bx_repeat:browse>
+                <a class="bx-albums-unit-image" title="__title_attr__" href="__url__">
+                    <img alt="__title_attr__" src="__img_url__" />
+                    <bx_if:show_play>
+                        <div class="bx-albums-media-play bx-def-round-corners"><i class="sys-icon play"></i></div>
+                    </bx_if:show_play>
+                    <bx_if:show_duration>
+                        <div class="bx-albums-media-duration bx-def-padding-sec-leftright bx-def-padding-thd-topbottom bx-def-border bx-def-round-corners bx-def-font">__duration__</div>
+                    </bx_if:show_duration>
+                </a>
+            </bx_repeat:browse>
+        </div> 
+    </div> 
+</div>

+ 15 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/unit_gallery.html

@@ -0,0 +1,15 @@
+<div class="bx-base-text-unit bx-base-text-unit-gallery bx-def-gal-unit-size bx-def-padding-sec">
+    <div class="bx-base-text-unit-cnt bx-def-box bx-def-round-corners bx-def-color-bg-box">
+        <div class="bx-albums-unit-images-cont">
+            <div class="bx-albums-unit-images bx-def-box-round-corners-int bx-clearfix">
+                <bx_repeat:browse><a class="bx-albums-unit-image" title="__title_attr__" href="__url__"><img alt="__title_attr__" src="__img_url__" /></a></bx_repeat:browse>
+            </div> 
+        </div>
+        <div class="bx-albums-unit-text-cont bx-def-padding-leftright bx-def-padding-sec-topbottom bx-def-font-align-center">
+            <div class="bx-base-text-unit-title bx-def-font-bold"><a class="bx-def-font-color" href="__content_url__">__title__</a></div>
+            <div class="bx-base-text-unit-info bx-def-font-middle">
+                <bx_if:meta><div class="bx-base-general-unit-meta">__meta__</div></bx_if:meta>
+            </div>
+        </div>
+    </div>
+</div>

+ 24 - 0
modules/boonex/albums/updates/9.0.12_10.0.0/source/template/unit_media.html

@@ -0,0 +1,24 @@
+<div class="__class__ bx-albums-media-wrapper bx-def-padding-sec bx-def-box-sizing">
+    <div class="bx-albums-media-cnt bx-def-box bx-def-image-bg-block bx-def-color-bg-block bx-def-border-block bx-shadow-block bx-def-padding">
+	    <div class="bx-albums-media-thumb bx-albums-unit-size bx-def-centered">
+	        <bx_if:image>
+	            <a href="__url__" title="__title_attr__">
+	                <img class="bx-albums-unit-size" src="__url_img__" alt="__title_attr__" />
+	            </a>
+	        </bx_if:image>
+	        <bx_if:video>
+	            <a href="__url__" title="__title_attr__">
+	                <img class="bx-albums-unit-size" src="__url_img__" alt="__title_attr__" />
+                        <div class="bx-albums-media-play bx-def-round-corners"><i class="sys-icon play"></i></div>
+	            </a>
+                    <bx_if:show_duration>
+                        <div class="bx-albums-media-duration bx-def-padding-sec-leftright bx-def-padding-thd-topbottom bx-def-border bx-def-round-corners bx-def-font">__duration__</div>
+                    </bx_if:show_duration>
+	        </bx_if:video>
+	    </div>
+	    <div class="bx-albums-media-caption bx-def-margin-sec-topbottom">
+                <a href="__url__" title="__title_attr__">__title__<a/>
+            </div>
+	    <div class="bx-albums-media-actions bx-def-margin-sec-leftright-neg">__actions__</div>
+    </div>
+</div>

+ 469 - 0
modules/boonex/analytics/updates/9.0.1_10.0.0/source/classes/BxAnalyticsModule.php

@@ -0,0 +1,469 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+* Copyright (c) UNA, Inc - https://una.io
+* MIT License - https://opensource.org/licenses/MIT
+*
+* @defgroup    Analytics Analytics
+* @ingroup     UnaModules
+*
+* @{
+*/
+
+/**
+ * Analytics module
+ */     
+define('BX_ANALYTICS_SYSTEM', 'system');
+define('BX_ANALYTICS_TOP_BY_LIKES', 'top_by_likes');
+define('BX_ANALYTICS_TOP_BY_VIEWS', 'top_by_views');
+define('BX_ANALYTICS_CONTENT_TOTAL', 'content_total');
+define('BX_ANALYTICS_CONTENT_SPEED', 'content_speed');
+define('BX_ANALYTICS_MOST_FOLLOWED_PROFILES', 'top_by_followers');
+define('BX_ANALYTICS_MOST_ACTIVE_PROFILES', 'top_by_activity');
+class BxAnalyticsModule extends BxDolModule
+{
+    protected $aColors = array('#3366CC', '#DC3912', '#FF9900', '#109618', '#990099');
+          
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+          
+    /**
+    * Service methods
+    */
+          
+    /**
+    * @page service Service Calls
+    * @section bx_analytics Analytics
+    * @subsection bx_analytics-other Other
+    * @subsubsection bx_analytics get_canvas
+    * 
+    * @code bx_srv('bx_analytics', 'get_canvas', [...]); @endcode
+    * 
+    * Get canvas  
+    * 
+    * @return an html. 
+    * 
+    * @see BxAnalyticsModule::serviceGetCanvas
+    */
+    /** 
+    * @ref bx_analytics-get_canvas "get_canvas"
+    */
+    public function serviceGetCanvas()
+    {
+        return $this->_oTemplate->getCanvas();
+    }
+          
+    /**
+    * @page service Service Calls
+    * @section bx_analytics Analytics
+    * @subsection bx_analytics-other Other
+    * @subsubsection bx_analytics get_modules
+    * 
+    * @code bx_srv('bx_analytics', 'get_modules', [...]); @endcode
+    * 
+    * Get modules list  
+    * 
+    * @return an html. 
+    * 
+    * @see BxAnalyticsModule::serviceGetModules
+    */
+    /** 
+    * @ref bx_analytics-get_modules "get_modules"
+    */
+    public function serviceGetModules()
+    {
+        $aResult = array();
+        $aResult2 = array();
+        $aResult[BX_ANALYTICS_SYSTEM] = _t('_bx_analytics_system_text');
+        $BxDolModuleQuery = BxDolModuleQuery::getInstance();
+        $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
+        foreach($aModules as $aModule){
+            $oModule = BxDolModule::getInstance($aModule['name']);
+            if($oModule instanceof iBxDolContentInfoService){
+                $aResult[$aModule['name']] = $aModule['title'];
+            }
+        }
+        return array_merge($aResult, $aResult2);
+    }
+          
+    /**
+    * Action methods
+    */
+          
+    public function actionGetReports($sModuleName)
+    {
+        if(!BxDolAcl::getInstance()->isMemberLevelInSet(192))
+            return '';
+            
+        header('Content-Type: application/json');
+             
+        $aSystemsVote = BxDolVote::getSystems();
+        $aRv = array();
+        if ($sModuleName == BX_ANALYTICS_SYSTEM){
+            $aRv[BX_ANALYTICS_TOP_BY_LIKES] = _t('_bx_analytics_type_top_contents_by_likes');
+            $aRv[BX_ANALYTICS_TOP_BY_VIEWS] = _t('_bx_analytics_type_top_by_views');
+            $aRv[BX_ANALYTICS_CONTENT_TOTAL] = _t('_bx_analytics_type_accounts_growth');
+            $aRv[BX_ANALYTICS_CONTENT_SPEED] = _t('_bx_analytics_type_accounts_speed');
+        }
+        else{
+            $oModule = BxDolModule::getInstance($sModuleName);
+                  
+            if(BxDolRequest::serviceExists($sModuleName, 'act_as_profile') && BxDolService::call($sModuleName, 'act_as_profile') == true){
+                $aRv[BX_ANALYTICS_MOST_FOLLOWED_PROFILES] = _t('_bx_analytics_type_most_followed_profiles');
+                $aRv[BX_ANALYTICS_MOST_ACTIVE_PROFILES] = _t('_bx_analytics_type_most_active_profiles');
+            }
+                  
+            if(isset($oModule->_oConfig->CNF['OBJECT_VOTES']) && isset($aSystemsVote[$oModule->_oConfig->CNF['OBJECT_VOTES']])){
+                $aRv[BX_ANALYTICS_TOP_BY_LIKES] = _t('_bx_analytics_type_top_contents_by_likes');
+            }
+                  
+            if(isset($oModule->_oConfig->CNF['OBJECT_VIEWS'])){
+                $aRv[BX_ANALYTICS_TOP_BY_VIEWS] = _t('_bx_analytics_type_top_by_views');
+            }
+                  
+            $aRv[BX_ANALYTICS_CONTENT_TOTAL] = _t('_bx_analytics_type_content_growth');
+            $aRv[BX_ANALYTICS_CONTENT_SPEED] = _t('_bx_analytics_type_content_speed');
+        }
+        echo json_encode($aRv);
+    }
+          
+    public function actionGetReportsData($sModuleName, $sReportName, $sDateFrom, $sDateTo, $sType = '')
+    {
+        if(!BxDolAcl::getInstance()->isMemberLevelInSet(192))
+            return '';
+        
+        if ($sType == 'csv'){
+            header('Content-type: text/csv');
+            header('Content-disposition: attachment;filename=' . $sModuleName . '_' . $sReportName . '_' . $sDateFrom . '_' . $sDateTo . '.csv');
+            echo $this->actionGetReportsDataCsv($sModuleName, $sReportName, $sDateFrom, $sDateTo);
+            
+        }
+        
+        if ($sType == ''){
+            header('Content-Type: application/json');
+            echo $this->actionGetReportsDataJson($sModuleName, $sReportName, $sDateFrom, $sDateTo);
+        }
+            
+    }
+    
+    private function actionGetReportsDataCsv($sModuleName, $sReportName, $sDateFrom, $sDateTo)
+    {
+        $sRv = '';
+        $sColumn = ";";
+        $sRow = "\n";
+        $sData = $this->actionGetReportsDataJson($sModuleName, $sReportName, $sDateFrom, $sDateTo);
+        $oRv = json_decode($sData, true); 
+        $oData = $oRv['data'];
+        $sCol1 = $oRv['strings'][0];
+        $iColumnCount = count($oData['datasets']);
+        $sRv .= $sCol1 . $sColumn;
+        foreach($oData['datasets'] as $aItem){
+            $sRv .= ($aItem['label'] != '' ? $aItem['label'] : $oRv['strings'][1]) . $sColumn;
+        }
+   
+        $sRv .= $sRow;
+        $iK = 0;
+        foreach($oData['datasets'][0]['data'] as $sDx => $aItemData){
+            $sTxt = "";
+            if (is_array($oData['datasets'][0]['data'][$sDx]))
+                $sTxt = $oData['datasets'][0]['data'][$sDx]['x'];
+            else
+                $sTxt = $oData['labels'][$sDx];
+            if (isset($oRv['links']) && count($oRv['links'])>0) {
+                $sTxt .= ' (' . $oRv['links'][$sDx] . ')';
+            }
+            
+            $sRv .= $sTxt . $sColumn;
+            for ($i = 0; $i < $iColumnCount; $i++){
+                $sText = '';
+                if (is_array($aItemData)) {
+                    $sText = $aItemData['y'];
+                }
+                else {
+                    $sText = $aItemData;
+                }
+                $sRv .= $sText . $sColumn;
+            }
+            $sRv .= $sRow;
+            $iK++;
+        }
+        echo $sRv;
+    }
+    
+    private function actionGetReportsDataJson($sModuleName, $sReportName, $sDateFrom, $sDateTo)
+    { 
+        $iDateFrom = strtotime($sDateFrom);
+        $iDateTo = strtotime($sDateTo) + 86400;
+        $sType = "bar";
+        $bIsTimeX = false;
+        $iMinValueY = 0;
+        $iMaxValueY = 0;
+        $bDefaultFillData = true;
+        $aValues = array('labels' => array(), 'values' => array(array('legend' => '', 'data' => array())), 'links' => array(), 'strings' => array(0 => _t('_bx_analytics_txt_item'), 1 => _t('_bx_analytics_txt_value')));
+   
+        if ($sModuleName != BX_ANALYTICS_SYSTEM){
+            $oModule = BxDolModule::getInstance($sModuleName);
+            $aValues['strings'][0] = $oModule->_aModule['title'];
+            $aValues['strings'][1] = _t('_bx_analytics_type_' . $sReportName . '_label');
+        }
+        else{
+            $aValues['strings'][0] = _t('_bx_analytics_txt_total_content');
+            $aValues['strings'][1] = _t('_bx_analytics_type_' . $sReportName . '_label');
+        }
+              
+        switch ($sReportName) {
+            case BX_ANALYTICS_CONTENT_TOTAL:
+            case BX_ANALYTICS_CONTENT_SPEED:
+                $sType = "line";
+                $bIsTimeX = true;
+                $sTableName = '';
+                $aValues['strings'][0] = _t('_bx_analytics_txt_date');
+                $bDefaultFillData = false;
+                if ($sModuleName != BX_ANALYTICS_SYSTEM){
+                    $oModule = BxDolModule::getInstance($sModuleName);
+                    if (isset($oModule->_oConfig->CNF['TABLE_ENTRIES']))
+                        $sTableName = $oModule->_oConfig->CNF['TABLE_ENTRIES'];
+                    $aValues['strings'][1] = ($sReportName == BX_ANALYTICS_CONTENT_TOTAL ? _t('_bx_analytics_txt_total_count', $oModule->_aModule['title']) : _t('_bx_analytics_txt_count', $oModule->_aModule['title']));
+                }
+                else{
+                    $sTableName = 'sys_accounts';
+                    $aValues['strings'][1] = ($sReportName == BX_ANALYTICS_CONTENT_TOTAL ? _t('_bx_analytics_txt_total_count', _t('_bx_analytics_txt_accounts')) : _t('_bx_analytics_txt_count', _t('_bx_analytics_txt_accounts')));
+                }
+                if (isset($oModule) && isset($oModule->_oConfig->CNF['FIELD_ADDED']))
+                    $sColumnAdded = $oModule->_oConfig->CNF['FIELD_ADDED'];
+                else
+                    $sColumnAdded = 'added';
+                if ($sColumnAdded != ''){
+                    $aData = $this->_oDb->getGrowth($sTableName, $sColumnAdded, $iDateFrom, $iDateTo);
+                    $iValuePrev = $this->_oDb->getGrowthInitValue($sTableName, $sColumnAdded, $iDateFrom);
+                    $aTmpDates = array();
+                    foreach ($aData as $aValue) {
+                        $sX = $aValue['period'];
+                        $aTmpDates[$sX] = $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' => $sReportName == BX_ANALYTICS_CONTENT_TOTAL ? $iValuePrev : 0));
+                        }
+                        else{
+                            array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportName == BX_ANALYTICS_CONTENT_TOTAL ? ($iValuePrev + $aTmpDates[$sX]) : $aTmpDates[$sX]));
+                            $iValuePrev += $aTmpDates[$sX];
+                        }
+                        //array_push($aValues['labels'], $sX);
+                        if ($sReportName == BX_ANALYTICS_CONTENT_TOTAL){
+                            if ($iValuePrev > $iMaxValueY)
+                                $iMaxValueY = $iValuePrev;
+                        }
+                        else{
+                            if (array_key_exists($sX, $aTmpDates) && $aTmpDates[$sX] > $iMaxValueY)
+                                $iMaxValueY = $aTmpDates[$sX];
+                        } 
+                    }
+                }
+                break;
+                  
+            case BX_ANALYTICS_TOP_BY_LIKES:
+                $bDefaultFillData = false;
+                $this->getViewsOrVotes(BxDolVote::getSystems(), 'OBJECT_VOTES', $sModuleName, $iDateFrom, $iDateTo, $aValues, $iMaxValueY, $iMinValueY);
+                break;
+                  
+            case BX_ANALYTICS_TOP_BY_VIEWS:
+                $bDefaultFillData = false;
+                $this->getViewsOrVotes(BxDolView::getSystems(), 'OBJECT_VIEWS', $sModuleName, $iDateFrom, $iDateTo, $aValues, $iMaxValueY, $iMinValueY);
+                break;
+                  
+            case BX_ANALYTICS_MOST_FOLLOWED_PROFILES:
+                $oModule = BxDolModule::getInstance($sModuleName);
+                $aData = $this->_oDb->getMostFollowedProfiles($sModuleName, $iDateFrom, $iDateTo);
+                break;
+                  
+            case BX_ANALYTICS_MOST_ACTIVE_PROFILES:
+                $aData = array();
+                $oModule = BxDolModule::getInstance($sModuleName);
+                $aTmp = $this->getSelectedModules();
+                foreach($aTmp[0] as $sContentModule){
+                    $oContentModule = BxDolModule::getInstance($sContentModule);
+                    if ($oContentModule && isset($oContentModule->_oConfig->CNF['TABLE_ENTRIES']) && isset($oContentModule->_oConfig->CNF['FIELD_AUTHOR'])){
+                        $sContentTable = $oContentModule->_oConfig->CNF['TABLE_ENTRIES'];
+                        $sColumnAuthor = $oContentModule->_oConfig->CNF['FIELD_AUTHOR'];
+                        $sColumnAdded = $oContentModule->_oConfig->CNF['FIELD_ADDED'];
+                        if (!empty($sContentTable) && !empty($sColumnAuthor) && !empty($sColumnAdded) && (!BxDolRequest::serviceExists($sContentModule, 'act_as_profile') || BxDolService::call($sContentModule, 'act_as_profile') == false)){
+                            $aData1 = $this->_oDb->getMostActiveProfiles($sModuleName, $sContentModule, $sContentTable, $sColumnAuthor, $sColumnAuthor, $sColumnAdded, $iDateFrom, $iDateTo);
+                            foreach($aData1 as $aTmp3){
+                                if (array_key_exists($aTmp3['object_id'], $aData))
+                                    $aData[$aTmp3['object_id']]['value'] += $aTmp3['value'];
+                                else
+                                    $aData[$aTmp3['object_id']] = $aTmp3;
+                            }
+                        }
+                    }
+                }
+                $aData = $this->sortArrayOfArraysAndSlice($aData, 'value', intval(getParam('bx_analytics_items_count')));
+                break;
+        }
+              
+        if ($bDefaultFillData){
+            foreach ($aData as $aValue) {
+                array_push($aValues['labels'], $this->getItemName($oModule->serviceGetTitle($aValue['object_id'])));
+                array_push($aValues['values'][0]['data'], $aValue['value']);
+                array_push($aValues['links'], $oModule->serviceGetLink($aValue['object_id']));
+                if ($aValue['value'] > $iMaxValueY)
+                    $iMaxValueY = $aValue['value'];
+            }
+        }
+        $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' => true
+                ),
+                'display' => true
+            );
+        }
+       
+        $aDataForChartDatasets = array();
+        for($i = 0; $i < count($aValues['values']); $i++){
+            $aDataForChartDatasets[] = array(
+                'label' => $aValues['values'][$i]['legend'],
+                'fill' => false,
+                'backgroundColor' => $this->aColors[$i],
+                'borderColor' => $this->aColors[$i],
+                'borderWidth' => 2,
+                '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
+                ),
+                'elements' => array(
+                    'point'=> array(
+                        'radius' => 0
+                    )
+                ),
+                'scales' => array(
+                    'yAxes' => array(
+                        array(
+                            'ticks' => array(
+                                'max' => $iMaxValueY, 
+                                'min' => $iMinValueY, 
+                                'stepSize' => $this->getStep($iMinValueY, $iMaxValueY), 
+                                'autoSkip' => true
+                            )
+                        )
+                    ),
+                    'xAxes' => array($aDataForChartXAxes)
+                )
+            ),
+            'links' => $aValues['links'],
+            'strings' => $aValues['strings'],
+        );
+        
+        return json_encode($aDataForChart);
+    }
+          
+    public function getSelectedModules()
+    {
+        $aModulesList = $this->serviceGetModules();
+        $aModules = array_keys($aModulesList);
+        $sModulesDisabled = explode(',', getParam('bx_analytics_modules_disabled'));
+        return array(array_diff($aModules, $sModulesDisabled), $aModulesList);
+    }
+
+    private function getViewsOrVotes($aSystems, $sSystem, $sModuleName, $iDateFrom, $iDateTo, &$aValues, &$iMaxValueY, &$iMinValueY)
+    {
+        $aData = array();
+        if ($sModuleName != BX_ANALYTICS_SYSTEM){
+            $oModule = BxDolModule::getInstance($sModuleName);
+            $sSystem = $oModule->_oConfig->CNF['OBJECT_VIEWS'];
+            if(isset($aSystems[$sSystem]))
+                $aData = $this->_oDb->getTopContentByLikes($sModuleName, $aSystems[$sSystem]['table_track'], $iDateFrom, $iDateTo);
+        }
+        else{
+            $aTmp = $this->getSelectedModules();
+            foreach ($aTmp[0] as $sModule) {
+                if ($sModule != BX_ANALYTICS_SYSTEM){
+                    $oModule = BxDolModule::getInstance($sModule);
+                    if (isset($oModule->_oConfig->CNF['OBJECT_VIEWS'])){
+                        $sSystem = $oModule->_oConfig->CNF['OBJECT_VIEWS'];
+                        if(isset($aSystems[$sSystem])){
+                            $aData1 = $this->_oDb->getTopContentByLikes($sModule, $aSystems[$sSystem]['table_track'], $iDateFrom, $iDateTo);
+                            $aData = array_merge($aData, $aData1);
+                        }
+                    }
+                }
+            }
+            $aData = $this->sortArrayOfArraysAndSlice($aData, 'value', intval(getParam('bx_analytics_items_count')));
+        }
+        foreach ($aData as $aValue) {
+            $oModule = BxDolModule::getInstance($aValue['module']);
+            array_push($aValues['labels'], $this->getItemName($oModule->serviceGetTitle($aValue['object_id'])));
+            array_push($aValues['values'][0]['data'], $aValue['value']);
+            array_push($aValues['links'], $oModule->serviceGetLink($aValue['object_id']));
+            if ($aValue['value'] > $iMaxValueY)
+                $iMaxValueY = $aValue['value'];
+        }
+    }
+          
+    private function getStep($iMin, $iMax)
+    {
+        $iCount = 8;
+        return ceil(($iMax - $iMin) / $iCount);
+    }
+          
+    private function sortArrayOfArraysAndSlice($aArr, $sFld, $Count)
+    {
+        $aDataSort = array();
+        foreach ($aArr as $sKey => $oRow)
+        {
+            $aDataSort[$sKey] = $oRow[$sFld];
+        }
+        array_multisort($aDataSort, SORT_DESC, $aArr);
+        return array_slice($aArr, 0, $Count);
+    }
+          
+    private function getItemName($sString)
+    {
+        $sString = strip_tags($sString);
+        if ($sString == ''){
+            $sString = _t('_bx_analytics_txt_empty_title_item');
+        }
+        return $sString;
+    }
+}
+
+/** @} */

+ 77 - 0
modules/boonex/analytics/updates/9.0.1_10.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    Analytics Analytics
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_analytics',
+    'title' => 'Analytics',
+    'note' => 'Analytics module.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/analytics/',
+    'home_uri' => 'analytics',
+
+    'db_prefix' => 'bx_analytics_',
+    'class_prefix' => 'BxAnalytics',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Analytics',
+
+    /**
+     * 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(),
+);
+
+/** @} */

+ 39 - 0
modules/boonex/analytics/updates/9.0.1_10.0.0/source/install/langs/en.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+  <string name="_bx_analytics"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_adm_stg_cpt_type"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_adm_stg_cpt_category_general"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_page_block_title_canvas"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_page_block_title_system_canvas"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_adm_stg_cpt_modules_enabled"><![CDATA[Enabled for modules]]></string>
+  <string name="_bx_analytics_adm_stg_cpt_items_count"><![CDATA[Max number of items]]></string>
+  <string name="_bx_analytics_adm_stg_cpt_default_interval_day"><![CDATA[Default interval in days]]></string>
+  <string name="_bx_analytics_page_title_sys_page"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_page_title_page"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_page_block_title_system_canvas"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_page_block_title_canvas"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_item_title_system_analytics"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_item_title_analytics"><![CDATA[Analytics]]></string>
+  <string name="_bx_analytics_type_top_contents_by_likes"><![CDATA[Top contents by likes]]></string>
+  <string name="_bx_analytics_type_content_growth"><![CDATA[Total numbers]]></string>
+  <string name="_bx_analytics_type_content_speed"><![CDATA[Growth speed]]></string>
+  <string name="_bx_analytics_type_accounts_growth"><![CDATA[Accounts - Total numbers]]></string>
+  <string name="_bx_analytics_type_accounts_speed"><![CDATA[Accounts - Growth speed]]></string>
+  <string name="_bx_analytics_type_top_by_views"><![CDATA[Top by views]]></string>
+  <string name="_bx_analytics_type_most_followed_profiles"><![CDATA[Most followed profiles]]></string>
+  <string name="_bx_analytics_type_most_active_profiles"><![CDATA[Most active profiles]]></string>
+  <string name="_bx_analytics_system_text"><![CDATA[System]]></string>
+  <string name="_bx_analytics_txt_empty_title_item"><![CDATA[Empty title]]></string>
+  <string name="_bx_analytics_txt_item"><![CDATA[Item]]></string>
+  <string name="_bx_analytics_txt_date"><![CDATA[Date]]></string>
+  <string name="_bx_analytics_txt_value"><![CDATA[Value]]></string>
+  <string name="_bx_analytics_txt_total_count"><![CDATA[Total]]></string>
+  <string name="_bx_analytics_txt_count"><![CDATA[{0}]]></string>
+  <string name="_bx_analytics_txt_accounts"><![CDATA[Accounts]]></string>
+  <string name="_bx_analytics_txt_export_to_csv_title"><![CDATA[Export to CSV file]]></string>
+  <string name="_bx_analytics_txt_total_content"><![CDATA[All content]]></string>
+  <string name="_bx_analytics_type_top_by_views_label"><![CDATA[Views]]></string>
+  <string name="_bx_analytics_type_top_by_likes_label"><![CDATA[Likes]]></string>
+  <string name="_bx_analytics_type_top_by_followers_label"><![CDATA[Followed]]></string>
+  <string name="_bx_analytics_type_top_by_activity_label"><![CDATA[Content]]></string>
+</resources>

+ 151 - 0
modules/boonex/analytics/updates/9.0.1_10.0.0/source/js/analytics.js

@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Analytics Analytics
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxAnalytics(oOptions) {
+    this._sContainerId = 'bx_analytics_container';
+    this._sModuleSelector = '#' + this._sContainerId + ' .bx_analytics_module_selector';
+    this._sReportSelector = '#' + this._sContainerId + " .bx_analytics_report_selector";
+    this._sContainerDataSelector = '#' + this._sContainerId + " .bx_analytics_data";
+    this._sCanvasSelector = '#' + this._sContainerId + " .bx_analytics_grath";
+    this._sDatePickerSelector = '#' + this._sContainerId + " .bx_analytics_date_picker";
+    this._sExportUrlSelector = '#' + this._sContainerId + " .bx_analytics_export_url";
+    this._sActionsUri = oOptions.sActionUri;
+    this._aStrings = oOptions.aStrings;
+    var $this = this;
+    $(document).ready(function () {
+        $this.init(); 
+    });
+}
+
+BxAnalytics.prototype.init = function () {
+    var $this = this;
+    $($this._sModuleSelector).change(function () {
+        $this.reloadReports();
+    });
+    $($this._sReportSelector).change(function () {
+        $this.reloadData();
+    });
+    $this.reloadReports();
+
+    $($this._sDatePickerSelector).daterangepicker({
+        opens: 'left',
+        locale: {
+            "format": "DD/MM/YYYY"
+        },
+    }, function (start, end, label) {
+        $this.reloadData();
+    });
+
+}
+
+BxAnalytics.prototype.reloadReports = function () {
+    var $this = this;
+    $.getJSON($this._sActionsUri + 'GetReports/' + $($this._sModuleSelector).val() + '/', function (aReports) {
+        $($this._sReportSelector).empty();
+        $.each(aReports, function (key, value) {
+            $($this._sReportSelector).append('<option value="' + key + '">' + value + '</option>');
+        });
+        $this.reloadData();
+    });
+};
+
+BxAnalytics.prototype.reloadData = function () {
+    var $this = this;
+    bx_loading($($this._sContainerDataSelector), true);
+    $sUrl = $this._sActionsUri + 'GetReportsData/' + $($this._sModuleSelector).val() + '/' + $($this._sReportSelector).val() + '/' + $($this._sDatePickerSelector).data('daterangepicker').startDate.format('YYYY-MM-DD') + '/' + $($this._sDatePickerSelector).data('daterangepicker').endDate.format('YYYY-MM-DD') + '/';
+    $($this._sExportUrlSelector).attr('href', $sUrl + 'csv/');
+    $.getJSON($sUrl, function (oData) {
+        Chart.defaults.global.layout = {
+            padding: {
+                left: 0,
+                right: 0,
+                top: 0,
+                bottom: 0
+            }
+        }
+		
+        Chart.defaults.scale.ticks.callback = function (label, index, labels) {
+            if (label.length > 10)
+                return label.slice(0, 10) + '...';
+            else
+                return label;
+        };
+
+        
+        
+        bx_loading($($this._sContainerDataSelector), false);
+        var oDataForChart = oData.data || false;
+        var oChartOptions = oData.options || oOptionsDefault;
+        if ($this._oChart)
+            $this._oChart.destroy();
+        $this._oChart = new Chart($($this._sCanvasSelector), {
+            type: oData.type != undefined ? oData.type : 'line',
+            data: oDataForChart,
+            options: $.extend({}, $this._oChartOptionsDefault, oChartOptions)
+        });
+        $this.dataToTable(oData);
+    });
+};
+
+BxAnalytics.prototype.dataToTable = function (oDataIn) {
+    var $this = this;
+    var oData = oDataIn.data;
+    var sHtml = '<table>';
+    var sCol1 = oDataIn.strings[0];
+
+    var iColumnCount = oData.datasets.length;
+    sHtml += '<thead><tr><th> ' + sCol1 + '</th>';
+    $.each(oData.datasets, function (iDx, oItem) {
+        var sText = oItem.label;
+        sHtml += '<th>' + (oItem.label != '' ? oItem.label : oDataIn.strings[1]) + '</th>';
+    });
+
+    sHtml += '</tr></thead>';
+    var iK = 0;
+    
+    oData.datasets[0].data.forEach(function (oItemData, iDx) {
+        var sTxt = "";
+        if (oDataIn.options.scales.xAxes[0].type == 'time')
+            sTxt = oData.datasets[0].data[iDx].x;
+        else{
+            sTxt = oData.labels[iDx];
+        }
+        if (oDataIn.links && oDataIn.links.length > 0) {
+            sTxt = "<a href='" + oDataIn.links[iDx] + "'>" + sTxt + "</a>"
+        }
+        sHtml += '<tr><td>&nbsp;'+  sTxt + '</td>';
+        for (i = 0; i < iColumnCount; i++) {
+            var sText = '';
+            if (typeof oData.datasets[i].data[iDx] === 'object') {
+                sText = oData.datasets[i].data[iDx].y;
+            }
+            else {
+                sText = oData.datasets[i].data[iDx];
+            }
+            sHtml += '<td>' + sText + '</td>';
+        }
+        sHtml += '</tr>';
+        iK++;
+    });
+
+    sHtml += '</tr><tbody></table>';
+    if ($this._oTable)
+        $this._oTable.destroy();
+    $('.bx_analytics_table').html(sHtml);
+
+    var $aOrder = [];
+    if (oDataIn.options.scales.xAxes[0].type == 'time') {
+        $aOrder = [[0, 'desc']];
+    }
+    $this._oTable = $('.bx_analytics_table').DataTable({ dom: '<"top"i>rt<"bottom"flp><"clear">', paging: true, searching: false, ordering: true, order: $aOrder });
+   
+};
+
+/** @} */

+ 67 - 0
modules/boonex/analytics/updates/9.0.1_10.0.0/source/template/css/main.css

@@ -0,0 +1,67 @@
+.bx_analytics_filters
+{
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-align: stretch;
+    -webkit-align-items: stretch;
+    -ms-flex-align: stretch;
+    align-items: stretch;
+    -webkit-flex-wrap: wrap;
+    -ms-flex-wrap: wrap;
+    flex-wrap: wrap;
+    -webkit-box-pack: start;
+    -ms-flex-pack: start;
+    plex-pack: start;
+    -webkit-justify-content: space-between;
+    justify-content: space-between;
+}
+
+.bx_analytics_filters .bx-def-font-inputs{
+    position: relative;
+    display: inline-block;
+    overflow: hidden;
+    width: calc(33% - 1rem);
+}
+
+.bx_analytics_data .bx-def-font-inputs {
+    width: calc(100%);
+    max-width:200px;
+    float:left;
+}
+
+.bx_analytics_grath_cnt {
+    width:100%;
+}
+
+.bx_analytics_grath_cnt .bx_analytics_grath{
+    width:100%;
+    height:100%;
+}
+
+.bx_analytics_data .dataTables_info {
+    display:none;
+}
+
+.bx_analytics_data .bx-grid-table th, .bx-grid-table td {
+    text-align: left;
+}
+.bx_analytics_data .bx-grid-table .odd
+{
+    background-color: rgba(210, 230, 250, 0.3);
+}
+.bx_analytics_data .bottom {
+    margin-top:1rem;
+}
+/* datatables fix*/
+table.dataTable thead .sorting:after { margin-left:10px; font-family: "sys-user", "sys-user-fal", sans-serif; content: "\f0dc"; display:inline-block }
+table.dataTable thead .sorting_asc:after{ margin-left:10px;font-family: "sys-user", "sys-user-fal", sans-serif; content: "\f0de"; display:inline-block}
+table.dataTable thead .sorting_desc:after{ margin-left:10px; font-family: "sys-user", "sys-user-fal", sans-serif; content: "\f0dd"; display:inline-block}
+table.dataTable.no-footer {border-bottom:none !important}
+table.dataTable thead th{border-bottom:none !important; padding: 10px 10px !important}
+table.dataTable thead .sorting {background-image: none !important}
+.bx-media-phone #bx_analytics_container .bx-grid-table 
+{
+	min-width: inherit !important;
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 11 - 0
modules/boonex/analytics/updates/9.0.1_10.0.0/source/template/images/icons/std-icon.svg


+ 43 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamAlertsResponse.php

@@ -0,0 +1,43 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * alerts handler
+ */
+class BxAntispamAlertsResponse extends BxDolAlertsResponse
+{
+    public function response($oAlert)
+    {
+        if ('account' == $oAlert->sUnit) {
+
+            switch ($oAlert->sAction) {
+                case 'check_login':
+                    $oAlert->aExtras['error_msg'] = BxDolService::call('bx_antispam', 'check_login');
+                    break;
+                case 'check_join';
+                    $oAlert->aExtras['error_msg'] = BxDolService::call('bx_antispam', 'check_join', array($oAlert->aExtras['email'], &$oAlert->aExtras['approve']));
+                    break;
+            }
+
+        } elseif ('system' == $oAlert->sUnit) {
+            
+            switch ($oAlert->sAction) {    
+                case 'check_spam':
+                    $oAlert->aExtras['content'] = BxDolService::call('bx_antispam', 'filter_spam', array($oAlert->aExtras['content']));
+                    if ((!isset($oAlert->aExtras['type']) || 'textarea' == $oAlert->aExtras['type']) && is_string($oAlert->aExtras['content']))
+                        $oAlert->aExtras['is_spam'] = BxDolService::call('bx_antispam', 'is_spam', array(&$oAlert->aExtras['content']));
+                    break;
+            }
+        }
+    }
+}
+
+/** @} */

+ 75 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamConfig.php

@@ -0,0 +1,75 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAntispamConfig extends BxDolModuleConfig
+{
+    /**
+     * map system options to the local options names
+     */
+    protected $_aOptionsMap = array (
+        'antispam_block' => 'bx_antispam_block',
+        'antispam_report' => 'bx_antispam_report',
+        'dnsbl_enable' => 'bx_antispam_dnsbl_enable',
+        'uridnsbl_enable' => 'bx_antispam_uridnsbl_enable',
+        'dnsbl_behaviour_login' => 'bx_antispam_dnsbl_behaviour_login',
+        'dnsbl_behaviour_join' => 'bx_antispam_dnsbl_behaviour_join',
+        'akismet_enable' => 'bx_antispam_akismet_enable',
+        'disposable_email_domains_mode' => 'bx_antispam_disposable_email_domains_mode',
+        'disposable_email_domains_behaviour_join' => 'bx_antispam_disposable_email_domains_behaviour_join',
+        'profanity_enable' => 'bx_antispam_profanity_filter_enable',
+    );
+    /**
+     * default local options, it is filled in with real system options in class contructor, @see restoreAntispamOptions
+     */
+    protected $_aOptions = array (
+        'antispam_block' => '',
+        'antispam_report' => '',
+        'dnsbl_enable' => '',
+        'uridnsbl_enable' => '',
+        'dnsbl_behaviour_login' => 'block',
+        'dnsbl_behaviour_join' => 'approval',
+        'akismet_enable' => '',
+        'profanity_enable' => '',
+    );
+
+    public function __construct($aModule)
+    {
+        parent::__construct($aModule);
+        $this->restoreAntispamOptions ();
+    }
+
+    /**
+     * Set local option value, system value stays intact, useful for testing and debugging
+     */
+    public function setAntispamOption ($sOption, $mixedVal)
+    {
+        $this->_aOptions[$sOption] = $mixedVal;
+    }
+
+    /**
+     * Get an option, local value
+     */
+    public function getAntispamOption ($sOption)
+    {
+        return $this->_aOptions[$sOption];
+    }
+
+    /**
+     * set local options values from system options
+     */
+    public function restoreAntispamOptions ()
+    {
+        foreach ($this->_aOptionsMap as $sNameLocal => $sNameParam)
+            $this->setAntispamOption($sNameLocal, getParam($sNameParam));
+    }
+}
+
+/** @} */

+ 348 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamModule.php

@@ -0,0 +1,348 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxAntispamModule extends BxDolModule
+{
+    public function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    public function serviceUpdateDisposableDomainsLists ()
+    {
+        $o = bx_instance('BxAntispamDisposableEmailDomains', array(), 'bx_antispam');
+
+        $o->updateList('blacklist', 'https://raw.githubusercontent.com/martenson/disposable-email-domains/master/disposable_email_blocklist.conf');
+
+        // TODO: uncomment after adding interface for whitelisting
+        // $o->updateList('whitelist', 'https://raw.githubusercontent.com/martenson/disposable-email-domains/master/whitelist.conf');
+    }
+    
+    public function serviceIpTable ()
+    {
+        $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
+        $s = _t('_bx_antispam_ip_table_status', mb_strtolower($o->getIpTableConfigTitle((int)getParam('bx_antispam_ip_list_type'))));
+        $s .= $this->_grid('bx_antispam_grid_ip_table');
+        return $s;
+    }
+
+    public function serviceDnsblList ()
+    {
+        $s = _t('_bx_antispam_dnsbl_status',
+             BxTemplFunctions::getInstance()->statusOnOff((bool)$this->_oConfig->getAntispamOption('dnsbl_enable'), true),
+             BxTemplFunctions::getInstance()->statusOnOff((bool)$this->_oConfig->getAntispamOption('uridnsbl_enable'), true),
+             mb_strtolower(_t('_bx_antispam_dnsbl_behaviour_login_' . $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'))),
+             mb_strtolower(_t('_bx_antispam_dnsbl_behaviour_join_' . $this->_oConfig->getAntispamOption('dnsbl_behaviour_join')))
+        );
+        $s .= $this->_grid('bx_antispam_grid_dnsbl');
+        return $s;
+    }
+
+    public function serviceBlockLog ()
+    {
+        return $this->_grid('bx_antispam_grid_block_log');
+    }
+
+    /**
+     * Filter undesired words
+     *
+     * @param $sContent content to filter
+     * @param $sIp IP address of content poster
+     * @return modified or the same content.
+     */
+    public function serviceFilterSpam ($mContent, $sIp = '')
+    {      
+        if (defined('BX_DOL_CRON_EXECUTE') || isAdmin() || 'on' != $this->_oConfig->getAntispamOption('profanity_enable'))
+            return $mContent;
+        
+        $oProfanityFilter = bx_instance('BxAntispamProfanityFilter', array(), $this->_aModule);
+        return $oProfanityFilter->censor($mContent); 
+    }
+    
+    /**
+     * Check text for spam.
+     * First it check if IP is whitelisted(or under cron execution or user is admin) - for whitelisted IPs check for spam isn't performed,
+     * then it checks URLs found in text for DNSURI black lists (@see BxAntispamDNSURIBlacklists),
+     * then it checks text in Akismet service (@see BxAntispamAkismet).
+     * It can send report if spam is found or tries to inform caller to block the content (depending on configuration).
+     *
+     * @param $sContent content to check for spam
+     * @param $sIp IP address of content poster
+     * @param $isStripSlashes slashes parameter:
+     *          BX_SLASHES_AUTO - automatically detect magic_quotes_gpc setting
+     *          BX_SLASHES_NO_ACTION - do not perform any action with slashes
+     * @return true if spam detected and content shouln't be recorded, false if content should be processed as usual.
+     */
+    public function serviceIsSpam ($sContent, $sIp = '', $isStripSlashes = BX_SLASHES_AUTO)
+    {      
+        if (defined('BX_DOL_CRON_EXECUTE') || isAdmin())
+            return false;
+
+        if ($this->serviceIsIpWhitelisted($sIp))
+            return false;
+
+        if (get_magic_quotes_gpc() && $isStripSlashes == BX_SLASHES_AUTO)
+            $sContent = stripslashes($sContent);
+        
+        $bRet = false;
+        if ('on' == $this->_oConfig->getAntispamOption('uridnsbl_enable')) {
+            $oDNSURIBlacklists = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
+            if ($oDNSURIBlacklists->isSpam($sContent)) {
+                $oDNSURIBlacklists->onPositiveDetection($sContent);
+                $bRet = true;
+            }
+        }
+
+        if (!$bRet && 'on' == $this->_oConfig->getAntispamOption('akismet_enable')) {
+            $oAkismet = bx_instance('BxAntispamAkismet', array(), $this->_aModule);
+            if ($oAkismet->isSpam($sContent)) {
+                $oAkismet->onPositiveDetection($sContent);
+                $bRet = true;
+            }
+        }
+
+        if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_report')) {
+
+            $oProfile = BxDolProfile::getInstance();
+            $aPlus = array(
+                'SpammerUrl' => $oProfile->getUrl(),
+                'SpammerNickName' => $oProfile->getDisplayName(),
+                'Page' => htmlspecialchars_adv($_SERVER['PHP_SELF']),
+                'Get' => print_r($_GET, true),
+                'Post' => print_r($_POST, true),
+                'SpamContent' => htmlspecialchars_adv($sContent),
+            );
+
+            $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('bx_antispam_spam_report', $aPlus);
+            if (!$aTemplate)
+                trigger_error('Email template or translation missing: bx_antispam_spam_report', E_USER_ERROR);
+
+            sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
+        }
+
+        if ($bRet && 'on' == $this->_oConfig->getAntispamOption('antispam_block'))
+            return true;
+
+        return false;
+    }
+
+    /**
+     * Perform complex check if user is allowed to login.
+     * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
+     * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted).
+     *
+     * @param $sIp IP to check, or empty for current IP
+     * @return empty string - if join should be allowed, error message - if join should be blocked
+     */
+    public function serviceCheckLogin ($sIp = '')
+    {
+        $bLoginBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_login'));
+        $sErrorMsg = '';
+        $sNote = $bLoginBlock ? 'login block' : 'login log';
+
+        if (!$sIp)
+            $sIp = getVisitorIP();
+
+        if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
+            $sErrorMsg = $this->getErrorMessageIpBlocked();
+
+        if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote) && $bLoginBlock)
+            $sErrorMsg = $this->getErrorMessageSpam();
+
+        return $sErrorMsg;
+    }
+
+    /**
+     * Perform complex check if user is allowed to join.
+     * First it checks if IP is directly blocked (@see serviceIsIpBlocked),
+     * then it checks in DNS black lists (@see serviceIsIpDnsBlacklisted),
+     * then it checks in StopForumSpam service (@see BxAntispamStopForumSpam).
+     *
+     * @param $sCurIP IP to check, or empty for current IP
+     * @return empty string - if join should be allowed, error message - if join should be blocked
+     */
+    public function serviceCheckJoin ($sEmail, &$bApproval, $sIp = '')
+    {
+        $bJoinBlock = ('block' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'));
+        $bApproval = false;
+        $sErrorMsg = '';
+        $sNote = $bJoinBlock ? 'join block' : 'join approval';
+
+        if (!$sIp)
+            $sIp = getVisitorIP();
+
+        // check if IP is blocked
+        if (!$sErrorMsg && $this->serviceIsIpBlocked($sIp))
+            $sErrorMsg = $this->getErrorMessageIpBlocked();
+
+        // check in DNSBL lists
+        if (!$sErrorMsg && 'on' == $this->_oConfig->getAntispamOption('dnsbl_enable') && $this->serviceIsIpDnsBlacklisted($sIp, $sNote)) {
+            if ('approval' == $this->_oConfig->getAntispamOption('dnsbl_behaviour_join'))
+                $bApproval = true;
+            else
+                $sErrorMsg = $this->getErrorMessageSpam();
+        }
+
+        // check in StopForumSpam service
+        if (!$sErrorMsg) {
+            $oStopForumSpam = bx_instance('BxAntispamStopForumSpam', array(), $this->_aModule);
+            if ($oStopForumSpam->isSpammer(array('email' => $sEmail, 'ip' => $sIp), $sNote))
+                $sErrorMsg = $this->getErrorMessageSpam();
+        }
+
+        // check for disposable email domains
+        if (!$sErrorMsg && 'disable' != ($sMode = $this->_oConfig->getAntispamOption('disposable_email_domains_mode'))) {
+
+            $bDisposableEmailDomainsBehaviour = $this->_oConfig->getAntispamOption('disposable_email_domains_behaviour_join');
+            $oDisposableEmailDomains = bx_instance('BxAntispamDisposableEmailDomains', array(), 'bx_antispam');
+            
+            if ('blacklist' == $sMode && $oDisposableEmailDomains->isBlacklisted($sEmail)) {
+                if ('approval' == $bDisposableEmailDomainsBehaviour)
+                    $bApproval = true;
+                else
+                    $sErrorMsg = $oDisposableEmailDomains->getErrorMessageBlacklisted();
+            }
+            elseif ('whitelist' == $sMode && !$oDisposableEmailDomains->isWhitelisted($sEmail)) {
+                if ('approval' == $bDisposableEmailDomainsBehaviour)
+                    $bApproval = true;
+                else
+                    $sErrorMsg = $oDisposableEmailDomains->getErrorMessageNotWhitelisted();
+            }
+
+        }
+
+        return $sErrorMsg;
+    }
+
+    /**
+     * Check if IP is blacklisted in some DNS chain (@see BxAntispamDNSBlacklists).
+     *
+     * @param $sCurIP IP to check, or empty for current IP
+     * @param $sNote [optional] place where checking is performed, for example 'join', 'login'
+     * @return true if IP blacklisted and not whiteloisted, or false if under cron execution or if IP isn't blacklisted
+     */
+    public function serviceIsIpDnsBlacklisted($sCurIP = '', $sNote = '')
+    {
+        if (defined('BX_DOL_CRON_EXECUTE'))
+            return false;
+
+        if (!$sCurIP)
+            $sCurIP = getVisitorIP();
+
+        if ($this->serviceIsIpWhitelisted($sCurIP))
+            return false;
+
+        $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
+
+        if (BX_DOL_DNSBL_POSITIVE == $o->dnsbl_lookup_ip(BX_DOL_DNSBL_CHAIN_SPAMMERS, $sCurIP) && BX_DOL_DNSBL_POSITIVE != $o->dnsbl_lookup_ip(BX_DOL_DNSBL_CHAIN_WHITELIST, $sCurIP)) {
+            $o->onPositiveDetection ($sCurIP, $sNote);
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @see BxAntispamIP::isIpWhitelisted
+     */
+    public function serviceIsIpWhitelisted($sIp = '')
+    {
+        $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
+        return $o->isIpWhitelisted($sIp);
+    }
+
+    /**
+     * @see BxAntispamIP::isIpBlocked
+     */
+    public function serviceIsIpBlocked($sIp = '')
+    {
+        $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
+        return $o->isIpBlocked($sIp);
+    }
+
+    /**
+     * @see BxAntispamIP::blockIp
+     */
+    public function serviceBlockIp($mixedIP, $iExpirationInSec = 86400, $sComment = '')
+    {
+        $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
+        return $o->blockIp($mixedIP, $iExpirationInSec, $sComment);
+    }
+
+    /**
+     * @see BxAntispamIP::pruning
+     */
+    public function servicePruning()
+    {
+        $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
+        return $o->pruning();
+    }
+
+    /**
+     * @see BxAntispamIP::pruning
+     */
+    public function serviceConfigValues($s)
+    {
+        switch ($s) {
+            case 'ip_table':
+                $o = bx_instance('BxAntispamIP', array(), $this->_aModule);
+                return $o->getIpTableConfigValues();
+            case 'dnsbl_login':
+                $o = bx_instance('BxAntispamDNSBlacklists', array(), $this->_aModule);
+                return $o->getDNSBLConfigValues();
+            case 'dnsbl_join';
+                $o = bx_instance('BxAntispamDNSURIBlacklists', array(), $this->_aModule);
+                return $o->getURIDNSBLConfigValues();
+            case 'disposable_email_domains_join';
+                $o = bx_instance('BxAntispamDisposableEmailDomains', array(), $this->_aModule);
+                return $o->getJoinBehaviourValues();                
+            case 'disposable_email_domains_mode';
+                $o = bx_instance('BxAntispamDisposableEmailDomains', array(), $this->_aModule);
+                return $o->getJoinBehaviourModes();                
+        }
+    }
+    
+    /**
+     * @return array with avaliable dictionaries languages
+     */
+    public function serviceGetProfanityFilterDicts ()
+    {
+        $oProfanityFilter = bx_instance('BxAntispamProfanityFilter', array(), $this->_aModule);
+        return $oProfanityFilter->getDicts(); 
+    }
+
+    protected function getErrorMessageIpBlocked ()
+    {
+        bx_import('BxDolLanguages');
+        return _t('_bx_antispam_ip_blocked', $this->getErrorMessageSubmitFalsePositiveReport());
+    }
+
+    protected function getErrorMessageSpam ()
+    {
+        bx_import('BxDolLanguages');
+        return _t('_bx_antispam_spam_detected', $this->getErrorMessageSubmitFalsePositiveReport());
+    }
+
+    protected function getErrorMessageSubmitFalsePositiveReport ()
+    {
+        if (BxDolRequest::serviceExists('bx_contact', 'get_contact_page_url') && ($sUrl = BxDolService::call('bx_contact', 'get_contact_page_url')))
+            return _t('_bx_antispam_submit_false_positive_report', $sUrl);
+        return '';
+    }
+
+    protected function _grid ($sObjectGrid)
+    {
+        $oGrid = BxDolGrid::getObjectInstance($sObjectGrid);
+        return $oGrid ? $oGrid->getCode() : '';
+    }
+}
+
+/** @} */

+ 86 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/classes/BxAntispamProfanityFilter.php

@@ -0,0 +1,86 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Profanity Filter based on https://github.com/snipe/banbuilder
+ * Need change 
+ * str_ireplace(array_keys($leet_replace), array_values($leet_replace), $badwords[$x]) . '\b/i'
+ * to 
+ * str_ireplace(array_keys($leet_replace), array_values($leet_replace), $badwords[$x]) . '\b/iu'
+ * in CensorWords.php
+ */
+class BxAntispamProfanityFilter extends BxDol
+{
+    protected $oProfanityFilter = null;
+    protected $sPluginPath = BX_DIRECTORY_PATH_PLUGINS . 'banbuilder/src/';
+    
+    public function __construct()
+    {
+        parent::__construct();
+        
+        require_once ($this->sPluginPath .'CensorWords.php');
+        $sClassName = 'Snipe\BanBuilder\CensorWords';
+        $this->oProfanityFilter = new $sClassName;
+        
+        $aTmp = explode(',', getParam('bx_antispam_profanity_filter_dicts'));
+        foreach ($aTmp as $sLng) {
+            if ($sLng != '')
+                $this->oProfanityFilter->addDictionary($sLng);
+        }
+        
+        $Char = trim(getParam('bx_antispam_profanity_filter_char_replace'));
+        if ($Char != '')
+            $this->oProfanityFilter->setReplaceChar($Char);
+        
+        $sBadWords = trim(getParam('bx_antispam_profanity_filter_bad_words_list'));
+        if ($sBadWords != '')
+            $this->oProfanityFilter->addFromArray(array_map('trim', explode(',', $sBadWords)));
+
+        $sWhiteWords = getParam('bx_antispam_profanity_filter_white_words_list');
+        if ($sWhiteWords != '')
+            $this->oProfanityFilter->addWhiteList(array_map('trim', explode(',', $sWhiteWords)));
+    }
+
+    public function censor ($mValue)
+    {
+        $bFullWord = getParam('bx_antispam_profanity_filter_full_words_only') =='on' ? true : false;
+        if (is_array($mValue)){
+            for ($i = 0; $i < count($mValue); $i++) {
+                if (is_string($mValue[$i])){
+                    $aTmp = $this->oProfanityFilter->censorString($mValue[$i], $bFullWord);
+                    $mValue[$i] = $aTmp['clean'];
+                }
+            }
+        }
+        else{
+            $aTmp = $this->oProfanityFilter->censorString($mValue, $bFullWord);
+            $mValue = $aTmp['clean'];
+        }
+        return $mValue;
+    } 
+    
+    public function getDicts ()
+    {
+        $aResult = array();
+        if ($oHandle = opendir($this->sPluginPath . 'dict')) {
+            while (false !== ($oEntry = readdir($oHandle))) {
+                if (!is_dir($oEntry)){
+                    $sTmp = str_replace('.php', '', $oEntry);
+                    $aResult[$sTmp] = $sTmp;
+                }
+            }
+            closedir($oHandle);
+        }
+        return $aResult;
+    } 
+}
+
+/** @} */

+ 68 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/install/config.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Antispam Antispam
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_antispam',
+    'title' => 'Antispam',
+    'note' => 'Antispam tools',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/antispam/',
+    'home_uri' => 'antispam',
+
+    'db_prefix' => 'bx_antispam_',
+    'class_prefix' => 'BxAntispam',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Antispam',
+
+    /**
+     * 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(),
+);
+
+/** @} */

+ 170 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/install/langs/en.xml

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_antispam"><![CDATA[Antispam]]></string>
+    <string name="_bx_antispam_help"><![CDATA[Help]]></string>
+    <string name="_bx_antispam_help_text">
+      <![CDATA[This module allows to limit spam on the site, there are different build-in tools for this:
+<ul>
+    <li><b>IP table</b> - manual IP blocking/whitelisting</li>
+    <li><b>DNSBL</b> - automatic blocking by IP from different block lists</li>
+    <li><b>URI DNSBL</b> - automatic blocking of spam content by spam URLs in the text</li>
+    <li><b>Akismet</b> - automatic spam content blocking using <a target="_blank" href="http://akismet.com">Akismet service</a></li>
+    <li><b>StopForumSpam</b> - automatic spam content blocking using <a target="_blank" href="http://www.stopforumspam.com">StopForumSpam service</a></li>
+    <li><b>Profanity filter</b> - profanity filter, based on a predefined list of words with the ability to add to words this list</a></li>
+</ul>
+]]></string>
+    <string name="_bx_antispam_help_dnsbl"><![CDATA[
+DNSBL - <a href="http://en.wikipedia.org/wiki/DNSBL">Domain Name Service Block Lists</a>.
+This functionality allows to block by IP address if it exists in one of available blocklists.
+<br /><br />
+A URI DNSBL is a DNSBL that lists the domain names and IP addresses which are found in the "clickable" links contained in the body of spams, but generally not found inside legitimate messages.
+This antispam method scan submitted content for the URLs and check them if any of them is a link to spam site. If such URL detected in the text then content is not submitted.
+<br /><br />
+<button class="bx-btn" style="float:none;" onclick ="$('.bx-popup-applied:visible').dolPopupHide();">Close</button>
+]]></string>
+    <string name="_bx_antispam_dnsbl_status"><![CDATA[
+<table style="width:100%;"><tr>
+    <td>DNSBL: {0}</td>
+    <td>URI DNSBL: {1}</td>
+    <td>Login behavior: {2}</td>
+    <td>Join behavior: {3}</td>
+</tr></table>
+]]></string>
+    <string name="_bx_antispam_ip_table_status"><![CDATA[IP table mode: {0}]]></string>
+    <string name="_bx_antispam_ip_blocked"><![CDATA[IP address is blocked. {0}]]></string>
+    <string name="_bx_antispam_spam_detected"><![CDATA[Spam detected. {0}]]></string>
+    <string name="_bx_antispam_submit_false_positive_report"><![CDATA[If you believe that this is a mistake, please submit a false positive report here: {0}]]></string>
+	<string name="_bx_antispam_ip_allow"><![CDATA[Allow]]></string>
+	<string name="_bx_antispam_ip_deny"><![CDATA[Deny]]></string>
+	<string name="_bx_antispam_ip_table"><![CDATA[IP table]]></string>
+	<string name="_bx_antispam_dnsbl_list"><![CDATA[DNSBL list]]></string>
+	<string name="_bx_antispam_block_log"><![CDATA[Block log]]></string>
+	<string name="_bx_antispam_chain_whitelist"><![CDATA[IP whitelist]]></string>
+	<string name="_bx_antispam_chain_spammers"><![CDATA[IP blacklist]]></string>
+	<string name="_bx_antispam_chain_uridns"><![CDATA[Spam text]]></string>
+	<string name="_bx_antispam_rule_note_country"><![CDATA[Country: {0}]]></string>
+	<string name="_bx_antispam_rule_note_spamhaus_org"><![CDATA[Detect spammer IPs]]></string>
+	<string name="_bx_antispam_rule_note_zomgbl_spameatingmonkey_net"><![CDATA[Everything is blacklisted, <u>use it only if something is whitelisted!</u>]]></string>
+	<string name="_bx_antispam_rule_note_surbl_org"><![CDATA[Detect spammer URLs from SURBLs (lists of web sites that have appeared in unsolicited messages)]]></string>
+	<string name="_bx_antispam_rule_note_dnsbl_tornevall_org"><![CDATA[Detect anonymous/elite proxies and abuse IPs]]></string>
+	<string name="_bx_antispam_dnsbl"><![CDATA[DNSBL]]></string>
+	<string name="_bx_antispam_uri_dnsbl"><![CDATA[URI DNSBL]]></string>
+	<string name="_bx_antispam_type_dnsbl"><![CDATA[DNSBL]]></string>
+	<string name="_bx_antispam_type_dnsbluri"><![CDATA[URI DNSBL]]></string>
+	<string name="_bx_antispam_type_akismet"><![CDATA[Akismet]]></string>
+	<string name="_bx_antispam_type_stopforumspam"><![CDATA[StopForumSpam]]></string>
+	<string name="_bx_antispam_ip_table_disabled"><![CDATA[Disabled]]></string>
+	<string name="_bx_antispam_ip_table_all_allowed_except_listed"><![CDATA[All allowed except listed]]></string>
+	<string name="_bx_antispam_ip_table_all_blocked_except_listed"><![CDATA[All blocked except listed]]></string>
+	<string name="_bx_antispam_dnsbl_behaviour_login_block"><![CDATA[Block]]></string>
+	<string name="_bx_antispam_dnsbl_behaviour_login_log"><![CDATA[Log]]></string>
+	<string name="_bx_antispam_dnsbl_behaviour_join_block"><![CDATA[Block]]></string>
+    <string name="_bx_antispam_dnsbl_behaviour_join_approval"><![CDATA[Approval]]></string>
+	<string name="_bx_antispam_disposable_email_domains_mode_disable"><![CDATA[Disable]]></string>
+	<string name="_bx_antispam_disposable_email_domains_mode_whitelist"><![CDATA[Allow whitelisted only]]></string>
+	<string name="_bx_antispam_disposable_email_domains_mode_blacklist"><![CDATA[Disallow blacklisted]]></string>
+	<string name="_bx_antispam_disposable_email_domains_behaviour_join_block"><![CDATA[Block]]></string>
+	<string name="_bx_antispam_disposable_email_domains_behaviour_join_approval"><![CDATA[Approval]]></string>
+    <string name="_bx_antispam_disposable_email_domains_msg_blacklisted"><![CDATA[Your email domain isn't allowed for registration on this site]]></string>
+
+	<string name="_bx_antispam_popup_help"><![CDATA[DNSBL help]]></string>
+	<string name="_bx_antispam_popup_dnsbl_recheck"><![CDATA[Recheck IP/URL in DNSBL/URIDNSBL]]></string>
+	<string name="_bx_antispam_popup_dnsbl_add"><![CDATA[Add country based rule]]></string>
+	<string name="_bx_antispam_popup_block_log"><![CDATA[Block log]]></string>
+
+	<string name="_bx_antispam_page_title_sys_ip_table"><![CDATA[IP table]]></string>
+	<string name="_bx_antispam_page_title_ip_table"><![CDATA[IP table]]></string>
+	<string name="_bx_antispam_page_title_sys_dnsbl_list"><![CDATA[DNSBL list]]></string>
+	<string name="_bx_antispam_page_title_dnsbl_list"><![CDATA[DNSBL list]]></string>
+	<string name="_bx_antispam_page_title_sys_block_log"><![CDATA[Block log]]></string>
+	<string name="_bx_antispam_page_title_block_log"><![CDATA[Block log]]></string>
+
+	<string name="_bx_antispam_page_block_title_ip_table"><![CDATA[IP table]]></string>
+	<string name="_bx_antispam_page_block_title_dnsbl_list"><![CDATA[DNSBL list]]></string>
+	<string name="_bx_antispam_page_block_title_block_log"><![CDATA[Block log]]></string>
+
+	<string name="_bx_antispam_grid_action_delete"><![CDATA[Delete]]></string>
+	<string name="_bx_antispam_grid_action_add"><![CDATA[Add]]></string>
+	<string name="_bx_antispam_grid_action_log"><![CDATA[Log]]></string>
+	<string name="_bx_antispam_grid_action_recheck"><![CDATA[Re-check]]></string>
+	<string name="_bx_antispam_grid_action_help"><![CDATA[Help]]></string>
+
+	<string name="_bx_antispam_field_id"><![CDATA[ID]]></string>
+	<string name="_bx_antispam_field_ip"><![CDATA[IP]]></string>
+	<string name="_bx_antispam_field_ip_from"><![CDATA[IP from]]></string>
+	<string name="_bx_antispam_field_ip_to"><![CDATA[IP to]]></string>
+	<string name="_bx_antispam_field_action"><![CDATA[Action]]></string>
+	<string name="_bx_antispam_field_expiration"><![CDATA[Expiration]]></string>
+	<string name="_bx_antispam_field_note"><![CDATA[Note]]></string>
+	<string name="_bx_antispam_field_chain"><![CDATA[Rule]]></string>
+	<string name="_bx_antispam_field_ip_url"><![CDATA[IP for DNSBL or URL for URI DNSBL]]></string>
+	<string name="_bx_antispam_field_dnsbl_uridnsbl"><![CDATA[Check in]]></string>
+	<string name="_bx_antispam_field_profile_id"><![CDATA[Profile]]></string>
+	<string name="_bx_antispam_field_type"><![CDATA[Type]]></string>
+	<string name="_bx_antispam_field_when"><![CDATA[When]]></string>
+	<string name="_bx_antispam_field_country"><![CDATA[Country]]></string>
+	<string name="_bx_antispam_field_zonedomain"><![CDATA[ZONE domain]]></string>
+
+    <string name="_bx_antispam_form_ip_table"><![CDATA[IP table directive]]></string>
+    <string name="_bx_antispam_form_ip_table_add"><![CDATA[Add IP table directive]]></string>
+    <string name="_bx_antispam_form_ip_table_edit"><![CDATA[Edit IP table directive]]></string>
+    <string name="_bx_antispam_form_buttons"><![CDATA[Form buttons]]></string>
+
+    <string name="_bx_antispam_field_ip_err_msg"><![CDATA[Please enter correct IP address, for example 192.168.4.5]]></string>
+    <string name="_bx_antispam_field_expiration_err_msg"><![CDATA[Please enter correct date time value]]></string>
+
+    <string name="_bx_antispam_data_list_ip_table_actions"><![CDATA[IP table actions]]></string>
+
+    <string name="_bx_antispam_adm_stg_cpt_type"><![CDATA[Antispam]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_general"><![CDATA[General]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_ip_table"><![CDATA[IP table]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_dnsbl"><![CDATA[DNSBL]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_akismet"><![CDATA[Akismet]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_stopforumspam"><![CDATA[StopForumSpam]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_disposable_email_domains"><![CDATA[Disposable email domains]]></string>
+    <string name="_bx_antispam_adm_stg_cpt_category_profanity_filter"><![CDATA[Profanity filter]]></string>
+    
+	<string name="_bx_antispam_option_block"><![CDATA[Total block all spam content]]></string>
+	<string name="_bx_antispam_option_report"><![CDATA[Send report to admin if spam content discovered]]></string>
+	<string name="_bx_antispam_option_ip_list_type"><![CDATA[IP table mode]]></string>
+	<string name="_bx_antispam_option_dnsbl_enable"><![CDATA[Enable DNS Block Lists]]></string>
+	<string name="_bx_antispam_option_dnsbl_behaviour_login"><![CDATA[User login behaviour if listed in DNS Block Lists]]></string>
+	<string name="_bx_antispam_option_dnsbl_behaviour_join"><![CDATA[User join behaviour if listed in DNS Block Lists]]></string>
+	<string name="_bx_antispam_option_uridnsbl_enable"><![CDATA[Enable URI DNS Block Lists]]></string>
+	<string name="_bx_antispam_option_akismet_enable"><![CDATA[Enable Akismet]]></string>
+	<string name="_bx_antispam_option_akismet_api_key"><![CDATA[Akismet API Key]]></string>
+	<string name="_bx_antispam_option_stopforumspam_enable"><![CDATA[Enable "Stop Forum Spam"]]></string>
+    <string name="_bx_antispam_option_stopforumspam_api_key"><![CDATA["Stop Forum Spam" API Key]]></string> 
+	<string name="_bx_antispam_option_disposable_email_domains_mode"><![CDATA[Mode]]></string>
+	<string name="_bx_antispam_option_disposable_email_domains_behaviour_join"><![CDATA[Join behaviour]]></string>
+  <string name="_bx_antispam_option_profanity_filter_enable"><![CDATA[Enable Profanity filter]]></string>
+  <string name="_bx_antispam_option_profanity_filter_dicts"><![CDATA[Dictionaries]]></string>
+  <string name="_bx_antispam_option_profanity_filter_bad_words_list"><![CDATA[Bad words list (comma separated)]]></string>
+  <string name="_bx_antispam_option_profanity_filter_char_replace"><![CDATA[Char to replace]]></string>
+  <string name="_bx_antispam_option_profanity_filter_white_words_list"><![CDATA[White words list (comma separated)]]></string>
+  <string name="_bx_antispam_option_profanity_filter_full_words_only"><![CDATA[Full words only]]></string>
+
+  <string name="_bx_antispam_spam_report_name"><![CDATA[Spam report message]]></string>
+    <string name="_bx_antispam_spam_report_subject"><![CDATA[Automatic spam report]]></string>
+    <string name="_bx_antispam_spam_report_body"><![CDATA[{email_header}
+<b>Profile:</b> <a href="{SpammerUrl}">{SpammerNickName}</a><br />
+
+<b>Page:</b> {Page}<br /><br />
+
+<b>GET variables:</b>
+<pre>
+{Get}
+</pre>
+
+<b>POST variables:</b>
+<pre>
+{Post}
+</pre>
+
+<b>Spam content:</b>
+<pre>
+{SpamContent}
+</pre>
+{email_footer}]]></string>
+</resources>

+ 227 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/install/sql/enable.sql

@@ -0,0 +1,227 @@
+
+-- 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_antispam', '_bx_antispam_adm_stg_cpt_type', 'bx_antispam@modules/boonex/antispam/|std-icon.svg', IF(NOT ISNULL(@iTypeOrder), @iTypeOrder + 1, 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_general', '_bx_antispam_adm_stg_cpt_category_general', 1);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_block', '_bx_antispam_option_block', '', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'bx_antispam_report', '_bx_antispam_option_report', 'on', 'checkbox', '', '', '', 20);
+
+
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_ip_table', '_bx_antispam_adm_stg_cpt_category_ip_table', 2);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_ip_list_type', '_bx_antispam_option_ip_list_type', '0', 'select', 'a:3:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:13:"config_values";s:6:"params";a:1:{i:0;s:8:"ip_table";}}', '', '', 10);
+
+
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_dnsbl', '_bx_antispam_adm_stg_cpt_category_dnsbl', 3);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_dnsbl_enable', '_bx_antispam_option_dnsbl_enable', 'on', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'bx_antispam_dnsbl_behaviour_login', '_bx_antispam_option_dnsbl_behaviour_login', 'block', 'select', 'a:3:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:13:"config_values";s:6:"params";a:1:{i:0;s:11:"dnsbl_login";}}', '', '', 20),
+(@iCategoryId, 'bx_antispam_dnsbl_behaviour_join', '_bx_antispam_option_dnsbl_behaviour_join', 'approval', 'select', 'a:3:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:13:"config_values";s:6:"params";a:1:{i:0;s:10:"dnsbl_join";}}', '', '', 30),
+(@iCategoryId, 'bx_antispam_uridnsbl_enable', '_bx_antispam_option_uridnsbl_enable', 'on', 'checkbox', '', '', '', 40);
+
+
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_akismet', '_bx_antispam_adm_stg_cpt_category_akismet', 4);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_akismet_enable', '_bx_antispam_option_akismet_enable', '', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'bx_antispam_akismet_api_key', '_bx_antispam_option_akismet_api_key', '', 'digit', '', '', '', 20);
+
+
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_stopforumspam', '_bx_antispam_adm_stg_cpt_category_stopforumspam', 5);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_stopforumspam_enable', '_bx_antispam_option_stopforumspam_enable', 'on', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'bx_antispam_stopforumspam_api_key', '_bx_antispam_option_stopforumspam_api_key', '', 'digit', '', '', '', 20);
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_disposable_email_domains', '_bx_antispam_adm_stg_cpt_category_disposable_email_domains', 6);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_disposable_email_domains_mode', '_bx_antispam_option_disposable_email_domains_mode', 'blacklist', 'select', 'a:3:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:13:"config_values";s:6:"params";a:1:{i:0;s:29:"disposable_email_domains_mode";}}', '', '', 10),
+(@iCategoryId, 'bx_antispam_disposable_email_domains_behaviour_join', '_bx_antispam_option_disposable_email_domains_behaviour_join', 'block', 'select', 'a:3:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:13:"config_values";s:6:"params";a:1:{i:0;s:29:"disposable_email_domains_join";}}', '', '', 20);
+
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_antispam_profanity_filter', '_bx_antispam_adm_stg_cpt_category_profanity_filter', 7);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_antispam_profanity_filter_enable', '_bx_antispam_option_profanity_filter_enable', '', 'checkbox', '', '', '', 10),
+(@iCategoryId, 'bx_antispam_profanity_filter_dicts', '_bx_antispam_option_profanity_filter_dicts', '', 'list', 'a:2:{s:6:"module";s:11:"bx_antispam";s:6:"method";s:26:"get_profanity_filter_dicts";}', '', '', 15),
+(@iCategoryId, 'bx_antispam_profanity_filter_bad_words_list', '_bx_antispam_option_profanity_filter_bad_words_list', '', 'text', '', '', '', 20),
+(@iCategoryId, 'bx_antispam_profanity_filter_char_replace', '_bx_antispam_option_profanity_filter_char_replace', '*', 'digit', '', '', '', 30),
+(@iCategoryId, 'bx_antispam_profanity_filter_white_words_list', '_bx_antispam_option_profanity_filter_white_words_list', '', 'text', '', '', '', 40),
+(@iCategoryId, 'bx_antispam_profanity_filter_full_words_only', '_bx_antispam_option_profanity_filter_full_words_only', 'on', 'checkbox', '', '', '', 50);
+
+
+-- page: DNSBL list
+
+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_antispam_dnsbl', 'antispam-dnsbl-list', '_bx_antispam_page_title_sys_dnsbl_list', '_bx_antispam_page_title_dnsbl_list', 'bx_antispam', 5, 128, 1, 'page.php?i=antispam-dnsbl-list', '', '', '', 0, 1, 0, 'BxAntispamPage', 'modules/boonex/antispam/classes/BxAntispamPage.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_antispam_dnsbl', 1, 'bx_antispam', '_bx_antispam_page_block_title_dnsbl_list', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_antispam\";s:6:\"method\";s:10:\"dnsbl_list\";}', 0, 1, 1, 1);
+
+-- page: ip table
+
+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_antispam_ip_table', 'antispam-ip-table', '_bx_antispam_page_title_sys_ip_table', '_bx_antispam_page_title_ip_table', 'bx_antispam', 5, 128, 1, 'page.php?i=antispam-ip-table', '', '', '', 0, 1, 0, 'BxAntispamPage', 'modules/boonex/antispam/classes/BxAntispamPage.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_antispam_ip_table', 1, 'bx_antispam', '_bx_antispam_page_block_title_ip_table', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_antispam\";s:6:\"method\";s:8:\"ip_table\";}', 0, 1, 1, 1);
+
+-- page: block log
+
+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_antispam_block_log', 'antispam-block-log', '_bx_antispam_page_title_sys_block_log', '_bx_antispam_page_title_block_log', 'bx_antispam', 5, 192, 1, 'page.php?i=antispam-block-log', '', '', '', 0, 1, 0, 'BxAntispamPage', 'modules/boonex/antispam/classes/BxAntispamPage.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_antispam_block_log', 1, 'bx_antispam', '_bx_antispam_page_block_title_block_log', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_antispam\";s:6:\"method\";s:9:\"block_log\";}', 0, 1, 1, 1);
+
+-- grid: DNSBL
+
+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_antispam_grid_dnsbl', 'Sql', 'SELECT `id`, `chain`, `zonedomain`, `postvresp`, `url`, `recheck`, `comment`, `added`, `active` FROM `bx_antispam_dnsbl_rules`', 'bx_antispam_dnsbl_rules', 'id', 'added', 'active', '', 16, NULL, 'start', '', 'chain,zonedomain,url,recheck', 'comment', 'auto', 'chain,zonedomain', 'comment', 128, 'BxAntispamGridDNSBL', 'modules/boonex/antispam/classes/BxAntispamGridDNSBL.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_antispam_grid_dnsbl', 'switcher', '_sys_active', '10%', 0, 0, '', 1),
+('bx_antispam_grid_dnsbl', 'chain', '_bx_antispam_field_chain', '15%', 0, 0, '', 2),
+('bx_antispam_grid_dnsbl', 'zonedomain', '_bx_antispam_field_zonedomain', '15%', 0, 0, '', 3),
+('bx_antispam_grid_dnsbl', 'comment', '_bx_antispam_field_note', '55%', 0, 0, '', 4),
+('bx_antispam_grid_dnsbl', 'actions', '_sys_actions', '5%', 0, 0, '', 5);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
+('bx_antispam_grid_dnsbl', 'independent', 'log', '_bx_antispam_grid_action_log', '', 0, 1),
+('bx_antispam_grid_dnsbl', 'independent', 'recheck', '_bx_antispam_grid_action_recheck', '', 0, 2),
+('bx_antispam_grid_dnsbl', 'independent', 'add', '_bx_antispam_grid_action_add', '', 0, 3),
+('bx_antispam_grid_dnsbl', 'independent', 'help', '_bx_antispam_grid_action_help', '', 0, 4),
+('bx_antispam_grid_dnsbl', 'single', 'delete', '', 'remove',  1, 1);
+
+-- grid: ip table
+
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_mode`, `sorting_fields`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_antispam_grid_ip_table', 'Sql', 'SELECT `ID`, `From`, `To`, `Type`, `LastDT`, `Desc` FROM `bx_antispam_ip_table`', 'bx_antispam_ip_table', 'ID', '', '', 10, NULL, 'start', '', 'From,To,Desc', 'auto', 'From,To,Type,LastDT,Desc', 128, 'BxAntispamGridIpTable', 'modules/boonex/antispam/classes/BxAntispamGridIpTable.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `params`, `order`) VALUES
+('bx_antispam_grid_ip_table', 'checkbox', '_sys_select', '2%', '', 1),
+('bx_antispam_grid_ip_table', 'From', '_bx_antispam_field_ip_from', '15%', '', 2),
+('bx_antispam_grid_ip_table', 'To', '_bx_antispam_field_ip_to', '15%', '', 3),
+('bx_antispam_grid_ip_table', 'Type', '_bx_antispam_field_action', '15%', '', 4),
+('bx_antispam_grid_ip_table', 'LastDT', '_bx_antispam_field_expiration', '15%', '', 5),
+('bx_antispam_grid_ip_table', 'Desc', '_bx_antispam_field_note', '26%', '', 6),
+('bx_antispam_grid_ip_table', 'actions', '_sys_actions', '12%', '', 7);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
+('bx_antispam_grid_ip_table', 'bulk', 'delete', '_bx_antispam_grid_action_delete', '', 1, 1),
+('bx_antispam_grid_ip_table', 'single', 'edit', '', 'pencil-alt', 0, 1),
+('bx_antispam_grid_ip_table', 'single', 'delete', '', 'remove',  1, 2),
+('bx_antispam_grid_ip_table', 'independent', 'add', '_bx_antispam_grid_action_add', '', 0, 1);
+
+-- grid: block log
+
+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_antispam_grid_block_log', 'Sql', 'SELECT `id`, `ip`, `profile_id`, `type`, `extra`, `added` FROM `bx_antispam_block_log`', 'bx_antispam_block_log', 'id', 'id', '', '', 8, NULL, 'start', '', 'type,extra', '', 'auto', 'ip,profile_id,type,extra,added', '', 192, 'BxAntispamGridBlockLog', 'modules/boonex/antispam/classes/BxAntispamGridBlockLog.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_antispam_grid_block_log', 'ip', '_bx_antispam_field_ip', '20%', 0, 0, '', 1),
+('bx_antispam_grid_block_log', 'profile_id', '_bx_antispam_field_profile_id', '20%', 0, 0, '', 2),
+('bx_antispam_grid_block_log', 'type', '_bx_antispam_field_type', '15%', 0, 0, '', 3),
+('bx_antispam_grid_block_log', 'extra', '_bx_antispam_field_note', '15%', 0, 8, '', 4),
+('bx_antispam_grid_block_log', 'added', '_bx_antispam_field_when', '30%', 0, 0, '', 5);
+
+-- data list: ip table actions
+
+INSERT INTO `sys_form_pre_lists`(`module`, `key`, `title`, `use_for_sets`) VALUES 
+('bx_antispam', 'bx_antispam_ip_table_actions', '_bx_antispam_data_list_ip_table_actions', 0);
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `LKey`, `LKey2`, `Order`) VALUES 
+('bx_antispam_ip_table_actions', 'allow', '_bx_antispam_ip_allow', '', 0),
+('bx_antispam_ip_table_actions', 'deny', '_bx_antispam_ip_deny', '', 0);
+
+-- form: IP table add/edit
+
+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_antispam_ip_table_form', 'bx_antispam', '_bx_antispam_form_ip_table', 'grid.php?o={grid_object}&a={grid_action}', '', 'bx_antispam_ip_table', 'ID', '', '', 'bx_antispam_ip_table_submit', '', 0, 1, '', '');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_antispam_ip_table_form', 'bx_antispam_ip_table_form_add', 'bx_antispam', 0, '_bx_antispam_form_ip_table_add'),
+('bx_antispam_ip_table_form', 'bx_antispam_ip_table_form_edit', 'bx_antispam', 0, '_bx_antispam_form_ip_table_edit');
+
+INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
+('bx_antispam_ip_table_form', 'bx_antispam', 'ID', '', '', 0, 'hidden', '_bx_antispam_field_id', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'From', '', '', 0, 'text', '_bx_antispam_field_ip_from', '_bx_antispam_field_ip_from', '', 1, 0, 0, '', '', '', 'preg', 'a:1:{s:4:\"preg\";s:20:\"#\\d+\\.\\d+\\.\\d+\\.\\d+#\";}', '_bx_antispam_field_ip_err_msg', 'Xss', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'To', '', '', 0, 'text', '_bx_antispam_field_ip_to', '_bx_antispam_field_ip_to', '', 1, 0, 0, '', '', '', 'preg', 'a:1:{s:4:\"preg\";s:20:\"#\\d+\\.\\d+\\.\\d+\\.\\d+#\";}', '_bx_antispam_field_ip_err_msg', 'Xss', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'Type', 'allow', '#!bx_antispam_ip_table_actions', 0, 'select', '_bx_antispam_field_action', '_bx_antispam_field_action', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'LastDT', '', '', 0, 'datetime', '_bx_antispam_field_expiration', '_bx_antispam_field_expiration', '', 1, 0, 0, '', '', '', 'date_time', '', '_bx_antispam_field_expiration_err_msg', 'DateTimeTs', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'Desc', '', '', 0, 'text', '_bx_antispam_field_note', '_bx_antispam_field_note', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'bx_antispam_ip_table_submit', '_sys_submit', '', 0, 'submit', '_sys_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'close', '_sys_close', '', 0, 'reset', '_sys_close', '', '', 0, 0, 0, 'a:2:{s:7:\"onclick\";s:46:\"$(\'.bx-popup-applied:visible\').dolPopupHide();\";s:5:\"class\";s:22:\"bx-def-margin-sec-left\";}', '', '', '', '', '', '', '', 1, 0),
+('bx_antispam_ip_table_form', 'bx_antispam', 'buttons', '', 'bx_antispam_ip_table_submit,close', 0, 'input_set', '_bx_antispam_form_buttons', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
+('bx_antispam_ip_table_form_add', 'ID', 2147483647, 0, 0),
+('bx_antispam_ip_table_form_add', 'From', 2147483647, 1, 1),
+('bx_antispam_ip_table_form_add', 'To', 2147483647, 1, 2),
+('bx_antispam_ip_table_form_add', 'Type', 2147483647, 1, 3),
+('bx_antispam_ip_table_form_add', 'LastDT', 2147483647, 1, 4),
+('bx_antispam_ip_table_form_add', 'Desc', 2147483647, 1, 5),
+('bx_antispam_ip_table_form_add', 'bx_antispam_ip_table_submit', 2147483647, 1, 6),
+('bx_antispam_ip_table_form_add', 'close', 2147483647, 1, 7),
+('bx_antispam_ip_table_form_add', 'buttons', 2147483647, 1, 8),
+('bx_antispam_ip_table_form_edit', 'ID', 2147483647, 1, 0),
+('bx_antispam_ip_table_form_edit', 'From', 2147483647, 1, 1),
+('bx_antispam_ip_table_form_edit', 'To', 2147483647, 1, 2),
+('bx_antispam_ip_table_form_edit', 'Type', 2147483647, 1, 3),
+('bx_antispam_ip_table_form_edit', 'LastDT', 2147483647, 1, 4),
+('bx_antispam_ip_table_form_edit', 'Desc', 2147483647, 1, 5),
+('bx_antispam_ip_table_form_edit', 'bx_antispam_ip_table_submit', 2147483647, 1, 6),
+('bx_antispam_ip_table_form_edit', 'close', 2147483647, 1, 7),
+('bx_antispam_ip_table_form_edit', 'buttons', 2147483647, 1, 8);
+
+-- alerts
+
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_antispam', 'BxAntispamAlertsResponse', 'modules/boonex/antispam/classes/BxAntispamAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('account', 'check_login', @iHandler),
+('account', 'check_join', @iHandler),
+('system', 'check_spam', @iHandler);
+
+-- email templates
+
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+('bx_antispam', '_bx_antispam_spam_report_name', 'bx_antispam_spam_report', '_bx_antispam_spam_report_subject', '_bx_antispam_spam_report_body');
+
+-- cron
+
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_antispam_pruning', '0 0 * * *', 'BxAntispamCronPruning', 'modules/boonex/antispam/classes/BxAntispamCronPruning.php', ''),
+('bx_antispam_update_disposable_email_domains', '0 0 */14 * *', 'BxAntispamCronUpdateDisposableEmailDomains', 'modules/boonex/antispam/classes/BxAntispamCronUpdateDisposableEmailDomains.php', '');
+

+ 37 - 0
modules/boonex/antispam/updates/9.0.6_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
+    <title>Antispam</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <path d="M20,0 C8.95435484,0 0,8.95427419 0,20 C0,31.0457258 8.95435484,40 20,40 C31.0456452,40 40,31.0456452 40,20 C40,8.95435484 31.0457258,0 20,0 Z M30.4925806,9.50741935 C35.7706452,14.7854839 36.1377419,22.8526613 32.1600806,28.5104032 L11.4895161,7.84 C17.151129,3.85967742 25.2174194,4.23233871 30.4925806,9.50741935 Z M9.50741935,30.4925806 C4.22935484,25.2145161 3.86225806,17.1473387 7.83991935,11.4895968 L28.5104839,32.16 C22.8489516,36.1403226 14.7825806,35.7677419 9.50741935,30.4925806 Z" id="path-4"></path>
+        <filter x="-5.0%" y="-2.5%" width="110.0%" height="110.0%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Artboard" transform="translate(-583.000000, -348.000000)">
+            <g id="Antispam" transform="translate(583.000000, 348.000000)">
+                <mask id="mask-2" fill="white">
+                    <use xlink:href="#path-1"></use>
+                </mask>
+                <use id="Path" fill="#FF3B38" xlink:href="#path-1"></use>
+                <g id="ban" mask="url(#mask-2)" fill-rule="nonzero">
+                    <g transform="translate(12.000000, 12.000000)" id="Shape">
+                        <g>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
+                            <use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 64 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlAlertsResponse.php

@@ -0,0 +1,64 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+class BxCnlAlertsResponse extends BxBaseModGroupsAlertsResponse
+{
+    public function __construct()
+    {
+        $this->MODULE = 'bx_channels';
+        parent::__construct();
+    }
+    
+    public function response($oAlert)
+    {
+        parent::response($oAlert);
+
+        $aProfileModulesAutofollowLabels = array('bx_persons', 'bx_organizations');
+        if (in_array($oAlert->sUnit, $aProfileModulesAutofollowLabels) && in_array($oAlert->sAction, array('added', 'edited'))) {
+            $this->_oModule->followLabels($oAlert->sUnit, $oAlert->iObject);
+        }
+
+        if ($oAlert->sUnit == 'meta_keyword' && $oAlert->sAction == 'added'){
+            if (isset($oAlert->aExtras['meta']) && isset($oAlert->aExtras['object']) && isset($oAlert->iObject) && isset($oAlert->iSender)){
+                /*
+                 * TODO: $oAlert->aExtras['object'] - contains Metatags object name but further it's used as Module name.
+                 * It's working correctly while Metatags object name is equal to Module name.
+                 * This should be changed in Ticket #1596
+                 * 
+                 * Also there is a problem that only Content's Author ID is saved, but further it's used to check visibility 
+                 * in case of Context. So, it works correctly when Author posts something with tags in his own profile, 
+                 * but will work incorrecly when Author posts something with tags in some Context (group, event, etc).
+                 * In this case system will use Author's profile as context instead of the real Context 
+                 * in which the content was posted.
+                 */
+                $this->_oModule->processHashtag($oAlert->aExtras['meta'], $oAlert->aExtras['object'], $oAlert->iObject, $oAlert->iSender);
+            }
+        }
+        
+        if ($oAlert->sUnit == 'meta_keyword' && $oAlert->sAction == 'url'){
+            if (isset($oAlert->aExtras['keyword'])){
+                $sName = $oAlert->aExtras['keyword'];
+                $iCnlId = $this->_oModule->_oDb->getChannelIdByName($sName);
+                if ($iCnlId > 0){
+                    $oAlert->aExtras['url'] = $this->_oModule->serviceProfileUrl($iCnlId);
+                }
+            }
+        }
+
+        if ($oAlert->sUnit == 'meta_keyword' && $oAlert->sAction == 'deleted'){
+            if (isset($oAlert->aExtras['object']) && isset($oAlert->iObject) && isset($oAlert->iSender)){
+                $this->_oModule->removeContentFromChannel($oAlert->iObject, $oAlert->aExtras['object']);
+            }
+        }
+    }
+}
+
+/** @} */

+ 184 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlConfig.php

@@ -0,0 +1,184 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+class BxCnlConfig extends BxBaseModProfileConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $aMenuItems2Methods = array (
+            'view-channel-profile' => 'checkAllowedView',
+            'edit-channel-profile' => 'checkAllowedEdit',
+            'edit-channel-cover' => 'checkAllowedChangeCover',
+            'invite-to-channel' => 'checkAllowedInvite',
+            'delete-channel-profile' => 'checkAllowedDelete',
+            'profile-subscribe-add' => 'checkAllowedSubscribeAdd',
+            'profile-subscribe-remove' => 'checkAllowedSubscribeRemove',
+            'profile-actions-more' => 'checkAllowedViewMoreMenu',
+            'convos-compose' => 'checkAllowedCompose',
+        );
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'hashtag col-red2',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+            'TABLE_ENTRIES_FULLTEXT' => 'search_fields',
+            'TABLE_CONTENT' => $aModule['db_prefix'] . 'content',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_NAME' => 'channel_name',
+            'FIELD_TITLE' => 'channel_name',
+            'FIELD_PICTURE' => 'picture',
+            'FIELD_COVER' => 'cover',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELDS_QUICK_SEARCH' => array('channel_name'),
+            '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-channel-profile',
+            'URI_EDIT_ENTRY' => 'edit-channel-profile',
+            'URI_EDIT_COVER' => 'edit-channel-cover',
+            'URI_JOINED_ENTRIES' => 'channels-author',
+
+            'URL_HOME' => 'page.php?i=channels-home',
+            'URL_MANAGE_COMMON' => 'page.php?i=channels-manage',
+            'URL_MANAGE_ADMINISTRATION' => 'page.php?i=channels-administration',
+
+            'PARAM_NUM_RSS' => 'bx_channels_num_rss',
+            'PARAM_NUM_CONNECTIONS_QUICK' => 'bx_channels_num_connections_quick',
+
+            'PARAM_SEARCHABLE_FIELDS' => 'bx_channels_searchable_fields',
+            'PARAM_PER_PAGE_BROWSE_SHOWCASE' => 'bx_channels_per_page_browse_showcase',
+            'PARAM_PER_PAGE_BROWSE_RECOMMENDED' => 'bx_channels_per_page_browse_recommended',
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_channels_pics',
+            'OBJECT_STORAGE_COVER' => 'bx_channels_pics',
+            'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_channels_thumb',
+            'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_channels_icon',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR' => 'bx_channels_avatar',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR_BIG' => 'bx_channels_avatar_big',
+            'OBJECT_IMAGES_TRANSCODER_PICTURE' => 'bx_channels_picture',
+            'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_channels_cover',
+            'OBJECT_IMAGES_TRANSCODER_COVER_THUMB' => 'bx_channels_cover_thumb',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_channels_gallery',
+            'OBJECT_VIEWS' => 'bx_channels',
+            'OBJECT_VOTES' => 'bx_channels',
+            'OBJECT_SCORES' => 'bx_channels',
+            'OBJECT_FAVORITES' => 'bx_channels',
+            'OBJECT_FEATURED' => 'bx_channels',
+            'OBJECT_COMMENTS' => 'bx_channels',
+            'OBJECT_REPORTS' => 'bx_channels',
+            'OBJECT_METATAGS' => 'bx_channels',
+            'OBJECT_FORM_ENTRY' => 'bx_channel',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_channel_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW_FULL' => 'bx_channel_view_full', // for "info" tab on view channel page
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_channel_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_channel_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER' => 'bx_channel_edit_cover',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_channel_delete',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_channels_view_actions', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE' => 'bx_channels_view_actions_more', // actions menu on view entry page for "more" popup
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_channels_view_actions_all', // all actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_channels_my', // actions menu on profile entries page
+            'OBJECT_MENU_SUBMENU' => 'bx_channels_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => '',  // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_COVER' => '',  // view entry submenu displayed in cover
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'channels-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_SNIPPET_META' => 'bx_channels_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_channels_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_PAGE_VIEW_ENTRY' => 'bx_channels_view_profile',
+            'OBJECT_PAGE_VIEW_ENTRY_CLOSED' => 'bx_channels_view_profile_closed',
+            'OBJECT_PRIVACY_VIEW' => 'bx_channels_allow_view_to',
+            'OBJECT_PRIVACY_VIEW_NOTIFICATION_EVENT' => 'bx_channels_allow_view_notification_to',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_channels_administration',
+            'OBJECT_UPLOADERS_COVER' => array('bx_channels_cover_crop'),
+            'OBJECT_UPLOADERS_PICTURE' => array('bx_channels_picture_crop'),
+      
+
+            'TRIGGER_MENU_PROFILE_VIEW_SUBMENU' => 'trigger_group_view_submenu',
+            'TRIGGER_MENU_PROFILE_SNIPPET_META' => 'trigger_group_snippet_meta',
+            'TRIGGER_MENU_PROFILE_VIEW_ACTIONS' => 'trigger_group_view_actions',
+            'TRIGGER_PAGE_VIEW_ENTRY' => 'trigger_page_group_view_entry',
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_channels_view_actions' => $aMenuItems2Methods,
+                'bx_channels_view_actions_more' => $aMenuItems2Methods,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'status' => array (
+                    'name' => 'bx-channels-status-not-active',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_channels_txt_account_pending',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_channels_txt_account_suspended',
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_channels_txt_sample_single',
+                'txt_sample_single_with_article' => '_bx_channels_txt_sample_single_with_article',
+                'txt_sample_comment_single' => '_bx_channels_txt_sample_comment_single',
+                'txt_sample_vote_single' => '_bx_channels_txt_sample_vote_single',
+                'txt_sample_score_up_single' => '_bx_channels_txt_sample_score_up_single',
+                'txt_sample_score_down_single' => '_bx_channels_txt_sample_score_down_single',
+                'txt_private_group' => '_bx_channels_txt_private_channel',
+                'txt_ntfs_timeline_post_common' => '_bx_channels_txt_ntfs_timeline_post_common',
+                'form_field_author' => '_bx_channels_form_entry_input_author',
+                'menu_item_title_befriend_sent' => '_bx_channels_menu_item_title_befriend_sent',
+                'menu_item_title_unfriend_cancel_request' => '_bx_channels_menu_item_title_unfriend_cancel_request',
+                'menu_item_title_befriend_confirm' => '_bx_channels_menu_item_title_befriend_confirm',
+                'menu_item_title_unfriend_reject_request' => '_bx_channels_menu_item_title_unfriend_reject_request',
+                'menu_item_title_befriend' => '_bx_channels_menu_item_title_befriend',
+                'menu_item_title_unfriend' => '_bx_channels_menu_item_title_unfriend',
+                'grid_action_err_delete' => '_bx_channels_grid_action_err_delete',
+                'grid_txt_account_manager' => '_bx_channels_grid_txt_account_manager',
+                'filter_item_active' => '_bx_channels_grid_filter_item_title_adm_active',
+                'filter_item_pending' => '_bx_channels_grid_filter_item_title_adm_pending',
+                'filter_item_suspended' => '_bx_channels_grid_filter_item_title_adm_suspended',
+                'filter_item_select_one_filter1' => '_bx_channels_grid_filter_item_title_adm_select_one_filter1',
+                'menu_item_manage_my' => '_bx_channels_menu_item_title_manage_my',
+                'menu_item_manage_all' => '_bx_channels_menu_item_title_manage_all',
+                'txt_all_entries_by_author' => '_bx_channels_page_title_browse_by_author'
+            ),
+
+        );
+
+        $this->_aJsClasses = array(
+            'manage_tools' => 'BxCnlManageTools'
+        );
+
+        $this->_aJsObjects = array(
+            'manage_tools' => 'oBxCnlManageTools'
+        );
+
+        $this->_aGridObjects = array(
+            'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION']
+        );
+    }
+
+}
+
+/** @} */

+ 105 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlDb.php

@@ -0,0 +1,105 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Channels module database queries
+ */
+class BxCnlDb extends BxBaseModGroupsDb
+{
+    public function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+
+    public function getChannelIdByName($sName)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        return $this->getOne("SELECT `" . $CNF['FIELD_ID'] . "` FROM `" . $CNF['TABLE_ENTRIES'] . "` WHERE `" . $CNF['FIELD_NAME'] . "` = :name", array(
+            'name' => $sName,
+        ));
+    }
+
+    public function getChannelInfoByName($sName)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        return $this->getRow("SELECT `c`.*, `p`.`account_id`, `p`.`id` AS `profile_id`, `a`.`email` AS `profile_email`, `a`.`ip` AS `profile_ip`, `p`.`status` AS `profile_status` FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `c` INNER JOIN `sys_profiles` AS `p` ON (`p`.`content_id` = `c`.`id` AND `p`.`type` = :type) INNER JOIN `sys_accounts` AS `a` ON (`p`.`account_id` = `a`.`id`) WHERE `c`.`channel_name` = :name", array(
+            'type' => $this->_oConfig->getName(),
+            'name' => $sName,
+        ));
+    }
+
+    public function addContentToChannel($iContentId, $iCnlId, $sModuleName, $iAuthorId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'content_id' => $iContentId,
+            'cnl_id' => $iCnlId,
+            'module_name' => $sModuleName,
+            'author_id' => $iAuthorId,
+        );
+        $this->query("INSERT INTO `" . $CNF['TABLE_CONTENT'] . "` (`content_id`, `cnl_id`, `module_name`, `author_id`) VALUES (:content_id, :cnl_id, :module_name, :author_id)", $aBindings);
+        return $this->lastId();
+    }
+    
+    public function checkContentInChannel($iContentId, $iCnlId, $sModuleName, $iAuthorId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'content_id' => $iContentId,
+            'cnl_id' => $iCnlId,
+            'module_name' => $sModuleName,
+            'author_id' => $iAuthorId,
+        );
+        return $this->getOne("SELECT COUNT(*) FROM `" . $CNF['TABLE_CONTENT'] . "` WHERE `content_id` = :content_id AND `module_name` = :module_name  AND `cnl_id` = :cnl_id AND `author_id` =:author_id", $aBindings);
+    }
+    
+    public function getContentById($iId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'id' => $iId
+        );
+        return $this->getFirstRow("SELECT * FROM `" . $CNF['TABLE_CONTENT'] . "` WHERE `id` = :id", $aBindings);
+    }
+    
+    public function getDataByContent($iContentId, $sModuleName)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'content_id' => $iContentId,
+            'module_name' => $sModuleName
+        );
+        return $this->getAll("SELECT `id`, `author_id`, `cnl_id` FROM `" . $CNF['TABLE_CONTENT'] . "` WHERE `content_id` = :content_id AND `module_name` = :module_name", $aBindings);
+    }
+    
+    public function removeContentFromChannel($iContentId, $sModuleName)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'content_id' => $iContentId,
+            'module_name' => $sModuleName
+        );
+        $this->query("DELETE FROM `" . $CNF['TABLE_CONTENT'] . "` WHERE `content_id` = :content_id AND `module_name` = :module_name", $aBindings);
+    }
+	
+	public function removeChannelContent($iChannelId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $aBindings = array(
+            'channel_id' => $iChannelId
+        );
+        $this->query("DELETE FROM `" . $CNF['TABLE_CONTENT'] . "` WHERE `cnl_id` = :channel_id", $aBindings);
+    }
+}
+
+/** @} */

+ 40 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlFormEntry.php

@@ -0,0 +1,40 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+
+class BxCnlFormCheckerHelper extends BxDolFormCheckerHelper
+{
+    static public function checkNameExistOrEmpty($s)
+    {
+        if (trim($s) == '')
+            return false;
+         
+       $oModule = BxDolModule::getInstance('bx_channels');       
+       if ($oModule->_oDb->getChannelIdByName($s) !== false)
+            return false;
+        
+        return true;
+    }
+}
+
+/**
+ * Create/Edit Channel Form.
+ */
+class BxCnlFormEntry extends BxBaseModGroupsFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_channels';
+        parent::__construct($aInfo, $oTemplate);
+    }
+}
+
+/** @} */

+ 29 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlFormsEntryHelper.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
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Channels profile forms functions
+ */
+class BxCnlFormsEntryHelper extends BxBaseModGroupsFormsEntryHelper
+{
+    public function __construct($oModule)
+    {
+        parent::__construct($oModule);
+    }
+    
+    public function onDataDeleteAfter ($iContentId, $aContentInfo, $oProfile)
+    {
+        $this->_oModule->_oDb->removeChannelContent($iContentId);
+        return parent::onDataDeleteAfter ($iContentId, $aContentInfo, $oProfile);
+    }
+}
+
+/** @} */

+ 25 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlMenuView.php

@@ -0,0 +1,25 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * 'View channel' menu.
+ */
+class BxCnlMenuView extends BxBaseModGroupsMenuView
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->_sModule = 'bx_channels';
+
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 24 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlMenuViewActions.php

@@ -0,0 +1,24 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * 'View channel' actions menu.
+ */
+class BxCnlMenuViewActions extends BxBaseModGroupsMenuViewActions
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_channels';
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 374 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlModule.php

@@ -0,0 +1,374 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Channels profiles module.
+ */
+
+class BxCnlModule extends BxBaseModGroupsModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+   
+    public function checkAllowedSubscribeAdd (&$aDataEntry, $isPerformAction = false)
+    {
+        return parent::_checkAllowedSubscribeAdd ($aDataEntry, $isPerformAction);
+    }
+    
+    /**
+     * Process Hash Tag
+     * 
+     * @param string $sHashtag - hashtag to be processed.
+     * @param string $sModuleName - module name.
+     * @param integer $iContentId - ID of the content which has the hashtag.
+     * @param integer $iAuthorId - action's author id.
+     */
+    function processHashtag($sHashtag, $sModuleName, $iContentId, $iAuthorId)
+    {
+        /*
+         * Note! For now metatag object name is used here as module name, because usually it's equal to module's name. This should be changed in Ticket #1596
+         * For now if module cannot be created then a channel for such tag shouldn't be created too.
+         */
+        $oModule = BxDolModule::getInstance($sModuleName);
+        if(empty($oModule))
+            return;
+
+        $aCheck = checkActionModule($this->_iProfileId, 'create channel auto', $this->getName(), false);
+        $mixedCnlId = $this->_oDb->getChannelIdByName($sHashtag);
+        if (empty($mixedCnlId) && ($aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED)){
+            $CNF = &$this->_oConfig->CNF;
+            $oAccountQuery = BxDolAccountQuery::getInstance();
+            $aOperators = $oAccountQuery->getOperators();
+            if(count($aOperators) > 0){
+                $oProfile = BxDolProfile::getInstanceByAccount($aOperators[0]);
+                $aContent = $this->serviceEntityAdd($oProfile->id(), array($CNF['FIELD_NAME'] => $sHashtag));
+                checkActionModule($this->_iProfileId, 'create channel auto', $this->getName(), true);
+                if (isset($aContent['content']) && isset($aContent['content']['id']))
+                    $mixedCnlId = $aContent['content']['id'];
+            }
+        }
+
+        if(empty($mixedCnlId) || (int)$this->_oDb->checkContentInChannel($iContentId, $mixedCnlId, $sModuleName, $iAuthorId) != 0)
+            return;
+
+        $iId = (int)$this->_oDb->addContentToChannel($iContentId, $mixedCnlId, $sModuleName, $iAuthorId);
+        if($iId == 0)
+            return;
+
+        $oCnlProfile = BxDolProfile::getInstanceByContentAndType($mixedCnlId, $this->_oConfig->getName());
+        if(!$oCnlProfile)
+            return;
+
+        $iCnlProfileId = $oCnlProfile->id();
+
+        bx_alert($this->_aModule['name'], 'hashtag_added', $iId, $iCnlProfileId, array(
+            'object_author_id' => $iAuthorId, 
+            'privacy_view' => -$iCnlProfileId,
+
+            'timeline_group' => array(
+                'by' => $sModuleName . '_' . $iAuthorId . '_' . $iContentId,
+                'field' => 'owner_id'
+            )
+        ));
+
+        bx_alert($this->_aModule['name'], 'hashtag_added_notif', $mixedCnlId, $iCnlProfileId, array(
+            'object_author_id' => $iAuthorId, 
+            'privacy_view' => -$iCnlProfileId, 
+            'subobject_id' => $iId,
+
+            'content_id' => $iContentId,
+            'content_author_id' => $iAuthorId
+        ));
+    }
+    
+    function removeContentFromChannel($iContentId, $sModuleName)
+    {
+        $oDolProfileQuery = BxDolProfileQuery::getInstance();
+        
+        $aData = $this->_oDb->getDataByContent($iContentId, $sModuleName);
+        foreach ($aData as $aRow) {
+            $iProfileInfo = $oDolProfileQuery->getProfileByContentAndType($aRow['cnl_id'], $this->_aModule['name']);
+            if(is_array($iProfileInfo)){
+                bx_alert($this->_aModule['name'], 'hashtag_deleted', $aRow['id'], $iProfileInfo['id']);
+                bx_alert($this->_aModule['name'], 'hashtag_deleted_notif', $aRow['cnl_id'], $iProfileInfo['id'], array('subobject_id' => $aRow['id']));
+            }
+        }
+        
+        return $this->_oDb->removeContentFromChannel($iContentId, $sModuleName);
+    }
+
+    public function serviceEntityBreadcrumb($iContentId = 0)
+    {
+    	if(!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(!$iContentId)
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if(!$aContentInfo)
+            return false;
+
+        return $this->_oTemplate->entryBreadcrumb($aContentInfo);
+    }
+
+    public function serviceEntityParent($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc('entryParent', $iContentId);
+    }
+
+    public function serviceEntityChilds($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc('entryChilds', $iContentId);
+    }
+
+    function serviceSearchResultByHashtag($iContentId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $oSearch = new BxTemplSearch();
+        $oSearch->setLiveSearch(0);
+        $oSearch->setMetaType('keyword');
+        $aContentInfo = $this->_oDb->getContentInfoById(bx_get('id'));
+        $_GET['keyword'] = $aContentInfo[$CNF['FIELD_NAME']];
+        $sCode = $oSearch->response();
+        if (!$sCode)
+            $sCode = $oSearch->getEmptyResult();
+        
+        return $sCode;
+    }
+    
+    /**
+     * Data for Timeline module
+     */
+    public function serviceGetTimelineData()
+    {
+        $sModule = $this->_aModule['name'];
+
+        return array(
+            'handlers' => array(
+                array('group' => $sModule . '_hastag', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'hashtag_added', 'module_name' => $sModule, 'module_method' => 'get_timeline_post_hashtag', 'module_class' => 'Module',  'groupable' => 0, 'group_by' => ''),
+                array('group' => $sModule . '_hastag', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'hashtag_deleted')
+            ),
+            'alerts' => array(
+                array('unit' => $sModule, 'action' => 'hashtag_added'),
+                array('unit' => $sModule, 'action' => 'hashtag_deleted')
+            )
+        );
+    }
+    
+    public function serviceGetTimelinePostHashtag($aEvent, $aBrowseParams = array())
+    {
+        if(empty($aEvent) || !is_array($aEvent))
+            return false;
+
+        $aEventContent = $this->_oDb->getContentById($aEvent['object_id']);
+        if(empty($aEventContent) || !is_array($aEventContent))
+            return false;
+
+        if(!BxDolRequest::serviceExists($aEventContent['module_name'], 'get_timeline_post'))
+            return false;      
+
+        return BxDolService::call($aEventContent['module_name'], 'get_timeline_post', array(array('owner_id' => $aEventContent['author_id'], 'object_id' => $aEventContent['content_id'])));
+    }
+    
+    /**
+     * Data for Notifications module
+     */
+    public function serviceGetNotificationsData()
+    {      
+        $a = parent::serviceGetNotificationsData();
+
+        $sModule = $this->_aModule['name'];
+
+        $a['handlers'][] = array('group' => $sModule . '_hastag_notif', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'hashtag_added_notif', 'module_name' => $sModule, 'module_method' => 'get_notifications_post_hashtag', 'module_class' => 'Module');
+        $a['handlers'][] = array('group' => $sModule . '_hastag_notif', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'hashtag_deleted_notif');
+
+        $a['settings'][] = array('group' => 'hastag', 'unit' => $sModule, 'action' => 'hashtag_added_notif', 'types' => array('follow_context'));
+
+        $a['alerts'][] = array('unit' => $sModule, 'action' => 'hashtag_added_notif');
+        $a['alerts'][] = array('unit' => $sModule, 'action' => 'hashtag_deleted_notif');
+
+        return $a;
+    }
+
+    public function serviceGetNotificationsPostHashtag($aEvent)
+    {
+        if(empty($aEvent) || !is_array($aEvent))
+            return '';
+
+        $aContentEvent = $this->_oDb->getContentById($aEvent['subobject_id']);
+        if(empty($aContentEvent) || !is_array($aContentEvent))
+            return '';
+
+        $oModule = BxDolModule::getInstance($aContentEvent['module_name']);
+        if ($oModule) {
+            if (isset($oModule->_oConfig->CNF['OBJECT_PRIVACY_VIEW'])){
+                $oPrivacy = BxDolPrivacy::getObjectInstance($oModule->_oConfig->CNF['OBJECT_PRIVACY_VIEW']);
+                if (!$oPrivacy->check($aContentEvent['content_id']))
+                    return '';
+            }
+
+            $aRv = $oModule->serviceGetNotificationsPost(array(
+                'object_id' => $aContentEvent['content_id']
+            ));
+
+            $aRv['lang_key'] = '_bx_channels_ntfs_txt_subobject_added';
+            if(method_exists($oModule, 'serviceActAsProfile') && $oModule->serviceActAsProfile())
+                $aRv['lang_key'] = '_bx_channels_ntfs_txt_subobject_added_profile';
+
+            $aRv['entry_url'] = $this->serviceGetLink($aContentEvent['cnl_id']);
+            return $aRv;
+        }
+
+        return '';
+    }
+    
+    public function serviceBrowseAuthor($iProfileId = 0, $aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($iProfileId))
+            $iProfileId = bx_get_logged_profile_id();
+
+        $sResult = isset($aParams['empty_message']) && (bool)$aParams['empty_message'] === true ? MsgBox(_t('_Empty')) : '';
+
+        $oConnection = BxDolConnection::getObjectInstance('sys_profiles_subscriptions');
+        $aProfile = $oConnection->getConnectedContent($iProfileId);
+        $aVars = array();
+        foreach ($aProfile as $iProfileId) {
+            $oProfile = BxDolProfile::getInstance($iProfileId);
+            if (!$oProfile || $oProfile->getModule() != $this->getName())
+                continue;
+
+            $iContentId = $oProfile->getContentId();
+            $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+            if (isset($aContentInfo[$CNF['FIELD_NAME']]))
+                array_push($aVars, array('title' => $aContentInfo[$CNF['FIELD_NAME']], 'link' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId)));
+        }
+
+        if(empty($aVars) || !is_array($aVars))
+            return $sResult;
+
+        return $this->_oTemplate->parseHtmlByName('my_channels.html', array(
+            'bx_if:show_list' => array(
+                'condition' => count($aVars) > 0,
+                'content' => array(
+                    'bx_repeat:items' => $aVars
+                )
+            )
+        ));
+    }
+    
+    public function serviceDeleteProfileFromFansAndAdmins ($iProfileId)
+    {
+        return true;
+    }
+
+    public function serviceGetFollowingChannelsNames($iProfileId)
+    {
+        if (!($oConn = BxDolConnection::getObjectInstance('sys_profiles_subscriptions')))
+            return array();
+
+        if (!($aIds = $oConn->getConnectedContent($iProfileId)))
+            return array();
+
+        $a = array();
+        foreach ($aIds as $iId) {
+            if (!($oProfile = BxDolProfile::getInstance($iId)))
+                continue;
+            if ($oProfile->getModule() != $this->getName())
+                continue;
+            $a[] = $oProfile->getDisplayName();
+        }
+        return $a;
+    }
+    
+    public function checkAllowedCompose (&$aDataEntry, $isPerformAction = false)
+    {
+        return _t('_sys_txt_access_denied');
+    }
+
+    public function followLabels($sModule, $iContentId)
+    {
+        if (!getParam('bx_channels_labels_autofollow'))
+            return;
+        
+        if (!($oModuleProfiles = BxDolModule::getInstance($sModule)))
+            return;
+
+        if (!($aContentInfo = $oModuleProfiles->_oDb->getContentInfoById($iContentId)) || !($oProfile = BxDolProfile::getInstanceByContentAndType($iContentId, $sModule)))
+            return;
+
+        $CNF = &$oModuleProfiles->_oConfig->CNF;
+        
+        if (!$oModuleProfiles->serviceActAsProfile() || !isset($CNF['FIELD_LABELS']) || empty($aContentInfo[$CNF['FIELD_ID']]))
+            return;
+
+        if (!($oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS'])) || !$oMetatags->keywordsIsEnabled() || !($aLabels = $oMetatags->keywordsGet($aContentInfo[$CNF['FIELD_ID']])))
+            return;
+
+        if (!($oConn = BxDolConnection::getObjectInstance('sys_profiles_subscriptions')))
+            return;
+
+        foreach ($aLabels as $sLabel) {
+
+            if (!($iContentIdChannel = $this->_oDb->getChannelIdByName($sLabel)))
+                continue;
+
+            if (!($oProfileChannel = BxDolProfile::getInstanceByContentAndType($iContentIdChannel, 'bx_channels')))
+                continue;
+
+            $oConn->addConnection($oProfile->id(), $oProfileChannel->id());
+        }
+    }
+
+    /** Returns profile's subscribed channels  React Jot
+     *
+     * @param int $iProfileId
+     * @param array $aParams
+     * @return array
+     */
+
+    public function serviceBrowseAuthorChannels($iProfileId = 0, $aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($iProfileId))
+            $iProfileId = bx_get_logged_profile_id();
+
+        $oConnection = BxDolConnection::getObjectInstance('sys_profiles_subscriptions');
+        $aProfile = $oConnection->getConnectedContent($iProfileId);
+        $aVars = array();
+        foreach ($aProfile as $iProfileId) {
+            $oProfile = BxDolProfile::getInstance($iProfileId);
+            if (!$oProfile || $oProfile->getModule() != $this->getName())
+                continue;
+
+            $iContentId = $oProfile->getContentId();
+            $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+
+            if (isset($aContentInfo[$CNF['FIELD_NAME']]))
+                array_push($aVars, array(
+                    'title' => $aContentInfo[$CNF['FIELD_NAME']],
+                    'link' => BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId),
+                    'followers' => $oConnection -> getConnectedInitiatorsCount($iProfileId),
+                    'id' => $iProfileId,
+                    'icon' => $oProfile -> getThumb()
+                ));
+        }
+
+        return $aVars;
+    }
+}
+
+/** @} */

+ 122 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/classes/BxCnlTemplate.php

@@ -0,0 +1,122 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Channels module representation.
+ */
+class BxCnlTemplate extends BxBaseModGroupsTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        $this->MODULE = 'bx_channels';
+        parent::__construct($oConfig, $oDb);
+    }
+
+    public function entryBreadcrumb($aContentInfo, $aTmplVarsItems = array())
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+        $oLabel = BxDolLabel::getInstance();
+        $oPermalink = BxDolPermalinks::getInstance();
+
+        $aLabel = $oLabel->getLabels(array('type' => 'value', 'value' => $aContentInfo[$CNF['FIELD_NAME']]));
+        if(empty($aLabel) || !is_array($aLabel))
+            return '';
+
+        $aTmplVarsItems = array();
+        $this->_entryBreadcrumb($aLabel['id'], $oLabel, $oPermalink, $aTmplVarsItems);
+        $aTmplVarsItems = array_reverse($aTmplVarsItems);
+
+    	return parent::entryBreadcrumb($aContentInfo, $aTmplVarsItems);
+    }
+
+    public function entryParent($aContentInfo)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $oLabel = BxDolLabel::getInstance();
+
+        $aLabel = $oLabel->getLabels(array('type' => 'value', 'value' => $aContentInfo[$CNF['FIELD_NAME']]));
+        if(empty($aLabel) || !is_array($aLabel) || (int)$aLabel['parent'] == 0)
+            return false;
+
+        $aLabelParent = $oLabel->getLabels(array('type' => 'id', 'id' => $aLabel['parent']));
+        $aContentInfoParent = $this->_oDb->getChannelInfoByName($aLabelParent['value']);
+        if(empty($aContentInfoParent) || !is_array($aContentInfoParent))
+            return false;
+
+        return $this->parseHtmlByName('entry-parent.html', array('content' => $this->_entryRelatives(array($aContentInfoParent['profile_id']))));
+    }
+
+    public function entryChilds($aContentInfo)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        $oLabel = BxDolLabel::getInstance();
+
+        $aLabel = $oLabel->getLabels(array('type' => 'value', 'value' => $aContentInfo[$CNF['FIELD_NAME']]));
+        if(empty($aLabel) || !is_array($aLabel))
+            return false;
+
+        $aLabelChildren = $oLabel->getLabels(array('type' => 'parent', 'parent' => $aLabel['id']));
+        if(empty($aLabelChildren) || !is_array($aLabelChildren))
+            return false;
+
+        $aIds = array();
+        foreach($aLabelChildren as $aLabelChild) {
+            $aContentInfoChild = $this->_oDb->getChannelInfoByName($aLabelChild['value']);
+            if(empty($aContentInfoChild) || !is_array($aContentInfoChild))
+                continue;
+            
+            $aIds[] = $aContentInfoChild['profile_id'];
+        }
+
+        if(empty($aIds))
+            return false;
+
+        return $this->parseHtmlByName('entry-childs.html', array('content' => $this->_entryRelatives($aIds)));
+    }
+
+    protected function _entryBreadcrumb($iLabel, &$oLabel, &$oPermalink, &$aTmplVarsItems)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aLabel = $oLabel->getLabels(array('type' => 'id', 'id' => $iLabel));
+        if(empty($aLabel) || !is_array($aLabel))
+            return;
+
+        $iChannel = (int)$this->_oDb->getChannelIdByName($aLabel['value']);
+        $aTmplVarsItems[] = array(
+            'url' => $iChannel != 0 ? $oPermalink->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iChannel) : 'javascript:void(0)',
+            'title' => bx_process_output($aLabel['value'])
+        );
+
+        if(empty($aLabel['parent']))
+            return;
+
+        $this->_entryBreadcrumb((int)$aLabel['parent'], $oLabel, $oPermalink, $aTmplVarsItems);
+    }
+    
+    protected function _entryRelatives($aProfiles)
+    {
+        $sResult = '';
+
+        foreach($aProfiles as $iProfile) {
+            $oProfile = BxDolProfile::getInstance($iProfile);
+            if(!$oProfile)
+                continue;
+
+            $sResult .= $oProfile->getUnit(false, array('template' => 'unit_wo_cover'));
+        }
+
+        return $sResult;
+    }
+}
+
+/** @} */

+ 153 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/install/config.php

@@ -0,0 +1,153 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Channels Channels
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_channels',
+    'title' => 'Channels',
+    'note' => 'Channels functionality.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use channels in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/channels/',
+    'home_uri' => 'channels',
+
+    'db_prefix' => 'bx_cnl_',
+    'class_prefix' => 'BxCnl',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Channels',
+
+    /**
+     * Connections.
+     */
+    'connections' => array(
+        'sys_profiles_friends' => array ('type' => 'profiles'),
+        'sys_profiles_subscriptions' => array ('type' => 'profiles'),
+    ),
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_submenu',
+        'trigger_group_view_submenu',
+        'trigger_group_snippet_meta',
+        'trigger_group_view_actions',
+    ),
+
+    /**
+     * Page triggers.
+     */
+    'page_triggers' => array (
+        'trigger_page_profile_view_entry',
+        'trigger_page_group_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_channels_pics'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_channels_icon',
+        'bx_channels_thumb',
+        'bx_channels_avatar',
+        'bx_channels_avatar_big',
+        'bx_channels_picture',
+        'bx_channels_cover',
+        'bx_channels_cover_thumb',
+        'bx_channels_gallery'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_channels',
+        'bx_channels_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',
+    ),
+);
+
+/** @} */

+ 236 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/install/langs/en.xml

@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_channels"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_cmts"><![CDATA[Channels' Comments]]></string>
+	
+	<string name="_bx_channels_option_num_connections_quick"><![CDATA[Number of items in friends block]]></string>
+	<string name="_bx_channels_option_per_page_browse"><![CDATA[Number of items per page]]></string>
+	<string name="_bx_channels_option_num_rss"><![CDATA[Number of items in RSS feed]]></string>
+    <string name="_bx_channels_option_searchable_fields"><![CDATA[Searchable fields]]></string>
+    <string name="_bx_channels_option_labels_autofollow"><![CDATA[Auto-follow channels when used as labels in profiles]]></string>
+	
+	<string name="_bx_channels_form_profile"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_form_profile_display_add"><![CDATA[Add Channel]]></string>
+	<string name="_bx_channels_form_profile_display_edit"><![CDATA[Edit Channel]]></string>
+	<string name="_bx_channels_form_profile_display_edit_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_channels_form_profile_display_delete"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_form_profile_display_view"><![CDATA[View Channel]]></string>
+	<string name="_bx_channels_form_profile_display_view_full"><![CDATA[Full View Channel]]></string>
+	<string name="_bx_channels_form_profile_display_invite"><![CDATA[Invite to Channel]]></string>
+	<string name="_bx_channels_form_entry_input_author"><![CDATA[Author]]></string>
+	<string name="_bx_channels_form_profile_input_sys_do_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_channels_form_profile_input_sys_allow_view_to"><![CDATA[Privacy]]></string>
+	<string name="_bx_channels_form_profile_input_allow_view_to"><![CDATA[Privacy]]></string>
+	<string name="_bx_channels_form_profile_input_allow_view_to_desc"><![CDATA[Closed - anyone can find the channel and see who's in it, only members can see posts. Secret - only members can find the channel and see posts.]]></string>
+	<string name="_bx_channels_form_profile_input_sys_initial_members"><![CDATA[Invite Members]]></string>
+	<string name="_bx_channels_form_profile_input_initial_members"><![CDATA[Invite Members]]></string>
+  	<string name="_bx_channels_form_profile_input_sys_channel_name"><![CDATA[Channel Name]]></string>
+	<string name="_bx_channels_form_profile_input_channel_name"><![CDATA[Channel Name]]></string>
+	<string name="_bx_channels_form_profile_input_channel_name_err"><![CDATA[Please, fill in this field. Channel name must be unique.]]></string>
+	<string name="_bx_channels_form_profile_input_sys_picture"><![CDATA[Channel Picture]]></string>
+	<string name="_bx_channels_form_profile_input_picture"><![CDATA[Upload New Channel Picture]]></string>
+	<string name="_bx_channels_form_profile_input_picture_err"><![CDATA[Channel picture is mandatory.]]></string>
+	<string name="_bx_channels_form_profile_input_sys_cover"><![CDATA[Cover Picture]]></string>
+	<string name="_bx_channels_form_profile_input_cover"><![CDATA[Upload New Cover Picture]]></string>
+	<string name="_bx_channels_form_profile_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+	<string name="_bx_channels_form_profile_input_delete_confirm"><![CDATA[I am sure I want to delete this channel]]></string>
+	<string name="_bx_channels_form_profile_input_delete_confirm_info"><![CDATA[This action can not be undone.]]></string>
+	<string name="_bx_channels_form_profile_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete channel.]]></string>
+	
+	<string name="_bx_channels_acl_action_create_profile"><![CDATA[Create Channel]]></string>
+	<string name="_bx_channels_acl_action_delete_profile"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_acl_action_view_profile"><![CDATA[View Channel]]></string>
+	<string name="_bx_channels_acl_action_edit_any_profile"><![CDATA[Edit Any Channel]]></string>
+  <string name="_bx_channels_acl_action_create_channel_auto"><![CDATA[Create Channel Auto]]></string>
+
+  <string name="_bx_channels_page_title_sys_create_profile"><![CDATA[Create Channel]]></string>
+	<string name="_bx_channels_page_title_create_profile"><![CDATA[Create Channel]]></string>
+	<string name="_bx_channels_page_title_sys_edit_profile"><![CDATA[Edit Channel]]></string>
+	<string name="_bx_channels_page_title_edit_profile"><![CDATA[Edit Channel]]></string>
+	<string name="_bx_channels_page_title_sys_edit_profile_cover"><![CDATA[Edit Channel Cover]]></string>
+	<string name="_bx_channels_page_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_channels_page_title_sys_delete_profile"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_page_title_delete_profile"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_page_title_sys_view_profile_closed"><![CDATA[View Closed Channel]]></string>
+	<string name="_bx_channels_page_title_sys_view_profile"><![CDATA[View Channel]]></string>
+	<string name="_bx_channels_page_title_view_profile"><![CDATA[{display_name}]]></string>
+	<string name="_bx_channels_page_title_browse"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_page_title_browse_by_author"><![CDATA[Channels of {display_name}]]></string>
+	<string name="_bx_channels_page_title_browse_featured"><![CDATA[Featured Channels]]></string>
+	<string name="_bx_channels_page_title_browse_top"><![CDATA[Top Channels]]></string>
+	<string name="_bx_channels_page_title_browse_recent"><![CDATA[New Channels]]></string>
+	<string name="_bx_channels_page_title_browse_connections"><![CDATA[{0} connections]]></string>
+	<string name="_bx_channels_page_title_browse_connections_mutual"><![CDATA[{0} and {1} mutual connections]]></string>
+	<string name="_bx_channels_page_title_sys_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_page_title_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_page_title_sys_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_channels_page_title_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_channels_page_title_sys_profile_info"><![CDATA[Channel Info]]></string>
+	<string name="_bx_channels_page_title_profile_info"><![CDATA[Info about {display_name}]]></string>
+	<string name="_bx_channels_page_title_sys_recent"><![CDATA[New Channels]]></string>
+	<string name="_bx_channels_page_title_recent"><![CDATA[New Channels]]></string>
+	<string name="_bx_channels_page_title_sys_manage"><![CDATA[Manage Own Channels]]></string>
+	<string name="_bx_channels_page_title_sys_manage_administration"><![CDATA[Manage All Channels]]></string>
+	<string name="_bx_channels_page_title_manage"><![CDATA[Manage Channels]]></string>
+	<string name="_bx_channels_page_title_sys_top"><![CDATA[Top Channels]]></string>
+	<string name="_bx_channels_page_title_top"><![CDATA[Top Channels]]></string>
+	<string name="_bx_channels_page_title_sys_entries_search"><![CDATA[Search]]></string>
+	<string name="_bx_channels_page_title_entries_search"><![CDATA[Search]]></string>
+        <string name="_bx_channels_page_title_sys_entries_of_author"><![CDATA[Сhannels of author]]></string>
+        <string name="_bx_channels_page_title_entries_of_author"><![CDATA[Сhannels by {display_name}]]></string>
+
+        <string name="_bx_channels_page_block_title_sys_entries_actions"><![CDATA[Channels actions]]></string>
+	<string name="_bx_channels_page_block_title_entries_actions"><![CDATA[Channels actions]]></string>
+	<string name="_bx_channels_page_block_title_sys_entries_of_author"><![CDATA[Followed Сhannels]]></string>
+	<string name="_bx_channels_page_block_title_entries_of_author"><![CDATA[Followed Сhannels]]></string>
+	<string name="_bx_channels_page_block_title_favorites_of_author"><![CDATA[Favorite Channels]]></string>
+	<string name="_bx_channels_page_block_title_sys_favorites_of_author"><![CDATA[Favorite Channels]]></string>
+  <string name="_bx_channels_page_block_title_create_profile"><![CDATA[Create Channel]]></string>
+	<string name="_bx_channels_page_block_title_edit_profile"><![CDATA[Edit Channel]]></string>
+	<string name="_bx_channels_page_block_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_channels_page_block_title_delete_profile"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_page_block_title_profile_info_link"><![CDATA[About <a href="{profile_link}">{display_name}</a>]]></string>
+	<string name="_bx_channels_page_block_title_profile_info"><![CDATA[Info]]></string>
+	<string name="_bx_channels_page_block_title_system_profile_info"><![CDATA[Info]]></string>
+	<string name="_bx_channels_page_block_title_profile_description"><![CDATA[Description]]></string>
+	<string name="_bx_channels_page_block_title_profile_friends_link"><![CDATA[Friends of <a href="{profile_link}">{display_name}</a>]]></string>
+	<string name="_bx_channels_page_block_title_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_page_block_title_system_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_page_block_title_admins"><![CDATA[Administrators]]></string>
+	<string name="_bx_channels_page_block_title_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_channels_page_block_title_profile_comments_link"><![CDATA[Comments to <a href="{entry_link}">{title}</a>]]></string>
+	<string name="_bx_channels_page_block_title_profile_actions"><![CDATA[Actions]]></string>
+	<string name="_bx_channels_page_block_title_featured_profiles"><![CDATA[Featured Channels]]></string>
+	<string name="_bx_channels_page_block_title_latest_profiles"><![CDATA[New Channels]]></string>
+	<string name="_bx_channels_page_block_title_system_manage"><![CDATA[Manage Own Channels]]></string>
+	<string name="_bx_channels_page_block_title_system_manage_administration"><![CDATA[Manage All Channels]]></string>
+	<string name="_bx_channels_page_block_title_manage"><![CDATA[Manage Channels]]></string>
+	<string name="_bx_channels_page_block_title_top_profiles"><![CDATA[Top Channels]]></string>
+        <string name="_bx_channels_page_block_title_entry_all_actions"><![CDATA[All Actions]]></string>
+	<string name="_bx_channels_page_block_title_entry_social_sharing"><![CDATA[Share]]></string>
+        <string name="_bx_channels_page_block_title_entry_breadcrumb"><![CDATA[Breadcrumb]]></string>
+        <string name="_bx_channels_page_block_title_entry_parent"><![CDATA[Parent Channel]]></string>
+        <string name="_bx_channels_page_block_title_entry_childs"><![CDATA[Child Channels]]></string>
+	<string name="_bx_channels_page_block_title_search_form"><![CDATA[Search Form]]></string>
+        <string name="_bx_channels_page_block_title_entries_my"><![CDATA[My Followed Channels]]></string>
+        <string name="_bx_channels_page_trigger_block_title_entries_my"><![CDATA[My Followed Channels]]></string>
+        <string name="_bx_channels_page_block_title_search_results"><![CDATA[Search Results]]></string>
+        <string name="_bx_channels_page_block_title_search_results_by_hashtag"><![CDATA[Search Results By Hashtag]]></string>
+	<string name="_bx_channels_page_block_title_search_form_cmts"><![CDATA[Comments Search Form]]></string>
+	<string name="_bx_channels_page_block_title_search_results_cmts"><![CDATA[Comments Search Results]]></string>
+	<string name="_bx_channels_page_block_title_sys_featured_entries_view_showcase"><![CDATA[Featured Channels (Showcase View)]]></string>
+	<string name="_bx_channels_page_block_title_featured_entries_view_showcase"><![CDATA[Featured Channels]]></string>
+	<string name="_bx_channels_page_block_title_sys_recommended_entries_view_showcase"><![CDATA[Recommended Channels (Showcase View)]]></string>
+	<string name="_bx_channels_page_block_title_recommended_entries_view_showcase"><![CDATA[Recommended Channels]]></string>
+
+	<string name="_bx_channels_menu_title_submenu"><![CDATA[Channels Submenu]]></string>
+	<string name="_bx_channels_menu_set_title_submenu"><![CDATA[Channels Submenu]]></string>
+	<string name="_bx_channels_menu_set_title_view_profile_actions"><![CDATA[Channel Actions]]></string>
+	<string name="_bx_channels_menu_title_view_profile_actions"><![CDATA[Channel Actions]]></string>
+	<string name="_bx_channels_menu_set_title_view_profile_actions_more"><![CDATA[Channel More Actions]]></string>
+	<string name="_bx_channels_menu_title_view_profile_actions_more"><![CDATA[Channel More Actions]]></string>
+	<string name="_bx_channels_menu_set_title_view_profile_submenu"><![CDATA[View Channel Submenu]]></string>
+	<string name="_bx_channels_menu_title_entries_my"><![CDATA[Profile Channels Action Menu]]></string>
+	<string name="_bx_channels_menu_set_title_entries_my"><![CDATA[Profile Channels Menu]]></string>
+	<string name="_bx_channels_menu_set_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+	<string name="_bx_channels_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
+	<string name="_bx_channels_menu_item_title_system_delete"><![CDATA[Delete]]></string>
+	<string name="_bx_channels_menu_item_title_delete"><![CDATA[Delete]]></string>
+	<string name="_bx_channels_menu_item_title_system_delete_with_content"><![CDATA[Delete With Content]]></string>
+	<string name="_bx_channels_menu_item_title_delete_with_content"><![CDATA[Delete With Content]]></string>
+	<string name="_bx_channels_menu_item_title_system_edit_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_channels_menu_item_title_edit_cover"><![CDATA[Edit Cover]]></string>
+	<string name="_bx_channels_menu_item_title_system_edit_profile"><![CDATA[Edit Channel]]></string>
+	<string name="_bx_channels_menu_item_title_edit_profile"><![CDATA[Edit Channel]]></string>
+	<string name="_bx_channels_menu_item_title_system_delete_profile"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_menu_item_title_delete_profile"><![CDATA[Delete Channel]]></string>
+	<string name="_bx_channels_menu_item_title_system_delete_account"><![CDATA[Delete Account]]></string>
+	<string name="_bx_channels_menu_item_title_delete_account"><![CDATA[Delete Account]]></string>
+	<string name="_bx_channels_menu_item_title_system_profile_type"><![CDATA[Channel]]></string>
+	<string name="_bx_channels_menu_item_title_profile_type"><![CDATA[Channel]]></string>
+	<string name="_bx_channels_menu_item_title_system_create_profile"><![CDATA[Channel]]></string>
+	<string name="_bx_channels_menu_item_title_create_profile"><![CDATA[Channel]]></string>
+	<string name="_bx_channels_menu_item_title_system_view_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_menu_item_title_view_profile_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_menu_item_title_system_view_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_channels_menu_item_title_view_profile_comments"><![CDATA[Comments]]></string>
+	<string name="_bx_channels_menu_item_title_system_view_profile_info"><![CDATA[Info]]></string>
+	<string name="_bx_channels_menu_item_title_view_profile_info"><![CDATA[Info]]></string>
+	<string name="_bx_channels_menu_item_title_system_view_profile_view"><![CDATA[Channel]]></string>
+	<string name="_bx_channels_menu_item_title_view_profile_view"><![CDATA[Channel]]></string>
+        <string name="_bx_channels_menu_item_title_system_view_profile_more_auto"><![CDATA[More]]></string>
+        <string name="_bx_channels_menu_item_title_view_profile_more_auto"><![CDATA[More]]></string>
+	<string name="_bx_channels_menu_item_title_system_invite"><![CDATA[Invite]]></string>
+	<string name="_bx_channels_menu_item_title_invite"><![CDATA[Invite]]></string>
+	
+	<string name="_bx_channels_menu_item_title_system_befriend"><![CDATA[Add friend]]></string>
+	<string name="_bx_channels_menu_item_title_befriend"><![CDATA[Add friend]]></string>
+	<string name="_bx_channels_menu_item_title_befriend_sent"><![CDATA[Add friend (requested)]]></string>
+	<string name="_bx_channels_menu_item_title_befriend_confirm"><![CDATA[Accept friend request]]></string>
+	<string name="_bx_channels_menu_item_title_system_unfriend"><![CDATA[Unfriend]]></string>
+	<string name="_bx_channels_menu_item_title_unfriend"><![CDATA[Unfriend]]></string>
+	<string name="_bx_channels_menu_item_title_unfriend_cancel_request"><![CDATA[Cancel friend request]]></string>
+	<string name="_bx_channels_menu_item_title_unfriend_reject_request"><![CDATA[Reject friend request]]></string>
+	
+	<string name="_bx_channels_menu_item_title_system_subscribe"><![CDATA[Follow]]></string>
+	<string name="_bx_channels_menu_item_title_subscribe"><![CDATA[Follow]]></string>
+	<string name="_bx_channels_menu_item_title_system_unsubscribe"><![CDATA[Unfollow]]></string>
+	<string name="_bx_channels_menu_item_title_unsubscribe"><![CDATA[Unfollow]]></string>
+	<string name="_bx_channels_menu_item_title_system_more_actions"><![CDATA[More Actions]]></string>
+	<string name="_bx_channels_menu_item_title_more_actions"><![CDATA[]]></string>
+	<string name="_bx_channels_menu_item_title_system_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_menu_item_title_friends"><![CDATA[Friends]]></string>
+	<string name="_bx_channels_menu_item_title_system_manage_my_channels"><![CDATA[My channels]]></string>
+	<string name="_bx_channels_menu_item_title_manage_my_channels"><![CDATA[{addon} channels]]></string>
+	<string name="_bx_channels_menu_item_title_system_entries_recent"><![CDATA[New]]></string>
+	<string name="_bx_channels_menu_item_title_entries_recent"><![CDATA[New]]></string>
+	<string name="_bx_channels_menu_item_title_system_entries_search"><![CDATA[Search]]></string>
+	<string name="_bx_channels_menu_item_title_entries_search"><![CDATA[Search]]></string>
+        <string name="_bx_channels_menu_item_title_system_entries_manage"><![CDATA[Manage]]></string>
+	<string name="_bx_channels_menu_item_title_entries_manage"><![CDATA[Manage]]></string>
+	<string name="_bx_channels_menu_item_title_system_entries_home"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_menu_item_title_entries_home"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_menu_item_title_system_admt_channels"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_menu_item_title_admt_channels"><![CDATA[Channels]]></string>
+	<string name="_bx_channels_menu_item_title_manage_my"><![CDATA[My Channels]]></string>
+	<string name="_bx_channels_menu_item_title_manage_all"><![CDATA[All Channels]]></string>
+	<string name="_bx_channels_menu_item_title_system_entries_top"><![CDATA[Top]]></string>
+	<string name="_bx_channels_menu_item_title_entries_top"><![CDATA[Top]]></string>
+        <string name="_bx_channels_menu_item_title_system_view_entries_author"><![CDATA[Channels]]></string>
+        <string name="_bx_channels_menu_item_title_view_entries_author"><![CDATA[Channels]]></string>
+
+	<string name="_bx_channels_grid_filter_item_title_adm_select_one_filter1"><![CDATA[All Statuses]]></string>
+	<string name="_bx_channels_grid_filter_item_title_adm_active"><![CDATA[Active]]></string>
+	<string name="_bx_channels_grid_filter_item_title_adm_pending"><![CDATA[Pending]]></string>
+	<string name="_bx_channels_grid_filter_item_title_adm_suspended"><![CDATA[Suspended]]></string>
+	<string name="_bx_channels_grid_column_title_adm_active"><![CDATA[Active]]></string>
+	<string name="_bx_channels_grid_column_title_adm_name"><![CDATA[Name]]></string>
+	<string name="_bx_channels_grid_column_title_adm_added"><![CDATA[Created]]></string>
+	<string name="_bx_channels_grid_column_title_adm_account"><![CDATA[Account]]></string>
+	<string name="_bx_channels_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+	<string name="_bx_channels_grid_action_title_adm_delete_with_content"><![CDATA[Delete With Content]]></string>
+	<string name="_bx_channels_grid_action_title_adm_more_actions"><![CDATA[More Actions]]></string>
+	<string name="_bx_channels_grid_action_err_delete"><![CDATA[Cannot delete the selected channel(s).]]></string>
+	<string name="_bx_channels_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+	
+	<string name="_bx_channels_chart_growth"><![CDATA[Channels: Growth]]></string>
+	<string name="_bx_channels_chart_growth_speed"><![CDATA[Channels: Growth Speed]]></string>
+	
+	<string name="_bx_channels_search_extended"><![CDATA[Channels Search]]></string>
+	<string name="_bx_channels_search_extended_cmts"><![CDATA[Channels Comments Search]]></string>
+
+	<string name="_bx_channels_txt_account_pending"><![CDATA[This channel is pending approval, please wait until it is activated.]]></string>
+	<string name="_bx_channels_txt_account_suspended"><![CDATA[This channel is suspended.]]></string>
+	<string name="_bx_channels_txt_sample_single"><![CDATA[channel]]></string>
+	<string name="_bx_channels_txt_sample_single_with_article"><![CDATA[a channel]]></string>
+	<string name="_bx_channels_txt_sample_comment_single"><![CDATA[comment to channel]]></string>
+	<string name="_bx_channels_txt_sample_vote_single"><![CDATA[vote to channel]]></string>
+        <string name="_bx_channels_txt_sample_score_up_single"><![CDATA[score up vote to channel]]></string>
+        <string name="_bx_channels_txt_sample_score_down_single"><![CDATA[score down vote to channel]]></string>
+
+    <string name="_bx_channels_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> channel timeline]]></string>
+    <string name="_bx_channels_ntfs_txt_subobject_added"><![CDATA[New content <b class="bx-ntfs-content-entry">{entry_caption}</b> in <b class="bx-ntfs-content-profile">{owner_name}</b> channel]]></string>
+    <string name="_bx_channels_ntfs_txt_subobject_added_profile"><![CDATA[<b class="bx-ntfs-content-entry">{entry_caption}</b> was added to <b class="bx-ntfs-content-profile">{owner_name}</b> channel]]></string>
+    <string name="_bx_channels_alert_action_hashtag_added"><![CDATA[New hashtags]]></string>
+    <string name="_bx_channels_alert_action_hashtag_added_notif_follow_context"><![CDATA[New hashtags]]></string>
+</resources>

+ 56 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/disable.sql

@@ -0,0 +1,56 @@
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = 'bx_channels' LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+-- PAGES
+DELETE FROM `sys_objects_page` WHERE `module` = 'bx_channels';
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_channels' OR `object` IN('bx_channels_create_profile', 'bx_channels_delete_profile', 'bx_channels_edit_profile', 'bx_channels_edit_profile_cover', 'bx_channels_view_profile', 'bx_channels_view_profile_closed', 'bx_channels_profile_info', 'bx_channels_profile_comments', 'bx_channels_author', 'bx_channels_home', 'bx_channels_top', 'bx_channels_search', 'bx_channels_manage', 'bx_channels_administration');
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = 'bx_channels';
+DELETE FROM `sys_menu_sets` WHERE `module` = 'bx_channels';
+DELETE FROM `sys_menu_items` WHERE `module` = 'bx_channels' OR `set_name` IN('bx_channels_submenu', 'bx_channels_view_actions', 'bx_channels_view_actions_more', 'bx_channels_view_actions_all', 'bx_channels_my', 'bx_channels_snippet_meta', 'bx_channels_menu_manage_tools');
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = 'bx_channels';
+DELETE FROM `sys_acl_actions` WHERE `Module` = 'bx_channels';
+
+-- METATAGS
+DELETE FROM `sys_objects_metatags` WHERE `object` = 'bx_channels';
+
+-- SEARCH
+DELETE FROM `sys_objects_search` WHERE `ObjectName` = 'bx_channels';
+
+-- STATS
+DELETE FROM `sys_statistics` WHERE `name` LIKE 'bx_channels%';
+
+-- CHARTS
+DELETE FROM `sys_objects_chart` WHERE `object` LIKE 'bx_channels%';
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_channels_administration', 'bx_channels_moderation');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_channels_administration', 'bx_channels_moderation');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_channels_administration', 'bx_channels_moderation');
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_channels' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;
+
+-- PRIVACY 
+DELETE FROM `sys_objects_privacy` WHERE `object` IN('bx_channels_allow_view_to', 'bx_channels_allow_view_notification_to');
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = 'bx_channels';
+
+-- UPLOADERS
+DELETE FROM `sys_objects_uploader` WHERE `object` IN('bx_channels_cover_crop', 'bx_channels_picture_crop');
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_channels' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;

+ 426 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/enable.sql

@@ -0,0 +1,426 @@
+
+-- 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_channels', '_bx_channels', 'bx_channels@modules/boonex/channels/|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_channels', '_bx_channels', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
+('bx_channels_num_connections_quick', '6', @iCategId, '_bx_channels_option_num_connections_quick', 'digit', '', '', '', 10),
+('bx_channels_per_page_browse', '24', @iCategId, '_bx_channels_option_per_page_browse', 'digit', '', '', '', 11),
+('bx_channels_num_rss', '10', @iCategId, '_bx_channels_option_num_rss', 'digit', '', '', '', 12),
+('bx_channels_per_page_browse_showcase', '32', @iCategId, '_sys_option_per_page_browse_showcase', 'digit', '', '', '', 15),
+('bx_channels_per_page_browse_recommended', '10', @iCategId, '_sys_option_per_page_browse_recommended', 'digit', '', '', '', 16),
+('bx_channels_searchable_fields', 'channel_name', @iCategId, '_bx_channels_option_searchable_fields', 'list', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:21:"get_searchable_fields";}', '', '', 30),
+('bx_channels_labels_autofollow', 'on', @iCategId, '_bx_channels_option_labels_autofollow', '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_channels_create_profile', 'create-channel-profile', '_bx_channels_page_title_sys_create_profile', '_bx_channels_page_title_create_profile', 'bx_channels', 5, 128, 1, 'page.php?i=create-channel-profile', '', '', '', 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_channels_create_profile', 1, 'bx_channels', '_bx_channels_page_block_title_create_profile', 11, 128, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:13:\"entity_create\";}', 0, 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_channels_view_profile', 'view-channel-profile', '_bx_channels_page_title_sys_view_profile', '_bx_channels_page_title_view_profile', 'bx_channels', 10, 2147483647, 1, 'page.php?i=view-channel-profile', '', '', '', 0, 1, 0, 'BxCnlPageEntry', 'modules/boonex/channels/classes/BxCnlPageEntry.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_channels_view_profile', 1, 'bx_channels', '', '_bx_channels_page_block_title_entry_social_sharing', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:21:\"entity_social_sharing\";}', 0, 0, 0, 0),
+('bx_channels_view_profile', 1, 'bx_channels', '', '_bx_channels_page_block_title_entry_all_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:18:\"entity_all_actions\";}', 0, 0, 0, 0),
+('bx_channels_view_profile', 1, 'bx_channels', '', '_bx_channels_page_block_title_entry_breadcrumb', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:17:"entity_breadcrumb";}', 0, 0, 1, 1),
+('bx_channels_view_profile', 2, 'bx_channels', '', '_bx_channels_page_block_title_entry_parent', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:13:"entity_parent";}', 0, 0, 1, 1),
+('bx_channels_view_profile', 3, 'bx_channels', '', '_bx_channels_page_block_title_entry_childs', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:13:"entity_childs";}', 0, 0, 1, 1),
+('bx_channels_view_profile', 4, 'bx_channels', '', '_bx_channels_page_block_title_search_results_by_hashtag', 0, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:24:\"search_result_by_hashtag\";}', 0, 0, 0, 0),
+('bx_channels_view_profile', 4, 'bx_channels', '', '_bx_channels_page_block_title_profile_comments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 0, 1);
+
+-- 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_channels_view_profile_closed', 'view-channel-profile-closed', '_bx_channels_page_title_sys_view_profile_closed', '_bx_channels_page_title_view_profile', 'bx_channels', 10, 2147483647, 1, 'page.php?i=view-channel-profile', '', '', '', 0, 1, 0, 'BxCnlPageEntry', 'modules/boonex/channels/classes/BxCnlPageEntry.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_channels_view_profile_closed', 2, 'bx_channels', '', '_bx_channels_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:11:\"entity_info\";}', 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_channels_edit_profile', 'edit-channel-profile', '_bx_channels_page_title_sys_edit_profile', '_bx_channels_page_title_edit_profile', 'bx_channels', 5, 2147483647, 1, 'page.php?i=edit-channel-profile', '', '', '', 0, 1, 0, 'BxCnlPageEntry', 'modules/boonex/channels/classes/BxCnlPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_channels_edit_profile', 1, 'bx_channels', '_bx_channels_page_block_title_edit_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";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_channels_edit_profile_cover', 'edit-channel-cover', '_bx_channels_page_title_sys_edit_profile_cover', '_bx_channels_page_title_edit_profile_cover', 'bx_channels', 5, 2147483647, 1, 'page.php?i=edit-channel-cover', '', '', '', 0, 1, 0, 'BxCnlPageEntry', 'modules/boonex/channels/classes/BxCnlPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_channels_edit_profile_cover', 1, 'bx_channels', '_bx_channels_page_block_title_edit_profile_cover', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";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_channels_delete_profile', 'delete-channel-profile', '_bx_channels_page_title_sys_delete_profile', '_bx_channels_page_title_delete_profile', 'bx_channels', 5, 2147483647, 1, 'page.php?i=delete-channel-profile', '', '', '', 0, 1, 0, 'BxCnlPageEntry', 'modules/boonex/channels/classes/BxCnlPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_channels_delete_profile', 1, 'bx_channels', '_bx_channels_page_block_title_delete_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:13:\"entity_delete\";}', 0, 0, 0);
+
+-- 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_channels_profile_comments', '_bx_channels_page_title_sys_profile_comments', '_bx_channels_page_title_profile_comments', 'bx_channels', 5, 2147483647, 1, 'channel-profile-comments', '', '', '', '', 0, 1, 0, 'BxCnlPageEntry', 'modules/boonex/channels/classes/BxCnlPageEntry.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_channels_profile_comments', 1, 'bx_channels', '_bx_channels_page_block_title_profile_comments', '_bx_channels_page_block_title_profile_comments_link', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:15:\"entity_comments\";}', 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_channels_author', 'channels-author', '_bx_channels_page_title_sys_entries_of_author', '_bx_channels_page_title_entries_of_author', 'bx_channels', 5, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxCnlPageAuthor', 'modules/boonex/channels/classes/BxCnlPageAuthor.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_channels_author', 1, 'bx_channels', '_bx_channels_page_block_title_sys_favorites_of_author', '_bx_channels_page_block_title_favorites_of_author', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_channels";s:6:"method";s:15:"browse_favorite";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 1, 1, 1),
+('bx_channels_author', 1, 'bx_channels', '_bx_channels_page_block_title_sys_entries_of_author', '_bx_channels_page_block_title_entries_of_author', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_channels";s:6:"method";s:13:"browse_author";s:6:"params";a:2:{i:0;s:12:"{profile_id}";i:1;a:1:{s:13:"empty_message";b:1;}}}}', 0, 0, 1, 2);
+
+-- 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_channels_home', '_bx_channels_page_title_sys_recent', '_bx_channels_page_title_recent', 'bx_channels', 5, 2147483647, 1, 'channels-home', 'page.php?i=channels-home', '', '', '', 0, 1, 0, 'BxCnlPageBrowse', 'modules/boonex/channels/classes/BxCnlPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('bx_channels_home', 1, 'bx_channels', '_bx_channels_page_block_title_featured_profiles', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_channels";s:6:"method";s:15:"browse_featured";s:6:"params";a:1:{i:0;s:7:"gallery";}}', 0, 1, 1, 0),
+('bx_channels_home', 1, 'bx_channels', '_bx_channels_page_block_title_latest_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:22:\"browse_recent_profiles\";s:6:"params";a:1:{i:0;b:1;}}', 0, 1, 1, 1),
+('bx_channels_home', 1, 'bx_channels', '_bx_channels_page_block_title_entries_my', 11, 2147483646, 'service', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:13:"browse_author";}',  0, 1, 0, 0);
+
+-- PAGE: top 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_channels_top', '_bx_channels_page_title_sys_top', '_bx_channels_page_title_top', 'bx_channels', 5, 2147483647, 1, 'channels-top', 'page.php?i=channels-top', '', '', '', 0, 1, 0, 'BxCnlPageBrowse', 'modules/boonex/channels/classes/BxCnlPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_channels_top', 1, 'bx_channels', '_bx_channels_page_block_title_top_profiles', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_channels\";s:6:\"method\";s:19:\"browse_top_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_channels_search', '_bx_channels_page_title_sys_entries_search', '_bx_channels_page_title_entries_search', 'bx_channels', 5, 2147483647, 1, 'channels-search', 'page.php?i=channels-search', '', '', '', 0, 1, 0, 'BxCnlPageBrowse', 'modules/boonex/channels/classes/BxCnlPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_channels_search', 1, 'bx_channels', '_bx_channels_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:11:"bx_channels";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 1),
+('bx_channels_search', 1, 'bx_channels', '_bx_channels_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:11:"bx_channels";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 1, 2),
+('bx_channels_search', 1, 'bx_channels', '_bx_channels_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:16:"bx_channels_cmts";}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 3),
+('bx_channels_search', 1, 'bx_channels', '_bx_channels_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:16:"bx_channels_cmts";s:10:"show_empty";b:1;}}s:5:"class";s:27:"TemplSearchExtendedServices";}', 0, 1, 0, 4);
+
+-- 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_channels_administration', '_bx_channels_page_title_sys_manage_administration', '_bx_channels_page_title_manage', 'bx_channels', 5, 128, 1, 'channels-administration', 'page.php?i=channels-administration', '', '', '', 0, 1, 0, 'BxCnlPageBrowse', 'modules/boonex/channels/classes/BxCnlPageBrowse.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_channels_administration', 1, 'bx_channels', '_bx_channels_page_block_title_system_manage_administration', '_bx_channels_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_channels\";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_channels', '', '_bx_channels_page_block_title_latest_profiles', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:22:"browse_recent_profiles";}', 1, 0, 0, IFNULL(@iBlockOrder, 0) + 1),
+('sys_home', 1, 'bx_channels', '_bx_channels_page_block_title_sys_recommended_entries_view_showcase', '_bx_channels_page_block_title_recommended_entries_view_showcase', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:18:"browse_recommended";}', 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_channels', '_bx_channels_page_block_title_sys_featured_entries_view_showcase', '_bx_channels_page_block_title_featured_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_channels\";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_channels', '_bx_channels_page_block_title_sys_recommended_entries_view_showcase', '_bx_channels_page_block_title_recommended_entries_view_showcase', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_channels\";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);
+
+-- PAGES: add page block to profiles modules (trigger* page objects are processed separately upon modules enable/disable)
+SET @iPBCellProfile = 3;
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_channels', '_bx_channels_page_trigger_block_title_entries_my', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_channels";s:6:"method";s:13:"browse_author";s:6:"params";a:2:{i:0;s:12:"{profile_id}";i:1;a:1:{s:13:"empty_message";b:0;}}}', 0, 0, 0);
+
+
+-- MENU
+
+-- MENU: add to site menu
+
+SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 ORDER BY `order` DESC LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_site', 'bx_channels', 'channels-home', '_bx_channels_menu_item_title_system_entries_home', '_bx_channels_menu_item_title_entries_home', 'page.php?i=channels-home', '', '', 'hashtag col-red2', 'bx_channels_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_channels', 'channels-home', '_bx_channels_menu_item_title_system_entries_home', '_bx_channels_menu_item_title_entries_home', 'page.php?i=channels-home', '', '', 'hashtag col-red2', 'bx_channels_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_channels', 'create-channel-profile', '_bx_channels_menu_item_title_system_create_profile', '_bx_channels_menu_item_title_create_profile', 'page.php?i=create-channel-profile', '', '', 'hashtag col-red2', '', 128, 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_channels_view_actions', '_bx_channels_menu_title_view_profile_actions', 'bx_channels_view_actions', 'bx_channels', 9, 0, 1, 'BxCnlMenuViewActions', 'modules/boonex/channels/classes/BxCnlMenuViewActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_view_actions', 'bx_channels', '_bx_channels_menu_set_title_view_profile_actions', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_channels_view_actions', 'bx_channels', 'profile-subscribe-add', '_bx_channels_menu_item_title_system_subscribe', '_bx_channels_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_channels_view_actions', 'bx_channels', 'profile-actions-more', '_bx_channels_menu_item_title_system_more_actions', '_bx_channels_menu_item_title_more_actions', 'javascript:void(0)', 'bx_menu_popup(''bx_channels_view_actions_more'', this, {}, {profile_id:{profile_id}});', '', 'cog', 'bx_channels_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_channels_view_actions_more', '_bx_channels_menu_title_view_profile_actions_more', 'bx_channels_view_actions_more', 'bx_channels', 6, 0, 1, 'BxCnlMenuViewActions', 'modules/boonex/channels/classes/BxCnlMenuViewActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_view_actions_more', 'bx_channels', '_bx_channels_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_channels_view_actions_more', 'bx_channels', 'profile-subscribe-remove', '_bx_channels_menu_item_title_system_unsubscribe', '_bx_channels_menu_item_title_unsubscribe', 'javascript:void(0)', 'bx_conn_action(this, \'sys_profiles_subscriptions\', \'remove\', \'{profile_id}\')', '', 'check', '', 2147483647, 1, 0, 20),
+('bx_channels_view_actions_more', 'bx_channels', 'edit-channel-cover', '_bx_channels_menu_item_title_system_edit_cover', '_bx_channels_menu_item_title_edit_cover', 'page.php?i=edit-channel-cover&id={content_id}', '', '', 'pencil-alt', '', 2147483647, 1, 0, 30),
+('bx_channels_view_actions_more', 'bx_channels', 'edit-channel-profile', '_bx_channels_menu_item_title_system_edit_profile', '_bx_channels_menu_item_title_edit_profile', 'page.php?i=edit-channel-profile&id={content_id}', '', '', 'pencil-alt', '', 2147483647, 0, 0, 40),
+('bx_channels_view_actions_more', 'bx_channels', 'delete-channel-profile', '_bx_channels_menu_item_title_system_delete_profile', '_bx_channels_menu_item_title_delete_profile', 'page.php?i=delete-channel-profile&id={content_id}', '', '', 'remove', '', 2147483647, 1, 0, 50);
+
+-- 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_channels_view_actions_all', '_sys_menu_title_view_actions', 'bx_channels_view_actions_all', 'bx_channels', 15, 0, 1, 'BxCnlMenuViewActionsAll', 'modules/boonex/channels/classes/BxCnlMenuViewActionsAll.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_view_actions_all', 'bx_channels', '_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`, `active`, `copyable`, `order`) VALUES 
+('bx_channels_view_actions_all', 'bx_channels', 'profile-subscribe-add', '_bx_channels_menu_item_title_system_subscribe', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 10),
+('bx_channels_view_actions_all', 'bx_channels', 'profile-subscribe-remove', '_bx_channels_menu_item_title_system_unsubscribe', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 20),
+('bx_channels_view_actions_all', 'bx_channels', 'comment', '_sys_menu_item_title_system_va_comment', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 200),
+('bx_channels_view_actions_all', 'bx_channels', 'view', '_sys_menu_item_title_system_va_view', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 210),
+('bx_channels_view_actions_all', 'bx_channels', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 220),
+('bx_channels_view_actions_all', 'bx_channels', 'score', '_sys_menu_item_title_system_va_score', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 230),
+('bx_channels_view_actions_all', 'bx_channels', 'favorite', '_sys_menu_item_title_system_va_favorite', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 240),
+('bx_channels_view_actions_all', 'bx_channels', 'feature', '_sys_menu_item_title_system_va_feature', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 250),
+('bx_channels_view_actions_all', 'bx_channels', 'report', '_sys_menu_item_title_system_va_report', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 260),
+('bx_channels_view_actions_all', 'bx_channels', 'social-sharing-facebook', '_sys_menu_item_title_system_social_sharing_facebook', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 300),
+('bx_channels_view_actions_all', 'bx_channels', 'social-sharing-twitter', '_sys_menu_item_title_system_social_sharing_twitter', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 320),
+('bx_channels_view_actions_all', 'bx_channels', 'social-sharing-pinterest', '_sys_menu_item_title_system_social_sharing_pinterest', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 330),
+('bx_channels_view_actions_all', 'bx_channels', 'edit-channel-cover', '_bx_channels_menu_item_title_system_edit_cover', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 400),
+('bx_channels_view_actions_all', 'bx_channels', 'edit-channel-profile', '_bx_channels_menu_item_title_system_edit_profile', '', '', '', '', '', '', '', 0, 2147483647, 0, 0, 410),
+('bx_channels_view_actions_all', 'bx_channels', 'delete-channel-profile', '_bx_channels_menu_item_title_system_delete_profile', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 420),
+('bx_channels_view_actions_all', 'bx_channels', '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_channels_my', '_bx_channels_menu_title_entries_my', 'bx_channels_my', 'bx_channels', 9, 0, 1, 'BxCnlMenu', 'modules/boonex/channels/classes/BxCnlMenu.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_my', 'bx_channels', '_bx_channels_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_channels_my', 'bx_channels', 'create-channel-profile', '_bx_channels_menu_item_title_system_create_profile', '_bx_channels_menu_item_title_create_profile', 'page.php?i=create-channel-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_channels_submenu', '_bx_channels_menu_title_submenu', 'bx_channels_submenu', 'bx_channels', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_submenu', 'bx_channels', '_bx_channels_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_channels_submenu', 'bx_channels', 'channels-home', '_bx_channels_menu_item_title_system_entries_recent', '_bx_channels_menu_item_title_entries_recent', 'page.php?i=channels-home', '', '', '', '', 2147483647, 1, 1, 1),
+('bx_channels_submenu', 'bx_channels', 'channels-top', '_bx_channels_menu_item_title_system_entries_top', '_bx_channels_menu_item_title_entries_top', 'page.php?i=channels-top', '', '', '', '', 2147483647, 1, 1, 2),
+('bx_channels_submenu', 'bx_channels', 'channels-search', '_bx_channels_menu_item_title_system_entries_search', '_bx_channels_menu_item_title_entries_search', 'page.php?i=channels-search', '', '', '', '', 2147483647, 1, 1, 3);
+
+-- 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_channels_snippet_meta', '_sys_menu_title_snippet_meta', 'bx_channels_snippet_meta', 'bx_channels', 15, 0, 1, 'BxCnlMenuSnippetMeta', 'modules/boonex/channels/classes/BxCnlMenuSnippetMeta.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_snippet_meta', 'bx_channels', '_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_channels_snippet_meta', 'bx_channels', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', 2147483647, 0, 0, 1, 1),
+('bx_channels_snippet_meta', 'bx_channels', 'tags', '_sys_menu_item_title_system_sm_tags', '_sys_menu_item_title_sm_tags', '', '', '', '', '', 2147483647, 0, 0, 1, 2),
+('bx_channels_snippet_meta', 'bx_channels', 'views', '_sys_menu_item_title_system_sm_views', '_sys_menu_item_title_sm_views', '', '', '', '', '', 2147483647, 0, 0, 1, 3),
+('bx_channels_snippet_meta', 'bx_channels', 'comments', '_sys_menu_item_title_system_sm_comments', '_sys_menu_item_title_sm_comments', '', '', '', '', '', 2147483647, 0, 0, 1, 4),
+('bx_channels_snippet_meta', 'bx_channels', 'members', '_sys_menu_item_title_system_sm_members', '_sys_menu_item_title_sm_members', '', '', '', '', '', 2147483647, 1, 0, 1, 5),
+('bx_channels_snippet_meta', 'bx_channels', 'subscribers', '_sys_menu_item_title_system_sm_subscribers', '_sys_menu_item_title_sm_subscribers', '', '', '', '', '', 2147483647, 1, 0, 1, 6),
+('bx_channels_snippet_meta', 'bx_channels', 'nl', '_sys_menu_item_title_system_sm_nl', '_sys_menu_item_title_sm_nl', '', '', '', '', '', 2147483647, 1, 0, 1, 7),
+('bx_channels_snippet_meta', 'bx_channels', 'subscribe', '_sys_menu_item_title_system_sm_subscribe', '_sys_menu_item_title_sm_subscribe', '', '', '', '', '', 2147483647, 1, 0, 1, 8),
+('bx_channels_snippet_meta', 'bx_channels', 'unsubscribe', '_sys_menu_item_title_system_sm_unsubscribe', '_sys_menu_item_title_sm_unsubscribe', '', '', '', '', '', 2147483647, 1, 0, 1, 9);
+
+-- 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_channels_menu_manage_tools', '_bx_channels_menu_title_manage_tools', 'bx_channels_menu_manage_tools', 'bx_channels', 6, 0, 1, 'BxCnlMenuManageTools', 'modules/boonex/channels/classes/BxCnlMenuManageTools.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_channels_menu_manage_tools', 'bx_channels', '_bx_channels_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_channels_menu_manage_tools', 'bx_channels', 'delete', '_bx_channels_menu_item_title_system_delete', '_bx_channels_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id});', '_self', 'far trash-alt', '', 2147483647, 1, 0, 1),
+('bx_channels_menu_manage_tools', 'bx_channels', 'delete-with-content', '_bx_channels_menu_item_title_system_delete_with_content', '_bx_channels_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id});', '_self', 'far trash-alt', '', 2147483647, 1, 0, 2);
+
+-- MENU: dashboard manage tools
+SET @iManageMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_account_dashboard_manage_tools' LIMIT 1);
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('sys_account_dashboard_manage_tools', 'bx_channels', 'channels-administration', '_bx_channels_menu_item_title_system_admt_channels', '_bx_channels_menu_item_title_admt_channels', 'page.php?i=channels-administration', '', '_self', 'hashtag', 'a:2:{s:6:"module";s:11:"bx_channels";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 128, 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_channels', 'channels-author', '_bx_channels_menu_item_title_system_view_entries_author', '_bx_channels_menu_item_title_view_entries_author', 'page.php?i=channels-author&profile_id={profile_id}', '', '', 'hashtag col-red2', '', 2147483647, 1, 0, 0);
+
+
+-- ACL
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_channels', 'create entry', NULL, '_bx_channels_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_channels', 'delete entry', NULL, '_bx_channels_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_channels', 'view entry', NULL, '_bx_channels_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_channels', 'edit any entry', NULL, '_bx_channels_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_channels', 'create channel auto', NULL, '_bx_channels_acl_action_create_channel_auto', '', 1, 1);
+SET @iIdActionCreateChannelAuto = 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
+(@iAdministrator, @iIdActionProfileCreate),
+
+-- profile delete
+(@iAdministrator, @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),
+
+-- create channel auto
+(@iAccount, @iIdActionCreateChannelAuto),
+(@iStandard, @iIdActionCreateChannelAuto),
+(@iUnconfirmed, @iIdActionCreateChannelAuto),
+(@iPending, @iIdActionCreateChannelAuto),
+(@iModerator, @iIdActionCreateChannelAuto),
+(@iAdministrator, @iIdActionCreateChannelAuto),
+(@iPremium, @iIdActionCreateChannelAuto);
+
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_channels', 'bx_cnl_meta_keywords', '', 'bx_cnl_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_channels', '_bx_channels', @iSearchOrder + 1, 'BxCnlSearchResult', 'modules/boonex/channels/classes/BxCnlSearchResult.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_channels', 'bx_channels', '_bx_channels', 'page.php?i=channels-home', 'hashtag col-red2', 'SELECT COUNT(*) FROM `bx_cnl_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id` = `tp`.`content_id` AND `tp`.`type`=''bx_channels'' 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_channels_growth', '_bx_channels_chart_growth', 'bx_cnl_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_channels'' WHERE 1 AND `tp`.`status`=''active'' {where_inteval} GROUP BY `period` ORDER BY {table}.{field_date} ASC', 1, @iMaxOrderCharts + 1, 'BxDolChartGrowth', ''),
+('bx_channels_growth_speed', '_bx_channels_chart_growth_speed', 'bx_cnl_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_channels'' 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_channels_administration', 'Sql', 'SELECT `td`.*, `td`.`channel_name` AS `name`, `ta`.`email` AS `account`, `td`.`added` AS `added_ts`, `tp`.`status` AS `status` FROM `bx_cnl_data` AS `td` LEFT JOIN `sys_profiles` AS `tp` ON `td`.`id`=`tp`.`content_id` AND `tp`.`type`=''bx_channels'' LEFT JOIN `sys_accounts` AS `ta` ON `tp`.`account_id`=`ta`.`id` WHERE 1 ', 'bx_cnl_data', 'id', 'added', 'status', '', 20, NULL, 'start', '', 'channel_name', '', 'like', 'reports', '', 192, 'BxCnlGridAdministration', 'modules/boonex/channels/classes/BxCnlGridAdministration.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_channels_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_channels_administration', 'switcher', '_bx_channels_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_channels_administration', 'reports', '_sys_txt_reports_title', '5%', 0, '', '', 3),
+('bx_channels_administration', 'name', '_bx_channels_grid_column_title_adm_name', '45%', 0, '', '', 4),
+('bx_channels_administration', 'added_ts', '_bx_channels_grid_column_title_adm_added', '20%', 1, '25', '', 5),
+('bx_channels_administration', 'actions', '', '20%', 0, '', '', 6);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_channels_administration', 'bulk', 'delete', '_bx_channels_grid_action_title_adm_delete', '', 0, 1, 2),
+('bx_channels_administration', 'bulk', 'delete_with_content', '_bx_channels_grid_action_title_adm_delete_with_content', '', 0, 1, 3),
+('bx_channels_administration', 'single', 'settings', '_bx_channels_grid_action_title_adm_more_actions', 'cog', 1, 0, 2);
+
+-- ALERTS
+
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_channels', 'BxCnlAlertsResponse', 'modules/boonex/channels/classes/BxCnlAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'save_setting', @iHandler),
+('bx_timeline', 'post_common', @iHandler),
+('bx_channels_pics', 'file_deleted', @iHandler),
+('profile', 'delete', @iHandler),
+('bx_channels', 'timeline_view', @iHandler),
+('bx_channels', 'timeline_post', @iHandler),
+('bx_channels', 'timeline_delete', @iHandler),
+('bx_channels', 'timeline_comment', @iHandler),
+('bx_channels', 'timeline_vote', @iHandler),
+('bx_channels', 'timeline_score', @iHandler),
+('bx_channels', 'timeline_report', @iHandler),
+('bx_channels', 'timeline_repost', @iHandler),
+('bx_channels', 'timeline_pin', @iHandler),
+('bx_channels', 'timeline_promote', @iHandler),
+('bx_persons', 'added', @iHandler),
+('bx_persons', 'edited', @iHandler),
+('bx_organizations', 'added', @iHandler),
+('bx_organizations', 'edited', @iHandler),
+('meta_keyword', 'added', @iHandler),
+('meta_keyword', 'url', @iHandler),
+('meta_keyword', 'deleted', @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_channels_allow_view_to', 'bx_channels', 'view', '_bx_channels_form_profile_input_allow_view_to', '3', '', 'bx_cnl_data', 'id', 'author', 'BxCnlPrivacy', 'modules/boonex/channels/classes/BxCnlPrivacy.php'),
+('bx_channels_allow_view_notification_to', 'bx_channels', 'view_event', '_bx_channels_form_profile_input_allow_view_notification_to', '3', '', 'bx_notifications_events', 'id', 'object_owner_id', 'BxCnlPrivacyNotifications', 'modules/boonex/channels/classes/BxCnlPrivacyNotifications.php');
+
+
+-- UPLOADERS
+
+INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_channels_cover_crop', 1, 'BxCnlUploaderCoverCrop', 'modules/boonex/channels/classes/BxCnlUploaderCoverCrop.php'),
+('bx_channels_picture_crop', 1, 'BxCnlUploaderPictureCrop', 'modules/boonex/channels/classes/BxCnlUploaderPictureCrop.php');

+ 294 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/install.sql

@@ -0,0 +1,294 @@
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: PROFILES
+CREATE TABLE IF NOT EXISTS `bx_cnl_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,
+  `channel_name` varchar(191) 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(255) DEFAULT '3',
+  PRIMARY KEY (`id`),
+  UNIQUE INDEX channel_name (`channel_name`),
+  FULLTEXT KEY `search_fields` (`channel_name`)
+);
+
+-- TABLE: items
+CREATE TABLE IF NOT EXISTS `bx_cnl_content` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `content_id` int(11) NOT NULL,
+  `cnl_id` int(11) NOT NULL,
+  `author_id` int(11) NOT NULL,
+  `module_name` varchar(19) NOT NULL,
+  PRIMARY KEY (`id`)
+);
+
+-- TABLE: STORAGES & TRANSCODERS
+CREATE TABLE `bx_cnl_pics` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE `bx_cnl_pics_resized` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+-- TABLE: comments
+CREATE TABLE IF NOT EXISTS `bx_cnl_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',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+-- TABLE: VIEWS
+CREATE TABLE `bx_cnl_views_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- TABLE: VOTES
+CREATE TABLE IF NOT EXISTS `bx_cnl_votes` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  `sum` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_cnl_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: REPORTS
+CREATE TABLE IF NOT EXISTS `bx_cnl_reports` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_cnl_reports_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(32) NOT NULL default '',
+  `text` text NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+);
+
+-- TABLE: metas
+CREATE TABLE `bx_cnl_meta_keywords` (
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE `bx_cnl_meta_mentions` (
+  `object_id` int(10) unsigned NOT NULL,
+  `profile_id` int(10) unsigned NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `profile_id` (`profile_id`)
+);
+
+
+-- TABLE: favorites
+CREATE TABLE `bx_cnl_favorites_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`author_id`)
+);
+
+-- TABLE: scores
+CREATE TABLE IF NOT EXISTS `bx_cnl_scores` (
+  `object_id` int(11) NOT NULL default '0',
+  `count_up` int(11) NOT NULL default '0',
+  `count_down` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_cnl_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_channels_pics', @sStorageEngine, '', 360, 2592000, 3, 'bx_cnl_pics', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
+('bx_channels_pics_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_cnl_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_channels_icon', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_thumb', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_avatar', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_avatar_big', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_picture', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_cover', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_cover_thumb', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0'),
+('bx_channels_gallery', 'bx_channels_pics_resized', 'Storage', 'a:1:{s:6:"object";s:16:"bx_channels_pics";}', 'no', '1', '2592000', '0');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_channels_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_channels_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_channels_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_channels_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_channels_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_channels_cover', 'Resize', 'a:1:{s:1:"w";s:4:"2000";}', '0'),
+('bx_channels_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_channels_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_channel', 'bx_channels', '_bx_channels_form_profile', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_cnl_data', 'id', '', '', 'do_submit', '', 0, 1, 'BxCnlFormEntry', 'modules/boonex/channels/classes/BxCnlFormEntry.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_channel', 'bx_channel_add', 'bx_channels', 0, '_bx_channels_form_profile_display_add'),
+('bx_channel', 'bx_channel_delete', 'bx_channels', 0, '_bx_channels_form_profile_display_delete'),
+('bx_channel', 'bx_channel_edit', 'bx_channels', 0, '_bx_channels_form_profile_display_edit'),
+('bx_channel', 'bx_channel_edit_cover', 'bx_channels', 0, '_bx_channels_form_profile_display_edit_cover'),
+('bx_channel', 'bx_channel_view', 'bx_channels', 1, '_bx_channels_form_profile_display_view'),
+('bx_channel', 'bx_channel_view_full', 'bx_channels', 1, '_bx_channels_form_profile_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_channel', 'bx_channels', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_channels_form_profile_input_sys_delete_confirm', '_bx_channels_form_profile_input_delete_confirm', '_bx_channels_form_profile_input_delete_confirm_info', 1, 0, 0, '', '', '', 'avail', '', '_bx_channels_form_profile_input_delete_confirm_error', '', '', 1, 0),
+('bx_channel', 'bx_channels', 'do_submit', '_sys_form_account_input_submit', '', 0, 'submit', '_bx_channels_form_profile_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_channel', 'bx_channels', 'channel_name', '', '', 0, 'text', '_bx_channels_form_profile_input_sys_channel_name', '_bx_channels_form_profile_input_channel_name', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_channels_form_profile_input_channel_name_err', 'Xss', '', 1, 0),
+('bx_channel', 'bx_channels', 'cover', 'a:1:{i:0;s:22:"bx_channels_cover_crop";}', 'a:1:{s:22:"bx_channels_cover_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_channels_form_profile_input_sys_cover', '_bx_channels_form_profile_input_cover', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_channel', 'bx_channels', 'picture', 'a:1:{i:0;s:24:"bx_channels_picture_crop";}', 'a:1:{s:24:"bx_channels_picture_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_channels_form_profile_input_sys_picture', '_bx_channels_form_profile_input_picture', '', 0, 0, 0, '', '', '', '', '', '_bx_channels_form_profile_input_picture_err', '', '', 1, 0);
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
+('bx_channel_add', 'channel_name', 2147483647, 1, 1),
+('bx_channel_add', 'do_submit', 2147483647, 1, 2),
+
+('bx_channel_delete', 'delete_confirm', 2147483647, 1, 0),
+('bx_channel_delete', 'do_submit', 2147483647, 1, 1),
+
+('bx_channel_edit', 'channel_name', 2147483647, 1, 1),
+('bx_channel_edit', 'do_submit', 2147483647, 1, 2),
+
+('bx_channel_edit_cover', 'cover', 2147483647, 1, 1),
+('bx_channel_edit_cover', 'do_submit', 2147483647, 1, 2),
+
+('bx_channel_view', 'channel_name', 2147483647, 1, 1),
+
+('bx_channel_view_full', 'channel_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_channels', 'bx_channels', 'bx_cnl_cmts', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-channel-profile&id={object_id}', '', 'bx_cnl_data', 'id', 'author', 'channel_name', 'comments', '', '');
+
+-- VIEWS
+INSERT INTO `sys_objects_view` (`name`, `table_track`, `period`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_channels', 'bx_cnl_views_track', '86400', '1', 'bx_cnl_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_channels', 'bx_cnl_votes', 'bx_cnl_votes_track', '604800', '1', '1', '0', '1', 'bx_cnl_data', 'id', 'author', 'rate', 'votes', '', '');
+
+-- 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_channels', 'bx_channels', 'bx_cnl_scores', 'bx_cnl_scores_track', '604800', '0', 'bx_cnl_data', 'id', 'author', 'score', 'sc_up', 'sc_down', '', '');
+
+-- REPORTS
+INSERT INTO `sys_objects_report` (`name`, `table_main`, `table_track`, `is_on`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_count`, `class_name`, `class_file`) VALUES 
+('bx_channels', 'bx_cnl_reports', 'bx_cnl_reports_track', '1', 'page.php?i=view-channel-profile&id={object_id}', 'bx_cnl_data', 'id', 'author', 'reports', '', '');
+
+-- 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_channels', 'bx_cnl_favorites_track', '1', '1', '1', 'page.php?i=view-channel-profile&id={object_id}', 'bx_cnl_data', 'id', 'author', 'favorites', '', '');
+
+-- FEATURED
+INSERT INTO `sys_objects_feature` (`name`, `is_on`, `is_undo`, `base_url`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_flag`, `class_name`, `class_file`) VALUES 
+('bx_channels', '1', '1', 'page.php?i=view-channel-profile&id={object_id}', 'bx_cnl_data', '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_channels', '_bx_channels', 'bx_channels', 'added', 'edited', 'deleted', '', ''),
+('bx_channels_cmts', '_bx_channels_cmts', 'bx_channels', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+INSERT INTO `sys_content_info_grids` (`object`, `grid_object`, `grid_field_id`, `condition`, `selection`) VALUES
+('bx_channels', 'bx_channels_administration', 'td`.`id', '', '');
+
+-- SEARCH EXTENDED
+INSERT INTO `sys_objects_search_extended` (`object`, `object_content_info`, `module`, `title`, `active`, `class_name`, `class_file`) VALUES
+('bx_channels', 'bx_channels', 'bx_channels', '_bx_channels_search_extended', 1, '', ''),
+('bx_channels_cmts', 'bx_channels_cmts', 'bx_channels', '_bx_channels_search_extended_cmts', 1, 'BxTemplSearchExtendedCmts', '');
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_channels', '_bx_channels', '_bx_channels', 'bx_channels@modules/boonex/channels/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_channels', '{url_studio}module.php?name=bx_channels', '', 'bx_channels@modules/boonex/channels/|std-icon.svg', '_bx_channels', '', '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));
+

+ 59 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/install/sql/uninstall.sql

@@ -0,0 +1,59 @@
+
+-- TABLES
+
+DROP TABLE IF EXISTS `bx_cnl_data`, `bx_cnl_content`, `bx_cnl_pics`, `bx_cnl_pics_resized`, `bx_cnl_cmts`, `bx_cnl_views_track`, `bx_cnl_meta_keywords`, `bx_cnl_meta_mentions`, `bx_cnl_votes`, `bx_cnl_votes_track`, `bx_cnl_reports`, `bx_cnl_reports_track`, `bx_cnl_favorites_track`, `bx_cnl_scores`, `bx_cnl_scores_track`;
+
+-- PROFILES
+
+DELETE FROM sys_profiles WHERE `type` = 'bx_channels';
+
+-- STORAGES & TRANSCODERS
+
+DELETE FROM `sys_objects_storage` WHERE `object` IN('bx_channels_pics', 'bx_channels_pics_resized');
+DELETE FROM `sys_storage_tokens` WHERE `object` IN('bx_channels_pics', 'bx_channels_pics_resized');
+
+DELETE FROM `sys_objects_transcoder` WHERE `object` IN('bx_channels_icon', 'bx_channels_thumb', 'bx_channels_avatar', 'bx_channels_avatar_big', 'bx_channels_picture', 'bx_channels_cover', 'bx_channels_cover_thumb', 'bx_channels_gallery');
+DELETE FROM `sys_transcoder_filters` WHERE `transcoder_object` IN('bx_channels_icon', 'bx_channels_thumb', 'bx_channels_avatar', 'bx_channels_avatar_big', 'bx_channels_picture', 'bx_channels_cover', 'bx_channels_cover_thumb', 'bx_channels_gallery');
+DELETE FROM `sys_transcoder_images_files` WHERE `transcoder_object` IN('bx_channels_icon', 'bx_channels_thumb', 'bx_channels_avatar', 'bx_channels_avatar_big', 'bx_channels_picture', 'bx_channels_cover', 'bx_channels_cover_thumb', 'bx_channels_gallery');
+
+-- FORMS
+
+DELETE FROM `sys_objects_form` WHERE `module` = 'bx_channels';
+DELETE FROM `sys_form_displays` WHERE `module` = 'bx_channels';
+DELETE FROM `sys_form_inputs` WHERE `module` = 'bx_channels';
+DELETE FROM `sys_form_display_inputs` WHERE `display_name` IN('bx_channel_add', 'bx_channel_delete', 'bx_channel_edit', 'bx_channel_edit_cover', 'bx_channel_view', 'bx_channel_view_full');
+
+-- COMMENTS
+DELETE FROM `sys_objects_cmts` WHERE `Name` = 'bx_channels';
+
+-- VIEWS
+DELETE FROM `sys_objects_view` WHERE `name` = 'bx_channels';
+
+-- VOTES
+DELETE FROM `sys_objects_vote` WHERE `Name` = 'bx_channels';
+
+-- SCORES
+DELETE FROM `sys_objects_score` WHERE `name` = 'bx_channels';
+
+-- REPORTS
+DELETE FROM `sys_objects_report` WHERE `name` = 'bx_channels';
+
+-- FAFORITES
+DELETE FROM `sys_objects_favorite` WHERE `name` = 'bx_channels';
+
+-- FEATURED
+DELETE FROM `sys_objects_feature` WHERE `name` = 'bx_channels';
+
+-- CONTENT INFO
+DELETE FROM `sys_objects_content_info` WHERE `name` IN ('bx_channels', 'bx_channels_cmts');
+
+DELETE FROM `sys_content_info_grids` WHERE `object` IN ('bx_channels');
+
+-- SEARCH EXTENDED
+DELETE FROM `sys_objects_search_extended` WHERE `module` = 'bx_channels';
+
+-- STUDIO PAGE & WIDGET
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = 'bx_channels';
+

+ 1 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/template/breadcrumb.html

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

+ 1 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/template/entry-childs.html

@@ -0,0 +1 @@
+__content__

+ 1 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/template/entry-parent.html

@@ -0,0 +1 @@
+__content__

+ 37 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
+    <title>channels</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <path d="M39.3452583,13.4025893 L39.9830259,9.83116071 C40.100258,9.17446429 39.5953475,8.57142857 38.9282943,8.57142857 L32.2488333,8.57142857 L33.5544576,1.25973214 C33.6716897,0.603035714 33.1667792,0 32.499726,0 L28.8718706,0 C28.352784,9.42915068e-06 27.9083685,0.372117744 27.817139,0.883125 L26.4441933,8.57142857 L17.6375012,8.57142857 L18.9431255,1.25973214 C19.0604469,0.603035714 18.5555364,0 17.8883939,0 L14.2605385,0 C13.7414519,9.42915068e-06 13.2970364,0.372117744 13.2058069,0.883125 L11.8328612,8.57142857 L4.77072178,8.57142857 C4.2516351,8.571438 3.80721964,8.94354632 3.71599016,9.45455357 L3.07822261,13.0259821 C2.96099053,13.6826786 3.46590099,14.2857143 4.13295424,14.2857143 L10.8124152,14.2857143 L8.77161267,25.7142857 L1.70947329,25.7142857 C1.19038661,25.7142951 0.745971146,26.0864035 0.654741663,26.5974107 L0.0169741193,30.1688393 C-0.100257966,30.8255357 0.4046525,31.4285714 1.07170574,31.4285714 L7.75116674,31.4285714 L6.44554238,38.7402679 C6.3283103,39.3969643 6.83322077,40 7.50027401,40 L11.1281294,40 C11.647216,39.9999906 12.0916315,39.6278823 12.182861,39.116875 L13.555896,31.4285714 L22.3624988,31.4285714 L21.0568745,38.7402679 C20.9395531,39.3969643 21.4444636,40 22.1116061,40 L25.7394615,40 C26.2585481,39.9999906 26.7029636,39.6278823 26.7941931,39.116875 L28.1671388,31.4285714 L35.2292782,31.4285714 C35.7483649,31.428562 36.1927804,31.0564537 36.2840098,30.5454464 L36.9217774,26.9740179 C37.0390095,26.3173214 36.534099,25.7142857 35.8670458,25.7142857 L29.1875848,25.7142857 L31.2283873,14.2857143 L38.2905267,14.2857143 C38.8096134,14.2857049 39.2540289,13.9135965 39.3452583,13.4025893 L39.3452583,13.4025893 Z M23.3829448,25.7142857 L14.576342,25.7142857 L16.6171445,14.2857143 L25.4237473,14.2857143 L23.3829448,25.7142857 Z" id="path-4"></path>
+        <filter x="-5.0%" y="-2.5%" width="110.0%" height="110.0%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Artboard" transform="translate(-421.000000, -430.000000)">
+            <g id="channels" transform="translate(421.000000, 430.000000)">
+                <mask id="mask-2" fill="white">
+                    <use xlink:href="#path-1"></use>
+                </mask>
+                <use id="Path" fill="#00B356" xlink:href="#path-1"></use>
+                <g id="hashtag" mask="url(#mask-2)" fill-rule="nonzero">
+                    <g transform="translate(12.000000, 12.000000)" id="Shape">
+                        <g>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
+                            <use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 1 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/template/menu_main_submenu.html

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

+ 1 - 0
modules/boonex/channels/updates/9.0.3_10.0.0/source/template/unit_wo_cover.html

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

+ 51 - 0
modules/boonex/charts/updates/9.0.2_10.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' => 'Charts',
+    'version_from' => '9.0.2',
+    'version_to' => '10.0.0',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/charts/updates/update_9.0.2_10.0.0/',
+    'home_uri' => 'charts_update_902_1000',
+
+    'module_dir' => 'boonex/charts/',
+    'module_uri' => 'charts',
+
+    'db_prefix' => 'bx_charts_',
+    'class_prefix' => 'BxCharts',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Charts',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/charts/updates/9.0.2_10.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 BxChartsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 77 - 0
modules/boonex/charts/updates/9.0.2_10.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    Charts Charts
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_charts',
+    'title' => 'Charts',
+    'note' => 'Charts module.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/charts/',
+    'home_uri' => 'charts',
+
+    'db_prefix' => 'bx_charts_',
+    'class_prefix' => 'BxCharts',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Charts',
+
+    /**
+     * 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(),
+);
+
+/** @} */

+ 37 - 0
modules/boonex/charts/updates/9.0.2_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="65px" viewBox="0 0 64 65" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 55 (78076) - https://sketchapp.com -->
+    <title>charts</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <path d="M38.808123,21.374948 L21.3603855,21.374948 L32.9802007,33.103865 C33.4243169,33.5521511 34.1551969,33.5885187 34.6118131,33.1543343 C37.4573921,30.4482892 39.4147387,26.8003978 39.9890015,22.6997672 C40.0875306,21.9976502 39.5103266,21.374948 38.808123,21.374948 L38.808123,21.374948 Z M37.6441562,16.5655206 C37.0382758,7.69925207 30.0191809,0.614252955 21.2353859,0.00268378721 C20.5647999,-0.0440745351 20.0000958,0.526673875 20.0000958,1.20504065 L20.0000958,17.8124092 L36.4537189,17.8124092 C37.1257755,17.8124092 37.6904796,17.242403 37.6441562,16.5655206 Z M16.4706955,21.374948 L16.4706955,3.76338885 C16.4706955,3.05459206 15.8537857,2.47196852 15.158935,2.57142273 C6.39646348,3.82128011 -0.301308906,11.5482784 0.010454788,20.8086528 C0.331041983,30.3191471 8.44351566,38.1181384 17.8699557,37.9986449 C21.575826,37.9518866 25.0000796,36.746561 27.8155116,34.7307577 C28.3963921,34.3151282 28.4346273,33.4519547 27.9309524,32.9435507 L16.4706955,21.374948 Z" id="path-4"></path>
+        <filter x="-5.0%" y="-2.6%" width="110.0%" height="110.5%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Artboard" transform="translate(-1394.000000, -510.000000)">
+            <g id="charts" transform="translate(1394.000000, 510.682593)">
+                <mask id="mask-2" fill="white">
+                    <use xlink:href="#path-1"></use>
+                </mask>
+                <use id="Path" fill="#00B356" xlink:href="#path-1"></use>
+                <g id="chart-pie" mask="url(#mask-2)" fill-rule="nonzero">
+                    <g transform="translate(13.000000, 12.317407)" id="Shape">
+                        <g>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
+                            <use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 51 - 0
modules/boonex/contact/updates/9.0.9_10.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' => 'Contact',
+    'version_from' => '9.0.9',
+    'version_to' => '10.0.0',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/contact/updates/update_9.0.9_10.0.0/',
+    'home_uri' => 'contact_update_909_1000',
+
+    'module_dir' => 'boonex/contact/',
+    'module_uri' => 'contact',
+
+    'db_prefix' => 'bx_contact_',
+    'class_prefix' => 'BxContact',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+        'clear_db_cache' => 0,
+    ),
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Contact',
+
+    /**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/contact/updates/9.0.9_10.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 BxContactUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}

+ 72 - 0
modules/boonex/contact/updates/9.0.9_10.0.0/source/install/config.php

@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Contact Contact
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_contact',
+    'title' => 'Contact',
+    'note' => 'Contact module.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+    
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/contact/',
+    'home_uri' => 'contact',
+
+    'db_prefix' => 'bx_contact_',
+    'class_prefix' => 'BxContact',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Contact',
+
+    /**
+     * 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(),
+
+);
+
+/** @} */

+ 37 - 0
modules/boonex/contact/updates/9.0.9_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 55 (78076) - https://sketchapp.com -->
+    <title>contact</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <path d="M35,0 L5,0 C2.2421875,0 0,2.24205644 0,4.99970774 L0,27.4983926 C0,30.2560439 2.2421875,32.4981003 5,32.4981003 L12.5,32.4981003 L12.5,39.0602167 C12.5,39.8257969 13.375,40.2710834 13.9921875,39.8179849 L23.75,32.4981003 L35,32.4981003 C37.7578125,32.4981003 40,30.2560439 40,27.4983926 L40,4.99970774 C40,2.24205644 37.7578125,0 35,0 Z M16.580952,24.5793332 L12.867576,24.9953572 C12.3668095,25.0492862 11.9507882,24.6255581 12.0047169,24.1324927 L12.4207382,20.4190937 L19.8397862,13 L24,17.1602395 L16.580952,24.5793332 Z M28.5478332,12.5731807 L26.1210139,15 L22,10.8789861 L24.4268193,8.4521668 C25.0297084,7.84927773 26.0065413,7.84927773 26.6094304,8.4521668 L28.5478332,10.3905696 C29.1507223,10.9934587 29.1507223,11.9702916 28.5478332,12.5731807 Z" id="path-4"></path>
+        <filter x="-5.0%" y="-2.5%" width="110.0%" height="110.0%" filterUnits="objectBoundingBox" id="filter-5">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Artboard" transform="translate(-826.000000, -430.000000)">
+            <g id="contact" transform="translate(826.000000, 430.000000)">
+                <mask id="mask-2" fill="white">
+                    <use xlink:href="#path-1"></use>
+                </mask>
+                <use id="Path" fill="#00B356" xlink:href="#path-1"></use>
+                <g id="comment-alt-edit" mask="url(#mask-2)" fill-rule="nonzero">
+                    <g transform="translate(12.000000, 13.000000)" id="Shape">
+                        <g>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
+                            <use fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 108 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvConfig.php

@@ -0,0 +1,108 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxCnvConfig extends BxBaseModTextConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $aMenuItems2Methods = array (
+            'edit-convo' => 'checkAllowedEdit',
+            'delete-convos' => 'checkAllowedDelete',
+            'mark-unread-convo' => 'checkAllowedView',
+        );
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'comments col-red1',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'conversations',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_TITLE' => '',
+            'FIELD_TEXT' => 'text',
+            'FIELD_TEXT_ID' => 'convo-text',
+            'FIELD_ALLOW_VIEW_TO' => '',
+            'FIELD_PHOTO' => 'attachments',
+            'FIELD_THUMB' => '',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELD_ALLOW_EDIT' => 'allow_edit',
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-convo',
+            'URI_AUTHOR_ENTRIES' => 'convos',
+            'URI_ADD_ENTRY' => 'start-convo',
+
+            'URL_HOME' => 'modules/?r=convos/folder/1',
+        	'URL_FOLDER' => 'modules/?r=convos/folder/',
+
+            // some params
+            'PARAM_CHARS_SUMMARY' => '',
+            'PARAM_CHARS_SUMMARY_PLAIN' => '',
+            'PARAM_NUM_RSS' => '',
+
+            // objects
+            'OBJECT_GRID' => 'bx_convos',
+            'OBJECT_STORAGE' => 'bx_convos_files',
+            'OBJECT_IMAGES_TRANSCODER_PREVIEW' => 'bx_convos_preview',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => '',
+            'OBJECT_VIDEOS_TRANSCODERS' => array(),
+            'OBJECT_VIEWS' => 'bx_convos',
+            'OBJECT_VOTES' => '',
+            'OBJECT_COMMENTS' => 'bx_convos',
+            'OBJECT_PRIVACY_VIEW' => '',
+            'OBJECT_FORM_ENTRY' => 'bx_convos',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_convos_entry_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_convos_entry_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_convos_entry_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_convos_entry_delete',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_convos_view', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_convos_my', // actions menu on my entries page
+            'OBJECT_MENU_SUBMENU' => 'bx_convos_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => '', // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'convos', // first item in view entry submenu from main module submenu
+            'OBJECT_UPLOADERS' => array('sys_simple', 'sys_html5'),
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_convos_view' => $aMenuItems2Methods,
+            ),
+
+            // some language keys
+            'T' => array (
+                'grid_action_err_delete' => '_bx_cnv_grid_action_err_delete',
+                'txt_sample_single' => '_bx_cnv_txt_sample_single',
+            	'txt_folder_' . BX_CNV_FOLDER_INBOX => '_bx_cnv_folder_inbox',
+	            'txt_folder_' . BX_CNV_FOLDER_DRAFTS => '_bx_cnv_folder_drafts',
+	            'txt_folder_' . BX_CNV_FOLDER_SPAM => '_bx_cnv_folder_spam',
+	            'txt_folder_' . BX_CNV_FOLDER_TRASH => '_bx_cnv_folder_trash',
+            ),
+        );
+        
+        $this->_aJsClasses = array_merge($this->_aJsClasses, array(
+           'manage_tools' => 'BxCnvManageTools'
+        ));
+
+        $this->_aJsObjects = array_merge($this->_aJsObjects, array(
+            'manage_tools' => 'oBxCnvManageTools'
+        ));
+
+    }
+}
+
+/** @} */

+ 150 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvDb.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    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Module database queries
+ */
+class BxCnvDb extends BxBaseModTextDb
+{
+    public function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+
+    public function conversationToFolder($iConversationId, $iFolderId, $iProfileCollaborator, $iReadCommentsNum = -1)
+    {
+        $sQuery = $this->prepare("INSERT IGNORE INTO `" . $this->getPrefix() . "conv2folder` SET `conv_id` = ?, `folder_id` = ?, `collaborator` = ?, `read_comments` = ?", $iConversationId, $iFolderId, $iProfileCollaborator, $iReadCommentsNum);
+        return $this->query($sQuery);
+    }
+
+    public function getFolder($iFolderId)
+    {
+        $sQuery = $this->prepare("SELECT `id`, `author`, `name` FROM `" . $this->getPrefix() . "folders` WHERE `id` = ?", $iFolderId);
+        return $this->getRow($sQuery);
+    }
+
+    public function getConversationFolder($iConversationId, $iProfileCollaborator)
+    {
+        $sQuery = $this->prepare("SELECT `folder_id` FROM `" . $this->getPrefix() . "conv2folder` WHERE `conv_id` = ? AND `collaborator` = ?", $iConversationId, $iProfileCollaborator);
+        return $this->getOne($sQuery);
+    }
+
+    public function removeCollaborator($iConversationId, $iProfileId) 
+    {
+        $sQuery = $this->prepare("DELETE FROM `" . $this->getPrefix() . "conv2folder` WHERE `conv_id` = ? AND `collaborator` = ?", $iConversationId, $iProfileId);
+        return $this->query($sQuery);
+    }
+
+    /**
+     * Remove collaborator from all conversations (when profile is deleted)
+     * @param $iProfileId profile id to remove
+     * @return number of deletions
+     */
+    public function removeCollaboratorFromAllConversations($iProfileId)
+    {
+        $aConvos = $this->getColumn("SELECT `conv_id` FROM `" . $this->getPrefix() . "conv2folder` WHERE `collaborator` = ?", array($iProfileId));
+        if (!($iRet = $this->query("DELETE FROM `" . $this->getPrefix() . "conv2folder` WHERE `collaborator` = ?", array($iProfileId))))
+            return 0;
+
+        foreach ($aConvos as $iConversationId) {
+            if (!$this->getCollaborators($iConversationId))
+                $this->deleteConvo($iConversationId);
+        }
+        return $iRet;
+    }
+    
+    public function getCollaborators($iConversationId)
+    {
+        $sQuery = $this->prepare("SELECT `collaborator`, `read_comments` FROM `" . $this->getPrefix() . "conv2folder` WHERE `conv_id` = ?", $iConversationId);
+        return $this->getPairs($sQuery, 'collaborator', 'read_comments');
+    }
+
+    public function updateReadComments($iProfileId, $iConversationId, $iReadComments)
+    {
+        $sQuery = $this->prepare("UPDATE `" . $this->getPrefix() . "conv2folder` SET `read_comments` = ? WHERE `conv_id` = ? AND `collaborator` = ?", $iReadComments, $iConversationId, $iProfileId);
+        return $this->query($sQuery);
+    }
+
+    public function updateLastCommentTimeProfile($iConversationId, $iProfileId, $iCommentId, $iTimestamp)
+    {
+        $sQuery = $this->prepare("UPDATE `" . $this->getPrefix() . "conversations` SET `last_reply_profile_id` = ?, `last_reply_timestamp` = ?, `last_reply_comment_id` = ? WHERE `id` = ?", $iProfileId, $iTimestamp, $iCommentId, $iConversationId);
+        return $this->query($sQuery);
+    }
+
+    public function moveConvo($iConversationId, $iProfileId, $iFolderId)
+    {
+        $sQuery = $this->prepare("SELECT `folder_id` FROM `" . $this->getPrefix() . "conv2folder` WHERE `conv_id` = ? AND `collaborator` = ?", $iConversationId, $iProfileId);
+        $iFolderIdOld = $this->getOne($sQuery);
+        if (BX_CNV_FOLDER_TRASH == $iFolderIdOld) // if convo is already in trash folder - delete it
+            return '' === $this->deleteConvo($iConversationId, $iProfileId) ? true : false;
+
+        $sQuery = $this->prepare("UPDATE `" . $this->getPrefix() . "conv2folder` SET `folder_id` = ? WHERE `conv_id` = ? AND `collaborator` = ?", $iFolderId, $iConversationId, $iProfileId);
+        return $this->query($sQuery);
+    }
+
+    public function deleteConvo($iConversationId, $iProfileId = 0)
+    {
+        $aContentInfo = $this->getContentInfoById ($iConversationId);
+        if (!$aContentInfo)
+            return '';
+
+        // delete convo
+        $aBindings = array(
+        	'conv_id' => $iConversationId
+        );
+
+        $sWhere = '';
+        if ($iProfileId) {
+        	$aBindings['collaborator'] = $iProfileId;
+
+            $sWhere = " AND `collaborator` = :collaborator";
+        }
+
+        $sQuery = "DELETE FROM `" . $this->getPrefix() . "conv2folder` WHERE `conv_id` = :conv_id" . $sWhere;
+        $this->query($sQuery, $aBindings);
+
+        // delete whole conversation if there is no refencences to the conversation in conv2folder table
+        if ($this->getCollaborators($iConversationId))
+            return '';
+            
+        $sQuery = $this->prepare("SELECT `id` FROM `" . $this->getPrefix() . "conv2folder` WHERE `conv_id` = ?", $iConversationId);
+        if (!$this->getOne($sQuery)) {
+            $CNF = &$this->_oConfig->CNF;
+            $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD']);
+            return $oForm->delete((int)$iConversationId, $aContentInfo) ? '' : _t('_sys_txt_error_occured');
+        }
+
+        return '';
+    }
+
+    public function getUnreadMessagesNum ($iProfileId, $iFolderId = BX_CNV_FOLDER_INBOX)
+    {
+        $sQuery = $this->prepare("SELECT SUM(`c`.`comments` - `f`.`read_comments`)
+            FROM `" . $this->getPrefix() . "conv2folder` as `f`
+            INNER JOIN `" . $this->getPrefix() . "conversations` AS `c` ON (`c`.`id` = `f`.`conv_id`)
+            WHERE `f`.`collaborator` = ? AND `f`.`folder_id` = ?", $iProfileId, $iFolderId);
+        return $this->getOne($sQuery);
+    }
+
+    public function getMessagesPreviews ($iProfileId, $iStart = 0, $iLimit = 4, $iFolderId = BX_CNV_FOLDER_INBOX)
+    {
+        $sQuery = $this->prepare("SELECT `c`.`id`, `c`.`text`, `c`.`author`, `cmts`.`cmt_text`, `c`.`last_reply_profile_id`, `c`.`comments`, (`c`.`comments` - `f`.`read_comments`) AS `unread_messages`, `last_reply_timestamp`
+            FROM `" . $this->getPrefix() . "conv2folder` as `f`
+            INNER JOIN `" . $this->getPrefix() . "conversations` AS `c` ON (`c`.`id` = `f`.`conv_id`)
+            LEFT JOIN `" . $this->getPrefix() . "cmts` AS `cmts` ON (`cmts`.`cmt_id` = `c`.`last_reply_comment_id`)
+            WHERE `f`.`collaborator` = ? AND `f`.`folder_id` = ?
+            ORDER BY `c`.`last_reply_timestamp` DESC
+            LIMIT ?, ?", $iProfileId, $iFolderId, $iStart, $iLimit);
+        return $this->getAll($sQuery);
+    }
+}
+
+/** @} */

+ 208 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvFormEntry.php

@@ -0,0 +1,208 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Create/Edit entry form
+ */
+class BxCnvFormEntry extends BxBaseModTextFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_convos';
+        parent::__construct($aInfo, $oTemplate);
+
+        $oTemplate = BxDolTemplate::getInstance();
+        $oTemplate->addJsTranslation(array(
+            '_bx_cnv_draft_saving_error',
+            '_bx_cnv_draft_saved_success',
+        ));
+    }
+
+    public function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        if ($bRet = parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges)) {
+            $iFolder = $this->_oModule->_oDb->getConversationFolder($iContentId, bx_get_logged_profile_id());
+
+            $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
+            if ($aContentInfo && bx_get_logged_profile_id() == $aContentInfo[$CNF['FIELD_AUTHOR']]) // allow to edit participants for author only
+                $this->updateParticipants ($iContentId, $iFolder, $iFolder == BX_CNV_FOLDER_DRAFTS ? true : false);
+        }
+
+        return $bRet;
+    }
+
+    public function insert ($aValsToAdd = array(), $isIgnore = false)
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+
+        $aValsToAdd['last_reply_timestamp'] = time();
+        $aValsToAdd['last_reply_profile_id'] = bx_get_logged_profile_id();
+
+        $bSaveToDrafts = bx_get('draft_save');
+        $iContentId = (int)bx_get('draft_id');
+        $bDraft = $iContentId ? BX_CNV_FOLDER_DRAFTS == $this->_oModule->_oDb->getConversationFolder($iContentId, bx_get_logged_profile_id()) : false;
+
+        // check for spam
+        $bSpam = false;
+        $sValue = $this->getCleanValue($CNF['FIELD_TEXT']);
+        bx_alert('system', 'check_spam', 0, getLoggedId(), array('is_spam' => &$bSpam, 'content' => &$sValue, 'where' => $this->MODULE));
+        self::setSubmittedValue($CNF['FIELD_TEXT'], $sValue, $this->aFormAttrs['method']);
+
+        if($iContentId) {
+            if(!$bDraft)
+                return 0;
+
+            if(!parent::update($iContentId, $aValsToAdd, $isIgnore))
+                return 0;
+
+        } 
+        else {
+            
+            $iContentId = parent::insert($aValsToAdd, $isIgnore);
+            if(!$iContentId)
+                return 0;
+        }
+
+        if($bSaveToDrafts) {
+            if(!$bDraft)
+                $this->_oModule->_oDb->conversationToFolder($iContentId, BX_CNV_FOLDER_DRAFTS, bx_get_logged_profile_id(), 0);
+
+            // process uploaded files
+            if(isset($CNF['FIELD_PHOTO']))
+                $this->processFiles ($CNF['FIELD_PHOTO'], $iContentId, true);
+
+            // draft is saved via ajax call only, upon successfull draft saving content id is returned
+            echo $iContentId . ',' . $this->getCsrfToken();
+            exit;
+        } 
+        else {
+            $iFolder = $bSpam ? BX_CNV_FOLDER_SPAM : BX_CNV_FOLDER_INBOX;
+            $this->updateParticipants ($iContentId, $iFolder, $bDraft);
+        }
+
+        return $iContentId;
+    }
+
+    public function updateParticipants ($iContentId, $iFolder, $bDraft, $aRecipientsAdd = array()) 
+    {
+        $iSender = bx_get_logged_profile_id();
+        $aRecipientsOld = $this->_oModule->_oDb->getCollaborators($iContentId);
+
+        // place conversation to "inbox" (or "spam" - in case of spam) folder
+        $aRecipientsFormForm = $this->getCleanValue('recipients') ? $this->getCleanValue('recipients') : array();
+        $aRecipients = array_unique(array_merge($aRecipientsFormForm, array($iSender), $aRecipientsAdd), SORT_NUMERIC);
+        foreach ($aRecipients as $iProfile) {
+            $oProfile = BxDolProfile::getInstance($iProfile);
+            if(!$oProfile)
+                continue;
+
+            $iRecipient = $oProfile->id();
+            if($bDraft && $iRecipient == $iSender)
+                $this->_oModule->_oDb->moveConvo($iContentId, $iRecipient, $iFolder);
+            else {
+                if($iRecipient != $iSender) {
+                    $bCanContact = true;
+                    bx_alert('profile', 'check_contact', 0, false, array('can_contact' => &$bCanContact, 'sender' => $iSender, 'recipient' => $iRecipient, 'where' => $this->MODULE));
+                    if(!$bCanContact)
+                        $iFolder = BX_CNV_FOLDER_SPAM;
+                }
+
+                if ($aRecipientsAdd && in_array($iRecipient, $aRecipientsAdd))
+                    $this->_oModule->_oDb->removeCollaborator($iContentId, $iRecipient);
+
+                $this->_oModule->_oDb->conversationToFolder($iContentId, $iFolder, $iRecipient, $iRecipient == $iSender ? 0 : -1);
+            }
+        }
+
+        // remove participants
+        foreach ($aRecipientsOld as $iProfileId => $iCount) {
+            if (!in_array($iProfileId, $aRecipients))
+                $this->_oModule->_oDb->removeCollaborator($iContentId, $iProfileId);
+        }
+    }
+
+    protected function genCustomInputRecipients ($aInput)
+    {
+        $aInput['ajax_get_suggestions'] = BX_DOL_URL_ROOT . "modules/?r=convos/ajax_get_recipients";
+        return $this->genCustomInputUsernamesSuggestions($aInput);
+    }
+
+    protected function genCustomInputSubmitText ($aInput)
+    {
+        $aVars = array();
+        return $this->_oModule->_oTemplate->parseHtmlByName('form_submit_text.html', $aVars);
+    }
+
+    function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
+        $CNF = $this->_oModule->_oConfig->CNF;
+        if ($aValues && bx_get_logged_profile_id() != $aValues[$CNF['FIELD_AUTHOR']]) { // unset some fields for non author
+            unset($this->aInputs[$CNF['FIELD_ALLOW_EDIT']]);
+            unset($this->aInputs['recipients']);
+        }
+
+        if ($iContentId = bx_get('draft_id')) { // if adding from draft, fill in existing fields info
+            $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
+            if ($aContentInfo)
+                $aValues = array_merge($aContentInfo, $aValues);
+        }
+
+        if ($sProfilesIds = bx_get('profiles')) { // if writing directly to some recipients, pre-fill them
+            $a = explode(',', $sProfilesIds);
+            $a = array_unique(BxDolFormCheckerHelper::passInt($a));
+            if ($a)
+                $aValues['recipients'] = array_merge(empty($aValues['recipients']) ? array() : $aValues['recipients'], $a);            
+        }
+
+        $sEt = bx_get('et');
+        if($sEt !== false) { // if 'attachable email template' was specified, process it
+            $aEt = unserialize(base64_decode(urldecode($sEt)));
+
+            if(!empty($aEt) && is_array($aEt) && !empty($aEt['name'])) {
+                $sName = bx_process_input($aEt['name']);
+                $aParams = isset($aEt['params']) ? bx_process_input($aEt['params']) : array();
+
+                $sAet = getParam('sys_email_attachable_email_templates');
+                if(strpos($sAet, $sName) !== false) {
+                    $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate($sName, $aParams);
+                    if(!empty($aTemplate) && is_array($aTemplate)) {
+                        if(isset($this->aInputs[$CNF['FIELD_TITLE']]) && empty($this->aInputs[$CNF['FIELD_TITLE']]['value']))
+                            $this->aInputs[$CNF['FIELD_TITLE']]['value'] = $aTemplate['Subject'];
+
+                        if(isset($this->aInputs[$CNF['FIELD_TEXT']]) && empty($this->aInputs[$CNF['FIELD_TEXT']]['value']))
+                            $this->aInputs[$CNF['FIELD_TEXT']]['value'] = $aTemplate['Body'];
+                    }
+                }
+            }
+            
+        }
+
+        return parent::initChecker ($aValues, $aSpecificValues);
+    }
+
+    function isValid ()
+    {
+        if (bx_get('draft_save')) // form is always valid when saving to drafts
+            return true;
+        return parent::isValid ();
+    }
+
+    public function processFiles ($sFieldFile, $iContentId = 0, $isAssociateWithContent = false)
+    {
+        if (!$isAssociateWithContent && bx_get('draft_id')) // when draft is already saved then db update is called but we still need to do association since it's draft
+            $isAssociateWithContent = true; // TODO: if edit mode will be added, then this functionality maybe reconsidered
+         
+        return parent::processFiles ($sFieldFile, $iContentId, $isAssociateWithContent);
+    }
+}
+
+/** @} */

+ 168 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvGrid.php

@@ -0,0 +1,168 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+class BxCnvGrid extends BxBaseModGeneralGridAdministration
+{
+    protected $MODULE;
+    protected $_sFilter1Name;
+	protected $_sFilter1Value;
+	protected $_aFilter1Values;
+
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_convos';
+        parent::__construct ($aOptions, $oTemplate);
+        $this->_sDefaultSortingOrder = 'DESC';
+
+        if ($iFolderId = (int)bx_get('folder_id'))
+            $this->addMarkers(array(
+                'folder_id' => $iFolderId,
+                'profile_id' => bx_get_logged_profile_id(),
+            ));
+        
+        $this->_sFilter1Name = 'filter1';
+        $this->_aFilter1Values = array(
+        	'' => _t('_bx_cnv_grid_filter_item_title_adm_all'),
+            'unread' => _t('_bx_cnv_grid_filter_item_title_adm_unread'),
+		);
+        
+    	$sFilter1 = bx_get($this->_sFilter1Name);
+        if(!empty($sFilter1)) {
+            $this->_sFilter1Value = bx_process_input($sFilter1);
+            $this->_aQueryAppend['filter1'] = $this->_sFilter1Value;
+        }
+        $this->_sManageType = BX_DOL_MANAGE_TOOLS_COMMON;
+    }
+    
+    protected function _getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+        if(strpos($sFilter, $this->_sParamsDivider) !== false)
+            list($this->_sFilter1Value, $sFilter) = explode($this->_sParamsDivider, $sFilter);
+
+    	if(!empty($this->_sFilter1Value)){
+            $CNF = &$this->_oModule->_oConfig->CNF;
+        	$this->_aOptions['source'] .= $this->_oModule->_oDb->prepareAsString(" WHERE `c`.`comments` > `f`.`read_comments` ");
+        }
+    
+        return parent::_getDataSql($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+    
+    //--- Layout methods ---//
+	protected function _getFilterControls()
+    {
+        parent::_getFilterControls();
+
+        return  $this->_getFilterSelectOne($this->_sFilter1Name, $this->_sFilter1Value, $this->_aFilter1Values) . $this->_getSearchInput();
+    }
+    
+    protected function _getFilterSelectOne($sFilterName, $sFilterValue, $aFilterValues)
+    {
+        if(empty($sFilterName) || empty($aFilterValues))
+            return '';
+
+		$CNF = &$this->_oModule->_oConfig->CNF;
+		$sJsObject = $this->_oModule->_oConfig->getJsObject('manage_tools');
+
+		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);
+    }
+
+    public function performActionCompose()
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_ADD_ENTRY']);
+
+        header('Location:' . $sUrl);
+    }
+
+    protected function _getActionAdd ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $CNF = &$oModule->_oConfig->CNF;
+
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_ADD_ENTRY']);
+
+        $a['attr']['onclick'] = "document.location='$sUrl'";
+        unset($a['attr']['bx_grid_action_independent']);
+
+        return parent::_getActionDefault ($sType, $sKey, $a, $isSmall, $isDisabled, $aRow);
+    }
+
+    protected function _getCellHeaderWrapper ($sKey, $aField, $sHeader, $sAttr)
+    {
+        $sHeader = '<span>' . $sHeader . '</span>';
+        return parent::_getCellHeaderWrapper ($sKey, $aField, $sHeader, $sAttr);
+    }
+
+    protected function _getCellPreview ($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault ('', $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellLastReplyTimestamp ($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $s = $oModule->_oTemplate->entryMessagePreviewInGrid ($aRow);
+        return parent::_getCellDefault ($s, $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellCollaborators ($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $s = $oModule->_oTemplate->entryCollaborators ($aRow);
+        return parent::_getCellDefault ($s, $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellComments ($mixedValue, $sKey, $aField, $aRow)
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $s = $oModule->_oTemplate->getMessageLabel ($aRow);
+        return parent::_getCellDefault ('<div class="bx-cnv-grid-field-messages"><span>' . (1 + $mixedValue) . '</span>' . $s . '</div>', $sKey, $aField, $aRow);
+    }
+
+    protected function _doDelete ($iId, $aParams = array())
+    {
+        $oModule = BxDolModule::getInstance($this->MODULE);
+
+        if ($sErrorMsg = $oModule->deleteConvo ($iId))
+            return 0;
+
+        return 1;
+    }
+
+    protected function _addJsCss()
+    {
+        parent::_addJsCss();
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $oModule->_oTemplate->addJs('main.js');
+        $oModule->_oTemplate->addCss(array('main-media-tablet.css', 'main-media-desktop.css'));
+    }
+}
+
+/** @} */

+ 466 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/classes/BxCnvModule.php

@@ -0,0 +1,466 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+define('BX_CNV_FOLDER_INBOX', 1);
+define('BX_CNV_FOLDER_DRAFTS', 2);
+define('BX_CNV_FOLDER_SPAM', 3);
+define('BX_CNV_FOLDER_TRASH', 4);
+
+/**
+ * Conversations module
+ */
+class BxCnvModule extends BxBaseModTextModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    public function sortCollaborators ($aCollaborators, $iProfileIdLastComment, $iProfileIdAuthor, $iProfileIdCurrent = 0)
+    {
+        if (!$iProfileIdCurrent)
+            $iProfileIdCurrent = bx_get_logged_profile_id();
+
+        $aMoveUp = array($iProfileIdCurrent, $iProfileIdLastComment, $iProfileIdAuthor);
+
+        asort($aCollaborators, SORT_NUMERIC);
+
+        foreach ($aMoveUp as $iProfileId) {
+            if (!isset($aCollaborators[$iProfileId]))
+                continue;
+
+            $a = array($iProfileId => $aCollaborators[$iProfileId]);
+            unset($aCollaborators[$iProfileId]);
+            $aCollaborators = $a + $aCollaborators;
+        }
+
+        return $aCollaborators;
+    }
+
+    public function setModuleSubmenu ($iCurrentFolderId = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aMapFolderId2MenuName = array (
+            BX_CNV_FOLDER_INBOX => 'convos-folder-inbox',
+            BX_CNV_FOLDER_DRAFTS => 'convos-drafts',
+            BX_CNV_FOLDER_SPAM => 'convos-spam',
+            BX_CNV_FOLDER_TRASH => 'convos-trash',
+        );
+
+        $oMenuSubmenu = BxDolMenu::getObjectInstance('sys_site_submenu');
+        if (!$oMenuSubmenu)
+            return;
+
+        $oMenuSubmenu->setObjectSubmenu($CNF['OBJECT_MENU_SUBMENU'], array (
+            'title' => _t('_bx_cnv'),
+            'link' => BX_DOL_URL_ROOT . $CNF['URL_HOME'],
+            'icon' => '',
+        ));
+
+        $oMenuModule = BxDolMenu::getObjectInstance($CNF['OBJECT_MENU_SUBMENU']);
+        if ($oMenuModule && isset($aMapFolderId2MenuName[$iCurrentFolderId]))
+            $oMenuModule->setSelected($this->_aModule['name'], $aMapFolderId2MenuName[$iCurrentFolderId]);
+    }
+
+    /**
+     * Mark conversation as unread for the current user
+     * @return error string on error, or empty string on success
+     */
+    public function markUnread ($iContentId)
+    {
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return _t('_sys_request_page_not_found_cpt');
+
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedView($aContentInfo)))
+            return $sMsg;
+
+        if (!$this->_oDb->updateReadComments(bx_get_logged_profile_id(), (int)$iContentId, -1))
+            return _t('_error occured');
+
+        return '';
+    }
+
+    /**
+     * Delete conversation for current user by content id, before deletetion it checks user permission to delete convos
+     * @return error string on error, or empty string on success
+     */
+    public function deleteConvo ($iContentId)
+    {
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return _t('_sys_request_page_not_found_cpt');
+
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedDelete($aContentInfo)))
+            return $sMsg;
+
+        if (!$this->_oDb->moveConvo((int)$iContentId, bx_get_logged_profile_id(), BX_CNV_FOLDER_TRASH))
+            return _t('_error occured');
+
+        return '';
+    }
+
+    /**
+     * Delete whole conversation for all users by content id
+     * @return error string on error, or empty string on success
+     */
+    public function deleteConvoForever ($iContentId)
+    {
+        return $this->_oDb->deleteConvo((int)$iContentId);
+    }
+
+    public function actionMarkUnread($iContentId)
+    {
+        header('Content-Type:text/plain; charset=utf-8');
+
+        if ($s = $this->markUnread ($iContentId)) {
+            echo $s;
+            exit;
+        }
+
+        echo BX_DOL_URL_ROOT . $this->_oConfig->CNF['URL_HOME'];
+        exit;
+    }
+
+    public function actionDelete($iContentId)
+    {
+        header('Content-Type:text/plain; charset=utf-8');
+
+        if ($s = $this->deleteConvo ($iContentId)) {
+            echo $s;
+            exit;
+        }
+
+        echo BX_DOL_URL_ROOT . $this->_oConfig->CNF['URL_HOME'];
+        exit;
+    }
+
+    /**
+     * Display convos in folder
+     */
+    public function actionFolder ($iFolderId)
+    {
+        $oTemplate = BxDolTemplate::getInstance();
+
+        $aFolder = $this->_oDb->getFolder((int)$iFolderId);
+        $oPage = BxDolPage::getObjectInstance('bx_convos_home');
+
+        if (!$aFolder || !$oPage) {
+            $this->_oTemplate->displayPageNotFound();
+            exit;
+        }
+
+        // add replaceable markers
+        $oPage->addMarkers(array(
+            'folder_id' => (int)$iFolderId,
+            'folder' => _t($aFolder['name']),
+        ));
+
+        $s = $oPage->getCode();
+
+        $this->_oTemplate = BxDolTemplate::getInstance();
+        $this->_oTemplate->setPageNameIndex (BX_PAGE_DEFAULT);
+        $this->_oTemplate->setPageContent ('page_main_code', $s);
+        $_GET['i']='convos-folder'; //#1148
+        $this->_oTemplate->getPageCode();
+    }
+
+    /**
+     * Get possible recipients for start conversation form
+     */
+    public function actionAjaxGetRecipients ()
+    {
+        $sTerm = bx_get('term');
+
+        $a = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
+
+        header('Content-Type:text/javascript; charset=utf-8');
+        echo(json_encode($a));
+    }
+
+    public function serviceConversationsInFolder ($iFolderId = BX_CNV_FOLDER_INBOX)
+    {
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->CNF['OBJECT_GRID']);
+        if (!$oGrid)
+            return false;
+
+        $aFolder = $this->_oDb->getFolder((int)$iFolderId);
+        if (!$aFolder)
+            return false;
+
+        $this->setModuleSubmenu ((int)$iFolderId);
+
+        // TODO: incorporate markers into custom class, so replace will work in search and so on
+        $oGrid->addMarkers(array(
+            'folder_id' => (int)$iFolderId,
+            'profile_id' => bx_get_logged_profile_id(),
+        ));
+
+        $this->_oTemplate->addCss(array('manage_tools.css'));
+        $this->_oTemplate->addJs(array('manage_tools.js'));
+        $this->_oTemplate->addJsTranslation(array('_sys_grid_search'));
+        
+        return $this->_oTemplate->getJsCode('manage_tools', array('sObjNameGrid' => $this->_oConfig->CNF['OBJECT_GRID'])) . $oGrid->getCode();
+    }
+
+    public function serviceMessagesPreviews ($iProfileId = 0, $bEmptyMessage = true)
+    {
+        if (!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+
+        $a = $this->_oDb->getMessagesPreviews($iProfileId, 0, (int)getParam('bx_convos_preview_messages_num'));
+        if((empty($a) || !is_array($a)) && !$bEmptyMessage)
+            return '';
+
+        return $this->_oTemplate->getMessagesPreviews($a);
+    }
+
+    /**
+     * Returns preview of profile's conversations with statistic for React Jot
+     * @param int $iProfileId
+     * @param int $iStart
+     * @param int $iPerPage
+     * @param int $iFolderId
+     * @return mixed
+     */
+    public function serviceGetMessagesPreviews ($iProfileId = 0, $iStart = 0, $iPerPage = 10, $iFolderId = BX_CNV_FOLDER_INBOX)
+    {
+        if (!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+
+        return $this->_oDb->getMessagesPreviews($iProfileId, (int)$iStart, (int)$iPerPage, $iFolderId);
+    }
+
+    /**
+     * Get number of unread messages for spme profile
+     * @param $iProfileId - profile to get unread messages for, if omitted then currently logged is profile is used
+     * @return integer
+     */
+    public function serviceGetUnreadMessagesNum ($iProfileId = 0)
+    {
+        if (!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+
+        return $this->_oDb->getUnreadMessagesNum((int)$iProfileId);
+    }
+
+    public function serviceGetLiveUpdates($aMenuItemParent, $aMenuItemChild, $iCount = 0)
+    {
+        $iProfileId = (int)bx_get_logged_profile_id();
+        $iCountNew = $this->_oDb->getUnreadMessagesNum($iProfileId);
+        if($iCountNew == $iCount)
+			return false;
+
+        return array(
+    		'count' => $iCountNew, // required
+    		'method' => 'bx_menu_show_live_update(oData)', // required
+    		'data' => array(
+    			'code' => BxDolTemplate::getInstance()->parseHtmlByTemplateName('menu_item_addon', array(
+    				'content' => '{count}'
+                )),
+                'mi_parent' => $aMenuItemParent,
+                'mi_child' => $aMenuItemChild
+    		),  // optional, may have some additional data to be passed in JS method provided using 'method' param above.
+    	);
+    }
+
+    /**
+     * Update last comment time and author
+     */
+    public function serviceTriggerCommentPost ($iContentId, $iProfileId, $iCommentId, $iTimestamp = 0, $sCommentText = '')
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        if (!(int)$iContentId)
+            return false;
+        $aContentInfo = $this->_oDb->getContentInfoById((int)$iContentId);
+        if (!$aContentInfo)
+            return false;
+
+        // add author to the list of collaborators when somebody replies
+        // if author is removed from collaborators
+        // of if authot placed message to trash
+        $aCollaborators = $this->_oDb->getCollaborators($aContentInfo[$CNF['FIELD_ID']]);
+        if (!isset($aCollaborators[$aContentInfo[$CNF['FIELD_AUTHOR']]]) || BX_CNV_FOLDER_TRASH == $this->_oDb->getConversationFolder($aContentInfo[$CNF['FIELD_ID']], $aContentInfo[$CNF['FIELD_AUTHOR']])) {
+            $oFormsHelper = $this->serviceFormsHelper ();
+            $oForm = $oFormsHelper->getObjectFormEdit();
+            $oForm->updateParticipants($aContentInfo[$CNF['FIELD_ID']], BX_CNV_FOLDER_INBOX, false, array($aContentInfo[$CNF['FIELD_AUTHOR']]));
+        }
+
+
+        $oCmts = BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $iContentId);
+        if(!$oCmts)
+            return false;
+            
+        if (!$iTimestamp)
+            $iTimestamp = time();
+
+        if ($iProfileId == bx_get_logged_profile_id())
+            $this->_oDb->updateReadComments($iProfileId, $aContentInfo[$CNF['FIELD_ID']], $aContentInfo[$CNF['FIELD_COMMENTS']]);
+
+        if (!$this->_oDb->updateLastCommentTimeProfile((int)$iContentId, (int)$iProfileId, (int)$iCommentId, $iTimestamp))
+            return false;
+
+        // send notification to all collaborators
+        if ($oProfile = BxDolProfile::getInstance($iProfileId)) {
+            foreach ($aCollaborators as $iCollaborator => $iReadComments) {
+                if ($iCollaborator == $iProfileId)
+                    continue;
+                sendMailTemplate('bx_cnv_new_reply', 0, $iCollaborator, array(
+                    'SenderDisplayName' => $oProfile->getDisplayName(),
+                    'SenderUrl' => $oProfile->getUrl(),
+                    'PageUrl' => $oCmts->getItemUrl($iCommentId),
+                    'PageTitle' => $oCmts->getObjectTitle(),
+                    'Message' => $sCommentText,
+                ), BX_EMAIL_NOTIFY, true);
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Entry collaborators block
+     */
+    public function serviceEntityCollaborators ($iContentId = 0)
+    {
+        if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId)
+            return false;
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return false;
+
+        return $this->_oTemplate->entryCollaborators ($aContentInfo, 5, 'right');
+    }
+
+    /**
+     * No social sharing for private conversations
+     */
+    public function serviceEntitySocialSharing ($mixedContent = false, $aParams = array())
+    {
+        return '';
+    }
+
+    /**
+     * Delete content entry
+     * @param $iContentId content id 
+     * @return error message or empty string on success
+     */
+    public function serviceDeleteEntity ($iContentId, $sFuncDelete = 'deleteData')
+    {
+        return $this->_oDb->deleteConvo($iContentId);
+    }
+    
+    /**
+     * Delete profile from all conversation (when profile is delete without content)
+     * @param $iProfileId profile id 
+     * @return number of deleted items
+     */    
+    public function serviceRemoveCollaboratorFromAllConversations ($iProfileId)
+    {
+        return $this->_oDb->removeCollaboratorFromAllConversations((int)$iProfileId);
+    }
+    
+    /**
+     * Delete all content by profile (when profile is delete with content)
+     * @param $iProfileId profile id 
+     * @return number of deleted items
+     */
+    public function serviceDeleteEntitiesByAuthor ($iProfileId)
+    {
+        $a = $this->_oDb->getEntriesByAuthor((int)$iProfileId);
+        if (!$a)
+            return 0;
+
+        $iCount = 0;
+        foreach ($a as $aContentInfo)
+            $iCount += ('' == $this->serviceDeleteEntity($aContentInfo[$this->_oConfig->CNF['FIELD_ID']]) ? 1 : 0);
+
+        return $iCount;
+    }
+    
+    /**
+     * No moderators for personal convos
+     */
+    public function _isModerator ($isPerformAction = false)
+    {
+        return false;
+    }
+
+    /**
+     * No thumbs for convos
+     */
+    public function checkAllowedSetThumb ($iContentId = 0)
+    {
+        return _t('_sys_txt_access_denied');
+    }
+
+    /**
+     * There is no 'moderator' access in convos
+     */
+    public function checkAllowedEditAnyEntry ($isPerformAction = false)
+    {
+    	return _t('_sys_txt_access_denied');
+    }
+
+    public function checkAllowedEdit ($aDataEntry, $isPerformAction = false)
+    {       
+        if ($aDataEntry[$this->_oConfig->CNF['FIELD_ALLOW_EDIT']] && $this->isCollaborator($aDataEntry, bx_get_logged_profile_id()))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return parent::checkAllowedEdit ($aDataEntry, $isPerformAction);
+    }
+    
+    /**
+     * Conversations can be deleted by author and/or collaborators only.
+     * Admins can't delete conversations, since it's designed for participant only, it's moved to trash actually, also it's private content.
+     */
+    public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false)
+    {
+        if ($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->isCollaborator($aDataEntry, bx_get_logged_profile_id()))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        if ($this->_isModerator($isPerformAction))
+            return _t('_sys_txt_access_denied');
+
+        return parent::checkAllowedDelete ($aDataEntry, $isPerformAction);
+    }
+
+    /**
+     * Only collaborators can view convo
+     */
+    public function checkAllowedView ($aDataEntry, $isPerformAction = false)
+    {
+        return $this->serviceCheckAllowedViewForProfile ($aDataEntry, $isPerformAction);
+    }
+
+    public function serviceCheckAllowedViewForProfile ($aDataEntry, $isPerformAction = false, $iProfileId = false)
+    {
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = parent::serviceCheckAllowedViewForProfile ($aDataEntry, $isPerformAction, $iProfileId)))
+            return $sMsg;
+
+        if (!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+
+        return $this->isCollaborator($aDataEntry, $iProfileId) ? CHECK_ACTION_RESULT_ALLOWED : _t('_sys_txt_access_denied');
+    }
+
+    protected function isCollaborator($aDataEntry, $iProfileId)
+    {
+        $aCollaborators = $this->_oDb->getCollaborators($aDataEntry[$this->_oConfig->CNF['FIELD_ID']]);
+        return isset($aCollaborators[$iProfileId]);
+    }
+}
+
+/** @} */

+ 104 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/install/config.php

@@ -0,0 +1,104 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_convos',
+    'title' => 'Conversations',
+    'note' => 'Conversations module.',
+    'version' => '10.0.0',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '10.0.0-B1'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/convos/',
+    'home_uri' => 'convos',
+
+    'db_prefix' => 'bx_convos_',
+    'class_prefix' => 'BxCnv',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Conversations',
+
+    /**
+     * Menu triggers.
+     */
+    'menu_triggers' => array(
+        'trigger_profile_view_actions',
+        'trigger_group_view_actions',
+    ),
+
+	/**
+     * Storage objects to automatically delete files from upon module uninstallation.
+     * Note. Don't add storage objects used in transcoder objects.
+     */
+    'storages' => array(
+    	'bx_convos_files'
+    ),
+
+	/**
+     * Transcoders.
+     */
+    'transcoders' => array(
+		'bx_convos_preview'
+    ),
+
+    /**
+     * 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(
+    	'process_menu_triggers' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 139 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/install/langs/en.xml

@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+
+	<string name="_bx_cnv"><![CDATA[Conversations]]></string>
+	<string name="_bx_convos"><![CDATA[Conversations]]></string>
+
+	<string name="_bx_cnv_option_preview_messages_num"><![CDATA[Number of preview messages]]></string>
+
+	<string name="_bx_cnv_form_entry"><![CDATA[Conversations]]></string>
+	<string name="_bx_cnv_form_entry_display_add"><![CDATA[New conversation]]></string>
+	<string name="_bx_cnv_form_entry_display_edit"><![CDATA[Edit conversation]]></string>
+	<string name="_bx_cnv_form_entry_display_delete"><![CDATA[Delete conversation]]></string>
+	<string name="_bx_cnv_form_entry_display_view"><![CDATA[View conversation]]></string>
+	<string name="_bx_cnv_form_entry_input_sys_do_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_cnv_form_entry_input_do_submit"><![CDATA[Submit]]></string>
+	<string name="_bx_cnv_form_entry_input_sys_text"><![CDATA[Text]]></string>
+	<string name="_bx_cnv_form_entry_input_text"><![CDATA[Text]]></string>
+	<string name="_bx_cnv_form_entry_input_text_err"><![CDATA[Text field can't be empty]]></string>
+	<string name="_bx_cnv_form_entry_input_sys_delete_confirm"><![CDATA[Delete confirmation]]></string>
+	<string name="_bx_cnv_form_entry_input_delete_confirm"><![CDATA[I am sure I want to delete this conversation]]></string>
+	<string name="_bx_cnv_form_entry_input_delete_confirm_info"><![CDATA[This action can not be undone]]></string>
+	<string name="_bx_cnv_form_entry_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete the conversation]]></string>
+	<string name="_bx_cnv_form_entry_input_sys_attachments"><![CDATA[Attachments]]></string>
+	<string name="_bx_cnv_form_entry_input_attachments"><![CDATA[Attachments]]></string>
+    <string name="_bx_cnv_form_entry_input_recipients"><![CDATA[Recipients]]></string>
+    <string name="_bx_cnv_form_entry_input_sys_recipients"><![CDATA[Recipients]]></string>
+    <string name="_bx_cnv_form_entry_input_recipients_err"><![CDATA[Recipients is mandatory]]></string>
+    <string name="_bx_cnv_form_entry_input_sys_submit_text"><![CDATA[Draft status]]></string>
+    <string name="_bx_cnv_form_entry_input_sys_submit_block"><![CDATA[Submit block]]></string>
+    <string name="_bx_cnv_form_entry_input_sys_draft_id"><![CDATA[Draft ID]]></string>
+    <string name="_bx_cnv_form_entry_input_sys_allow_edit"><![CDATA[Main post editing by participants]]></string>
+    <string name="_bx_cnv_form_entry_input_allow_edit"><![CDATA[Main post editing by participants]]></string>
+
+	<string name="_bx_cnv_acl_action_create_entry"><![CDATA[New conversation]]></string>
+	<string name="_bx_cnv_acl_action_delete_entry"><![CDATA[Delete conversation]]></string>
+	<string name="_bx_cnv_acl_action_view_entry"><![CDATA[View conversation]]></string>
+
+	<string name="_bx_cnv_page_title_sys_create_entry"><![CDATA[New conversation]]></string>
+	<string name="_bx_cnv_page_title_create_entry"><![CDATA[New conversation]]></string>
+	<string name="_bx_cnv_page_block_title_create_entry"><![CDATA[New conversation]]></string>
+	<string name="_bx_cnv_page_title_sys_view_entry"><![CDATA[View conversation]]></string>
+	<string name="_bx_cnv_page_title_view_entry"><![CDATA[{title}]]></string>
+	<string name="_bx_cnv_page_block_title_entry_attachments"><![CDATA[Attachments]]></string>
+	<string name="_bx_cnv_page_block_title_entry_text"><![CDATA[Text]]></string>
+    <string name="_bx_cnv_page_block_title_entry_author"><![CDATA[Author]]></string>
+    <string name="_bx_cnv_page_block_title_entry_actions"><![CDATA[Actions]]></string>
+    <string name="_bx_cnv_page_block_title_entry_breadcrumb"><![CDATA[Breadcrumb]]></string>
+    <string name="_bx_cnv_page_block_title_entry_comments"><![CDATA[Replies ({0})]]></string>
+    <string name="_bx_cnv_page_block_title_entry_collaborators"><![CDATA[Participants]]></string>
+    <string name="_bx_cnv_page_title_sys_folder"><![CDATA[Conversations in folder]]></string>
+    <string name="_bx_cnv_page_title_folder"><![CDATA[Folder: {folder}]]></string>
+    <string name="_bx_cnv_page_block_title_folder"><![CDATA[Folder: {folder}]]></string>
+    <string name="_bx_cnv_page_block_title_convos"><![CDATA[Conversations]]></string>
+    <string name="_bx_cnv_page_title_sys_edit_entry"><![CDATA[Edit conversation]]></string>
+    <string name="_bx_cnv_page_title_edit_entry"><![CDATA[Edit conversation]]></string>
+    <string name="_bx_cnv_page_block_title_edit_entry"><![CDATA[Edit conversation]]></string>
+
+    <string name="_bx_cnv_menu_set_title_view_entry"><![CDATA[Conversation Actions]]></string>
+    <string name="_bx_cnv_menu_title_view_entry"><![CDATA[Conversation Actions]]></string>
+    <string name="_bx_cnv_menu_title_submenu"><![CDATA[Conversations Submenu]]></string>
+    <string name="_bx_cnv_menu_set_title_submenu"><![CDATA[Conversations Submenu]]></string>
+    <string name="_bx_cnv_menu_title_folders_more"><![CDATA[Conversations folders]]></string>
+    <string name="_bx_cnv_menu_set_title_submenu"><![CDATA[Conversations folders]]></string>
+    <string name="_bx_cnv_menu_set_title_folders_more"><![CDATA[More folders]]></string>
+    <string name="_bx_cnv_menu_item_title_system_message"><![CDATA[Start conversation]]></string>
+    <string name="_bx_cnv_menu_item_title_message"><![CDATA[Start conversation]]></string>
+    <string name="_bx_cnv_menu_item_title_system_message_group"><![CDATA[Group Message]]></string>
+    <string name="_bx_cnv_menu_item_title_message_group"><![CDATA[Group Message]]></string>
+    <string name="_bx_cnv_menu_item_title_system_mark_unread_entry"><![CDATA[Mark as unread]]></string>
+    <string name="_bx_cnv_menu_item_title_mark_unread_entry"><![CDATA[Mark as unread]]></string>
+
+    <string name="_bx_cnv_menu_item_title_system_delete_entry"><![CDATA[Delete conversation]]></string>
+    <string name="_bx_cnv_menu_item_title_delete_entry"><![CDATA[Delete conversation]]></string>
+    <string name="_bx_cnv_menu_item_title_system_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_cnv_menu_item_title_edit_entry"><![CDATA[Edit]]></string>
+    <string name="_bx_cnv_menu_item_title_system_folder_inbox"><![CDATA[Inbox]]></string>
+    <string name="_bx_cnv_menu_item_title_folder_inbox"><![CDATA[Inbox]]></string>
+    <string name="_bx_cnv_menu_item_title_system_folder_drafts"><![CDATA[Drafts]]></string>
+    <string name="_bx_cnv_menu_item_title_folder_drafts"><![CDATA[Drafts]]></string>
+    <string name="_bx_cnv_menu_item_title_system_folder_spam"><![CDATA[Spam]]></string>
+    <string name="_bx_cnv_menu_item_title_folder_spam"><![CDATA[Spam]]></string>
+    <string name="_bx_cnv_menu_item_title_system_folder_trash"><![CDATA[Trash]]></string>
+    <string name="_bx_cnv_menu_item_title_folder_trash"><![CDATA[Trash]]></string>
+    <string name="_bx_cnv_menu_item_title_system_folder_more"><![CDATA[More]]></string>
+    <string name="_bx_cnv_menu_item_title_folder_more"><![CDATA[More]]></string>
+    <string name="_bx_cnv_menu_item_title_system_convos"><![CDATA[Conversations]]></string>
+    <string name="_bx_cnv_menu_item_title_convos"><![CDATA[Conversations]]></string>
+    <string name="_bx_cnv_menu_item_title_system_unread_messages"><![CDATA[Unread messages number]]></string>
+    <string name="_bx_cnv_menu_item_title_unread_messages"><![CDATA[Unread messages]]></string>
+
+    <string name="_bx_cnv_txt_sample_single"><![CDATA[conversation]]></string>
+
+    <string name="_bx_cnv_folder_inbox"><![CDATA[Inbox]]></string>
+    <string name="_bx_cnv_folder_drafts"><![CDATA[Drafts]]></string>
+    <string name="_bx_cnv_folder_spam"><![CDATA[Spam]]></string>
+    <string name="_bx_cnv_folder_trash"><![CDATA[Trash]]></string>
+
+    <string name="_bx_cnv_field_comments"><![CDATA[#]]></string>
+    <string name="_bx_cnv_field_preview"><![CDATA[Preview]]></string>
+    <string name="_bx_cnv_field_collaborators"><![CDATA[Participants]]></string>
+
+    <string name="_bx_cnv_grid_action_err_delete"><![CDATA[Cannot delete the selected conversation(s).]]></string>
+    <string name="_bx_cnv_grid_action_delete"><![CDATA[Delete]]></string>
+    <string name="_bx_cnv_grid_action_compose"><![CDATA[Compose]]></string>
+	<string name="_bx_cnv_grid_filter_item_title_adm_all"><![CDATA[All]]></string>
+	<string name="_bx_cnv_grid_filter_item_title_adm_unread"><![CDATA[Unread]]></string>
+
+    <string name="_bx_cnv_collaborator_author"><![CDATA[author]]></string>
+    <string name="_bx_cnv_collaborator_last_replier"><![CDATA[last replier]]></string>
+    <string name="_bx_cnv_more"><![CDATA[{0} more]]></string>
+
+    <string name="_bx_cnv_author_desc"><![CDATA[{0} (updated {1})]]></string>
+    <string name="_bx_cnv_x_date_by_x_replier"><![CDATA[{0} by {1}]]></string>
+
+    <string name="_bx_cnv_read_by_all"><![CDATA[Read by all]]></string>
+    <string name="_bx_cnv_see_all"><![CDATA[See all conversations...]]></string>
+    <string name="_bx_cnv_you_are_last_replier"><![CDATA[You are last replier]]></string>
+
+    <string name="_bx_cnv_draft_saving_error"><![CDATA[Draft saving error!]]></string>
+    <string name="_bx_cnv_draft_saved_success"><![CDATA[Draft saved.]]></string>
+
+    <string name="_bx_cnv_email_new_message"><![CDATA[New message]]></string>
+    <string name="_bx_cnv_email_new_message_subject"><![CDATA[New message from {SenderDisplayName}]]></string>
+    <string name="_bx_cnv_email_new_message_body"><![CDATA[{email_header}
+<p><a href="{PageUrl}">New message</a> from <a href="{SenderUrl}">{SenderDisplayName}</a>:</p>
+<hr />
+<p>{Message}</p>
+{email_footer}]]></string>
+
+    <string name="_bx_cnv_email_new_reply"><![CDATA[New reply]]></string>
+    <string name="_bx_cnv_email_new_reply_subject"><![CDATA[New reply in conversation from {SenderDisplayName}]]></string>
+    <string name="_bx_cnv_email_new_reply_body"><![CDATA[{email_header}
+<p>New reply in <a href="{PageUrl}">{PageTitle}</a> conversation from <a href="{SenderUrl}">{SenderDisplayName}</a>:</p>
+<hr />
+<p>{Message}</p>
+<hr />
+Don't reply to this email, to reply to the sender please go to <a href="{PageUrl}">conversation page</a>.
+{email_footer}]]></string>
+</resources>

+ 40 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/disable.sql

@@ -0,0 +1,40 @@
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = 'bx_convos' LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+-- PAGES
+DELETE FROM `sys_objects_page` WHERE `module` = 'bx_convos';
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_convos' OR `object` IN('bx_convos_create_entry', 'bx_convos_edit_entry', 'bx_convos_view_entry', 'bx_convos_home');
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = 'bx_convos';
+DELETE FROM `sys_menu_sets` WHERE `module` = 'bx_convos';
+DELETE FROM `sys_menu_items` WHERE `module` = 'bx_convos' OR `set_name` IN('bx_convos_view', 'bx_convos_submenu', 'bx_convos_menu_folders_more');
+
+-- GRID
+DELETE FROM `sys_objects_grid` WHERE `object` LIKE 'bx_convos%';
+DELETE FROM `sys_grid_fields` WHERE `object` LIKE 'bx_convos%';
+DELETE FROM `sys_grid_actions` WHERE `object` LIKE 'bx_convos%';
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = 'bx_convos';
+DELETE FROM `sys_acl_actions` WHERE `Module` = 'bx_convos';
+
+
+-- LIVE UPDATES
+DELETE FROM `sys_objects_live_updates` WHERE `name` = 'bx_convos';
+
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_convos' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;
+
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = 'bx_convos';
+

+ 205 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/enable.sql

@@ -0,0 +1,205 @@
+
+-- 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_convos', '_bx_cnv', 'bx_convos@modules/boonex/convos/|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_convos', '_bx_cnv', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
+('bx_convos_preview_messages_num', '3', @iCategId, '_bx_cnv_option_preview_messages_num', 'digit', '', '', '', 1);
+
+-- PAGE: dash
+SET @iPBCellDashboard = 3;
+SET @iPBOrderDashboard = 0;
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('sys_dashboard', @iPBCellDashboard, 'bx_convos', '_bx_cnv_page_block_title_convos', 11, 2147483644, 'service', 'a:3:{s:6:"module";s:9:"bx_convos";s:6:"method";s:17:"messages_previews";s:6:"params";a:2:{i:0;i:0;i:1;b:0;}}', 0, 1, 0, @iPBOrderDashboard);
+
+
+-- 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_convos_create_entry', '_bx_cnv_page_title_sys_create_entry', '_bx_cnv_page_title_create_entry', 'bx_convos', 5, 2147483647, 1, 'start-convo', 'page.php?i=start-convo', '', '', '', 0, 1, 0, 'BxCnvPageBrowse', 'modules/boonex/convos/classes/BxCnvPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_convos_create_entry', 1, 'bx_convos', '_bx_cnv_page_block_title_create_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_convos";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_convos_edit_entry', '_bx_cnv_page_title_sys_edit_entry', '_bx_cnv_page_title_edit_entry', 'bx_convos', 5, 2147483647, 0, 'edit-convo', '', '', '', '', 0, 0, 0, 'BxCnvPageBrowse', 'modules/boonex/convos/classes/BxCnvPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_convos_edit_entry', 1, 'bx_convos', '_bx_cnv_page_block_title_edit_entry', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_convos";s:6:"method";s:11:"entity_edit";}', 0, 0, 0);
+
+-- PAGE: view entry
+
+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_convos_view_entry', 'view-convo', '_bx_cnv_page_title_sys_view_entry', '_bx_cnv_page_title_view_entry', 'bx_convos', 10, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxCnvPageEntry', 'modules/boonex/convos/classes/BxCnvPageEntry.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('bx_convos_view_entry', 1, 'bx_convos', '_bx_cnv_page_block_title_entry_breadcrumb', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:9:"bx_convos";s:6:"method";s:17:"entity_breadcrumb";}', 0, 0, 1, 0),
+('bx_convos_view_entry', 1, 'bx_convos', '_bx_cnv_page_block_title_entry_actions', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_convos\";s:6:\"method\";s:14:\"entity_actions\";}', 0, 0, 1, 1),
+('bx_convos_view_entry', 4, 'bx_convos', '_bx_cnv_page_block_title_entry_text', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_convos\";s:6:\"method\";s:17:\"entity_text_block\";}', 0, 0, 1, 0),
+('bx_convos_view_entry', 3, 'bx_convos', '_bx_cnv_page_block_title_entry_collaborators', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_convos\";s:6:\"method\";s:20:\"entity_collaborators\";}', 0, 0, 1, 0),
+('bx_convos_view_entry', 2, 'bx_convos', '_bx_cnv_page_block_title_entry_author', 13, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_convos\";s:6:\"method\";s:13:\"entity_author\";}', 0, 0, 1, 0),
+('bx_convos_view_entry', 4, 'bx_convos', '_bx_cnv_page_block_title_entry_attachments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_convos\";s:6:\"method\";s:18:\"entity_attachments\";}', 0, 0, 1, 1),
+('bx_convos_view_entry', 4, 'bx_convos', '_bx_cnv_page_block_title_entry_comments', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_convos\";s:6:\"method\";s:15:\"entity_comments\";}', 0, 0, 1, 2);
+
+
+-- 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_convos_home', '_bx_cnv_page_title_sys_folder', '_bx_cnv_page_title_folder', 'bx_convos', 5, 2147483647, 1, 'convos-folder', 'modules/?r=convos/folder/1', '', '', '', 0, 1, 0, 'BxCnvPageBrowse', 'modules/boonex/convos/classes/BxCnvPageBrowse.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
+('bx_convos_home', 1, 'bx_convos', '_bx_cnv_page_block_title_folder', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:9:"bx_convos";s:6:"method";s:23:"conversations_in_folder";s:6:"params";a:1:{i:0;s:11:"{folder_id}";}}', 0, 1, 0);
+
+
+-- 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_convos_view', '_bx_cnv_menu_title_view_entry', 'bx_convos_view', 'bx_convos', 9, 0, 1, 'BxCnvMenuView', 'modules/boonex/convos/classes/BxCnvMenuView.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_convos_view', 'bx_convos', '_bx_cnv_menu_set_title_view_entry', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('bx_convos_view', 'bx_convos', 'edit-convo', '_bx_cnv_menu_item_title_system_edit_entry', '_bx_cnv_menu_item_title_edit_entry', 'page.php?i=edit-convo&id={content_id}', '', '', 'pencil-alt', '', 2147483647, 1, 0, 1),
+('bx_convos_view', 'bx_convos', 'delete-convo', '_bx_cnv_menu_item_title_system_delete_entry', '_bx_cnv_menu_item_title_delete_entry', 'javascript:void(0);', 'bx_cnv_delete(this, \'{content_id}\')', '', 'remove', '', 2147483647, 1, 0, 2),
+('bx_convos_view', 'bx_convos', 'mark-unread-convo', '_bx_cnv_menu_item_title_system_mark_unread_entry', '_bx_cnv_menu_item_title_mark_unread_entry', 'javascript:void(0);', 'bx_cnv_mark_unread(this, \'{content_id}\')', '', 'check', '', 2147483647, 1, 0, 3);
+
+
+-- 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_convos_submenu', '_bx_cnv_menu_title_submenu', 'bx_convos_submenu', 'bx_convos', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_convos_submenu', 'bx_convos', '_bx_cnv_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_convos_submenu', 'bx_convos', 'convos-folder-inbox', '_bx_cnv_menu_item_title_system_folder_inbox', '_bx_cnv_menu_item_title_folder_inbox', 'modules/?r=convos/folder/1', '', '', '', '', 2147483647, 1, 1, 1),
+('bx_convos_submenu', 'bx_convos', 'convos-drafts', '_bx_cnv_menu_item_title_system_folder_drafts', '_bx_cnv_menu_item_title_folder_drafts', 'modules/?r=convos/folder/2', '', '', '', '', 2147483647, 1, 1, 2),
+('bx_convos_submenu', 'bx_convos', 'convos-spam', '_bx_cnv_menu_item_title_system_folder_spam', '_bx_cnv_menu_item_title_folder_spam', 'modules/?r=convos/folder/3', '', '', '', '', 2147483647, 1, 1, 3),
+('bx_convos_submenu', 'bx_convos', 'convos-trash', '_bx_cnv_menu_item_title_system_folder_trash', '_bx_cnv_menu_item_title_folder_trash', 'modules/?r=convos/folder/4', '', '', '', '', 2147483647, 1, 1, 4);
+-- ('bx_convos_submenu', 'bx_convos', 'convos-folder-more', '_bx_cnv_menu_item_title_system_folder_more', '_bx_cnv_menu_item_title_folder_more', 'javascript:void(0);', 'bx_menu_popup(''bx_convos_menu_folders_more'', this);', '', '', '', 2147483647, 1, 1, 5)
+
+-- TODO: Remove it completely if 'more' menu item isn't needed.
+-- MENU: more folders
+-- INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+-- ('bx_convos_menu_folders_more', '_bx_cnv_menu_title_folders_more', 'bx_convos_menu_folders_more', 'bx_convos', 4, 0, 1, '', '');
+
+-- INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+-- ('bx_convos_menu_folders_more', 'bx_convos', '_bx_cnv_menu_set_title_folders_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_convos_menu_folders_more', 'bx_convos', 'convos-drafts', '_bx_cnv_menu_item_title_system_folder_drafts', '_bx_cnv_menu_item_title_folder_drafts', 'modules/?r=convos/folder/2', '', '', '', '', 2147483647, 1, 1, 1);
+
+
+-- MENU: notifications
+SET @iMIOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name` = 'sys_account_notifications' AND `order` < 9999);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES
+('sys_account_notifications', 'bx_convos', 'notifications-convos', '_bx_cnv_menu_item_title_system_convos', '_bx_cnv_menu_item_title_convos', 'modules/?r=convos/folder/1', '', '', 'comments col-red1', 'a:2:{s:6:"module";s:9:"bx_convos";s:6:"method";s:23:"get_unread_messages_num";}', '', 2147483646, 1, 0, @iMIOrder + 1);
+
+
+-- MENU: profile stats
+
+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_convos', 'profile-stats-unread-messages', '_bx_cnv_menu_item_title_system_unread_messages', '_bx_cnv_menu_item_title_unread_messages', 'modules/?r=convos/folder/1', '', '', 'comments col-red1', 'a:2:{s:6:"module";s:9:"bx_convos";s:6:"method";s:23:"get_unread_messages_num";}', '', 2147483646, 1, 0, 2);
+
+-- MENU: add menu item to profiles modules actions menu (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_actions', 'bx_convos', 'convos-compose', '_bx_cnv_menu_item_title_system_message', '_bx_cnv_menu_item_title_message', 'page.php?i=start-convo&profiles={profile_id}', '', '', 'envelope', '', 2147483646, 1, 0, 0),
+('trigger_group_view_actions', 'bx_convos', 'convos-compose', '_bx_cnv_menu_item_title_system_message_group', '_bx_cnv_menu_item_title_message_group', 'page.php?i=start-convo&profiles={recipients}', '', '', 'envelope', '', 2147483646, 1, 0, 0);
+
+-- GRID
+
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_mode`, `sorting_fields`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_convos', 'Sql', 'SELECT `c`.`id`, `c`.`author`, `c`.`text`, `c`.`added`, `c`.`comments`, `f`.`read_comments`, `last_reply_timestamp`, `last_reply_profile_id`, `cmt`.`cmt_text` FROM `bx_convos_conversations` AS `c` INNER JOIN `bx_convos_conv2folder` AS `f` ON (`c`.`id` = `f`.`conv_id` AND `f`.`folder_id` = {folder_id} AND `f`.`collaborator` = {profile_id}) LEFT JOIN `bx_convos_cmts` AS `cmt` ON (`cmt`.`cmt_id` = `c`.`last_reply_comment_id`)', 'bx_convos_conversations', 'id', 'last_reply_timestamp', '', 10, NULL, 'start', '', 'text', 'auto', 'comments,last_reply_timestamp', 2147483646, 'BxCnvGrid', 'modules/boonex/convos/classes/BxCnvGrid.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `params`, `order`) VALUES
+('bx_convos', 'checkbox', '_sys_select', '2%', '', 1),
+('bx_convos', 'collaborators', '_bx_cnv_field_collaborators', '25%', '', 2),
+('bx_convos', 'last_reply_timestamp', '_bx_cnv_field_preview', '68%', '', 3),
+('bx_convos', 'comments', '_bx_cnv_field_comments', '5%', '', 4);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `confirm`, `order`) VALUES
+('bx_convos', 'bulk', 'delete', '_bx_cnv_grid_action_delete', '', 1, 1),
+('bx_convos', 'independent', 'add', '_bx_cnv_grid_action_compose', '', 0, 1);
+
+
+-- ACL
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_convos', 'create entry', NULL, '_bx_cnv_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_convos', 'delete entry', NULL, '_bx_cnv_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_convos', 'view entry', NULL, '_bx_cnv_acl_action_view_entry', '', 1, 0);
+SET @iIdActionEntryView = 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 view
+(@iUnauthenticated, @iIdActionEntryView),
+(@iAccount, @iIdActionEntryView),
+(@iStandard, @iIdActionEntryView),
+(@iUnconfirmed, @iIdActionEntryView),
+(@iPending, @iIdActionEntryView),
+(@iModerator, @iIdActionEntryView),
+(@iAdministrator, @iIdActionEntryView),
+(@iPremium, @iIdActionEntryView);
+
+
+-- LIVE UPDATES
+INSERT INTO `sys_objects_live_updates`(`name`, `frequency`, `service_call`, `active`) VALUES
+('bx_convos', 1, 'a:3:{s:6:"module";s:9:"bx_convos";s:6:"method";s:16:"get_live_updates";s:6:"params";a:3:{i:0;a:2:{s:11:"menu_object";s:18:"sys_toolbar_member";s:9:"menu_item";s:7:"account";}i:1;a:2:{s:11:"menu_object";s:25:"sys_account_notifications";s:9:"menu_item";s:20:"notifications-convos";}i:2;s:7:"{count}";}}', 1);
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_convos', 'BxCnvAlertsResponse', 'modules/boonex/convos/classes/BxCnvAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('bx_convos', 'commentPost', @iHandler),
+('bx_convos', 'commentRemoved', @iHandler),
+('profile', 'delete', @iHandler);
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+('bx_convos', '_bx_cnv_email_new_message', 'bx_cnv_new_message', '_bx_cnv_email_new_message_subject', '_bx_cnv_email_new_message_body'),
+('bx_convos', '_bx_cnv_email_new_reply', 'bx_cnv_new_reply', '_bx_cnv_email_new_reply_subject', '_bx_cnv_email_new_reply_body');

+ 200 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/install.sql

@@ -0,0 +1,200 @@
+
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: entries
+
+CREATE TABLE IF NOT EXISTS `bx_convos_conversations` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `author` int(10) unsigned NOT NULL,
+  `added` int(11) NOT NULL,
+  `changed` int(11) NOT NULL,
+  `text` text NOT NULL,
+  `allow_edit` tinyint(4) NOT NULL DEFAULT '0',
+  `views` int(11) NOT NULL default '0',
+  `comments` int(11) NOT NULL default '0',
+  `last_reply_timestamp` int(11) NOT NULL,
+  `last_reply_profile_id` int(10) unsigned NOT NULL,
+  `last_reply_comment_id` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `last_reply_timestamp` (`last_reply_timestamp`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_convos_conv2folder` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `conv_id` int(10) unsigned NOT NULL,
+  `folder_id` int(10) unsigned NOT NULL,
+  `collaborator` int(10) unsigned NOT NULL,
+  `read_comments` int(11) NOT NULL default '-1',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `collaborator_folder_conv` (`collaborator`,`folder_id`, `conv_id`),
+  KEY `conv_id` (`conv_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_convos_folders` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `author` int(10) unsigned NOT NULL,
+  `name` varchar(255) NOT NULL DEFAULT '',
+  PRIMARY KEY (`id`),
+  KEY `author` (`author`)
+);
+
+INSERT INTO `bx_convos_folders` (`id`, `author`, `name`) VALUES
+(1, 0, '_bx_cnv_folder_inbox'),
+(2, 0, '_bx_cnv_folder_drafts'),
+(3, 0, '_bx_cnv_folder_spam'),
+(4, 0, '_bx_cnv_folder_trash');
+
+-- TABLE: storages & transcoders
+
+CREATE TABLE IF NOT EXISTS `bx_convos_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` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_convos_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` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+-- TABLE: comments
+
+CREATE TABLE IF NOT EXISTS `bx_convos_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',
+  PRIMARY KEY (`cmt_id`),
+  KEY `cmt_object_id` (`cmt_object_id`,`cmt_parent_id`),
+  FULLTEXT KEY `search_fields` (`cmt_text`)
+);
+
+-- TABLE: views
+
+CREATE TABLE `bx_convos_views_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- 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_convos_files', @sStorageEngine, '', 360, 2592000, 3, 'bx_convos_files', 'deny-allow', '', 'action,apk,app,bat,bin,cmd,com,command,cpl,csh,exe,gadget,inf,ins,inx,ipa,isu,job,jse,ksh,lnk,msc,msi,msp,mst,osx,out,paf,pif,prg,ps1,reg,rgs,run,sct,shb,shs,u3p,vb,vbe,vbs,vbscript,workflow,ws,wsf', 0, 0, 0, 0, 0, 0),
+('bx_convos_photos_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_convos_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_convos_preview', 'bx_convos_photos_resized', 'Storage', 'a:1:{s:6:"object";s:15:"bx_convos_files";}', 'no', '1', '2592000', '0');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_convos_preview', 'Resize', 'a:3:{s:1:"w";s:3:"300";s:1:"h";s:3:"200";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_convos', 'bx_convos', '_bx_cnv_form_entry', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_convos_conversations', 'id', '', '', 'do_submit', '', 0, 1, 'BxCnvFormEntry', 'modules/boonex/convos/classes/BxCnvFormEntry.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_convos', 'bx_convos_entry_add', 'bx_convos', 0, '_bx_cnv_form_entry_display_add'),
+('bx_convos', 'bx_convos_entry_edit', 'bx_convos', 0, '_bx_cnv_form_entry_display_edit'),
+('bx_convos', 'bx_convos_entry_delete', 'bx_convos', 0, '_bx_cnv_form_entry_display_delete'),
+('bx_convos', 'bx_convos_entry_view', 'bx_convos', 1, '_bx_cnv_form_entry_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`) VALUES 
+('bx_convos', 'bx_convos', 'allow_edit', 1, '', 0, 'switcher', '_bx_cnv_form_entry_input_sys_allow_edit', '_bx_cnv_form_entry_input_allow_edit', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_convos', 'bx_convos', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_cnv_form_entry_input_sys_delete_confirm', '_bx_cnv_form_entry_input_delete_confirm', '_bx_cnv_form_entry_input_delete_confirm_info', 1, 0, 0, '', '', '', 'Avail', '', '_bx_cnv_form_entry_input_delete_confirm_error', '', '', 1, 0),
+('bx_convos', 'bx_convos', 'do_submit', '_bx_cnv_form_entry_input_do_submit', '', 0, 'submit', '_bx_cnv_form_entry_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_convos', 'bx_convos', 'submit_text', '', '', 0, 'custom', '_bx_cnv_form_entry_input_sys_submit_text', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_convos', 'bx_convos', 'submit_block', '', 'do_submit,submit_text', 0, 'input_set', '_bx_cnv_form_entry_input_sys_submit_block', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_convos', 'bx_convos', 'draft_id', '0', '', 0, 'hidden', '_bx_cnv_form_entry_input_sys_draft_id', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_convos', 'bx_convos', 'text', '', '', 0, 'textarea', '_bx_cnv_form_entry_input_sys_text', '_bx_cnv_form_entry_input_text', '', 1, 0, 2, '', '', '', 'Avail', '', '_bx_cnv_form_entry_input_text_err', 'XssHtml', '', 1, 0),
+('bx_convos', 'bx_convos', 'recipients', '', '', 0, 'custom', '_bx_cnv_form_entry_input_sys_recipients', '_bx_cnv_form_entry_input_recipients', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_cnv_form_entry_input_recipients_err', '', '', 1, 0),
+('bx_convos', 'bx_convos', 'attachments', 'a:1:{i:0;s:9:"sys_html5";}', 'a:2:{s:10:"sys_simple";s:26:"_sys_uploader_simple_title";s:9:"sys_html5";s:25:"_sys_uploader_html5_title";}', 0, 'files', '_bx_cnv_form_entry_input_sys_attachments', '_bx_cnv_form_entry_input_attachments', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_convos_entry_add', 'delete_confirm', 2147483647, 0, 0),
+('bx_convos_entry_add', 'recipients', 2147483647, 1, 1),
+('bx_convos_entry_add', 'text', 2147483647, 1, 2),
+('bx_convos_entry_add', 'attachments', 2147483647, 1, 3),
+('bx_convos_entry_add', 'allow_edit', 2147483647, 1, 4),
+('bx_convos_entry_add', 'submit_block', 2147483647, 1, 5),
+('bx_convos_entry_add', 'do_submit', 2147483647, 1, 6),
+('bx_convos_entry_add', 'submit_text', 2147483647, 1, 7),
+('bx_convos_entry_add', 'draft_id', 2147483647, 1, 8),
+
+('bx_convos_entry_edit', 'delete_confirm', 2147483647, 0, 1),
+('bx_convos_entry_edit', 'recipients', 2147483647, 1, 2),
+('bx_convos_entry_edit', 'text', 2147483647, 1, 3),
+('bx_convos_entry_edit', 'attachments', 2147483647, 1, 4),
+('bx_convos_entry_edit', 'allow_edit', 2147483647, 1, 5),
+('bx_convos_entry_edit', 'submit_block', 2147483647, 1, 6),
+('bx_convos_entry_edit', 'do_submit', 2147483647, 1, 7),
+('bx_convos_entry_edit', 'submit_text', 2147483647, 0, 8),
+('bx_convos_entry_edit', 'draft_id', 2147483647, 0, 9),
+
+('bx_convos_entry_view', 'delete_confirm', 2147483647, 0, 0),
+('bx_convos_entry_view', 'do_submit', 2147483647, 0, 0),
+('bx_convos_entry_view', 'recipients', 2147483647, 0, 0),
+('bx_convos_entry_view', 'text', 2147483647, 0, 0),
+('bx_convos_entry_view', 'attachments', 2147483647, 0, 0),
+
+('bx_convos_entry_delete', 'delete_confirm', 2147483647, 1, 1),
+('bx_convos_entry_delete', 'do_submit', 2147483647, 1, 2),
+('bx_convos_entry_delete', 'attachments', 2147483647, 0, 0),
+('bx_convos_entry_delete', 'recipients', 2147483647, 0, 0),
+('bx_convos_entry_delete', 'text', 2147483647, 0, 0);
+
+
+-- 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_convos', 'bx_convos', 'bx_convos_cmts', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=view-convo&id={object_id}', '', 'bx_convos_conversations', 'id', 'author', 'text', 'comments', 'BxCnvCmts', 'modules/boonex/convos/classes/BxCnvCmts.php');
+
+
+-- 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_convos', 'bx_convos_views_track', '86400', '1', 'bx_convos_conversations', 'id', 'author', 'views', '', '');
+
+
+-- STUDIO: page & widget
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_convos', '_bx_cnv', '_bx_cnv', 'bx_convos@modules/boonex/convos/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_convos', '{url_studio}module.php?name=bx_convos', '', 'bx_convos@modules/boonex/convos/|std-icon.svg', '_bx_cnv', '', '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));
+

+ 35 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/install/sql/uninstall.sql

@@ -0,0 +1,35 @@
+
+-- TABLES: entries
+
+DROP TABLE IF EXISTS `bx_convos_conversations`, `bx_convos_conv2folder`, `bx_convos_folders`, `bx_convos_files`, `bx_convos_photos_resized`, `bx_convos_cmts`, `bx_convos_views_track`;
+
+-- STORAGES & TRANSCODERS
+
+DELETE FROM `sys_objects_storage` WHERE `object` = 'bx_convos_files' OR `object` = 'bx_convos_photos_resized';
+DELETE FROM `sys_storage_tokens` WHERE `object` = 'bx_convos_files' OR `object` = 'bx_convos_photos_resized';
+
+DELETE FROM `sys_objects_transcoder` WHERE `object` = 'bx_convos_preview';
+DELETE FROM `sys_transcoder_filters` WHERE `transcoder_object` = 'bx_convos_preview';
+DELETE FROM `sys_transcoder_images_files` WHERE `transcoder_object` = 'bx_convos_preview';
+
+-- FORMS
+
+DELETE FROM `sys_objects_form` WHERE `module` = 'bx_convos';
+DELETE FROM `sys_form_displays` WHERE `module` = 'bx_convos';
+DELETE FROM `sys_form_inputs` WHERE `module` = 'bx_convos';
+DELETE FROM `sys_form_display_inputs` WHERE `display_name` IN('bx_convos_entry_add', 'bx_convos_entry_edit', 'bx_convos_entry_view', 'bx_convos_entry_delete');
+
+
+-- COMMENTS
+DELETE FROM `sys_objects_cmts` WHERE `Name` = 'bx_convos';
+
+
+-- VIEWS
+DELETE FROM `sys_objects_view` WHERE `Name` = 'bx_convos';
+
+
+-- STUDIO: page & widget
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = 'bx_convos';
+

+ 57 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/js/manage_tools.js

@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Convos Convos
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxCnvManageTools(oOptions) {
+	this._iSearchTimeoutId = false;
+	this._sActionsUrl = oOptions.sActionUrl;
+	this._sObjNameGrid = oOptions.sObjNameGrid;
+	this._sObjName = oOptions.sObjName == undefined ? 'oBxCnvManageTools' : oOptions.sObjName;
+
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this._sParamsDivider = oOptions.sParamsDivider == undefined ? '#-#' : oOptions.sParamsDivider;
+
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+}
+
+BxCnvManageTools.prototype.onChangeFilter = function (oFilter) {
+    var $this = this;
+    console.log($this._sObjNameGrid+"vcb");
+	var oFilter1 = $('#bx-grid-filter1-' + this._sObjNameGrid);
+	var sValueFilter1 = oFilter1.length > 0 ? oFilter1.val() : '';
+
+	var oSearch = $('#bx-grid-search-' + this._sObjNameGrid);
+	var sValueSearch = oSearch.length > 0 ? oSearch.val() : '';
+	if(sValueSearch == _t('_sys_grid_search'))
+		sValueSearch = '';
+
+	clearTimeout($this._iSearchTimeoutId);
+    $this._iSearchTimeoutId = setTimeout(function () {
+        glGrids[$this._sObjNameGrid].setFilter(sValueFilter1 + $this._sParamsDivider + sValueSearch, true);
+    }, 500);
+};
+
+BxCnvManageTools.prototype.onClickSettings = function (sMenuObject, oButton) {
+	if($(oButton).hasClass('bx-btn-disabled'))
+		return false;
+
+	bx_menu_popup(sMenuObject, oButton, {}, {
+		content_id: $(oButton).attr('bx_grid_action_data')
+	});
+};
+
+BxCnvManageTools.prototype.onClickDelete = function (iContentId) {
+	$('.bx-popup-applied:visible').dolPopupHide();
+
+	glGrids[this._sObjNameGrid].actionWithId(iContentId, 'delete', {}, '', false, 1);
+};
+
+/** @} */

+ 1 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/template/css/manage_tools.css

@@ -0,0 +1 @@
+@import url(../../../../base/general/template/css/manage_tools.css);

+ 46 - 0
modules/boonex/convos/updates/9.0.14_10.0.0/source/template/images/icons/std-icon.svg

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 55 (78076) - https://sketchapp.com -->
+    <title>conversations</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M32,64 C46.0222222,64 53.8173667,64 58.9086889,58.9086889 C64,53.8173667 64,46.0222222 64,32 C64,17.9777778 64,10.1826333 58.9086889,5.09131111 C53.8173667,0 46.0222222,0 32,0 C17.9777778,0 10.1826333,0 5.09131111,5.09131111 C0,10.1826333 0,17.9777778 0,32 C0,46.0222222 0,53.8173667 5.09131111,58.9086889 C10.1826333,64 17.9777778,64 32,64 Z" id="path-1"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
+            <stop stop-color="#FDFEFF" offset="0%"></stop>
+            <stop stop-color="#FBFCFD" stop-opacity="0.9" offset="100%"></stop>
+        </linearGradient>
+        <filter x="-12.8%" y="-10.3%" width="125.6%" height="125.6%" filterUnits="objectBoundingBox" id="filter-4">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
+            <feMerge>
+                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
+                <feMergeNode in="SourceGraphic"></feMergeNode>
+            </feMerge>
+        </filter>
+        <path d="M34.125,0 L4.875,0 C2.18613281,0 0,2.18600503 0,4.87471504 L0,26.8109327 C0,29.4996428 2.18613281,31.6856478 4.875,31.6856478 L12.1875,31.6856478 L12.1875,38.0837113 C12.1875,38.830152 13.040625,39.2643063 13.6423828,38.8225353 L23.15625,31.6856478 L34.125,31.6856478 C36.8138672,31.6856478 39,29.4996428 39,26.8109327 L39,4.87471504 C39,2.18600503 36.8138672,0 34.125,0 Z M21.9375,20.1081996 C21.9375,20.4433362 21.6632812,20.7175389 21.328125,20.7175389 L10.359375,20.7175389 C10.0242187,20.7175389 9.75,20.4433362 9.75,20.1081996 L9.75,18.8895208 C9.75,18.5543841 10.0242187,18.2801814 10.359375,18.2801814 L21.328125,18.2801814 C21.6632812,18.2801814 21.9375,18.5543841 21.9375,18.8895208 L21.9375,20.1081996 Z M29.25,12.796127 C29.25,13.1312637 28.9757812,13.4054664 28.640625,13.4054664 L10.359375,13.4054664 C10.0242187,13.4054664 9.75,13.1312637 9.75,12.796127 L9.75,11.5774482 C9.75,11.2423116 10.0242187,10.9681088 10.359375,10.9681088 L28.640625,10.9681088 C28.9757812,10.9681088 29.25,11.2423116 29.25,11.5774482 L29.25,12.796127 Z" id="path-5"></path>
+        <filter x="-5.1%" y="-2.6%" width="110.3%" height="110.3%" filterUnits="objectBoundingBox" id="filter-6">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="0.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Artboard" transform="translate(-1150.000000, -430.000000)">
+            <g id="conversations" transform="translate(1150.000000, 430.000000)">
+                <mask id="mask-2" fill="white">
+                    <use xlink:href="#path-1"></use>
+                </mask>
+                <use id="Path" fill="#00B356" xlink:href="#path-1"></use>
+                <g id="comment-alt-lines" filter="url(#filter-4)" mask="url(#mask-2)" fill-rule="nonzero">
+                    <g transform="translate(13.000000, 15.000000)" id="Shape">
+                        <g>
+                            <use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
+                            <use fill="url(#linearGradient-3)" xlink:href="#path-5"></use>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 128 - 0
modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/studio/scripts/BxTemplStudioFormsField.php

@@ -0,0 +1,128 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaStudioView UNA Studio Representation classes
+ * @ingroup     UnaStudio
+ * @{
+ */
+defined('BX_DOL') or die('hack attempt');
+
+class BxTemplStudioFormsField extends BxBaseStudioFormsField
+{
+}
+
+class BxTemplStudioFormsFieldBlockHeader extends BxBaseStudioFormsFieldBlockHeader
+{
+}
+
+class BxTemplStudioFormsFieldBlockEnd extends BxBaseStudioFormsFieldBlockEnd
+{
+}
+
+class BxTemplStudioFormsFieldValue extends BxBaseStudioFormsFieldValue
+{
+}
+
+class BxTemplStudioFormsFieldText extends BxBaseStudioFormsFieldText
+{
+}
+
+class BxTemplStudioFormsFieldPassword extends BxBaseStudioFormsFieldPassword
+{
+}
+
+class BxTemplStudioFormsFieldTextarea extends BxBaseStudioFormsFieldTextarea
+{
+}
+
+class BxTemplStudioFormsFieldNumber extends BxBaseStudioFormsFieldNumber
+{
+}
+
+class BxTemplStudioFormsFieldDatepicker extends BxBaseStudioFormsFieldDatepicker
+{
+}
+
+class BxTemplStudioFormsFieldDatetime extends BxBaseStudioFormsFieldDatetime
+{
+}
+
+class BxTemplStudioFormsFieldCheckbox extends BxBaseStudioFormsFieldCheckbox
+{
+}
+
+class BxTemplStudioFormsFieldSwitcher extends BxBaseStudioFormsFieldSwitcher
+{
+}
+
+class BxTemplStudioFormsFieldFile extends BxBaseStudioFormsFieldFile
+{
+}
+
+class BxTemplStudioFormsFieldFiles extends BxBaseStudioFormsFieldFiles
+{
+}
+
+class BxTemplStudioFormsFieldSlider extends BxBaseStudioFormsFieldSlider
+{
+}
+
+class BxTemplStudioFormsFieldDoublerange extends BxBaseStudioFormsFieldDoublerange
+{
+}
+
+class BxTemplStudioFormsFieldHidden extends BxBaseStudioFormsFieldHidden
+{
+}
+
+class BxTemplStudioFormsFieldButton extends BxBaseStudioFormsFieldButton
+{
+}
+
+class BxTemplStudioFormsFieldReset extends BxBaseStudioFormsFieldReset
+{
+}
+
+class BxTemplStudioFormsFieldSubmit extends BxBaseStudioFormsFieldSubmit
+{
+}
+
+class BxTemplStudioFormsFieldImage extends BxBaseStudioFormsFieldImage
+{
+}
+
+class BxTemplStudioFormsFieldSelect extends BxBaseStudioFormsFieldSelect
+{
+}
+
+class BxTemplStudioFormsFieldSelectMultiple extends BxBaseStudioFormsFieldSelectMultiple
+{
+}
+
+class BxTemplStudioFormsFieldCheckboxSet extends BxBaseStudioFormsFieldCheckboxSet
+{
+}
+
+class BxTemplStudioFormsFieldRadioSet extends BxBaseStudioFormsFieldRadioSet
+{
+}
+
+class BxTemplStudioFormsFieldCustom extends BxBaseStudioFormsFieldCustom
+{
+}
+
+class BxTemplStudioFormsFieldInputSet extends BxBaseStudioFormsFieldInputSet
+{
+}
+
+class BxTemplStudioFormsFieldCaptcha extends BxBaseStudioFormsFieldCaptcha
+{
+}
+
+class BxTemplStudioFormsFieldLocation extends BxBaseStudioFormsFieldLocation
+{
+}
+
+/** @} */

+ 19 - 0
modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/studio/scripts/BxTemplStudioFormsLabels.php

@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaStudioView UNA Studio Representation classes
+ * @ingroup     UnaStudio
+ * @{
+ */
+defined('BX_DOL') or die('hack attempt');
+
+class BxTemplStudioFormsLabels extends BxBaseStudioFormsLabels
+{
+    function __construct($aOptions, $oTemplate = false)
+    {
+        parent::__construct($aOptions, $oTemplate);
+    }
+}
+/** @} */

+ 42 - 0
modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/_header_js_custom.html

@@ -0,0 +1,42 @@
+<script type="text/javascript" language="javascript">
+    $(document).ready(function () {
+        bx_activate_anim_icons('#283c50');
+
+        //responsive template
+        var mainContent = $('.cd-main-content'),
+            header = $('.cd-main-header'),
+            sidebar = $('.cd-side-nav'),
+            sidebarTrigger = $('.cd-nav-trigger');
+
+        //on window scrolling - fix sidebar nav
+        var scrolling = false;
+        checkScrollbarPosition();
+        $(window).on('scroll', function(){
+            if( !scrolling ) {
+                (!window.requestAnimationFrame) ? setTimeout(checkScrollbarPosition, 300) : window.requestAnimationFrame(checkScrollbarPosition);
+                scrolling = true;
+            }
+        });
+
+        //mobile only - open sidebar when user clicks the hamburger menu
+        sidebarTrigger.on('click', function(event){
+            event.preventDefault();
+            sidebar.toggleClass('nav-is-visible');
+            sidebarTrigger.toggleClass('bx-menu-tab-active');
+        });
+
+        function checkScrollbarPosition() {
+            var mq = checkMQ();
+            
+            if( mq != 'mobile' ) {
+                var sidebarHeight = sidebar.outerHeight(),
+                    windowHeight = $(window).height(),
+                    mainContentHeight = mainContent.outerHeight(),
+                    scrollTop = $(window).scrollTop();
+
+                ( ( scrollTop + windowHeight > sidebarHeight ) && ( mainContentHeight - sidebarHeight != 0 ) ) ? sidebar.addClass('is-fixed').css('bottom', 0) : sidebar.removeClass('is-fixed').attr('style', '');
+            }
+            scrolling = false;
+        }
+    });
+</script>

+ 45 - 0
modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/_sub_footer.html

@@ -0,0 +1,45 @@
+						
+						                <bx_injection:injection_content_after />
+						
+						                <div class="bx-clear"></div>
+						
+						            <bx_injection:banner_bottom />
+						
+						        </div> <!-- #bx-content-main -->
+						
+						        <bx_injection:injection_between_content_footer />
+						
+						    </div> <!-- #bx-content-container -->
+						
+						</div>
+				
+					</div> <!-- #bx-content-wrapper -->
+	
+	                <div id="bx-footer-wrapper" class="bx-footer-wrapper bx-def-image-bg-footer bx-def-color-bg-footer bx-def-border-footer bx-shadow-footer">    
+                            <div class="bx-def-centered bx-def-padding-sec-leftright bx-def-box-sizing">
+                                <div id="bx-footer" class="bx-footer bx-def-padding-sec-left bx-def-padding-sec-right bx-clearfix">
+                                    <div class="bx-footer-cnt bx-content-padding-footer">
+                                        <bx_injection:injection_footer_before />
+
+                                        <div id="bx-menu-bottom">
+                                            <bx_menu:sys_footer />
+                                        </div>
+
+                                        <bx_injection:injection_footer_after />
+                                    </div>
+                                </div>
+                            </div>
+	                </div>
+	
+		        </div> <!-- .content-wrapper -->
+	
+	        </div> <!-- .content-wrapper-wrp -->
+	
+	    </div> <!-- .cd-main-content -->
+
+    </div> <!-- .cd-main-content-wrp -->
+
+	<bx_menu:sys_site_action />
+</div>
+
+<bx_include_auto:_footer.html />

+ 52 - 0
modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/_sub_header.html

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

+ 889 - 0
modules/boonex/decorous/updates/9.0.7_10.0.0/source/data/template/system/css/default.less

@@ -0,0 +1,889 @@
+@import '../../../../../../../template/css/default.less';
+
+/* viewport */
+
+html.bx-media-tablet {
+    font-size: @bx-viewport-font-tablet !important;
+}
+
+html.bx-media-phone {
+    font-size: @bx-viewport-font-mobile !important;
+}
+
+/* height */
+.bx-header {
+	height: @bx-height-header !important;
+}
+.cd-side-nav,
+.cd-main-content .content-wrapper {
+    padding-top: @bx-height-header;
+}
+
+
+/* content paddings */
+.bx-content-padding-header {
+	padding: @bx-content-padding-header;
+}
+.bx-content-padding-footer {
+	padding: @bx-content-padding-footer;
+}
+.bx-content-padding-block {
+	padding: @bx-content-padding-block;
+}
+
+
+/* shadow */
+.bx-shadow-header {
+    -webkit-box-shadow: @bx-shadow-header;
+    -moz-box-shadow: @bx-shadow-header;
+    box-shadow: @bx-shadow-header;
+}
+.bx-shadow-footer {
+    -webkit-box-shadow: @bx-shadow-footer;
+    -moz-box-shadow: @bx-shadow-footer;
+    box-shadow: @bx-shadow-footer;
+}
+.bx-shadow-block {
+    -webkit-box-shadow: @bx-shadow-block;
+    -moz-box-shadow: @bx-shadow-block;
+    box-shadow: @bx-shadow-block;
+}
+.bx-def-box {
+    -webkit-box-shadow: @bx-shadow-card;
+    -moz-box-shadow: @bx-shadow-card;
+    box-shadow: @bx-shadow-card;
+}
+.bx-popup-applied {
+    border-radius: @bx-border-radius-popup;
+    background-clip: padding-box;
+}
+.bx-popup-applied:not(.bx-popup-chain),
+.bx-popup-applied.bx-popup-chain .bx-popup-chain-item {
+    -webkit-box-shadow: @bx-shadow-popup;
+    -moz-box-shadow: @bx-shadow-popup;
+    box-shadow: @bx-shadow-popup;
+}
+.bx-popup-applied.bx-popup-chain .bx-popup-chain-item a:hover {
+    background-color: @bx-color-hl;
+}
+.bx-popup-wrapper.bx-popup-slide-wrapper {
+    -webkit-box-shadow: @bx-shadow-menu-slide;
+    -moz-box-shadow: @bx-shadow-menu-slide;
+    box-shadow: @bx-shadow-menu-slide;
+}
+.bx-btn {
+    -webkit-box-shadow: @bx-shadow-button;
+    -moz-box-shadow: @bx-shadow-button;
+    box-shadow: @bx-shadow-button;
+}
+.bx-btn.bx-btn-small {
+    -webkit-box-shadow: @bx-shadow-button-small;
+    -moz-box-shadow: @bx-shadow-button-small;
+    box-shadow: @bx-shadow-button-small;
+}
+
+
+/* background images */
+.bx-def-image-bg-header,
+.bx-def-image-bg-footer,
+.bx-def-image-bg-page,
+.bx-def-image-bg-block,
+.bx-def-box,
+.bx-popup-color-bg,
+.bx-popup-wrapper.bx-popup-slide-wrapper,
+#bx-sliding-menu-sys_site.bx-sliding-smenu-main,
+#bx-sliding-menu-sys_add_content.bx-sliding-menu-main,
+#bx-sliding-menu-account.bx-sliding-menu-main,
+.bx-menu-main-bar-wrapper {
+    background-position: center center;
+}
+.bx-def-image-bg-header {
+	background-image: @bx-image-bg-header;
+	background-repeat: @bx-image-bg-header-repeat;
+	background-attachment: @bx-image-bg-header-attachment;
+    background-size: @bx-image-bg-header-size;
+}
+.bx-def-image-bg-footer {
+	background-image: @bx-image-bg-footer;
+	background-repeat: @bx-image-bg-footer-repeat;
+	background-attachment: @bx-image-bg-footer-attachment;
+    background-size: @bx-image-bg-footer-size;
+}
+.bx-def-image-bg-page {
+	background-image: @bx-image-bg-page;
+	background-repeat: @bx-image-bg-page-repeat;
+	background-attachment: @bx-image-bg-page-attachment;
+    background-size: @bx-image-bg-page-size;
+}
+.bx-def-image-bg-block {
+	background-image: @bx-image-bg-block;
+	background-repeat: @bx-image-bg-block-repeat;
+	background-attachment: @bx-image-bg-block-attachment;
+    background-size: @bx-image-bg-block-size;
+}
+.bx-def-box {
+	background-image: @bx-image-bg-box;
+	background-repeat: @bx-image-bg-box-repeat;
+	background-attachment: @bx-image-bg-box-attachment;
+    background-size: @bx-image-bg-box-size;
+}
+
+/* body */
+a {
+	color: @bx-color-link-body; 
+}
+a:hover {
+	color: @bx-color-link-body-hover; 
+}
+.sys-icon:not(.sys-colored),
+.sys-icon-a:not(.sys-colored) {
+    color: @bx-color-icon-body; 
+}
+a:hover > .sys-icon:not(.sys-colored),
+a:hover > .sys-icon-a:not(.sys-colored) {
+	color: @bx-color-icon-body-hover; 
+}
+.sys-icon-a i {
+	.background-color (@bx-color-icon-body) !important;
+	color: @bx-color-icon-body;
+}
+a:hover > .sys-icon-a i {
+	.background-color (@bx-color-icon-body-hover) !important;
+	color: @bx-color-icon-body-hover;
+}
+
+/* header */
+.bx-header.bx-def-color-bg-header {
+    .background-color (@bx-color-header);
+}
+.bx-header.bx-def-border-header {
+    border-bottom-width: @bx-border-width-header;
+    border-bottom-style: @bx-border-type;
+    border-bottom-color: @bx-color-border-header;
+}
+.bx-header a {
+	color: @bx-color-link-header; 
+}
+.bx-header a:hover {
+	color: @bx-color-link-header-hover;
+}
+.bx-header .sys-icon,
+.bx-header .sys-icon-a {
+	color: @bx-color-icon-header; 
+}
+.bx-header .cd-nav-trigger span, 
+.bx-header .cd-nav-trigger span::before, 
+.bx-header .cd-nav-trigger span::after,
+.bx-header .cd-nav-trigger.nav-is-visible span::before, 
+.bx-header .cd-nav-trigger.nav-is-visible span::after {
+    background: @bx-color-icon-header;
+}
+.bx-header a:hover .sys-icon,
+.bx-header a:hover .sys-icon-a {
+	color: @bx-color-icon-header-hover; 
+}
+.bx-header .cd-nav-trigger.nav-is-visible:hover span {
+  background: rgba(255, 255, 255, 0);
+}
+.bx-header .cd-nav-trigger:hover span, 
+.bx-header .cd-nav-trigger:hover span::before, 
+.bx-header .cd-nav-trigger:hover span::after,
+.bx-header .cd-nav-trigger.nav-is-visible:hover span::before, 
+.bx-header .cd-nav-trigger.nav-is-visible:hover span::after {
+    background: @bx-color-icon-header-hover;
+}
+.bx-header .sys-icon-a i {
+	.background-color (@bx-color-icon-header) !important;
+	color: @bx-color-icon-header;
+}
+.bx-header a:hover .sys-icon-a i {
+	.background-color (@bx-color-icon-header-hover) !important;
+	color: @bx-color-icon-header-hover;
+}
+
+/* footer */
+.bx-footer-wrapper.bx-def-color-bg-footer {
+    .background-color (@bx-color-footer);    
+}
+.bx-footer-wrapper.bx-def-border-footer {
+    border-top-width: @bx-border-width-footer;
+    border-top-style: @bx-border-type;
+    border-top-color: @bx-color-border-footer;
+}
+
+.bx-footer {
+	color: @bx-font-color-footer;
+}
+.bx-footer a {
+	color: @bx-color-link-footer; 
+}
+.bx-footer a:hover {
+	color: @bx-color-link-footer-hover; 
+}
+.bx-footer .sys-icon,
+.bx-footer .sys-icon-a {
+	color: @bx-color-icon-footer; 
+}
+.bx-footer a:hover .sys-icon,
+.bx-footer a:hover .sys-icon-a {
+	color: @bx-color-icon-footer-hover; 
+}
+.bx-footer .sys-icon-a i {
+	.background-color (@bx-color-icon-footer) !important;
+	color: @bx-color-icon-footer;
+}
+.bx-footer a:hover .sys-icon-a i {
+	.background-color (@bx-color-icon-footer-hover) !important;
+	color: @bx-color-icon-footer-hover;
+}
+
+/* fonts */
+.bx-def-font-inputs {
+	font-family: @bx-font-family-form-input;
+	font-size: @bx-font-size-form-input;
+	color: @bx-font-color-form-input;
+}
+
+h1,
+.bx-def-font-h1 {
+	font-weight: @bx-font-weight-h1;
+	color: @bx-font-color-default-h1;
+}
+h1.bx-def-font-grayed,
+h1 .bx-def-font-grayed,
+.bx-def-font-h1.bx-def-font-grayed,
+.bx-def-font-h1 .bx-def-font-grayed {
+	color: @bx-font-color-grayed-h1;
+}
+h1.bx-def-font-contrasted,
+h1.bx-def-font-contrasted:after,
+h1.bx-def-font-contrasted:before,
+h1 .bx-def-font-contrasted,
+h1 .bx-def-font-contrasted:after,
+h1 .bx-def-font-contrasted:before,
+.bx-def-font-h1.bx-def-font-contrasted,
+.bx-def-font-h1.bx-def-font-contrasted:after,
+.bx-def-font-h1.bx-def-font-contrasted:before,
+.bx-def-font-h1 .bx-def-font-contrasted,
+.bx-def-font-h1 .bx-def-font-contrasted:after,
+.bx-def-font-h1 .bx-def-font-contrasted:before {
+	color: @bx-font-color-contrasted-h1;
+}
+h1 a,
+.bx-def-font-h1 a,
+a.bx-def-font-h1 {
+	color: @bx-font-color-link-h1;
+}
+h1 a:hover,
+.bx-def-font-h1 a:hover,
+a.bx-def-font-h1:hover {
+	color: @bx-font-color-link-h1-hover;
+}
+
+h2,
+.bx-def-font-h2 {
+	font-weight: @bx-font-weight-h2;
+	color: @bx-font-color-default-h2;
+}
+h2.bx-def-font-grayed,
+h2 .bx-def-font-grayed,
+.bx-def-font-h2.bx-def-font-grayed,
+.bx-def-font-h2 .bx-def-font-grayed {
+	color: @bx-font-color-grayed-h2;
+}
+h2.bx-def-font-contrasted,
+h2.bx-def-font-contrasted:after,
+h2.bx-def-font-contrasted:before,
+h2 .bx-def-font-contrasted,
+h2 .bx-def-font-contrasted:after,
+h2 .bx-def-font-contrasted:before,
+.bx-def-font-h2.bx-def-font-contrasted,
+.bx-def-font-h2.bx-def-font-contrasted:after,
+.bx-def-font-h2.bx-def-font-contrasted:before,
+.bx-def-font-h2 .bx-def-font-contrasted,
+.bx-def-font-h2 .bx-def-font-contrasted:after,
+.bx-def-font-h2 .bx-def-font-contrasted:before {
+	color: @bx-font-color-contrasted-h2;
+}
+h2 a,
+.bx-def-font-h2 a,
+a.bx-def-font-h2 {
+	color: @bx-font-color-link-h2;
+}
+h2 a:hover,
+.bx-def-font-h2 a:hover,
+a.bx-def-font-h2:hover {
+	color: @bx-font-color-link-h2-hover;
+}
+
+h3,
+.bx-def-font-h3 {
+	font-weight: @bx-font-weight-h3;
+	color: @bx-font-color-default-h3;
+}
+h3.bx-def-font-grayed,
+h3 .bx-def-font-grayed,
+.bx-def-font-h3.bx-def-font-grayed,
+.bx-def-font-h3 .bx-def-font-grayed {
+	color: @bx-font-color-grayed-h3;
+}
+h3.bx-def-font-contrasted,
+h3.bx-def-font-contrasted:after,
+h3.bx-def-font-contrasted:before,
+h3 .bx-def-font-contrasted,
+h3 .bx-def-font-contrasted:after,
+h3 .bx-def-font-contrasted:before,
+.bx-def-font-h3.bx-def-font-contrasted,
+.bx-def-font-h3.bx-def-font-contrasted:after,
+.bx-def-font-h3.bx-def-font-contrasted:before,
+.bx-def-font-h3 .bx-def-font-contrasted,
+.bx-def-font-h3 .bx-def-font-contrasted:after,
+.bx-def-font-h3 .bx-def-font-contrasted:before {
+	color: @bx-font-color-contrasted-h3;
+}
+h3 a,
+.bx-def-font-h3 a,
+a.bx-def-font-h3 {
+	color: @bx-font-color-link-h3;
+}
+h3 a:hover,
+.bx-def-font-h3 a:hover,
+a.bx-def-font-h3:hover {
+	color: @bx-font-color-link-h3-hover;
+}
+
+/* cover */
+.bx-menu-toolbar-padding .bx-def-cover-color-bg {
+    background-color: @bx-color-cover;
+}
+
+.bx-menu-toolbar-padding .bx-cover-wrapper {
+    border-width: @bx-border-width-cover;
+    border-style: @bx-border-type;
+    border-color: @bx-color-border-cover;
+
+    border-radius: @bx-border-radius-cover;
+    background-clip: padding-box;
+
+    -webkit-box-shadow: @bx-shadow-cover;
+    -moz-box-shadow: @bx-shadow-cover;
+    box-shadow: @bx-shadow-cover;
+}
+.bx-cover-wrapper .bx-cover {
+    min-height: @bx-height-cover;
+}
+.bx-cover-wrapper .bx-cover,
+.bx-cover-wrapper .bx-cover .bx-cover-actions .bx-menu-btns-hor {
+    text-align: @bx-text-align-cover;
+}
+.bx-cover-wrapper .bx-cover.bx-def-padding {
+    padding: @bx-content-padding-cover;
+}
+.bx-cover-wrapper .bx-cover .bx-cover-image img {
+    border-width: @bx-border-width-cover-icon;
+    border-style: @bx-border-type;
+    border-color: @bx-color-border-cover-icon;
+
+    border-radius: @bx-border-radius-cover-icon;
+    background-clip: padding-box;
+
+    -webkit-box-shadow: @bx-shadow-cover-icon;
+    -moz-box-shadow: @bx-shadow-cover-icon;
+    box-shadow: @bx-shadow-cover-icon;
+}
+
+.bx-cover-wrapper .bx-cover .bx-cover-title {
+    text-shadow: @bx-shadow-text-cover;
+
+    font-family: @bx-font-family-cover;
+}
+.bx-cover-wrapper .bx-cover .bx-cover-title,
+.bx-cover-wrapper .bx-cover .bx-cover-title .bx-def-font-contrasted {
+    color: @bx-color-font-cover;
+}
+.bx-cover-wrapper .bx-cover .bx-cover-title,
+.bx-cover-wrapper .bx-cover .bx-cover-title.bx-def-font-h1 {
+    font-size: @bx-font-size-cover;
+    font-weight: @bx-font-weight-cover;
+}
+
+
+/* block */
+.bx-def-border-block {
+    border-width: @bx-border-width-block;
+    border-style: @bx-border-type;
+    border-color: @bx-color-border-block;
+
+    border-radius: @bx-border-radius-block;
+    background-clip: padding-box;
+}
+.bx-def-border-radius-block {
+    border-radius: @bx-border-radius-block;
+    background-clip: padding-box;
+}
+.bx-db-header {
+    padding: @bx-title-padding-block;
+
+    border-width: @bx-border-width-block-title;
+    border-style: solid;
+    border-color: @bx-color-border-block-title;
+
+    border-radius: @bx-border-radius-block-title;
+}
+.bx-def-color-bg-block .bx-db-header,
+.bx-def-image-bg-block .bx-db-header {
+    background-color: @bx-color-block-title;
+}
+.bx-db-header .bx-db-title {
+    font-family: @bx-font-family-block-title;
+    font-weight: @bx-font-weight-block-title;
+    color: @bx-color-font-block-title;
+}
+.bx-db-header .bx-db-title.bx-def-font-h2 {
+    font-size: @bx-font-size-block-title;
+}
+.bx-db-divider {
+    border-top:@bx-height-block-title-div @bx-border-type @bx-color-block-title-div;
+}
+
+
+/* box */
+.bx-def-box {
+    border-width: @bx-border-width-box;
+    border-style: @bx-border-type;
+    border-color: @bx-color-border-box;
+}
+.bx-def-box.bx-def-padding {
+    padding: @bx-content-padding-card;
+}
+.bx-def-box.bx-def-color-bg-box {
+    .background-color (@bx-color-box);
+}
+.bx-def-box.bx-def-color-bg-box-active,
+.bx-def-box.bx-def-color-bg-box-hover:hover {
+    .background-color (@bx-color-box-hover);
+}
+.bx-def-box-round-corners,
+.bx-def-box.bx-def-round-corners {
+    border-radius: @bx-border-radius-box;
+    background-clip: padding-box;
+}
+.bx-def-box-round-corners-int {
+    border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+    background-clip: padding-box;
+}
+.bx-def-box-round-corners-int-top {
+    border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+    background-clip: padding-box;
+}
+.bx-def-box-round-corners-int-bottom {
+    border-radius: 0 0 @bx-border-radius-box-ibr @bx-border-radius-box-ibl;
+    background-clip: padding-box;
+}
+.bx-base-pofile-unit-with-cover .bx-def-round-corners .bx-base-pofile-unit-cover {
+    border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+}
+.bx-base-text-unit.bx-base-text-unit-ext.bx-def-round-corners img.bx-base-text-unit-cover.bx-def-round-corners,
+.bx-base-text-unit.bx-base-text-unit-ext .bx-def-round-corners img.bx-base-text-unit-cover.bx-def-round-corners {
+    border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+}
+.bx-base-text-unit.bx-base-text-unit-gallery.bx-def-round-corners .bx-base-text-unit-thumb.bx-def-round-corners,
+.bx-base-text-unit.bx-base-text-unit-gallery .bx-def-round-corners .bx-base-text-unit-thumb.bx-def-round-corners {
+    border-radius: @bx-border-radius-box-itl @bx-border-radius-box-itr 0 0;
+}
+
+/* popup */
+.bx-popup-border {
+    border-width: @bx-border-width-popup;
+    border-style: solid;
+    border-color: @bx-color-border-popup;
+
+    border-radius: @bx-border-radius-popup;
+    background-clip: padding-box;
+}
+.bx-popup-color-bg {
+    background-color: @bx-color-popup;
+
+    background-image: @bx-image-bg-popup;
+    background-repeat: @bx-image-bg-popup-repeat;
+    background-attachment: @bx-image-bg-popup-attachment;
+    background-size: @bx-image-bg-popup-size;
+}
+.bx-popup-content-indent {
+	padding: @bx-content-padding-popup;
+}
+.bx-popup-header {
+	padding: @bx-title-padding-popup;
+}
+.bx-popup-header-color-bg {
+	background-color: @bx-color-popup-title;
+}
+.bx-popup-header h2 {
+    line-height: 1.8rem;
+    font-family: @bx-font-family-popup-title;
+    font-size: @bx-font-size-popup-title;
+}
+.bx-popup-header h2,
+.bx-popup-header.bx-def-font-contrasted h2,
+.bx-popup-header .bx-popup-element-close,
+.bx-popup-header.bx-def-font-contrasted .bx-popup-element-close,
+.bx-popup-header .bx-popup-element-close .sys-icon,
+.bx-popup-header.bx-def-font-contrasted .bx-popup-element-close .sys-icon {
+	color: @bx-color-font-popup-title;
+}
+
+/* slide menu */
+.bx-popup-wrapper.bx-popup-slide-wrapper {
+	border-width: @bx-border-width-menu-slide;
+	border-style: solid;
+	border-color: @bx-color-border-menu-slide;
+
+	.background-color (@bx-color-menu-slide);
+
+	background-image: @bx-image-bg-menu-slide;
+	background-repeat: @bx-image-bg-menu-slide-repeat;
+	background-attachment: @bx-image-bg-menu-slide-attachment;
+    background-size: @bx-image-bg-menu-slide-size;
+}
+.bx-popup-wrapper.bx-popup-slide-wrapper.bx-def-padding {
+	padding: @bx-content-padding-menu-slide;
+}
+.bx-popup-wrapper.bx-popup-slide-wrapper li a {
+	text-shadow: @bx-shadow-font-menu-slide;
+
+	font-family: @bx-font-family-menu-slide;
+	font-size: @bx-font-size-menu-slide;
+	font-weight: @bx-font-weight-menu-slide;
+	color: @bx-font-color-menu-slide;
+}
+.bx-popup-wrapper.bx-popup-slide-wrapper li a:hover {
+	color: @bx-font-color-menu-slide-hover;
+}
+.bx-popup-wrapper.bx-popup-slide-wrapper li.bx-menu-tab-active a,
+.bx-popup-wrapper.bx-popup-slide-wrapper li.bx-menu-inter-act {
+	color: @bx-font-color-menu-slide-active;
+}
+
+/* main menu */
+.cd-main-content .cd-side-nav {
+	-webkit-box-shadow: @bx-shadow-menu-main;
+	-moz-box-shadow: @bx-shadow-menu-main;
+	box-shadow: @bx-shadow-menu-main;
+
+	border-width: @bx-border-width-menu-main;
+	border-style: solid;
+	border-color: @bx-color-border-menu-main;
+
+	background-color: @bx-color-menu-main;
+
+	background-image: @bx-image-bg-menu-main;
+	background-repeat: @bx-image-bg-menu-main-repeat;
+	background-attachment: @bx-image-bg-menu-main-attachment;
+    background-size: @bx-image-bg-menu-main-size;
+}
+
+#bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt {
+	padding: @bx-content-padding-menu-main;
+}
+#bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a {
+	text-shadow: @bx-shadow-font-menu-main;
+
+	font-family: @bx-font-family-menu-main;
+	font-size: @bx-font-size-menu-main;
+	font-weight: @bx-font-weight-menu-main;
+	color: @bx-font-color-menu-main;
+}
+#bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a {
+	color: @bx-font-color-menu-main-active;
+}
+#bx-sliding-menu-sys_site.bx-sliding-smenu-main .bx-sliding-menu-main-cnt li a:hover {
+	color: @bx-font-color-menu-main-hover;
+}
+
+
+/* account menu */
+#bx-sliding-menu-account.bx-sliding-menu-main {
+    -webkit-box-shadow: @bx-shadow-menu-account;
+    -moz-box-shadow: @bx-shadow-menu-account;
+    box-shadow: @bx-shadow-menu-account;
+
+    border-width: @bx-border-width-menu-account;
+    border-style: solid;
+    border-color: @bx-color-border-menu-account;
+
+    background-color: @bx-color-menu-account;
+
+    background-image: @bx-image-bg-menu-account;
+    background-repeat: @bx-image-bg-menu-account-repeat;
+    background-attachment: @bx-image-bg-menu-account-attachment;
+    background-size: @bx-image-bg-menu-account-size;
+}
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt {
+    padding: @bx-content-padding-menu-account;
+}
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt,
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .bx-def-font-h1,
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .bx-def-font-h2,
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt a,
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-sliding-menu-main-cnt .sys-icon {
+    color: @bx-font-color-menu-account;
+}
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a,
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a .bx-menu-floating-blocks-title {
+    text-shadow: @bx-shadow-font-menu-account;
+
+    font-family: @bx-font-family-menu-account;
+    font-size: @bx-font-size-menu-account;
+    font-weight: @bx-font-weight-menu-account;
+}
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li.bx-menu-tab-active a {
+    color: @bx-font-color-menu-account-active;
+}
+#bx-sliding-menu-account.bx-sliding-menu-main .bx-menu-account-popup li a:hover {
+    color: @bx-font-color-menu-account-hover;
+}
+
+/* add menu */
+#bx-sliding-menu-sys_add_content.bx-sliding-menu-main {
+    -webkit-box-shadow: @bx-shadow-menu-add;
+    -moz-box-shadow: @bx-shadow-menu-add;
+    box-shadow: @bx-shadow-menu-add;
+
+    border-width: @bx-border-width-menu-add;
+    border-style: solid;
+    border-color: @bx-color-border-menu-add;
+
+    background-color: @bx-color-menu-add;
+
+    background-image: @bx-image-bg-menu-add;
+    background-repeat: @bx-image-bg-menu-add-repeat;
+    background-attachment: @bx-image-bg-menu-add-attachment;
+    background-size: @bx-image-bg-menu-add-size;
+}
+#bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt {
+    padding: @bx-content-padding-menu-add;
+}
+#bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a {
+    text-shadow: @bx-shadow-font-menu-add;
+
+    font-family: @bx-font-family-menu-add;
+    font-size: @bx-font-size-menu-add;
+    font-weight: @bx-font-weight-menu-add;
+    color: @bx-font-color-menu-add;
+}
+#bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li.bx-menu-tab-active a {
+    color: @bx-font-color-menu-add-active;
+}
+#bx-sliding-menu-sys_add_content.bx-sliding-menu-main .bx-sliding-menu-main-cnt li a:hover {
+    color: @bx-font-color-menu-add-hover;
+}
+
+/* page menu */
+.bx-menu-main-bar-wrapper {
+    -webkit-box-shadow: @bx-shadow-menu-page;
+    -moz-box-shadow: @bx-shadow-menu-page;
+    box-shadow: @bx-shadow-menu-page;
+
+    border-width: @bx-border-width-menu-page;
+    border-style: solid;
+    border-color: @bx-color-border-menu-page;
+
+    background-color: @bx-color-menu-page;
+
+    background-image: @bx-image-bg-menu-page;
+    background-repeat: @bx-image-bg-menu-page-repeat;
+    background-attachment: @bx-image-bg-menu-page-attachment;
+    background-size: @bx-image-bg-menu-page-size;
+}
+.bx-menu-main-bar-wrapper:before {
+    border-bottom-left-radius: @bx-border-radius-block-bl;
+    background: @bx-color-menu-page-gradient-left;
+}
+.bx-menu-main-bar-wrapper:after {
+    border-bottom-right-radius: @bx-border-radius-block-br;
+    background: @bx-color-menu-page-gradient-right;
+}
+.bx-menu-main-bar-wrapper .bx-menu-main-submenu {
+	padding: @bx-content-padding-menu-page;
+}
+.bx-menu-main-bar-wrapper .bx-menu-main-submenu li a {
+	text-shadow: @bx-shadow-font-menu-page;
+
+	font-family: @bx-font-family-menu-page;
+	font-size: @bx-font-size-menu-page;
+	font-weight: @bx-font-weight-menu-page;
+	color: @bx-font-color-menu-page;
+}
+.bx-menu-main-bar-wrapper .bx-menu-main-submenu li a:hover {
+	color: @bx-font-color-menu-page-hover;
+}
+.bx-menu-main-bar-wrapper .bx-menu-main-submenu li.bx-menu-tab-active a {
+	color: @bx-font-color-menu-page-active;
+}
+
+/* form */
+.bx-form-value .bx-form-input-slider,
+.bx-form-value .bx-form-input-doublerange,
+.bx-form-value .bx-form-input-select_multiple,
+.bx-form-value .bx-form-input-select,
+.bx-form-value .bx-form-input-radio_set,
+.bx-form-value .bx-form-input-checkbox_set,
+.bx-form-value .bx-form-input-number,
+.bx-form-value .bx-form-input-datepicker,
+.bx-form-value .bx-form-input-datetime,
+.bx-form-value .bx-form-input-textarea,
+.bx-form-value .bx-form-input-password,
+.bx-form-value .bx-form-input-text {
+	border-color: @bx-color-border-form-input;
+	border-width: @bx-border-width-form-input;
+
+	background-color: @bx-color-form-input;
+
+	-webkit-box-shadow: @bx-shadow-form-input;
+	-moz-box-shadow: @bx-shadow-form-input;
+	box-shadow: @bx-shadow-form-input;
+}
+.bx-form-value .bx-form-input-slider,
+.bx-form-value .bx-form-input-doublerange,
+.bx-form-value .bx-form-input-select,
+.bx-form-value .bx-form-input-number,
+.bx-form-value .bx-form-input-datepicker,
+.bx-form-value .bx-form-input-datetime,
+.bx-form-value .bx-form-input-password,
+.bx-form-value .bx-form-input-text {
+	height: @bx-height-form-input;
+}
+.bx-form-value .bx-form-input-text.bx-form-input-autotoken b {
+    line-height: @bx-height-form-input;
+}
+.bx-form-value .bx-form-input-text.bx-form-input-autotoken b .bx-def-thumb-size {
+	width: @bx-height-form-input;
+    height: @bx-height-form-input;
+    line-height: @bx-height-form-input;
+}
+.bx-form-value .bx-form-input-slider:focus,
+.bx-form-value .bx-form-input-doublerange:focus,
+.bx-form-value .bx-form-input-number:focus,
+.bx-form-value .bx-form-input-datepicker:focus,
+.bx-form-value .bx-form-input-datetime:focus,
+.bx-form-value .bx-form-input-textarea:focus,
+.bx-form-value .bx-form-input-password:focus,
+.bx-form-value .bx-form-input-text:focus {
+	border-color: @bx-color-border-form-input-active;
+	background-color: @bx-color-form-input-active;
+}
+.bx-form-value .bx-switcher-cont {
+	border-color: @bx-color-border-form-input;
+	border-width: @bx-border-width-form-input;
+
+	background-color: @bx-color-form-input;
+
+	-webkit-box-shadow: @bx-shadow-form-input;
+	-moz-box-shadow: @bx-shadow-form-input;
+	box-shadow: @bx-shadow-form-input;
+}
+
+/* button large */
+.bx-btn,
+.bx-btn.bx-btn-primary {
+	.box-sizing(content-box);
+
+	height: @bx-height-button;
+	line-height: @bx-height-button;
+
+	.background-color (@bx-color-button);
+
+	border-width: @bx-border-width-button;
+	border-style: solid;
+	border-color: @bx-color-border-button;
+
+        border-radius: @bx-border-radius-button;
+	background-clip: padding-box;
+
+	text-shadow: @bx-shadow-font-button;
+
+	font-family: @bx-font-family-button;
+	font-size: @bx-font-size-button;
+	font-weight: @bx-font-weight-button;
+	color: @bx-font-color-button;
+}
+.bx-btn-height {
+	height: @bx-height-button;
+	line-height: @bx-height-button;
+}
+.bx-btn-border {
+	border-width: @bx-border-width-button;
+	border-style: solid;
+	border-color: transparent;
+}
+.bx-btn:hover,
+.bx-btn:active,
+.bx-btn.bx-btn-primary:hover,
+.bx-btn.bx-btn-primary:active {
+	border-width: @bx-border-width-button;
+	border-style: solid;
+	border-color: @bx-color-border-button-hover;
+
+	.background-color (@bx-color-button-hover);
+
+	color: @bx-font-color-button-hover;
+}
+.bx-btn .sys-icon:not(.sys-colored) {
+    color: @bx-font-color-button;
+}
+.bx-btn:hover .sys-icon:not(.sys-colored),
+.bx-btn:active .sys-icon:not(.sys-colored),
+.bx-btn.bx-btn-primary:hover .sys-icon:not(.sys-colored),
+.bx-btn.bx-btn-primary:active .sys-icon:not(.sys-colored) {
+    color: @bx-font-color-button-hover;
+}
+
+/* button small */
+.bx-btn.bx-btn-small {
+	.box-sizing(content-box);
+
+	height: @bx-height-button-small;
+	line-height: @bx-height-button-small;
+
+	.background-color (@bx-color-button-small);
+
+	border-width: @bx-border-width-button-small;
+	border-style: solid;
+	border-color: @bx-color-border-button-small;
+
+        border-radius: @bx-border-radius-button-small;
+	background-clip: padding-box;
+
+	text-shadow: @bx-shadow-font-button-small;
+
+	font-family: @bx-font-family-button-small;
+	font-size: @bx-font-size-button-small;
+	font-weight: @bx-font-weight-button-small;
+	color: @bx-font-color-button-small;
+}
+.bx-btn-small-height {
+	height: @bx-height-button-small;
+	line-height: @bx-height-button-small;
+}
+.bx-btn-small-border {
+	border-width: @bx-border-width-button-small;
+	border-style: solid;
+	border-color: transparent;
+}
+.bx-btn.bx-btn-small:hover,
+.bx-btn.bx-btn-small:active {
+	border-width: @bx-border-width-button-small;
+	border-style: solid;
+	border-color: @bx-color-border-button-small-hover;
+
+	.background-color (@bx-color-button-small-hover);
+
+	color: @bx-font-color-button-small-hover;
+}
+.bx-btn.bx-btn-small .sys-icon {
+	color: @bx-font-color-button-small;
+}
+.bx-btn.bx-btn-small:hover .sys-icon,
+.bx-btn.bx-btn-small:active .sys-icon {
+	color: @bx-font-color-button-small-hover;
+}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio