فهرست منبع

Modules updates.

AntonLV 8 سال پیش
والد
کامیت
898fa950db
58فایلهای تغییر یافته به همراه12622 افزوده شده و 0 حذف شده
  1. 51 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/install/config.php
  2. 13 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/install/installer.php
  3. 6 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/install/langs/en.xml
  4. 15 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/install/sql/enable.sql
  5. 31 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerCron.php
  6. 249 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerDb.php
  7. 61 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerFormEntry.php
  8. 625 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerModule.php
  9. 77 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/config.php
  10. 152 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/langs/en.xml
  11. 37 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/sql/disable.sql
  12. 126 0
      modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/sql/enable.sql
  13. 51 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/install/config.php
  14. 25 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/install/installer.php
  15. 4 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/install/langs/en.xml
  16. 19 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/install/sql/enable.sql
  17. 18 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/install/sql/install.sql
  18. 242 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/classes/BxOrgsConfig.php
  19. 150 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/config.php
  20. 418 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/langs/en.xml
  21. 81 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/disable.sql
  22. 636 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/enable.sql
  23. 377 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/install.sql
  24. 38 0
      modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/uninstall.sql
  25. 51 0
      modules/boonex/payment/updates/9.0.11_9.0.12/install/config.php
  26. 13 0
      modules/boonex/payment/updates/9.0.11_9.0.12/install/installer.php
  27. 5 0
      modules/boonex/payment/updates/9.0.11_9.0.12/install/langs/en.xml
  28. 8 0
      modules/boonex/payment/updates/9.0.11_9.0.12/install/sql/install.sql
  29. 154 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/classes/BxPaymentGridCart.php
  30. 78 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/classes/BxPaymentGridSbsAdministration.php
  31. 453 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/classes/BxPaymentTemplate.php
  32. 70 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/install/config.php
  33. 527 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/install/langs/en.xml
  34. 474 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/install/sql/install.sql
  35. 36 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/template/order_history.html
  36. 37 0
      modules/boonex/payment/updates/9.0.11_9.0.12/source/template/order_processed.html
  37. 51 0
      modules/boonex/polls/updates/9.0.7_9.0.8/install/config.php
  38. 13 0
      modules/boonex/polls/updates/9.0.7_9.0.8/install/installer.php
  39. 141 0
      modules/boonex/polls/updates/9.0.7_9.0.8/source/classes/BxPollsDb.php
  40. 204 0
      modules/boonex/polls/updates/9.0.7_9.0.8/source/classes/BxPollsFormEntry.php
  41. 136 0
      modules/boonex/polls/updates/9.0.7_9.0.8/source/install/config.php
  42. 34 0
      modules/boonex/polls/updates/9.0.7_9.0.8/source/js/form.js
  43. 27 0
      modules/boonex/polls/updates/9.0.7_9.0.8/source/template/css/forms.css
  44. 11 0
      modules/boonex/polls/updates/9.0.7_9.0.8/source/template/form_subentries.html
  45. 51 0
      modules/boonex/spaces/updates/9.0.3_9.0.4/install/config.php
  46. 13 0
      modules/boonex/spaces/updates/9.0.3_9.0.4/install/installer.php
  47. 70 0
      modules/boonex/spaces/updates/9.0.3_9.0.4/source/classes/BxSpacesFormEntry.php
  48. 105 0
      modules/boonex/spaces/updates/9.0.3_9.0.4/source/classes/BxSpacesModule.php
  49. 151 0
      modules/boonex/spaces/updates/9.0.3_9.0.4/source/install/config.php
  50. 51 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/install/config.php
  51. 13 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/install/installer.php
  52. 5 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/install/sql/enable.sql
  53. 709 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/source/classes/BxTimelineDb.php
  54. 3065 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/source/classes/BxTimelineModule.php
  55. 1787 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/source/classes/BxTimelineTemplate.php
  56. 135 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/source/install/config.php
  57. 80 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/source/install/sql/disable.sql
  58. 362 0
      modules/boonex/timeline/updates/9.0.12_9.0.13/source/install/sql/enable.sql

+ 51 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/install/config.php

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

+ 13 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/install/installer.php

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

+ 6 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/install/langs/en.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string_add name="_bx_massmailer_delete_sent_email_in_days"><![CDATA[Delete sent email campaigns older than (days)]]></string_add>
+
+    <string_del name="_bx_massmailer_initial_from_name"><![CDATA[Letter's header "From"]]></string_del>
+</resources>

+ 15 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/install/sql/enable.sql

@@ -0,0 +1,15 @@
+SET @sName = 'bx_massmailer';
+
+
+-- SETTINGS
+SET @iCategoryId = (SELECT `id` FROM `sys_options_categories` WHERE `name`='bx_massmailer_general' LIMIT 1);
+
+DELETE FROM `sys_options` WHERE `name` IN ('bx_massmailer_initial_from_email', 'bx_massmailer_delete_sent_email_in_days');
+INSERT INTO `sys_options` (`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_params`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_massmailer_delete_sent_email_in_days', '_bx_massmailer_delete_sent_email_in_days', '365', 'digit', '', '', '', '', 1);
+
+
+-- CRON
+DELETE FROM `sys_cron_jobs` WHERE `name`='bx_massmailer_cron';
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_massmailer_cron', '0 1 * * *', 'BxMassMailerCron', 'modules/boonex/massmailer/classes/BxMassMailerCron.php', '');

+ 31 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerCron.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    MassMailer Mass Mailer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxMassMailerCron extends BxDolCron
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    public function __construct()
+    {
+        $this->_sModule = 'bx_massmailer';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        parent::__construct();
+    }
+
+    function processing()
+    {
+        $this->_oModule->_oDb->deleteOldCampagns(getParam('bx_massmailer_delete_sent_email_in_days'));
+    }
+}
+
+/** @} */

+ 249 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerDb.php

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

+ 61 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerFormEntry.php

@@ -0,0 +1,61 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    MassMailer Mass Mailer
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxMassMailerFormCheckerHelper extends BxDolFormCheckerHelper
+{
+    static public function checkEmailOrEmpty($s)
+    {
+        if (trim($s) == '')
+            return true;
+        
+        if (!self::checkEmail($s))
+            return false;
+
+        return true;
+    }
+    
+    static public function checkUnsubscribeUrl($s)
+    {
+        if (trim($s) == '')
+            return false;
+        
+        if (strpos($s, '{unsubscribe_url}') === false)
+            return false;
+        
+        return true;
+    }
+}
+
+/**
+ * Create/Edit entry form
+ */
+class BxMassMailerFormEntry extends BxBaseModTextFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_massmailer';
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+        parent::__construct($aInfo, $oTemplate);
+        
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        if (isset( $this->aInputs[$CNF['FIELD_SEGMENTS']]))
+            $this->aInputs[$CNF['FIELD_SEGMENTS']]['values'] = $this->_oModule->getSegments();
+    }
+
+    public function insert ($aValsToAdd = array(), $isIgnore = false)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+        $aValsToAdd[$CNF['FIELD_AUTHOR']] = bx_get_logged_profile_id();
+        return parent::insert ($aValsToAdd, $isIgnore);
+    }
+}
+
+/** @} */

+ 625 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/classes/BxMassMailerModule.php

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

+ 77 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/config.php

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

+ 152 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/langs/en.xml

@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+  <string name="_bx_massmailer"><![CDATA[Mass Mailer]]></string>
+  <string name="_bx_massmailer_acl_action_use_massmailer"><![CDATA[Use Massmailer]]></string>
+  <string name="_bx_massmailer_adm_stg_cpt_type"><![CDATA[Mass Mailer]]></string>
+  <string name="_bx_massmailer_adm_stg_cpt_category_general"><![CDATA[General]]></string>
+  <string name="_bx_massmailer_delete_sent_email_in_days"><![CDATA[Delete sent email campaigns older than (days)]]></string>
+  <string name="_bx_massmailer_page_title_sys_manage_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_page_title_manage_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_page_title_sys_manage_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_page_block_title_manage_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_page_block_title_system_manage_campaigns"><![CDATA[Manage Campaigns]]></string>
+  <string name="_bx_massmailer_page_block_title_system_manage_segments"><![CDATA[Manage Segments]]></string>
+  <string name="_bx_massmailer_page_block_title_manage_segments"><![CDATA[Manage Segments]]></string>
+  <string name="_bx_massmailer_page_title_manage_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_page_title_sys_manage_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_page_title_manage_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_page_title_sys_create_campaign"><![CDATA[New Campaign]]></string>
+  <string name="_bx_massmailer_page_title_create_campaign"><![CDATA[New Campaign]]></string>
+  <string name="_bx_massmailer_page_block_title_create_campaign"><![CDATA[New Campaign]]></string>
+  <string name="_bx_massmailer_page_title_sys_edit_campaign"><![CDATA[Edit Campaign]]></string>
+  <string name="_bx_massmailer_page_title_edit_campaign"><![CDATA[Edit Campaign]]></string>
+  <string name="_bx_massmailer_page_block_title_edit_campaign"><![CDATA[Edit Campaign]]></string>
+  <string name="_bx_massmailer_page_title_sys_view_campaign"><![CDATA[Campaign report]]></string>
+  <string name="_bx_massmailer_page_title_view_campaign"><![CDATA[Campaign report]]></string>
+  <string name="_bx_massmailer_page_block_title_view_campaign_info"><![CDATA[Info]]></string>
+  <string name="_bx_massmailer_page_block_title_view_campaign_subscribers"><![CDATA[Subscribers]]></string>
+  <string name="_bx_massmailer_page_block_title_view_campaign_links"><![CDATA[Link activity]]></string>
+  <string name="_bx_massmailer_page_block_title_entry_breadcrumb"><![CDATA[Breadcrumb]]></string>
+  <string name="_bx_massmailer_page_title_sys_unsubscribe"><![CDATA[Unsubscribe From Site Newsletters]]></string>
+  <string name="_bx_massmailer_page_title_unsubscribe"><![CDATA[Unsubscribe From Site Newsletters]]></string>
+  <string name="_bx_massmailer_page_block_title_system_unsubscribe"><![CDATA[Unsubscribe From Site Newsletters]]></string>
+  <string name="_bx_massmailer_page_block_title_unsubscribe"><![CDATA[Unsubscribe From Site Newsletters]]></string>
+  <string name="_bx_massmailer_page_block_title_system_viewsubscribers"><![CDATA[Subscribers]]></string>
+  <string name="_bx_massmailer_page_block_title_viewsubscribers"><![CDATA[Subscribers]]></string>
+  <string name="_bx_massmailer_page_block_title_attributes"><![CDATA[Attributes]]></string>
+  <string name="_bx_massmailer_menu_item_title_system_admt_mailer"><![CDATA[Mass Mailer]]></string>
+  <string name="_bx_massmailer_menu_item_title_admt_mailer"><![CDATA[Mass Mailer]]></string>
+  <string name="_bx_massmailer_menu_item_title_manage_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_menu_title_submenu"><![CDATA[Mass Mailer  Submenu]]></string>
+  <string name="_bx_massmailer_menu_set_title_submenu"><![CDATA[Mass Mailer Submenu]]></string>
+  <string name="_bx_massmailer_menu_item_title_system_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_menu_item_title_campaigns"><![CDATA[Campaigns]]></string>
+  <string name="_bx_massmailer_menu_item_title_system_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_menu_item_title_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_menu_item_title_system_create_entry"><![CDATA[Campaign]]></string>
+  <string name="_bx_massmailer_menu_item_title_create_entry"><![CDATA[Campaign]]></string>
+
+  <string name="_bx_massmailer_grid_column_title_adm_title"><![CDATA[Title]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_author"><![CDATA[Author]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_date_created"><![CDATA[Created]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_date_sent"><![CDATA[Sent]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_edit"><![CDATA[Edit]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_copy"><![CDATA[Copy]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_view"><![CDATA[Report]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_send_test"><![CDATA[Send test]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_send_all"><![CDATA[Send All]]></string>
+  <string name="_bx_massmailer_grid_action_title_adm_add"><![CDATA[Add new campaign]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_segment"><![CDATA[Segment]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_is_one_per_account"><![CDATA[One per account]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_is_one_per_account_yes"><![CDATA[Yes]]></string>
+  <string name="_bx_massmailer_grid_column_title_adm_is_one_per_account_no"><![CDATA[No]]></string>
+  
+  <string name="_bx_massmailer_campaign_form_add_title"><![CDATA[New campaign]]></string>
+  <string name="_bx_massmailer_campaign_form_edit_title"><![CDATA[Edit campaign]]></string>
+  <string name="_bx_massmailer_campaign_form_send_test_title"><![CDATA[Send test letter]]></string>
+  <string name="_bx_massmailer_campaign_form_send_all_title"><![CDATA[Send campaign]]></string>
+  <string name="_bx_massmailer_form_campaign"><![CDATA[Campaign]]></string>
+  <string name="_bx_massmailer_form_campaign_add_display"><![CDATA[Add]]></string>
+  <string name="_bx_massmailer_form_campaign_edit_display"><![CDATA[Edit]]></string>
+  <string name="_bx_massmailer_form_entry_input_do_submit"><![CDATA[Save]]></string>
+  <string name="_bx_massmailer_form_entry_input_sys_do_submit"><![CDATA[Save]]></string>
+  <string name="_bx_massmailer_form_entry_input_do_send"><![CDATA[Send]]></string>
+  <string name="_bx_massmailer_form_entry_input_sys_do_send"><![CDATA[Send]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_title"><![CDATA[Campaign name]]></string>
+  <string name="_bx_massmailer_form_campaign_input_title"><![CDATA[Campaign name]]></string>
+  <string name="_bx_massmailer_form_campaign_input_title_err"><![CDATA[Campaign name can't be empty]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_body"><![CDATA[Body]]></string>
+  <string name="_bx_massmailer_form_campaign_input_body"><![CDATA[Body]]></string>
+  <string name="_bx_massmailer_form_campaign_input_body_err"><![CDATA[Body can't be empty and {unsubscribe_url} marker must be present]]></string>
+  <string name="_bx_massmailer_form_campaign_input_is_one_per_account"><![CDATA[One letter per one account]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_test_email"><![CDATA[Email]]></string>
+  <string name="_bx_massmailer_form_campaign_input_email"><![CDATA[Email]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_form_campaign_input_segments"><![CDATA[Segments]]></string>
+  <string name="_bx_massmailer_form_campaign_input_segments_err"><![CDATA[Segments's can't be empty]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_subject"><![CDATA[Subject]]></string>
+  <string name="_bx_massmailer_form_campaign_input_subject"><![CDATA[Subject]]></string>
+  <string name="_bx_massmailer_form_campaign_input_subject_err"><![CDATA[Subject can't be empty]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_from_name"><![CDATA[From name]]></string>
+  <string name="_bx_massmailer_form_campaign_input_from_name"><![CDATA[From name]]></string>
+  <string name="_bx_massmailer_form_campaign_input_from_name_info"><![CDATA[If empty, Site Name is used]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_reply_to"><![CDATA[Reply to Email]]></string>
+  <string name="_bx_massmailer_form_campaign_input_reply_to"><![CDATA[Reply to Email]]></string>
+  <string name="_bx_massmailer_form_campaign_input_reply_to_info"><![CDATA[If empty, Site Email is used]]></string>
+  <string name="_bx_massmailer_form_campaign_input_reply_to_err"><![CDATA[Email is not valid]]></string>
+  <string name="_bx_massmailer_form_campaign_input_from_name_info_value"><![CDATA[The message will be sent to {0} profiles.]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_campaign_info"><![CDATA[Campaign info]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_receive_news"><![CDATA[Receive Newsletterso]]></string>
+  <string name="_bx_massmailer_form_campaign_input_receive_news"><![CDATA[Receive Newsletters]]></string>
+  <string name="_bx_massmailer_form_campaign_input_sys_code"><![CDATA[Code]]></string>
+  <string name="_bx_massmailer_form_entry_input_cancel"><![CDATA[Cancel]]></string>
+
+  <string name="_bx_massmailer_txt_breadcrumb_title_new_campaign"><![CDATA[New campaign]]></string>
+  <string name="_bx_massmailer_txt_never_sent"><![CDATA[Never]]></string>
+  <string name="_bx_massmailer_txt_title_email"><![CDATA[Email]]></string>
+  <string name="_bx_massmailer_txt_title_title"><![CDATA[Title]]></string>
+  <string name="_bx_massmailer_txt_link_title"><![CDATA[Url]]></string>
+  <string name="_bx_massmailer_txt_click_count_title"><![CDATA[Total clicks]]></string>
+  <string name="_bx_massmailer_txt_last_click_title"><![CDATA[Last click]]></string>
+  <string name="_bx_massmailer_txt_subject_title"><![CDATA[Subject:]]></string>
+  <string name="_bx_massmailer_txt_body_title"><![CDATA[Body:]]></string>
+  <string name="_bx_massmailer_txt_sent_on_title"><![CDATA[Sent on:]]></string>
+  <string name="_bx_massmailer_txt_sent_to_title"><![CDATA[Segment:]]></string>
+  
+  <string name="_bx_massmailer_txt_sent_total_title"><![CDATA[Total sent - {0}]]></string>
+  <string name="_bx_massmailer_txt_opened_total_title"><![CDATA[Opened - {0}]]></string>
+  <string name="_bx_massmailer_txt_unopened_total_title"><![CDATA[Unopened - {0}]]></string>
+  <string name="_bx_massmailer_txt_clicked_total_title"><![CDATA[Clicked - {0}]]></string>
+  <string name="_bx_massmailer_txt_unsubscribed_total_title"><![CDATA[Unsubscribed - {0}]]></string>
+
+  <string name="_bx_massmailer_txt_attribute_global"><![CDATA[Account]]></string>
+  <string name="_bx_massmailer_txt_item"><![CDATA[Item]]></string>
+  <string name="_bx_massmailer_txt_value"><![CDATA[Value]]></string>
+  <string name="_bx_massmailer_txt_date"><![CDATA[Date]]></string>
+  <string name="_bx_massmailer_txt_attribute_email"><![CDATA[Email]]></string>
+  <string name="_bx_massmailer_txt_attribute_account_name"><![CDATA[Account name]]></string>
+  <string name="_bx_massmailer_txt_attribute_account_id"><![CDATA[Account id]]></string>
+  <string name="_bx_massmailer_txt_attribute_unsubscribe_url"><![CDATA[Unsubscribe url]]></string>
+  <string name="_bx_massmailer_txt_created_title"><![CDATA[Created:]]></string>
+  <string name="_bx_massmailer_txt_from_name_title"><![CDATA[From name:]]></string>
+  <string name="_bx_massmailer_txt_reply_title"><![CDATA[Reply:]]></string>
+  <string name="_bx_massmailer_txt_title_content_total"><![CDATA[Total numbers]]></string>
+  <string name="_bx_massmailer_txt_title_content_speed"><![CDATA[Growth speed]]></string>
+  <string name="_bx_massmailer_txt_title_date_sent"><![CDATA[Sent]]></string>
+  <string name="_bx_massmailer_txt_title_date_click"><![CDATA[Last click]]></string>
+  <string name="_bx_massmailer_txt_title_date_seen"><![CDATA[Seen]]></string>
+  <string name="_bx_massmailer_txt_copy_title"><![CDATA[ - Copy]]></string>
+  <string name="_bx_massmailer_txt_unsubscribe_error_occured"><![CDATA[Unsubscribe error]]></string>
+  <string name="_bx_massmailer_txt_subscribed"><![CDATA[Subscribed]]></string>
+  <string name="_bx_massmailer_txt_unsubscribed"><![CDATA[Unsubscribed]]></string>
+  <string name="_bx_massmailer_segments_all"><![CDATA[All subscribers]]></string>
+  <string name="_bx_massmailer_email_name"><![CDATA[Mass Mailer message]]></string>
+  <string name="_bx_massmailer_email_subject"><![CDATA[Mass Mailer message]]></string>
+  <string name="_bx_massmailer_email_body">
+    <![CDATA[
+  <br />{content} <br />
+  <img src="{seen_image_url}" width="1" height="1">
+  ]]></string>
+</resources>

+ 37 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/sql/disable.sql

@@ -0,0 +1,37 @@
+SET @sName = 'bx_massmailer';
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = @sName LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+-- PAGES
+DELETE FROM `sys_objects_page` WHERE `module` = @sName;
+DELETE FROM `sys_pages_blocks` WHERE `module` = @sName;
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = @sName;
+DELETE FROM `sys_menu_sets` WHERE `module` = @sName;
+DELETE FROM `sys_menu_items` WHERE `module` = @sName;
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_massmailer_campaigns', 'bx_massmailer_letters');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_massmailer_campaigns', 'bx_massmailer_letters');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_massmailer_campaigns', 'bx_massmailer_letters');
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `module` = @sName;
+
+-- ACL
+DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matrix` WHERE `sys_acl_matrix`.`IDAction` = `sys_acl_actions`.`ID` AND `sys_acl_actions`.`Module` = @sName;
+DELETE FROM `sys_acl_actions` WHERE `Module` = @sName;
+
+-- CRON
+DELETE FROM `sys_cron_jobs` WHERE `name` LIKE 'bx_massmailer%';
+
+-- ALERTS
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = @sName LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;

+ 126 - 0
modules/boonex/massmailer/updates/9.0.3_9.0.4/source/install/sql/enable.sql

@@ -0,0 +1,126 @@
+SET @sName = 'bx_massmailer';
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT IFNULL(MAX(`order`), 0) + 1 FROM `sys_options_types` WHERE `group` = 'modules');
+
+INSERT INTO `sys_options_types` (`group`, `name`, `caption`, `icon`, `order`) 
+VALUES('modules', @sName, '_bx_massmailer_adm_stg_cpt_type', 'bx_massmailer@modules/boonex/massmailer/|std-icon.svg', IF(ISNULL(@iTypeOrder), 1, @iTypeOrder + 1));
+
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `hidden`, `order`) VALUES(@iTypeId,  'bx_massmailer_general', '_bx_massmailer_adm_stg_cpt_category_general', 0, 1);
+SET @iCategoryId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_params`, `check_error`, `order`) VALUES
+(@iCategoryId, 'bx_massmailer_delete_sent_email_in_days', '_bx_massmailer_delete_sent_email_in_days', '365', 'digit', '', '', '', '', 1);
+
+
+-- PAGE: create campaign
+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_massmailer_create_campaign', '_bx_massmailer_page_title_sys_create_campaign', '_bx_massmailer_page_title_create_campaign', 'bx_massmailer', 7, 128, 1, 'create-campaign', 'page.php?i=create-campaign', '', '', '', 0, 1, 0, 'BxMassMailerPageEntry', 'modules/boonex/massmailer/classes/BxMassMailerPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_massmailer_create_campaign', 1, @sName, '_bx_massmailer_page_block_title_entry_breadcrumb', 13, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:17:"entity_breadcrumb";}', 0, 0, 0),
+('bx_massmailer_create_campaign', 2, @sName, '_bx_massmailer_page_block_title_create_campaign', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:13:"entity_create";}', 0, 1, 1),
+('bx_massmailer_create_campaign', 3, @sName, '_bx_massmailer_page_block_title_attributes', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:10:"attributes";}', 0, 0, 1);
+
+-- PAGE: edit campaign
+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_massmailer_edit_campaign', '_bx_massmailer_page_title_sys_edit_campaign', '_bx_massmailer_page_title_edit_campaign', 'bx_massmailer', 7, 128, 1, 'edit-campaign', '', '', '', '', 0, 1, 0, 'BxMassMailerPageEntry', 'modules/boonex/massmailer/classes/BxMassMailerPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_massmailer_edit_campaign', 1, @sName, '_bx_massmailer_page_block_title_entry_breadcrumb', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:17:"entity_breadcrumb";}', 0, 0, 0),
+('bx_massmailer_edit_campaign', 2, @sName, '_bx_massmailer_page_block_title_edit_campaign', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:11:"entity_edit";}', 0, 0, 1),
+('bx_massmailer_edit_campaign', 3, @sName, '_bx_massmailer_page_block_title_attributes', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:10:"attributes";}', 0, 0, 1);
+
+-- PAGE: view campaign
+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_massmailer_view_campaign', '_bx_massmailer_page_title_sys_view_campaign', '_bx_massmailer_page_title_view_campaign', 'bx_massmailer', 5, 128, 1, 'view-campaign', '', '', '', '', 0, 1, 0, 'BxMassMailerPageEntry', 'modules/boonex/massmailer/classes/BxMassMailerPageEntry.php');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_massmailer_view_campaign', 1, @sName, '_bx_massmailer_page_block_title_entry_breadcrumb', 13, 2147483647, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:17:"entity_breadcrumb";}', 0, 0, 0),
+('bx_massmailer_view_campaign', 1, @sName, '_bx_massmailer_page_block_title_view_campaign_info', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:12:"campagn_info";}', 0, 0, 1),
+('bx_massmailer_view_campaign', 1, @sName, '_bx_massmailer_page_block_title_view_campaign_subscribers', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:19:"campagn_subscribers";}', 0, 0, 2),
+('bx_massmailer_view_campaign', 1, @sName, '_bx_massmailer_page_block_title_view_campaign_links', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:13:"campagn_links";}', 0, 0, 3);
+
+-- PAGE: campaigns 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_massmailer_campaigns', '_bx_massmailer_page_title_sys_manage_campaigns', '_bx_massmailer_page_title_manage_campaigns', @sName, 5, 128, 1, 'massmailer-campaigns', 'page.php?i=massmailer-campaigns', '', '', '', 0, 1, 0, 'BxMassMailerPageBrowse', 'modules/boonex/massmailer/classes/BxMassMailerPageBrowse.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_massmailer_campaigns', 1, @sName, '_bx_massmailer_page_block_title_system_manage_campaigns', '_bx_massmailer_page_block_title_manage_campaigns', 11, 128, 'service', 'a:3:{s:6:\"module\";s:13:\"bx_massmailer\";s:6:\"method\";s:12:\"manage_tools\";s:6:\"params\";a:1:{i:0;s:9:\"campaigns\";}}', 0, 1, 0),
+('bx_massmailer_campaigns', 1, @sName, '_bx_massmailer_page_block_title_system_viewsubscribers', '_bx_massmailer_page_block_title_viewsubscribers', 11, 128, 'service', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:17:"total_subscribers";}', 0, 0, 1);
+
+-- MENU: module sub-menu
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_massmailer_submenu', '_bx_massmailer_menu_title_submenu', 'bx_massmailer_submenu', 'bx_massmailer', 8, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_massmailer_submenu', @sName, '_bx_massmailer_menu_set_title_submenu', 0);
+
+-- 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', @sName, 'create-campaign', '_bx_massmailer_menu_item_title_system_create_entry', '_bx_massmailer_menu_item_title_create_entry', 'page.php?i=create-campaign', '', '', 'envelope col-red2', '', 128, 1, 1, IFNULL(@iAddMenuOrder, 0) + 1);
+
+-- 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, 'massmailer-campaigns', '_bx_massmailer_menu_item_title_system_admt_mailer', '_bx_massmailer_menu_item_title_admt_mailer', 'page.php?i=massmailer-campaigns', '', '_self', '', 'a:2:{s:6:"module";s:13:"bx_massmailer";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 128, 1, 0, @iManageMenuOrder + 1);
+
+-- MENU: account dashboard
+SET @iMoAccountDashboard = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WHERE `set_name`='sys_account_dashboard' LIMIT 1);
+INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES
+('sys_account_dashboard', @sName, 'dashboard-massmailer', '_bx_massmailer_menu_item_title_system_admt_mailer', '_bx_massmailer_menu_item_title_admt_mailer', 'page.php?i=massmailer-campaigns', '', '', 'envelope col-red', '', '', 128, 1, 0, 1, @iMoAccountDashboard + 1);
+
+-- GRIDS: campaigns 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_massmailer_campaigns', 'Sql', 'SELECT * FROM `bx_massmailer_campaigns` WHERE 1 ', 'bx_massmailer_campaigns', 'id', 'added', '', '', 20, NULL, 'start', '', 'title', '', 'like', '', '', 128, 'BxMassMailerGridCampaigns', 'modules/boonex/massmailer/classes/BxMassMailerGridCampaigns.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_massmailer_campaigns', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_massmailer_campaigns', 'title', '_bx_massmailer_grid_column_title_adm_title', '26%', 0, '22', '', 2),
+('bx_massmailer_campaigns', 'author', '_bx_massmailer_grid_column_title_adm_author', '8%', 0, '22', '', 3),
+('bx_massmailer_campaigns', 'segments', '_bx_massmailer_grid_column_title_adm_segment', '10%', 0, '22', '', 4),
+('bx_massmailer_campaigns', 'is_one_per_account', '_bx_massmailer_grid_column_title_adm_is_one_per_account', '10%', 0, '0', '', 5),
+('bx_massmailer_campaigns', 'added', '_bx_massmailer_grid_column_title_adm_date_created', '10%', 0, '15', '', 6),
+('bx_massmailer_campaigns', 'date_sent', '_bx_massmailer_grid_column_title_adm_date_sent', '10%', 0, '22', '', 7),
+('bx_massmailer_campaigns', 'actions', '', '24%', 0, '', '', 8);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_massmailer_campaigns', 'bulk', 'delete', '_bx_massmailer_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_massmailer_campaigns', 'single', 'edit', '_bx_massmailer_grid_action_title_adm_edit', 'pencil-alt', 1, 0, 1),
+('bx_massmailer_campaigns', 'single', 'delete', '_bx_massmailer_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_massmailer_campaigns', 'single', 'copy', '_bx_massmailer_grid_action_title_adm_copy', 'copy', 1, 0, 4),
+('bx_massmailer_campaigns', 'single', 'send_test', '_bx_massmailer_grid_action_title_adm_send_test', 'envelope-open', 1, 0, 5),
+('bx_massmailer_campaigns', 'single', 'view', '_bx_massmailer_grid_action_title_adm_view', 'eye', 1, 0, 6),
+('bx_massmailer_campaigns', 'single', 'send_all', '_bx_massmailer_grid_action_title_adm_send_all', 'envelope', 1, 0, 7),
+('bx_massmailer_campaigns', 'independent', 'add', '_bx_massmailer_grid_action_title_adm_add', '', 0, 0, 1);
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES
+(@sName, '_bx_massmailer_email_name', 'bx_massmailer_email', '_bx_massmailer_email_subject', '_bx_massmailer_email_body');
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_massmailer', 'use massmailer', NULL, '_bx_massmailer_acl_action_use_massmailer', '', 1, 3);
+SET @iIdActionUseMassmailer = LAST_INSERT_ID();
+
+SET @iAdministrator = 8;
+
+INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
+(@iAdministrator, @iIdActionUseMassmailer);
+
+
+-- CRON
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_massmailer_cron', '0 1 * * *', 'BxMassMailerCron', 'modules/boonex/massmailer/classes/BxMassMailerCron.php', '');
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+(@sName, 'BxMassMailerAlertsResponse', 'modules/boonex/massmailer/classes/BxMassMailerAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('account', 'change_receive_news', @iHandler);

+ 51 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/install/config.php

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

+ 25 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/install/installer.php

@@ -0,0 +1,25 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+class BxOrgsUpdater extends BxDolStudioUpdater
+{
+    function __construct($aConfig)
+	{
+        parent::__construct($aConfig);
+    }
+
+    public function actionExecuteSql($sOperation)
+    {
+        if($sOperation == 'install') {
+            if(!$this->oDb->isFieldExists('bx_organizations_data', 'rate'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_data` ADD `rate` float NOT NULL default '0' AFTER `views`");
+            if(!$this->oDb->isFieldExists('bx_organizations_data', 'votes'))
+                $this->oDb->query("ALTER TABLE `bx_organizations_data` ADD `votes` int(11) NOT NULL default '0' AFTER `rate`");
+        }
+
+        return parent::actionExecuteSql($sOperation);
+    }
+}

+ 4 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/install/langs/en.xml

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

+ 19 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/install/sql/enable.sql

@@ -0,0 +1,19 @@
+-- MENUS
+UPDATE `sys_menu_items` SET `title_system`='_bx_orgs_menu_item_title_system_become_fan' WHERE `set_name`='bx_organizations_view_actions_all' AND `name`='profile-fan-add';
+UPDATE `sys_menu_items` SET `title_system`='_bx_orgs_menu_item_title_system_leave_organization' WHERE `set_name`='bx_organizations_view_actions_all' AND `name`='profile-fan-remove';
+UPDATE `sys_menu_items` SET `title_system`='_bx_orgs_menu_item_title_system_subscribe' WHERE `set_name`='bx_organizations_view_actions_all' AND `name`='profile-subscribe-add';
+UPDATE `sys_menu_items` SET `title_system`='_bx_orgs_menu_item_title_system_unsubscribe' WHERE `set_name`='bx_organizations_view_actions_all' AND `name`='profile-subscribe-remove';
+
+DELETE FROM `sys_menu_items` WHERE `set_name`='bx_organizations_view_actions_all' AND `name`='vote';
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('bx_organizations_view_actions_all', 'bx_organizations', 'vote', '_sys_menu_item_title_system_va_vote', '', '', '', '', '', '', '', 0, 2147483647, 1, 0, 215);
+
+
+-- VIEWS
+UPDATE `sys_objects_view` SET `module`='bx_organizations' WHERE `name`='bx_organizations';
+
+
+-- VOTES
+DELETE FROM `sys_objects_vote` WHERE `Name`='bx_organizations';
+INSERT INTO `sys_objects_vote` (`Name`, `TableMain`, `TableTrack`, `PostTimeout`, `MinValue`, `MaxValue`, `IsUndo`, `IsOn`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldRate`, `TriggerFieldRateCount`, `ClassName`, `ClassFile`) VALUES 
+('bx_organizations', 'bx_organizations_votes', 'bx_organizations_votes_track', '604800', '1', '1', '0', '1', 'bx_organizations_data', 'id', 'author', 'rate', 'votes', '', '');

+ 18 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/install/sql/install.sql

@@ -0,0 +1,18 @@
+-- TABLES
+CREATE TABLE IF NOT EXISTS `bx_organizations_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_organizations_votes_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);

+ 242 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/classes/BxOrgsConfig.php

@@ -0,0 +1,242 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Organizations Organizations
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxOrgsConfig extends BxBaseModProfileConfig
+{
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+
+        $this->_aMenuItems2MethodsSubmenu = array_merge($this->_aMenuItems2MethodsSubmenu, array(
+            'organization-profile-subscriptions' => 'checkAllowedSubscriptionsView'
+        ));
+
+        $this->_aMenuItems2MethodsActions = array_merge($this->_aMenuItems2MethodsActions, array(
+            'view-organization-profile' => 'checkAllowedView',
+            'edit-organization-profile' => 'checkAllowedEdit',
+            'edit-organization-cover' => 'checkAllowedChangeCover',
+            'invite-to-organization' => 'checkAllowedInvite',
+            'delete-organization-profile' => 'checkAllowedDelete',
+            'profile-fan-add' => 'checkAllowedFanAdd',
+            'profile-fan-remove' => 'checkAllowedFanRemove',
+        ));
+
+        $this->CNF = array (
+
+            // module icon
+            'ICON' => 'briefcase col-red2',
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+            'TABLE_ENTRIES_FULLTEXT' => 'search_fields',
+            'TABLE_ADMINS' => $aModule['db_prefix'] . 'admins',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_NAME' => 'org_name',
+            'FIELD_TITLE' => 'org_name',
+            'FIELD_TEXT' => 'org_desc',
+            'FIELD_PICTURE' => 'picture',
+            'FIELD_COVER' => 'cover',
+            'FIELD_JOIN_CONFIRMATION' => 'join_confirmation',
+            'FIELD_ALLOW_VIEW_TO' => 'allow_view_to',
+            'FIELD_VIEWS' => 'views',
+            'FIELD_COMMENTS' => 'comments',
+            'FIELDS_QUICK_SEARCH' => array('org_name'),
+            'FIELD_LOCATION_PREFIX' => 'location',
+            'FIELD_LABELS' => 'labels',
+            'FIELDS_WITH_KEYWORDS' => 'auto', // can be 'auto', array of fields or comma separated string of field names, works only when OBJECT_METATAGS is specified
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-organization-profile',
+            'URI_VIEW_FRIENDS' => 'organization-profile-friends',
+            'URI_VIEW_FRIEND_REQUESTS' => 'organization-friend-requests',
+            'URI_VIEW_FAVORITES' => 'organization-profile-favorites',
+            'URI_EDIT_ENTRY' => 'edit-organization-profile',
+            'URI_EDIT_COVER' => 'edit-organization-cover',
+            'URI_JOINED_ENTRIES' => 'joined-organizations',
+            'URI_MANAGE_COMMON' => 'organizations-manage',
+
+            'URL_HOME' => 'page.php?i=organizations-home',
+            'URL_CREATE' => 'page.php?i=create-organization-profile',
+            'URL_ENTRY_FANS' => 'page.php?i=organization-profile-fans',
+            'URL_MANAGE_COMMON' => 'page.php?i=organizations-manage',
+            'URL_MANAGE_ADMINISTRATION' => 'page.php?i=organizations-administration',
+
+            // some params
+            'PARAM_AUTOAPPROVAL' => 'bx_organizations_autoapproval',
+            'PARAM_ENABLE_ACTIVATION_LETTER' => 'bx_organizations_enable_profile_activation_letter',
+            'PARAM_DEFAULT_ACL_LEVEL' => 'bx_organizations_default_acl_level',
+            'PARAM_NUM_RSS' => 'bx_organizations_num_rss',
+            'PARAM_NUM_CONNECTIONS_QUICK' => 'bx_organizations_num_connections_quick',
+            'PARAM_SEARCHABLE_FIELDS' => 'bx_organizations_searchable_fields',
+            'PARAM_PER_PAGE_BROWSE_SHOWCASE' => 'bx_organizations_per_page_browse_showcase',
+            'PARAM_PER_PAGE_BROWSE_RECOMMENDED' => 'bx_organizations_per_page_browse_recommended',
+            'PARAM_PUBLIC_SBSN' => 'bx_organizations_public_subscriptions',
+            'PARAM_PUBLIC_SBSD' => 'bx_organizations_public_subscribed_me',
+            'PARAM_REDIRECT_AADD' => 'bx_organizations_redirect_aadd',
+            'PARAM_REDIRECT_AADD_CUSTOM_URL' => 'bx_organizations_redirect_aadd_custom_url',
+            'PARAM_LABELS' => 'bx_organizations_labels',
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_organizations_pics',
+            'OBJECT_STORAGE_COVER' => 'bx_organizations_pics',
+            'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_organizations_thumb',
+            'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_organizations_icon',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR' => 'bx_organizations_avatar',
+            'OBJECT_IMAGES_TRANSCODER_PICTURE' => 'bx_organizations_picture',
+            'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_organizations_cover',
+            'OBJECT_IMAGES_TRANSCODER_COVER_THUMB' => 'bx_organizations_cover_thumb',
+            'OBJECT_IMAGES_TRANSCODER_GALLERY' => 'bx_organizations_gallery',
+            'OBJECT_VIEWS' => 'bx_organizations',
+            'OBJECT_VOTES' => 'bx_organizations',
+            'OBJECT_SCORES' => 'bx_organizations',
+            'OBJECT_FAVORITES' => 'bx_organizations',
+            'OBJECT_FEATURED' => 'bx_organizations',
+            'OBJECT_COMMENTS' => 'bx_organizations',
+            'OBJECT_REPORTS' => 'bx_organizations',
+            'OBJECT_METATAGS' => 'bx_organizations',
+            'OBJECT_FORM_ENTRY' => 'bx_organization',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_organization_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW_FULL' => 'bx_organization_view_full', // for "info" tab on view profile page
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_organization_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_organization_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER' => 'bx_organization_edit_cover',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_organization_delete',
+            'OBJECT_FORM_ENTRY_DISPLAY_INVITE' => 'bx_organization_invite',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_organizations_view_actions', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE' => 'bx_organizations_view_actions_more', // actions menu on view entry page for "more" popup
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_ALL' => 'bx_organizations_view_actions_all', // all actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_MY_ENTRIES' => 'bx_organizations_my', // actions menu on profile entries page
+            'OBJECT_MENU_SUBMENU' => 'bx_organizations_submenu', // main module submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_organizations_view_submenu',  // view entry submenu
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_COVER' => 'bx_organizations_view_submenu_cover',  // view entry submenu displayed in cover
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY_MAIN_SELECTION' => 'organizations-home', // first item in view entry submenu from main module submenu
+            'OBJECT_MENU_SNIPPET_META' => 'bx_organizations_snippet_meta', // menu for snippet meta info
+            'OBJECT_MENU_MANAGE_TOOLS' => 'bx_organizations_menu_manage_tools', //manage menu in content administration tools
+            'OBJECT_PAGE_VIEW_ENTRY' => 'bx_organizations_view_profile',
+            'OBJECT_PAGE_VIEW_ENTRY_CLOSED' => 'bx_organizations_view_profile_closed',
+            'OBJECT_PRIVACY_VIEW' => 'bx_organizations_allow_view_to',
+            'OBJECT_PRIVACY_VIEW_NOTIFICATION_EVENT' => 'bx_organizations_allow_view_notification_to',
+            'OBJECT_GRID_ADMINISTRATION' => 'bx_organizations_administration',
+            'OBJECT_GRID_COMMON' => 'bx_organizations_common',
+            'OBJECT_GRID_CONNECTIONS' => 'bx_organizations_fans',
+            'OBJECT_CONNECTIONS' => 'bx_organizations_fans',
+            'OBJECT_UPLOADERS_COVER' => array('bx_organizations_cover_crop'),
+            'OBJECT_UPLOADERS_PICTURE' => array('bx_organizations_picture_crop'),
+
+            'EMAIL_FRIEND_REQUEST' => 'bx_organizations_friend_request',
+            'EMAIL_INVITATION' => 'bx_organizations_invitation',
+            'EMAIL_JOIN_REQUEST' => 'bx_organizations_join_request',
+            'EMAIL_JOIN_CONFIRM' => 'bx_organizations_join_confirm',
+            'EMAIL_FAN_BECOME_ADMIN' => 'bx_organizations_fan_become_admin',
+            'EMAIL_ADMIN_BECOME_FAN' => 'bx_organizations_admin_become_fan',
+            'EMAIL_FAN_REMOVE' => 'bx_organizations_fan_remove',
+            'EMAIL_JOIN_REJECT' => 'bx_organizations_join_reject',
+
+            'TRIGGER_MENU_PROFILE_VIEW_SUBMENU' => 'trigger_profile_view_submenu',
+            'TRIGGER_MENU_PROFILE_SNIPPET_META' => 'trigger_profile_snippet_meta',
+            'TRIGGER_MENU_PROFILE_VIEW_ACTIONS' => 'trigger_profile_view_actions',
+            'TRIGGER_PAGE_VIEW_ENTRY' => 'trigger_page_profile_view_entry',
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_organizations_view_submenu' => $this->_aMenuItems2MethodsSubmenu,
+                'bx_organizations_view_actions' => $this->_aMenuItems2MethodsActions,
+                'bx_organizations_view_actions_more' => $this->_aMenuItems2MethodsActions,
+                'bx_organizations_view_actions_all' => $this->_aMenuItems2MethodsActions,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'status' => array (
+                    'name' => 'bx-organizations-status-not-active',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_orgs_txt_account_pending',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_orgs_txt_account_suspended',
+                    ),
+                ),
+                'status_moderation' => array (
+                    'name' => 'bx-organizations-status-not-active-moderation',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_orgs_txt_account_pending_moderation',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_orgs_txt_account_suspended_moderation',
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'txt_sample_single' => '_bx_orgs_txt_sample_single',
+            	'txt_sample_comment_single' => '_bx_orgs_txt_sample_comment_single',
+                'txt_sample_vote_single' => '_bx_orgs_txt_sample_vote_single',
+            	'txt_sample_pp_single' => '_bx_orgs_txt_sample_pp_single',
+            	'txt_sample_pp_single_with_article' => '_bx_orgs_txt_sample_pp_single_with_article',
+                'txt_sample_pc_single' => '_bx_orgs_txt_sample_pc_single',
+            	'txt_sample_pc_single_with_article' => '_bx_orgs_txt_sample_pc_single_with_article',
+            	'txt_sample_pi_action' => '_bx_orgs_txt_sample_pi_action',
+            	'txt_sample_pi_action_user' => '_bx_orgs_txt_sample_pi_action_user',
+            	'txt_private_group' => '_bx_orgs_txt_private_organization',
+                'txt_N_fans' => '_bx_orgs_txt_N_friends',
+            	'txt_ntfs_join_request' => '_bx_orgs_txt_ntfs_join_request',
+                'txt_ntfs_fan_added' => '_bx_orgs_txt_ntfs_fan_added',
+            	'txt_ntfs_timeline_post_common' => '_bx_orgs_txt_ntfs_timeline_post_common',
+            	'txt_all_entries_by_author' => '_bx_orgs_page_title_browse_by_author',
+            	'form_field_picture' => '_bx_orgs_form_profile_input_picture_search',
+                'form_field_online' => '_bx_orgs_form_profile_input_online_search',
+                'menu_item_title_befriend_sent' => '_bx_orgs_menu_item_title_befriend_sent',
+                'menu_item_title_unfriend_cancel_request' => '_bx_orgs_menu_item_title_unfriend_cancel_request',
+                'menu_item_title_befriend_confirm' => '_bx_orgs_menu_item_title_befriend_confirm',
+                'menu_item_title_unfriend_reject_request' => '_bx_orgs_menu_item_title_unfriend_reject_request',
+                'menu_item_title_befriend' => '_bx_orgs_menu_item_title_befriend',
+                'menu_item_title_unfriend' => '_bx_orgs_menu_item_title_unfriend',
+            	'menu_item_title_become_fan_sent' => '_bx_orgs_menu_item_title_become_fan_sent',
+                'menu_item_title_leave_group_cancel_request' => '_bx_orgs_menu_item_title_leave_organization_cancel_request',
+                'menu_item_title_become_fan' => '_bx_orgs_menu_item_title_become_fan',
+                'menu_item_title_leave_group' => '_bx_orgs_menu_item_title_leave_organization',
+            	'menu_item_manage_my' => '_bx_orgs_menu_item_title_manage_my',
+            	'menu_item_manage_all' => '_bx_orgs_menu_item_title_manage_all',
+            	'grid_action_err_delete' => '_bx_orgs_grid_action_err_delete',
+            	'grid_txt_account_manager' => '_bx_orgs_grid_txt_account_manager',
+				'filter_item_active' => '_bx_orgs_grid_filter_item_title_adm_active',
+            	'filter_item_pending' => '_bx_orgs_grid_filter_item_title_adm_pending',
+            	'filter_item_suspended' => '_bx_orgs_grid_filter_item_title_adm_suspended',
+                'filter_item_unconfirmed' => '_bx_orgs_grid_filter_item_title_adm_unconfirmed',
+            	'filter_item_select_one_filter1' => '_bx_orgs_grid_filter_item_title_adm_select_one_filter1',
+				'filter_item_select_one_filter2' => '_bx_orgs_grid_filter_item_title_adm_select_one_filter2',
+            	'txt_browse_favorites' => '_bx_orgs_page_title_browse_favorites',
+            	'option_redirect_aadd_profile' => '_bx_orgs_option_redirect_aadd_profile',
+            	'option_redirect_aadd_last' => '_bx_orgs_option_redirect_aadd_last',
+            	'option_redirect_aadd_custom' => '_bx_orgs_option_redirect_aadd_custom'
+            ),
+        );
+
+        $this->_aJsClasses = array(
+        	'manage_tools' => 'BxOrgsManageTools'
+        );
+
+        $this->_aJsObjects = array(
+        	'manage_tools' => 'oBxOrgsManageTools'
+        );
+
+        $this->_aGridObjects = array(
+        	'common' => $this->CNF['OBJECT_GRID_COMMON'],
+        	'administration' => $this->CNF['OBJECT_GRID_ADMINISTRATION'],
+        	
+        );
+    }
+
+}
+
+/** @} */

+ 150 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/config.php

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

+ 418 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/langs/en.xml

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

+ 81 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/disable.sql

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

+ 636 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/enable.sql

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

+ 377 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/install.sql

@@ -0,0 +1,377 @@
+
+SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_storage_default');
+
+-- TABLE: PROFILES
+CREATE TABLE IF NOT EXISTS `bx_organizations_data` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `author` int(10) unsigned NOT NULL,
+  `added` int(11) NOT NULL,
+  `changed` int(11) NOT NULL,
+  `picture` int(11) NOT NULL,
+  `cover` int(11) NOT NULL,
+  `org_name` varchar(255) NOT NULL,
+  `org_cat` int(11) NOT NULL,
+  `org_desc` text NOT NULL,
+  `views` int(11) NOT NULL default '0',
+  `rate` float NOT NULL default '0',
+  `votes` int(11) NOT NULL default '0',
+  `score` int(11) NOT NULL default '0',
+  `sc_up` int(11) NOT NULL default '0',
+  `sc_down` int(11) NOT NULL default '0',
+  `favorites` int(11) NOT NULL default '0',
+  `comments` int(11) NOT NULL default '0',
+  `reports` int(11) NOT NULL default '0',
+  `featured` int(11) NOT NULL default '0',
+  `join_confirmation` tinyint(4) NOT NULL DEFAULT '1',
+  `allow_view_to` varchar(16) NOT NULL DEFAULT '3',
+  PRIMARY KEY (`id`),
+  FULLTEXT KEY `search_fields` (`org_name`,`org_desc`)
+);
+
+-- TABLE: STORAGES & TRANSCODERS
+CREATE TABLE IF NOT EXISTS `bx_organizations_pics` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_pics_resized` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `profile_id` int(10) unsigned NOT NULL,
+  `remote_id` varchar(128) NOT NULL,
+  `path` varchar(255) NOT NULL,
+  `file_name` varchar(255) NOT NULL,
+  `mime_type` varchar(128) NOT NULL,
+  `ext` varchar(32) NOT NULL,
+  `size` int(11) NOT NULL,
+  `added` int(11) NOT NULL,
+  `modified` int(11) NOT NULL,
+  `private` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `remote_id` (`remote_id`)
+);
+
+-- TABLE: comments
+CREATE TABLE IF NOT EXISTS `bx_organizations_cmts` (
+  `cmt_id` int(11) NOT NULL AUTO_INCREMENT,
+  `cmt_parent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_vparent_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_object_id` int(11) NOT NULL DEFAULT '0',
+  `cmt_author_id` int(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 IF NOT EXISTS `bx_organizations_views_track` (
+  `object_id` int(11) NOT NULL default '0',
+  `viewer_id` int(11) NOT NULL default '0',
+  `viewer_nip` int(11) unsigned NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  KEY `id` (`object_id`,`viewer_id`,`viewer_nip`)
+);
+
+-- TABLE: VOTES
+CREATE TABLE IF NOT EXISTS `bx_organizations_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_organizations_votes_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `value` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+-- TABLE: favorites
+CREATE TABLE IF NOT EXISTS `bx_organizations_favorites_track` (
+  `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: reports
+CREATE TABLE IF NOT EXISTS `bx_organizations_reports` (
+  `object_id` int(11) NOT NULL default '0',
+  `count` int(11) NOT NULL default '0',
+  UNIQUE KEY `object_id` (`object_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_reports_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(32) NOT NULL default '',
+  `text` text NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `report` (`object_id`, `author_nip`)
+);
+
+-- TABLE: metas
+CREATE TABLE IF NOT EXISTS `bx_organizations_meta_keywords` (
+  `object_id` int(10) unsigned NOT NULL,
+  `keyword` varchar(255) NOT NULL,
+  KEY `object_id` (`object_id`),
+  KEY `keyword` (`keyword`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_organizations_meta_locations` (
+  `object_id` int(10) unsigned NOT NULL,
+  `lat` double NOT NULL,
+  `lng` double NOT NULL,
+  `country` varchar(2) NOT NULL,
+  `state` varchar(255) NOT NULL,
+  `city` varchar(255) NOT NULL,
+  `zip` varchar(255) NOT NULL,
+  `street` varchar(255) NOT NULL,
+  `street_number` varchar(255) NOT NULL,
+  PRIMARY KEY (`object_id`),
+  KEY `country_state_city` (`country`,`state`(8),`city`(8))
+);
+
+CREATE TABLE `bx_organizations_meta_mentions` (
+  `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: fans
+CREATE TABLE IF NOT EXISTS `bx_organizations_fans` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `initiator` int(11) NOT NULL,
+  `content` int(11) NOT NULL,
+  `mutual` tinyint(4) NOT NULL,
+  `added` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `initiator` (`initiator`,`content`),
+  KEY `content` (`content`)
+);
+
+-- TABLE: admins
+CREATE TABLE IF NOT EXISTS `bx_organizations_admins` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `group_profile_id` int(10) unsigned NOT NULL,
+  `fan_id` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `admin` (`group_profile_id`,`fan_id`)
+);
+
+-- TABLE: scores
+CREATE TABLE IF NOT EXISTS `bx_organizations_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_organizations_scores_track` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `object_id` int(11) NOT NULL default '0',
+  `author_id` int(11) NOT NULL default '0',
+  `author_nip` int(11) unsigned NOT NULL default '0',
+  `type` varchar(8) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY (`id`),
+  KEY `vote` (`object_id`, `author_nip`)
+);
+
+
+-- STORAGES & TRANSCODERS
+INSERT INTO `sys_objects_storage` (`object`, `engine`, `params`, `token_life`, `cache_control`, `levels`, `table_files`, `ext_mode`, `ext_allow`, `ext_deny`, `quota_size`, `current_size`, `quota_number`, `current_number`, `max_file_size`, `ts`) VALUES
+('bx_organizations_pics', @sStorageEngine, '', 360, 2592000, 3, 'bx_organizations_pics', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
+('bx_organizations_pics_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_organizations_pics_resized', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0);
+
+INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`) VALUES 
+('bx_organizations_icon', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_thumb', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_avatar', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_picture', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_cover', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_cover_thumb', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0'),
+('bx_organizations_gallery', 'bx_organizations_pics_resized', 'Storage', 'a:1:{s:6:"object";s:21:"bx_organizations_pics";}', 'no', '1', '2592000', '0');
+
+INSERT INTO `sys_transcoder_filters` (`transcoder_object`, `filter`, `filter_params`, `order`) VALUES 
+('bx_organizations_icon', 'Resize', 'a:3:{s:1:"w";s:2:"32";s:1:"h";s:2:"32";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_thumb', 'Resize', 'a:3:{s:1:"w";s:2:"48";s:1:"h";s:2:"48";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_avatar', 'Resize', 'a:3:{s:1:"w";s:2:"96";s:1:"h";s:2:"96";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_picture', 'Resize', 'a:3:{s:1:"w";s:4:"1024";s:1:"h";s:4:"1024";s:13:"square_resize";s:1:"0";}', '0'),
+('bx_organizations_cover', 'Resize', 'a:1:{s:1:"w";s:4:"2000";}', '0'),
+('bx_organizations_cover_thumb', 'Resize', 'a:3:{s:1:"w";s:2:"48";s:1:"h";s:2:"48";s:13:"square_resize";s:1:"1";}', '0'),
+('bx_organizations_gallery', 'Resize', 'a:1:{s:1:"w";s:3:"500";}', '0');
+
+
+-- FORMS
+INSERT INTO `sys_objects_form`(`object`, `module`, `title`, `action`, `form_attrs`, `table`, `key`, `uri`, `uri_title`, `submit_name`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_organization', 'bx_organizations', '_bx_orgs_form_profile', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_organizations_data', 'id', '', '', 'do_submit', '', 0, 1, 'BxOrgsFormEntry', 'modules/boonex/organizations/classes/BxOrgsFormEntry.php');
+
+INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
+('bx_organization', 'bx_organization_add', 'bx_organizations', 0, '_bx_orgs_form_profile_display_add'),
+('bx_organization', 'bx_organization_delete', 'bx_organizations', 0, '_bx_orgs_form_profile_display_delete'),
+('bx_organization', 'bx_organization_edit', 'bx_organizations', 0, '_bx_orgs_form_profile_display_edit'),
+('bx_organization', 'bx_organization_edit_cover', 'bx_organizations', 0, '_bx_orgs_form_profile_display_edit_cover'),
+('bx_organization', 'bx_organization_view', 'bx_organizations', 1, '_bx_orgs_form_profile_display_view'),
+('bx_organization', 'bx_organization_view_full', 'bx_organizations', 1, '_bx_orgs_form_profile_display_view_full'),
+('bx_organization', 'bx_organization_invite', 'bx_organizations', 0, '_bx_orgs_form_profile_display_invite');
+
+INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES 
+('bx_organization', 'bx_organizations', 'allow_view_to', 3, '', 0, 'custom', '_bx_orgs_form_profile_input_sys_allow_view_to', '_bx_orgs_form_profile_input_allow_view_to', '_bx_orgs_form_profile_input_allow_view_to_info', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'delete_confirm', 1, '', 0, 'checkbox', '_bx_orgs_form_profile_input_sys_delete_confirm', '_bx_orgs_form_profile_input_delete_confirm', '_bx_orgs_form_profile_input_delete_confirm_info', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_profile_input_delete_confirm_error', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'do_submit', '_sys_form_account_input_submit', '', 0, 'submit', '_bx_orgs_form_profile_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'org_desc', '', '', 0, 'textarea', '_bx_orgs_form_profile_input_sys_org_desc', '_bx_orgs_form_profile_input_org_desc', '', 0, 0, 1, '', '', '', '', '', '', 'XssHtml', '', 1, 1),
+('bx_organization', 'bx_organizations', 'org_cat', '', '#!bx_organizations_cats', 0, 'select', '_bx_orgs_form_profile_input_sys_org_cat', '_bx_orgs_form_profile_input_org_cat', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_profile_input_org_cat_err', 'Xss', '', 1, 1),
+('bx_organization', 'bx_organizations', 'org_name', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_org_name', '_bx_orgs_form_profile_input_org_name', '', 1, 0, 0, '', '', '', 'avail', '', '_bx_orgs_form_profile_input_org_name_err', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'initial_members', '', '', 0, 'custom', '_bx_orgs_form_profile_input_sys_initial_members', '_bx_orgs_form_profile_input_initial_members', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 1),
+('bx_organization', 'bx_organizations', 'join_confirmation', 1, '', 1, 'switcher', '_bx_orgs_form_profile_input_sys_join_confirm', '_bx_orgs_form_profile_input_join_confirm', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'cover', 'a:1:{i:0;s:27:"bx_organizations_cover_crop";}', 'a:1:{s:27:"bx_organizations_cover_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_orgs_form_profile_input_sys_cover', '_bx_orgs_form_profile_input_cover', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'picture', 'a:1:{i:0;s:29:"bx_organizations_picture_crop";}', 'a:1:{s:29:"bx_organizations_picture_crop";s:24:"_sys_uploader_crop_title";}', 0, 'files', '_bx_orgs_form_profile_input_sys_picture', '_bx_orgs_form_profile_input_picture', '', 0, 0, 0, '', '', '', '', '', '_bx_orgs_form_profile_input_picture_err', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'location', '', '', 0, 'location', '_sys_form_input_sys_location', '_sys_form_input_location', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'profile_email', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_profile_email', '_bx_orgs_form_profile_input_profile_email', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'profile_status', '', '', 0, 'custom', '_bx_orgs_form_profile_input_sys_profile_status', '_bx_orgs_form_profile_input_profile_status', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'profile_ip', '', '', 0, 'text', '_bx_orgs_form_profile_input_sys_profile_ip', '_bx_orgs_form_profile_input_profile_ip', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_organization', 'bx_organizations', 'labels', '', '', 0, 'custom', '_sys_form_input_sys_labels', '_sys_form_input_labels', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'added', '', '', 0, 'datetime', '_bx_orgs_form_profile_input_sys_date_added', '_bx_orgs_form_profile_input_date_added', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_organization', 'bx_organizations', 'changed', '', '', 0, 'datetime', '_bx_orgs_form_profile_input_sys_date_changed', '_bx_orgs_form_profile_input_date_changed', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
+
+INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_organization_add', 'initial_members', 2147483647, 1, 1),
+('bx_organization_add', 'picture', 2147483647, 1, 2),
+('bx_organization_add', 'org_name', 2147483647, 1, 3),
+('bx_organization_add', 'org_cat', 2147483647, 1, 4),
+('bx_organization_add', 'org_desc', 2147483647, 1, 5),
+('bx_organization_add', 'location', 2147483647, 1, 6),
+('bx_organization_add', 'join_confirmation', 2147483647, 1, 7),
+('bx_organization_add', 'allow_view_to', 2147483647, 1, 8),
+('bx_organization_add', 'do_submit', 2147483647, 1, 9),
+
+('bx_organization_invite', 'initial_members', 2147483647, 1, 1),
+('bx_organization_invite', 'do_submit', 2147483647, 1, 2),
+
+('bx_organization_delete', 'delete_confirm', 2147483647, 1, 1),
+('bx_organization_delete', 'do_submit', 2147483647, 1, 2),
+
+('bx_organization_edit', 'picture', 2147483647, 1, 1),
+('bx_organization_edit', 'org_name', 2147483647, 1, 2),
+('bx_organization_edit', 'org_cat', 2147483647, 1, 3),
+('bx_organization_edit', 'org_desc', 2147483647, 1, 4),
+('bx_organization_edit', 'location', 2147483647, 1, 5),
+('bx_organization_edit', 'join_confirmation', 2147483647, 1, 6),
+('bx_organization_edit', 'allow_view_to', 2147483647, 1, 7),
+('bx_organization_edit', 'do_submit', 2147483647, 1, 8),
+
+('bx_organization_edit_cover', 'cover', 2147483647, 1, 1),
+('bx_organization_edit_cover', 'do_submit', 2147483647, 1, 2),
+
+('bx_organization_view', 'org_name', 2147483647, 1, 1),
+('bx_organization_view', 'org_cat', 2147483647, 1, 2),
+('bx_organization_view', 'profile_email', 192, 1, 3),
+('bx_organization_view', 'profile_status', 192, 1, 4),
+('bx_organization_view', 'profile_ip', 192, 1, 5),
+('bx_organization_view', 'added', 192, 1, 6),
+('bx_organization_view', 'changed', 192, 1, 7),
+
+('bx_organization_view_full', 'org_name', 2147483647, 1, 1),
+('bx_organization_view_full', 'org_cat', 2147483647, 1, 2),
+('bx_organization_view_full', 'org_desc', 2147483647, 1, 3),
+('bx_organization_view_full', 'profile_email', 192, 1, 4),
+('bx_organization_view_full', 'profile_status', 192, 1, 5);
+
+
+-- PRE-VALUES
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`) VALUES
+('bx_organizations_cats', '_bx_orgs_pre_lists_cats', 'bx_organizations', '0');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_organizations_cats', '', 0, '_sys_please_select', ''),
+('bx_organizations_cats', '1', 1, '_bx_orgs_cat_Agriculture', ''),
+('bx_organizations_cats', '2', 2, '_bx_orgs_cat_Financial', ''),
+('bx_organizations_cats', '3', 3, '_bx_orgs_cat_Biotech', ''),
+('bx_organizations_cats', '4', 4, '_bx_orgs_cat_Cause', ''),
+('bx_organizations_cats', '5', 5, '_bx_orgs_cat_Chemical', ''),
+('bx_organizations_cats', '6', 6, '_bx_orgs_cat_Religious', ''),
+('bx_organizations_cats', '7', 7, '_bx_orgs_cat_Community', ''),
+('bx_organizations_cats', '8', 8, '_bx_orgs_cat_Company', ''),
+('bx_organizations_cats', '9', 9, '_bx_orgs_cat_Entertainment', ''),
+('bx_organizations_cats', '10', 10, '_bx_orgs_cat_Technology', ''),
+('bx_organizations_cats', '11', 11, '_bx_orgs_cat_Consulting', ''),
+('bx_organizations_cats', '12', 12, '_bx_orgs_cat_Education', ''),
+('bx_organizations_cats', '13', 13, '_bx_orgs_cat_Energy', ''),
+('bx_organizations_cats', '14', 14, '_bx_orgs_cat_Engineering', ''),
+('bx_organizations_cats', '15', 15, '_bx_orgs_cat_Food', ''),
+('bx_organizations_cats', '16', 16, '_bx_orgs_cat_Government', ''),
+('bx_organizations_cats', '17', 17, '_bx_orgs_cat_Health', ''),
+('bx_organizations_cats', '18', 18, '_bx_orgs_cat_Medical', ''),
+('bx_organizations_cats', '19', 19, '_bx_orgs_cat_Industrial', ''),
+('bx_organizations_cats', '20', 20, '_bx_orgs_cat_Insurance', ''),
+('bx_organizations_cats', '21', 21, '_bx_orgs_cat_Internet', ''),
+('bx_organizations_cats', '22', 22, '_bx_orgs_cat_Software', ''),
+('bx_organizations_cats', '23', 23, '_bx_orgs_cat_Legal', ''),
+('bx_organizations_cats', '24', 24, '_bx_orgs_cat_Media', ''),
+('bx_organizations_cats', '25', 25, '_bx_orgs_cat_School', ''),
+('bx_organizations_cats', '26', 26, '_bx_orgs_cat_NGO', ''),
+('bx_organizations_cats', '27', 27, '_bx_orgs_cat_NPO', ''),
+('bx_organizations_cats', '28', 28, '_bx_orgs_cat_Political', ''),
+('bx_organizations_cats', '29', 29, '_bx_orgs_cat_Retail', ''),
+('bx_organizations_cats', '30', 30, '_bx_orgs_cat_Small_Business', ''),
+('bx_organizations_cats', '31', 31, '_bx_orgs_cat_Telecommunication', ''),
+('bx_organizations_cats', '32', 32, '_bx_orgs_cat_Transport', ''),
+('bx_organizations_cats', '33', 33, '_bx_orgs_cat_Travel', ''),
+('bx_organizations_cats', '34', 34, '_bx_orgs_cat_University', ''),
+('bx_organizations_cats', '35', 35, '_bx_orgs_cat_Other', '');
+
+
+-- CONTENT INFO
+INSERT INTO `sys_objects_content_info` (`name`, `title`, `alert_unit`, `alert_action_add`, `alert_action_update`, `alert_action_delete`, `class_name`, `class_file`) VALUES
+('bx_organizations', '_bx_orgs', 'bx_organizations', 'added', 'edited', 'deleted', '', ''),
+('bx_organizations_cmts', '_bx_orgs_cmts', 'bx_organizations', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+INSERT INTO `sys_content_info_grids` (`object`, `grid_object`, `grid_field_id`, `condition`, `selection`) VALUES
+('bx_organizations', 'bx_organizations_administration', 'td`.`id', '', ''),
+('bx_organizations', 'bx_organizations_common', 'td`.`id', '', '');
+
+
+-- SEARCH EXTENDED
+INSERT INTO `sys_objects_search_extended` (`object`, `object_content_info`, `module`, `title`, `active`, `class_name`, `class_file`) VALUES
+('bx_organizations', 'bx_organizations', 'bx_organizations', '_bx_orgs_search_extended', 1, '', ''),
+('bx_organizations_cmts', 'bx_organizations_cmts', 'bx_organizations', '_bx_orgs_search_extended_cmts', 1, 'BxTemplSearchExtendedCmts', '');
+
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_organizations', '_bx_orgs', '_bx_orgs', 'bx_organizations@modules/boonex/organizations/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_organizations', '{url_studio}module.php?name=bx_organizations', '', 'bx_organizations@modules/boonex/organizations/|std-icon.svg', '_bx_orgs', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));

+ 38 - 0
modules/boonex/organizations/updates/9.0.10_9.0.11/source/install/sql/uninstall.sql

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

+ 51 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/install/config.php

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

+ 13 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/install/installer.php

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

+ 5 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/install/langs/en.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+    <string_add name="_bx_payment_grid_column_title_ods_item"><![CDATA[Product]]></string_add>
+    <string_add name="_bx_payment_txt_license"><![CDATA[License]]></string_add>
+</resources>

+ 8 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/install/sql/install.sql

@@ -0,0 +1,8 @@
+SET @sName = 'bx_payment';
+
+
+-- GRIDS
+UPDATE `sys_objects_grid` SET `source`='SELECT `tt`.`id` AS `id`, `tt`.`seller_id` AS `seller_id`, `tt`.`module_id` AS `module_id`, `tt`.`item_id` AS `item_id`, `ttp`.`order` AS `transaction`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''single'' ' WHERE `object`='bx_payment_grid_orders_history';
+
+UPDATE `sys_grid_fields` SET `name`='item', `title`='_bx_payment_grid_column_title_ods_item' WHERE `object`='bx_payment_grid_orders_history' AND `name`='license';
+UPDATE `sys_grid_fields` SET `name`='item', `title`='_bx_payment_grid_column_title_ods_item' WHERE `object`='bx_payment_grid_orders_processed' AND `name`='license';

+ 154 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/classes/BxPaymentGridCart.php

@@ -0,0 +1,154 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+
+class BxPaymentGridCart extends BxBaseModPaymentGridCarts
+{
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_bSelectAll = true;
+    }
+
+    public function performActionCheckout()
+    {
+    	$aParams = array(
+			'seller_id' => bx_process_input(bx_get('seller_id'), BX_DATA_INT), 
+			'provider' => bx_process_input(bx_get('provider')), 
+			'items' => bx_process_input(bx_get('ids'))    		
+    	);
+    	if(empty($aParams['seller_id']) || empty($aParams['provider']))
+    		return echoJson(array());
+
+        if(empty($aParams['items']) || !is_array($aParams['items'])) 
+        	return echoJson(array('msg' => _t('_bx_payment_err_nothing_selected')));
+
+		$oProvider = $this->_oModule->getObjectProvider($aParams['provider'], $aParams['seller_id']);
+		if($oProvider !== false && method_exists($oProvider, 'getCheckoutParamsSingle'))
+			$aParams = $oProvider->getCheckoutParamsSingle($aParams, $this);
+
+		$sLink = $this->_oModule->_oConfig->getUrl('URL_CART_CHECKOUT');
+		$sLink = $sLink . (strpos($sLink, '?') === false ? '?' : '&') . http_build_query($aParams);
+
+		echoJson(array(
+			'eval' => $this->_oModule->_oConfig->getJsObject('cart') . '.onCartCheckout(oData);', 
+			'link' => $sLink
+		));
+    }
+
+    protected function _getCellTitle($mixedValue, $sKey, $aField, $aRow)
+    {
+    	return parent::_getCellDefault($this->_oModule->_oTemplate->displayLink('link', array(
+            'href' => $aRow['url'],
+            'title' => bx_html_attribute($aRow['title']),
+            'content' => $aRow['title']
+    	)), $sKey, $aField, $aRow);
+    }
+
+	protected function _getCellPriceSingle($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault($this->_sCurrencySign . $mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function _getActionCheckout ($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = array())
+    {
+        return '';
+    }
+
+    protected function _getActions ($sType, $sActionData = false, $isSmall = false, $isDisabled = false, $isPermanentState = false, $aRow = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$sActions = '';
+    	if($sType == 'bulk' && !empty($this->_aQueryAppend['seller_id'])) {
+    		$sActionName = 'checkout';
+
+    		$iClientId = (int)$this->_aQueryAppend['client_id'];
+            $iSellerId = (int)$this->_aQueryAppend['seller_id'];
+
+            $oCart = $this->_oModule->getObjectCart();
+    		$aProviders = $this->_oModule->_oDb->getVendorInfoProvidersSingle($iSellerId);
+    		foreach($aProviders as $aProvider) {
+				$sAction = $this->_getActionDefault($sType, $sActionName, array(
+					'title'=> _t('_bx_payment_grid_action_title_crt_checkout', _t($CNF['T']['TXT_CART_PROVIDER'] . $aProvider['name'])),
+	    			'icon' => '',
+					'icon_only' => 0,
+	    			'confirm' => 0,
+					'attr' => array(
+						'bx_grid_action_' . $sType => $sActionName,
+						'bx_grid_action_append' => json_encode(array('provider' => $aProvider['name'])),
+						'bx_grid_action_confirm' => 0,
+						'bx_grid_action_reset_paginate' => 0,
+					)
+				), $isSmall, $isDisabled, $aRow);
+
+    			$oProvider = $this->_oModule->getObjectProvider($aProvider['name'], $iSellerId);
+    			if($oProvider !== false && method_exists($oProvider, 'getButtonSingle')) {
+    			    $aParams = array(
+    					'sObjNameGrid' => $this->getObject()
+    				);
+
+    			    $aCartInfo = $oCart->getInfo(BX_PAYMENT_TYPE_SINGLE, $iClientId, $iSellerId);
+    			    if(!empty($aCartInfo['items_price']) && !empty($aCartInfo['items']) && is_array($aCartInfo['items'])) {
+    			        $aTitles = array();
+    			        foreach ($aCartInfo['items'] as $aItem)
+    			            $aTitles[] = $aItem['title'];
+    
+    			        $aParams = array_merge($aParams, array(
+    			            'iAmount' => (int)round(100 * (float)$aCartInfo['items_price']),
+    			        	'sItemTitle' => implode(', ', $aTitles)
+    			        ));
+    			    }
+
+    				$sAction = $oProvider->getButtonSingle($iClientId, $iSellerId, $aParams);
+    			}
+
+    			$sActions .= $sAction;
+    		}
+    	}
+
+    	return $sActions . parent::_getActions ($sType, $sActionData, $isSmall, $isDisabled, $isPermanentState, $aRow);
+    }
+
+	protected function _getDataArray($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage)
+    {
+		if(empty($this->_aQueryAppend['client_id']) || empty($this->_aQueryAppend['seller_id']))
+			return array();
+
+		$aCart = $this->_oCart->getInfo(BX_PAYMENT_TYPE_SINGLE, $this->_aQueryAppend['client_id'], $this->_aQueryAppend['seller_id']);
+		if(empty($aCart) || empty($aCart['items']) || !is_array($aCart['items']))
+			return array();
+
+        $this->_aOptions['source'] = array();
+		foreach($aCart['items'] as $aCartItem) {
+			$aCartItem['descriptor'] = $this->_oModule->_oConfig->descriptorA2S(array($aCart['vendor_id'], $aCartItem['module_id'], $aCartItem['id'], $aCartItem['quantity']));
+			$aCartItem['description'] = strip_tags($aCartItem['description']);
+
+			$this->_aOptions['source'][] = $aCartItem;
+		}
+
+        return parent::_getDataArray($sFilter, $sOrderField, $sOrderDir, $iStart, $iPerPage);
+    }
+
+    protected function _delete($mixedId)
+    {
+    	list($iVendorId, $iModuleId, $iItemId) = $this->_oModule->_oConfig->descriptorS2A($mixedId);
+    	if((int)$iVendorId != (int)$this->_aQueryAppend['seller_id'])
+    		return false;
+
+    	return $this->_oCart->serviceDeleteFromCart($iVendorId, $iModuleId, $iItemId);
+    }
+}
+
+/** @} */

+ 78 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/classes/BxPaymentGridSbsAdministration.php

@@ -0,0 +1,78 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Payment Payment
+ * @ingroup     UnaModules
+ * 
+ * @{
+ */
+
+
+class BxPaymentGridSbsAdministration extends BxBaseModPaymentGridOrders
+{
+    protected $_sManageType;
+
+    public function __construct ($aOptions, $oTemplate = false)
+    {
+    	$this->MODULE = 'bx_payment';
+
+        parent::__construct ($aOptions, $oTemplate);
+
+        $this->_sOrdersType = BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION;
+        $this->_sManageType = 'administration';
+    }
+
+    public function performActionCancel()
+    {
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) 
+        	return echoJson(array());
+
+		$oSubscriptions = $this->_oModule->getObjectSubscriptions();
+
+		$iAffected = 0;
+		$aAffected = array();
+		foreach($aIds as $iId)
+			if($oSubscriptions->cancel($iId)) {
+				$aAffected[] = $iId;
+            	$iAffected++;
+			}
+
+        echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aAffected) : array('msg' => _t($this->_sLangsPrefix . 'err_cannot_perform')));
+    }
+
+    protected function _getCellProvider($mixedValue, $sKey, $aField, $aRow)
+    {
+        return parent::_getCellDefault(_t('_bx_payment_txt_name_' . $mixedValue), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellSubscriptionId($mixedValue, $sKey, $aField, $aRow)
+    {
+        $aItems = $this->_oModule->_oConfig->descriptorsM2A($aRow['items']);
+        if(!is_array($aItems) || count($aItems) != 1)
+            return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+
+        $aItem = array_shift($aItems);
+        $aInfo = BxDolService::call((int)$aItem['module_id'], 'get_payment_data');
+        if(!empty($aInfo['url_browse_order_' . $this->_sManageType]))
+            $mixedValue = $this->_oModule->_oTemplate->displayLink('link', array(
+                'href' => bx_replace_markers($aInfo['url_browse_order_' . $this->_sManageType], array(
+                    'order' => $mixedValue
+                )),
+                'title' => bx_html_attribute($mixedValue),
+                'content' => $mixedValue
+            ));
+
+        return parent::_getCellDefault($mixedValue, $sKey, $aField, $aRow);
+    }
+        
+    protected function _getCellPaid($mixedValue, $sKey, $aField, $aRow)
+    {
+        $aStates = array(0 => 'no', 1 => 'yes');
+        return parent::_getCellDefault(_t('_bx_payment_txt_' . $aStates[(int)$mixedValue]), $sKey, $aField, $aRow);
+    }
+}
+
+/** @} */

+ 453 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/classes/BxPaymentTemplate.php

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

+ 70 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/install/config.php

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

+ 527 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/install/langs/en.xml

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

+ 474 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/install/sql/install.sql

@@ -0,0 +1,474 @@
+SET @sName = 'bx_payment';
+
+
+-- TABLES
+CREATE TABLE IF NOT EXISTS `bx_payment_providers` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(64) NOT NULL default '',
+  `caption` varchar(128) NOT NULL default '',
+  `description` varchar(128) NOT NULL default '',
+  `option_prefix` varchar(32) NOT NULL default '',
+  `for_visitor` tinyint(4) NOT NULL default '0',
+  `for_single` tinyint(4) NOT NULL default '0',
+  `for_recurring` tinyint(4) NOT NULL default '0',
+  `active` tinyint(4) NOT NULL default '0',
+  `order` tinyint(4) NOT NULL default '0',
+  `class_name` varchar(128) NOT NULL default '',
+  `class_file` varchar(255) NOT NULL  default '',
+  PRIMARY KEY(`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_providers_options` (
+  `id` int(11) NOT NULL auto_increment,
+  `provider_id` varchar(64) NOT NULL default '',
+  `name` varchar(64) NOT NULL default '',
+  `type` varchar(64) NOT NULL default 'text',
+  `caption` varchar(255) NOT NULL default '',
+  `description` text NOT NULL default '',
+  `extra` varchar(255) NOT NULL default '',
+  `check_type` varchar(64) NOT NULL default '',
+  `check_params` varchar(128) NOT NULL default '',
+  `check_error` varchar(128) NOT NULL default '',
+  `order` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `name`(`name`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_user_values` (
+  `user_id` int(11) NOT NULL default '0',
+  `option_id` int(11) NOT NULL default '0',  
+  `value` varchar(255) NOT NULL default '',
+  UNIQUE KEY `value`(`user_id`, `option_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_cart` (
+  `client_id` int(11) NOT NULL default '0',
+  `items` text NOT NULL default '',
+  `customs` text NOT NULL default '',
+  PRIMARY KEY(`client_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_transactions` (
+  `id` int(11) NOT NULL auto_increment,
+  `pending_id` int(11) NOT NULL default '0',
+  `client_id` int(11) NOT NULL default '0',
+  `seller_id` int(11) NOT NULL default '0',
+  `module_id` int(11) NOT NULL default '0',  
+  `item_id` int(11) NOT NULL default '0',
+  `item_count` int(11) NOT NULL default '0',
+  `amount` float NOT NULL default '0',
+  `license` varchar(16) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `new` tinyint(1) NOT NULL default '1',
+  PRIMARY KEY(`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_subscriptions` (
+  `id` int(11) NOT NULL auto_increment,
+  `pending_id` int(11) NOT NULL default '0',
+  `customer_id` varchar(32) NOT NULL default '',
+  `subscription_id` varchar(32) NOT NULL default '',
+  `paid` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `pending_id` (`pending_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_subscriptions_deleted` (
+  `id` int(11) NOT NULL auto_increment,
+  `pending_id` int(11) NOT NULL default '0',
+  `customer_id` varchar(32) NOT NULL default '',
+  `subscription_id` varchar(32) NOT NULL default '',
+  `paid` tinyint(4) NOT NULL default '0',
+  `date` int(11) NOT NULL default '0',
+  `reason` varchar(16) NOT NULL default '',
+  `deleted` int(11) NOT NULL default '0',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `pending_id` (`pending_id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_transactions_pending` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `client_id` int(11) NOT NULL default '0',
+  `seller_id` int(11) NOT NULL default '0',
+  `type` varchar(16) NOT NULL default 'single',
+  `provider` varchar(32) NOT NULL default '',
+  `items` text NOT NULL default '',
+  `customs` text NOT NULL default '',
+  `amount` float NOT NULL default '0',
+  `order` varchar(32) NOT NULL default '',
+  `error_code` varchar(16) NOT NULL default '',
+  `error_msg` varchar(255) NOT NULL default '',
+  `date` int(11) NOT NULL default '0',
+  `processed` tinyint(4) NOT NULL default '0',
+  PRIMARY KEY(`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `bx_payment_modules` (
+  `id` int(11) NOT NULL auto_increment,
+  `name` varchar(32) NOT NULL default '',
+  PRIMARY KEY(`id`),
+  UNIQUE KEY `uri`(`name`)
+);
+
+
+-- PayPal payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('paypal', '_bx_payment_pp_cpt', '_bx_payment_pp_dsc', 'pp_', 1, 1, 0, 1, 1, 'BxPaymentProviderPayPal');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'pp_active', 'checkbox', '_bx_payment_pp_active_cpt', '_bx_payment_pp_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'pp_mode', 'select', '_bx_payment_pp_mode_cpt', '_bx_payment_pp_mode_dsc', '1|_bx_payment_pp_mode_live,2|_bx_payment_pp_mode_test', '', '', '', 2),
+(@iProviderId, 'pp_business', 'text', '_bx_payment_pp_business_cpt', '_bx_payment_pp_business_dsc', '', '', '', '', 3),
+(@iProviderId, 'pp_prc_type', 'select', '_bx_payment_pp_prc_type_cpt', '_bx_payment_pp_prc_type_dsc', '1|_bx_payment_pp_prc_type_direct,2|_bx_payment_pp_prc_type_pdt,3|_bx_payment_pp_prc_type_ipn', '', '', '', 4),
+(@iProviderId, 'pp_token', 'text', '_bx_payment_pp_token_cpt', '_bx_payment_pp_token_dsc', '', '', '', '', 5),
+(@iProviderId, 'pp_sandbox', 'text', '_bx_payment_pp_sandbox_cpt', '_bx_payment_pp_sandbox_dsc', '', '', '', '', 6),
+(@iProviderId, 'pp_return_data_url', 'value', '_bx_payment_pp_return_data_url_cpt', '', '', '', '', '', 7);
+
+
+-- 2Checkout payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('2checkout', '_bx_payment_2co_cpt', '_bx_payment_2co_dsc', '2co_', 1, 1, 0, 0, 2, 'BxPaymentProvider2Checkout');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, '2co_active', 'checkbox', '_bx_payment_2co_active_cpt', '_bx_payment_2co_active_dsc', '', '', '', '', 1),
+(@iProviderId, '2co_mode', 'select', '_bx_payment_2co_mode_cpt', '_bx_payment_2co_mode_dsc', '1|_bx_payment_2co_mode_live,2|_bx_payment_2co_mode_test', '', '', '', 2),
+(@iProviderId, '2co_account_id', 'text', '_bx_payment_2co_account_id_cpt', '_bx_payment_2co_account_id_dsc', '', '', '', '', 3),
+(@iProviderId, '2co_payment_method', 'select', '_bx_payment_2co_payment_method_cpt', '_bx_payment_2co_payment_method_dsc', 'CC|_bx_payment_2co_payment_method_cc,PPI|_bx_payment_2co_payment_method_ppi', '', '', '', 4),
+(@iProviderId, '2co_secret_word', 'text', '_bx_payment_2co_secret_word_cpt', '_bx_payment_2co_secret_word_dsc', '', '', '', '', 5),
+(@iProviderId, '2co_return_data_url', 'value', '_bx_payment_2co_return_data_url_cpt', '', '', '', '', '', 6);
+
+
+-- BitPay payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('bitpay', '_bx_payment_bp_cpt', '_bx_payment_bp_dsc', 'bp_', 0, 1, 0, 0, 3, 'BxPaymentProviderBitPay');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'bp_active', 'checkbox', '_bx_payment_bp_active_cpt', '_bx_payment_bp_active_dsc', '', 'https', '', '_bx_payment_bp_active_err', 1),
+(@iProviderId, 'bp_api_key', 'text', '_bx_payment_bp_api_key_cpt', '_bx_payment_bp_api_key_dsc', '', '', '', '', 2),
+(@iProviderId, 'bp_transaction_speed', 'select', '_bx_payment_bp_transaction_speed_cpt', '_bx_payment_bp_transaction_speed_dsc', 'high|_bx_payment_bp_transaction_speed_high,medium|_bx_payment_bp_transaction_speed_medium,low|_bx_payment_bp_transaction_speed_low', '', '', '', 3),
+(@iProviderId, 'bp_full_notifications', 'checkbox', '_bx_payment_bp_full_notifications_cpt', '_bx_payment_bp_full_notifications_dsc', '', '', '', '', 4),
+(@iProviderId, 'bp_notification_email', 'text', '_bx_payment_bp_notification_email_cpt', '_bx_payment_bp_notification_email_dsc', '', '', '', '', 5);
+
+
+-- Chargebee payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('chargebee', '_bx_payment_cbee_cpt', '_bx_payment_cbee_dsc', 'cbee_', 1, 0, 1, 1, 4, 'BxPaymentProviderChargebee');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'cbee_active', 'checkbox', '_bx_payment_cbee_active_cpt', '_bx_payment_cbee_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'cbee_hidden', 'checkbox', '_bx_payment_cbee_hidden_cpt', '_bx_payment_cbee_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'cbee_mode', 'select', '_bx_payment_cbee_mode_cpt', '_bx_payment_cbee_mode_dsc', '1|_bx_payment_cbee_mode_live,2|_bx_payment_cbee_mode_test', '', '', '', 3),
+(@iProviderId, 'cbee_live_site', 'text', '_bx_payment_cbee_live_site_cpt', '_bx_payment_cbee_live_site_dsc', '', '', '', '', 4),
+(@iProviderId, 'cbee_live_api_key', 'text', '_bx_payment_cbee_live_api_key_cpt', '_bx_payment_cbee_live_api_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'cbee_test_site', 'text', '_bx_payment_cbee_test_site_cpt', '_bx_payment_cbee_test_site_dsc', '', '', '', '', 6),
+(@iProviderId, 'cbee_test_api_key', 'text', '_bx_payment_cbee_test_api_key_cpt', '_bx_payment_cbee_test_api_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'cbee_check_amount', 'checkbox', '_bx_payment_cbee_check_amount_cpt', '_bx_payment_cbee_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'cbee_ssl', 'checkbox', '_bx_payment_cbee_ssl_cpt', '_bx_payment_cbee_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'cbee_return_data_url', 'value', '_bx_payment_cbee_return_data_url_cpt', '', '', '', '', '', 10),
+(@iProviderId, 'cbee_notify_url', 'value', '_bx_payment_cbee_notify_url_cpt', '', '', '', '', '', 11);
+
+-- Chargebee V3 payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('chargebee_v3', '_bx_payment_cbee_v3_cpt', '_bx_payment_cbee_v3_dsc', 'cbee_v3_', 1, 0, 1, 1, 5, 'BxPaymentProviderChargebeeV3');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'cbee_v3_active', 'checkbox', '_bx_payment_cbee_active_cpt', '_bx_payment_cbee_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'cbee_v3_hidden', 'checkbox', '_bx_payment_cbee_hidden_cpt', '_bx_payment_cbee_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'cbee_v3_mode', 'select', '_bx_payment_cbee_mode_cpt', '_bx_payment_cbee_mode_dsc', '1|_bx_payment_cbee_mode_live,2|_bx_payment_cbee_mode_test', '', '', '', 3),
+(@iProviderId, 'cbee_v3_live_site', 'text', '_bx_payment_cbee_live_site_cpt', '_bx_payment_cbee_live_site_dsc', '', '', '', '', 4),
+(@iProviderId, 'cbee_v3_live_api_key', 'text', '_bx_payment_cbee_live_api_key_cpt', '_bx_payment_cbee_live_api_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'cbee_v3_test_site', 'text', '_bx_payment_cbee_test_site_cpt', '_bx_payment_cbee_test_site_dsc', '', '', '', '', 6),
+(@iProviderId, 'cbee_v3_test_api_key', 'text', '_bx_payment_cbee_test_api_key_cpt', '_bx_payment_cbee_test_api_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'cbee_v3_check_amount', 'checkbox', '_bx_payment_cbee_check_amount_cpt', '_bx_payment_cbee_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'cbee_v3_ssl', 'checkbox', '_bx_payment_cbee_ssl_cpt', '_bx_payment_cbee_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'cbee_v3_return_data_url', 'value', '_bx_payment_cbee_return_data_url_cpt', '', '', '', '', '', 10),
+(@iProviderId, 'cbee_v3_notify_url', 'value', '_bx_payment_cbee_notify_url_cpt', '', '', '', '', '', 11);
+
+-- Recurly payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('recurly', '_bx_payment_rcrl_cpt', '_bx_payment_rcrl_dsc', 'rcrl_', 1, 0, 1, 0, 6, 'BxPaymentProviderRecurly');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'rcrl_active', 'checkbox', '_bx_payment_rcrl_active_cpt', '_bx_payment_rcrl_active_dsc', '', 'https', '', '_bx_payment_rcrl_active_err', 1),
+(@iProviderId, 'rcrl_hidden', 'checkbox', '_bx_payment_rcrl_hidden_cpt', '_bx_payment_rcrl_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'rcrl_mode', 'select', '_bx_payment_rcrl_mode_cpt', '_bx_payment_rcrl_mode_dsc', '1|_bx_payment_rcrl_mode_live,2|_bx_payment_rcrl_mode_test', '', '', '', 3),
+(@iProviderId, 'rcrl_site', 'text', '_bx_payment_rcrl_site_cpt', '_bx_payment_rcrl_site_dsc', '', '', '', '', 4),
+(@iProviderId, 'rcrl_api_key_private', 'text', '_bx_payment_rcrl_api_key_private_cpt', '_bx_payment_rcrl_api_key_private_dsc', '', '', '', '', 5),
+(@iProviderId, 'rcrl_api_key_public', 'text', '_bx_payment_rcrl_api_key_public_cpt', '_bx_payment_rcrl_api_key_public_dsc', '', '', '', '', 6),
+(@iProviderId, 'rcrl_return_data_url', 'value', '_bx_payment_rcrl_return_data_url_cpt', '', '', '', '', '', 7),
+(@iProviderId, 'rcrl_notify_url', 'value', '_bx_payment_rcrl_notify_url_cpt', '', '', '', '', '', 8);
+
+-- Stripe payment provider
+INSERT INTO `bx_payment_providers`(`name`, `caption`, `description`, `option_prefix`, `for_visitor`, `for_single`, `for_recurring`, `active`, `order`, `class_name`) VALUES
+('stripe', '_bx_payment_strp_cpt', '_bx_payment_strp_dsc', 'strp_', 1, 1, 1, 1, 7, 'BxPaymentProviderStripe');
+SET @iProviderId = LAST_INSERT_ID();
+
+INSERT INTO `bx_payment_providers_options`(`provider_id`, `name`, `type`, `caption`, `description`, `extra`, `check_type`, `check_params`, `check_error`, `order`) VALUES
+(@iProviderId, 'strp_active', 'checkbox', '_bx_payment_strp_active_cpt', '_bx_payment_strp_active_dsc', '', '', '', '', 1),
+(@iProviderId, 'strp_hidden', 'checkbox', '_bx_payment_strp_hidden_cpt', '_bx_payment_strp_hidden_dsc', '', '', '', '', 2),
+(@iProviderId, 'strp_mode', 'select', '_bx_payment_strp_mode_cpt', '_bx_payment_strp_mode_dsc', '1|_bx_payment_strp_mode_live,2|_bx_payment_strp_mode_test', '', '', '', 3),
+(@iProviderId, 'strp_live_pub_key', 'text', '_bx_payment_strp_live_pub_key_cpt', '_bx_payment_strp_live_pub_key_dsc', '', '', '', '', 4),
+(@iProviderId, 'strp_live_sec_key', 'text', '_bx_payment_strp_live_sec_key_cpt', '_bx_payment_strp_live_sec_key_dsc', '', '', '', '', 5),
+(@iProviderId, 'strp_test_pub_key', 'text', '_bx_payment_strp_test_pub_key_cpt', '_bx_payment_strp_test_pub_key_dsc', '', '', '', '', 6),
+(@iProviderId, 'strp_test_sec_key', 'text', '_bx_payment_strp_test_sec_key_cpt', '_bx_payment_strp_test_sec_key_dsc', '', '', '', '', 7),
+(@iProviderId, 'strp_check_amount', 'checkbox', '_bx_payment_strp_check_amount_cpt', '_bx_payment_strp_check_amount_dsc', '', '', '', '', 8),
+(@iProviderId, 'strp_ssl', 'checkbox', '_bx_payment_strp_ssl_cpt', '_bx_payment_strp_ssl_dsc', '', '', '', '', 9),
+(@iProviderId, 'strp_cancellation_email', 'text', '_bx_payment_strp_cancellation_email_cpt', '', '', '', '', '', 10),
+(@iProviderId, 'strp_notify_url', 'value', '_bx_payment_strp_notify_url_cpt', '', '', '', '', '', 11);
+
+
+-- GRIDS
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_payment_grid_providers', 'Sql', 'SELECT * FROM `bx_payment_providers` WHERE 1 ', 'bx_payment_providers', 'id', 'order', 'active', '', 100, NULL, 'start', '', 'name', 'caption,description', 'auto', '', '', 192, 'BxPaymentGridProviders', 'modules/boonex/payment/classes/BxPaymentGridProviders.php'),
+
+('bx_payment_grid_carts', 'Array', '', '', 'vendor_id', '', '', '', 20, NULL, 'start', '', '', '', 'like', '', '', 2147483647, 'BxPaymentGridCarts', 'modules/boonex/payment/classes/BxPaymentGridCarts.php'),
+('bx_payment_grid_cart', 'Array', '', '', 'descriptor', '', '', '', 20, NULL, 'start', '', 'title,description', '', 'like', '', '', 2147483647, 'BxPaymentGridCart', 'modules/boonex/payment/classes/BxPaymentGridCart.php'),
+
+('bx_payment_grid_sbs_list_my', 'Sql', 'SELECT `ttp`.`id` AS `id`, `ttp`.`seller_id` AS `seller_id`, `ts`.`customer_id` AS `customer_id`, `ts`.`subscription_id` AS `subscription_id`, `ttp`.`provider` AS `provider`, `ttp`.`items` AS `items`, `ts`.`date` AS `date` FROM `bx_payment_subscriptions` AS `ts` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `ts`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''recurring'' ', 'bx_payment_subscriptions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ts`.`customer_id,ts`.`subscription_id,ts`.`date', '', 'auto', '', '', 2147483647, 'BxPaymentGridSbsList', 'modules/boonex/payment/classes/BxPaymentGridSbsList.php'),
+('bx_payment_grid_sbs_list_all', 'Sql', 'SELECT `ttp`.`id` AS `id`, `ttp`.`client_id` AS `client_id`, `tac`.`email` AS `client_email`, `ttp`.`seller_id` AS `seller_id`, `ts`.`customer_id` AS `customer_id`, `ts`.`subscription_id` AS `subscription_id`, `ttp`.`provider` AS `provider`, `ttp`.`items` AS `items`, `ts`.`paid` AS `paid`, `ts`.`date` AS `date` FROM `bx_payment_subscriptions` AS `ts` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `ts`.`pending_id`=`ttp`.`id` LEFT JOIN `sys_profiles` AS `tpc` ON `ttp`.`client_id`=`tpc`.`id` LEFT JOIN `sys_accounts` AS `tac` ON `tpc`.`account_id`=`tac`.`id` WHERE 1 AND `ttp`.`type`=''recurring'' ', 'bx_payment_subscriptions', 'id', 'date', '', '', 100, NULL, 'start', '', 'tac`.`email,ts`.`customer_id,ts`.`subscription_id,ts`.`date', '', 'auto', '', '', 192, 'BxPaymentGridSbsAdministration', 'modules/boonex/payment/classes/BxPaymentGridSbsAdministration.php'),
+('bx_payment_grid_sbs_history', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`seller_id` AS `seller_id`, `ttp`.`order` AS `transaction`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''recurring'' ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, 'BxPaymentGridSbsHistory', 'modules/boonex/payment/classes/BxPaymentGridSbsHistory.php'),
+
+('bx_payment_grid_orders_history', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`seller_id` AS `seller_id`, `tt`.`module_id` AS `module_id`, `tt`.`item_id` AS `item_id`, `ttp`.`order` AS `transaction`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` WHERE 1 AND `ttp`.`type`=''single'' ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, 'BxPaymentGridHistory', 'modules/boonex/payment/classes/BxPaymentGridHistory.php'),
+('bx_payment_grid_orders_processed', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`client_id` AS `client_id`, `tt`.`seller_id` AS `seller_id`, `tt`.`module_id` AS `module_id`, `tt`.`item_id` AS `item_id`, `tt`.`item_count` AS `item_count`, `ttp`.`order` AS `transaction`, `ttp`.`error_msg` AS `error_msg`, `ttp`.`provider` AS `provider`, `tt`.`license` AS `license`, `tt`.`amount` AS `amount`, `tt`.`date` AS `date` FROM `bx_payment_transactions` AS `tt` LEFT JOIN `bx_payment_transactions_pending` AS `ttp` ON `tt`.`pending_id`=`ttp`.`id` WHERE 1 ', 'bx_payment_transactions', 'id', 'date', '', '', 100, NULL, 'start', '', 'ttp`.`order,tt`.`license,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, 'BxPaymentGridProcessed', 'modules/boonex/payment/classes/BxPaymentGridProcessed.php'),
+('bx_payment_grid_orders_pending', 'Sql', 'SELECT `tt`.`id` AS `id`, `tt`.`client_id` AS `client_id`, `tt`.`seller_id` AS `seller_id`, `tt`.`items` AS `items`, `tt`.`amount` AS `amount`, `tt`.`order` AS `transaction`, `tt`.`error_msg` AS `error_msg`, `tt`.`provider` AS `provider`, `tt`.`date` AS `date` FROM `bx_payment_transactions_pending` AS `tt` WHERE 1 AND (ISNULL(`tt`.`order`) OR (NOT ISNULL(`tt`.`order`) AND `tt`.`error_code`<>''0'')) ', 'bx_payment_transactions_pending', 'id', 'date', '', '', 100, NULL, 'start', '', 'tt`.`order,tt`.`amount,tt`.`date', '', 'auto', '', '', 2147483647, 'BxPaymentGridPending', 'modules/boonex/payment/classes/BxPaymentGridPending.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_payment_grid_providers', 'order', '', '2%', 0, '', '', 1),
+('bx_payment_grid_providers', 'switcher', '', '8%', 0, '', '', 2),
+('bx_payment_grid_providers', 'caption', '_bx_payment_grid_column_title_pdrs_caption', '25%', 1, '16', '', 3),
+('bx_payment_grid_providers', 'description', '_bx_payment_grid_column_title_pdrs_description', '35%', 1, '32', '', 4),
+('bx_payment_grid_providers', 'for_visitor', '_bx_payment_grid_column_title_pdrs_for_visitor', '10%', 0, '8', '', 5),
+('bx_payment_grid_providers', 'for_single', '_bx_payment_grid_column_title_pdrs_for_single', '10%', 0, '8', '', 6),
+('bx_payment_grid_providers', 'for_recurring', '_bx_payment_grid_column_title_pdrs_for_recurring', '10%', 0, '8', '', 7),
+
+('bx_payment_grid_carts', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_carts', 'vendor_id', '_bx_payment_grid_column_title_crts_vendor_id', '40%', 0, '36', '', 2),
+('bx_payment_grid_carts', 'items_count', '_bx_payment_grid_column_title_crts_items_count', '20%', 0, '16', '', 3),
+('bx_payment_grid_carts', 'items_price', '_bx_payment_grid_column_title_crts_items_price', '20%', 0, '16', '', 4),
+('bx_payment_grid_carts', 'actions', '', '18%', 0, '', '', 5),
+
+('bx_payment_grid_cart', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_cart', 'title', '_bx_payment_grid_column_title_crt_title', '25%', 0, '24', '', 2),
+('bx_payment_grid_cart', 'description', '_bx_payment_grid_column_title_crt_description', '35%', 0, '48', '', 3),
+('bx_payment_grid_cart', 'quantity', '_bx_payment_grid_column_title_crt_quantity', '10%', 0, '16', '', 4),
+('bx_payment_grid_cart', 'price_single', '_bx_payment_grid_column_title_crt_price', '10%', 0, '16', '', 5),
+('bx_payment_grid_cart', 'actions', '', '18%', 0, '', '', 6),
+
+('bx_payment_grid_sbs_list_my', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_sbs_list_my', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '20%', 0, '24', '', 2),
+('bx_payment_grid_sbs_list_my', 'customer_id', '_bx_payment_grid_column_title_sbs_customer_id', '20%', 0, '24', '', 3),
+('bx_payment_grid_sbs_list_my', 'subscription_id', '_bx_payment_grid_column_title_sbs_subscription_id', '20%', 0, '32', '', 4),
+('bx_payment_grid_sbs_list_my', 'provider', '_bx_payment_grid_column_title_sbs_provider', '10%', 0, '16', '', 5),
+('bx_payment_grid_sbs_list_my', 'date', '_bx_payment_grid_column_title_sbs_date_created', '14%', 0, '10', '', 6),
+('bx_payment_grid_sbs_list_my', 'actions', '', '14%', 0, '', '', 7),
+
+('bx_payment_grid_sbs_list_all', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '10%', 0, '24', '', 1),
+('bx_payment_grid_sbs_list_all', 'client_id', '_bx_payment_grid_column_title_sbs_client_id', '10%', 0, '24', '', 2),
+('bx_payment_grid_sbs_list_all', 'client_email', '_bx_payment_grid_column_title_sbs_client_email', '15%', 0, '24', '', 3),
+('bx_payment_grid_sbs_list_all', 'customer_id', '_bx_payment_grid_column_title_sbs_customer_id', '15%', 0, '18', '', 4),
+('bx_payment_grid_sbs_list_all', 'subscription_id', '_bx_payment_grid_column_title_sbs_subscription_id', '15%', 0, '32', '', 5),
+('bx_payment_grid_sbs_list_all', 'provider', '_bx_payment_grid_column_title_sbs_provider', '5%', 0, '16', '', 6),
+('bx_payment_grid_sbs_list_all', 'paid', '_bx_payment_grid_column_title_sbs_paid', '4%', 0, '4', '', 7),
+('bx_payment_grid_sbs_list_all', 'date', '_bx_payment_grid_column_title_sbs_date_created', '10%', 0, '10', '', 8),
+('bx_payment_grid_sbs_list_all', 'actions', '', '16%', 0, '', '', 9),
+
+('bx_payment_grid_sbs_history', 'seller_id', '_bx_payment_grid_column_title_sbs_seller_id', '24%', 0, '20', '', 1),
+('bx_payment_grid_sbs_history', 'transaction', '_bx_payment_grid_column_title_sbs_transaction', '22%', 0, '18', '', 2),
+('bx_payment_grid_sbs_history', 'license', '_bx_payment_grid_column_title_sbs_license', '22%', 0, '18', '', 3),
+('bx_payment_grid_sbs_history', 'amount', '_bx_payment_grid_column_title_sbs_amount', '10%', 1, '10', '', 4),
+('bx_payment_grid_sbs_history', 'date', '_bx_payment_grid_column_title_sbs_date', '10%', 0, '10', '', 5),
+('bx_payment_grid_sbs_history', 'actions', '', '12%', 0, '', '', 6),
+
+('bx_payment_grid_orders_history', 'seller_id', '_bx_payment_grid_column_title_ods_seller_id', '24%', 0, '20', '', 1),
+('bx_payment_grid_orders_history', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '22%', 0, '18', '', 2),
+('bx_payment_grid_orders_history', 'item', '_bx_payment_grid_column_title_ods_item', '22%', 0, '18', '', 3),
+('bx_payment_grid_orders_history', 'amount', '_bx_payment_grid_column_title_ods_amount', '10%', 1, '10', '', 4),
+('bx_payment_grid_orders_history', 'date', '_bx_payment_grid_column_title_ods_date', '10%', 0, '10', '', 5),
+('bx_payment_grid_orders_history', 'actions', '', '12%', 0, '', '', 6),
+
+('bx_payment_grid_orders_processed', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_orders_processed', 'client_id', '_bx_payment_grid_column_title_ods_client_id', '22%', 0, '18', '', 2),
+('bx_payment_grid_orders_processed', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '20%', 0, '18', '', 3),
+('bx_payment_grid_orders_processed', 'item', '_bx_payment_grid_column_title_ods_item', '20%', 0, '18', '', 4),
+('bx_payment_grid_orders_processed', 'amount', '_bx_payment_grid_column_title_ods_amount', '10%', 1, '10', '', 5),
+('bx_payment_grid_orders_processed', 'date', '_bx_payment_grid_column_title_ods_date', '10%', 0, '10', '', 6),
+('bx_payment_grid_orders_processed', 'actions', '', '16%', 0, '', '', 7),
+
+('bx_payment_grid_orders_pending', 'checkbox', '', '2%', 0, '', '', 1),
+('bx_payment_grid_orders_pending', 'client_id', '_bx_payment_grid_column_title_ods_client_id', '25%', 0, '25', '', 2),
+('bx_payment_grid_orders_pending', 'transaction', '_bx_payment_grid_column_title_ods_transaction', '25%', 0, '25', '', 3),
+('bx_payment_grid_orders_pending', 'amount', '_bx_payment_grid_column_title_ods_amount', '14%', 1, '14', '', 4),
+('bx_payment_grid_orders_pending', 'date', '_bx_payment_grid_column_title_ods_date', '14%', 0, '14', '', 5),
+('bx_payment_grid_orders_pending', 'actions', '', '20%', 0, '', '', 6);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_payment_grid_carts', 'bulk', 'delete', '_bx_payment_grid_action_title_crts_delete', '', 0, 1, 1),
+('bx_payment_grid_carts', 'single', 'continue', '_bx_payment_grid_action_title_crts_continue', 'money', 1, 0, 1),
+('bx_payment_grid_carts', 'single', 'delete', '_bx_payment_grid_action_title_crts_delete', 'remove', 1, 1, 2),
+
+('bx_payment_grid_cart', 'bulk', 'checkout', '_bx_payment_grid_action_title_crt_checkout', '', 0, 0, 1),
+('bx_payment_grid_cart', 'single', 'delete', '_bx_payment_grid_action_title_crt_delete', 'remove', 1, 1, 1),
+
+('bx_payment_grid_sbs_list_my', 'single', 'view_order', '_bx_payment_grid_action_title_sbs_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_sbs_list_my', 'single', 'actions', '_bx_payment_grid_action_title_sbs_actions', 'cog', 1, 0, 2),
+
+('bx_payment_grid_sbs_list_all', 'single', 'view_order', '_bx_payment_grid_action_title_sbs_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_sbs_list_all', 'single', 'cancel', '_bx_payment_grid_action_title_sbs_cancel', 'times', 1, 1, 2),
+
+('bx_payment_grid_sbs_history', 'single', 'view_order', '_bx_payment_grid_action_title_sbs_view_order', 'ellipsis-h', 1, 0, 1),
+
+('bx_payment_grid_orders_history', 'single', 'view_order', '_bx_payment_grid_action_title_ods_view_order', 'ellipsis-h', 1, 0, 1),
+
+('bx_payment_grid_orders_processed', 'independent', 'add', '_bx_payment_grid_action_title_ods_add', '', 0, 0, 1),
+('bx_payment_grid_orders_processed', 'bulk', 'cancel', '_bx_payment_grid_action_title_ods_cancel', '', 0, 1, 1),
+('bx_payment_grid_orders_processed', 'single', 'view_order', '_bx_payment_grid_action_title_ods_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_orders_processed', 'single', 'cancel', '_bx_payment_grid_action_title_ods_cancel', 'times', 1, 1, 2),
+
+('bx_payment_grid_orders_pending', 'bulk', 'cancel', '_bx_payment_grid_action_title_ods_cancel', '', 0, 1, 1),
+('bx_payment_grid_orders_pending', 'single', 'view_order', '_bx_payment_grid_action_title_ods_view_order', 'ellipsis-h', 1, 0, 1),
+('bx_payment_grid_orders_pending', 'single', 'process', '_bx_payment_grid_action_title_ods_process', 'sync', 1, 0, 2),
+('bx_payment_grid_orders_pending', 'single', 'cancel', '_bx_payment_grid_action_title_ods_cancel', 'times', 1, 1, 3);
+
+
+-- FORMS
+INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_payment_form_pendings', @sName, '_bx_payment_form_pendings_form', '', '', 'do_submit', 'bx_payment_transactions_pending', 'id', '', '', '', 0, 1, 'BxPaymentFormView', 'modules/boonex/payment/classes/BxPaymentFormView.php'),
+('bx_payment_form_processed', @sName, '_bx_payment_form_processed_form', '', '', 'do_submit', 'bx_payment_transactions', 'id', '', '', '', 0, 1, 'BxPaymentFormView', 'modules/boonex/payment/classes/BxPaymentFormView.php'),
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card', @sName, '_bx_payment_form_rcrl_card', '', '', 'do_submit', '', '', '', '', '', 0, 1, '', ''),
+-- FORMS: Stripe
+('bx_payment_form_strp_details', @sName, '_bx_payment_form_strp_details', '', '', 'do_submit', '', '', '', '', '', 0, 1, '', ''),
+('bx_payment_form_strp_card', @sName, '_bx_payment_form_strp_card', '', '', 'do_submit', '', '', '', '', '', 0, 1, '', '');
+
+
+INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
+('bx_payment_form_pendings_process', @sName, 'bx_payment_form_pendings', '_bx_payment_form_pendings_display_process', 0),
+('bx_payment_form_processed_add', @sName, 'bx_payment_form_processed', '_bx_payment_form_processed_display_add', 0),
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card_add', @sName, 'bx_payment_form_rcrl_card', '_bx_payment_form_rcrl_card_display_add', 0),
+-- FORMS: Stripe
+('bx_payment_form_strp_details_edit', @sName, 'bx_payment_form_strp_details', '_bx_payment_form_strp_details_display_edit', 0),
+('bx_payment_form_strp_card_add', @sName, 'bx_payment_form_strp_card', '_bx_payment_form_strp_card_display_add', 0);
+
+INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
+('bx_payment_form_pendings', @sName, 'id', '0', '', 0, 'hidden', '_bx_payment_form_pendings_input_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'seller_id', '0', '', 0, 'hidden', '_bx_payment_form_pendings_input_seller_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'order', '', '', 0, 'text', '_bx_payment_form_pendings_input_order_sys', '_bx_payment_form_pendings_input_order', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_pendings_input_order_err', 'Xss', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'do_submit', '_bx_payment_form_pendings_input_process', '', 0, 'submit', '_bx_payment_form_pendings_input_process_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_pendings', @sName, 'do_cancel', '_bx_payment_form_pendings_input_cancel', '', 0, 'button', '_bx_payment_form_pendings_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+('bx_payment_form_processed', @sName, 'seller_id', '0', '', 0, 'hidden', '_bx_payment_form_processed_input_seller_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_processed', @sName, 'client_id', '0', '', 0, 'hidden', '_bx_payment_form_processed_input_client_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_processed', @sName, 'client', '0', '', 0, 'custom', '_bx_payment_form_processed_input_client_sys', '_bx_payment_form_processed_input_client', '', 0, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_processed_input_client_err', 'Xss', '', 0, 0),
+('bx_payment_form_processed', @sName, 'order', '0', '', 0, 'text', '_bx_payment_form_processed_input_order_sys', '_bx_payment_form_processed_input_order', '', 0, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_processed_input_order_err', 'Xss', '', 0, 0),
+('bx_payment_form_processed', @sName, 'module_id', '0', '', 0, 'select', '_bx_payment_form_processed_input_module_id_sys', '_bx_payment_form_processed_input_module_id', '', 0, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_processed_input_module_id_err', 'Int', '', 0, 0),
+('bx_payment_form_processed', @sName, 'items', '0', '', 0, 'custom', '_bx_payment_form_processed_input_items_sys', '_bx_payment_form_processed_input_items', '', 0, 0, 0, '', '', '', '', '', '_bx_payment_form_processed_input_items_err', '', '', 0, 0),
+('bx_payment_form_processed', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_processed', @sName, 'do_submit', '_bx_payment_form_processed_input_add', '', 0, 'submit', '_bx_payment_form_processed_input_add_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_processed', @sName, 'do_cancel', '_bx_payment_form_processed_input_cancel', '', 0, 'button', '_bx_payment_form_processed_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card', @sName, 'pending_id', '0', '', 0, 'hidden', '_bx_payment_form_rcrl_card_input_pending_id_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'item', '', '', 0, 'hidden', '_bx_payment_form_rcrl_card_input_item_sys', '', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'token', '', '', 0, 'hidden', '_bx_payment_form_rcrl_card_input_token_sys', '', '', 0, 0, 0, 'a:1:{s:12:"data-recurly";s:5:"token";}', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'first_name', '', '', 0, 'text', '_bx_payment_form_rcrl_card_input_first_name_sys', '_bx_payment_form_rcrl_card_input_first_name', '', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:10:"first_name";}', '', '', 'Avail', '', '_bx_payment_form_rcrl_card_input_first_name_err', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'last_name', '', '', 0, 'text', '_bx_payment_form_rcrl_card_input_last_name_sys', '_bx_payment_form_rcrl_card_input_last_name', '', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:9:"last_name";}', '', '', 'Avail', '', '_bx_payment_form_rcrl_card_input_last_name_err', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'email', '', '', 0, 'text', '_bx_payment_form_rcrl_card_input_email_sys', '_bx_payment_form_rcrl_card_input_email', '', 1, 0, 0, '', '', '', 'Email', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'card_number', '', '', 0, 'custom', '_bx_payment_form_rcrl_card_input_card_number_sys', '_bx_payment_form_rcrl_card_input_card_number', '_bx_payment_form_rcrl_card_input_card_number_inf', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:6:"number";}', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'card_expire', '', '', 0, 'custom', '_bx_payment_form_rcrl_card_input_card_expire_sys', '_bx_payment_form_rcrl_card_input_card_expire', '_bx_payment_form_rcrl_card_input_card_expire_inf', 1, 0, 0, '', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'card_cvv', '', '', 0, 'custom', '_bx_payment_form_rcrl_card_input_card_cvv_sys', '_bx_payment_form_rcrl_card_input_card_cvv', '_bx_payment_form_rcrl_card_input_card_cvv_inf', 1, 0, 0, 'a:1:{s:12:"data-recurly";s:3:"cvv";}', '', '', '', '', '', 'Xss', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'do_submit', '_bx_payment_form_rcrl_card_input_submit', '', 0, 'submit', '_bx_payment_form_rcrl_card_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_rcrl_card', @sName, 'do_cancel', '_bx_payment_form_rcrl_card_input_cancel', '', 0, 'button', '_bx_payment_form_rcrl_card_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+-- FORMS: Stripe
+('bx_payment_form_strp_details', @sName, 'item_id', '', '', 0, 'select', '_bx_payment_form_strp_details_input_item_id_sys', '_bx_payment_form_strp_details_input_item_id', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_details_input_item_id_err', 'Int', '', 0, 0),
+('bx_payment_form_strp_details', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_details', @sName, 'do_submit', '_bx_payment_form_strp_details_input_submit', '', 0, 'submit', '_bx_payment_form_strp_details_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_details', @sName, 'do_cancel', '_bx_payment_form_strp_details_input_cancel', '', 0, 'button', '_bx_payment_form_strp_details_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0),
+
+('bx_payment_form_strp_card', @sName, 'card_number', '', '', 0, 'text', '_bx_payment_form_strp_card_input_card_number_sys', '_bx_payment_form_strp_card_input_card_number', '_bx_payment_form_strp_card_input_card_number_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_card_input_card_number_err', 'Xss', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'card_expire', '', '', 0, 'text', '_bx_payment_form_strp_card_input_card_expire_sys', '_bx_payment_form_strp_card_input_card_expire', '_bx_payment_form_strp_card_input_card_expire_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_card_input_card_expire_err', 'Xss', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'card_cvv', '', '', 0, 'text', '_bx_payment_form_strp_card_input_card_cvv_sys', '_bx_payment_form_strp_card_input_card_cvv', '_bx_payment_form_strp_card_input_card_cvv_inf', 1, 0, 0, '', '', '', 'Avail', '', '_bx_payment_form_strp_card_input_card_cvv_err', 'Xss', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'controls', '', 'do_submit,do_cancel', 0, 'input_set', '', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'do_submit', '_bx_payment_form_strp_card_input_submit', '', 0, 'submit', '_bx_payment_form_strp_card_input_submit_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_payment_form_strp_card', @sName, 'do_cancel', '_bx_payment_form_strp_card_input_cancel', '', 0, 'button', '_bx_payment_form_strp_card_input_cancel_sys', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 0, 0);
+
+
+INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
+('bx_payment_form_pendings_process', 'id', 2147483647, 1, 1),
+('bx_payment_form_pendings_process', 'seller_id', 2147483647, 1, 2),
+('bx_payment_form_pendings_process', 'order', 2147483647, 1, 3),
+('bx_payment_form_pendings_process', 'controls', 2147483647, 1, 4),
+('bx_payment_form_pendings_process', 'do_submit', 2147483647, 1, 5),
+('bx_payment_form_pendings_process', 'do_cancel', 2147483647, 1, 6),
+
+('bx_payment_form_processed_add', 'seller_id', 2147483647, 1, 2),
+('bx_payment_form_processed_add', 'client_id', 2147483647, 1, 3),
+('bx_payment_form_processed_add', 'client', 2147483647, 1, 4),
+('bx_payment_form_processed_add', 'order', 2147483647, 1, 5),
+('bx_payment_form_processed_add', 'module_id', 2147483647, 1, 6),
+('bx_payment_form_processed_add', 'items', 2147483647, 1, 7),
+('bx_payment_form_processed_add', 'controls', 2147483647, 1, 8),
+('bx_payment_form_processed_add', 'do_submit', 2147483647, 1, 9),
+('bx_payment_form_processed_add', 'do_cancel', 2147483647, 1, 10),
+
+-- FORMS: Recurly
+('bx_payment_form_rcrl_card_add', 'pending_id', 2147483647, 1, 1),
+('bx_payment_form_rcrl_card_add', 'item', 2147483647, 1, 2),
+('bx_payment_form_rcrl_card_add', 'token', 2147483647, 1, 3),
+('bx_payment_form_rcrl_card_add', 'first_name', 2147483647, 1, 4),
+('bx_payment_form_rcrl_card_add', 'last_name', 2147483647, 1, 5),
+('bx_payment_form_rcrl_card_add', 'email', 2147483647, 1, 6),
+('bx_payment_form_rcrl_card_add', 'card_number', 2147483647, 1, 7),
+('bx_payment_form_rcrl_card_add', 'card_expire', 2147483647, 1, 8),
+('bx_payment_form_rcrl_card_add', 'card_cvv', 2147483647, 1, 9),
+('bx_payment_form_rcrl_card_add', 'controls', 2147483647, 1, 10),
+('bx_payment_form_rcrl_card_add', 'do_submit', 2147483647, 1, 11),
+('bx_payment_form_rcrl_card_add', 'do_cancel', 2147483647, 1, 12),
+
+-- FORMS: Stripe
+('bx_payment_form_strp_details_edit', 'item_id', 2147483647, 1, 1),
+('bx_payment_form_strp_details_edit', 'controls', 2147483647, 1, 2),
+('bx_payment_form_strp_details_edit', 'do_submit', 2147483647, 1, 3),
+('bx_payment_form_strp_details_edit', 'do_cancel', 2147483647, 1, 4),
+
+('bx_payment_form_strp_card_add', 'card_number', 2147483647, 1, 1),
+('bx_payment_form_strp_card_add', 'card_expire', 2147483647, 1, 2),
+('bx_payment_form_strp_card_add', 'card_cvv', 2147483647, 1, 3),
+('bx_payment_form_strp_card_add', 'controls', 2147483647, 1, 4),
+('bx_payment_form_strp_card_add', 'do_submit', 2147483647, 1, 5),
+('bx_payment_form_strp_card_add', 'do_cancel', 2147483647, 1, 6);
+
+
+-- PRE-VALUES
+INSERT INTO `sys_form_pre_lists`(`key`, `title`, `module`, `use_for_sets`, `extendable`) VALUES
+('bx_payment_currencies', '_bx_payment_pre_lists_currencies', 'bx_payment', '0', '0');
+
+INSERT INTO `sys_form_pre_values`(`Key`, `Value`, `Order`, `LKey`, `LKey2`) VALUES
+('bx_payment_currencies', 'AUD', 1, 'AUD', 'A&#36;'),
+('bx_payment_currencies', 'CAD', 2, 'CAD', 'C&#36;'),
+('bx_payment_currencies', 'EUR', 3, 'EUR', '&#128;'),
+('bx_payment_currencies', 'GBP', 4, 'GBP', '&#163;'),
+('bx_payment_currencies', 'USD', 5, 'USD', '&#36;'),
+('bx_payment_currencies', 'YEN', 6, 'YEN', '&#165;');
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '_bx_payment', '_bx_payment', 'bx_payment@modules/boonex/payment/|std-icon.svg');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, @sName, '{url_studio}module.php?name=bx_payment', '', 'bx_payment@modules/boonex/payment/|std-icon.svg', '_bx_payment', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));

+ 36 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/template/order_history.html

@@ -0,0 +1,36 @@
+<div class="bx-payment-view-order-popup">
+    <div class="bx-payment-view-order-popup-cnt">
+		<div class="bx-payment-view-order bx-def-border">
+		    <div class="bx-payment-vo-row bx-def-padding-thd-topbottom bx-def-border-top bx-clearfix">
+		        <div class="bx-payment-vo-caption bx-def-padding-thd-left bx-def-box-sizing">__txt_seller__</div><div class="bx-payment-vo-content">
+					<bx_if:show_link>
+		            	<a href="__seller_url__" target="_blank">__seller_name__</a>
+		            </bx_if:show_link>
+		            <bx_if:show_text>__seller_name__</bx_if:show_text>
+		        </div>
+		    </div>
+		    <div class="bx-payment-vo-row bx-def-padding-thd-topbottom bx-def-border-top bx-clearfix">
+		        <div class="bx-payment-vo-caption bx-def-padding-thd-left bx-def-box-sizing">__txt_order__</div><div class="bx-payment-vo-content">__order__</div>
+		    </div>
+                    <bx_if:show_license>
+                        <div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+                            <div class="bx-payment-vo-caption">__txt_license__</div><div class="bx-payment-vo-content">__license__</div>
+                        </div>
+                    </bx_if:show_license>
+		    <div class="bx-payment-vo-row bx-def-padding-thd-topbottom bx-def-border-top bx-clearfix">
+		        <div class="bx-payment-vo-caption bx-def-padding-thd-left bx-def-box-sizing">__txt_date__</div><div class="bx-payment-vo-content">__date__</div>
+		    </div>
+		    <div class="bx-payment-vo-row bx-def-padding-thd-topbottom bx-def-border-top bx-clearfix">
+		        <div class="bx-payment-vo-caption bx-def-padding-thd-left bx-def-box-sizing">__txt_products__</div><div class="bx-payment-vo-items">
+		            <bx_repeat:items>
+		                <bx_if:link>
+		                    <a href="__url__" target="_blank">__title__</a>
+		                </bx_if:link>
+		                <bx_if:text>__title__</bx_if:text>
+		                (__quantity__) - __price__ __currency_code__<br />
+		            </bx_repeat:items>
+		        </div>
+		    </div> 
+		</div>
+	</div>
+</div>

+ 37 - 0
modules/boonex/payment/updates/9.0.11_9.0.12/source/template/order_processed.html

@@ -0,0 +1,37 @@
+<div class="bx-payment-view-order-popup">
+    <div class="bx-payment-view-order-popup-cnt">
+		<div class="bx-payment-view-order bx-def-border">
+			<div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+				<div class="bx-payment-vo-caption">__txt_client__</div><div class="bx-payment-vo-content">
+					<a href="__client_url__" target="_blank">__client_name__</a>            
+				</div>
+			</div>
+			<div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+				<div class="bx-payment-vo-caption">__txt_order__</div><div class="bx-payment-vo-content">__order__</div>
+			</div>
+                        <bx_if:show_license>
+                            <div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+                                <div class="bx-payment-vo-caption">__txt_license__</div><div class="bx-payment-vo-content">__license__</div>
+                            </div>
+                        </bx_if:show_license>
+			<div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+				<div class="bx-payment-vo-caption">__txt_processed_with__</div><div class="bx-payment-vo-content">__provider__</div>
+			</div>
+			<div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+				<div class="bx-payment-vo-caption">__txt_message__</div><div class="bx-payment-vo-content">__error__</div>
+			</div>
+			<div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+				<div class="bx-payment-vo-caption">__txt_date__</div><div class="bx-payment-vo-content">__date__</div>
+			</div>
+			<div class="bx-payment-vo-row bx-def-padding-thd bx-def-border-top bx-clearfix">
+				<div class="bx-payment-vo-caption">__txt_products__</div><div class="bx-payment-vo-items">
+					<bx_repeat:items>
+						<bx_if:link><a href="__url__" target="_blank">__title__</a></bx_if:link>
+						<bx_if:text>__title__</bx_if:text>
+						(__quantity__) - __price__ __currency_code__<br />
+					</bx_repeat:items>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>

+ 51 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/install/config.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'title' => 'Polls',
+    'version_from' => '9.0.7',
+	'version_to' => '9.0.8',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '9.0.0-RC12'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/polls/updates/update_9.0.7_9.0.8/',
+	'home_uri' => 'polls_update_907_908',
+
+	'module_dir' => 'boonex/polls/',
+	'module_uri' => 'polls',
+
+    'db_prefix' => 'bx_polls_',
+    'class_prefix' => 'BxPolls',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+		'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+		'clear_db_cache' => 0,
+    ),
+
+	/**
+     * Category for language keys.
+     */
+    'language_category' => 'Polls',
+
+	/**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/install/installer.php

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

+ 141 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/source/classes/BxPollsDb.php

@@ -0,0 +1,141 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Polls Polls
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+/*
+ * Module database queries
+ */
+class BxPollsDb extends BxBaseModTextDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+
+    public function isPerformed($iEntryId, $iAuthorId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aSubentries = $this->getSubentries(array('type' => 'entry_id_pairs', 'entry_id' => $iEntryId));
+        return (int)$this->getOne("SELECT `object_id` FROM `" . $CNF['TABLE_VOTES_SUBENTRIES_TRACK'] . "` WHERE `object_id` IN (" . $this->implode_escape(array_keys($aSubentries)) . ") AND `author_id`=:author_id LIMIT 1", array(
+            'author_id' => $iAuthorId
+        )) != 0;
+    }
+
+    public function getContentInfoBySubentryId ($iSubentryId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sQuery = $this->prepare ("SELECT `te`.* FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `te` LEFT JOIN `" . $CNF['TABLE_SUBENTRIES'] . "` AS `tse` ON `te`.`" . $CNF['FIELD_ID'] . "`=`tse`.`entry_id` WHERE `tse`.`id` = ?", $iSubentryId);
+        return $this->getRow($sQuery);
+    }
+
+    public function getSubentries($aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+        $sWhereClause = $sOrderByClause = "";
+
+        $sSelectClause = "*";
+        switch($aParams['type']) {
+            case 'id':
+                $aMethod['name'] = 'getRow';
+                $aMethod['params'][1] = array(
+                	'id' => $aParams['id']
+                );
+
+                $sWhereClause .= " AND `id`=:id";
+                break;
+
+            case 'entry_id_pairs':
+                $aMethod['name'] = 'getPairs';
+                $aMethod['params'][1] = 'id';
+                $aMethod['params'][2] = 'title';
+                $aMethod['params'][3] = array(
+                	'entry_id' => $aParams['entry_id']
+                );
+
+                $sWhereClause .= " AND `entry_id`=:entry_id";
+                break;
+
+            case 'entry_id':
+                $aMethod['params'][1] = array(
+                	'entry_id' => $aParams['entry_id']
+                );
+
+                $sWhereClause .= " AND `entry_id`=:entry_id";
+                break;
+
+            case 'entry_id_max_order':
+                $aMethod['name'] = 'getOne';
+                $aMethod['params'][1] = array(
+                	'entry_id' => $aParams['entry_id']
+                );
+
+                $sSelectClause = "MAX(`order`)";
+                $sWhereClause .= " AND `entry_id`=:entry_id";
+                break;
+
+            case 'all':
+            	break;
+        }
+
+        $sOrderByClause = " ORDER BY " . (isset($aParams['order_by']) ? '`' . $aParams['order_by'] . '`' : '`order`');
+        $sOrderByClause .= " " . (isset($aParams['order_way']) ? strtoupper($aParams['order_way']) : 'ASC');
+
+        $aMethod['params'][0] = "SELECT " . $sSelectClause . " FROM `" . $CNF['TABLE_SUBENTRIES'] . "` WHERE 1 " . $sWhereClause . $sOrderByClause;
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+    }
+
+    public function insertSubentry($aParamsSet)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($aParamsSet))
+            return false;
+
+        $sSql = "INSERT INTO `" . $CNF['TABLE_SUBENTRIES'] . "` SET " . $this->arrayToSQL($aParamsSet);
+        return $this->query($sSql);
+    }
+
+    public function updateSubentry($aParamsSet, $aParamsWhere)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($aParamsSet) || empty($aParamsWhere))
+            return false;
+
+        $sSql = "UPDATE `" . $CNF['TABLE_SUBENTRIES'] . "` SET " . $this->arrayToSQL($aParamsSet) . " WHERE " . $this->arrayToSQL($aParamsWhere, " AND ");
+        return $this->query($sSql);
+    }
+
+    public function deleteSubentry($aParams)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $sSql = "DELETE FROM `" . $CNF['TABLE_SUBENTRIES'] . "` WHERE " . $this->arrayToSQL($aParams, " AND ");
+        return $this->query($sSql);
+    }
+
+    public function deleteSubentryById($mixedId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!is_array($mixedId))
+            $mixedId = array($mixedId);
+
+        $sSql = "DELETE FROM `" . $CNF['TABLE_SUBENTRIES'] . "` WHERE `id` IN (" . $this->implode_escape($mixedId) . ")";
+        return $this->query($sSql);
+    }
+}
+
+/** @} */

+ 204 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/source/classes/BxPollsFormEntry.php

@@ -0,0 +1,204 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Polls Polls
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxPollsFormEntryCheckerHelper extends BxDolFormCheckerHelper
+{
+    static public function checkAvailSubentries ($s)
+    {
+        return !self::_isEmptyArray($s) && count($s) >= 2;
+    }
+}
+/**
+ * Create/Edit entry form
+ */
+class BxPollsFormEntry extends BxBaseModTextFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_polls';
+        parent::__construct($aInfo, $oTemplate);
+    }
+
+    public function getCode($bDynamicMode = false)
+    {
+        $sJs = $this->_oModule->_oTemplate->addJs(array('form.js'), $bDynamicMode);
+
+        $sCode = '';
+        if($bDynamicMode)
+        	$sCode .= $sJs;
+
+		$sCode .= $this->_oModule->_oTemplate->getJsCode('form');
+		$sCode .= parent::getCode($bDynamicMode);
+
+        return $sCode;
+    }
+
+    function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(isset($this->aInputs[$CNF['FIELD_SUBENTRIES']]) && !empty($aValues['id'])) {
+            $aSubentries = $this->_oModule->_oDb->getSubentries(array(
+                'type' => 'entry_id_pairs',
+                'entry_id' => $aValues['id']
+            ));
+
+            $this->aInputs[$CNF['FIELD_SUBENTRIES']]['value'] = array_values($aSubentries);
+            $this->aInputs[$CNF['FIELD_SUBENTRIES']]['value_ids'] = array_keys($aSubentries);
+        }
+
+        return parent::initChecker($aValues, $aSpecificValues);
+    }
+
+    public function insert ($aValsToAdd = array(), $isIgnore = false)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iContentId = parent::insert($aValsToAdd, $isIgnore);
+        if(!empty($iContentId))
+            $this->processSubentriesAdd($CNF['FIELD_SUBENTRIES'], $iContentId);
+
+        return $iContentId;
+    }
+
+    public function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iResult = parent::update($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
+
+        $this->processSubentriesUpdate($CNF['FIELD_SUBENTRIES'], $iContentId);
+
+        return $iResult;
+    }
+
+    public function processSubentriesAdd ($sField, $iContentId = 0)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(!isset($this->aInputs[$sField]))
+            return true;
+
+        $aSubentries = $this->getCleanValue($sField);
+        if(empty($aSubentries) || !is_array($aSubentries))
+            return true;
+
+        foreach($aSubentries as $iIndex => $sSubentry)
+            if(!empty($sSubentry))
+                $this->_oModule->_oDb->insertSubentry(array(
+                    'entry_id' => $iContentId,
+                    'title' => bx_process_input($sSubentry),
+                    'order' => $iIndex
+                ));
+
+        return true;
+    }
+
+    public function processSubentriesUpdate($sField, $iContentId = 0)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if(!isset($this->aInputs[$sField]))
+            return true;
+
+        $aSubentriesIds = $this->getCleanValue($sField . '_ids');
+        $aSubentriesValues = $this->getCleanValue($sField);
+
+        //--- Remove deleted
+        $aSubentriesDb = $this->_oModule->_oDb->getSubentries(array('type' => 'entry_id_pairs', 'entry_id' => $iContentId));
+        $this->_oModule->_oDb->deleteSubentryById(array_diff(array_keys($aSubentriesDb), $aSubentriesIds));
+
+        //--- Update existed and remove empty
+        foreach($aSubentriesIds as $iIndex => $iId)
+            if(!empty($aSubentriesValues[$iIndex]))
+                $this->_oModule->_oDb->updateSubentry(array('title' => bx_process_input($aSubentriesValues[$iIndex])), array('id' => (int)$iId));
+            else 
+                $this->_oModule->_oDb->deleteSubentry(array('id' => (int)$iId));
+
+        //--- Add new
+        $iSubentriesIds = count($aSubentriesIds);
+        $iSubentriesValues = count($aSubentriesValues);
+        if($iSubentriesValues > $iSubentriesIds) {
+            $iMaxOrder = (int)$this->_oModule->_oDb->getSubentries(array('type' => 'entry_id_max_order', 'entry_id' => $iContentId));
+
+            $aSubentriesValues = array_slice($aSubentriesValues, $iSubentriesIds);
+            foreach($aSubentriesValues as $sSubentriesValue)
+                if(!empty($sSubentriesValue))
+                    $this->_oModule->_oDb->insertSubentry(array(
+                        'entry_id' => $iContentId,
+                        'title' => bx_process_input($sSubentriesValue),
+                        'order' => ++$iMaxOrder
+                    ));
+        }
+
+        return true;
+    }
+
+    protected function genCustomInputSubentries(&$aInput)
+    {
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('form');
+
+        if(!empty($aInput['value']) && is_array($aInput['value'])) {
+            $aTmplVarsSubentries = array();
+            foreach($aInput['value'] as $iKey => $sValue) {
+                $sInput = $this->genCustomInputSubentriesText($aInput, $sValue);
+                if(!empty($aInput['value_ids'][$iKey]))
+                    $sInput .= $this->genCustomInputSubentriesHidden($aInput, (int)$aInput['value_ids'][$iKey]);
+
+                $aTmplVarsSubentries[] = array('js_object' => $sJsObject, 'input_text' => $sInput);
+            }
+        }
+        else 
+            $aTmplVarsSubentries = array(
+                array('js_object' => $sJsObject, 'input_text' => $this->genCustomInputSubentriesText($aInput)),
+                array('js_object' => $sJsObject, 'input_text' => $this->genCustomInputSubentriesText($aInput))
+            );
+
+        return $this->_oModule->_oTemplate->parseHtmlByName('form_subentries.html', array(
+            'bx_repeat:subentries' => $aTmplVarsSubentries,
+            'btn_add' => $this->genCustomInputSubentriesButton($aInput)
+        ));
+    }
+    
+    protected function genCustomInputSubentriesText($aInput, $mixedValue = '')
+    {
+        $aInput['type'] = 'text';
+        $aInput['name'] .= '[]';
+        $aInput['value'] = $mixedValue;
+        $aInput['attrs']['class'] = 'bx-def-margin-sec-top-auto';
+        
+        return $this->genInput($aInput);
+    }
+
+    protected function genCustomInputSubentriesHidden($aInput, $mixedValue = '')
+    {
+        $aInput['type'] = 'hidden';
+        $aInput['name'] .= '_ids[]';
+        $aInput['value'] = $mixedValue;
+
+        return $this->genInput($aInput);
+    }
+
+    protected function genCustomInputSubentriesButton($aInput)
+    {
+        $sName = $aInput['name'];
+
+        $aInput['type'] = 'button';
+        $aInput['name'] .= '_add';
+        $aInput['value'] = _t('_bx_polls_form_entry_input_subentries_add');
+        $aInput['attrs']['class'] = 'bx-def-margin-sec-top';
+        $aInput['attrs']['onclick'] = $this->_oModule->_oConfig->getJsObject('form') . ".subentryAdd(this, '" . $sName . "');";
+
+        return $this->genInputButton($aInput);
+    }
+}
+
+/** @} */

+ 136 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/source/install/config.php

@@ -0,0 +1,136 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Polls Polls
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_polls',
+    'title' => 'Polls',
+    'note' => 'Basic poll module.',
+    'version' => '9.0.8',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.0.0-RC12'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/polls/',
+    'home_uri' => 'polls',
+
+    'db_prefix' => 'bx_polls_',
+    'class_prefix' => 'BxPolls',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Polls',
+
+    /**
+     * 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_polls_files'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+		'bx_polls_preview',
+        'bx_polls_gallery',
+        'bx_polls_cover'
+    ),
+
+	/**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_polls',
+    	'bx_polls_cmts',
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+    	'process_esearches' => 1,
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+        'process_menu_triggers' => 1,
+        'process_page_triggers' => 1,
+    	'process_esearches' => 1,
+    	'register_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relations' => array(
+    	'bx_timeline',
+    	'bx_notifications'
+    ),
+
+);
+
+/** @} */

+ 34 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/source/js/form.js

@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Polls Polls
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+function BxPollsForm(oOptions) {
+    this._sActionsUrl = oOptions.sActionUrl;
+    this._sObjName = oOptions.sObjName == undefined ? 'oBxPollsForm' : oOptions.sObjName;
+
+    this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
+    this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+
+    this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+    this._oRequestParams = oOptions.oRequestParams == undefined ? {} : oOptions.oRequestParams;
+}
+
+BxPollsForm.prototype.subentryAdd = function(oButton, sName) {
+    var oButton = $(oButton);
+
+    var oSubentry = oButton.parents('#bx-form-element-' + sName).find('.bx-form-input-subentry:first').clone();
+    oSubentry.find("input[type = 'text']").val('');
+    oSubentry.find("input[type = 'hidden']").remove();
+
+    oButton.parents('.bx-form-input-subentry-add:first').before(oSubentry);
+};
+
+BxPollsForm.prototype.subentryDelete = function(oButton) {
+    $(oButton).parents('.bx-form-input-subentry:first').remove();
+};

+ 27 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/source/template/css/forms.css

@@ -0,0 +1,27 @@
+@import url(../../../../base/text/template/css/forms.css);
+
+/*-- Subentries custom element --*/
+.bx-form-input-subentry {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-align-items: center;
+    align-items: center;
+}
+.bx-form-input-subentry-cell.bx-fi-sc-txt {
+    -webkit-flex: 1 1 auto;
+    -ms-flex: 1 1 auto;
+    flex: 1 1 auto;
+}
+.bx-form-input-subentry-cell.bx-fi-sc-btn {
+    -webkit-flex: 0 0 auto;
+    -ms-flex: 0 0 auto;
+    flex: 0 0 auto;
+}
+
+.bx-form-input-subentry-add {
+    text-align: right;
+}
+.bx-form-input-subentry-add .bx-form-input-button {
+    display: inline-block;
+    float: none;
+}

+ 11 - 0
modules/boonex/polls/updates/9.0.7_9.0.8/source/template/form_subentries.html

@@ -0,0 +1,11 @@
+<div class="bx-form-input-subentries">
+    <bx_repeat:subentries>
+        <div class="bx-form-input-subentry bx-def-padding-thd-topbottom">
+            <div class="bx-form-input-subentry-cell bx-fi-sc-txt">__input_text__</div>
+            <div class="bx-form-input-subentry-cell bx-fi-sc-btn bx-def-padding-sec-left">
+                <a class="bx-btn" href="javascript:void(0)" onclick="javascript:__js_object__.subentryDelete(this)"><i class="sys-icon times"></i></a>
+            </div>
+        </div>
+    </bx_repeat:subentries>
+    <div class="bx-form-input-subentry-add">__btn_add__</div>
+</div>

+ 51 - 0
modules/boonex/spaces/updates/9.0.3_9.0.4/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' => 'Spaces',
+    'version_from' => '9.0.3',
+	'version_to' => '9.0.4',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '9.0.0-RC12'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/spaces/updates/update_9.0.3_9.0.4/',
+	'home_uri' => 'spaces_update_903_904',
+
+	'module_dir' => 'boonex/spaces/',
+	'module_uri' => 'spaces',
+
+    'db_prefix' => 'bx_spaces_',
+    'class_prefix' => 'BxSpaces',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+		'execute_sql' => 0,
+        'update_files' => 1,
+        'update_languages' => 0,
+		'clear_db_cache' => 0,
+    ),
+
+	/**
+     * Category for language keys.
+     */
+    'language_category' => 'Spaces',
+
+	/**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/spaces/updates/9.0.3_9.0.4/install/installer.php

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

+ 70 - 0
modules/boonex/spaces/updates/9.0.3_9.0.4/source/classes/BxSpacesFormEntry.php

@@ -0,0 +1,70 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Spaces Spaces
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Create/Edit Space Form.
+ */
+class BxSpacesFormEntry extends BxBaseModGroupsFormEntry
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_spaces';
+        parent::__construct($aInfo, $oTemplate);
+    }
+    
+    protected function genCustomInputParentSpace($aInput)
+    {
+        $iCurrent = bx_get('id');
+        if ($iCurrent === false)
+            $iCurrent = - 1;
+        $aInput['ajax_get_suggestions'] = BX_DOL_URL_ROOT . "modules/?r=" . $this->_oModule->_oConfig->getUri() . "/ajax_get_parent_space&id=" . $iCurrent;
+        $aInput['custom']['only_once'] = 1;
+        if (isset($aInput['value']) && !is_array($aInput['value']))
+            $aInput['value'] = array($aInput['value']);
+        return $this->genCustomInputUsernamesSuggestions($aInput);
+    }
+    
+    public function insert ($aValsToAdd = array(), $isIgnore = false)
+    {
+        $this->defineLevelById($aValsToAdd);
+        return parent::insert ($aValsToAdd, $isIgnore);
+    }
+
+    function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null)
+    {
+        $this->defineLevelById($aValsToAdd);
+        return parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
+    }
+    
+    function defineLevelById(&$aValsToAdd)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iParentId = 0;
+        if(isset($this->aInputs[$CNF['FIELD_PARENT']])){
+            $iParentId = $this->aInputs[$CNF['FIELD_PARENT']]['value'];
+            if(is_array($iParentId))
+                $iParentId = array_shift($iParentId);
+        }
+        $aValsToAdd[$CNF['FIELD_PARENT']] = $iParentId;
+
+        if(isset($CNF['FIELD_LEVEL']) && empty($aValsToAdd[$CNF['FIELD_LEVEL']])) {
+            $aValsToAdd[$CNF['FIELD_LEVEL']] = 0;
+            if(!empty($iParentId)) {
+                $oParent = BxDolProfile::getInstance($iParentId);
+                if($oParent)
+                    $aValsToAdd[$CNF['FIELD_LEVEL']] = $this->_oModule->_oDb->getLevelById($oParent->getContentId()) + 1;
+            }
+        }
+    }
+}
+
+/** @} */

+ 105 - 0
modules/boonex/spaces/updates/9.0.3_9.0.4/source/classes/BxSpacesModule.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    Spaces Spaces
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+/**
+ * Spaces profiles module.
+ */
+define('BX_SPS_LEVELS_LIMIT', 1);
+
+class BxSpacesModule extends BxBaseModGroupsModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+       
+        $this->_aSearchableNamesExcept[] = $this->_oConfig->CNF['FIELD_JOIN_CONFIRMATION'];
+    }
+    
+    public function serviceEntityDelete ($iContentId = 0)
+    {
+        $iContentId = $this->_getContent($iContentId, false);
+        if($iContentId === false)
+            return false;
+        $iCount = $this->_oDb->getCountEntriesByParent($iContentId);
+        if ($iCount > 0)
+            return MsgBox(_t('_bx_spaces_err_delete_child_presend'));
+        return $this->_serviceEntityForm ('deleteDataForm', $iContentId);
+    }
+    
+    public function serviceEntityParent ($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc ('entryParent', $iContentId);
+    }
+    
+    public function serviceEntityChilds ($iContentId = 0)
+    {
+        return $this->_serviceTemplateFunc ('entryChilds', $iContentId);
+    }
+    
+    public function serviceBrowseTopLevel ($bDisplayEmptyMsg = false)
+    {
+        return $this->_serviceBrowse ('top_level', false, BX_DB_PADDING_DEF, $bDisplayEmptyMsg);
+    }
+    
+    /**
+     * Get possible recipients for start conversation form
+     */
+    public function actionAjaxGetParentSpace ()
+    {
+        $sTerm = bx_get('term');
+        $iContentId = bx_get('id');
+        $a = $this->getListSpacesForParent($sTerm, $iContentId, 10);
+        header('Content-Type:text/javascript; charset=utf-8');
+        echo(json_encode($a));
+    }
+
+    public function checkAllowedPost ($aDataEntry, $isPerformAction = false)
+    {
+        if(isLogged())
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    public function checkAllowedSubscribeAdd (&$aDataEntry, $isPerformAction = false)
+    {
+        return parent::_checkAllowedSubscribeAdd ($aDataEntry, $isPerformAction);
+    }
+    
+    public function getListSpacesForParent ($sTerm, $iContentId, $iLimit)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if (!isLogged())
+            return false;
+
+        $iLevelsLimit = BX_SPS_LEVELS_LIMIT;
+        if(getParam($CNF['PARAM_MULTILEVEL_HIERARCHY']) == 'on')
+            $iLevelsLimit = 0;
+
+        $aRv = array();
+        $aTmp = $this->_oDb->searchByTermForParentSpace(bx_get_logged_profile_id(), $iContentId, $iLevelsLimit, $sTerm, $iLimit);
+        foreach ($aTmp as $aSpace) {
+            $oProfile = BxDolProfile::getInstance($aSpace['profile_id']);
+
+            $aRv[] = array (
+                'label' => $this->serviceProfileName($aSpace['content_id']),
+                'value' => $aSpace['profile_id'],
+                'url' => $oProfile->getUrl(),
+                'thumb' => $oProfile->getThumb(),
+                'unit' => $oProfile->getUnit(0, array('template' => 'unit_wo_info'))
+            );
+        }
+        return $aRv;
+    }
+}
+
+/** @} */

+ 151 - 0
modules/boonex/spaces/updates/9.0.3_9.0.4/source/install/config.php

@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defdroup    Spaces Spaces
+ * @indroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_spaces',
+    'title' => 'Spaces',
+    'note' => 'Spaces functionality.',
+    'version' => '9.0.4',
+    'vendor' => 'BoonEx',
+    'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.0.0-RC12'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/spaces/',
+    'home_uri' => 'spaces',
+
+    'db_prefix' => 'bx_spaces_',
+    'class_prefix' => 'BxSpaces',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Spaces',
+
+    /**
+     * 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_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_spaces_pics'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+        'bx_spaces_icon',
+        'bx_spaces_thumb',
+        'bx_spaces_avatar',
+        'bx_spaces_picture',
+        'bx_spaces_cover',
+        'bx_spaces_cover_thumb',
+        'bx_spaces_gallery'
+    ),
+
+    /**
+     * Extended Search Forms.
+     */
+    'esearches' => array(
+        'bx_spaces',
+        'bx_spaces_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',
+    ),
+);
+
+/** @} */

+ 51 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/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' => 'Timeline',
+    'version_from' => '9.0.12',
+	'version_to' => '9.0.13',
+    'vendor' => 'BoonEx',
+
+    'compatible_with' => array(
+        '9.0.0-RC12'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/timeline/updates/update_9.0.12_9.0.13/',
+	'home_uri' => 'timeline_update_9012_9013',
+
+	'module_dir' => 'boonex/timeline/',
+	'module_uri' => 'timeline',
+
+    'db_prefix' => 'bx_timeline_',
+    'class_prefix' => 'BxTimeline',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+		'execute_sql' => 1,
+        'update_files' => 1,
+        'update_languages' => 0,
+		'clear_db_cache' => 1,
+    ),
+
+	/**
+     * Category for language keys.
+     */
+    'language_category' => 'Timeline',
+
+	/**
+     * Files Section
+     */
+    'delete_files' => array(),
+);

+ 13 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/install/installer.php

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

+ 5 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/install/sql/enable.sql

@@ -0,0 +1,5 @@
+-- PRELOADER
+DELETE FROM `sys_preloader` WHERE `module`='bx_timeline';
+SET @iOrderPreloader = (SELECT IFNULL(MAX(`order`), 9999) FROM `sys_preloader` WHERE `type`='js_system' AND `order` > 9999 LIMIT 1);
+INSERT INTO `sys_preloader`(`module`, `type`, `content`, `active`, `order`) VALUES
+('bx_timeline', 'js_system', 'modernizr.min.js', 1, @iOrderPreloader + 1);

+ 709 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/source/classes/BxTimelineDb.php

@@ -0,0 +1,709 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxTimelineDb extends BxBaseModNotificationsDb
+{
+    protected $_sTableEvent2User;
+    protected $_sTablesRepostTrack;
+    protected $_sTableHotTrack;
+
+    protected $_aTablesMedia;
+    protected $_aTablesMedia2Events;
+
+    /*
+     * Constructor.
+     */
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+        $this->_sTableEvent2User = $this->_sPrefix . 'events2users';
+        $this->_sTableRepostsTrack = $this->_sPrefix . 'reposts_track';
+        $this->_sTableHotTrack = $this->_sPrefix . 'hot_track';
+
+        $this->_aTablesMedia = array(
+        	BX_TIMELINE_MEDIA_PHOTO => $this->_sPrefix . 'photos',
+        	BX_TIMELINE_MEDIA_VIDEO => $this->_sPrefix . 'videos' 
+        );
+        $this->_aTablesMedia2Events = array(
+        	BX_TIMELINE_MEDIA_PHOTO => $this->_sPrefix . 'photos2events',
+        	BX_TIMELINE_MEDIA_VIDEO => $this->_sPrefix . 'videos2events'
+        );
+    }
+
+    public function deleteModuleEvents($aData)
+    {
+    	foreach($aData['handlers'] as $aHandler) {
+    		//Delete system events.
+            $this->deleteEvent(array('type' => $aHandler['alert_unit'], 'action' => $aHandler['alert_action']));
+
+            //Delete reposted events.
+    		$aEvents = $this->getEvents(array('browse' => 'reposted_by_descriptor', 'type' => $aHandler['alert_unit'], 'action' => $aHandler['alert_action']));
+			foreach($aEvents as $aEvent) {
+				$aContent = unserialize($aEvent['content']);
+				if(isset($aContent['type']) && $aContent['type'] == $aHandler['alert_unit'] && isset($aContent['action']) && $aContent['action'] == $aHandler['alert_action'])
+					$this->deleteEvent(array('id' => (int)$aEvent['id']));
+			}
+    	}
+    }
+
+	public function activateModuleEvents($aData, $bActivate = true)
+    {
+    	$iActivate = $bActivate ? 1 : 0;
+
+    	foreach($aData['handlers'] as $aHandler) {
+    		//Activate (deactivate) system events.
+            $this->updateEvent(array('active' => $iActivate), array('type' => $aHandler['alert_unit'], 'action' => $aHandler['alert_action']));
+
+			//Activate (deactivate) reposted events.
+			$aEvents = $this->getEvents(array('browse' => 'reposted_by_descriptor', 'type' => $aHandler['alert_unit'], 'action' => $aHandler['alert_action']));
+			foreach($aEvents as $aEvent) {
+				$aContent = unserialize($aEvent['content']);
+				if(isset($aContent['type']) && $aContent['type'] == $aHandler['alert_unit'] && isset($aContent['action']) && $aContent['action'] == $aHandler['alert_action'])
+					$this->updateEvent(array('active' => $iActivate), array('id' => (int)$aEvent['id']));
+			}
+    	}
+    }
+
+    public function getMaxDuration($aParams)
+    {
+        $aParams['browse'] = 'last';
+        if(isset($aParams['timeline']))
+            unset($aParams['timeline']);
+
+        $aEvent = $this->getEvents($aParams);
+        if(empty($aEvent) || !is_array($aEvent))
+            return 0;
+
+        $iNowYear = date('Y', time());
+        return (int)$aEvent['year'] < $iNowYear ? (int)$aEvent['year'] : 0;
+    }
+
+    //--- Repost related methods ---//
+    public function insertRepostTrack($iEventId, $iAuthorId, $sAuthorIp, $iRepostedId)
+    {
+        $iNow = time();
+        $iAuthorNip = ip2long($sAuthorIp);
+        $sQuery = $this->prepare("INSERT INTO `{$this->_sTableRepostsTrack}` SET `event_id` = ?, `author_id` = ?, `author_nip` = ?, `reposted_id` = ?, `date` = ?", $iEventId, $iAuthorId, $iAuthorNip, $iRepostedId, $iNow);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function deleteRepostTrack($iEventId)
+    {
+        $sQuery = $this->prepare("DELETE FROM `{$this->_sTableRepostsTrack}` WHERE `event_id` = ?", $iEventId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function updateRepostCounter($iId, $iCounter, $iIncrement = 1)
+    {
+        return (int)$this->updateEvent(array('reposts' => (int)$iCounter + $iIncrement), array('id' => $iId)) > 0;
+    }
+
+    public function getReposted($sType, $sAction, $iObjectId)
+    {
+    	$bSystem = $this->_oConfig->isSystem($sType, $sAction);
+
+        if($bSystem)
+            $aParams = array('browse' => 'descriptor', 'type' => $sType, 'action' => $sAction, 'object_id' => $iObjectId);
+        else
+            $aParams = array('browse' => 'id', 'value' => $iObjectId);
+
+		$aReposted = $this->getEvents($aParams);
+		if($bSystem && (empty($aReposted) || !is_array($aReposted))) {
+			$iOwnerId = 0;
+			$iDate = 0;
+			$iHidden = 1;
+
+			$mixedResult = $this->_oConfig->getSystemDataByDescriptor($sType, $sAction, $iObjectId);
+			if(is_array($mixedResult)) {
+                            $iOwnerId = !empty($mixedResult['owner_id']) ? (int)$mixedResult['owner_id'] : 0;
+                            $iDate = !empty($mixedResult['date']) ? (int)$mixedResult['date'] : 0;
+                            if($this->_oConfig->isUnhideRestored() && !empty($iOwnerId) && !empty($iDate))
+                                $iHidden = 0;
+			}
+
+			$iId = $this->insertEvent(array(
+                            'owner_id' => $iOwnerId,
+                            'type' => $sType,
+                            'action' => $sAction,
+                            'object_id' => $iObjectId,
+                            'object_privacy_view' => $this->_oConfig->getPrivacyViewDefault('object'),
+                            'content' => '',
+                            'title' => '',
+                            'description' => '',
+                            'date' => $iDate,
+                            'hidden' => $iHidden
+			));
+
+			$aReposted = $this->getEvents(array('browse' => 'id', 'value' => $iId));
+		}
+
+        return $aReposted;
+    }
+
+    function getRepostedBy($iRepostedId)
+    {
+        $sQuery = $this->prepare("SELECT `author_id` FROM `{$this->_sTableRepostsTrack}` WHERE `reposted_id`=?", $iRepostedId);
+        return $this->getColumn($sQuery);
+    }
+
+    function isReposted($iRepostedId, $iOwnerId, $iAuthorId)
+    {
+    	$sQuery = $this->prepare("SELECT 
+    			`te`.`id`
+    		FROM `{$this->_sTableRepostsTrack}` AS `tst` 
+    		LEFT JOIN `{$this->_sTable}` AS `te` ON `tst`.`event_id`=`te`.`id` 
+    		WHERE `tst`.`author_id`=? AND `tst`.`reposted_id`=? AND `te`.`owner_id`=?", $iAuthorId, $iRepostedId, $iOwnerId);
+
+    	return (int)$this->getOne($sQuery) > 0;
+    }
+
+    //--- Photo uploader related methods ---//
+    public function saveMedia($sType, $iEventId, $iItemId)
+    {
+    	$sTable = $this->_aTablesMedia2Events[$sType];
+
+        $sQuery = $this->prepare("INSERT INTO `" . $sTable . "` SET `event_id`=?, `media_id`=?", $iEventId, $iItemId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function deleteMedia($sType, $iEventId)
+    {
+    	$sTable = $this->_aTablesMedia2Events[$sType];
+
+        $sQuery = $this->prepare("DELETE FROM `" . $sTable . "` WHERE `event_id` = ?", $iEventId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function getMedia($sType, $iEventId, $iOffset = 0)
+    {
+    	$sTableMedia = $this->_aTablesMedia[$sType];
+    	$sTableMedia2Events = $this->_aTablesMedia2Events[$sType];
+
+        $sLimitAddon = '';
+        if($iOffset != 0)
+            $sLimitAddon = $this->prepareAsString(" OFFSET ?", $iOffset);
+
+        $sQuery = $this->prepare("SELECT
+                 `tme`.`media_id` AS `id`
+            FROM `" . $sTableMedia2Events . "` AS `tme`
+            LEFT JOIN `" . $sTableMedia . "` AS `tm` ON `tme`.`media_id`=`tm`.`id`
+            WHERE `tme`.`event_id`=?" . $sLimitAddon, $iEventId);
+
+        return $this->getColumn($sQuery);
+    }
+
+    //--- Link attach related methods ---//
+    public function getUnusedLinks($iUserId, $iLinkId = 0)
+    {
+        $aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+        $aMethod['params'][1] = array(
+			'profile_id' => $iUserId
+		);
+
+        $sWhereAddon = '';
+        if(!empty($iLinkId)) {
+            $aMethod['name'] = 'getRow';
+            $aMethod['params'][1]['id'] = $iLinkId;
+
+            $sWhereAddon = " AND `tl`.`id`=:id";
+        }
+
+        $aMethod['params'][0] = "SELECT
+                `tl`.`id` AS `id`,
+                `tl`.`profile_id` AS `profile_id`,
+                `tl`.`media_id` AS `media_id`,
+                `tl`.`url` AS `url`,
+                `tl`.`title` AS `title`,
+                `tl`.`text` AS `text`,
+                `tl`.`added` AS `added`
+            FROM `" . $this->_sPrefix . "links` AS `tl`
+            LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id`
+            WHERE `tl`.`profile_id`=:profile_id AND ISNULL(`tle`.`event_id`)" . $sWhereAddon . "
+            ORDER BY `tl`.`added` DESC";
+
+        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);;
+    }
+
+    public function deleteUnusedLinks($iUserId, $iLinkId = 0)
+    {
+    	$aBindings = array(
+    		'profile_id' => $iUserId
+    	);
+
+        $sWhereAddon = '';
+        if(!empty($iLinkId)) {
+        	$aBindings['id'] = $iLinkId;
+
+            $sWhereAddon = " AND `id`=:id";
+        }
+
+        return $this->query("DELETE FROM `" . $this->_sPrefix . "links` WHERE `profile_id`=:profile_id" . $sWhereAddon, $aBindings);
+    }
+
+    public function saveLink($iEventId, $iLinkId)
+    {
+        $sQuery = $this->prepare("INSERT INTO `" . $this->_sPrefix . "links2events` SET `event_id`=?, `link_id`=?", $iEventId, $iLinkId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function deleteLinks($iEventId)
+    {
+        $sQuery = $this->prepare("DELETE FROM `tl`, `tle` USING `" . $this->_sPrefix . "links` AS `tl` LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id` WHERE `tle`.`event_id` = ?", $iEventId);
+        return (int)$this->query($sQuery) > 0;
+    }
+
+    public function getLinks($iEventId)
+    {
+        $sQuery = $this->prepare("SELECT
+                `tl`.`id` AS `id`,
+                `tl`.`profile_id` AS `profile_id`,
+                `tl`.`media_id` AS `media_id`,
+                `tl`.`url` AS `url`,
+                `tl`.`title` AS `title`,
+                `tl`.`text` AS `text`,
+                `tl`.`added` AS `added`
+            FROM `" . $this->_sPrefix . "links` AS `tl`
+            LEFT JOIN `" . $this->_sPrefix . "links2events` AS `tle` ON `tl`.`id`=`tle`.`link_id`
+            WHERE `tle`.`event_id`=?", $iEventId);
+
+        return $this->getAll($sQuery);
+    }
+
+    public function getHot()
+    {
+        return $this->getColumn("SELECT `event_id` FROM `" . $this->_sTableHotTrack . "`");
+    }
+
+    public function clearHot()
+    {
+        return $this->query("TRUNCATE TABLE `" . $this->_sTableHotTrack . "`");
+    }
+
+    public function getHotTrackByDate($iInterval = 24)
+    {
+        $sQuery = "SELECT 
+                `te`.`id` AS `event_id`,
+    			`te`.`date` AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		WHERE `te`.`date` > (UNIX_TIMESTAMP() - 3600 * :interval)";
+
+        return $this->getPairs($sQuery, 'event_id', 'value', array('interval' => $iInterval));
+    }
+
+    public function getHotTrackByCommentsDate($sModule, $sTableTrack, $iInterval = 24)
+    {
+        $sQuery = "SELECT 
+    			`te`.`id` as `event_id`,
+    			MAX(`tt`.`cmt_time`) AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		INNER JOIN `" . $sTableTrack . "` AS `tt` ON `te`.`id`=`tt`.`cmt_object_id` AND `te`.`type`=:module 
+    		WHERE `tt`.`cmt_time` > (UNIX_TIMESTAMP() - 3600 * :interval) 
+    		GROUP BY `te`.`id`";
+
+        return $this->getPairs($sQuery, 'event_id', 'value', array('module' => $sModule, 'interval' => $iInterval));
+    }
+
+    public function getHotTrackByCommentsDateModule($sModule, $sTableTrack, $iInterval = 24)
+    {
+        $sQuery = "SELECT 
+    			`te`.`id` as `event_id`,
+    			MAX(`tt`.`cmt_time`) AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		INNER JOIN `" . $sTableTrack . "` AS `tt` ON `te`.`object_id`=`tt`.`cmt_object_id` AND `te`.`type`=:module 
+    		WHERE `tt`.`cmt_time` > (UNIX_TIMESTAMP() - 3600 * :interval) 
+    		GROUP BY `te`.`object_id`";
+
+        return $this->getPairs($sQuery, 'event_id', 'value', array('module' => $sModule, 'interval' => $iInterval));
+    }
+
+    public function getHotTrackByVotesDate($sModule, $sTableTrack, $iInterval = 24)
+    {
+        $sQuery = "SELECT 
+    			`te`.`id` as `event_id`,
+    			MAX(`tt`.`date`) AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		INNER JOIN `" . $sTableTrack . "` AS `tt` ON `te`.`id`=`tt`.`object_id` AND `te`.`type`=:module 
+    		WHERE `tt`.`date` > (UNIX_TIMESTAMP() - 3600 * :interval) 
+    		GROUP BY `te`.`id`";
+
+        return $this->getPairs($sQuery, 'event_id', 'value', array('module' => $sModule, 'interval' => $iInterval));
+    }
+
+    public function getHotTrackByVotesDateModule($sModule, $sTableTrack, $iInterval = 24)
+    {
+        $sQuery = "SELECT 
+    			`te`.`id` as `event_id`,
+    			MAX(`tt`.`date`) AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		INNER JOIN `" . $sTableTrack . "` AS `tt` ON `te`.`object_id`=`tt`.`object_id` AND `te`.`type`=:module 
+    		WHERE `tt`.`date` > (UNIX_TIMESTAMP() - 3600 * :interval) 
+    		GROUP BY `te`.`object_id`";
+
+        return $this->getPairs($sQuery, 'event_id', 'value', array('module' => $sModule, 'interval' => $iInterval));
+    }
+
+    /**
+     * Hot Track by Sum of Votes during specified Period is currently disabled.
+     */
+    public function getHotTrackByVotesSum($sModule, $sTableTrack, $iInterval = 24)
+    {
+        $sQuery = "SELECT 
+    			`te`.`id` as `event_id`,
+    			SUM(`tt`.`value`) AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		INNER JOIN `" . $sTableTrack . "` AS `tt` ON `te`.`id`=`tt`.`object_id` AND `te`.`type`=:module 
+    		WHERE `tt`.`date` > (UNIX_TIMESTAMP() - 3600 * :interval) 
+    		GROUP BY `te`.`id`";
+
+        return $this->getAll($sQuery, array('module' => $sModule, 'interval' => $iInterval));
+    }
+
+    /**
+     * Hot Track by Sum of Votes during specified Period is currently disabled.
+     */
+    public function getHotTrackByVotesSumModule($sModule, $sTableTrack, $iInterval = 24)
+    {
+        $sQuery = "SELECT 
+    			`te`.`id` as `event_id`,
+    			SUM(`tt`.`value`) AS `value`
+    		FROM `" . $this->_sTable . "` AS `te`
+    		INNER JOIN `" . $sTableTrack . "` AS `tt` ON `te`.`object_id`=`tt`.`object_id` AND `te`.`type`=:module 
+    		WHERE `tt`.`date` > (UNIX_TIMESTAMP() - 3600 * :interval) 
+    		GROUP BY `te`.`object_id`";
+
+        return $this->getAll($sQuery, array('module' => $sModule, 'interval' => $iInterval));
+    }
+
+    public function updateHotTrack($aTrack)
+    {
+        return (int)$this->query("REPLACE INTO `" . $this->_sTableHotTrack . "` SET " . $this->arrayToSQL($aTrack)) > 0;
+    }
+
+    protected function _getFilterAddon($iOwnerId, $sFilter)
+    {
+        switch($sFilter) {
+            /**
+             * Direct posts in Timeline made by a timeline owner ($iOwnerId)
+             */
+            case BX_TIMELINE_FILTER_OWNER:
+                $sFilterAddon = $this->prepareAsString(" AND `{$this->_sTable}`.`action`='' AND `{$this->_sTable}`.`object_id`=? ", $iOwnerId);
+                break;
+
+            /**
+             * Direct posts in Timeline made by users except a timeline owner ($iOwnerId)
+             */
+            case BX_TIMELINE_FILTER_OTHER:
+                $sFilterAddon = $this->prepareAsString(" AND `{$this->_sTable}`.`action`='' AND `{$this->_sTable}`.`object_id`<>? ", $iOwnerId);
+                break;
+
+			/**
+             * All (Direct and System) posts in Timeline (owned by $iOwnerId) made by users except the viewer
+             */
+            case BX_TIMELINE_FILTER_OTHER_VIEWER:
+                $sFilterAddon = $this->prepareAsString(" AND (`{$this->_sTable}`.`action`<>'' OR (`{$this->_sTable}`.`action`='' AND `{$this->_sTable}`.`object_id`<>?)) ", bx_get_logged_profile_id());
+                break;
+                
+
+            case BX_TIMELINE_FILTER_ALL:
+            default:
+                $sFilterAddon = "";
+        }
+        return $sFilterAddon;
+    }
+
+    protected function _getSqlPartsEvents($aParams)
+    {
+    	$sMethod = 'getAll';
+    	$sSelectClause = "`{$this->_sTable}`.*";
+        $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
+
+        switch($aParams['browse']) {
+        	case 'owner_id':
+        		$sWhereClause = $this->prepareAsString("AND `{$this->_sTable}`.`owner_id`=? ", $aParams['value']);
+        		break;
+
+        	case 'common_by_object':
+        		$sCommonPostPrefix = $this->_oConfig->getPrefix('common_post');
+        		$sWhereClause = $this->prepareAsString("AND SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ")='" . $sCommonPostPrefix . "' AND `{$this->_sTable}`.`object_id`=? ", $aParams['value']);
+        		break;
+
+            case 'descriptor':
+                $sMethod = 'getRow';
+                $sWhereClause = "";
+
+                if(isset($aParams['type']))
+                    $sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`type`=? ", $aParams['type']);
+                if(isset($aParams['action']))
+                    $sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`action`=? ", $aParams['action']);
+                if(isset($aParams['object_id']))
+                    $sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`object_id`=? ", $aParams['object_id']);
+
+                $sLimitClause = "LIMIT 1";
+                break;
+
+            case 'reposted_by_descriptor':
+            	$sWhereClause = "";
+
+            	if(isset($aParams['type']))
+                    $sWhereClause .= "AND `{$this->_sTable}`.`content` LIKE " . $this->escape('%' . $aParams['type'] . '%');
+
+                if(isset($aParams['action']))
+                    $sWhereClause .= "AND `{$this->_sTable}`.`content` LIKE " . $this->escape('%' . $aParams['action'] . '%');
+                break;
+
+            case 'list':
+                list($sMethod, $sSelectClause, $sJoinClause, $sWhereClause, $sOrderClause, $sLimitClause) = parent::_getSqlPartsEvents($aParams);
+                if(in_array($aParams['type'], array(BX_BASE_MOD_NTFS_TYPE_CONNECTIONS, BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS)))
+                    $sSelectClause  = "DISTINCT " . $sSelectClause;
+                break;
+
+            default:
+            	list($sMethod, $sSelectClause, $sJoinClause, $sWhereClause, $sOrderClause, $sLimitClause) = parent::_getSqlPartsEvents($aParams);
+        }
+
+		$sSelectClause .= ", DAYOFYEAR(FROM_UNIXTIME(`{$this->_sTable}`.`date`)) AS `days`, DAYOFYEAR(NOW()) AS `today`, ROUND((UNIX_TIMESTAMP() - `{$this->_sTable}`.`date`)/86400) AS `ago_days`, YEAR(FROM_UNIXTIME(`{$this->_sTable}`.`date`)) AS `year`";
+		if($aParams['browse'] == 'list') {
+			$sOrderClause = "";
+
+			switch($aParams['type']) {
+				case BX_TIMELINE_TYPE_HOT:
+                    $sOrderClause = "`{$this->_sTableHotTrack}`.`value` DESC, ";
+                    break;
+
+				case BX_BASE_MOD_NTFS_TYPE_PUBLIC:
+				case BX_BASE_MOD_NTFS_TYPE_CONNECTIONS:
+				case BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS:
+					$sOrderClause = "`{$this->_sTable}`.`sticked` DESC, ";
+					break;
+
+				case BX_BASE_MOD_NTFS_TYPE_OWNER:
+					$sOrderClause = "`{$this->_sTable}`.`pinned` DESC, ";
+					break;
+			}
+
+            $sOrderClause = "ORDER BY " . $sOrderClause . "`{$this->_sTable}`.`date` DESC";
+		}
+
+        if(isset($aParams['count']) && $aParams['count'] === true) {
+            $sMethod = 'getOne';
+            $sSelectClause = "COUNT(`{$this->_sTable}`.`id`)";
+        }
+
+        return array($sMethod, $sSelectClause, $sJoinClause, $sWhereClause, $sOrderClause, $sLimitClause);
+    }
+
+    protected function _getSqlPartsEventsList($aParams)
+    {
+        $sCommonPostPrefix = $this->_oConfig->getPrefix('common_post');
+
+    	$sJoinClause = "";
+    	$sWhereClause = "AND `{$this->_sTable}`.`hidden`='0' ";
+
+		if(isset($aParams['active']))
+        	$sWhereClause .= $this->prepareAsString("AND `{$this->_sTable}`.`active`=? ", (int)$aParams['active']);
+
+		//--- Apply filter
+        if(isset($aParams['filter']))
+        	$sWhereClause .= $this->_getFilterAddon($aParams['owner_id'], $aParams['filter']);
+
+		//--- Apply timeline
+        if(isset($aParams['timeline']) && !empty($aParams['timeline'])) {
+        	$iYear = (int)$aParams['timeline'];
+            $sWhereClause .= $this->prepareAsString("AND `date`<=? ", mktime(23, 59, 59, 12, 31, $iYear));
+		}
+
+		//--- Apply modules or handlers filter
+        $sWhereModuleFilter = '';
+        if(!empty($aParams['modules']) && is_array($aParams['modules']))
+        	$sWhereModuleFilter = "AND `" . $this->_sTable . "`.`type` IN (" . $this->implode_escape($aParams['modules']) . ") ";
+
+		if($sWhereModuleFilter == '') {
+        	$aHidden = $this->_oConfig->getHandlersHidden();
+			$sWhereModuleFilter = !empty($aHidden) && is_array($aHidden) ? "AND `" . $this->_sTableHandlers . "`.`id` NOT IN (" . $this->implode_escape($aHidden) . ") " : "";
+		}
+
+		if($sWhereModuleFilter != '')
+			$sWhereClause .= $sWhereModuleFilter;
+
+        //--- Apply unpublished (date in future) filter
+        $sWhereClause .= $this->prepareAsString("AND IF(SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "' AND `{$this->_sTable}`.`object_id` = ?, 1, `{$this->_sTable}`.`date` <= UNIX_TIMESTAMP()) ", bx_get_logged_profile_id());
+
+		//--- Check type
+		$sWhereSubclause = "";
+		switch($aParams['type']) {
+		    case BX_TIMELINE_TYPE_HOT: //--- Hot (Public) Feed.
+		        $sJoinClause .= " INNER JOIN `{$this->_sTableHotTrack}` ON `{$this->_sTable}`.`id`=`{$this->_sTableHotTrack}`.`event_id`";
+		        
+		    case BX_BASE_MOD_NTFS_TYPE_PUBLIC: //--- Site (Public) Feed.
+		        //--- Apply privacy filter
+		        $aPrivacyGroups = array(BX_DOL_PG_ALL);
+		        if(isLogged())
+		            $aPrivacyGroups[] = BX_DOL_PG_MEMBERS;
+
+        		$aQueryParts = BxDolPrivacy::getObjectInstance($this->_oConfig->getObject('privacy_view'))->getContentByGroupAsSQLPart($aPrivacyGroups);
+        		$sWhereClause .= $aQueryParts['where'] . " ";
+
+        		if($this->_oConfig->isShowAll())
+        		    break;
+
+        		//--- Select All System posts
+        		$sWhereSubclause = "SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") <> '" . $sCommonPostPrefix . "'";
+
+        		//--- Select Public (Direct) posts created on Home Page Timeline (Public Feed) 
+        		$sWhereSubclause .= $this->prepareAsString(" OR `{$this->_sTable}`.`owner_id`=?", 0);
+
+        		//--- Select Promoted posts.
+		        $sWhereSubclause .= " OR `{$this->_sTable}`.`promoted` <> '0'";
+		        break;
+
+                    //--- Profile Feed
+                    case BX_BASE_MOD_NTFS_TYPE_OWNER:
+                        if(empty($aParams['owner_id']))
+                            break;
+
+                        //--- Select Own (System and Direct) posts from Profile's Timeline.
+                        $sWhereSubclause = $this->prepareAsString("(`{$this->_sTable}`.`owner_id` = ?)", $aParams['owner_id']);
+
+                        //--- Select Own Public (Direct) posts from Home Page Timeline (Public Feed).
+                        $sWhereSubclause .= $this->prepareAsString(" OR (`{$this->_sTable}`.`owner_id` = '0' AND IF(SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "', `{$this->_sTable}`.`object_id` = ?, 1))", $aParams['owner_id']);
+
+                        bx_alert($this->_oConfig->getName(), 'get_list_by_type', 0, 0, array(
+                            'type' => BX_BASE_MOD_NTFS_TYPE_OWNER,
+                            'owner_id' => $aParams['owner_id'],
+                            'table' => $this->_sTable,
+                            'where_clause' => &$sWhereClause,
+                            'where_subclause' => &$sWhereSubclause
+                        ));
+                        break;
+
+                    //--- Profile Connections Feed
+                    case BX_BASE_MOD_NTFS_TYPE_CONNECTIONS:
+                        if(empty($aParams['owner_id']))
+                            break;
+
+                        $oConnection = BxDolConnection::getObjectInstance($this->_oConfig->getObject('conn_subscriptions'));
+
+                        $aQueryParts = $oConnection->getConnectedContentAsSQLPartsExt($this->_sPrefix . 'events', 'owner_id', $aParams['owner_id']);
+                        $aJoin1 = $aQueryParts['join'];
+
+                        $aQueryParts = $oConnection->getConnectedContentAsSQLPartsExt($this->_sPrefix . 'events', 'object_id', $aParams['owner_id']);
+                        $aJoin2 = $aQueryParts['join'];
+
+                        //--- Join System and Direct posts made by following members.  
+                        $sJoinClause .= " " . $aJoin1['type'] . " JOIN `" . $aJoin1['table'] . "` AS `" . $aJoin1['table_alias'] . "` ON ((" . $aJoin1['condition'] . ") OR (SUBSTRING(`" . $this->_sTable . "`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "' AND " . $aJoin2['condition'] . "))";
+
+                        //--- Exclude Own (Direct) posts on timelines of following members.
+                        //--- Note. Disabled for now.
+                        //$sWhereSubclause = $this->prepareAsString("IF(SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "', `{$this->_sTable}`.`object_id` <> ?, 1)", $aParams['owner_id']);
+
+                        //--- Select Promoted posts.
+                        $sWhereSubclause .= " OR `{$this->_sTable}`.`promoted` <> '0'";
+                        break;
+
+                    //--- Profile + Profile Connections Feed
+                    case BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS:
+                        if(empty($aParams['owner_id']))
+                            break;
+
+                        $oConnection = BxDolConnection::getObjectInstance($this->_oConfig->getObject('conn_subscriptions'));
+
+                        $aQueryParts = $oConnection->getConnectedContentAsSQLPartsExt($this->_sPrefix . 'events', 'owner_id', $aParams['owner_id']);
+                        $aJoin1 = $aQueryParts['join'];
+
+                        $aQueryParts = $oConnection->getConnectedContentAsSQLPartsExt($this->_sPrefix . 'events', 'object_id', $aParams['owner_id']);
+                        $aJoin2 = $aQueryParts['join'];
+
+                        //--- Join System and Direct posts made by following members. 'LEFT' join is essential to apply different conditions.
+                        $sJoinClause .= " LEFT JOIN `" . $aJoin1['table'] . "` AS `" . $aJoin1['table_alias'] . "` ON ((" . $aJoin1['condition'] . ") OR (SUBSTRING(`" . $this->_sTable . "`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "' AND " . $aJoin2['condition'] . "))";
+
+                        //--- Select Own (System and Direct) posts from Profile's Timeline.
+                        $sWhereSubclause = $this->prepareAsString("(`{$this->_sTable}`.`owner_id` = ?)", $aParams['owner_id']);
+
+                        //--- Select Own Public (Direct) posts from Home Page Timeline (Public Feed).
+                        $sWhereSubclause .= $this->prepareAsString(" OR (`{$this->_sTable}`.`owner_id` = '0' AND IF(SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "', `{$this->_sTable}`.`object_id` = ?, 1))", $aParams['owner_id']);
+
+                        //--- Exclude Own (Direct) posts on timelines of following members.
+                        //--- Note. Disabled for now and next check is used instead. 
+                        //$sWhereSubclause .= $this->prepareAsString(" OR (NOT ISNULL(`c`.`content`) AND IF(SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "', `{$this->_sTable}`.`object_id` <> ?, 1))", $aParams['owner_id']);
+
+                        //--- All posts on timelines of following members.
+                        $sWhereSubclause .= " OR NOT ISNULL(`c`.`content`)";				
+
+                        //--- Select Promoted posts.
+                        $sWhereSubclause .= " OR `{$this->_sTable}`.`promoted` <> '0'";
+                        break;
+		}
+
+		if(!empty($sWhereSubclause))
+		    $sWhereClause .= "AND (" . $sWhereSubclause . ") ";
+
+		return array($sJoinClause, $sWhereClause);
+    }
+
+    function updateSimilarObject($iId, &$oAlert, $sDuration = 'day')
+    {
+        $sType = $oAlert->sUnit;
+        $sAction = $oAlert->sAction;
+
+        //Check handler
+        $aHandler = $this->_oConfig->getHandlers($sType . '_' . $sAction);
+        if(empty($aHandler) || !is_array($aHandler) || (int)$aHandler['groupable'] != 1)
+            return false;
+
+        //Check content's extra values
+        if(isset($aHandler['group_by']) && !empty($aHandler['group_by']) && (!isset($oAlert->aExtras[$aHandler['group_by']]) || empty($oAlert->aExtras[$aHandler['group_by']])))
+            return false;
+
+		$aBindings = array(
+			'object_id' => $oAlert->iObject,
+			'id' => $iId,
+			'owner_id' => $oAlert->iSender,
+			'type' => $sType,
+			'action' => $sAction
+		);
+
+        $sWhereClause = "";
+        switch($sDuration) {
+            case 'day':
+                $aBindings['day_start'] = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
+                $aBindings['day_end'] = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
+
+                $sWhereClause .= "AND `date`>:day_start AND `date`<:day_end ";
+                break;
+        }
+
+        if(isset($aHandler['group_by'])) {
+        	$aBindings['content'] = '%' . $oAlert->aExtras[$aHandler['group_by']] . '%';
+
+            $sWhereClause .= "AND `content` LIKE :content ";
+        }
+
+        $sSql = "UPDATE `{$this->_sTable}`
+            SET
+                `object_id`=CONCAT(`object_id`, ',:object_id'),
+                `title`='',
+                `description`='',
+                `date`=UNIX_TIMESTAMP()
+            WHERE
+                `id`<>:id AND
+                `owner_id`=:owner_id AND
+                `type`=:type AND
+                `action`=:action " . $sWhereClause;
+        $mixedResult = $this->query($sSql, $aBindings);
+
+        if((int)$mixedResult > 0)
+            $this->deleteEvent(array('id' => $iId));
+
+        return $mixedResult;
+    }
+}
+
+/** @} */

+ 3065 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/source/classes/BxTimelineModule.php

@@ -0,0 +1,3065 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAcl');
+bx_import('BxBaseModNotificationsModule');
+
+define('BX_TIMELINE_TYPE_ITEM', 'view_item');
+define('BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS', 'owner_and_connections');
+define('BX_TIMELINE_TYPE_HOT', 'hot');
+define('BX_TIMELINE_TYPE_DEFAULT', BX_BASE_MOD_NTFS_TYPE_OWNER);
+
+define('BX_TIMELINE_VIEW_ITEM', 'item');
+define('BX_TIMELINE_VIEW_TIMELINE', 'timeline');
+define('BX_TIMELINE_VIEW_OUTLINE', 'outline');
+define('BX_TIMELINE_VIEW_SEARCH', 'search');
+define('BX_TIMELINE_VIEW_DEFAULT', BX_TIMELINE_VIEW_OUTLINE);
+
+define('BX_TIMELINE_FILTER_ALL', 'all');
+define('BX_TIMELINE_FILTER_OWNER', 'owner');
+define('BX_TIMELINE_FILTER_OTHER', 'other');
+define('BX_TIMELINE_FILTER_OTHER_VIEWER', 'other_viewer');
+
+define('BX_TIMELINE_PARSE_TYPE_POST', 'post');
+define('BX_TIMELINE_PARSE_TYPE_REPOST', 'repost');
+define('BX_TIMELINE_PARSE_TYPE_DEFAULT', BX_TIMELINE_PARSE_TYPE_POST);
+
+define('BX_TIMELINE_MEDIA_PHOTO', 'photo');
+define('BX_TIMELINE_MEDIA_VIDEO', 'video');
+
+//--- Video Auto Play 
+define('BX_TIMELINE_VAP_OFF', 'off');
+define('BX_TIMELINE_VAP_ON_MUTE', 'on_mute');
+define('BX_TIMELINE_VAP_ON', 'on');
+
+class BxTimelineModule extends BxBaseModNotificationsModule implements iBxDolContentInfoService
+{
+    protected $_sJsPostObject;
+    protected $_sJsViewObject;
+    protected $_aPostElements;
+    protected $_sJsOutlineObject;
+
+    protected $_sDividerTemplate;
+    protected $_sBalloonTemplate;
+    protected $_sCmtPostTemplate;
+    protected $_sCmtViewTemplate;
+    protected $_sCmtTemplate;
+
+    /**
+     * Constructor
+     */
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    /**
+     * ACTION METHODS
+     */
+    public function actionVideo($iEventId, $iVideoId)
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iEventId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return;
+
+        $aData = $this->_oTemplate->getData($aEvent);
+        if($aData === false || !isset($aData['content']['videos'][$iVideoId]))
+            return;
+
+        $oTemplate = $this->_oTemplate;
+        $oTemplate->setPageNameIndex (BX_PAGE_CLEAR);
+        $oTemplate->setPageContent ('page_main_code', $this->_oTemplate->getVideo($aEvent, $aData['content']['videos'][$iVideoId]));
+        $oTemplate->getPageCode();
+    }
+
+    public function actionPost()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $mixedAllowed = $this->isAllowedPost(true);
+        if($mixedAllowed !== true)
+            return echoJson(array('message' => strip_tags($mixedAllowed)));
+
+        echoJson($this->getFormPost());
+    }
+
+    public function actionEdit($iId)
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $mixedAllowed = $this->isAllowedPost(true);
+        if($mixedAllowed !== true)
+            return echoJson(array('message' => strip_tags($mixedAllowed)));
+
+        echoJson($this->getFormEdit($iId, array('dynamic_mode' => true)));
+    }
+
+	function actionPin()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+
+        $mixedAllowed = $this->{'isAllowed' . ((int)$aEvent['pinned'] == 0 ? 'Pin' : 'Unpin')}($aEvent, true);
+        if($mixedAllowed !== true)
+            return echoJson(array('code' => 1, 'message' => strip_tags($mixedAllowed)));
+
+		$aEvent['pinned'] = (int)$aEvent['pinned'] == 0 ? time() : 0;
+        if(!$this->_oDb->updateEvent(array('pinned' => $aEvent['pinned']), array('id' => $iId)))
+        	return echoJson(array('code' => 2));
+
+		echoJson(array(
+			'code' => 0, 
+			'id' => $iId, 
+			'eval' => $this->_oConfig->getJsObject('view') . '.onPinPost(oData)'
+		));
+    }
+
+    function actionStick()
+    {
+    	$this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+    	$iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+    	$aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+
+    	$mixedAllowed = $this->{'isAllowed' . ((int)$aEvent['sticked'] == 0 ? 'Stick' : 'Unstick')}($aEvent, true);
+    	if($mixedAllowed !== true)
+    		return echoJson(array('code' => 1, 'message' => strip_tags($mixedAllowed)));
+
+    	$aEvent['sticked'] = (int)$aEvent['sticked'] == 0 ? time() : 0;
+    	if(!$this->_oDb->updateEvent(array('sticked' => $aEvent['sticked']), array('id' => $iId)))
+    		return echoJson(array('code' => 2));
+
+    	echoJson(array(
+	    	'code' => 0,
+	    	'id' => $iId,
+	    	'eval' => $this->_oConfig->getJsObject('view') . '.onStickPost(oData)'
+		));
+    }
+
+    function actionPromote()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+
+        $mixedAllowed = $this->{'isAllowed' . ((int)$aEvent['promoted'] == 0 ? 'Promote' : 'Unpromote')}($aEvent, true);
+        if($mixedAllowed !== true)
+            return echoJson(array('code' => 1, 'message' => strip_tags($mixedAllowed)));
+
+		$aEvent['promoted'] = (int)$aEvent['promoted'] == 0 ? time() : 0;
+        if(!$this->_oDb->updateEvent(array('promoted' => $aEvent['promoted']), array('id' => $iId)))
+        	return echoJson(array('code' => 2));
+
+		echoJson(array(
+			'code' => 0, 
+			'message' => _t('_bx_timeline_txt_msg_performed_action')
+		));
+    }
+
+    function actionDelete()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => bx_process_input(bx_get('id'), BX_DATA_INT)));
+
+        $mixedAllowed = $this->isAllowedDelete($aEvent, true);
+        if($mixedAllowed !== true)
+            return echoJson(array('code' => 1, 'message' => strip_tags($mixedAllowed)));
+
+        if(!$this->deleteEvent($aEvent))
+            return echoJson(array('code' => 2));
+
+        echoJson(array(
+        	'code' => 0, 
+        	'id' => $aEvent['id'], 
+        	'eval' => $this->_oConfig->getJsObject('view') . '.onDeletePost(oData)'
+        ));
+    }
+
+    public function actionRepost()
+    {
+    	$iAuthorId = $this->getUserId();
+        $iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+        $sType = bx_process_input(bx_get('type'), BX_DATA_TEXT);
+        $sAction = bx_process_input(bx_get('action'), BX_DATA_TEXT);
+        $iObjectId = bx_process_input(bx_get('object_id'), BX_DATA_INT);
+
+        $aResult = $this->serviceRepost($iAuthorId, $iOwnerId, $sType, $sAction, $iObjectId);
+        if(!empty($aResult) && is_array($aResult))
+            return echoJson($aResult);
+
+        $aReposted = $this->_oDb->getReposted($sType, $sAction, $iObjectId);
+        $sCounter = $this->_oTemplate->getRepostCounter($aReposted);
+
+        echoJson(array(
+            'code' => 0, 
+            'message' => _t('_bx_timeline_txt_msg_success_repost'), 
+            'count' => $aReposted['reposts'], 
+            'countf' => (int)$aReposted['reposts'] > 0 ? $this->_oTemplate->getRepostCounterLabel($aReposted['reposts']) : '',
+            'counter' => $sCounter,
+            'disabled' => true
+        ));
+    }
+
+    function actionGetPost()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $sJsObject = bx_process_input(bx_get('js_object'));
+        if(empty($sJsObject))
+            $sJsObject = $this->_oConfig->getJsObject('post');
+
+        $sView = bx_process_input(bx_get('view'));
+        $sType = bx_process_input(bx_get('type'));
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        $bAfpsLoading = (int)bx_get('afps_loading') === 1;
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return echoJson(array());
+
+        /**
+         * Note. Disabled for now, because Own posts on Timelines of Following members 
+         * became visible on posts' author Dashboard Timeline.
+         */
+        //if($bAfpsLoading && $this->_iOwnerId != $aEvent['owner_id'])
+        //    return echoJson(array('message' => _t('_bx_timeline_txt_msg_posted')));
+            
+        echoJson(array(
+            'id' => $aEvent['id'],
+            'view' => $sView,
+        	'item' => $this->_oTemplate->getPost($aEvent, array(
+        		'view' => $sView, 
+        		'type' => !empty($sType) ? $sType : BX_TIMELINE_TYPE_DEFAULT,
+        		'owner_id' => $this->_iOwnerId, 
+        		'dynamic_mode' => true
+            )),
+            'eval' => $sJsObject . "._onGetPost(oData)"
+        ));
+    }
+
+    function actionGetPosts()
+    {
+        $aParams = $this->_prepareParamsGet();
+        list($sItems, $sLoadMore, $sBack, $sEmpty) = $this->_oTemplate->getPosts($aParams);
+
+        echoJson(array(
+        	'view' => $aParams['view'],
+        	'items' => $sItems, 
+        	'load_more' => $sLoadMore, 
+        	'back' => $sBack,
+            'empty' => $sEmpty,
+        	'eval' => $this->_oConfig->getJsObject('view') . "._onGetPosts(oData)"
+        ));
+    }
+
+    public function actionGetPostForm()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+        $sType = bx_process_input(bx_get('type'));
+
+        echoJson($this->getFormPost(array(
+            'type' => $sType,
+            'form_display' => $this->_oConfig->getPostFormDisplay($sType)
+        )));
+    }
+
+    public function actionGetEditForm($iId)
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        echoJson($this->getFormEdit($iId, array('dynamic_mode' => true)));
+    }
+
+    public function actionGetComments()
+    {
+        $this->_iOwnerId = bx_process_input(bx_get('owner_id'), BX_DATA_INT);
+
+        $sSystem = bx_process_input(bx_get('system'), BX_DATA_TEXT);
+        $iId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        $sComments = $this->_oTemplate->getComments($sSystem, $iId, array('dynamic_mode' => true));
+
+        echoJson(array('content' => $sComments));
+    }
+
+    public function actionAddAttachLink()
+    {
+        $sUrl = bx_process_input(bx_get('url'));
+        if(empty($sUrl))
+            return echoJson(array());
+
+        echoJson($this->addAttachLink(array(
+            'url' => $sUrl
+        )));
+    }
+
+    public function actionDeleteAttachLink()
+    {
+    	$iUserId = $this->getUserId();
+        $iLinkId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(empty($iLinkId)) {
+            echoJson(array());
+            return;
+        }
+
+        $aLink = $this->_oDb->getUnusedLinks($iUserId, $iLinkId);
+    	if(empty($aLink) || !is_array($aLink)) {
+            echoJson(array());
+            return;
+        }
+
+		if(!empty($aLink['media_id']))
+			BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'))->deleteFile($aLink['media_id']);
+
+        $aResult = array();
+        if($this->_oDb->deleteUnusedLinks($iUserId, $iLinkId))
+            $aResult = array('code' => 0);
+        else
+            $aResult = array('code' => 1, 'message' => _t('_bx_timeline_form_post_input_link_err_delete'));
+
+        echoJson($aResult);
+    }
+
+    public function actionGetAttachLinkForm()
+    {
+        echo $this->_oTemplate->getAttachLinkForm();
+    }
+
+    public function actionSubmitAttachLinkForm()
+    {
+        echoJson($this->getFormAttachLink());
+    }
+
+    public function actionGetRepostedBy()
+    {
+        $iRepostedId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+        echo $this->_oTemplate->getRepostedBy($iRepostedId);
+    }
+
+    public function actionGetItemBrief()
+    {
+        echo BxDolPage::getObjectInstance($this->_oConfig->getObject('page_item_brief'), $this->_oTemplate)->getCode();
+    }
+
+    public function actionResumeLiveUpdate($sType, $iOwnerId)
+    {
+    	$sKey = $this->_oConfig->getLiveUpdateKey($sType, $iOwnerId);
+
+    	bx_import('BxDolSession');
+    	BxDolSession::getInstance()->unsetValue($sKey, $iOwnerId);
+    }
+
+	public function actionPauseLiveUpdate($sType, $iOwnerId)
+    {
+    	$sKey = $this->_oConfig->getLiveUpdateKey($sType, $iOwnerId);
+
+    	bx_import('BxDolSession');
+    	BxDolSession::getInstance()->setValue($sKey, 1);
+    }
+
+    function actionRss()
+    {
+        $aArgs = func_get_args();
+
+        $sType = array_shift($aArgs);
+        $iOwnerId = 0;
+
+        switch($sType) {
+            case BX_BASE_MOD_NTFS_TYPE_OWNER:
+                $iOwnerId = array_shift($aArgs);
+                list($sUserName) = $this->getUserInfo($iOwnerId);
+
+                $sRssCaption = _t('_bx_timeline_txt_rss_caption', $sUserName);
+                $sRssLink = $this->_oConfig->getViewUrl($iOwnerId);
+                break;
+
+            case BX_BASE_MOD_NTFS_TYPE_PUBLIC:
+                $sRssCaption = _t('_bx_timeline_page_title_view_home');
+                $sRssLink = $this->_oConfig->getHomeViewUrl();
+                break;
+        }
+
+        $aParams = $this->_prepareParams(BX_TIMELINE_VIEW_DEFAULT, $sType, $iOwnerId, 0, $this->_oConfig->getRssLength(), '', array(), 0);
+        $aEvents = $this->_oDb->getEvents($aParams);
+
+        $aRssData = array();
+        foreach($aEvents as $aEvent) {
+            if(empty($aEvent['title'])) 
+                continue;
+
+            $iOwner = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $aEvent['owner_id'] : $aEvent['object_id'];
+            $oOwner = BxDolProfile::getInstanceMagic($iOwner);
+
+            $aRssData[$aEvent['id']] = array(
+               'UnitID' => $aEvent['id'],
+               'UnitTitle' => $aEvent['title'],
+               'UnitLink' => $this->_oConfig->getItemViewUrl($aEvent),
+               'UnitDesc' => bx_replace_markers($aEvent['description'], array(
+                    'profile_name' => $oOwner->getDisplayName()
+                )),
+               'UnitDateTimeUTS' => $aEvent['date'],
+            );
+        }
+
+        $oRss = new BxDolRssFactory();
+
+        header('Content-Type: application/xml; charset=utf-8');
+        echo $oRss->GenRssByData($aRssData, $sRssCaption, $sRssLink);
+    }
+
+
+    /**
+     * SERVICE METHODS
+     */
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_create_post_form get_create_post_form
+     * 
+     * @code bx_srv('bx_timeline', 'get_create_post_form', [...]); @endcode
+     * 
+     * Get form code for add content. Is needed for United Post Form.
+     * 
+     * @param $aParams optional array with parameters(display name, etc)
+     * @return form code or error
+     * 
+     * @see BxTimelineModule::serviceGetCreatePostForm
+     */
+    /** 
+     * @ref bx_timeline-get_create_post_form "get_create_post_form"
+     */
+    public function serviceGetCreatePostForm($aParams = array())
+    {
+    	$aParams = array_merge($this->_aFormParams, $aParams);
+
+        $this->_iOwnerId = $aParams['context_id'];
+
+    	$oForm = $this->serviceGetObjectForm('add', $aParams);
+    	if(!$oForm)
+            return '';
+
+        if(!empty($aParams['display']))
+            $aParams['form_display'] = $aParams['display'];
+        else if(isset($aParams['context_id'])) {
+            if((int)$aParams['context_id'] == 0)
+                $aParams['form_display'] = 'form_display_post_add_public';
+            else
+                $aParams['form_display'] = 'form_display_post_add_profile';
+        }
+
+    	$aResult = $this->getFormPost($aParams);
+    	if(!empty($aResult['form'])) {
+            $bDynamicMode = isset($aParams['dynamic_mode']) && $aParams['dynamic_mode'];
+
+            $sCode = '';
+            $sCode .= $this->_oTemplate->getCssJs($bDynamicMode);
+            $sCode .= $this->_oTemplate->getJsCodePost($this->_iOwnerId);
+            $sCode .= $aResult['form'];
+            return $sCode;
+        }
+
+        if(!empty($aResult['message']))
+                return $aResult['message'];
+
+        return '';
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_object_form get_object_form
+     * 
+     * @code bx_srv('bx_timeline', 'get_object_form', [...]); @endcode
+     * 
+     * Get form object for add, edit, view or delete the content.
+     * 
+     * @param $sType 'add' is supported only 
+     * @param $aParams optional array with parameters(display name, etc)
+     * @return form object or false on error
+     * 
+     * @see BxTimelineModule::serviceGetObjectForm
+     */
+    /** 
+     * @ref bx_timeline-get_object_form "get_object_form"
+     */
+    public function serviceGetObjectForm ($sType, $aParams = array())
+    {
+    	if (!in_array($sType, array('add')))
+            return false;
+
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!empty($aParams['display']))
+            $aParams['form_display'] = $aParams['display'];
+        else if(isset($aParams['context_id'])) {
+            if((int)$aParams['context_id'] == 0)
+                $aParams['form_display'] = 'form_display_post_add_public';
+            else
+                $aParams['form_display'] = 'form_display_post_add_profile';
+        }
+
+    	return $this->getFormPostObject($aParams);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection get_timeline_post
+     * @see BxTimelineModule::serviceGetTimelinePost
+     *
+     * Get Timeline post. It's needed for Timeline module.
+     * 
+     * @param $aEvent timeline event array from Timeline module
+     * @return array in special format which is needed specifically for Timeline module to display the data.
+     */
+    public function serviceGetTimelinePost($aEvent, $aBrowseParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        /*
+         * Note. For 'Direct Timeline Posts' FIELD_OBJECT_ID contains post's author profile ID.
+         */
+        $CNF['FIELD_AUTHOR'] = $CNF['FIELD_OBJECT_ID'];
+        return parent::serviceGetTimelinePost($aEvent, $aBrowseParams);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_author get_author
+     * 
+     * @code bx_srv('bx_timeline', 'get_author', [...]); @endcode
+     * 
+     * Get author ID from content info by content ID. Is used in "Content Info Objects" system.
+     * 
+     * @param $iContentId integer value with content ID.
+     * @return integer value with author ID.
+     * 
+     * @see BxTimelineModule::serviceGetAuthor
+     */
+    /** 
+     * @ref bx_timeline-get_author "get_author"
+     */
+    public function serviceGetAuthor ($iContentId)
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContentId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return 0;
+
+        return $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? (int)$aEvent['owner_id'] : (int)$aEvent['object_id'];
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_date_changed get_date_changed
+     * 
+     * @code bx_srv('bx_timeline', 'get_date_changed', [...]); @endcode
+     * 
+     * Get date when the content was changed last time. Is used in "Content Info Objects" system.
+     * Note. In case of Timeline event 0 is returned everytime.
+     * 
+     * @param $iContentId integer value with content ID.
+     * @return integer value with changing date.
+     * 
+     * @see BxTimelineModule::serviceGetDateChanged
+     */
+    /** 
+     * @ref bx_timeline-get_date_changed "get_date_changed"
+     */
+    public function serviceGetDateChanged ($iContentId)
+    {
+        return 0;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_link get_link
+     * 
+     * @code bx_srv('bx_timeline', 'get_link', [...]); @endcode
+     * 
+     * Get content view page link. Is used in "Content Info Objects" system.
+     * 
+     * @param $iContentId integer value with content ID.
+     * @return string value with view page link.
+     * 
+     * @see BxTimelineModule::serviceGetLink
+     */
+    /** 
+     * @ref bx_timeline-get_link "get_link"
+     */
+    public function serviceGetLink ($iContentId)
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContentId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return '';
+
+        return $this->_oConfig->getItemViewUrl($aEvent);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_thumb get_thumb
+     * 
+     * @code bx_srv('bx_timeline', 'get_thumb', [...]); @endcode
+     * 
+     * Get content thumbnail link. Is used in "Content Info Objects" system.
+     * Note. In case of Timeline event an empty string is returned everytime.
+     * 
+     * @param $iContentId integer value with content ID.
+     * @param $sTranscoder (optional) string value with transcoder name which should be applied to thumbnail image.
+     * @return string value with thumbnail link.
+     * 
+     * @see BxTimelineModule::serviceGetThumb
+     */
+    /** 
+     * @ref bx_timeline-get_thumb "get_thumb"
+     */
+    public function serviceGetThumb ($iContentId, $sTranscoder = '') 
+    {
+        return '';
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_info get_info
+     * 
+     * @code bx_srv('bx_timeline', 'get_info', [...]); @endcode
+     * 
+     * Get content info by content ID. Is used in "Content Info Objects" system.
+     * 
+     * @param $iContentId integer value with content ID.
+     * @param $bSearchableFieldsOnly (optional) boolean value determining all info or "searchable fields" only will be returned.
+     * @return an array with content info. Empty array is returned if something is wrong.
+     * 
+     * @see BxTimelineModule::serviceGetInfo
+     */
+    /** 
+     * @ref bx_timeline-get_info "get_info"
+     */
+    public function serviceGetInfo ($iContentId, $bSearchableFieldsOnly = true)
+    {
+        $aContentInfo = $this->_oDb->getEvents(array(
+        	'browse' => 'id', 
+        	'value' => $iContentId)
+        );
+
+        return BxDolContentInfo::formatFields($aContentInfo);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_search_result_unit get_search_result_unit
+     * 
+     * @code bx_srv('bx_timeline', 'get_search_result_unit', [...]); @endcode
+     * 
+     * Get search result unit by content ID. Is used in "Content Info Objects" system.
+     * 
+     * @param $iContentId integer value with content ID.
+     * @param $sUnitTemplate (optional) string value with template name.
+     * @return HTML string with search result unit. Empty string is returned if something is wrong.
+     * 
+     * @see BxTimelineModule::serviceGetSearchResultUnit
+     */
+    /** 
+     * @ref bx_timeline-get_search_result_unit "get_search_result_unit"
+     */
+    public function serviceGetSearchResultUnit ($iContentId, $sUnitTemplate = '')
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContentId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return '';
+
+        if(empty($sUnitTemplate))
+            $sUnitTemplate = 'unit.html';
+
+        return $this->_oTemplate->unit($aEvent, true, $sUnitTemplate);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_post get_block_post
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_post', [...]); @endcode
+     * 
+     * Get Post block for a separate page.
+     *
+     * @param $iProfileId (optional) profile ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockPost
+     */
+    /** 
+     * @ref bx_timeline-get_block_post "get_block_post"
+     */
+    public function serviceGetBlockPost($iProfileId = 0)
+    {
+    	if(empty($iProfileId) && bx_get('profile_id') !== false)
+			$iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
+
+		if(empty($iProfileId) && isLogged())
+			$iProfileId = bx_get_logged_profile_id();
+
+        if(!$iProfileId)
+            return array();
+
+        $sType = BX_BASE_MOD_NTFS_TYPE_OWNER;
+        return $this->_getBlockPost($iProfileId, array(
+        	'type' => $sType,
+        	'form_display' => $this->_oConfig->getPostFormDisplay($sType)
+        ));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_post_profile get_block_post_profile
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_post_profile', [...]); @endcode
+     * 
+     * Get Post block for the Profile page.
+     *
+     * @param $sProfileModule (optional) string value with profile based module name. Persons module is used by default.
+     * @param $iProfileContentId (optional) profile's content ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockPostProfile
+     */
+    /** 
+     * @ref bx_timeline-get_block_post_profile "get_block_post_profile"
+     */
+    public function serviceGetBlockPostProfile($sProfileModule = 'bx_persons', $iProfileContentId = 0)
+    {
+        if(empty($sProfileModule))
+    		return array();
+
+    	if(empty($iProfileContentId) && bx_get('id') !== false)
+    		$iProfileContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+		$oProfile = BxDolProfile::getInstanceByContentAndType($iProfileContentId, $sProfileModule);
+		if(empty($oProfile))
+			return array();
+
+        $iProfileId = $oProfile->id();
+        $sType = BX_BASE_MOD_NTFS_TYPE_OWNER;
+		return $this->_getBlockPost($iProfileId, array(
+		    'type' => $sType,
+			'form_display' => $this->_oConfig->getPostFormDisplay($sType)
+		));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_post_home get_block_post_home
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_post_home', [...]); @endcode
+     * 
+     * Get Post block for site's Home page.
+     *
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockPostHome
+     */
+    /** 
+     * @ref bx_timeline-get_block_post_home "get_block_post_home"
+     */
+    public function serviceGetBlockPostHome()
+    {
+        $iProfileId = 0;
+        $sType = BX_BASE_MOD_NTFS_TYPE_PUBLIC;
+        return $this->_getBlockPost($iProfileId, array(
+        	'type' => $sType,
+            'form_display' => $this->_oConfig->getPostFormDisplay($sType)
+        ));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_post_account get_block_post_account
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_post_account', [...]); @endcode
+     * 
+     * Get Post block for the Dashboard page.
+     *
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockPostAccount
+     */
+    /** 
+     * @ref bx_timeline-get_block_post_account "get_block_post_account"
+     */
+    public function serviceGetBlockPostAccount()
+    {
+        if(!isLogged())
+            return '';
+
+        $iProfileId = $this->getProfileId();
+        $sType = BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS;
+		return $this->_getBlockPost($iProfileId, array(
+		    'type' => $sType,
+			'form_display' => $this->_oConfig->getPostFormDisplay($sType)
+		));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view get_block_view
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view', [...]); @endcode
+     * 
+     * Get Timeline View block for a separate page.
+     *
+     * @param $iProfileId (optional) profile ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockView
+     */
+    /** 
+     * @ref bx_timeline-get_block_view "get_block_view"
+     */
+    public function serviceGetBlockView($iProfileId = 0)
+    {
+    	return $this->_serviceGetBlockView($iProfileId, BX_TIMELINE_VIEW_TIMELINE);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_outline get_block_view_outline
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_outline', [...]); @endcode
+     * 
+     * Get Outline View block for a separate page.
+     * 
+     * @param $iProfileId (optional) profile ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewOutline
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_outline "get_block_view_outline"
+     */
+    public function serviceGetBlockViewOutline($iProfileId = 0)
+    {
+        return $this->_serviceGetBlockView($iProfileId, BX_TIMELINE_VIEW_OUTLINE);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_profile get_block_view_profile
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_profile', [...]); @endcode
+     * 
+     * Get Timeline View block for the Profile page.
+     * 
+     * @param $sProfileModule (optional) string value with profile based module name. Persons module is used by default.
+     * @param $iProfileContentId (optional) profile's content ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewProfile
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_profile "get_block_view_profile"
+     */
+    public function serviceGetBlockViewProfile($sProfileModule = 'bx_persons', $iProfileContentId = 0, $iStart = -1, $iPerPage = -1, $sFilter = '', $aModules = array(), $iTimeline = -1)
+    {
+        $sView = BX_TIMELINE_VIEW_TIMELINE;
+
+        return $this->_serviceGetBlockViewProfile($sProfileModule, $iProfileContentId, $sView, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_profile_outline get_block_view_profile_outline
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_profile_outline', [...]); @endcode
+     * 
+     * Get Outline View block for the Profile page.
+     * 
+     * @param $sProfileModule (optional) string value with profile based module name. Persons module is used by default.
+     * @param $iProfileContentId (optional) profile's content ID. If empty value is provided, an attempt to get it from GET/POST arrays will be performed.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewProfileOutline
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_profile_outline "get_block_view_profile_outline"
+     */
+	public function serviceGetBlockViewProfileOutline($sProfileModule = 'bx_persons', $iProfileContentId = 0, $iStart = -1, $iPerPage = -1, $sFilter = '', $aModules = array(), $iTimeline = -1)
+    {
+        $sView = BX_TIMELINE_VIEW_OUTLINE;
+
+        return $this->_serviceGetBlockViewProfile($sProfileModule, $iProfileContentId, $sView, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_home get_block_view_home
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_home', [...]); @endcode
+     * 
+     * Get Timeline View block for site's Home page.
+     * 
+     * @param $iProfileId (optional) profile ID. 0 should be used here.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewHome
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_home "get_block_view_home"
+     */
+    public function serviceGetBlockViewHome($iProfileId = 0, $iStart = -1, $iPerPage = -1, $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        return $this->_serviceGetBlockViewHome($iProfileId, BX_TIMELINE_VIEW_TIMELINE, $iStart, $iPerPage, $this->_oConfig->getPerPage('home'), $iTimeline, $sFilter, $aModules);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_home_outline get_block_view_home_outline
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_home_outline', [...]); @endcode
+     * 
+     * Get Outline View block for site's Home page.
+     * 
+     * @param $iProfileId (optional) profile ID. 0 should be used here.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewHomeOutline
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_home_outline "get_block_view_home_outline"
+     */
+	public function serviceGetBlockViewHomeOutline($iProfileId = 0, $iStart = -1, $iPerPage = -1, $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        return $this->_serviceGetBlockViewHome($iProfileId, BX_TIMELINE_VIEW_OUTLINE, $iStart, $iPerPage, $this->_oConfig->getPerPage('home'), $iTimeline, $sFilter, $aModules);
+    }
+
+	/**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_hot get_block_view_hot
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_hot', [...]); @endcode
+     * 
+     * Get Timeline View block with Hot public events.
+     * 
+     * @param $iProfileId (optional) profile ID. 0 should be used here.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewHot
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_hot "get_block_view_hot"
+     */
+    public function serviceGetBlockViewHot($iProfileId = 0, $iStart = -1, $iPerPage = -1, $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        return $this->_serviceGetBlockViewHot($iProfileId, BX_TIMELINE_VIEW_TIMELINE, $iStart, $iPerPage, $this->_oConfig->getPerPage('home'), $iTimeline, $sFilter, $aModules);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_hot_outline get_block_view_hot_outline
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_hot_outline', [...]); @endcode
+     * 
+     * Get Outline View block with Hot public events.
+     * 
+     * @param $iProfileId (optional) profile ID. 0 should be used here.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewHotOutline
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_hot_outline "get_block_view_hot_outline"
+     */
+	public function serviceGetBlockViewHotOutline($iProfileId = 0, $iStart = -1, $iPerPage = -1, $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        return $this->_serviceGetBlockViewHot($iProfileId, BX_TIMELINE_VIEW_OUTLINE, $iStart, $iPerPage, $this->_oConfig->getPerPage('home'), $iTimeline, $sFilter, $aModules);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_account get_block_view_account
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_account', [...]); @endcode
+     * 
+     * Get Timeline View block for the Dashboard page.
+     * 
+     * @param $iProfileId (optional) profile ID. 0 should be used here.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewAccount
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_account "get_block_view_account"
+     */
+    public function serviceGetBlockViewAccount($iProfileId = 0, $iStart = -1, $iPerPage = -1, $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        if(!isLogged())
+            return '';
+
+        return $this->_serviceGetBlockViewByType($iProfileId, BX_TIMELINE_VIEW_TIMELINE, BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS, $iStart, $iPerPage, $this->_oConfig->getPerPage('account'), $iTimeline, $sFilter, $aModules);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_view_account_outline get_block_view_account_outline
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_view_account_outline', [...]); @endcode
+     * 
+     * Get Outline View block for the Dashboard page.
+     * 
+     * @param $iProfileId (optional) profile ID. 0 should be used here.
+     * @param $iStart (optional) integer value with a page number. Is used in pagination.
+     * @param $iPerPage (optional) integer value with a number of items per page. Is used in pagination.
+     * @param $iTimeline (optional) integer value determining whether the timeline should be displayed or not. 
+     * @param $sFilter (optional) string value with filter name.
+     * @param $aModules (optional) an array of modules from which the events should be displayed. All available modules are used by default.
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockViewAccountOutline
+     */
+    /** 
+     * @ref bx_timeline-get_block_view_account_outline "get_block_view_account_outline"
+     */
+    public function serviceGetBlockViewAccountOutline($iProfileId = 0, $iStart = -1, $iPerPage = -1, $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        if(!isLogged())
+            return '';
+
+        return $this->_serviceGetBlockViewByType($iProfileId, BX_TIMELINE_VIEW_OUTLINE, BX_TIMELINE_TYPE_OWNER_AND_CONNECTIONS, $iStart, $iPerPage, $this->_oConfig->getPerPage('account'), $iTimeline, $sFilter, $aModules);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-page_blocks Page Blocks
+     * @subsubsection bx_timeline-get_block_item get_block_item
+     * 
+     * @code bx_srv('bx_timeline', 'get_block_item', [...]); @endcode
+     * 
+     * Get View Item block.
+     * 
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetBlockItem
+     */
+    /** 
+     * @ref bx_timeline-get_block_item "get_block_item"
+     */
+    public function serviceGetBlockItem()
+    {
+        $iItemId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(!$iItemId)
+            return array();
+
+        return $this->_oTemplate->getItemBlock($iItemId);
+    }
+
+    public function serviceGetBlockItemContent()
+    {
+        $iItemId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        $sMode = bx_process_input(bx_get('mode'));
+        if(!$iItemId || !$sMode)
+            return '';
+            
+        return $this->_oTemplate->getItemBlockContent($iItemId, $sMode);
+    }
+    
+    public function serviceGetBlockItemInfo()
+    {
+        $iItemId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(!$iItemId)
+            return '';
+
+        return $this->_oTemplate->getItemBlockInfo($iItemId);
+    }
+
+    public function serviceGetBlockItemComments()
+    {
+        $iItemId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if(!$iItemId)
+            return '';
+
+        return $this->_oTemplate->getItemBlockComments($iItemId);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-integration_notifications Integration with Notifications
+     * @subsubsection bx_timeline-get_notifications_data get_notifications_data
+     * 
+     * @code bx_srv('bx_timeline', 'get_notifications_data', [...]); @endcode
+     * 
+     * Data for Notifications module.
+     * 
+     * @return an array with special format.
+     * 
+     * @see BxTimelineModule::serviceGetNotificationsData
+     */
+    /** 
+     * @ref bx_timeline-get_notifications_data "get_notifications_data"
+     */
+    public function serviceGetNotificationsData()
+    {
+    	$sModule = $this->_aModule['name'];
+
+        return array(
+            'handlers' => array(
+                array('group' => $sModule . '_object', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'post_common', 'module_name' => $sModule, 'module_method' => 'get_notifications_post', 'module_class' => 'Module'),
+                array('group' => $sModule . '_object', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'delete'),
+
+                array('group' => $sModule . '_repost', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'repost', 'module_name' => $sModule, 'module_method' => 'get_notifications_repost', 'module_class' => 'Module'),
+                array('group' => $sModule . '_repost', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'delete_repost'),
+
+                array('group' => $sModule . '_comment', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'commentPost', 'module_name' => $sModule, 'module_method' => 'get_notifications_comment', 'module_class' => 'Module'),
+                array('group' => $sModule . '_comment', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'commentRemoved'),
+
+                array('group' => $sModule . '_vote', 'type' => 'insert', 'alert_unit' => $sModule, 'alert_action' => 'doVote', 'module_name' => $sModule, 'module_method' => 'get_notifications_vote', 'module_class' => 'Module'),
+                array('group' => $sModule . '_vote', 'type' => 'delete', 'alert_unit' => $sModule, 'alert_action' => 'undoVote'),
+            ),
+            'settings' => array(
+                array('group' => 'content', 'unit' => $sModule, 'action' => 'post_common', 'types' => array('personal', 'follow_member', 'follow_context')),
+                array('group' => 'content', 'unit' => $sModule, 'action' => 'repost', 'types' => array('follow_member', 'follow_context')),
+                array('group' => 'comment', 'unit' => $sModule, 'action' => 'commentPost', 'types' => array('personal', 'follow_member', 'follow_context')),
+                array('group' => 'vote', 'unit' => $sModule, 'action' => 'doVote', 'types' => array('personal', 'follow_member', 'follow_context'))
+            ),
+            'alerts' => array(
+                array('unit' => $sModule, 'action' => 'post_common'),
+                array('unit' => $sModule, 'action' => 'delete'),
+                
+                array('unit' => $sModule, 'action' => 'repost'),
+                array('unit' => $sModule, 'action' => 'delete_repost'),
+                
+                array('unit' => $sModule, 'action' => 'commentPost'),
+                array('unit' => $sModule, 'action' => 'commentRemoved'),
+                
+                array('unit' => $sModule, 'action' => 'doVote'),
+                array('unit' => $sModule, 'action' => 'undoVote'),
+            )
+        );
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-integration_notifications Integration with Notifications
+     * @subsubsection bx_timeline-get_notifications_repost get_notifications_repost
+     * 
+     * @code bx_srv('bx_timeline', 'get_notifications_repost', [...]); @endcode
+     * 
+     * Get data for Repost event to display in Notifications module.
+     * 
+     * @param $aEvent an array with event description.
+     * @return an array with special format.
+     * 
+     * @see BxTimelineModule::serviceGetNotificationsRepost
+     */
+    /** 
+     * @ref bx_timeline-get_notifications_repost "get_notifications_repost"
+     */
+    public function serviceGetNotificationsRepost($aEvent)
+    {
+        $aResult = $this->serviceGetNotificationsPost($aEvent);
+        $aResult['lang_key'] = '_bx_timeline_txt_object_reposted';
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-integration_notifications Integration with Notifications
+     * @subsubsection bx_timeline-get_notifications_post get_notifications_post
+     * 
+     * @code bx_srv('bx_timeline', 'get_notifications_post', [...]); @endcode
+     * 
+     * Get data for Post event to display in Notifications module.
+     * 
+     * @param $aEvent an array with event description.
+     * @return an array with special format.
+     * 
+     * @see BxTimelineModule::serviceGetNotificationsPost
+     */
+    /** 
+     * @ref bx_timeline-get_notifications_post "get_notifications_post"
+     */
+    public function serviceGetNotificationsPost($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iContent = (int)$aEvent['object_id'];
+		$aContent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContent));
+        if(empty($aContent) || !is_array($aContent))
+            return array();
+
+        $sEntryCaption = !empty($aContent['title']) ? $aContent['title'] : $this->_oConfig->getTitle($aContent['description']);
+
+		return array(
+			'entry_sample' => $CNF['T']['txt_sample_single_ext'],
+			'entry_url' => $this->_oConfig->getItemViewUrl($aContent),
+			'entry_caption' => $sEntryCaption,
+			'entry_author' => $aContent['owner_id'],
+			'lang_key' => '_bx_timeline_ntfs_txt_object_added', //may be empty or not specified. In this case the default one from Notification module will be used.
+		);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-integration_notifications Integration with Notifications
+     * @subsubsection bx_timeline-get_notifications_comment get_notifications_comment
+     * 
+     * @code bx_srv('bx_timeline', 'get_notifications_comment', [...]); @endcode
+     * 
+     * Get data for Post Comment event to display in Notifications module.
+     * 
+     * @param $aEvent an array with event description.
+     * @return an array with special format.
+     * 
+     * @see BxTimelineModule::serviceGetNotificationsComment
+     */
+    /** 
+     * @ref bx_timeline-get_notifications_comment "get_notifications_comment"
+     */
+    public function serviceGetNotificationsComment($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iContent = (int)$aEvent['object_id'];
+    	$aContent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContent));
+        if(empty($aContent) || !is_array($aContent))
+            return array();
+
+		$oComment = BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $iContent);
+        if(!$oComment || !$oComment->isEnabled())
+            return array();
+
+        $sEntryCaption = !empty($aContent['title']) ? $aContent['title'] : $this->_oConfig->getTitle($aContent['description']);
+
+		return array(
+			'entry_sample' => $CNF['T']['txt_sample_single'],
+			'entry_url' => $this->_oConfig->getItemViewUrl($aContent),
+			'entry_caption' => $sEntryCaption,
+			'entry_author' => $aContent['owner_id'],
+			'subentry_sample' => $CNF['T']['txt_sample_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.
+		);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-integration_notifications Integration with Notifications
+     * @subsubsection bx_timeline-get_notifications_vote get_notifications_vote
+     * 
+     * @code bx_srv('bx_timeline', 'get_notifications_vote', [...]); @endcode
+     * 
+     * Get data for Vote event to display in Notifications module.
+     * 
+     * @param $aEvent an array with event description.
+     * @return an array with special format.
+     * 
+     * @see BxTimelineModule::serviceGetNotificationsVote
+     */
+    /** 
+     * @ref bx_timeline-get_notifications_vote "get_notifications_vote"
+     */
+    public function serviceGetNotificationsVote($aEvent)
+    {
+    	$CNF = &$this->_oConfig->CNF;
+
+    	$iContent = (int)$aEvent['object_id'];
+    	$aContent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContent));
+        if(empty($aContent) || !is_array($aContent))
+            return array();
+
+		$oVote = BxDolVote::getObjectInstance($CNF['OBJECT_VOTES'], $iContent);
+        if(!$oVote || !$oVote->isEnabled())
+            return array();
+
+        $sEntryCaption = !empty($aContent['title']) ? $aContent['title'] : $this->_oConfig->getTitle($aContent['description']);
+
+		return array(
+			'entry_sample' => $CNF['T']['txt_sample_single'],
+			'entry_url' => $this->_oConfig->getItemViewUrl($aContent),
+			'entry_caption' => $sEntryCaption,
+			'entry_author' => $aContent['owner_id'],
+			'subentry_sample' => $CNF['T']['txt_sample_vote_single'],
+			'lang_key' => '', //may be empty or not specified. In this case the default one from Notification module will be used.
+		);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-repost Repost
+     * @subsubsection bx_timeline-get_repost_element_block get_repost_element_block
+     * 
+     * @code bx_srv('bx_timeline', 'get_repost_element_block', [...]); @endcode
+     * 
+     * Get repost element for content based modules.
+     * 
+     * @param $iOwnerId integer value with owner profile ID.
+     * @param $sType string value with type (module name). 
+     * @param $sAction string value with action (module action). 
+     * @param $iObjectId integer value with object ID to be reposted. 
+     * @param $aParams (optional) an array with additional params.
+     * @return HTML string with repost element to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetRepostElementBlock
+     */
+    /** 
+     * @ref bx_timeline-get_repost_element_block "get_repost_element_block"
+     */
+    public function serviceGetRepostElementBlock($iOwnerId, $sType, $sAction, $iObjectId, $aParams = array())
+    {
+    	if(!$this->isEnabled())
+    		return '';
+
+        $aParams = array_merge($this->_oConfig->getRepostDefaults(), $aParams);
+        return $this->_oTemplate->getRepostElement($iOwnerId, $sType, $sAction, $iObjectId, $aParams);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-repost Repost
+     * @subsubsection bx_timeline-get_repost_counter get_repost_counter
+     * 
+     * @code bx_srv('bx_timeline', 'get_repost_counter', [...]); @endcode
+     * 
+     * Get repost counter.
+     * 
+     * @param $sType string value with type (module name). 
+     * @param $sAction string value with action (module action). 
+     * @param $iObjectId integer value with object ID to be reposted. 
+     * @return HTML string with repost counter to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetRepostCounter
+     */
+    /** 
+     * @ref bx_timeline-get_repost_counter "get_repost_counter"
+     */
+    public function serviceGetRepostCounter($sType, $sAction, $iObjectId)
+    {
+    	if(!$this->isEnabled())
+    		return '';
+
+		$aReposted = $this->_oDb->getReposted($sType, $sAction, $iObjectId);
+
+        return $this->_oTemplate->getRepostCounter($aReposted);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-repost Repost
+     * @subsubsection bx_timeline-get_repost_js_script get_repost_js_script
+     * 
+     * @code bx_srv('bx_timeline', 'get_repost_js_script', [...]); @endcode
+     * 
+     * Get repost JavaScript code.
+     * 
+     * @return HTML string with JavaScript code to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxTimelineModule::serviceGetRepostJsScript
+     */
+    /** 
+     * @ref bx_timeline-get_repost_js_script "get_repost_js_script"
+     */
+    public function serviceGetRepostJsScript()
+    {
+    	if(!$this->isEnabled())
+    		return '';
+
+        return $this->_oTemplate->getRepostJsScript();
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-repost Repost
+     * @subsubsection bx_timeline-get_repost_js_click get_repost_js_click
+     * 
+     * @code bx_srv('bx_timeline', 'get_repost_js_click', [...]); @endcode
+     * 
+     * Get repost JavaScript code for OnClick event.
+     * 
+     * @param $iOwnerId integer value with owner profile ID.
+     * @param $sType string value with type (module name). 
+     * @param $sAction string value with action (module action). 
+     * @param $iObjectId integer value with object ID to be reposted. 
+     * @return HTML string with JavaScript code to display in OnClick events of HTML elements.
+     * 
+     * @see BxTimelineModule::serviceGetRepostJsClick
+     */
+    /** 
+     * @ref bx_timeline-get_repost_js_click "get_repost_js_click"
+     */
+    public function serviceGetRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId)
+    {
+    	if(!$this->isEnabled())
+    		return '';
+
+        return $this->_oTemplate->getRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-repost Repost
+     * @subsubsection bx_timeline-repost repost
+     * 
+     * @code bx_srv('bx_timeline', 'repost', [...]); @endcode
+     * 
+     * Perform repost action.
+     * 
+     * @param $iAuthorId integer value with performer profile ID.
+     * @param $iOwnerId integer value with repost event owner profile ID.
+     * @param $sType string value with type (module name). 
+     * @param $sAction string value with action (module action). 
+     * @param $iObjectId integer value with object ID to be reposted. 
+     * @parem $bForce boolean value force reposting without ACL check.
+     * @return an array with error (code and message) or integer with newly created repost event ID.
+     * 
+     * @see BxTimelineModule::serviceRepost
+     */
+    /** 
+     * @ref bx_timeline-repost "repost"
+     */
+    public function serviceRepost($iAuthorId, $iOwnerId, $sType, $sAction, $iObjectId, $bForce = false)
+    {
+        $aReposted = $this->_oDb->getReposted($sType, $sAction, $iObjectId);
+        if(empty($aReposted) || !is_array($aReposted))
+            return array('code' => 1, 'message' => _t('_bx_timeline_txt_err_cannot_repost'));
+
+        $mixedAllowed = $this->isAllowedRepost($aReposted, true);
+        if(!$bForce && $mixedAllowed !== true)
+            return array('code' => 2, 'message' => strip_tags($mixedAllowed));
+
+        $bReposted = $this->_oDb->isReposted($aReposted['id'], $iOwnerId, $iAuthorId);
+        if($bReposted)
+            return array('code' => 3, 'message' => _t('_bx_timeline_txt_err_already_reposted'));
+
+        $iId = $this->_oDb->insertEvent(array(
+            'owner_id' => $iOwnerId,
+            'type' => $this->_oConfig->getPrefix('common_post') . 'repost',
+            'action' => '',
+            'object_id' => $iAuthorId,
+            'object_privacy_view' => $this->_oConfig->getPrivacyViewDefault('object'),
+            'content' => serialize(array(
+                'type' => $sType,
+                'action' => $sAction,
+                'object_id' => $iObjectId,
+            )),
+            'title' => '',
+            'description' => ''
+        ));
+
+        if(empty($iId))
+            return array('code' => 4, 'message' => _t('_bx_timeline_txt_err_cannot_repost'));
+
+        $this->onRepost($iId, $aReposted);
+
+        return $iId;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-repost Repost
+     * @subsubsection bx_timeline-repost_by_id repost_by_id
+     * 
+     * @code bx_srv('bx_timeline', 'repost_by_id', [...]); @endcode
+     * 
+     * Perform repost action by Timeline event ID.
+     * 
+     * @param $iAuthorId integer value with performer profile ID.
+     * @param $iOwnerId integer value with repost event owner profile ID.
+     * @param $iEventId integer value with event ID which will be reposted.
+     * @parem $bForce boolean value force reposting without ACL check.
+     * @return an array with error (code and message) or integer with newly created repost event ID.
+     * 
+     * @see BxTimelineModule::serviceRepostById
+     */
+    /** 
+     * @ref bx_timeline-repost_by_id "repost_by_id"
+     */
+    public function serviceRepostById($iAuthorId, $iOwnerId, $iEventId, $bForce = false)
+    {
+        $aEvent = $this->_oDb->getEntriesBy(array('type' => 'id', 'id' => $iEventId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return array('code' => 1, 'message' => _t('_bx_timeline_txt_err_cannot_repost'));
+
+        $sType = $aEvent['type'];
+        $sAction = $aEvent['action'];
+        $iObjectId = $this->_oConfig->isSystem($sType, $sAction) ? $aEvent['object_id'] : $aEvent['id'];
+
+        $sCommonPrefix = $this->_oConfig->getPrefix('common_post');
+        if(str_replace($sCommonPrefix, '', $sType) == BX_TIMELINE_PARSE_TYPE_REPOST) {
+            $aReposted = $this->_oDb->getReposted($sType, $sAction, $iObjectId);
+            if(empty($aReposted) || !is_array($aReposted))
+                return array('code' => 1, 'message' => _t('_bx_timeline_txt_err_cannot_repost'));
+
+            $aRepostedData = unserialize($aEvent['content']);
+
+            $sType = $aRepostedData['type'];
+            $sAction = $aRepostedData['action'];
+            $iObjectId = $aRepostedData['object_id'];
+        }
+
+        return $this->serviceRepost($iAuthorId, $iOwnerId, $sType, $sAction, $iObjectId, $bForce);
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-update update
+     * 
+     * @code bx_srv('bx_timeline', 'update', [...]); @endcode
+     * 
+     * Update timeline event by ID.
+     * 
+     * @param $iEventId integer value with event ID.
+     * @param $aSet an array with key=>value pairs for fields which should be updated. 
+     * @return boolean value with the result of operation.
+     * 
+     * @see BxTimelineModule::serviceUpdate
+     */
+    /** 
+     * @ref bx_timeline-update "update"
+     */
+    public function serviceUpdate($iEventId, $aSet)
+    {
+        if(empty($iEventId))
+            return false;
+
+        return (int)$this->_oDb->updateEvent($aSet, array('id' => $iEventId)) > 0;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_menu_item_addon_comment get_menu_item_addon_comment
+     * 
+     * @code bx_srv('bx_timeline', 'get_menu_item_addon_comment', [...]); @endcode
+     * 
+     * Get addon for Comment menu item.
+     * 
+     * @param $sSystem string value with comments engine system.
+     * @param $iObjectId integer value with object ID. 
+     * @return HTML string to display in menu item.
+     * 
+     * @see BxTimelineModule::serviceGetMenuItemAddonComment
+     */
+    /** 
+     * @ref bx_timeline-get_menu_item_addon_comment "get_menu_item_addon_comment"
+     */
+    public function serviceGetMenuItemAddonComment($sSystem, $iObjectId)
+    {
+        if(empty($sSystem) || empty($iObjectId))
+            return '';
+
+        $oCmts = $this->getCmtsObject($sSystem, $iObjectId);
+        if($oCmts === false)
+            return '';
+
+        $iCounter = (int)$oCmts->getCommentsCount();
+        return  $this->_oTemplate->parseLink('javascript:void(0)', $iCounter > 0 ? $iCounter : '', array(
+            'title' => _t('_bx_timeline_menu_item_title_item_comment'),
+        	'onclick' => "javascript:" . $this->_oConfig->getJsObject('view') . ".commentItem(this, '" . $sSystem . "', " . $iObjectId . ")" 
+        ));
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_settings_checker_helper get_settings_checker_helper
+     * 
+     * @code bx_srv('bx_timeline', 'get_settings_checker_helper', [...]); @endcode
+     * 
+     * Get Checker Helper class name for Forms engine.
+     * 
+     * @return string with Checker Helper class name.
+     * 
+     * @see BxTimelineModule::serviceGetSettingsCheckerHelper
+     */
+    /** 
+     * @ref bx_timeline-get_settings_checker_helper "get_settings_checker_helper"
+     */
+    public function serviceGetSettingsCheckerHelper()
+    {
+        bx_import('FormCheckerHelper', $this->_aModule);
+        return 'BxTimelineFormCheckerHelper';
+    }
+
+	/**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_options_videos_autoplay get_options_videos_autoplay
+     * 
+     * @code bx_srv('bx_timeline', 'get_options_videos_autoplay', [...]); @endcode
+     * 
+     * Get an array with available options for 'Videos autoplay in Timeline' setting.
+     *
+     * @return an array with available options represented as key => value pairs.
+     * 
+     * @see BxTimelineModule::serviceGetOptionsVideosAutoplay
+     */
+    /** 
+     * @ref bx_timeline-get_options_videos_autoplay "get_options_videos_autoplay"
+     */
+    public function serviceGetOptionsVideosAutoplay()
+    {
+        $aOptions = array(BX_TIMELINE_VAP_OFF, BX_TIMELINE_VAP_ON_MUTE, BX_TIMELINE_VAP_ON);
+
+        $aResult = array();
+        foreach($aOptions as $sOption)
+            $aResult[] = array(
+                'key' => $sOption,
+                'value' => _t('_bx_timeline_option_videos_autoplay_' . $sOption)
+            );
+
+        return $aResult;
+    }
+
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Timeline
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_live_updates get_live_updates
+     * 
+     * @code bx_srv('bx_timeline', 'get_live_updates', [...]); @endcode
+     * 
+     * Get an array with actual Live Update info.
+     *
+     * @return an array with Live Update info.
+     * 
+     * @see BxTimelineModule::serviceGetLiveUpdates
+     */
+    /** 
+     * @ref bx_timeline-get_live_updates "get_live_updates"
+     */
+    public function serviceGetLiveUpdates($sType, $iOwnerId, $iProfileId, $iCount = 0, $iInit = 0)
+    {
+		$sKey = $this->_oConfig->getLiveUpdateKey($sType, $iOwnerId);
+
+		bx_import('BxDolSession');
+    	if((int)BxDolSession::getInstance()->getValue($sKey) == 1)
+    		return false;
+
+        $aParams = $this->_prepareParams(BX_TIMELINE_VIEW_DEFAULT, $sType, $iOwnerId, false, false, BX_TIMELINE_FILTER_OTHER_VIEWER);
+        $aParams['count'] = true;
+
+		$iCountNew = $this->_oDb->getEvents($aParams);
+		if($iCountNew == $iCount)
+			return false;
+
+		if((int)$iInit != 0)
+			return array('count' => $iCountNew);
+
+    	return array(
+			'count' => $iCountNew, // required (for initialization and visualization)
+			'method' => $this->_oConfig->getJsObject('view') . '.showLiveUpdate(oData)', // required (for visualization)
+			'data' => array(
+				'code' => $this->_oTemplate->getLiveUpdateNotification($sType, $iOwnerId, $iProfileId, $iCount, $iCountNew)
+			),  // optional, may have some additional data to be passed in JS method provided using 'method' param above.
+		);
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_timeline Accounts
+     * @subsection bx_timeline-other Other
+     * @subsubsection bx_timeline-get_menu_addon_manage_tools get_menu_addon_manage_tools
+     * 
+     * @code bx_srv('bx_timeline', 'get_menu_addon_manage_tools', [...]); @endcode
+     * 
+     * Get number of 'hidden' events for User End -> Dasboard page -> Manage block.
+     *
+     * @return integer number of 'hidden' events
+     * 
+     * @see BxTimelineModule::serviceGetMenuAddonManageTools
+     */
+    /** 
+     * @ref bx_timeline-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->fillFilters(array(
+			'active' => 0
+        ));
+        $o->unsetPaginate();
+
+        return $o->getNum();
+	}
+
+    /*
+     * COMMON METHODS
+     */
+    public function deleteEvent($aEvent)
+    {
+    	if(empty($aEvent) || !is_array($aEvent) || !$this->_oDb->deleteEvent(array('id' => (int)$aEvent['id'])))
+            return false;
+
+        $this->onDelete($aEvent);
+        return true;
+    }
+    
+
+    public function addAttachLink($aValues, $sDisplay = false)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!$sDisplay)
+            $sDisplay = $this->_oConfig->getObject('form_display_attach_link_add');
+
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_attach_link'), $sDisplay, $this->_oTemplate);
+        if(!$oForm)
+            return array('message' => '_sys_txt_error_occured');
+
+        $oForm->aFormAttrs['method'] = BX_DOL_FORM_METHOD_SPECIFIC;
+        $oForm->aParams['csrf']['disable'] = true;
+        if(!empty($oForm->aParams['db']['submit_name'])) {
+            $sSubmitName = $oForm->aParams['db']['submit_name'];
+            if(!isset($oForm->aInputs[$sSubmitName])) {
+                if(isset($oForm->aInputs[$CNF['FIELD_CONTROLS']]))
+                    foreach($oForm->aInputs[$CNF['FIELD_CONTROLS']] as $mixedIndex => $aInput) {
+                        if(!is_numeric($mixedIndex) || empty($aInput['name']) || $aInput['name'] != $sSubmitName)
+                            continue;
+    
+                        $aValues[$sSubmitName] = $aInput['value'];
+                    }
+            }
+            else            
+                $aValues[$sSubmitName] = $oForm->aInputs[$sSubmitName]['value'];
+        }
+
+        $oForm->aInputs['url']['checker']['params']['preg'] = $this->_oConfig->getPregPattern('url');
+
+        $oForm->initChecker(array(), $aValues);
+        if(!$oForm->isSubmittedAndValid())
+            return array('message' => '_sys_txt_error_occured');
+
+        return $this->_addLink($oForm);
+    }
+
+    public function getFormAttachLink()
+    {
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject('form_attach_link'), $this->_oConfig->getObject('form_display_attach_link_add'), $this->_oTemplate);
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'submit_attach_link_form/';
+        $oForm->aInputs['url']['checker']['params']['preg'] = $this->_oConfig->getPregPattern('url');
+
+        $oForm->initChecker();
+        if($oForm->isSubmittedAndValid())
+            return $this->_addLink($oForm);
+
+        return array('form' => $oForm->getCode(), 'form_id' => $oForm->id);
+    }
+
+    public function getFormPost($aParams = array())
+    {
+        $iUserId = $this->getUserId();
+
+        $oForm = $this->getFormPostObject($aParams);
+        $oForm->initChecker();
+
+        $bAjaxMode = $oForm->isAjaxMode();
+        $bDynamicMode = $bAjaxMode;
+
+        if($oForm->isSubmittedAndValid()) {
+            list($sUserName) = $this->getUserInfo($iUserId);
+
+            $sType = $oForm->getCleanValue('type');
+            $sType = $this->_oConfig->getPrefix('common_post') . $sType;
+            BxDolForm::setSubmittedValue('type', $sType, $oForm->aFormAttrs['method']);
+
+            $aContent = array();
+
+            //--- Process Text ---//
+            $sText = $oForm->getCleanValue('text');
+            $sText = $this->_prepareTextForSave($sText);
+            $bText = !empty($sText);
+
+            if($bText)
+            	$aContent['text'] = $sText;
+
+            //--- Process Context and Privacy ---//
+            $iOwnerId = (int)$oForm->getCleanValue('owner_id');
+            $iObjectPrivacyView = (int)$oForm->getCleanValue('object_privacy_view');
+            $iObjectPrivacyViewDefault = $this->_oConfig->getPrivacyViewDefault('object');
+            if(empty($iObjectPrivacyView))
+                $iObjectPrivacyView = $iObjectPrivacyViewDefault;
+            else if($iObjectPrivacyView < 0)
+                $iOwnerId = abs($iObjectPrivacyView);
+
+            //--- Process Link ---//
+            $aLinkIds = $oForm->getCleanValue('link');
+            $bLinkIds = !empty($aLinkIds) && is_array($aLinkIds);
+
+            //--- Process Media ---//
+            $aPhotoIds = $oForm->getCleanValue(BX_TIMELINE_MEDIA_PHOTO);
+            $bPhotoIds = !empty($aPhotoIds) && is_array($aPhotoIds);
+
+            $aVideoIds = $oForm->getCleanValue(BX_TIMELINE_MEDIA_VIDEO);
+            $bVideoIds = !empty($aVideoIds) && is_array($aVideoIds);
+
+            if(!$bText && !$bLinkIds && !$bPhotoIds && !$bVideoIds) {
+                $oForm->aInputs['text']['error'] =  _t('_bx_timeline_txt_err_empty_post');
+                $oForm->setValid(false);
+
+            	return $this->_prepareResponse(array('form' => $oForm->getCode($bDynamicMode), 'form_id' => $oForm->id), $bAjaxMode);
+            }
+
+            $sTitle = $bText ? $this->_oConfig->getTitle($sText) : $this->_oConfig->getTitleDefault($bLinkIds, $bPhotoIds, $bVideoIds);
+            $sDescription = _t('_bx_timeline_txt_user_added_sample', '{profile_name}', _t('_bx_timeline_txt_sample_with_article'));
+
+            //--- Process Date ---//
+            $iDate = 0;
+            if(isset($oForm->aInputs['date']))
+                $iDate = $oForm->getCleanValue('date');
+            if(empty($iDate))
+                $iDate = time();
+
+            /**
+             * Unset 'text' input because its data was already processed 
+             * and will be saved via additional values which were passed 
+             * to BxDolForm::insert method.
+             */
+            unset($oForm->aInputs['text']);
+
+            $iId = $oForm->insert(array(
+                'owner_id' => $iOwnerId,
+                'object_id' => $iUserId,
+                'object_privacy_view' => $iObjectPrivacyView,
+                'content' => serialize($aContent),
+                'title' => $sTitle,
+                'description' => $sDescription,
+                'date' => $iDate
+            ));
+
+            if(!empty($iId)) {
+            	$oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
+            	if($bText)
+                    $oMetatags->metaAdd($iId, $sText);
+                $oMetatags->locationsAddFromForm($iId, $this->_oConfig->CNF['FIELD_LOCATION_PREFIX']);
+
+                //--- Process Link ---//
+                if($bLinkIds)
+                    foreach($aLinkIds as $iLinkId)
+                        $this->_oDb->saveLink($iId, $iLinkId);
+
+				//--- Process Media ---//
+				if($bPhotoIds) 
+					$this->_saveMedia(BX_TIMELINE_MEDIA_PHOTO, $iId, $aPhotoIds);
+
+				if($bVideoIds)
+					$this->_saveMedia(BX_TIMELINE_MEDIA_VIDEO, $iId, $aVideoIds);
+
+                $this->onPost($iId);
+
+                return $this->_prepareResponse(array('id' => $iId), $bAjaxMode, array(
+                	'redirect' => $this->_oConfig->getItemViewUrl(array('id' => $iId))
+                ));
+            }
+
+            return $this->_prepareResponse(array('message' => _t('_bx_timeline_txt_err_cannot_perform_action')), $bAjaxMode);
+        }
+
+        return $this->_prepareResponse(array('form' => $oForm->getCode($bDynamicMode), 'form_id' => $oForm->id), $bAjaxMode && $oForm->isSubmitted());
+    }
+
+    public function getFormEdit($iId, $aParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent) || !is_array($aEvent))
+            return array();
+
+        $aContent = unserialize($aEvent['content']);
+        if(is_array($aContent) && !empty($aContent['text']))
+            $aEvent['text'] = $aContent['text'];
+
+		$bDynamicMode = isset($aParams['dynamic_mode']) ? (bool)$aParams['dynamic_mode'] : false;
+        $sFormObject = !empty($aParams['form_object']) ? $aParams['form_object'] : 'form_post';
+        $sFormDisplay = !empty($aParams['form_display']) ? $aParams['form_display'] : 'form_display_post_edit';
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject($sFormObject), $this->_oConfig->getObject($sFormDisplay), $this->_oTemplate);
+        $oForm->setId($this->_oConfig->getHtmlIds('view', 'edit_form') . $iId);
+
+        $oForm->aFormAttrs['action'] = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'edit/' . $iId ;
+        foreach($oForm->aInputs[$CNF['FIELD_CONTROLS']] as $mixedIndex => $aInput) {
+            if(!is_numeric($mixedIndex))
+                continue;
+
+            $oForm->aInputs[$CNF['FIELD_CONTROLS']][$mixedIndex]['attrs'] = bx_replace_markers($aInput['attrs'], array(
+                'js_object_view' => $this->_oConfig->getJsObject('view'),
+            	'content_id' => $iId
+            ));
+        }
+
+        $oForm->initChecker($aEvent);
+        if($oForm->isSubmittedAndValid()) {
+            $aContent = array();
+
+            //--- Process Text ---//
+            $sText = $oForm->getCleanValue('text');
+            $sText = $this->_prepareTextForSave($sText);
+            $bText = !empty($sText);
+            unset($oForm->aInputs['text']);
+
+            if($bText)
+            	$aContent['text'] = $sText;
+
+            $aValsToAdd = array(
+            	'content' => serialize($aContent)
+            );
+
+            //--- Process Privacy ---//
+            $iObjectPrivacyView = (int)$oForm->getCleanValue('object_privacy_view');
+            $iObjectPrivacyViewDefault = $this->_oConfig->getPrivacyViewDefault('object');
+            if(empty($iObjectPrivacyView))
+                $aValsToAdd = array_merge($aValsToAdd, array(
+                    'object_privacy_view' => $iObjectPrivacyViewDefault
+                ));
+            else if($iObjectPrivacyView < 0) 
+                $aValsToAdd = array_merge($aValsToAdd, array(
+                    'owner_id' => abs($iObjectPrivacyView),
+                    'object_privacy_view' => $iObjectPrivacyViewDefault
+                ));
+
+            //--- Process Date ---//
+            if(isset($oForm->aInputs['date'])) {
+                $iDate = $oForm->getCleanValue('date');
+                if(empty($iDate))
+                    $iDate = time();
+
+                $aValsToAdd['date'] = $iDate;
+            }
+
+            if(!$oForm->update($iId, $aValsToAdd))
+                return array('message' => _t('_bx_timeline_txt_err_cannot_perform_action'));
+
+            $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
+        	if($bText)
+				$oMetatags->metaAdd($iId, $sText);
+			$oMetatags->locationsAddFromForm($iId, $this->_oConfig->CNF['FIELD_LOCATION_PREFIX']);
+
+            return array(
+                'id' => $iId,
+            	'eval' => $this->_oConfig->getJsObject('view') . '.onEditPostSubmit(oData)'
+            );
+        }
+
+        return array(
+            'id' => $iId, 
+        	'form' => $oForm->getCode($bDynamicMode), 
+        	'form_id' => $oForm->id,
+        	'eval' => $this->_oConfig->getJsObject('view') . '.onEditPost(oData)'
+        );
+    }
+
+    public function getFormPostObject($aParams)
+    {
+    	$sFormObject = !empty($aParams['form_object']) ? $aParams['form_object'] : 'form_post';
+        $sFormDisplay = !empty($aParams['form_display']) ? $aParams['form_display'] : 'form_display_post_add';
+
+        $oForm = BxDolForm::getObjectInstance($this->_oConfig->getObject($sFormObject), $this->_oConfig->getObject($sFormDisplay), $this->_oTemplate);        
+
+        $sParamsKey = 'ajax_mode';
+        if(isset($aParams[$sParamsKey]) && is_bool($aParams[$sParamsKey]))
+            $oForm->setAjaxMode((bool)$aParams[$sParamsKey]);
+
+        $sParamsKey = 'visibility_autoselect';
+        if(isset($aParams[$sParamsKey]) && is_bool($aParams[$sParamsKey]))
+            $oForm->setVisibilityAutoselect((bool)$aParams[$sParamsKey]);
+
+        $oForm->init();
+        return $oForm;
+    }
+
+    public function getCmtsObject($sSystem, $iId)
+    {
+        if(empty($sSystem) || (int)$iId == 0)
+            return false;
+
+        $oCmts = BxDolCmts::getObjectInstance($sSystem, $iId, true, $this->_oTemplate);
+        if(!$oCmts || !$oCmts->isEnabled())
+            return false;
+
+        return $oCmts;
+    }
+
+    public function getViewObject($sSystem, $iId)
+    {
+        if(empty($sSystem) || (int)$iId == 0)
+            return false;
+
+        $oView = BxDolView::getObjectInstance($sSystem, $iId, true, $this->_oTemplate);
+        if(!$oView || !$oView->isEnabled())
+            return false;
+
+        return $oView;
+    }
+
+    public function getVoteObject($sSystem, $iId)
+    {
+        if(empty($sSystem) || (int)$iId == 0)
+            return false;
+
+        $oVote = BxDolVote::getObjectInstance($sSystem, $iId, true, $this->_oTemplate);
+        if(!$oVote || !$oVote->isEnabled())
+            return false;
+
+        return $oVote;
+    }
+
+    public function getScoreObject($sSystem, $iId)
+    {
+        if(empty($sSystem) || (int)$iId == 0)
+            return false;
+
+        $oScore = BxDolScore::getObjectInstance($sSystem, $iId, true, $this->_oTemplate);
+        if(!$oScore || !$oScore->isEnabled())
+            return false;
+
+        return $oScore;
+    }
+
+	public function getReportObject($sSystem, $iId)
+    {
+        if(empty($sSystem) || (int)$iId == 0)
+            return false;
+
+        $oReport = BxDolReport::getObjectInstance($sSystem, $iId, true, $this->_oTemplate);
+        if(!$oReport || !$oReport->isEnabled())
+            return false;
+
+        return $oReport;
+    }
+
+    public function getAttachmentsMenuObject()
+    {
+        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_post_attachments'), $this->_oTemplate);
+        $oMenu->addMarkers(array(
+            'js_object' => $this->_oConfig->getJsObject('post'),
+        ));
+
+        return $oMenu;
+    }
+
+    public function getManageMenuObject()
+    {
+        return BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_manage'), $this->_oTemplate);
+    }
+
+    //--- Check permissions methods ---//
+    public function isModerator()
+    {
+        $sModule = $this->getName();
+        $iUserId = (int)$this->getUserId();
+
+        $aCheckResult = checkActionModule($iUserId, 'edit', $sModule);
+        if($aCheckResult[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
+            return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'delete', $sModule);
+        if($aCheckResult[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
+            return true;
+
+        return false;
+    }
+
+    public function isAllowedPost($bPerform = false)
+    {
+        if(isAdmin())
+            return true;
+
+        $iUserId = $this->getUserId();
+        $aCheckResult = checkActionModule($iUserId, 'post', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($this->_iOwnerId);
+        if($oProfileOwner !== false) {
+            if($oProfileOwner->checkAllowedPostInProfile() !== CHECK_ACTION_RESULT_ALLOWED)
+                return _t('_sys_txt_access_denied');
+
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_post', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+        }
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function isAllowedView($aEvent, $bPerform = false)
+    {
+        $CNF = $this->_oConfig->CNF;
+
+        $mixedResult = BxDolProfile::getInstance($aEvent[$CNF['FIELD_OWNER_ID']])->checkAllowedProfileView();
+        if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
+            return false;
+
+		return true;
+    }
+
+    public function isAllowedEdit($aEvent, $bPerform = false)
+    {
+        if(!isLogged())
+            return false;
+            
+        //--- System posts and Reposts cannot be edited at all.
+        if(!$this->_oConfig->isCommon($aEvent['type'], $aEvent['action']) || $aEvent['type'] == $this->_oConfig->getPrefix('common_post') . 'repost')
+            return false;
+
+        if(isAdmin())
+            return true;
+
+        $iUserId = (int)$this->getUserId();
+        $iOwnerId = (int)$aEvent['owner_id'];
+        $iObjectId = abs((int)$aEvent['object_id']);
+        if($iObjectId == $iUserId && $this->_oConfig->isAllowEdit())
+           return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'edit', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($iOwnerId);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_edit', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function isAllowedDelete($aEvent, $bPerform = false)
+    {
+        if(!isLogged())
+            return false;
+
+        if(isAdmin())
+            return true;
+
+        $iUserId = (int)$this->getUserId();
+        $iOwnerId = (int)$aEvent['owner_id'];
+        $iObjectId = abs((int)$aEvent['object_id']);
+        if((($iOwnerId == $iUserId && $this->_oConfig->isAllowDelete()) || ($this->_oConfig->isCommon($aEvent['type'], $aEvent['action']) && $iObjectId == $iUserId)))
+           return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'delete', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($iOwnerId);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_delete', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function isAllowedComment($aEvent, $bPerform = false)
+    {
+        $mixedComments = $this->getCommentsData($aEvent['comments']);
+        if($mixedComments === false)
+            return false;
+
+        list($sSystem, $iObjectId) = $mixedComments;
+        $oCmts = $this->getCmtsObject($sSystem, $iObjectId);
+        $oCmts->addCssJs();
+
+        $bResult = true;
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false) {
+            if($oProfileOwner->checkAllowedPostInProfile() !== CHECK_ACTION_RESULT_ALLOWED)
+                return false;
+
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_comment', $oProfileOwner->id(), (int)$this->getUserId(), array('result' => &$bResult));
+        }
+
+        return $bResult;
+    }
+
+    public function isAllowedViewCounter($aEvent, $bPerform = false)
+    {
+        $mixedViews = $this->getViewsData($aEvent['views']);
+        if($mixedViews === false)
+            return false;
+
+        list($sSystem, $iObjectId) = $mixedViews;
+        $oView = $this->getViewObject($sSystem, $iObjectId);
+
+        if(!$oView->isAllowedViewView($bPerform))
+        	return false;
+
+        $bResult = true;
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_view_counter', $oProfileOwner->id(), (int)$this->getUserId(), array('result' => &$bResult));
+
+        return $bResult;
+    }
+
+    public function isAllowedVote($aEvent, $bPerform = false)
+    {
+        $mixedVotes = $this->getVotesData($aEvent['votes']);
+        if($mixedVotes === false)
+            return false;
+
+        list($sSystem, $iObjectId) = $mixedVotes;
+        $oVote = $this->getVoteObject($sSystem, $iObjectId);
+
+        if(!$oVote->isAllowedVote($bPerform))
+        	return false;
+
+        $bResult = true;
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_vote', $oProfileOwner->id(), (int)$this->getUserId(), array('result' => &$bResult));
+
+        return $bResult;
+    }
+
+    public function isAllowedScore($aEvent, $bPerform = false)
+    {
+        $mixedScores = $this->getScoresData($aEvent['scores']);
+        if($mixedScores === false)
+            return false;
+
+        list($sSystem, $iObjectId) = $mixedScores;
+        $oScore = $this->getScoreObject($sSystem, $iObjectId);
+
+        if(!$oScore->isAllowedVote($bPerform))
+        	return false;
+
+        $bResult = true;
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_score', $oProfileOwner->id(), (int)$this->getUserId(), array('result' => &$bResult));
+
+        return $bResult;
+    }
+
+    public function isAllowedReport($aEvent, $bPerform = false)
+    {
+        $mixedReports = $this->getReportsData($aEvent['reports']);
+        if($mixedReports === false)
+            return false;
+
+        list($sSystem, $iObjectId) = $mixedReports;
+        $oReport = $this->getReportObject($sSystem, $iObjectId);
+
+        if(!$oReport->isAllowedReport($bPerform))
+        	return false;
+
+        $bResult = true;
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_report', $oProfileOwner->id(), (int)$this->getUserId(), array('result' => &$bResult));
+
+        return $bResult;
+    }
+
+    public function isAllowedRepost($aEvent, $bPerform = false)
+    {
+        if(isAdmin())
+            return true;
+
+        $iUserId = (int)$this->getUserId();
+        if($iUserId == 0)
+            return false;
+
+        $aCheckResult = checkActionModule($iUserId, 'repost', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_repost', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    public function isAllowedSend($aEvent, $bPerform = false)
+    {
+        if(!$this->_oDb->isEnabledByName('bx_convos'))
+            return false;
+
+        if(isAdmin())
+            return true;
+
+        $iUserId = (int)$this->getUserId();
+        if($iUserId == 0)
+            return false;
+
+        $aCheckResult = checkActionModule($iUserId, 'send', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_send', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    /**
+     * Pin - "Pin here" - pin the post on Profile Timeline for profile owner.
+     * Can be done by profile owner for himself or by admin for profile owner to see.
+     * @param type $aEvent
+     * @param type $bPerform
+     * @return boolean
+     */
+    public function isAllowedPin($aEvent, $bPerform = false)
+    {
+    	if((int)$aEvent['pinned'] != 0)
+    		return false;
+
+        return $this->_isAllowedPin($aEvent, $bPerform);
+    }
+
+    public function isAllowedUnpin($aEvent, $bPerform = false)
+    {
+    	if((int)$aEvent['pinned'] == 0)
+    		return false;
+
+        return $this->_isAllowedPin($aEvent, $bPerform);
+    }
+
+    /**
+     * Stick - "Pin for All" - pin the post on Public Timeline for everybody to see.
+     * Is available for Administrators/Moderators only.
+     * @param type $aEvent
+     * @param type $bPerform
+     * @return boolean
+     */
+    public function isAllowedStick($aEvent, $bPerform = false)
+    {
+    	if((int)$aEvent['sticked'] != 0)
+    		return false;
+    
+    	return $this->_isAllowedStick($aEvent, $bPerform);
+    }
+    
+    public function isAllowedUnstick($aEvent, $bPerform = false)
+    {
+    	if((int)$aEvent['sticked'] == 0)
+    		return false;
+    
+    	return $this->_isAllowedStick($aEvent, $bPerform);
+    }
+    
+    public function isAllowedPromote($aEvent, $bPerform = false)
+    {
+    	if((int)$aEvent['promoted'] != 0)
+    		return false;
+
+        return $this->_isAllowedPromote($aEvent, $bPerform);
+    }
+
+	public function isAllowedUnpromote($aEvent, $bPerform = false)
+    {
+    	if((int)$aEvent['promoted'] == 0)
+    		return false;
+
+        return $this->_isAllowedPromote($aEvent, $bPerform);
+    }
+
+    public function isAllowedMore($aEvent, $bPerform = false)
+    {
+    	$oMoreMenu = $this->getManageMenuObject();
+    	$oMoreMenu->setEventById($aEvent['id']);
+    	return $oMoreMenu->isVisible();
+    }
+
+    public function checkAllowedView ($aContentInfo, $isPerformAction = false)
+    {
+        if(!$this->isAllowedView($aContentInfo, $isPerformAction))
+            return _t('_sys_txt_access_denied');
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedCommentsView ($aContentInfo, $isPerformAction = false)
+    {
+        $CNF = $this->_oConfig->CNF;
+
+        $mixedResult = BxDolProfile::getInstance($aContentInfo[$CNF['FIELD_OWNER_ID']])->checkAllowedProfileView();
+        if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
+            return $mixedResult;
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function checkAllowedCommentsPost ($aContentInfo, $isPerformAction = false)
+    {
+        $sError = '_sys_txt_access_denied';
+
+        $aContentInfo = $this->_oTemplate->getData($aContentInfo);
+        if($aContentInfo === false)
+            return _t($sError);
+
+        if(!$this->isAllowedComment($aContentInfo, $isPerformAction))
+            return _t($sError);
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    public function onPost($iId)
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+
+        if($this->_oConfig->isSystem($aEvent['type'], $aEvent['action'])) {
+            //--- Request event's data from content module and update it in the Timeline DB.
+            $this->_oTemplate->getData($aEvent);
+
+            $sPostType = 'system';
+            $iSenderId = $aEvent['owner_id'];
+        } else {
+            $sPostType = 'common';
+            $iSenderId = $aEvent['object_id'];
+        }
+
+        //--- Event -> Post for Alerts Engine ---//
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'post_' . $sPostType, $iId, $iSenderId, array(
+        	'privacy_view' => $aEvent['object_privacy_view'],
+        	'object_author_id' => $aEvent['owner_id'],
+        ));
+        $oAlert->alert();
+        //--- Event -> Post for Alerts Engine ---//
+    }
+
+    public function onRepost($iId, $aReposted = array())
+    {
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+
+        if(empty($aReposted)) {
+            $aContent = unserialize($aEvent['content']);
+
+            $aReposted = $this->_oDb->getReposted($aContent['type'], $aContent['action'], $aContent['object_id']);
+            if(empty($aReposted) || !is_array($aReposted))
+                return;
+        }
+
+        $iUserId = $this->getUserId();
+        $this->_oDb->insertRepostTrack($aEvent['id'], $iUserId, $this->getUserIp(), $aReposted['id']);
+        $this->_oDb->updateRepostCounter($aReposted['id'], $aReposted['reposts']);
+
+        //--- Timeline -> Update for Alerts Engine ---//
+        $oAlert = new BxDolAlerts($this->_oConfig->getObject('alert'), 'repost', $aReposted['id'], $iUserId, array(
+        	'privacy_view' => $aEvent['object_privacy_view'],
+        	'object_author_id' => $aReposted['owner_id'],
+        	'repost_id' => $iId,
+        ));
+        $oAlert->alert();
+        //--- Timeline -> Update for Alerts Engine ---//
+    }
+
+    public function onDelete($aEvent)
+    {
+        $iUserId = $this->getUserId();
+    	$sCommonPostPrefix = $this->_oConfig->getPrefix('common_post');
+    	$sCommonPostComment = $this->_oConfig->getObject('comment');
+    	
+    	//--- Delete comments for Common posts.
+    	if($this->_oConfig->isCommon($aEvent['type'], $aEvent['action'])) {
+            $oComments = $this->getCmtsObject($sCommonPostComment, $aEvent['id']);
+            if($oComments !== false)
+                $oComments->onObjectDelete($aEvent['id']);
+    	}
+
+    	//--- Delete attached photos, videos and links when common event was deleted.
+    	if($aEvent['type'] == $sCommonPostPrefix . BX_TIMELINE_PARSE_TYPE_POST) {
+    		$this->_deleteMedia(BX_TIMELINE_MEDIA_PHOTO, $aEvent['id']);
+    		$this->_deleteMedia(BX_TIMELINE_MEDIA_VIDEO, $aEvent['id']);
+
+	        $this->_deleteLinks($aEvent['id']);
+    	}
+
+    	//--- Update parent event when repost event was deleted.
+    	$bRepost = $aEvent['type'] == $sCommonPostPrefix . BX_TIMELINE_PARSE_TYPE_REPOST;
+        if($bRepost) {
+            $this->_oDb->deleteRepostTrack($aEvent['id']);
+
+            $aContent = unserialize($aEvent['content']);
+            $aReposted = $this->_oDb->getReposted($aContent['type'], $aContent['action'], $aContent['object_id']);
+            if(!empty($aReposted) && is_array($aReposted))
+                $this->_oDb->updateRepostCounter($aReposted['id'], $aReposted['reposts'], -1);
+        }
+
+        //--- Find and delete repost events when parent event was deleted.
+        $bSystem = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']);
+	    $aRepostEvents = $this->_oDb->getEvents(array('browse' => 'reposted_by_descriptor', 'type' => $aEvent['type']));
+		foreach($aRepostEvents as $aRepostEvent) {
+			$aContent = unserialize($aRepostEvent['content']);
+			if(isset($aContent['type']) && $aContent['type'] == $aEvent['type'] && isset($aContent['object_id']) && (($bSystem && (int)$aContent['object_id'] == (int)$aEvent['object_id']) || (!$bSystem  && (int)$aContent['object_id'] == (int)$aEvent['id'])) && (int)$this->_oDb->deleteEvent(array('id' => (int)$aRepostEvent['id'])) > 0) {
+			    $oComments = $this->getCmtsObject($sCommonPostComment, $aRepostEvent['id']);
+                if($oComments !== false)
+                    $oComments->onObjectDelete($aRepostEvent['id']);
+
+                bx_alert($this->_oConfig->getObject('alert'), 'delete_repost', $aEvent['id'], $iUserId, array(
+                    'repost_id' => $aRepostEvent['id'],
+                ));
+            }
+		}
+
+		//--- Delete associated meta.
+        $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
+        $oMetatags->onDeleteContent($aEvent['id']);
+
+        //--- Event -> Delete for Alerts Engine ---//
+        if($bRepost)
+            bx_alert($this->_oConfig->getObject('alert'), 'delete_repost', $aReposted['id'], $iUserId, array(
+                'repost_id' => $aEvent['id'],
+            ));
+        else
+            bx_alert($this->_oConfig->getObject('alert'), 'delete', $aEvent['id'], $iUserId);
+        //--- Event -> Delete for Alerts Engine ---//
+    }
+
+    public function getParams($sView = '', $sType = '', $iOwnerId = 0, $iStart = 0, $iPerPage = 0, $sFilter = BX_TIMELINE_FILTER_ALL, $aModules = array(), $iTimeline = 0)
+    {
+        return $this->_prepareParams($sView, $sType, $iOwnerId, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline);
+    }
+
+    public function getViewsData(&$aViews)
+    {
+        if(empty($aViews) || !is_array($aViews))
+            return false;
+
+        $sSystem = isset($aViews['system']) ? $aViews['system'] : '';
+        $iObjectId = isset($aViews['object_id']) ? (int)$aViews['object_id'] : 0;
+        $iCount = isset($aViews['count']) ? (int)$aViews['count'] : 0;
+        if($sSystem == '' || $iObjectId == 0)
+            return false;
+
+        return array($sSystem, $iObjectId, $iCount);
+    }
+
+    public function getVotesData(&$aVotes)
+    {
+        if(empty($aVotes) || !is_array($aVotes))
+            return false;
+
+        $sSystem = isset($aVotes['system']) ? $aVotes['system'] : '';
+        $iObjectId = isset($aVotes['object_id']) ? (int)$aVotes['object_id'] : 0;
+        $iCount = isset($aVotes['count']) ? (int)$aVotes['count'] : 0;
+        if($sSystem == '' || $iObjectId == 0)
+            return false;
+
+        return array($sSystem, $iObjectId, $iCount);
+    }
+
+    public function getScoresData(&$aScores)
+    {
+        if(empty($aScores) || !is_array($aScores))
+            return false;
+
+        $sSystem = isset($aScores['system']) ? $aScores['system'] : '';
+        $iObjectId = isset($aScores['object_id']) ? (int)$aScores['object_id'] : 0;
+        $iScore = isset($aScores['score']) ? (int)$aScores['score'] : 0;
+        if($sSystem == '' || $iObjectId == 0)
+            return false;
+
+        return array($sSystem, $iObjectId, $iScore);
+    }
+
+    public function getReportsData(&$aReports)
+    {
+        if(empty($aReports) || !is_array($aReports))
+            return false;
+
+        $sSystem = isset($aReports['system']) ? $aReports['system'] : '';
+        $iObjectId = isset($aReports['object_id']) ? (int)$aReports['object_id'] : 0;
+        $iCount = isset($aReports['count']) ? (int)$aReports['count'] : 0;
+        if($sSystem == '' || $iObjectId == 0)
+            return false;
+
+        return array($sSystem, $iObjectId, $iCount);
+    }
+
+    public function getCommentsData(&$aComments)
+    {
+        if(empty($aComments) || !is_array($aComments))
+            return false;
+
+        $sSystem = isset($aComments['system']) ? $aComments['system'] : '';
+        $iObjectId = isset($aComments['object_id']) ? (int)$aComments['object_id'] : 0;
+        $iCount = isset($aComments['count']) ? (int)$aComments['count'] : 0;
+        if($sSystem == '' || $iObjectId == 0 || ($iCount == 0 && !isLogged()))
+            return false;
+
+        return array($sSystem, $iObjectId, $iCount);
+    }
+
+    public function getUserInfo($iUserId = 0)
+    {
+        $iLoggedId = $this->getUserId();
+        $iUserId = (int)$iUserId;
+        return parent::getUserInfo($iUserId);
+    }
+
+    /**
+     * Protected Methods 
+     */
+    protected function _serviceGetBlockView($iProfileId = 0, $sView = BX_TIMELINE_VIEW_DEFAULT)
+    {
+        if(empty($iProfileId) && bx_get('profile_id') !== false)
+			$iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
+
+		if(empty($iProfileId) && isLogged())
+			$iProfileId = bx_get_logged_profile_id();
+
+        $aBlock = $this->_getBlockView($iProfileId, $sView);
+        if(!empty($aBlock))
+            return $aBlock;
+
+        return array('content' => MsgBox(_t('_bx_timeline_txt_msg_no_results')));
+    }
+
+    protected function _serviceGetBlockViewProfile($sProfileModule = 'bx_persons', $iProfileContentId = 0, $sView = BX_TIMELINE_VIEW_DEFAULT, $iStart = -1, $iPerPage = -1, $sFilter = '', $aModules = array(), $iTimeline = -1)
+    {
+    	if(empty($sProfileModule))
+    		return array();
+
+    	if(empty($iProfileContentId) && bx_get('id') !== false)
+    		$iProfileContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+
+		$oProfile = BxDolProfile::getInstanceByContentAndType($iProfileContentId, $sProfileModule);
+		if(empty($oProfile))
+			return array();
+
+        return $this->_getBlockView($oProfile->id(), $sView, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline);
+    }
+
+    protected function _serviceGetBlockViewHome($iProfileId = 0, $sView = BX_TIMELINE_VIEW_DEFAULT, $iStart = -1, $iPerPage = -1, $iPerPageDefault = -1,  $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        $sRssUrl = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'rss/' . BX_BASE_MOD_NTFS_TYPE_PUBLIC . '/';
+        BxDolTemplate::getInstance()->addPageRssLink(_t('_bx_timeline_page_title_view_home'), $sRssUrl);
+
+        return $this->_serviceGetBlockViewByType($iProfileId, $sView, BX_BASE_MOD_NTFS_TYPE_PUBLIC, $iStart, $iPerPage, $iPerPageDefault, $iTimeline, $sFilter, $aModules);
+    }
+
+    protected function _serviceGetBlockViewHot($iProfileId = 0, $sView = BX_TIMELINE_VIEW_DEFAULT, $iStart = -1, $iPerPage = -1, $iPerPageDefault = -1,  $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        $sRssUrl = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'rss/' . BX_TIMELINE_TYPE_HOT . '/';
+        BxDolTemplate::getInstance()->addPageRssLink(_t('_bx_timeline_page_title_view_hot'), $sRssUrl);
+
+        return $this->_serviceGetBlockViewByType($iProfileId, $sView, BX_TIMELINE_TYPE_HOT, $iStart, $iPerPage, $iPerPageDefault, $iTimeline, $sFilter, $aModules);
+    }
+
+    protected function _serviceGetBlockViewByType($iProfileId = 0, $sView = BX_TIMELINE_VIEW_DEFAULT, $sType = BX_TIMELINE_TYPE_DEFAULT, $iStart = -1, $iPerPage = -1, $iPerPageDefault = -1,  $iTimeline = -1, $sFilter = '', $aModules = array())
+    {
+        $aParams = $this->_prepareParams($sView, $sType, $iProfileId, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline);
+
+        $aParams['view'] = $sView;
+        $aParams['per_page'] = (int)$iPerPage > 0 ? $iPerPage : ((int)$iPerPageDefault > 0 ? $iPerPageDefault : $this->_oConfig->getPerPage());
+
+        $this->_iOwnerId = $aParams['owner_id'];
+
+        $sContent = $this->_oTemplate->getViewBlock($aParams);
+        return array('content' => $sContent);
+    }
+
+    protected function _getBlockPost($iProfileId, $aParams = array())
+    {
+        $this->_iOwnerId = $iProfileId;
+
+        if($this->isAllowedPost() !== true)
+            return array();
+
+		$sContent = $this->_oTemplate->getPostBlock($this->_iOwnerId, $aParams);
+        return array('content' => $sContent);
+    }
+
+    protected function _getBlockView($iProfileId, $sView = BX_TIMELINE_VIEW_DEFAULT, $iStart = -1, $iPerPage = -1, $sFilter = '', $aModules = array(), $iTimeline = -1)
+    {
+        if(!$iProfileId)
+			return array();
+
+        $aParams = $this->_prepareParams($sView, BX_BASE_MOD_NTFS_TYPE_OWNER, $iProfileId, $iStart, $iPerPage, $sFilter, $aModules, $iTimeline);
+        $aParams['view'] = $sView;
+        $aParams['per_page'] = (int)$iPerPage > 0 ? $iPerPage : $this->_oConfig->getPerPage('profile');
+
+        $this->_iOwnerId = $aParams['owner_id'];
+        $oProfileOwner = BxDolProfile::getInstance($this->_iOwnerId);
+
+        $mixedResult = $oProfileOwner->checkAllowedProfileView();
+        if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
+            return array('content' => MsgBox($mixedResult));
+
+        list($sUserName, $sUserUrl) = $this->getUserInfo($aParams['owner_id']);
+
+        $sRssUrl = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'rss/' . BX_BASE_MOD_NTFS_TYPE_OWNER . '/' . $iProfileId . '/';
+        $sJsObject = $this->_oConfig->getJsObject('view');
+        $aMenu = array(
+            array('id' => $sView . '-view-all', 'name' => $sView . '-view-all', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.changeFilter(this)', 'target' => '_self', 'title' => _t('_bx_timeline_menu_item_view_all'), 'active' => 1),
+            array('id' => $sView . '-view-owner', 'name' => $sView . '-view-owner', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.changeFilter(this)', 'target' => '_self', 'title' => _t('_bx_timeline_menu_item_view_owner', $sUserName)),
+            array('id' => $sView . '-view-other', 'name' => $sView . '-view-other', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.changeFilter(this)', 'target' => '_self', 'title' => _t('_bx_timeline_menu_item_view_other')),
+            array('id' => $sView . '-get-rss', 'name' => $sView . '-get-rss', 'class' => '', 'link' => $sRssUrl, 'target' => '_blank', 'title' => _t('_bx_timeline_menu_item_get_rss')),
+        );
+
+        $sContent = '';
+        bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_view', $this->_iOwnerId, $this->getUserId(), array('override_content' => &$sContent, 'params' => &$aParams, 'menu' => &$aMenu));
+
+        $oMenu = new BxTemplMenuInteractive(array('template' => 'menu_interactive_vertical.html', 'menu_id'=> $sView . '-view-all', 'menu_items' => $aMenu));
+        $oMenu->setSelected('', $sView . '-view-all');
+
+        if (!$sContent)
+            $sContent = $this->_oTemplate->getViewBlock($aParams);
+
+        BxDolTemplate::getInstance()->addPageRssLink(_t('_bx_timeline_page_title_view'), $sRssUrl);
+
+        return array('content' => $sContent, 'menu' => $oMenu);
+    }
+    
+    protected function _getContentForTimelinePost($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']]);
+
+        $sText = ''; 
+        if(isset($aContentInfo['content'])){
+            $aTmp = unserialize($aContentInfo['content']);
+            if(isset($aTmp['text']))
+                $sText = $aTmp['text'];
+        }
+
+        if(empty($sText) && !empty($aContentInfo[$CNF['FIELD_TITLE']]))
+            $sText = $aContentInfo[$CNF['FIELD_TITLE']];
+
+        if(!empty($CNF['OBJECT_METATAGS']) && !empty($sText)) {
+            $oMetatags = BxDolMetatags::getObjectInstance($CNF['OBJECT_METATAGS']);
+            $sText = $oMetatags->metaParse($aContentInfo[$CNF['FIELD_ID']], $sText);
+        }
+
+        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']) ? $CNF['T']['txt_sample_action'] : '',
+            'url' => $sUrl,
+            'title' => '',
+            'text' => $sText,
+            'images' => array(),
+            'videos' => array()
+        );
+    }
+
+	protected function _isAllowedPin($aEvent, $bPerform = false)
+    {
+    	$iUserId = (int)$this->getUserId();
+    	if($iUserId == 0)
+    		return false;
+
+		if(isAdmin() || (int)$aEvent['owner_id'] == $iUserId || ((int)$aEvent['owner_id'] == 0 && $this->_oConfig->isCommon($aEvent['type'], $aEvent['action']) && (int)$aEvent['object_id'] == $iUserId))
+           return true;
+
+        $aCheckResult = checkActionModule($iUserId, 'pin', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_pin', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    protected function _isAllowedStick($aEvent, $bPerform = false)
+    {
+    	$iUserId = (int)$this->getUserId();
+    	if($iUserId == 0)
+    		return false;
+
+    	if(isAdmin())
+    		return true;
+
+    	$aCheckResult = checkActionModule($iUserId, 'stick', $this->getName(), $bPerform);
+    
+    	$oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+    	if($oProfileOwner !== false)
+    		bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_stick', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+    
+    	return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    protected function _isAllowedPromote($aEvent, $bPerform = false)
+    {
+        if(isAdmin())
+            return true;
+
+        $iUserId = (int)$this->getUserId();
+        if($iUserId == 0)
+            return false;
+
+        $aCheckResult = checkActionModule($iUserId, 'promote', $this->getName(), $bPerform);
+
+        $oProfileOwner = BxDolProfile::getInstance($aEvent['owner_id']);
+        if($oProfileOwner !== false)
+            bx_alert($oProfileOwner->getModule(), $this->_oConfig->getUri() . '_promote', $oProfileOwner->id(), $iUserId, array('check_result' => &$aCheckResult));
+
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
+
+    protected function _addLink(&$oForm)
+    {
+        $iUserId = $this->getUserId();
+
+        $sLink = $oForm->getCleanValue('url');
+
+        $aMatches = array();
+        preg_match($this->_oConfig->getPregPattern('url'), $sLink, $aMatches);
+        $sLink = (empty($aMatches[2]) ? 'http://' : '') . $aMatches[0];
+
+        $aSiteInfo = bx_get_site_info($sLink, array(
+            'thumbnailUrl' => array('tag' => 'link', 'content_attr' => 'href'),
+            'OGImage' => array('name_attr' => 'property', 'name' => 'og:image'),
+        ));
+
+        $sTitle = !empty($aSiteInfo['title']) ? $aSiteInfo['title'] : _t('_Empty');
+        $sDescription = !empty($aSiteInfo['description']) ? $aSiteInfo['description'] : _t('_Empty');
+
+        $sMediaUrl = '';
+        if(!empty($aSiteInfo['thumbnailUrl']))
+        	$sMediaUrl = $aSiteInfo['thumbnailUrl'];
+        else if(!empty($aSiteInfo['OGImage']))
+        	$sMediaUrl = $aSiteInfo['OGImage'];
+
+		$iMediaId = 0;
+		$oStorage = null;
+        if(!empty($sMediaUrl)) {
+        	$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . BX_TIMELINE_MEDIA_PHOTO . 's'));
+
+        	$iMediaId = $oStorage->storeFileFromUrl($sMediaUrl, true, $iUserId);
+        }
+
+        $iId = (int)$oForm->insert(array('profile_id' => $iUserId, 'media_id' => $iMediaId, 'url' => $sLink, 'title' => $sTitle, 'text' => $sDescription, 'added' => time()));
+        if(!empty($iId)) {
+        	if(!empty($oStorage) && !empty($iMediaId))
+        		$oStorage->afterUploadCleanup($iMediaId, $iUserId);
+
+            return array('id' => $iId, 'item' => $this->_oTemplate->getAttachLinkItem($iUserId, $iId));
+        }
+
+        return array('message' => _t('_bx_timeline_txt_err_cannot_perform_action'));
+    }
+
+	protected function _deleteLinks($iId)
+    {
+	    $aLinks = $this->_oDb->getLinks($iId);
+	    if(empty($aLinks) || !is_array($aLinks))
+	    	return;
+
+		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_photos'));
+		foreach($aLinks as $aLink)
+			if(!empty($aLink['media_id']))
+				$oStorage->deleteFile($aLink['media_id']);
+
+		$this->_oDb->deleteLinks($iId);
+    }
+
+    protected function _saveMedia($sType, $iId, $aItemIds)
+    {
+    	if(empty($aItemIds) || !is_array($aItemIds))
+    		return; 
+
+    	$iUserId = $this->getUserId();
+
+		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
+		foreach($aItemIds as $iItemId)
+        	if($this->_oDb->saveMedia($sType, $iId, $iItemId))
+            	$oStorage->afterUploadCleanup($iItemId, $iUserId);
+    }
+
+    protected function _deleteMedia($sType, $iId)
+    {
+	    $aItems = $this->_oDb->getMedia($sType, $iId);
+	    if(empty($aItems) || !is_array($aItems))
+	    	return;
+
+		$oStorage = BxDolStorage::getObjectInstance($this->_oConfig->getObject('storage_' . strtolower($sType) . 's'));
+		foreach($aItems as $iItemId)
+			$oStorage->deleteFile($iItemId);
+
+		$this->_oDb->deleteMedia($sType, $iId);
+    }
+
+    protected function _prepareParams($sView, $sType, $iOwnerId, $iStart, $iPerPage, $sFilter = BX_TIMELINE_FILTER_ALL, $aModules = array(), $iTimeline = 0, $aBlink = array())
+    {
+         $aParams = array(
+            'view' => !empty($sView) ? $sView : BX_TIMELINE_VIEW_DEFAULT,
+
+            'browse' => 'list',
+            'type' => !empty($sType) ? $sType : BX_TIMELINE_TYPE_DEFAULT,
+            'owner_id' => (int)$iOwnerId != 0 ? $iOwnerId : $this->getUserId(),
+            'filter' => !empty($sFilter) ? $sFilter : BX_TIMELINE_FILTER_ALL,
+            'modules' => is_array($aModules) && !empty($aModules) ? $aModules : array(),
+            'timeline' => (int)$iTimeline > 0 ? $iTimeline : 0,
+         	'blink' => is_array($aBlink) && !empty($aBlink) ? $aBlink : array(),
+            'active' => 1,
+            'hidden' => 0
+        );
+
+        if($iStart !== false)
+            $aParams['start'] = (int)$iStart > 0 ? $iStart : 0;
+
+        if($iPerPage !== false)
+            $aParams['per_page'] = (int)$iPerPage > 0 ? $iPerPage : $this->_oConfig->getPerPage();
+
+        if($this->_oConfig->isHot())
+            $aParams['hot'] = $this->_oDb->getHot();
+
+        return $aParams;
+    }
+
+    protected function _prepareParamsGet()
+    {
+        $aParams = array(
+            'browse' => 'list',
+            'dynamic_mode' => true,
+        );
+
+        $aParams['view'] = bx_get('view');
+        $aParams['view'] = $aParams['view'] !== false ? bx_process_input($aParams['view'], BX_DATA_TEXT) : BX_TIMELINE_VIEW_DEFAULT;
+
+        $aParams['type'] = bx_get('type');
+        $aParams['type'] = $aParams['type'] !== false ? bx_process_input($aParams['type'], BX_DATA_TEXT) : BX_TIMELINE_TYPE_DEFAULT;
+
+        $aParams['owner_id'] = bx_get('owner_id');
+        $aParams['owner_id'] = $aParams['owner_id'] !== false ? bx_process_input($aParams['owner_id'], BX_DATA_INT) : $this->getUserId();
+
+        $aParams['start'] = bx_get('start');
+        $aParams['start'] = $aParams['start'] !== false ? bx_process_input($aParams['start'], BX_DATA_INT) : 0;
+
+        $aParams['per_page'] = bx_get('per_page');
+        $aParams['per_page'] = $aParams['per_page'] !== false ? bx_process_input($aParams['per_page'], BX_DATA_INT) : $this->_oConfig->getPerPage();
+
+        $aParams['filter'] = bx_get('filter');
+        $aParams['filter'] = $aParams['filter'] !== false ? bx_process_input($aParams['filter'], BX_DATA_TEXT) : BX_TIMELINE_FILTER_ALL;
+
+        $aParams['modules'] = bx_get('modules');
+        $aParams['modules'] = $aParams['modules'] !== false ? bx_process_input($aParams['modules'], BX_DATA_TEXT) : array();
+
+        $aParams['timeline'] = bx_get('timeline');
+        $aParams['timeline'] = $aParams['timeline'] !== false ? bx_process_input($aParams['timeline'], BX_DATA_INT) : 0;
+
+        $aParams['blink'] = bx_get('blink');
+        $aParams['blink'] = $aParams['blink'] !== false ? explode(',', bx_process_input($aParams['blink'], BX_DATA_TEXT)) : array();
+
+        $aParams['active'] = 1;
+        $aParams['hidden'] = 0;
+
+        if($this->_oConfig->isHot())
+            $aParams['hot'] = $this->_oDb->getHot();
+
+        return $aParams;
+    }
+
+    protected function _prepareTextForSave($s)
+    {
+        return bx_process_input($s, BX_DATA_HTML);
+    }
+
+    protected function _getFieldValue($sField, $iContentId)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        if(empty($CNF[$sField]))
+            return false;
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iContentId));
+        if(empty($aEvent) || empty($aEvent[$CNF[$sField]]))
+            return false;
+
+        return $aEvent[$CNF[$sField]];
+    }
+}
+
+/** @} */

+ 1787 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/source/classes/BxTimelineTemplate.php

@@ -0,0 +1,1787 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxTimelineTemplate extends BxBaseModNotificationsTemplate
+{
+    protected static $_sTmplContentItemItem;
+    protected static $_sTmplContentItemOutline;
+    protected static $_sTmplContentItemTimeline;
+    protected static $_sTmplContentItemSearch;
+    protected static $_sTmplContentTypePost;
+    protected static $_sTmplContentTypeRepost;
+
+    protected $_bShowTimelineDividers;
+
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+
+        $this->_bShowTimelineDividers = false;
+    }
+
+    public function getCss($bDynamic = false)
+    {
+        $mixedResult = parent::getCss($bDynamic);
+        $mixedResult .= $this->addCss(array(
+            BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'flickity/|flickity.css',
+            BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'emoji/css/|emoji.css',
+            'jquery-ui/jquery-ui.css',
+            'cmts.css',
+            'post.css',
+            'repost.css',
+        ), $bDynamic);
+
+        if($bDynamic)
+            return $mixedResult; 
+    }
+
+    public function getJs($bDynamic = false)
+    {
+        $mixedResult = parent::getJs($bDynamic);
+        $mixedResult .= $this->addJs(array(
+            'jquery-ui/jquery-ui.custom.min.js',
+            'jquery.form.min.js',
+            'jquery.ba-resize.min.js',
+            'autosize.min.js',
+            'masonry.pkgd.min.js',
+            'flickity/flickity.pkgd.min.js',
+            'embedly-player.min.js',
+            'BxDolCmts.js',            
+            'post.js',
+            'repost.js',
+        ), $bDynamic);
+
+        if($bDynamic)
+            return $mixedResult; 
+    }
+
+    public function getJsCodePost($iOwnerId, $aParams = array())
+    {
+        return $this->getJsCode('post', array(
+            'sVideosAutoplay' => $this->_oConfig->getVideosAutoplay(),
+            'oRequestParams' => array_merge(array(
+                    'type' => isset($aParams['type']) ? $aParams['type'] : BX_TIMELINE_TYPE_DEFAULT, 
+                    'owner_id' => $iOwnerId
+            ), $aParams)
+        ));
+    }
+
+    public function getPostBlock($iOwnerId, $aParams = array())
+    {
+        $aForm = $this->getModule()->getFormPost($aParams);
+
+        return $this->parseHtmlByName('block_post.html', array (
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'js_object' => $this->_oConfig->getJsObject('post'),
+            'js_content' => $this->getJsCodePost($iOwnerId, $aParams),
+            'form' => $aForm['form']
+        ));
+    }
+
+    public function getViewBlock($aParams)
+    {
+        $oModule = $this->getModule();
+
+        //--- Add live update
+		$oModule->actionResumeLiveUpdate($aParams['type'], $aParams['owner_id']);
+
+		$sServiceCall = BxDolService::getSerializedService($this->_oConfig->getName(), 'get_live_updates', array($aParams['type'], $aParams['owner_id'], $oModule->getUserId(), '{count}', '{init}'));
+		$sLiveUpdatesCode = BxDolLiveUpdates::getInstance()->add($this->_oConfig->getLiveUpdateKey($aParams['type'], $aParams['owner_id']), 1, $sServiceCall);
+		//--- Add live update
+
+        list($sContent, $sLoadMore, $sBack, $sEmpty) = $this->getPosts($aParams);
+
+        return $sLiveUpdatesCode . $this->parseHtmlByName('block_view.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+        	'html_id' => $this->_oConfig->getHtmlIds('view', 'main_' . $aParams['view']),
+            'view' => $aParams['view'],
+            'back' => $sBack,
+            'empty' => $sEmpty, 
+            'content' => $sContent,
+            'load_more' =>  $sLoadMore,
+            'show_more' => $this->_getShowMore($aParams),
+            'view_image_popup' => $this->_getImagePopup($aParams),
+            'js_content' => $this->getJsCode('view', array(
+                'sVideosAutoplay' => $this->_oConfig->getVideosAutoplay(),
+            	'oRequestParams' => array(
+	                'type' => $aParams['type'],
+	                'owner_id' => $aParams['owner_id'],
+	                'start' => $aParams['start'],
+	                'per_page' => $aParams['per_page'],
+	                'filter' => $aParams['filter'],
+	                'modules' => $aParams['modules'],
+	                'timeline' => $aParams['timeline'],
+        		)
+            )) . $this->getJsCode('repost')
+        ));
+    }
+
+    public function getSearchBlock($sContent)
+    {
+        $oModule = $this->getModule();
+        $aParams = $oModule->getParams(BX_TIMELINE_VIEW_SEARCH);
+
+        return $this->parseHtmlByName('block_search.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+        	'html_id' => $this->_oConfig->getHtmlIds('view', 'main_' . $aParams['view']),
+            'view' => $aParams['view'],
+            'content' => $sContent,
+        	'view_image_popup' => $this->_getImagePopup($aParams),
+            'js_content' => $this->getJsCode('view', array(
+            	'oRequestParams' => array(
+	                'type' => $aParams['type'],
+	                'owner_id' => $aParams['owner_id'],
+	                'start' => $aParams['start'],
+	                'per_page' => $aParams['per_page'],
+	                'filter' => $aParams['filter'],
+	                'modules' => $aParams['modules'],
+	                'timeline' => $aParams['timeline'],
+        		)
+            ))
+        ));
+    }
+
+    public function getItemBlock($iId)
+    {
+        $CNF = $this->_oConfig->CNF;
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent))
+            return array('content' => MsgBox(_t('_Empty')), 'designbox_id' => 13);
+
+        $iProfile = (int)$aEvent[$CNF['FIELD_OWNER_ID']];
+        if(!empty($iProfile)) {
+            $oProfile = BxDolProfile::getInstance($iProfile);
+            if(!$oProfile)
+                return array('content' => MsgBox(_t('_Empty')), 'designbox_id' => 13);
+
+            $mixedResult = $oProfile->checkAllowedProfileView();
+            if($mixedResult !== CHECK_ACTION_RESULT_ALLOWED)
+                return array('content' => MsgBox($mixedResult), 'designbox_id' => 13);
+        }
+
+        $aParams = array(
+            'view' => BX_TIMELINE_VIEW_ITEM, 
+            'type' => BX_TIMELINE_TYPE_ITEM
+        );
+        $sContent = $this->getPost($aEvent, $aParams);
+
+        $sKey = 'allowed_view';
+        if(isset($aEvent[$sKey]) && $aEvent[$sKey] !== CHECK_ACTION_RESULT_ALLOWED) 
+            return array('content' => MsgBox($aEvent[$sKey]), 'designbox_id' => 13);
+
+        $oModule = $this->getModule();
+        if($oModule->isAllowedViewCounter($aEvent) !== true)
+            return array('content' => MsgBox(_t('_Access denied')), 'designbox_id' => 13);
+
+        if(!$this->_oConfig->isSystem($aEvent['type'], $aEvent['action'])) {
+            $mixedViews = $oModule->getViewsData($aEvent['views']);
+            if($mixedViews !== false) {
+                list($sSystem, $iObjectId) = $mixedViews;
+                $oModule->getViewObject($sSystem, $iObjectId)->doView();
+            }
+        }
+
+        list($sAuthorName) = $oModule->getUserInfo($aEvent['object_owner_id']);
+
+        $oTemplate = BxDolTemplate::getInstance();
+        $oTemplate->setPageHeader(strip_tags($sAuthorName . ' ' . _t($aEvent['sample_action'], _t($aEvent['sample']))));
+        $oTemplate->setPageDescription(strip_tags($aEvent['title']));
+
+        $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
+        if($oMetatags)
+            $oMetatags->addPageMetaInfo($aEvent[$CNF['FIELD_ID']]);
+
+        $sReferrer = '';
+        if(isset($_SERVER['HTTP_REFERER']) && mb_stripos($_SERVER['HTTP_REFERER'], BX_DOL_URL_ROOT) === 0)
+            $sReferrer = $_SERVER['HTTP_REFERER'];
+        else 
+            $sReferrer = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_HOME']);
+
+        return array('content' => $this->parseHtmlByName('block_item.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'html_id' => $this->_oConfig->getHtmlIds('view', 'main_item'),
+            'content' => $sContent,
+            'show_more' => $this->_getShowMore($aParams),
+            'view_image_popup' => $this->_getImagePopup($aParams),
+            'js_content' => $this->getJsCode('view', array(
+                'sVideosAutoplay' => $this->_oConfig->getVideosAutoplay(),
+                'sReferrer' => $sReferrer
+            )) . $this->getJsCode('repost')
+        )));
+    }
+
+    /**
+     * Get event's content.
+     * @param integer $iId - event ID.
+     * @param string $sMode - 'photo' is only one mode which is available for now.
+     */
+    public function getItemBlockContent($iId, $sMode) {
+        $CNF = $this->_oConfig->CNF;
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent))
+            return '';
+
+        $aTmplVars = array(
+        	'style_prefix' => $sStylePrefix,
+            'bx_if:show_image' => array(
+                'condition' => false,
+                'content' => array()
+            )
+        );
+
+        switch($sMode) {
+            case 'photo':
+                $aTmplVars['bx_if:show_image']['condition'] = true;
+                $aTmplVars['bx_if:show_image']['content'] = array(
+                    'style_prefix' => $sStylePrefix,
+                    'src' => base64_decode(bx_process_input(bx_get('src'))),
+                );
+                break;
+        }
+
+        return $this->parseHtmlByName('block_item_content.html', $aTmplVars);
+    }
+
+    public function getItemBlockInfo($iId) {
+        $CNF = $this->_oConfig->CNF;
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent))
+            return '';
+
+        $aResult = $this->getData($aEvent);
+        if($aResult === false)
+            return '';
+
+        list($sAuthorName, $sAuthorUrl, $sAuthorIcon, $sAuthorUnit) = $this->getModule()->getUserInfo($aResult['owner_id']);
+
+        return $this->parseHtmlByName('block_item_info.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'author' => $sAuthorUnit
+        ));
+    }
+
+    public function getItemBlockComments($iId) {
+        $CNF = $this->_oConfig->CNF;
+
+        $aEvent = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $iId));
+        if(empty($aEvent))
+            return '';
+
+        $aResult = $this->getData($aEvent);
+        if($aResult === false)
+            return '';
+            
+        return $this->_getComments($aResult['comments']);
+    }
+
+    public function getUnit(&$aEvent, $aBrowseParams = array())
+    {
+        $oModule = $this->getModule();
+
+        if(empty($aBrowseParams) || !is_array($aBrowseParams))
+            $aBrowseParams = $oModule->getParams(BX_TIMELINE_VIEW_SEARCH);
+
+        return $this->getPost($aEvent, $aBrowseParams);
+    }
+
+    public function getPost(&$aEvent, $aBrowseParams = array())
+    {
+        $oPrivacy = BxDolPrivacy::getObjectInstance($this->_oConfig->getObject('privacy_view'));
+        if($oPrivacy) {
+            $oPrivacy->setTableFieldAuthor($this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? 'owner_id' : 'object_id');
+            if(!$oPrivacy->check($aEvent['id']))
+                return '';
+        }
+
+        $aResult = $this->getData($aEvent, $aBrowseParams);
+        if($aResult === false)
+            return '';
+
+        $aEvent['object_owner_id'] = $aResult['owner_id'];
+        $aEvent['icon'] = !empty($aResult['icon']) ? $aResult['icon'] : '';
+        $aEvent['sample'] = !empty($aResult['sample']) ? $aResult['sample'] : '_bx_timeline_txt_sample';
+        $aEvent['sample_action'] = !empty($aResult['sample_action']) ? $aResult['sample_action'] : '_bx_timeline_txt_added_sample';
+        $aEvent['content'] = $aResult['content'];
+        $aEvent['allowed_view'] = isset($aResult['allowed_view']) ? $aResult['allowed_view'] : CHECK_ACTION_RESULT_ALLOWED;
+        $aEvent['views'] = $aResult['views'];
+        $aEvent['votes'] = $aResult['votes'];
+        $aEvent['scores'] = $aResult['scores'];
+        $aEvent['reports'] = $aResult['reports'];
+        $aEvent['comments'] = $aResult['comments'];
+
+        $sKey = 'allowed_view';
+        if(isset($aEvent[$sKey]) && $aEvent[$sKey] !== CHECK_ACTION_RESULT_ALLOWED) 
+            return '';
+
+        $sType = !empty($aResult['content_type']) ? $aResult['content_type'] : BX_TIMELINE_PARSE_TYPE_DEFAULT;
+        return $this->_getPost($sType, $aEvent, $aBrowseParams);
+    }
+
+    public function getPosts($aParams)
+    {
+        $bViewTimeline = $aParams['view'] == BX_TIMELINE_VIEW_TIMELINE;
+
+        $iStart = $aParams['start'];
+        $iPerPage = $aParams['per_page'];
+
+        $aParamsDb = $aParams;
+
+        //--- Check for Previous
+        $iDays = -1;
+        $bPrevious = false;
+        if($iStart - 1 >= 0) {
+            $aParamsDb['start'] -= 1;
+            $aParamsDb['per_page'] += 1;
+            $bPrevious = true;
+        }
+
+        //--- Check for Next
+        $aParamsDb['per_page'] += 1;
+        $aEvents = $this->_oDb->getEvents($aParamsDb);
+
+        //--- Check for Previous
+        if($bPrevious) {
+            $aEvent = array_shift($aEvents);
+            $iDays = (int)$aEvent['days'];
+        }
+
+        //--- Check for Next
+        $bNext = false;
+        if(count($aEvents) > $iPerPage) {
+            $aEvent = array_pop($aEvents);
+            $bNext = true;
+        }
+
+        $sContent = '';
+        $sContent .= $this->getSizer($aParams);
+
+        $iEvents = count($aEvents);
+        if($bViewTimeline && $iEvents <= 0)
+        	$sContent .= $this->getDividerToday();
+
+        //--- Check for Visual Grouping
+        $aGroups = array();
+        foreach($aEvents as $iIndex => $aEvent) {
+            $aContent = unserialize($aEvent['content']);
+            if(!isset($aContent['timeline_group']))
+                continue;
+
+            $aGroup = $aContent['timeline_group'];
+            $sGroup = $aGroup['by'];
+            if(!isset($aGroups[$sGroup]))
+               $aGroups[$sGroup] = array('field' => $aGroup['field'], 'indexes' => array(), 'processed' => false);
+
+            $aGroups[$sGroup]['indexes'][] = $iIndex;
+        }
+
+        //--- Perform Visual Grouping
+        foreach($aGroups as $sGroup => $aGroup) {
+            if(empty($aGroup['field']) || empty($aGroup['indexes']))
+                continue;
+
+            switch($aGroup['field']) {
+                case 'owner_id':
+                    $aOwnerIds = array();
+                    foreach($aGroup['indexes'] as $iIndex)
+                        $aOwnerIds[] = $aEvents[$iIndex]['owner_id'];
+
+                    $iGroupIndex = (int)array_shift($aGroup['indexes']);
+                    if(is_null($iGroupIndex))
+                        break;
+
+                    foreach($aGroup['indexes'] as $iIndex)
+                        unset($aEvents[$iIndex]);
+
+                    $aEvents[$iGroupIndex]['owner_id'] = $aOwnerIds;
+                    break;
+            }
+        }
+
+        $bFirst = true;
+        foreach($aEvents as $aEvent) {
+            $iEvent = (int)$aEvent['id'];
+
+            $sEvent = $this->getPost($aEvent, $aParams);
+            if(empty($sEvent))
+                continue;
+
+            if($bViewTimeline && $bFirst) {
+                $sContent .= $this->getDividerToday($aEvent);
+                $bFirst = false;
+            }
+
+            $sContent .= $bViewTimeline ? $this->getDivider($iDays, $aEvent) : '';
+            $sContent .= $sEvent;
+        }
+
+        $sBack = $this->getBack($aParams);
+        $sLoadMore = $this->getLoadMore($aParams, $bNext, $iEvents > 0);
+        $sEmpty = $this->getEmpty($iEvents <= 0);
+        return array($sContent, $sLoadMore, $sBack, $sEmpty);
+    }
+
+    public function getEmpty($bVisible)
+    {
+        return $this->parseHtmlByName('empty.html', array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'visible' => $bVisible ? 'block' : 'none',
+            'content' => MsgBox(_t('_bx_timeline_txt_msg_no_results'))
+        ));
+    }
+
+    public function getDivider(&$iDays, &$aEvent)
+    {
+        if(!$this->_bShowTimelineDividers || $iDays == $aEvent['days'])
+            return '';
+
+        $iDays = $aEvent['days'];
+        $iDaysAgo = (int)$aEvent['ago_days'];
+        if($aEvent['today'] == $aEvent['days'] || (($aEvent['today'] - $aEvent['days']) == 1 && $iDaysAgo == 0))
+            return '';
+
+        return $this->parseHtmlByName('divider.html', array(
+        	'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'type' => 'common',
+            'bx_if:show_hidden' => array(
+                'condition' => false,
+                'content' => array()
+            ),
+            'content' => bx_time_js($aEvent['date'])
+        ));
+    }
+
+    public function getDividerToday($aEvent = array())
+    {
+        if(!$this->_bShowTimelineDividers)
+            return '';
+
+    	$bToday = !empty($aEvent) && ($aEvent['today'] == $aEvent['days'] || (($aEvent['today'] - $aEvent['days']) == 1 && (int)$aEvent['ago_days'] == 0));
+
+        return $this->parseHtmlByName('divider.html', array(
+        	'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'type' => 'today',
+        	'bx_if:show_hidden' => array(
+                'condition' => !$bToday,
+                'content' => array()
+            ),
+            'content' => _t('_bx_timeline_txt_today')
+        ));
+    }
+
+    public function getSizer($aParams)
+    {
+        if($aParams['view'] != BX_TIMELINE_VIEW_OUTLINE)
+            return '';
+
+        return $this->parseHtmlByName('sizer_' . $aParams['view'] . '.html', array(
+        	'style_prefix' => $this->_oConfig->getPrefix('style')
+        ));
+    }
+
+    public function getBack($aParams)
+    {
+        $iYearSel = (int)$aParams['timeline'];
+        if($iYearSel == 0)
+            return '';
+
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('view');
+
+        $iYearNow = date('Y', time());
+        return $this->parseHtmlByName('back.html', array(
+        	'style_prefix' => $sStylePrefix,
+            'content' => $this->parseLink('javascript:void(0)', _t('_bx_timeline_txt_jump_to_recent'), array(
+                'title' => _t('_bx_timeline_txt_jump_to_n_year', $iYearNow),
+        		'onclick' => 'javascript:' . $sJsObject . '.changeTimeline(this, 0)'
+            ))
+        ));
+    }
+
+    public function getLoadMore($aParams, $bEnabled, $bVisible = true)
+    {
+        $iStart = $aParams['start'];
+        $iPerPage = $aParams['per_page'];
+        $iYearSel = (int)$aParams['timeline'];
+        $iYearMin = $this->_oDb->getMaxDuration($aParams);
+
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('view');
+
+        $sYears = '';
+        if(!empty($iYearMin)) {
+            $iYearMax = date('Y', time()) - 1;
+            for($i = $iYearMax; $i >= $iYearMin; $i--)
+                $sYears .= ($i != $iYearSel ? $this->parseLink('javascript:void(0)', $i, array(
+                    'title' => _t('_bx_timeline_txt_jump_to_n_year', $i),
+                    'onclick' => 'javascript:' . $sJsObject . '.changeTimeline(this, ' . $i . ')'
+                )) : $i) . ', ';
+
+            $sYears = substr($sYears, 0, -2);
+        }
+
+        $aTmplVars = array(
+            'style_prefix' => $sStylePrefix,
+            'visible' => ($aParams['view'] == BX_TIMELINE_VIEW_TIMELINE && $bVisible) || ($aParams['view'] == BX_TIMELINE_VIEW_OUTLINE && $bEnabled && $bVisible) ? 'block' : 'none',
+            'bx_if:is_disabled' => array(
+                'condition' => !$bEnabled,
+                'content' => array()
+            ),
+            'bx_if:show_on_click' => array(
+                'condition' => $bEnabled,
+                'content' => array(
+                    'on_click' => 'javascript:' . $sJsObject . '.changePage(this, ' . ($iStart + $iPerPage) . ', ' . $iPerPage . ')'
+                )
+            ),
+            'bx_if:show_jump_to' => array(
+                'condition' => !empty($sYears),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'years' => $sYears
+                )
+            )
+        );
+        return $this->parseHtmlByName('load_more.html', $aTmplVars);
+    }
+
+    public function getComments($sSystem, $iId, $aBrowseParams = array())
+    {
+        $oModule = $this->getModule();
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $oCmts = $oModule->getCmtsObject($sSystem, $iId);
+        if($oCmts === false)
+            return '';
+
+        $aCmtsBp = array();
+        if(!empty($aBrowseParams['cmts_preload_number']))
+            $aCmtsBp['per_view'] = $aBrowseParams['cmts_preload_number'];
+
+        $aCmtsDp = array(
+            'in_designbox' => false, 
+            'dynamic_mode' => isset($aBrowseParams['dynamic_mode']) && $aBrowseParams['dynamic_mode'] === true
+        );
+        if(!empty($aBrowseParams['cmts_min_post_form']))
+            $aCmtsDp['min_post_form'] = $aBrowseParams['cmts_min_post_form'];
+
+        $aComments = $oCmts->getCommentsBlock($aCmtsBp, $aCmtsDp);
+        return $this->parseHtmlByName('comments.html', array(
+            'style_prefix' => $sStylePrefix,
+            'id' => $iId,
+            'content' => $aComments['content']
+        ));
+    }
+
+    public function getRepostElement($iOwnerId, $sType, $sAction, $iObjectId, $aParams = array())
+    {
+        $aReposted = $this->_oDb->getReposted($sType, $sAction, $iObjectId);
+        if(empty($aReposted) || !is_array($aReposted))
+            return '';
+
+		$oModule = $this->getModule();
+		$bDisabled = $oModule->isAllowedRepost($aReposted) !== true || $this->_oDb->isReposted($aReposted['id'], $iOwnerId, $oModule->getUserId());
+		if($bDisabled && (int)$aReposted['reposts'] == 0)
+            return '';
+
+		$sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sStylePrefixRepost = $sStylePrefix . '-repost-';
+
+        $bDynamicMode = isset($aParams['dynamic_mode']) && $aParams['dynamic_mode'] === true;
+
+        $bShowDoRepostAsButtonSmall = isset($aParams['show_do_repost_as_button_small']) && $aParams['show_do_repost_as_button_small'] == true;
+        $bShowDoRepostAsButton = !$bShowDoRepostAsButtonSmall && isset($aParams['show_do_repost_as_button']) && $aParams['show_do_repost_as_button'] == true;
+
+        $bShowDoRepostImage = isset($aParams['show_do_repost_image']) && $aParams['show_do_repost_image'] == true && !empty($aParams['image_do_repost']);
+        $bShowDoRepostIcon = isset($aParams['show_do_repost_icon']) && $aParams['show_do_repost_icon'] == true && !empty($aParams['icon_do_repost']);
+        $bShowDoRepostText = isset($aParams['show_do_repost_text']) && $aParams['show_do_repost_text'] == true && !empty($aParams['text_do_repost']);
+        $bShowCounter = isset($aParams['show_counter']) && $aParams['show_counter'] === true;
+
+        //--- Do repost link ---//
+		$sClass = $sStylePrefixRepost . 'do-repost';
+		if($bShowDoRepostAsButton)
+			$sClass .= ' bx-btn';
+		else if($bShowDoRepostAsButtonSmall)
+			$sClass .= ' bx-btn bx-btn-small';
+
+                $sOnClick = '';
+                if(!$bDisabled) {
+                    $sCommonPrefix = $this->_oConfig->getPrefix('common_post');
+                    if(str_replace($sCommonPrefix, '', $sType) == BX_TIMELINE_PARSE_TYPE_REPOST) {
+                        $aRepostedData = unserialize($aReposted['content']);
+
+                        $sOnClick = $this->_getRepostJsClick($iOwnerId, $aRepostedData['type'], $aRepostedData['action'], $aRepostedData['object_id']);
+                    }
+                    else
+                        $sOnClick = $this->_getRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId);
+                }
+                else
+                    $sClass .= $bShowDoRepostAsButton || $bShowDoRepostAsButtonSmall ? ' bx-btn-disabled' : ' ' . $sStylePrefixRepost . 'disabled';
+
+		$aOnClickAttrs = array(
+			'title' => _t('_bx_timeline_txt_do_repost')
+		);
+		if(!empty($sClass))
+			$aOnClickAttrs['class'] = $sClass;
+		if(!empty($sOnClick))
+			$aOnClickAttrs['onclick'] = $sOnClick;
+
+		//--- Do repost label ---//
+		$sMethodDoRepostLabel = ''; 
+		$sTemplateDoRepostLabel = '';
+		if(!empty($aParams['template_do_repost_label'])) {
+			$sMethodDoRepostLabel = 'parseHtmlByContent';
+			$sTemplateDoRepostLabel = $aParams['template_do_repost_label'];
+		}
+		else {
+			$sMethodDoRepostLabel = 'parseHtmlByName';
+			$sTemplateDoRepostLabel = $aParams['template_do_repost_label_name'];
+		}
+
+		$sDoRepost = $this->$sMethodDoRepostLabel($sTemplateDoRepostLabel, array(
+        	'bx_if:show_image' => array(
+        		'condition' => $bShowDoRepostImage,
+        		'content' => array(
+        			'src' => $this->getIconUrl($aParams['image_do_repost'])
+        		)
+        	),
+        	'bx_if:show_icon' => array(
+        		'condition' => $bShowDoRepostIcon,
+        		'content' => array(
+        			'name' => $aParams['icon_do_repost']
+        		)
+        	),
+        	'bx_if:show_text' => array(
+        		'condition' => $bShowDoRepostText,
+        		'content' => array(
+        			'text' => _t($aParams['text_do_repost'])
+        		)
+        	)
+        ));
+
+        return $this->parseHtmlByName('repost_element_block.html', array(
+            'style_prefix' => $sStylePrefix,
+            'html_id' => $this->_oConfig->getHtmlIds('repost', 'main') . $aReposted['id'],
+            'class' => ($bShowDoRepostAsButton ? $sStylePrefixRepost . 'button' : '') . ($bShowDoRepostAsButtonSmall ? $sStylePrefixRepost . 'button-small' : ''),
+            'count' => $aReposted['reposts'],
+            'do_repost' => $this->parseLink('javascript:void(0)', $sDoRepost, $aOnClickAttrs),
+            'bx_if:show_counter' => array(
+                'condition' => $bShowCounter,
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+        			'bx_if:show_hidden' => array(
+        				'condition' => (int)$aReposted['reposts'] == 0,
+        				'content' => array()
+        			),
+                    'counter' => $this->getRepostCounter($aReposted, $aParams)
+                )
+            ),
+            'script' => $this->getRepostJsScript($bDynamicMode)
+        ));
+    }
+
+    public function getRepostCounter($aEvent, $aParams = array())
+    {
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('repost');
+
+        $bShowDoRepostAsButtonSmall = isset($aParams['show_do_repost_as_button_small']) && $aParams['show_do_repost_as_button_small'] == true;
+        $bShowDoRepostAsButton = !$bShowDoRepostAsButtonSmall && isset($aParams['show_do_repost_as_button']) && $aParams['show_do_repost_as_button'] == true;
+
+        $sClass = $sStylePrefix . '-repost-counter';
+        if($bShowDoRepostAsButtonSmall)
+            $sClass .= ' bx-btn-small-height';
+        if($bShowDoRepostAsButton)
+            $sClass .= ' bx-btn-height';
+
+        return $this->parseLink('javascript:void(0)', !empty($aEvent['reposts']) && (int)$aEvent['reposts'] > 0 ? $this->getRepostCounterLabel($aEvent['reposts']) : '', array(
+            'id' => $this->_oConfig->getHtmlIds('repost', 'counter') . $aEvent['id'],
+            'class' => $sClass,
+            'title' => _t('_bx_timeline_txt_reposted_by'),
+            'onclick' => 'javascript:' . $sJsObject . '.toggleByPopup(this, ' . $aEvent['id'] . ')'
+        ));
+    }
+
+    public function getRepostCounterLabel($iCount)
+    {
+        return $iCount;
+    }
+
+    public function getRepostedBy($iId)
+    {
+        $aTmplUsers = array();
+        $oModule = $this->getModule();
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $aUserIds = $this->_oDb->getRepostedBy($iId);
+        foreach($aUserIds as $iUserId) {
+            list($sUserName, $sUserUrl, $sUserIcon, $sUserUnit) = $oModule->getUserInfo($iUserId);
+            $aTmplUsers[] = array(
+                'style_prefix' => $sStylePrefix,
+                'user_unit' => $sUserUnit
+            );
+        }
+
+        if(empty($aTmplUsers))
+            $aTmplUsers = MsgBox(_t('_Empty'));
+
+        return $this->parseHtmlByName('repost_by_list.html', array(
+            'style_prefix' => $sStylePrefix,
+            'bx_repeat:list' => $aTmplUsers
+        ));
+    }
+
+    public function getRepostJsScript($bDynamicMode = false)
+    {
+        $sCode = $this->getJsCode('repost', array(), array('mask' => '{object} = new {class}({params});', 'wrap' => false));
+
+        if($bDynamicMode) {
+            $sJsObject = $this->_oConfig->getJsObject('repost');
+
+			$sCode = "var " . $sJsObject . " = null; 
+			$.getScript('" . bx_js_string($this->getJsUrl('main.js'), BX_ESCAPE_STR_APOS) . "', function(data, textStatus, jqxhr) {
+				$.getScript('" . bx_js_string($this->getJsUrl('repost.js'), BX_ESCAPE_STR_APOS) . "', function(data, textStatus, jqxhr) {
+    				bx_get_style('" . bx_js_string($this->getCssUrl('repost.css'), BX_ESCAPE_STR_APOS) . "');
+    				" . $sCode . "
+				});
+        	}); ";
+        }
+        else {
+        	$sCode = "var " . $sCode;
+
+        	$this->addCss(array('repost.css'));
+            $this->addJs(array('main.js', 'repost.js'));
+        }
+
+        return $this->_wrapInTagJsCode($sCode);
+    }
+
+    public function getRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId)
+    {
+        $aReposted = $this->_oDb->getReposted($sType, $sAction, $iObjectId);
+        if(empty($aReposted) || !is_array($aReposted))
+            return '';
+
+        $sResult = '';
+        $sCommonPrefix = $this->_oConfig->getPrefix('common_post');
+        if(str_replace($sCommonPrefix, '', $sType) == BX_TIMELINE_PARSE_TYPE_REPOST) {
+            $aRepostedData = unserialize($aReposted['content']);
+
+            $sResult = $this->_getRepostJsClick($iOwnerId, $aRepostedData['type'], $aRepostedData['action'], $aRepostedData['object_id']);
+        }
+        else
+            $sResult = $this->_getRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId);
+
+        return $sResult;
+    }
+
+    public function getAttachLinkForm()
+    {
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('post');
+
+        $aForm = $this->getModule()->getFormAttachLink();
+
+        return $this->parseHtmlByName('attach_link_form.html', array(
+            'style_prefix' => $sStylePrefix,
+            'js_object' => $sJsObject,
+            'form_id' => $aForm['form_id'],
+            'form' => $aForm['form'],
+        ));
+    }
+
+    public function getAttachLinkField($iUserId)
+    {
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $aLinks = $this->_oDb->getUnusedLinks($iUserId);
+
+        $sLinks = '';
+        foreach($aLinks as $aLink)
+            $sLinks .= $this->getAttachLinkItem($iUserId, $aLink);
+
+        return $this->parseHtmlByName('attach_link_form_field.html', array(
+            'html_id' => $this->_oConfig->getHtmlIds('post', 'attach_link_form_field'),
+            'style_prefix' => $sStylePrefix,
+            'links' => $sLinks
+        ));
+    }
+
+    public function getAttachLinkItem($iUserId, $mixedLink)
+    {
+        $aLink = is_array($mixedLink) ? $mixedLink : $this->_oDb->getUnusedLinks($iUserId, (int)$mixedLink);
+        if(empty($aLink) || !is_array($aLink))
+            return '';
+
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('post');
+        $sLinkIdPrefix = $this->_oConfig->getHtmlIds('post', 'attach_link_item');
+
+        $bTmplVarsEmbed = false;
+        $aTmplVarsEmbed = array();
+        $oEmbed = BxDolEmbed::getObjectInstance();
+        if($oEmbed) {
+            $bTmplVarsEmbed = true;
+            $aTmplVarsEmbed = array(
+                'style_prefix' => $sStylePrefix,
+                'embed' => $oEmbed->getLinkHTML($aLink['url'], $aLink['title'], 300),
+            );
+        }
+        else {
+            $aLinkAttrs = array(
+            	'title' => bx_html_attribute($aLink['title'])
+            );
+            if(!$this->_oConfig->isEqualUrls(BX_DOL_URL_ROOT, $aLink['url'])) {
+                $aLinkAttrs['target'] = '_blank';
+    
+                if($this->_oDb->getParam('sys_add_nofollow') == 'on')
+            	    $aLinkAttrs['rel'] = 'nofollow';
+            }
+
+            $sThumbnail = "";
+            if((int)$aLink['media_id'] != 0)
+                $sThumbnail = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_preview'))->getFileUrl($aLink['media_id']);
+
+            $aTmplVarsEmbed = array(
+                'style_prefix' => $sStylePrefix,
+            	'bx_if:show_thumbnail' => array(
+            		'condition' => !empty($sThumbnail),
+            		'content' => array(
+            			'style_prefix' => $sStylePrefix,
+            			'thumbnail' => $sThumbnail
+            		)
+            	),
+    			'url' => $aLink['url'],
+            	'link' => $this->parseLink($aLink['url'], $aLink['title'], $aLinkAttrs)
+            );
+        }
+
+        return $this->parseHtmlByName('attach_link_item.html', array(
+            'html_id' => $sLinkIdPrefix . $aLink['id'],
+            'style_prefix' => $sStylePrefix,
+            'js_object' => $sJsObject,
+            'id' => $aLink['id'],
+        	'bx_if:show_embed_outer' => array(
+        		'condition' => $bTmplVarsEmbed,
+        		'content' => $aTmplVarsEmbed
+        	),
+        	'bx_if:show_embed_inner' => array(
+        		'condition' => !$bTmplVarsEmbed,
+        		'content' => $aTmplVarsEmbed
+            ),
+        ));
+    }
+
+    public function getData(&$aEvent, $aBrowseParams = array())
+    {
+        $aResult = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $this->_getSystemData($aEvent, $aBrowseParams) : $this->_getCommonData($aEvent, $aBrowseParams);
+        if(empty($aResult) || empty($aResult['owner_id']) || empty($aResult['content']))
+            return false;
+
+        list($sUserName) = $this->getModule()->getUserInfo($aResult['owner_id']);
+
+        $sSample = !empty($aResult['sample']) ? $aResult['sample'] : '_bx_timeline_txt_sample';
+        if(empty($aEvent['title']) || empty($aEvent['description'])) {
+            $sTitle = !empty($aResult['title']) ? $this->_oConfig->getTitle($aResult['title']) : _t($sSample);
+
+            $sDescription = !empty($aResult['description']) ? $aResult['description'] : _t('_bx_timeline_txt_user_added_sample', $sUserName, _t($sSample));
+            if($sDescription == '' && !empty($aResult['content']['text']))
+                $sDescription = $aResult['content']['text'];
+
+            $this->_oDb->updateEvent(array(
+                'title' => bx_process_input(strip_tags($sTitle)),
+                'description' => bx_process_input(strip_tags($sDescription))
+            ), array('id' => $aEvent['id']));
+        }
+
+        return $aResult;
+    }
+
+    public function getVideo($aEvent, $aVideo)
+    {
+        $sVideoId = $this->_oConfig->getHtmlIds('view', 'video') . $aEvent['id'] . '-' . $aVideo['id'];
+        return $this->parseHtmlByName('video_player.html', array(
+            'player' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm'], array('id' => $sVideoId)),
+            'html_id' => $sVideoId
+        ));
+    }
+
+    function getLiveUpdateNotification($sType, $iOwnerId, $iProfileId, $iCountOld = 0, $iCountNew = 0)
+    {
+        $bShowAll = true;
+        $bShowActions = false;
+        $oModule = $this->getModule();
+
+    	$iCount = (int)$iCountNew - (int)$iCountOld;
+    	if($iCount < 0)
+            return '';
+
+        $iCountMax = $this->_oConfig->getLiveUpdateLength();
+        if($iCount > $iCountMax)
+            $iCount = $iCountMax;
+
+        $aParams = $oModule->getParams(BX_TIMELINE_VIEW_DEFAULT, $sType, $iOwnerId, 0, $iCount, BX_TIMELINE_FILTER_OTHER_VIEWER);
+        $aEvents = $this->_oDb->getEvents($aParams);
+        if(empty($aEvents) || !is_array($aEvents))
+            return '';
+
+        $sJsObject = $this->_oConfig->getJsObject('view');
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $iUserId = $oModule->getUserId();
+        $bModerator = $oModule->isModerator();
+
+        $aEvents = array_reverse($aEvents);
+        $iEvents = count($aEvents);
+
+        $aTmplVarsItems = array();
+        foreach($aEvents as $iIndex => $aEvent) {
+            $aData = $this->getData($aEvent);
+            if($aData === false)
+                continue;
+
+            $iEventId = $aEvent['id'];
+            $iEventAuthorId = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? (int)$aEvent['owner_id'] : (int)$aEvent['object_id'];
+            if($iEventAuthorId < 0) {
+                if(abs($iEventAuthorId) == $iUserId)
+                    continue;
+                else if($bModerator)
+                    $iEventAuthorId *= -1;
+            }
+
+            $oAuthor = $oModule->getObjectUser($iEventAuthorId);
+            $sAuthorName = $oAuthor->getDisplayName();
+
+            $aTmplVarsItems[] = array(
+                'bx_if:show_as_hidden' => array(
+                    'condition' => !$bShowAll && $iIndex < ($iEvents - 1),
+                    'content' => array(),
+                ),
+                'item' => $this->parseHtmlByName('live_update_notification.html', array(
+                    'style_prefix' => $sStylePrefix,
+                    'onclick_show' => "javascript:" . $sJsObject . ".goTo(this, 'timeline-event-" . $iEventId . "', '" . $iEventId . "');",
+                    'author_link' => $oAuthor->getUrl(), 
+                    'author_title' => bx_html_attribute($sAuthorName),
+                    'author_name' => $sAuthorName,
+                    'author_unit' => $oAuthor->getUnit(0, array('template' => 'unit_wo_info_links')), 
+                    'text' => _t($aData['sample_action'], _t($aData['sample'])),
+                )),
+                'bx_if:show_previous' => array(
+                    'condition' => $bShowActions && $iIndex > 0,
+                    'content' => array(
+                        'onclick_previous' => $sJsObject . '.previousLiveUpdate(this)'
+                    )
+                ),
+                'bx_if:show_close' => array(
+                    'condition' => $bShowActions,
+                    'content' => array(
+                        'onclick_close' => $sJsObject . '.hideLiveUpdate(this)'
+                    )
+                )
+            );
+        }
+
+        return $this->parseHtmlByName('popup_chain.html', array(
+            'html_id' => $this->_oConfig->getHtmlIds('view', 'live_update_popup') . $sType,
+            'bx_repeat:items' => $aTmplVarsItems
+        ));
+    }
+
+    protected function _getPost($sType, $aEvent, $aBrowseParams = array())
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oModule = $this->getModule();
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('view');
+
+        list($sAuthorName, $sAuthorUrl, $sAuthorIcon, $sAuthorUnit, $sAuthorUnitShort) = $oModule->getUserInfo($aEvent['object_owner_id']);
+        $bAuthorIcon = !empty($sAuthorIcon);
+
+        $aTmplVarsNote = $this->_getTmplVarsNote($aEvent);
+        $aTmplVarsMenuItemActions = $this->_getTmplVarsMenuItemActions($aEvent, $aBrowseParams);
+        $aTmplVarsMenuItemMeta = $this->_getTmplVarsMenuItemMeta($aEvent, $aBrowseParams);
+
+        $aTmplVarsOwnerActions = $this->_getTmplVarsOwnerActions($aEvent);
+        $bTmplVarsOwnerActions = !empty($aTmplVarsOwnerActions); 
+
+        $aTmplVarsTimelineOwner = $this->_getTmplVarsTimelineOwner($aEvent);
+
+        $bViewItem = isset($aBrowseParams['view']) && $aBrowseParams['view'] == BX_TIMELINE_VIEW_ITEM;
+        $bViewOutline = isset($aBrowseParams['view']) && $aBrowseParams['view'] == BX_TIMELINE_VIEW_OUTLINE;
+
+        $bPinned = (int)$aEvent['pinned'] > 0;
+        $bSticked = (int)$aEvent['sticked'] > 0;
+        $bPromoted = (int)$aEvent['promoted'] > 0;
+
+        $sClass = $sStylePrefix . '-view-sizer';
+        if($bViewOutline) {
+            $sClass = $sStylePrefix . '-grid-item-sizer';
+            if($bPinned || $bSticked || $bPromoted) {
+                $sClass .= ' ' . $sStylePrefix . '-gis';
+
+            if($bPinned)
+                $sClass .= '-pnd';
+            if($bSticked)
+                $sClass .= '-psd';
+            if($bPromoted)
+                $sClass .= '-pmd';
+            }
+        }
+        if(!empty($aBrowseParams['blink']) && in_array($aEvent['id'], $aBrowseParams['blink']))
+			$sClass .= ' ' . $sStylePrefix . '-blink';
+        if($bPinned)
+            $sClass .= ' ' . $sStylePrefix . '-pinned';
+        if($bSticked)
+            $sClass .= ' ' . $sStylePrefix . '-sticked';
+        if($bPromoted)
+            $sClass .= ' ' . $sStylePrefix . '-promoted';
+
+        $sClassOwner = $bTmplVarsOwnerActions ? $sStylePrefix . '-io-with-actions' : '';
+
+        $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
+        $sLocation = $oMetatags->locationsString($aEvent['id']);
+ 
+        $aTmplVars = array (
+            'style_prefix' => $sStylePrefix,
+            'js_object' => $sJsObject,
+            'html_id' => $this->_oConfig->getHtmlIds('view', 'item_' . $aBrowseParams['view']) . $aEvent['id'],
+            'class' => $sClass,
+            'class_owner' => $sClassOwner,
+            'class_content' => $bViewItem ? 'bx-def-color-bg-block' : 'bx-def-color-bg-box',
+            'id' => $aEvent['id'],
+            'bx_if:show_note' => array(
+                'condition' => !empty($aTmplVarsNote),
+                'content' => $aTmplVarsNote
+            ),
+            'bx_if:show_owner_icon' => array(
+                'condition' => $bAuthorIcon,
+                'content' => array(
+                    'owner_icon' => $sAuthorIcon
+                )
+            ),
+            'bx_if:show_owner_icon_empty' => array(
+                'condition' => !$bAuthorIcon,
+                'content' => array()
+            ),
+            'bx_if:show_owner_actions' => array(
+                'condition' => $bTmplVarsOwnerActions,
+                'content' => $aTmplVarsOwnerActions
+            ),
+            'item_icon' => !empty($aEvent['icon']) ? $aEvent['icon'] : $CNF['ICON'],
+            'item_owner_url' => $sAuthorUrl,
+            'item_owner_title' => bx_html_attribute($sAuthorName),
+            'item_owner_name' => $sAuthorName,
+            'item_owner_unit' => $sAuthorUnitShort,
+            'item_owner_action' => _t($aEvent['sample_action'], _t($aEvent['sample'])),
+            'bx_if:show_timeline_owner' => array(
+                'condition' => !empty($aTmplVarsTimelineOwner),
+                'content' => $aTmplVarsTimelineOwner
+            ),
+            'item_view_url' => $this->_oConfig->getItemViewUrl($aEvent),
+            'item_date' => bx_time_js($aEvent['date']),
+            'bx_if:show_pinned' => array(
+            	'condition' => $bPinned,
+            	'content' => array(
+                    'style_prefix' => $sStylePrefix,
+            	)
+            ),
+            'bx_if:show_sticked' => array(
+            	'condition' => $bSticked,
+            	'content' => array(
+                    'style_prefix' => $sStylePrefix,
+            	)
+            ),
+            'bx_if:show_hot' => array(
+            	'condition' => isset($aBrowseParams['hot']) && is_array($aBrowseParams['hot']) && in_array($aEvent['id'], $aBrowseParams['hot']),
+            	'content' => array(
+                    'style_prefix' => $sStylePrefix,
+            	)
+            ),
+            'content' => is_string($aEvent['content']) ? $aEvent['content'] : $this->_getContent($sType, $aEvent, $aBrowseParams),
+            'bx_if:show_location' => array(
+            	'condition' => !empty($sLocation),
+            	'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'location' => $sLocation
+            	)
+            ),
+            'bx_if:show_menu_item_actions' => array(
+                'condition' => !empty($aTmplVarsMenuItemActions),
+                'content' => $aTmplVarsMenuItemActions
+            ),
+            'bx_if:show_menu_item_meta' => array(
+                'condition' => !empty($aTmplVarsMenuItemMeta),
+                'content' => $aTmplVarsMenuItemMeta
+            ),
+            'comments' => '',
+        );
+
+        $iPreloadComments = $this->_oConfig->getPreloadComments();
+        if($iPreloadComments > 0 && in_array($aBrowseParams['view'], array(BX_TIMELINE_VIEW_TIMELINE, BX_TIMELINE_VIEW_OUTLINE)))
+            $aTmplVars['comments'] = $this->_getComments($aEvent['comments'], array_merge($aBrowseParams, array(
+                'cmts_preload_number' => $iPreloadComments,
+                'cmts_min_post_form' => false
+            )));
+
+        $sVariable = '_sTmplContentItem' . bx_gen_method_name($aBrowseParams['view']);
+        if(empty(self::$$sVariable))
+            self::$$sVariable = $this->getHtml('item_' . $aBrowseParams['view'] . '.html');
+
+        return $this->parseHtmlByContent(self::$$sVariable, $aTmplVars);
+    }
+
+    protected function _getContent($sType, $aEvent, $aBrowseParams = array())
+    {
+        $sMethod = '_getTmplVarsContent' . ucfirst($sType);
+        if(!method_exists($this, $sMethod))
+            return '';
+
+        $sVariable = '_sTmplContentType' . bx_gen_method_name($sType);
+        if(empty(self::$$sVariable))
+            self::$$sVariable = $this->getHtml('type_' . $sType . '.html');
+
+		return $this->parseHtmlByContent(self::$$sVariable, $this->$sMethod($aEvent, $aBrowseParams));
+    }
+
+    protected function _getComments($aComments, $aBrowseParams = array())
+    {
+        $mixedComments = $this->getModule()->getCommentsData($aComments);
+        if($mixedComments === false)
+            return '';
+
+        list($sSystem, $iObjectId, $iCount) = $mixedComments;
+        return $this->getComments($sSystem, $iObjectId, $aBrowseParams);
+    }
+
+    protected function _getShowMore($aParams)
+    {
+        return $this->parseHtmlByName('show_more.html', array(
+        	'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'js_object' => $this->_oConfig->getJsObject('view'),
+        ));
+    }
+
+    protected function _getImagePopup($aParams)
+    {
+        $sViewImagePopupId = $this->_oConfig->getHtmlIds('view', 'photo_popup_' . $aParams['view']);
+        $sViewImagePopupContent = $this->parseHtmlByName('popup_image.html', array(
+    		'image_url' => ''
+    	));
+
+    	return BxTemplFunctions::getInstance()->transBox($sViewImagePopupId, $sViewImagePopupContent, true);
+    }
+
+    protected function _getRepostJsClick($iOwnerId, $sType, $sAction, $iObjectId)
+    {
+        $sJsObject = $this->_oConfig->getJsObject('repost');
+        $sFormat = "%s.repostItem(this, %d, '%s', '%s', %d);";
+
+        $iOwnerId = !empty($iOwnerId) ? (int)$iOwnerId : $this->getModule()->getUserId(); //--- in whose timeline the content will be reposted
+        return sprintf($sFormat, $sJsObject, $iOwnerId, $sType, $sAction, (int)$iObjectId);
+    }
+
+    protected function _getTmplVarsMenuItemActions(&$aEvent, $aBrowseParams = array())
+    {
+        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_actions'));
+        $oMenu->setEvent($aEvent);
+        $oMenu->setBrowseParams($aBrowseParams['type'], $aBrowseParams['view']);
+        $oMenu->setDynamicMode(isset($aBrowseParams['dynamic_mode']) && $aBrowseParams['dynamic_mode'] === true);
+
+        $sMenu = $oMenu->getCode();
+        if(empty($sMenu))
+            return array();
+
+        return array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'js_object' => $this->_oConfig->getJsObject('view'),
+            'menu_item_actions' => $sMenu
+        );
+    }
+
+    protected function _getTmplVarsMenuItemMeta(&$aEvent, $aBrowseParams = array())
+    {
+        $oMenu = BxDolMenu::getObjectInstance($this->_oConfig->getObject('menu_item_meta'));
+        $oMenu->setEvent($aEvent);
+
+        $sMenu = $oMenu->getCode();
+        if(empty($sMenu))
+            return array();
+
+        return array(
+            'style_prefix' => $this->_oConfig->getPrefix('style'),
+            'meta' => $sMenu
+        );
+    }
+
+    protected function _getTmplVarsTimelineOwner(&$aEvent)
+    {
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $iUser = bx_get_logged_profile_id();
+        $oModule = $this->getModule();
+
+        $sConnection = $this->_oConfig->getObject('conn_subscriptions');
+        $oConnection = BxDolConnection::getObjectInstance($sConnection);
+        $sConnectionTitle = _t('_sys_menu_item_title_sm_subscribe');
+
+        $aOwnerIds = is_array($aEvent['owner_id']) ? $aEvent['owner_id'] : array($aEvent['owner_id']);
+
+        $aTmplVarsOwners = array();
+        foreach($aOwnerIds as $iOwnerId) {
+            $iOwnerId = (int)$iOwnerId;
+            $iObjectOwner = (int)$aEvent['object_owner_id'];
+            if($iObjectOwner < 0 && abs($iObjectOwner) == $iUser)
+                $iObjectOwner *= -1;
+
+            if($iOwnerId == 0 || $iOwnerId == $iObjectOwner)
+                continue;
+
+            list($sToName, $sToUrl, $sToThumb, $sToUnit, $sToUnitWoInfo) = $oModule->getUserInfo($iOwnerId);
+            $sToType = $oModule->getObjectUser($iOwnerId)->getModule();
+
+            $aTmplVarsActions = array();
+            if(!empty($iUser) && $iUser != $iOwnerId && $oConnection->checkAllowedConnect($iUser, $iOwnerId) === CHECK_ACTION_RESULT_ALLOWED) {
+                $aTmplVarsActions[] = array(
+                    'href' => "javascript:void(0)",
+                    'onclick' => "bx_conn_action(this, '" . $sConnection . "', 'add', '" . $iOwnerId . "')",
+                    'title' => bx_html_attribute($sConnectionTitle),
+                    'content' => $sConnectionTitle,
+                    'icon' => 'check'
+                );
+            }
+
+            $aTmplVarsOwners[] =  array(
+                'style_prefix' => $sStylePrefix,
+                'owner_type' => _t('_' . $sToType),
+                'owner_url' => $sToUrl,
+                'owner_username' => $sToName,
+                'owner_thumb' => $sToThumb,
+                'owner_unit' => $sToUnit,
+                'owner_unit_wo_info' => $sToUnitWoInfo,
+                'bx_if:show_timeline_owner_actions' => array(
+                    'condition' => !empty($aTmplVarsActions),
+                    'content' => array(
+                        'style_prefix' => $sStylePrefix,
+                        'bx_repeat:timeline_owner_actions' => $aTmplVarsActions
+                    )
+                )
+            );
+        }
+
+        if(empty($aTmplVarsOwners))
+            return array();
+
+        return array(
+            'style_prefix' => $sStylePrefix,
+            'bx_repeat:owners' => $aTmplVarsOwners
+        );
+    }
+
+    protected function _getTmplVarsContentPost(&$aEvent, $aBrowseParams = array())
+    {
+    	$aContent = &$aEvent['content'];
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+        $sJsObject = $this->_oConfig->getJsObject('view');
+
+        $bViewItem = isset($aBrowseParams['view']) && $aBrowseParams['view'] == BX_TIMELINE_VIEW_ITEM;
+
+        //--- Process Raw ---//
+        $sRaw = isset($aContent['raw']) ? $aContent['raw'] : '';
+
+        //--- Process Text ---//
+        $sUrl = isset($aContent['url']) ? bx_html_attribute($aContent['url']) : '';
+        $sTitle = '';
+        if(isset($aContent['title']))
+            $sTitle = bx_process_output($aContent['title']);
+
+        if(!empty($sUrl) && !empty($sTitle))
+            $sTitle = $this->parseLink($sUrl, $sTitle, array(
+            	'class' => $sStylePrefix . '-title',
+                'title' => $sTitle
+            ));
+
+        $sText = isset($aContent['text']) ? $aContent['text'] : '';
+        $sText = $this->_prepareTextForOutput($sText, $aEvent['id']);
+
+        //--- Process Links ---//
+        $bAddNofollow = $this->_oDb->getParam('sys_add_nofollow') == 'on';
+
+        $aTmplVarsLinks = array();
+        if(!empty($aContent['links']))
+            foreach($aContent['links'] as $aLink) {
+                $bTmplVarsEmbed = false;
+                $aTmplVarsEmbed = array();
+                $oEmbed = BxDolEmbed::getObjectInstance();
+                if ($oEmbed) {
+                    $bTmplVarsEmbed = true;
+                    $aTmplVarsEmbed = array(
+                        'style_prefix' => $sStylePrefix,
+                        'embed' => $oEmbed->getLinkHTML($aLink['url'], $aLink['title']),
+                    );
+                }
+                else {
+                    $aLinkAttrs = array(
+                    	'title' => $aLink['title']
+                    );
+                    if(!$this->_oConfig->isEqualUrls(BX_DOL_URL_ROOT, $aLink['url'])) {
+                        $aLinkAttrs['target'] = '_blank';
+    
+                        if($bAddNofollow)
+                    	    $aLinkAttrs['rel'] = 'nofollow';
+                    }
+
+                    $sLinkAttrs = '';
+                    foreach($aLinkAttrs as $sKey => $sValue)
+                        $sLinkAttrs .= ' ' . $sKey . '="' . bx_html_attribute($sValue) . '"';
+            
+                    $aTmplVarsEmbed = array(
+                        'bx_if:show_thumbnail' => array(
+                    		'condition' => !empty($aLink['thumbnail']),
+                    		'content' => array(
+                    			'style_prefix' => $sStylePrefix,
+                    			'thumbnail' => $aLink['thumbnail'],
+                                'link' => !empty($aLink['url']) ? $aLink['url'] : 'javascript:void(0)',
+                                'attrs' => $sLinkAttrs
+                    		)
+                    	),
+                    	'link' => !empty($aLink['url']) ? $aLink['url'] : 'javascript:void(0)',
+                    	'attrs' => $sLinkAttrs,
+                    	'content' => $aLink['title'],
+                        'bx_if:show_text' => array(
+                            'condition' => !empty($aLink['text']),
+                            'content' => array(
+                                'style_prefix' => $sStylePrefix,
+                                'text' => $aLink['text']
+                            )
+                        )
+                    );
+                }
+
+                $aTmplVarsLinks[] = array(
+                    'style_prefix' => $sStylePrefix,
+                    'bx_if:show_embed_outer' => array(
+                		'condition' => $bTmplVarsEmbed,
+                		'content' => $aTmplVarsEmbed
+                	),
+                	'bx_if:show_embed_inner' => array(
+                		'condition' => !$bTmplVarsEmbed,
+                		'content' => $aTmplVarsEmbed
+                    )
+                );
+            }
+
+        //--- Process Photos ---//
+        $sImagesDisplay = '';
+        $aTmplVarsImages = array();
+        if(!empty($aContent['images'])) {
+            $sImageSrcKey = '';
+            $sImageSrcKeyDefault = 'src';
+            if(count($aContent['images']) == 1) {
+                $sImagesDisplay = 'single';
+                $sImageSrcKey = $bViewItem ? 'src_orig' : 'src_medium';
+            }
+            else {
+                $sImagesDisplay = 'gallery';
+                $sImageSrcKey = 'src';
+            }
+
+            foreach($aContent['images'] as $aImage) {
+                $sImageSrc = !empty($aImage[$sImageSrcKey]) ? $aImage[$sImageSrcKey] : $aImage[$sImageSrcKeyDefault];
+                if(empty($sImageSrc))
+                    continue;
+
+                $sImage = $this->parseImage($sImageSrc, array(
+                	'class' => $sStylePrefix . '-item-image'
+                ));
+
+                $aAttrs = array();
+                if(isset($aImage['onclick']))
+                    $aAttrs['onclick'] = $aImage['onclick'];
+                else if(!$bViewItem && !empty($aImage['src_orig']))
+                    $aAttrs['onclick'] = 'return ' . $sJsObject . '.showItem(this, \'' . $aEvent['id'] . '\', \'photo\', ' . json_encode(array('src' => base64_encode($aImage['src_orig']))) . ')'; 
+
+                $sImage = $this->parseLink(isset($aImage['url']) ? $aImage['url'] : 'javascript:void(0)', $sImage, $aAttrs);
+
+                $aTmplVarsImages[] = array(
+                    'style_prefix' => $sStylePrefix,
+                    'image' => $sImage
+                );
+            }
+
+            //--- Add Meta Image when Item is viewed on a separate page ---//
+            if($bViewItem && !empty($aContent['images'][0]['src']))
+                BxDolTemplate::getInstance()->addPageMetaImage($aContent['images'][0]['src']);
+        }
+
+    	//--- Process Videos ---//
+    	$sVap = $this->_oConfig->getVideosAutoplay();
+    	$sVapId = $this->_oConfig->getHtmlIds('view', 'video_iframe') . $aEvent['id'] . '-';
+    	$sVapSrc = BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'video/' . $aEvent['id'] . '/';
+
+        $aTmplVarsVideos = array();
+        if(!empty($aContent['videos']))
+            foreach($aContent['videos'] as $iVideo => $aVideo)
+                if($sVap == BX_TIMELINE_VAP_OFF)
+                    $aTmplVarsVideos[] = array(
+                        'style_prefix' => $sStylePrefix,
+                    	'video' => BxTemplFunctions::getInstance()->videoPlayer($aVideo['src_poster'], $aVideo['src_mp4'], $aVideo['src_webm']) 
+                    );
+                else 
+                    $aTmplVarsVideos[] = array(
+                        'style_prefix' => $sStylePrefix,
+                    	'video' => $this->parseHtmlByName('video_iframe.html', array(
+                    		'style_prefix' => $sStylePrefix,
+                            'html_id' => $sVapId . $iVideo,
+                            'src' => $sVapSrc . $iVideo . '/'
+                        )) 
+                    );
+
+        return array(
+            'style_prefix' => $sStylePrefix,
+            'bx_if:show_title' => array(
+                'condition' => !empty($sTitle),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'title' => $sTitle,
+                )
+            ),
+            'bx_if:show_content' => array(
+                'condition' => !empty($sText),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'item_content' => $sText
+                )
+            ),
+            'bx_if:show_content_raw' => array(
+                'condition' => !empty($sRaw),
+                'content' => array(
+                    'item_content_raw' => $sRaw
+                )
+            ),
+            'bx_if:show_links' => array(
+                'condition' => !empty($aTmplVarsLinks),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'bx_repeat:links' => $aTmplVarsLinks
+                )
+            ),
+            'bx_if:show_images' => array(
+                'condition' => !empty($aTmplVarsImages),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+            		'images_display' => $sImagesDisplay,
+                    'bx_repeat:images' => $aTmplVarsImages
+                )
+            ),
+            'bx_if:show_videos' => array(
+                'condition' => !empty($aTmplVarsVideos),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'bx_repeat:videos' => $aTmplVarsVideos
+                )
+            )
+        );
+    }
+
+    protected function _getTmplVarsContentRepost(&$aEvent, $aBrowseParams = array())
+    {
+    	$aContent = &$aEvent['content'];
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $sOwnerLink = $this->parseLink($aContent['owner_url'], $aContent['owner_name']);
+
+        $sSample = _t($aContent['sample']);
+        $sSampleLink = empty($aContent['url']) ? $sSample : $this->parseLink($aContent['url'], $sSample);
+
+        $sTitle = _t('_bx_timeline_txt_reposted', $sOwnerLink, $sSampleLink);
+        $sText = $this->_getContent($aContent['parse_type'], $aEvent);
+
+        return array(
+            'bx_if:show_title' => array(
+                'condition' => !empty($sTitle),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'title' => $sTitle,
+                )
+            ),
+            'bx_if:show_content' => array(
+                'condition' => !empty($sText),
+                'content' => array(
+                    'style_prefix' => $sStylePrefix,
+                    'content' => $sText,
+                )
+            )
+        );
+    }
+
+    protected function _getTmplVarsNote(&$aEvent)
+    {
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $iUser = bx_get_logged_profile_id();
+        $iOwner = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $aEvent['owner_id'] : $aEvent['object_id'];
+
+        $aTmplVars = array();
+        if(!empty($aEvent['promoted'])) {
+            $sConnection = $this->_oConfig->getObject('conn_subscriptions');
+            $oConnection = BxDolConnection::getObjectInstance($sConnection);
+            if(!$oConnection->isConnected($iUser, $iOwner))
+                $aTmplVars = array(
+                    'style_prefix' => $sStylePrefix,
+                    'bx_if:show_note_color' => array(
+                        'condition' => false,
+                        'content' => array(
+                            'item_note_color' => 'red1',
+                        )
+                    ),
+                    'item_note' => _t('_bx_timeline_txt_promoted')
+                );
+        }
+
+        return $aTmplVars;
+    }
+
+    protected function _getTmplVarsOwnerActions(&$aEvent)
+    {
+        $sStylePrefix = $this->_oConfig->getPrefix('style');
+
+        $iUser = bx_get_logged_profile_id();
+        $iOwner = $this->_oConfig->isSystem($aEvent['type'], $aEvent['action']) ? $aEvent['object_owner_id'] : $aEvent['object_id'];
+
+        $aTmplVarsActions = array();
+        if(!empty($iUser) && !empty($iOwner) && $iUser != $iOwner) {
+            $sConnection = $this->_oConfig->getObject('conn_subscriptions');
+            if(BxDolConnection::getObjectInstance($sConnection)->checkAllowedConnect($iUser, $iOwner) === CHECK_ACTION_RESULT_ALLOWED) {
+                $sContent = _t('_sys_menu_item_title_sm_subscribe');
+                $aTmplVarsActions[] = array(
+                    'href' => "javascript:void(0)",
+                    'onclick' => "bx_conn_action(this, '" . $sConnection . "', 'add', '" . $iOwner . "')",
+                	'title' => bx_html_attribute($sContent),
+                    'content' => $sContent,
+                    'icon' => 'check'
+                );
+            }
+        }
+
+        return array(
+            'style_prefix' => $sStylePrefix,
+            'bx_repeat:owner_actions' => $aTmplVarsActions
+        );
+    }
+
+    protected function _getSystemData(&$aEvent, $aBrowseParams = array())
+    {
+        $mixedResult = $this->_oConfig->getSystemData($aEvent, $aBrowseParams);
+        if($mixedResult === false) {
+            $sMethod = 'display' . bx_gen_method_name($aEvent['type'] . '_' . $aEvent['action']);
+            if(method_exists($this, $sMethod))
+                $mixedResult = $this->$sMethod($aEvent);
+        }
+
+        if($mixedResult === false)
+            return '';
+
+        $this->_preparetDataActions($aEvent, $mixedResult);
+        return $mixedResult;
+    }
+
+    protected function _getCommonData(&$aEvent, $aBrowseParams = array())
+    {
+        $CNF = $this->_oConfig->CNF;
+
+        $oModule = $this->getModule();
+        $sJsObject = $this->_oConfig->getJsObject('view');
+        $sPrefix = $this->_oConfig->getPrefix('common_post');
+        $sType = str_replace($sPrefix, '', $aEvent['type']);
+
+        $oOwner = BxDolProfile::getInstanceMagic($aEvent['object_id']);
+
+        $aResult = array(
+            'owner_id' => $aEvent['object_id'],
+            'icon' => $CNF['ICON'],
+            'sample' => '_bx_timeline_txt_sample_with_article',
+            'sample_wo_article' => '_bx_timeline_txt_sample',
+            'sample_action' => '_bx_timeline_txt_added_sample',
+            'content_type' => $sType,
+            'content' => array(
+                'sample' => '_bx_timeline_txt_sample_with_article',
+                'sample_wo_article' => '_bx_timeline_txt_sample',
+                'sample_action' => '_bx_timeline_txt_added_sample',
+                'url' => $this->_oConfig->getItemViewUrl($aEvent)
+            ), //a string to display or array to parse default template before displaying.
+            'views' => '',
+            'votes' => '',
+            'scores' => '',
+            'reports' => '',
+            'comments' => '',
+            'title' => $aEvent['title'], //may be empty.
+            'description' => bx_replace_markers($aEvent['description'], array(
+                'profile_name' => $oOwner->getDisplayName()
+            )) //may be empty.
+        );
+
+        switch($sType) {
+            case BX_TIMELINE_PARSE_TYPE_POST:
+                if(!empty($aEvent['content']))
+                    $aResult['content'] = array_merge($aResult['content'], unserialize($aEvent['content']));
+
+                $aLinks = $this->_oDb->getLinks($aEvent['id']);
+                if(!empty($aLinks) && is_array($aLinks))
+                	$oTranscoder = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_preview'));
+
+                    foreach($aLinks as $aLink)
+                        $aResult['content']['links'][] = array(
+                            'url' => $aLink['url'],
+                            'title' => $aLink['title'],
+                            'text' => $aLink['text'],
+                        	'thumbnail' => (int)$aLink['media_id'] != 0 ? $oTranscoder->getFileUrl($aLink['media_id']) : ''
+                        );
+
+                $aPhotos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_PHOTO, $aEvent['id']);
+                if(!empty($aPhotos) && is_array($aPhotos)) {
+                    $oTranscoder = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_view'));
+                    $oTranscoderMedium = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_medium'));
+                    $oTranscoderBig = BxDolTranscoderImage::getObjectInstance($this->_oConfig->getObject('transcoder_photos_big'));
+
+                    foreach($aPhotos as $iPhotoId) {
+                        $sPhotoSrc = $oTranscoder->getFileUrl($iPhotoId);
+                        $sPhotoSrcMedium = $oTranscoderMedium->getFileUrl($iPhotoId);
+                        $sPhotoSrcBig = $oTranscoderBig->getFileUrl($iPhotoId);
+                        if(empty($sPhotoSrcMedium) && !empty($sPhotoSrc))
+                            $sPhotoSrcMedium = $sPhotoSrc;
+                        if(empty($sPhotoSrcBig) && !empty($sPhotoSrcMedium))
+                            $sPhotoSrcBig = $sPhotoSrcMedium;
+
+                        $aResult['content']['images'][] = array(
+                            'src' => $sPhotoSrc,
+                        	'src_medium' => $sPhotoSrcMedium,
+                            'src_orig' => $sPhotoSrcBig,
+                        );
+                    }
+                }
+
+                $aVideos = $this->_oDb->getMedia(BX_TIMELINE_MEDIA_VIDEO, $aEvent['id']);
+                if(!empty($aVideos) && is_array($aVideos)) {
+                    $oTranscoderPoster = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_poster'));
+                    $oTranscoderMp4 = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_mp4'));
+                    $oTranscoderWebm = BxDolTranscoderVideo::getObjectInstance($this->_oConfig->getObject('transcoder_videos_webm'));
+
+                    foreach($aVideos as $iVideoId) {
+                        $aResult['content']['videos'][$iVideoId] = array(
+                            'id' => $iVideoId,
+                            'src_poster' => $oTranscoderPoster->getFileUrl($iVideoId),
+                        	'src_mp4' => $oTranscoderMp4->getFileUrl($iVideoId),
+                        	'src_webm' => $oTranscoderWebm->getFileUrl($iVideoId),
+                        );
+                    }
+                }
+                break;
+
+            case BX_TIMELINE_PARSE_TYPE_REPOST:
+                if(empty($aEvent['content']))
+                    return array();
+
+                $aContent = unserialize($aEvent['content']);
+
+                if(!$this->_oConfig->isSystem($aContent['type'] , $aContent['action'])) {
+                    $aReposted = $this->_oDb->getEvents(array('browse' => 'id', 'value' => $aContent['object_id']));
+                    $aReposted = $this->_getCommonData($aReposted, $aBrowseParams);
+                } 
+                else {
+                    $aReposted = $this->_oDb->getEvents(array_merge(array('browse' => 'descriptor'), $aContent));
+                    $aReposted = $this->_getSystemData($aReposted, $aBrowseParams);
+                }
+
+                if(empty($aReposted) || !is_array($aReposted))
+                    return array();
+
+                $aResult['content'] = array_merge($aContent, $aReposted['content']);
+                $aResult['content']['parse_type'] = !empty($aReposted['content_type']) ? $aReposted['content_type'] : BX_TIMELINE_PARSE_TYPE_DEFAULT;
+                $aResult['content']['owner_id'] = $aReposted['owner_id'];
+                list($aResult['content']['owner_name'], $aResult['content']['owner_url']) = $oModule->getUserInfo($aReposted['owner_id']);
+
+                if(!empty($aReposted['sample']))
+                    $aResult['content']['sample'] = $aReposted['sample'];
+                if(!empty($aReposted['sample_wo_article']))
+                    $aResult['content']['sample'] = $aReposted['sample_wo_article'];
+
+                list($sUserName) = $oModule->getUserInfo($aEvent['object_id']);
+                $aResult['title'] = _t('_bx_timeline_txt_user_repost', $sUserName, _t($aResult['content']['sample']));
+                $aResult['description'] = _t('_bx_timeline_txt_user_reposted_user_sample', $sUserName, $aResult['content']['owner_name'], _t($aResult['content']['sample']));
+                break;
+        }
+
+        $this->_preparetDataActions($aEvent, $aResult);
+        return $aResult;
+    }
+
+    protected function _preparetDataActions(&$aEvent, &$aResult)
+    {
+        if(empty($aEvent) || !is_array($aEvent) || empty($aEvent['id']))
+            return;
+
+        $oModule = $this->getModule();
+
+        $sSystem = $this->_oConfig->getObject('view');
+        if(empty($aResult['views']) && $oModule->getViewObject($sSystem, $aEvent['id']) !== false)
+            $aResult['views'] = array(
+                'system' => $sSystem,
+                'object_id' => $aEvent['id'],
+                'count' => $aEvent['views']
+            );
+
+        $sSystem = $this->_oConfig->getObject('vote');
+        if(empty($aResult['votes']) && $oModule->getVoteObject($sSystem, $aEvent['id']) !== false)
+            $aResult['votes'] = array(
+                'system' => $sSystem,
+                'object_id' => $aEvent['id'],
+                'count' => $aEvent['votes']
+            );
+
+        $sSystem = $this->_oConfig->getObject('score');
+        if(empty($aResult['scores']) && $oModule->getScoreObject($sSystem, $aEvent['id']) !== false)
+            $aResult['scores'] = array(
+                'system' => $sSystem,
+                'object_id' => $aEvent['id'],
+                'score' => $aEvent['score']
+            );
+
+		$sSystem = $this->_oConfig->getObject('report');
+        if(empty($aResult['reports']) && $oModule->getReportObject($sSystem, $aEvent['id']) !== false)
+            $aResult['reports'] = array(
+                'system' => $sSystem,
+                'object_id' => $aEvent['id'],
+                'count' => $aEvent['reports']
+            );
+
+        $sSystem = $this->_oConfig->getObject('comment');
+        if(empty($aResult['comments']) && $oModule->getCmtsObject($sSystem, $aEvent['id']) !== false)
+            $aResult['comments'] = array(
+                'system' => $sSystem,
+                'object_id' => $aEvent['id'],
+                'count' => $aEvent['comments']
+            );
+    }
+
+    protected function _prepareTextForOutput($s, $iEventId = 0)
+    {
+    	$s = bx_process_output($s, BX_DATA_HTML);
+
+        $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
+		$s = $oMetatags->metaParse($iEventId, $s);
+
+        return $s;
+    }
+}
+
+/** @} */

+ 135 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/source/install/config.php

@@ -0,0 +1,135 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    Timeline Timeline
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_timeline',
+    'title' => 'Timeline',
+    'note' => 'Timeline module.',
+    'version' => '9.0.13',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.una.io/?section={module_name}',
+
+    'compatible_with' => array(
+        '9.0.0-RC12'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/timeline/',
+    'home_uri' => 'timeline',
+
+    'db_prefix' => 'bx_timeline_',
+    'class_prefix' => 'BxTimeline',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Timeline',
+
+    /**
+     * List of page triggers.
+     */
+    'page_triggers' => array (
+        'trigger_page_profile_view_entry',
+        'trigger_page_group_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_timeline_photos',
+    	'bx_timeline_videos'
+    ),
+
+    /**
+     * Transcoders.
+     */
+    'transcoders' => array(
+    	'bx_timeline_photos_preview',
+    	'bx_timeline_photos_view',
+        'bx_timeline_photos_big',
+    	'bx_timeline_videos_poster',
+    	'bx_timeline_videos_mp4',
+    	'bx_timeline_videos_webm'
+    ),
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+    	'update_relations_for_all' => 1,
+    	'update_relations' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'enable_success' => array(
+    	'process_page_triggers' => 1,
+		'process_menu_triggers' => 1,
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+    'disable' => array (
+        'execute_sql' => 1,
+    	'update_relations_for_all' => 1,
+    	'update_relations' => 1,
+    	'unregister_transcoders' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable_failed' => array (
+    	'register_transcoders' => 1,
+    	'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+
+    /**
+     * Relations Section
+     */
+    'relation_handlers' => array(
+    	'on_install' => '',
+    	'on_uninstall' => 'delete_module_events',
+	    'on_enable' => 'add_handlers',
+	    'on_disable' => 'delete_handlers',
+    ),
+    'relations' => array(
+    	'bx_notifications'
+    )
+);
+
+/** @} */

+ 80 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/source/install/sql/disable.sql

@@ -0,0 +1,80 @@
+-- PAGES & BLOCKS
+DELETE FROM `sys_objects_page` WHERE `module` = 'bx_timeline';
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_timeline' OR `object` IN('bx_timeline_view', 'bx_timeline_view_home', 'bx_timeline_item', 'bx_photos_item_brief');
+
+
+-- MENU
+DELETE FROM `sys_objects_menu` WHERE `module` = 'bx_timeline';
+DELETE FROM `sys_menu_sets` WHERE `module` = 'bx_timeline';
+DELETE FROM `sys_menu_items` WHERE `module` = 'bx_timeline' OR `set_name` IN('bx_timeline_menu_item_share', 'bx_timeline_menu_item_manage', 'bx_timeline_menu_item_actions', 'bx_timeline_menu_item_meta', 'bx_timeline_menu_post_attachments');
+
+
+-- SETTINGS
+SET @iTypeId = (SELECT `ID` FROM `sys_options_types` WHERE `name` = 'bx_timeline' LIMIT 1);
+SET @iCategId = (SELECT `ID` FROM `sys_options_categories` WHERE `type_id` = @iTypeId LIMIT 1);
+DELETE FROM `sys_options` WHERE `category_id` = @iCategId;
+DELETE FROM `sys_options_categories` WHERE `type_id` = @iTypeId;
+DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
+
+
+-- PRIVACY 
+DELETE FROM `sys_objects_privacy` WHERE `module` = 'bx_timeline';
+
+
+-- 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_timeline';
+DELETE FROM `sys_acl_actions` WHERE `Module` = 'bx_timeline';
+
+
+-- ALERTS
+SET @iHandlerId = (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_timeline' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandlerId;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandlerId LIMIT 1;
+
+
+-- COMMENTS
+DELETE FROM `sys_objects_cmts` WHERE `Name` = 'bx_timeline' LIMIT 1;
+
+
+-- VIEWS
+DELETE FROM `sys_objects_view` WHERE `name` = 'bx_timeline' LIMIT 1;
+
+
+-- VOTES
+DELETE FROM `sys_objects_vote` WHERE `Name` = 'bx_timeline' LIMIT 1;
+
+
+-- SCORES
+DELETE FROM `sys_objects_score` WHERE `name` = 'bx_timeline';
+
+
+-- REPORTS
+DELETE FROM `sys_objects_report` WHERE `Name` = 'bx_timeline' LIMIT 1;
+
+
+-- SEARCH
+DELETE FROM `sys_objects_search` WHERE `ObjectName` IN ('bx_timeline', 'bx_timeline_cmts');
+
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_timeline_administration');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_timeline_administration');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_timeline_administration');
+
+-- METATAGS
+DELETE FROM `sys_objects_metatags` WHERE `object` = 'bx_timeline';
+
+
+-- EMAIL TEMPLATES
+DELETE FROM `sys_email_templates` WHERE `Module` = 'bx_timeline';
+
+
+-- CONTENT INFO
+DELETE FROM `sys_objects_content_info` WHERE `name` IN ('bx_timeline', 'bx_timeline_cmts');
+
+
+-- CRON
+DELETE FROM `sys_cron_jobs` WHERE `name` LIKE 'bx_timeline%';
+
+
+-- PRELOADER
+DELETE FROM `sys_preloader` WHERE `module` = 'bx_timeline';

+ 362 - 0
modules/boonex/timeline/updates/9.0.12_9.0.13/source/install/sql/enable.sql

@@ -0,0 +1,362 @@
+-- PAGES & BLOCKS
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_timeline_view', '_bx_timeline_page_title_sys_view', '_bx_timeline_page_title_view', 'bx_timeline', 5, 2147483647, 1, 'timeline-view', 'page.php?i=timeline-view', '', '', '', 0, 1, 0, 'BxTimelinePageView', 'modules/boonex/timeline/classes/BxTimelinePageView.php'),
+('bx_timeline_view_home', '_bx_timeline_page_title_sys_view_home', '_bx_timeline_page_title_view_home', 'bx_timeline', 5, 2147483647, 1, 'timeline-view-home', 'page.php?i=timeline-view-home', '', '', '', 0, 1, 0, '', ''),
+('bx_timeline_view_hot', '_bx_timeline_page_title_sys_view_hot', '_bx_timeline_page_title_view_hot', 'bx_timeline', 5, 2147483647, 1, 'timeline-view-hot', 'page.php?i=timeline-view-hot', '', '', '', 0, 1, 0, '', ''),
+
+('bx_timeline_item', '_bx_timeline_page_title_sys_item', '_bx_timeline_page_title_item', 'bx_timeline', 5, 2147483647, 1, 'item', 'page.php?i=item', '', '', '', 0, 1, 0, '', ''),
+('bx_timeline_item_brief', '_bx_timeline_page_title_sys_item_brief', '_bx_timeline_page_title_item_brief', 'bx_timeline', 2, 2147483647, 1, 'item-quick', 'page.php?i=item-quick', '', '', '', 0, 1, 0, '', '');
+
+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_timeline_view', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_post_profile', '_bx_timeline_page_block_title_post_profile', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:14:"get_block_post";}', 0, 0, 1, 1),
+('bx_timeline_view', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_view_profile', '_bx_timeline_page_block_title_view_profile', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:14:"get_block_view";}', 0, 0, 1, 2),
+('bx_timeline_view', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_view_profile_outline', '_bx_timeline_page_block_title_view_profile_outline', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_view_outline";}', 0, 0, 0, 3),
+
+('bx_timeline_view_home', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_post_home', '_bx_timeline_page_block_title_post_home', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:19:"get_block_post_home";}', 0, 0, 1, 1),
+('bx_timeline_view_home', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_view_home', '_bx_timeline_page_block_title_view_home', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:19:"get_block_view_home";}', 0, 0, 0, 2),
+('bx_timeline_view_home', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_view_home_outline', '_bx_timeline_page_block_title_view_home_outline', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:27:"get_block_view_home_outline";}', 0, 0, 1, 3),
+
+('bx_timeline_view_hot', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_view_hot', '_bx_timeline_page_block_title_view_hot', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:18:"get_block_view_hot";}', 0, 1, 0, 1),
+('bx_timeline_view_hot', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_view_hot_outline', '_bx_timeline_page_block_title_view_hot_outline', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:26:"get_block_view_hot_outline";}', 0, 1, 1, 2),
+
+('bx_timeline_item', 1, 'bx_timeline', '', '_bx_timeline_page_block_title_item', 0, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:14:"get_block_item";}', 0, 0, 1, 1),
+('bx_timeline_item', 1, 'bx_timeline', '', '_bx_timeline_page_block_title_item_comments', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:23:"get_block_item_comments";}', 0, 0, 1, 2),
+
+('bx_timeline_item_brief', 1, 'bx_timeline', '', '_bx_timeline_page_block_title_item_content', 0, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_item_content";}', 0, 0, 1, 1),
+('bx_timeline_item_brief', 2, 'bx_timeline', '', '_bx_timeline_page_block_title_item_info', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:19:"get_block_item_info";}', 0, 0, 1, 1),
+('bx_timeline_item_brief', 2, 'bx_timeline', '', '_bx_timeline_page_block_title_item_comments', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:23:"get_block_item_comments";}', 0, 0, 1, 2);
+
+
+-- PAGES: add page block on dashboard
+SET @iPBCellDashboard = 2;
+SET @iPBOrderDashboard = 1; --(SELECT IFNULL(MAX(`order`), 0) FROM `sys_pages_blocks` WHERE `object` = 'sys_dashboard' AND `cell_id` = @iPBCellDashboard LIMIT 1);
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('sys_dashboard', @iPBCellDashboard, 'bx_timeline', '_bx_timeline_page_block_title_system_post_account', '_bx_timeline_page_block_title_post_account', 11, 2147483644, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_post_account";}', 0, 1, 1, @iPBOrderDashboard),
+('sys_dashboard', @iPBCellDashboard, 'bx_timeline', '_bx_timeline_page_block_title_system_view_account', '_bx_timeline_page_block_title_view_account', 11, 2147483644, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_view_account";}', 0, 1, 1, @iPBOrderDashboard + 1),
+('sys_dashboard', @iPBCellDashboard, 'bx_timeline', '_bx_timeline_page_block_title_system_view_account_outline', '_bx_timeline_page_block_title_view_account_outline', 11, 2147483644, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:30:"get_block_view_account_outline";}', 0, 1, 0, @iPBOrderDashboard + 1);
+
+-- PAGES: add page block on home
+SET @iPBCellHome = 1;
+SET @iPBOrderHome = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_pages_blocks` WHERE `object` = 'sys_home' AND `cell_id` = @iPBCellHome 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', @iPBCellHome, 'bx_timeline', '_bx_timeline_page_block_title_system_post_home', '_bx_timeline_page_block_title_post_home', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:19:"get_block_post_home";}', 0, 1, 1, @iPBOrderHome + 1),
+('sys_home', @iPBCellHome, 'bx_timeline', '_bx_timeline_page_block_title_system_view_home', '_bx_timeline_page_block_title_view_home', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:19:"get_block_view_home";}', 0, 1, 0, @iPBOrderHome + 2),
+('sys_home', @iPBCellHome, 'bx_timeline', '_bx_timeline_page_block_title_system_view_home_outline', '_bx_timeline_page_block_title_view_home_outline', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:27:"get_block_view_home_outline";}', 0, 1, 1, @iPBOrderHome + 3);
+
+-- PAGES: add page block to profiles modules (trigger* page objects are processed separately upon modules enable/disable)
+SET @iPBCellProfile = 2;
+SET @iPBCellGroup = 4;
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_timeline', '_bx_timeline_page_block_title_system_post_profile', '_bx_timeline_page_block_title_post_profile', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_post_profile";s:6:"params";a:1:{i:0;s:6:"{type}";}}', 0, 0, 1, 0),
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_timeline', '_bx_timeline_page_block_title_system_view_profile', '_bx_timeline_page_block_title_view_profile', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_view_profile";s:6:"params";a:1:{i:0;s:6:"{type}";}}', 0, 0, 1, 0),
+('trigger_page_profile_view_entry', @iPBCellProfile, 'bx_timeline', '_bx_timeline_page_block_title_system_view_profile_outline', '_bx_timeline_page_block_title_view_profile_outline', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:30:"get_block_view_profile_outline";s:6:"params";a:1:{i:0;s:6:"{type}";}}', 0, 0, 0, 0),
+
+('trigger_page_group_view_entry', @iPBCellGroup, 'bx_timeline', '_bx_timeline_page_block_title_system_post_profile', '_bx_timeline_page_block_title_post_profile', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_post_profile";s:6:"params";a:1:{i:0;s:6:"{type}";}}', 0, 0, 1, 0),
+('trigger_page_group_view_entry', @iPBCellGroup, 'bx_timeline', '_bx_timeline_page_block_title_system_view_profile', '_bx_timeline_page_block_title_view_profile', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:22:"get_block_view_profile";s:6:"params";a:1:{i:0;s:6:"{type}";}}', 0, 0, 1, 0),
+('trigger_page_group_view_entry', @iPBCellGroup, 'bx_timeline', '_bx_timeline_page_block_title_system_view_profile_outline', '_bx_timeline_page_block_title_view_profile_outline', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:30:"get_block_view_profile_outline";s:6:"params";a:1:{i:0;s:6:"{type}";}}', 0, 0, 0, 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_timeline_administration', '_bx_timeline_page_title_sys_manage_administration', '_bx_timeline_page_title_manage', 'bx_timeline', 5, 192, 1, 'timeline-administration', 'page.php?i=timeline-administration', '', '', '', 0, 1, 0, 'BxTimelinePageBrowse', 'modules/boonex/timeline/classes/BxTimelinePageBrowse.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_timeline_administration', 1, 'bx_timeline', '_bx_timeline_page_block_title_system_manage_administration', '_bx_timeline_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:11:\"bx_timeline\";s:6:\"method\";s:12:\"manage_tools\";s:6:\"params\";a:1:{i:0;s:14:\"administration\";}}', 0, 1, 0);
+
+
+-- MENU: Item Share (Repost, Send to Friend, etc)
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_timeline_menu_item_share', '_bx_timeline_menu_title_item_share', 'bx_timeline_menu_item_share', 'bx_timeline', 6, 0, 1, 'BxTimelineMenuItemShare', 'modules/boonex/timeline/classes/BxTimelineMenuItemShare.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_timeline_menu_item_share', 'bx_timeline', '_bx_timeline_menu_set_title_item_share', 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_timeline_menu_item_share', 'bx_timeline', 'item-repost', '_bx_timeline_menu_item_title_system_item_repost', '_bx_timeline_menu_item_title_item_repost', 'javascript:void(0)', 'javascript:{js_onclick_repost}', '_self', 'repeat', '', 2147483647, 1, 0, 1),
+('bx_timeline_menu_item_share', 'bx_timeline', 'item-send', '_bx_timeline_menu_item_title_system_item_send', '_bx_timeline_menu_item_title_item_send', 'page.php?i=start-convo&et={et_send}', '', '_self', 'envelope', '', 2147483647, 1, 0, 2);
+
+-- MENU: Item Manage (Pin, Delete, etc)
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_timeline_menu_item_manage', '_bx_timeline_menu_title_item_manage', 'bx_timeline_menu_item_manage', 'bx_timeline', 20, 0, 1, 'BxTimelineMenuItemManage', 'modules/boonex/timeline/classes/BxTimelineMenuItemManage.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_timeline_menu_item_manage', 'bx_timeline', '_bx_timeline_menu_set_title_item_manage', 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_timeline_menu_item_manage', 'bx_timeline', 'item-pin', '_bx_timeline_menu_item_title_system_item_pin', '_bx_timeline_menu_item_title_item_pin', 'javascript:void(0)', 'javascript:{js_object_view}.pinPost(this, {content_id}, 1)', '_self', 'thumbtack', '', 2147483647, 1, 0, 0),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-unpin', '_bx_timeline_menu_item_title_system_item_unpin', '_bx_timeline_menu_item_title_item_unpin', 'javascript:void(0)', 'javascript:{js_object_view}.pinPost(this, {content_id}, 0)', '_self', 'thumbtack', '', 2147483647, 1, 0, 1),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-stick', '_bx_timeline_menu_item_title_system_item_stick', '_bx_timeline_menu_item_title_item_stick', 'javascript:void(0)', 'javascript:{js_object_view}.stickPost(this, {content_id}, 1)', '_self', 'thumbtack', '', 2147483647, 1, 0, 2),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-unstick', '_bx_timeline_menu_item_title_system_item_unstick', '_bx_timeline_menu_item_title_item_unstick', 'javascript:void(0)', 'javascript:{js_object_view}.stickPost(this, {content_id}, 0)', '_self', 'thumbtack', '', 2147483647, 1, 0, 3),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-promote', '_bx_timeline_menu_item_title_system_item_promote', '_bx_timeline_menu_item_title_item_promote', 'javascript:void(0)', 'javascript:{js_object_view}.promotePost(this, {content_id}, 1)', '_self', 'certificate ', '', 2147483647, 1, 0, 4),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-unpromote', '_bx_timeline_menu_item_title_system_item_unpromote', '_bx_timeline_menu_item_title_item_unpromote', 'javascript:void(0)', 'javascript:{js_object_view}.promotePost(this, {content_id}, 0)', '_self', 'certificate', '', 2147483647, 1, 0, 5),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-report', '_bx_timeline_menu_item_title_system_item_report', '', 'javascript:void(0)', '', '', '', '', 2147483647, 1, 0, 6),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-edit', '_bx_timeline_menu_item_title_system_item_edit', '_bx_timeline_menu_item_title_item_edit', 'javascript:void(0)', 'javascript:{js_object_view}.editPost(this, {content_id})', '_self', 'pencil-alt', '', 2147483647, 1, 0, 7),
+('bx_timeline_menu_item_manage', 'bx_timeline', 'item-delete', '_bx_timeline_menu_item_title_system_item_delete', '_bx_timeline_menu_item_title_item_delete', 'javascript:void(0)', 'javascript:{js_object_view}.deletePost(this, {content_id})', '_self', 'remove', '', 2147483647, 1, 0, 8);
+
+-- MENU: Item Actions (Comment, Vote, Share, Report, etc)
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_timeline_menu_item_actions', '_bx_timeline_menu_title_item_actions', 'bx_timeline_menu_item_actions', 'bx_timeline', 15, 0, 1, 'BxTimelineMenuItemActions', 'modules/boonex/timeline/classes/BxTimelineMenuItemActions.php');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_timeline_menu_item_actions', 'bx_timeline', '_bx_timeline_menu_set_title_item_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`, `editable`, `order`) VALUES
+('bx_timeline_menu_item_actions', 'bx_timeline', 'item-view', '_bx_timeline_menu_item_title_system_item_view', '', 'javascript:void(0)', '', '', '', '', '', 0, 2147483647, 0, 0, 1, 0),
+('bx_timeline_menu_item_actions', 'bx_timeline', 'item-comment', '_bx_timeline_menu_item_title_system_item_comment', '_bx_timeline_menu_item_title_item_comment', 'javascript:void(0)', 'javascript:{comment_onclick}', '_self', 'comment', 'a:3:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:27:"get_menu_item_addon_comment";s:6:"params";a:3:{i:0;s:16:"{comment_system}";i:1;s:16:"{comment_object}";i:2;s:6:"{view}";}}', '', 0, 2147483647, 1, 0, 1, 1),
+('bx_timeline_menu_item_actions', 'bx_timeline', 'item-vote', '_bx_timeline_menu_item_title_system_item_vote', '', 'javascript:void(0)', '', '', '', '', '', 0, 2147483647, 1, 0, 1, 2),
+('bx_timeline_menu_item_actions', 'bx_timeline', 'item-score', '_bx_timeline_menu_item_title_system_item_score', '', 'javascript:void(0)', '', '', '', '', '', 0, 2147483647, 0, 0, 1, 3),
+('bx_timeline_menu_item_actions', 'bx_timeline', 'item-share', '_bx_timeline_menu_item_title_system_item_share', '_bx_timeline_menu_item_title_item_share', 'javascript:void(0)', 'bx_menu_popup(''bx_timeline_menu_item_share'', this, {''id'':''bx_timeline_menu_item_share_{content_id}''}, {content_id:{content_id}});', '', 'share-alt', '', 'bx_timeline_menu_item_share', 1, 2147483647, 1, 0, 1, 4),
+('bx_timeline_menu_item_actions', 'bx_timeline', 'item-more', '_bx_timeline_menu_item_title_system_item_more', '_bx_timeline_menu_item_title_item_more', 'javascript:void(0)', 'bx_menu_popup(''bx_timeline_menu_item_manage'', this, {''id'':''bx_timeline_menu_item_manage_{content_id}''}, {content_id:{content_id}, type:''{type}'', view:''{view}''});', '', 'ellipsis-h', '', 'bx_timeline_menu_item_manage', 1, 2147483647, 1, 0, 1, 5);
+
+-- MENU: Item Meta Info
+INSERT INTO `sys_objects_menu` (`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
+('bx_timeline_menu_item_meta', '_sys_menu_title_snippet_meta', 'bx_timeline_menu_item_meta', 'bx_timeline', 15, 0, 1, 'BxTimelineMenuSnippetMeta', 'modules/boonex/timeline/classes/BxTimelineMenuSnippetMeta.php');
+
+INSERT INTO `sys_menu_sets` (`set_name`, `module`, `title`, `deletable`) VALUES
+('bx_timeline_menu_item_meta', 'bx_timeline', '_sys_menu_set_title_snippet_meta', 0);
+
+-- comment meta info menu
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `submenu_popup`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_timeline_menu_item_meta', 'bx_timeline', 'date', '_sys_menu_item_title_system_sm_date', '_sys_menu_item_title_sm_date', '', '', '', '', '', '', 0, 2147483647, 1, 0, 1, 1),
+('bx_timeline_menu_item_meta', 'bx_timeline', 'membership', '_sys_menu_item_title_system_sm_membership', '_sys_menu_item_title_sm_membership', '', '', '', '', '', '', 0, 2147483647, 0, 0, 1, 2);
+
+-- MENU: Post form attachments (Link, Photo, Video)
+INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
+('bx_timeline_menu_post_attachments', '_bx_timeline_menu_title_post_attachments', 'bx_timeline_menu_post_attachments', 'bx_timeline', 9, 0, 1, '', '');
+
+INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
+('bx_timeline_menu_post_attachments', 'bx_timeline', '_bx_timeline_menu_set_title_post_attachments', 0);
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `editable`, `order`) VALUES 
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-emoji', '_bx_timeline_menu_item_title_system_add_emoji', '_bx_timeline_menu_item_title_add_emoji', 'javascript:void(0)', '', '_self', 'far smile', '', '', 2147483647, 1, 0, 1, 0),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-link', '_bx_timeline_menu_item_title_system_add_link', '_bx_timeline_menu_item_title_add_link', 'javascript:void(0)', 'javascript:{js_object}.showAttachLink(this);', '_self', 'link', '', '', 2147483647, 1, 0, 1, 1),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-photo', '_bx_timeline_menu_item_title_system_add_photo', '_bx_timeline_menu_item_title_add_photo', 'javascript:void(0)', 'javascript:{js_object_uploader_photo}.showUploaderForm();', '_self', 'camera', '', '', 2147483647, 1, 0, 1, 2),
+('bx_timeline_menu_post_attachments', 'bx_timeline', 'add-video', '_bx_timeline_menu_item_title_system_add_video', '_bx_timeline_menu_item_title_add_video', 'javascript:void(0)', 'javascript:{js_object_uploader_video}.showUploaderForm();', '_self', 'video', '', '', 2147483647, 1, 0, 1, 3);
+
+-- 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_timeline', 'create-item', '_bx_timeline_menu_item_title_system_create_entry', '_bx_timeline_menu_item_title_create_entry', 'page.php?i=timeline-view', '', '', 'far clock col-green1', '', 2147483647, 1, 1, IFNULL(@iAddMenuOrder, 0) + 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_timeline', 'timeline-view', '_bx_timeline_menu_item_title_system_view_timeline_view', '_bx_timeline_menu_item_title_view_timeline_view', 'page.php?i=timeline-view&profile_id={profile_id}', '', '', 'far clock col-green1', '', 2147483647, 1, 0, 0),
+('trigger_group_view_submenu', 'bx_timeline', 'timeline-view', '_bx_timeline_menu_item_title_system_view_timeline_view', '_bx_timeline_menu_item_title_view_timeline_view', 'page.php?i=timeline-view&profile_id={profile_id}', '', '', 'far clock col-green1', '', 2147483647, 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_timeline', 'timeline-administration', '_bx_timeline_menu_item_title_system_admt_timeline', '_bx_timeline_menu_item_title_admt_timeline', 'page.php?i=timeline-administration', '', '_self', '', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 192, 1, 0, @iManageMenuOrder + 1);
+
+-- SETTINGS
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', 'bx_timeline', '_bx_timeline', 'bx_timeline@modules/boonex/timeline/|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_timeline', '_bx_timeline', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_params`, `check_error`, `extra`, `order`) VALUES
+-- View/Browse related settings
+('bx_timeline_enable_edit', 'on', @iCategId, '_bx_timeline_option_enable_edit', 'checkbox', '', '', '', '', 0),
+('bx_timeline_enable_delete', 'on', @iCategId, '_bx_timeline_option_enable_delete', 'checkbox', '', '', '', '', 1),
+('bx_timeline_enable_show_all', '', @iCategId, '_bx_timeline_option_enable_show_all', 'checkbox', '', '', '', '', 5),
+('bx_timeline_events_per_page_profile', '12', @iCategId, '_bx_timeline_option_events_per_page_profile', 'digit', '', '', '', '', 10),
+('bx_timeline_events_per_page_account', '12', @iCategId, '_bx_timeline_option_events_per_page_account', 'digit', '', '', '', '', 11),
+('bx_timeline_events_per_page_home', '24', @iCategId, '_bx_timeline_option_events_per_page_home', 'digit', '', '', '', '', 12),
+('bx_timeline_events_per_page', '24', @iCategId, '_bx_timeline_option_events_per_page', 'digit', '', '', '', '', 13),
+('bx_timeline_rss_length', '5', @iCategId, '_bx_timeline_option_rss_length', 'digit', '', '', '', '', 20),
+('bx_timeline_events_hide', '', @iCategId, '_bx_timeline_option_events_hide', 'rlist', '', '', '', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:21:"get_actions_checklist";}', 30),
+('bx_timeline_videos_autoplay', 'off', @iCategId, '_bx_timeline_option_videos_autoplay', 'select', '', '', '', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:27:"get_options_videos_autoplay";}', 50),
+('bx_timeline_preload_comments', '0', @iCategId, '_bx_timeline_option_preload_comments', 'digit', '', '', '', '', 51),
+('bx_timeline_enable_hot', '', @iCategId, '_bx_timeline_option_enable_hot', 'checkbox', '', '', '', '', 60),
+('bx_timeline_hot_interval', '48', @iCategId, '_bx_timeline_option_hot_interval', 'digit', '', '', '', '', 61),
+
+-- Post related settings
+('bx_timeline_enable_editor_toolbar', '', @iCategId, '_bx_timeline_option_enable_editor_toolbar', 'checkbox', '', '', '', '', 100);
+
+
+-- 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_timeline_privacy_view', 'bx_timeline', 'view', '_bx_timeline_privacy_view', '3', 'bx_timeline_events', 'id', '', 'BxTimelinePrivacy', 'modules/boonex/timeline/classes/BxTimelinePrivacy.php');
+
+
+-- ACL
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'post', NULL, '_bx_timeline_acl_action_post', '', 1, 3);
+SET @iIdActionPost = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'edit', NULL, '_bx_timeline_acl_action_edit', '', 1, 3);
+SET @iIdActionEdit = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'delete', NULL, '_bx_timeline_acl_action_delete', '', 1, 3);
+SET @iIdActionDelete = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'vote', NULL, '_bx_timeline_acl_action_vote', '', 1, 0);
+SET @iIdActionVote = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'repost', NULL, '_bx_timeline_acl_action_repost', '', 1, 3);
+SET @iIdActionRepost = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'send', NULL, '_bx_timeline_acl_action_send', '', 1, 3);
+SET @iIdActionSend = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'pin', NULL, '_bx_timeline_acl_action_pin', '', 1, 3);
+SET @iIdActionPin = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'stick', NULL, '_bx_timeline_acl_action_stick', '', 1, 3);
+SET @iIdActionStick = LAST_INSERT_ID();
+
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('bx_timeline', 'promote', NULL, '_bx_timeline_acl_action_promote', '', 1, 3);
+SET @iIdActionPromote = 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
+
+-- post
+(@iStandard, @iIdActionPost),
+(@iModerator, @iIdActionPost),
+(@iAdministrator, @iIdActionPost),
+(@iPremium, @iIdActionPost),
+
+-- edit any post
+(@iModerator, @iIdActionEdit),
+(@iAdministrator, @iIdActionEdit),
+
+-- delete any post
+(@iModerator, @iIdActionDelete),
+(@iAdministrator, @iIdActionDelete),
+
+-- vote
+(@iStandard, @iIdActionVote),
+(@iModerator, @iIdActionVote),
+(@iAdministrator, @iIdActionVote),
+(@iPremium, @iIdActionVote),
+
+-- repost
+(@iStandard, @iIdActionRepost),
+(@iModerator, @iIdActionRepost),
+(@iAdministrator, @iIdActionRepost),
+(@iPremium, @iIdActionRepost),
+
+-- send
+(@iStandard, @iIdActionSend),
+(@iModerator, @iIdActionSend),
+(@iAdministrator, @iIdActionSend),
+(@iPremium, @iIdActionSend),
+
+-- pin any post
+(@iModerator, @iIdActionPin),
+(@iAdministrator, @iIdActionPin),
+
+-- stick any post
+(@iModerator, @iIdActionStick),
+(@iAdministrator, @iIdActionStick),
+
+-- promote any post
+(@iModerator, @iIdActionPromote),
+(@iAdministrator, @iIdActionPromote);
+
+
+-- ALERTS
+INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `service_call`) VALUES 
+('bx_timeline', 'BxTimelineResponse', 'modules/boonex/timeline/classes/BxTimelineResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('profile', 'delete', @iHandler);
+
+
+-- 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_timeline', 'bx_timeline', 'bx_timeline_comments', 1, 5000, 1000, 3, 5, 3, 'tail', 1, 'bottom', 1, 1, 1, -3, 1, 'cmt', 'page.php?i=item&id={object_id}', '', 'bx_timeline_events', 'id', 'object_id', 'title', 'comments', 'BxTimelineCmts', 'modules/boonex/timeline/classes/BxTimelineCmts.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_timeline', 'bx_timeline_views_track', '86400', '1', 'bx_timeline_events', 'id', 'object_id', 'views', '', '');
+
+
+-- VOTES
+INSERT INTO `sys_objects_vote`(`Name`, `TableMain`, `TableTrack`, `PostTimeout`, `MinValue`, `MaxValue`, `IsUndo`, `IsOn`, `TriggerTable`, `TriggerFieldId`, `TriggerFieldAuthor`, `TriggerFieldRate`, `TriggerFieldRateCount`, `ClassName`, `ClassFile`) VALUES 
+('bx_timeline', 'bx_timeline_votes', 'bx_timeline_votes_track', '604800', '1', '1', '0', '1', 'bx_timeline_events', 'id', 'object_id', 'rate', 'votes', 'BxTimelineVote', 'modules/boonex/timeline/classes/BxTimelineVote.php');
+
+
+-- SCORES
+INSERT INTO `sys_objects_score` (`name`, `module`, `table_main`, `table_track`, `post_timeout`, `is_on`, `trigger_table`, `trigger_field_id`, `trigger_field_author`, `trigger_field_score`, `trigger_field_cup`, `trigger_field_cdown`, `class_name`, `class_file`) VALUES 
+('bx_timeline', 'bx_timeline', 'bx_timeline_scores', 'bx_timeline_scores_track', '604800', '0', 'bx_timeline_events', 'id', 'object_id', '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_timeline', 'bx_timeline_reports', 'bx_timeline_reports_track', '1', 'page.php?i=item&id={object_id}', 'bx_timeline_events', 'id', 'owner_id', 'reports',  'BxTimelineReport', 'modules/boonex/timeline/classes/BxTimelineReport.php');
+
+
+-- SEARCH
+SET @iSearchOrder = (SELECT IFNULL(MAX(`Order`), 0) FROM `sys_objects_search`);
+INSERT INTO `sys_objects_search` (`ObjectName`, `Title`, `Order`, `ClassName`, `ClassPath`) VALUES
+('bx_timeline', '_bx_timeline', @iSearchOrder + 1, 'BxTimelineSearchResult', 'modules/boonex/timeline/classes/BxTimelineSearchResult.php'),
+('bx_timeline_cmts', '_bx_timeline_cmts', @iSearchOrder + 2, 'BxTimelineCmtsSearchResult', 'modules/boonex/timeline/classes/BxTimelineCmtsSearchResult.php');
+
+
+-- 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_timeline_administration', 'Sql', 'SELECT * FROM `bx_timeline_events` WHERE 1 ', 'bx_timeline_events', 'id', 'date', 'active', '', 20, NULL, 'start', '', 'title,description', '', 'like', 'reports', '', 192, 'BxTimelineGridAdministration', 'modules/boonex/timeline/classes/BxTimelineGridAdministration.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_timeline_administration', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_timeline_administration', 'switcher', '_bx_timeline_grid_column_title_adm_active', '8%', 0, '', '', 2),
+('bx_timeline_administration', 'reports', '_sys_txt_reports_title', '5%', 0, '', '', 2),
+('bx_timeline_administration', 'description', '_bx_timeline_grid_column_title_adm_description', '25%', 0, '25', '', 3),
+('bx_timeline_administration', 'date', '_bx_timeline_grid_column_title_adm_added', '20%', 1, '25', '', 5),
+('bx_timeline_administration', 'owner_id', '_bx_timeline_grid_column_title_adm_author', '20%', 0, '25', '', 6),
+('bx_timeline_administration', 'actions', '', '20%', 0, '', '', 7);
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_timeline_administration', 'bulk', 'delete', '_bx_timeline_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_timeline_administration', 'single', 'delete', '_bx_timeline_grid_action_title_adm_delete', 'remove', 1, 1, 2);
+
+
+-- METATAGS
+INSERT INTO `sys_objects_metatags` (`object`, `table_keywords`, `table_locations`, `table_mentions`, `override_class_name`, `override_class_file`) VALUES
+('bx_timeline', 'bx_timeline_meta_keywords', 'bx_timeline_meta_locations', 'bx_timeline_meta_mentions', '', '');
+
+
+-- EMAIL TEMPLATES
+INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES 
+('bx_timeline', '_bx_timeline_et_txt_name_send', 'bx_timeline_send', '_bx_timeline_et_txt_subject_send', '_bx_timeline_et_txt_body_send');
+
+
+-- 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_timeline', '_bx_timeline', 'bx_timeline', 'post_common', '', 'delete', '', ''),
+('bx_timeline_cmts', '_bx_timeline_cmts', 'bx_timeline', 'commentPost', 'commentUpdated', 'commentRemoved', 'BxDolContentInfoCmts', '');
+
+
+-- CRON
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
+('bx_timeline_hot', '0 * * * *', 'BxTimelineCronHot', 'modules/boonex/timeline/classes/BxTimelineCronHot.php', '');
+
+
+-- PRELOADER
+SET @iOrderPreloader = (SELECT IFNULL(MAX(`order`), 9999) FROM `sys_preloader` WHERE `type`='js_system' AND `order` > 9999 LIMIT 1);
+INSERT INTO `sys_preloader`(`module`, `type`, `content`, `active`, `order`) VALUES
+('bx_timeline', 'js_system', 'modernizr.min.js', 1, @iOrderPreloader + 1);