Parcourir la source

Merge branch 'master' of https://github.com/unaio/una

AntonLV il y a 6 ans
Parent
commit
cc8ffc357f
37 fichiers modifiés avec 1181 ajouts et 163 suppressions
  1. 5 0
      .htaccess
  2. 32 0
      inc/classes/BxDolPage.php
  3. 8 3
      inc/classes/BxDolPageQuery.php
  4. 23 0
      inc/classes/BxDolRewriteRulesQuery.php
  5. 1 1
      inc/classes/BxDolService.php
  6. 145 0
      inc/classes/BxDolWiki.php
  7. 57 0
      inc/classes/BxDolWikiQuery.php
  8. 1 1
      inc/utils.inc.php
  9. 0 0
      install/sql/system.sql
  10. 31 0
      modules/boonex/accounts/classes/BxAccntGridAdministration.php
  11. 3 0
      modules/boonex/accounts/classes/BxAccntMenuManageTools.php
  12. 9 0
      modules/boonex/accounts/classes/BxAccntModule.php
  13. 5 1
      modules/boonex/accounts/install/langs/en.xml
  14. 10 8
      modules/boonex/accounts/install/sql/enable.sql
  15. 8 0
      modules/boonex/accounts/js/manage_tools.js
  16. 84 55
      modules/boonex/analytics/classes/BxAnalyticsModule.php
  17. 3 0
      modules/boonex/english/data/langs/system/en.xml
  18. 5 0
      modules/boonex/invites/classes/BxInvConfig.php
  19. 38 0
      modules/boonex/invites/classes/BxInvDb.php
  20. 282 0
      modules/boonex/invites/classes/BxInvGridInvites.php
  21. 2 0
      modules/boonex/invites/classes/BxInvGridRequests.php
  22. 60 26
      modules/boonex/invites/classes/BxInvModule.php
  23. 47 3
      modules/boonex/invites/classes/BxInvResponse.php
  24. 27 4
      modules/boonex/invites/classes/BxInvTemplate.php
  25. 33 8
      modules/boonex/invites/install/langs/en.xml
  26. 6 0
      modules/boonex/invites/install/sql/disable.sql
  27. 61 3
      modules/boonex/invites/install/sql/enable.sql
  28. 0 25
      modules/boonex/invites/install/sql/install.sql
  29. 0 7
      modules/boonex/invites/install/sql/uninstall.sql
  30. 17 0
      modules/boonex/protean/data/template/system/scripts/BxTemplServiceWiki.php
  31. 3 0
      modules/boonex/russian/data/langs/bx_accounts/ru.xml
  32. 49 12
      modules/boonex/russian/data/langs/bx_invites/ru.xml
  33. 4 0
      modules/boonex/russian/data/langs/system/ru.xml
  34. 2 6
      page.php
  35. 32 0
      r.php
  36. 21 0
      template/scripts/BxBasePage.php
  37. 67 0
      template/scripts/BxBaseServiceWiki.php

+ 5 - 0
.htaccess

@@ -11,6 +11,11 @@ Options -MultiViews -Indexes
     RewriteRule ^m/(.*)$  modules/index.php?r=$1 [QSA,L]
     RewriteRule ^page/(.*)$  page.php?i=$1 [QSA,L]
     RewriteRule ^s/([a-zA-Z0-9_]+)/([a-zA-Z0-9\.]+)  storage.php?o=$1&f=$2   [QSA,L]
+
+    RewriteCond %{REQUEST_FILENAME} -f [OR]
+    RewriteCond %{REQUEST_FILENAME} -d
+    RewriteRule .+ - [L]
+    RewriteRule ^(.+)$ r.php?_q=$1 [QSA,L]
 </IfModule>
 
 AddType image/svg+xml svg

+ 32 - 0
inc/classes/BxDolPage.php

@@ -129,6 +129,24 @@ class BxDolPage extends BxDolFactory implements iBxDolFactoryObject, iBxDolRepla
         $this->_oQuery = new BxDolPageQuery($this->_aObject);
     }
 
+    /**
+     * Get page object instance by Module name and page URI
+     * @param $sModule module name
+     * @param $sURI unique page URI
+     * @return object instance or false on error
+     */
+    static public function getObjectInstanceByModuleAndURI($sModule, $sURI = '', $oTemplate = false)
+    {
+    	if(empty($sURI) && bx_get('i') !== false)
+    		$sURI = bx_process_input(bx_get('i'));
+
+    	if(empty($sURI))
+			return false;
+
+        $sObject = BxDolPageQuery::getPageObjectNameByURI($sURI, $sModule);
+        return $sObject ? self::getObjectInstance($sObject, $oTemplate) : false;
+    }
+
     /**
      * Get page object instance by page URI
      * @param $sURI unique page URI
@@ -215,6 +233,20 @@ class BxDolPage extends BxDolFactory implements iBxDolFactoryObject, iBxDolRepla
         return true;
     }
 
+    /**
+     * Display complete page
+     */
+    public function displayPage ($oTemplate = null)
+    {
+        if (!$oTemplate)
+            $oTemplate = BxDolTemplate::getInstance();
+
+        $oTemplate->setPageNameIndex (BX_PAGE_DEFAULT);
+        $oTemplate->setPageType ($this->getType());
+        $oTemplate->setPageContent ('page_main_code', $this->getCode());
+        $oTemplate->getPageCode();
+    }
+
     public function getType ()
     {
     	return (int)$this->_aObject['type_id'];

+ 8 - 3
inc/classes/BxDolPageQuery.php

@@ -32,11 +32,16 @@ class BxDolPageQuery extends BxDolDb
         return $aObject;
     }
 
-    static public function getPageObjectNameByURI($sURI)
+    static public function getPageObjectNameByURI($sURI, $sModule = false)
     {
         $oDb = BxDolDb::getInstance();
-        $sQuery = $oDb->prepare("SELECT `object` FROM `sys_objects_page` WHERE `uri` = ?", $sURI);
-        return $oDb->getOne($sQuery);
+        $a = array('uri' => $sURI);
+        $sQuery = "SELECT `object` FROM `sys_objects_page` WHERE `uri` = :uri";
+        if ($sModule) {
+            $a['module'] = $sModule;
+            $sQuery .= " AND `module` = :module";
+        }
+        return $oDb->getOne($sQuery, $a);
     }
 
 	static public function getPageTriggers($sTriggerName)

+ 23 - 0
inc/classes/BxDolRewriteRulesQuery.php

@@ -0,0 +1,23 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+class BxDolRewriteRulesQuery extends BxDolDb
+{
+    public function __construct()
+    {
+    	parent::__construct();
+    }
+
+    static public function getActiveRules()
+    {        
+        return BxDolDb::getInstance()->fromCache("sys_wiki_rewrite_rules", "getAll", "SELECT * FROM `sys_rewrite_rules` WHERE `active` = 1");
+    }
+}
+
+/** @} */

+ 1 - 1
inc/classes/BxDolService.php

@@ -45,7 +45,7 @@ class BxDolService extends BxDol
         if (empty($aModule))
             return '';
 
-        $sKey = md5($mixed . $sMethod . print_r($aParams, true) . $sClass);
+        $sKey = md5($mixed . $sMethod . print_r($aParams, true) . $sClass . bx_get_logged_profile_id());
         if (!$bIgnoreCache && isset(self::$_aMemoryCache[$sKey]))
             return self::$_aMemoryCache[$sKey];
 

+ 145 - 0
inc/classes/BxDolWiki.php

@@ -0,0 +1,145 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+/**
+ * WIKI object.
+ *
+ * It's possble to create different WIKI object which will different URLs, Menus and permissions.
+ * For example it's possible to create 
+ * http://example.com/wiki/somepageshere and http://example.com/cocs/anotherpageshere
+ *
+ * @section wiki_create Creating the WIKI object:
+ *
+ *
+ * Add record to 'sys_objects_wiki' table:
+ *
+ * - object: name of the WIKI object, this name will be user in URL as well, 
+ *          for example, 'wiki' will have URLs like this: http://example.com/wiki/somepageshere
+ * - title: title of the WIKI, for example, documentation, help, tutorial
+ * - module: module name WIKI object belongs to
+ * - allow_add_for_levels: allow to add pages and blocks for this member levels
+ * - allow_edit_for_levels: allow to edit block for this member levels
+ * - allow_delete_for_levels: allow to delet pages and blocks for this member levels
+ * - allow_translate_for_levels: allow to add translations for this member levels
+ * - override_class_name: user defined class name 
+ * - override_class_file: the location of the user defined class, leave it empty if class is located in system folders.
+ *
+ * Add record to 'sys_rewrite_rules' table:
+ * - preg - regular expression which matches some URL
+ * - service - service method to call if abbe regular expression matches
+ * - active - active flag
+ *
+ * Add record to 'sys_permalinks' table:
+ * - standard - how link should look like when permalinks are off
+ * - permalink - how link should look like when permalinks are on, 
+ *      some special server configuration may be required to make permalink to work, 
+ *      such as 'mod_rewrite' and .htaccess file for Apache
+ * - check - option name which enables/disables permalinks
+ * - compare_by_prefix - compare by prefix
+ */
+class BxDolWiki extends BxDolFactory implements iBxDolFactoryObject
+{
+    protected $_sObject;
+    protected $_aObject;
+
+    /**
+     * Constructor
+     * @param $aObject array of WIKI options
+     */
+    protected function __construct($aObject)
+    {
+        parent::__construct();
+
+        $this->_sObject = $aObject['object'];
+        $this->_aObject = $aObject;
+        $this->_oQuery = new BxDolWikiQuery($aObject);
+    }
+
+    /**
+     * Get WIKI object instance by object name
+     * @param $sObject object name
+     * @return object instance or false on error
+     */
+    static public function getObjectInstance($sObject = false, $oTemplate = false)
+    {
+        if (isset($GLOBALS['bxDolClasses']['BxDolWiki!'.$sObject]))
+            return $GLOBALS['bxDolClasses']['BxDolWiki!'.$sObject];
+
+        $aObject = BxDolWikiQuery::getWikiObject($sObject);
+        if (!$aObject || !is_array($aObject))
+            return false;
+
+        $sClass = empty($aObject['override_class_name']) ? 'BxDolWiki' : $aObject['override_class_name'];
+        if (!empty($aObject['override_class_file']))
+            require_once(BX_DIRECTORY_PATH_ROOT . $aObject['override_class_file']);
+
+        $o = new $sClass($aObject, $oTemplate);
+
+        return ($GLOBALS['bxDolClasses']['BxDolWiki!'.$sObject] = $o);
+    }
+
+    /**
+     * Get object name
+     */
+    public function getObjectName ()
+    {
+        return $this->_sObject;
+    }
+
+    /**
+     * Get WIKI block content
+     * @param $iBlockId block ID
+     * @param $sLang optional language name
+     * @return block content
+     */
+    public function getBlockContent ($iBlockId, $sLang = false)
+    {
+        if (!$sLang)
+            $sLang = bx_lang_name();
+        $s = $this->_oQuery->getBlockContent ($iBlockId, $sLang);
+        // $s = TODO: wiki - process markdown
+        $s = $this->addControls($iBlockId, $s);
+        return $s;
+    }
+
+    /**
+     * Add controls for edit, delete, translate, history, etc content
+     * @param $iBlockId block ID
+     * @param $sLang optional language name
+     * @return block content
+     */
+    public function addControls ($iBlockId, $s)
+    {
+        $sControl = "<div>TODO: wiki - controls here, such as edit, delete, translate, history</div>";
+        return $s . $sControl;
+    }
+
+    /**
+     * Check if partucular action is allowed
+     * @param $sType action type: add, edit, delete, translate
+     * @param $sProfileId profile to check, if not provided then current profile is used
+     * @return true if action is allowed, false otherwise
+     */
+    public function isAllowed ($sType, $iProfileId = false)
+    {
+        $aTypes = array(
+            'add' => 'allow_add_for_levels',
+            'edit' => 'allow_edit_for_levels',
+            'delete' => 'allow_delete_for_levels',
+            'translate' => 'allow_translate_for_levels',
+        );
+        if (!isset($aTypes[$sType]) || !isset($this->_aObject[$aTypes[$sType]]))
+            return false;
+
+        $oAcl = BxDolAcl::getInstance();
+        return $oAcl->isMemberLevelInSet($this->_aObject[$aTypes[$sType]], $iProfileId); 
+    }
+}
+
+/** @} */

+ 57 - 0
inc/classes/BxDolWikiQuery.php

@@ -0,0 +1,57 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+/**
+ * Database queries for WIKI objects.
+ * @see BxDolWiki
+ */
+class BxDolWikiQuery extends BxDolDb
+{
+    protected $_aObject;
+
+    public function __construct($aObject)
+    {
+        parent::__construct();
+        $this->_aObject = $aObject;
+    }
+
+    static public function getWikiObject ($sObject)
+    {
+        $oDb = BxDolDb::getInstance();
+        $sQuery = $oDb->prepare("SELECT * FROM `sys_objects_wiki` WHERE `object` = ?", $sObject);
+        $aObject = $oDb->getRow($sQuery);
+        if (!$aObject || !is_array($aObject))
+            return false;
+
+        return $aObject;
+    }
+
+    public function getBlockContent ($iBlockId, $sLang, $iRevision = false)
+    {
+        $sWhere = '';
+        $aBind = array('block' => $iBlockId, 'lang' => $sLang);
+        if (false !== $iRevision) {
+            $sWhere = " AND `revision` = :rev";
+            $aBind['rev'] = $iRevision;
+        }
+
+        // get latest revision for specific language
+        $aRow = $this->getRow("SELECT `content` FROM `sys_pages_wiki_blocks` WHERE `block_id` = :block AND `language` = :lang $sWhere ORDER BY `revision` DESC LIMIT 1", $aBind);
+
+        // if translation isn't found for specific language then get latest revision for main language 
+        if (!$aRow) {
+            unset($aBind['lang']);
+            $aRow = $this->getRow("SELECT `content` FROM `sys_pages_wiki_blocks` WHERE `block_id` = :block AND `main_language` = 1 $sWhere ORDER BY `revision` DESC LIMIT 1", $aBind);
+        }
+
+        return $aRow ? $aRow['content'] : false;
+    }
+}
+
+/** @} */

+ 1 - 1
inc/utils.inc.php

@@ -544,7 +544,7 @@ function dbgTiming($sStartMicrotime)
     $i1 = explode(' ', microtime ());
     $i2 = explode(' ', $sStartMicrotime);
     $iTime = ($i1[0]+$i1[1]) - ($i2[0]+$i2[1]);
-    return round($iTime, 3) . ' sec';
+    return round($iTime, 6) . ' sec';
 }
 
 function echoJson($a)

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
install/sql/system.sql


+ 31 - 0
modules/boonex/accounts/classes/BxAccntGridAdministration.php

@@ -151,7 +151,38 @@ class BxAccntGridAdministration extends BxBaseModProfileGridAdministration
             echoJson(array('popup' => array('html' => $sContent, 'options' => array())));
         }
     }
+    
+    public function performActionConfirm()
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+    	$aIds = bx_get('ids');
+        if(!$aIds || !is_array($aIds)) {
+            echoJson(array());
+            return;
+        }
 
+        $oAccount = BxDolAccount::getInstance();
+
+        $iAffected = 0;
+        $aIdsAffected = array();
+        foreach($aIds as $iId){
+            if (BxDolAccount::isNeedConfirmEmail()){
+			    if($oAccount->updateEmailConfirmed(true, true, $iId)) {
+				    $aIdsAffected[] = $iId;
+        		    $iAffected++;  
+			    }
+            }
+            if (BxDolAccount::isNeedConfirmPhone()){
+			    if($oAccount->updatePhoneConfirmed(true, $iId)) {
+				    $aIdsAffected[] = $iId;
+        		    $iAffected++;  
+			    }
+            }
+        }
+		echoJson($iAffected ? array('grid' => $this->getCode(false), 'blink' => $aIdsAffected) : array('msg' => _t($CNF['T']['grid_action_err_perform'])));
+    }
+    
     public function performActionResendCemail()
     {
     	$CNF = &$this->_oModule->_oConfig->CNF;

+ 3 - 0
modules/boonex/accounts/classes/BxAccntMenuManageTools.php

@@ -50,6 +50,9 @@ class BxAccntMenuManageTools extends BxBaseModGeneralMenuManageTools
             case 'unlock-account':
             	$sCheckFuncName = 'checkAllowedUnlockAccount';
             	break;
+            case 'confirm':
+            	$sCheckFuncName = 'checkAllowedConfirm';
+            	break;
         }
 
         if(!$sCheckFuncName || !method_exists($this->_oModule, $sCheckFuncName))

+ 9 - 0
modules/boonex/accounts/classes/BxAccntModule.php

@@ -52,6 +52,15 @@ class BxAccntModule extends BxBaseModGeneralModule
       
         return array('counter1_value' => $o->getNum(),'counter3_value' => $iNumTotal, 'counter1_caption' => _t('_bx_accnt_menu_dashboard_manage_tools_addon_counter1_caption'));
 	}
+    
+    public function checkAllowedConfirm(&$aDataEntry, $isPerformAction = false)
+    {
+    	$bAdmin = isAdmin();
+    	if(!$bAdmin || BxDolAccount::getInstance($aDataEntry['id'])->isConfirmed())
+    		return _t('_sys_txt_access_denied');
+
+    	return CHECK_ACTION_RESULT_ALLOWED;
+    }
 
     public function checkAllowedDelete(&$aDataEntry, $isPerformAction = false)
     {

+ 5 - 1
modules/boonex/accounts/install/langs/en.xml

@@ -17,7 +17,10 @@
     <string name="_bx_accnt_menu_title_manage_tools"><![CDATA[Manage Tools Submenu]]></string>
     <string name="_bx_accnt_menu_item_title_system_resend_cemail"><![CDATA[Resend Confirmation]]></string>
     <string name="_bx_accnt_menu_item_title_resend_cemail"><![CDATA[Resend Confirmation]]></string>
-    <string name="_bx_accnt_menu_item_title_system_edit_email"><![CDATA[Edit Email]]></string>
+    <string name="_bx_accnt_menu_item_title_system_confirm"><![CDATA[Confirm]]></string>
+    <string name="_bx_accnt_menu_item_title_confirm"><![CDATA[Confirm]]></string>
+
+  <string name="_bx_accnt_menu_item_title_system_edit_email"><![CDATA[Edit Email]]></string>
     <string name="_bx_accnt_menu_item_title_edit_email"><![CDATA[Edit Email]]></string>
     <string name="_bx_accnt_menu_item_title_system_reset_password"><![CDATA[Reset Password]]></string>
     <string name="_bx_accnt_menu_item_title_reset_password"><![CDATA[Reset Password]]></string>
@@ -56,6 +59,7 @@
     <string name="_bx_accnt_grid_column_title_adm_logged"><![CDATA[Last Logged]]></string>
     <string name="_bx_accnt_grid_action_title_adm_activate"><![CDATA[Activate]]></string>
     <string name="_bx_accnt_grid_action_title_adm_suspend"><![CDATA[Suspend]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_confirm"><![CDATA[Confirm]]></string>
     <string name="_bx_accnt_grid_action_title_adm_edit_email"><![CDATA[Edit Email]]></string>
     <string name="_bx_accnt_grid_action_title_adm_resend_cemail"><![CDATA[Resend Confirmation]]></string>
     <string name="_bx_accnt_grid_action_title_adm_reset_password"><![CDATA[Reset Password]]></string>

+ 10 - 8
modules/boonex/accounts/install/sql/enable.sql

@@ -19,12 +19,13 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
 ('bx_accounts_menu_manage_tools', @sName, 'edit-email', '_bx_accnt_menu_item_title_system_edit_email', '_bx_accnt_menu_item_title_edit_email', 'javascript:void(0)', 'javascript:{js_object}.onClickEditEmail({content_id}, this);', '_self', 'at', '', 192, 1, 0, 1),
 ('bx_accounts_menu_manage_tools', @sName, 'resend-cemail', '_bx_accnt_menu_item_title_system_resend_cemail', '_bx_accnt_menu_item_title_resend_cemail', 'javascript:void(0)', 'javascript:{js_object}.onClickResendCemail({content_id}, this);', '_self', 'far envelope', '', 192, 1, 0, 2),
-('bx_accounts_menu_manage_tools', @sName, 'reset-password', '_bx_accnt_menu_item_title_system_reset_password', '_bx_accnt_menu_item_title_reset_password', 'javascript:void(0)', 'javascript:{js_object}.onClickResetPassword({content_id}, this);', '_self', 'eraser', '', 192, 1, 0, 3),
-('bx_accounts_menu_manage_tools', @sName, 'unlock-account', '_bx_accnt_menu_item_title_system_unlock_account', '_bx_accnt_menu_item_title_unlock_account', 'javascript:void(0)', 'javascript:{js_object}.onClickUnlockAccount({content_id}, this);', '_self', 'unlock', '', 192, 1, 0, 4),
-('bx_accounts_menu_manage_tools', @sName, 'delete', '_bx_accnt_menu_item_title_system_delete', '_bx_accnt_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id}, this);', '_self', 'far trash-alt', '', 192, 1, 0, 5),
-('bx_accounts_menu_manage_tools', @sName, 'delete-with-content', '_bx_accnt_menu_item_title_system_delete_with_content', '_bx_accnt_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id}, this);', '_self', 'far trash-alt', '', 192, 1, 0, 6),
-('bx_accounts_menu_manage_tools', @sName, 'make-operator', '_bx_accnt_menu_item_title_system_make_operator', '_bx_accnt_menu_item_title_make_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickMakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 7),
-('bx_accounts_menu_manage_tools', @sName, 'unmake-operator', '_bx_accnt_menu_item_title_system_unmake_operator', '_bx_accnt_menu_item_title_unmake_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickUnmakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 8);
+('bx_accounts_menu_manage_tools', @sName, 'confirm', '_bx_accnt_menu_item_title_system_confirm', '_bx_accnt_menu_item_title_confirm', 'javascript:void(0)', 'javascript:{js_object}.onClickConfirm({content_id}, this);', '_self', 'fas check', '', 192, 1, 0, 3),
+('bx_accounts_menu_manage_tools', @sName, 'reset-password', '_bx_accnt_menu_item_title_system_reset_password', '_bx_accnt_menu_item_title_reset_password', 'javascript:void(0)', 'javascript:{js_object}.onClickResetPassword({content_id}, this);', '_self', 'eraser', '', 192, 1, 0, 4),
+('bx_accounts_menu_manage_tools', @sName, 'unlock-account', '_bx_accnt_menu_item_title_system_unlock_account', '_bx_accnt_menu_item_title_unlock_account', 'javascript:void(0)', 'javascript:{js_object}.onClickUnlockAccount({content_id}, this);', '_self', 'unlock', '', 192, 1, 0, 5),
+('bx_accounts_menu_manage_tools', @sName, 'delete', '_bx_accnt_menu_item_title_system_delete', '_bx_accnt_menu_item_title_delete', 'javascript:void(0)', 'javascript:{js_object}.onClickDelete({content_id}, this);', '_self', 'far trash-alt', '', 192, 1, 0, 6),
+('bx_accounts_menu_manage_tools', @sName, 'delete-with-content', '_bx_accnt_menu_item_title_system_delete_with_content', '_bx_accnt_menu_item_title_delete_with_content', 'javascript:void(0)', 'javascript:{js_object}.onClickDeleteWithContent({content_id}, this);', '_self', 'far trash-alt', '', 192, 1, 0, 7),
+('bx_accounts_menu_manage_tools', @sName, 'make-operator', '_bx_accnt_menu_item_title_system_make_operator', '_bx_accnt_menu_item_title_make_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickMakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 8),
+('bx_accounts_menu_manage_tools', @sName, 'unmake-operator', '_bx_accnt_menu_item_title_system_unmake_operator', '_bx_accnt_menu_item_title_unmake_operator', 'javascript:void(0)', 'javascript:{js_object}.onClickUnmakeOperator({content_id}, this);', '_self', 'wrench', '', 192, 1, 0, 9);
 
 -- 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);
@@ -72,8 +73,9 @@ INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon
 ('bx_accounts_administration', 'bulk', 'activate', '_bx_accnt_grid_action_title_adm_activate', '', 0, 0, 1),
 ('bx_accounts_administration', 'bulk', 'suspend', '_bx_accnt_grid_action_title_adm_suspend', '', 0, 0, 2),
 ('bx_accounts_administration', 'bulk', 'resend_cemail', '_bx_accnt_grid_action_title_adm_resend_cemail', '', 0, 0, 3),
-('bx_accounts_administration', 'bulk', 'delete', '_bx_accnt_grid_action_title_adm_delete', '', 0, 1, 4),
-('bx_accounts_administration', 'bulk', 'delete_with_content', '_bx_accnt_grid_action_title_adm_delete_with_content', '', 0, 1, 5),
+('bx_accounts_administration', 'bulk', 'confirm', '_bx_accnt_grid_action_title_adm_confirm', '', 0, 0, 4),
+('bx_accounts_administration', 'bulk', 'delete', '_bx_accnt_grid_action_title_adm_delete', '', 0, 1, 5),
+('bx_accounts_administration', 'bulk', 'delete_with_content', '_bx_accnt_grid_action_title_adm_delete_with_content', '', 0, 1, 6),
 ('bx_accounts_administration', 'single', 'edit_email', '_bx_accnt_grid_action_title_adm_edit_email', '', 0, 0, 0),
 ('bx_accounts_administration', 'single', 'reset_password', '_bx_accnt_grid_action_title_adm_reset_password', '', 0, 0, 0),
 ('bx_accounts_administration', 'single', 'unlock_account', '_bx_accnt_grid_action_title_adm_unlock_account', '', 0, 0, 0),

+ 8 - 0
modules/boonex/accounts/js/manage_tools.js

@@ -66,6 +66,14 @@ BxAccntManageTools.prototype.onClickResendCemail = function(iContentId, oLink) {
 	oGrid.actionWithId(iContentId, 'resend_cemail', oData, '', false, 0);
 };
 
+BxAccntManageTools.prototype.onClickConfirm = function (iContentId, oLink) {
+    $('.bx-popup-applied:visible').dolPopupHide();
+
+    var oGrid = glGrids[this._sObjNameGrid];
+    var oData = oGrid._checkAppend(oLink, oGrid._getActionDataForReload());
+    oGrid.actionWithId(iContentId, 'confirm', oData, '', false, 0);
+};
+
 BxAccntManageTools.prototype.onClickResetPassword = function(iContentId, oLink) {
 	$('.bx-popup-applied:visible').dolPopupHide();
 

+ 84 - 55
modules/boonex/analytics/classes/BxAnalyticsModule.php

@@ -74,7 +74,6 @@ class BxAnalyticsModule extends BxDolModule
     public function serviceGetModules()
     {
         $aResult = array();
-        $aResult2 = array();
         $aResult[BX_ANALYTICS_SYSTEM] = _t('_bx_analytics_system_text');
         $BxDolModuleQuery = BxDolModuleQuery::getInstance();
         $aModules = $BxDolModuleQuery->getModulesBy(array('type' => 'modules', 'active' => 1));
@@ -84,7 +83,12 @@ class BxAnalyticsModule extends BxDolModule
                 $aResult[$aModule['name']] = $aModule['title'];
             }
         }
-        return array_merge($aResult, $aResult2);
+        
+        bx_alert($this->_aModule['name'], 'get_modules', 0, 0, array(
+            'list' => &$aResult,
+        ));
+        
+        return $aResult;
     }
           
     /**
@@ -125,6 +129,12 @@ class BxAnalyticsModule extends BxDolModule
             $aRv[BX_ANALYTICS_CONTENT_TOTAL] = _t('_bx_analytics_type_content_growth');
             $aRv[BX_ANALYTICS_CONTENT_SPEED] = _t('_bx_analytics_type_content_speed');
         }
+        
+        bx_alert($this->_aModule['name'], 'get_reports', 0, 0, array(
+            'module' => $sModuleName,
+            'list' => &$aRv,
+        ));
+        
         echo json_encode($aRv);
     }
           
@@ -143,8 +153,7 @@ class BxAnalyticsModule extends BxDolModule
         if ($sType == ''){
             header('Content-Type: application/json');
             echo $this->actionGetReportsDataJson($sModuleName, $sReportName, $sDateFrom, $sDateTo);
-        }
-            
+        } 
     }
     
     private function actionGetReportsDataCsv($sModuleName, $sReportName, $sDateFrom, $sDateTo)
@@ -200,21 +209,61 @@ class BxAnalyticsModule extends BxDolModule
         $iMinValueY = 0;
         $iMaxValueY = 0;
         $bDefaultFillData = true;
+        $sReportType = $sReportName;
+        
         $aValues = array('labels' => array(), 'values' => array(array('legend' => '', 'data' => array())), 'links' => array(), 'strings' => array(0 => _t('_bx_analytics_txt_item'), 1 => _t('_bx_analytics_txt_value')));
    
         if ($sModuleName != BX_ANALYTICS_SYSTEM){
             $oModule = BxDolModule::getInstance($sModuleName);
             $aValues['strings'][0] = $oModule->_aModule['title'];
-            $aValues['strings'][1] = _t('_bx_analytics_type_' . $sReportName . '_label');
+            $aValues['strings'][1] = _t('_bx_analytics_type_' . $sReportType . '_label');
         }
         else{
             $aValues['strings'][0] = _t('_bx_analytics_txt_total_content');
-            $aValues['strings'][1] = _t('_bx_analytics_type_' . $sReportName . '_label');
+            $aValues['strings'][1] = _t('_bx_analytics_type_' . $sReportType . '_label');
         }
               
-        switch ($sReportName) {
-            case BX_ANALYTICS_CONTENT_TOTAL:
-            case BX_ANALYTICS_CONTENT_SPEED:
+        switch ($sReportType) {
+            case BX_ANALYTICS_TOP_BY_LIKES:
+                $bDefaultFillData = false;
+                $this->getViewsOrVotes(BxDolVote::getSystems(), 'OBJECT_VOTES', $sModuleName, $iDateFrom, $iDateTo, $aValues, $iMaxValueY, $iMinValueY);
+                break;
+                  
+            case BX_ANALYTICS_TOP_BY_VIEWS:
+                $bDefaultFillData = false;
+                $this->getViewsOrVotes(BxDolView::getSystems(), 'OBJECT_VIEWS', $sModuleName, $iDateFrom, $iDateTo, $aValues, $iMaxValueY, $iMinValueY);
+                break;
+                  
+            case BX_ANALYTICS_MOST_FOLLOWED_PROFILES:
+                $oModule = BxDolModule::getInstance($sModuleName);
+                $aData = $this->_oDb->getMostFollowedProfiles($sModuleName, $iDateFrom, $iDateTo);
+                break;
+                  
+            case BX_ANALYTICS_MOST_ACTIVE_PROFILES:
+                $aData = array();
+                $oModule = BxDolModule::getInstance($sModuleName);
+                $aTmp = $this->getSelectedModules();
+                foreach($aTmp[0] as $sContentModule){
+                    $oContentModule = BxDolModule::getInstance($sContentModule);
+                    if ($oContentModule && isset($oContentModule->_oConfig->CNF['TABLE_ENTRIES']) && isset($oContentModule->_oConfig->CNF['FIELD_AUTHOR'])){
+                        $sContentTable = $oContentModule->_oConfig->CNF['TABLE_ENTRIES'];
+                        $sColumnAuthor = $oContentModule->_oConfig->CNF['FIELD_AUTHOR'];
+                        $sColumnAdded = $oContentModule->_oConfig->CNF['FIELD_ADDED'];
+                        if (!empty($sContentTable) && !empty($sColumnAuthor) && !empty($sColumnAdded) && (!BxDolRequest::serviceExists($sContentModule, 'act_as_profile') || BxDolService::call($sContentModule, 'act_as_profile') == false)){
+                            $aData1 = $this->_oDb->getMostActiveProfiles($sModuleName, $sContentModule, $sContentTable, $sColumnAuthor, $sColumnAuthor, $sColumnAdded, $iDateFrom, $iDateTo);
+                            foreach($aData1 as $aTmp3){
+                                if (array_key_exists($aTmp3['object_id'], $aData))
+                                    $aData[$aTmp3['object_id']]['value'] += $aTmp3['value'];
+                                else
+                                    $aData[$aTmp3['object_id']] = $aTmp3;
+                            }
+                        }
+                    }
+                }
+                $aData = $this->sortArrayOfArraysAndSlice($aData, 'value', intval(getParam('bx_analytics_items_count')));
+                break;
+                
+            default:
                 $sType = "line";
                 $bIsTimeX = true;
                 $sTableName = '';
@@ -224,19 +273,38 @@ class BxAnalyticsModule extends BxDolModule
                     $oModule = BxDolModule::getInstance($sModuleName);
                     if (isset($oModule->_oConfig->CNF['TABLE_ENTRIES']))
                         $sTableName = $oModule->_oConfig->CNF['TABLE_ENTRIES'];
-                    $aValues['strings'][1] = ($sReportName == BX_ANALYTICS_CONTENT_TOTAL ? _t('_bx_analytics_txt_total_count', $oModule->_aModule['title']) : _t('_bx_analytics_txt_count', $oModule->_aModule['title']));
+                    $aValues['strings'][1] = ($sReportType == BX_ANALYTICS_CONTENT_TOTAL ? _t('_bx_analytics_txt_total_count', $oModule->_aModule['title']) : _t('_bx_analytics_txt_count', $oModule->_aModule['title']));
                 }
                 else{
                     $sTableName = 'sys_accounts';
-                    $aValues['strings'][1] = ($sReportName == BX_ANALYTICS_CONTENT_TOTAL ? _t('_bx_analytics_txt_total_count', _t('_bx_analytics_txt_accounts')) : _t('_bx_analytics_txt_count', _t('_bx_analytics_txt_accounts')));
+                    $aValues['strings'][1] = ($sReportType == BX_ANALYTICS_CONTENT_TOTAL ? _t('_bx_analytics_txt_total_count', _t('_bx_analytics_txt_accounts')) : _t('_bx_analytics_txt_count', _t('_bx_analytics_txt_accounts')));
                 }
                 if (isset($oModule) && isset($oModule->_oConfig->CNF['FIELD_ADDED']))
                     $sColumnAdded = $oModule->_oConfig->CNF['FIELD_ADDED'];
                 else
                     $sColumnAdded = 'added';
-                if ($sColumnAdded != ''){
+                
+                $aData = array();
+                $iValuePrev = 0;
+                
+                bx_alert($this->_aModule['name'], 'get_chart_data_line', 0, 0, array(
+                    'module' => $sModuleName,
+                    'report_name' => $sReportName,
+                    'report_type' => &$sReportType,
+                    'date_from' => $iDateFrom,
+                    'date_to' => $iDateTo,
+                    'data' => &$aData,
+                    'prev_value' => &$iValuePrev,
+                ));
+                
+                
+                
+                if ($sColumnAdded != '' && count($aData) == 0){
                     $aData = $this->_oDb->getGrowth($sTableName, $sColumnAdded, $iDateFrom, $iDateTo);
                     $iValuePrev = $this->_oDb->getGrowthInitValue($sTableName, $sColumnAdded, $iDateFrom);
+                }
+                
+                if (count($aData) > 0){
                     $aTmpDates = array();
                     foreach ($aData as $aValue) {
                         $sX = $aValue['period'];
@@ -245,14 +313,14 @@ class BxAnalyticsModule extends BxDolModule
                     for ($i = $iDateFrom; $i < $iDateTo ; $i = $i + 86400 ){
                         $sX = date('Y-m-d', $i);
                         if (!array_key_exists($sX, $aTmpDates)){
-                            array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportName == BX_ANALYTICS_CONTENT_TOTAL ? $iValuePrev : 0));
+                            array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportType == BX_ANALYTICS_CONTENT_TOTAL ? $iValuePrev : 0));
                         }
                         else{
-                            array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportName == BX_ANALYTICS_CONTENT_TOTAL ? ($iValuePrev + $aTmpDates[$sX]) : $aTmpDates[$sX]));
+                            array_push($aValues['values'][0]['data'], array('x' => $sX, 'y' => $sReportType == BX_ANALYTICS_CONTENT_TOTAL ? ($iValuePrev + $aTmpDates[$sX]) : $aTmpDates[$sX]));
                             $iValuePrev += $aTmpDates[$sX];
                         }
                         //array_push($aValues['labels'], $sX);
-                        if ($sReportName == BX_ANALYTICS_CONTENT_TOTAL){
+                        if ($sReportType == BX_ANALYTICS_CONTENT_TOTAL){
                             if ($iValuePrev > $iMaxValueY)
                                 $iMaxValueY = $iValuePrev;
                         }
@@ -263,47 +331,8 @@ class BxAnalyticsModule extends BxDolModule
                     }
                 }
                 break;
-                  
-            case BX_ANALYTICS_TOP_BY_LIKES:
-                $bDefaultFillData = false;
-                $this->getViewsOrVotes(BxDolVote::getSystems(), 'OBJECT_VOTES', $sModuleName, $iDateFrom, $iDateTo, $aValues, $iMaxValueY, $iMinValueY);
-                break;
-                  
-            case BX_ANALYTICS_TOP_BY_VIEWS:
-                $bDefaultFillData = false;
-                $this->getViewsOrVotes(BxDolView::getSystems(), 'OBJECT_VIEWS', $sModuleName, $iDateFrom, $iDateTo, $aValues, $iMaxValueY, $iMinValueY);
-                break;
-                  
-            case BX_ANALYTICS_MOST_FOLLOWED_PROFILES:
-                $oModule = BxDolModule::getInstance($sModuleName);
-                $aData = $this->_oDb->getMostFollowedProfiles($sModuleName, $iDateFrom, $iDateTo);
-                break;
-                  
-            case BX_ANALYTICS_MOST_ACTIVE_PROFILES:
-                $aData = array();
-                $oModule = BxDolModule::getInstance($sModuleName);
-                $aTmp = $this->getSelectedModules();
-                foreach($aTmp[0] as $sContentModule){
-                    $oContentModule = BxDolModule::getInstance($sContentModule);
-                    if ($oContentModule && isset($oContentModule->_oConfig->CNF['TABLE_ENTRIES']) && isset($oContentModule->_oConfig->CNF['FIELD_AUTHOR'])){
-                        $sContentTable = $oContentModule->_oConfig->CNF['TABLE_ENTRIES'];
-                        $sColumnAuthor = $oContentModule->_oConfig->CNF['FIELD_AUTHOR'];
-                        $sColumnAdded = $oContentModule->_oConfig->CNF['FIELD_ADDED'];
-                        if (!empty($sContentTable) && !empty($sColumnAuthor) && !empty($sColumnAdded) && (!BxDolRequest::serviceExists($sContentModule, 'act_as_profile') || BxDolService::call($sContentModule, 'act_as_profile') == false)){
-                            $aData1 = $this->_oDb->getMostActiveProfiles($sModuleName, $sContentModule, $sContentTable, $sColumnAuthor, $sColumnAuthor, $sColumnAdded, $iDateFrom, $iDateTo);
-                            foreach($aData1 as $aTmp3){
-                                if (array_key_exists($aTmp3['object_id'], $aData))
-                                    $aData[$aTmp3['object_id']]['value'] += $aTmp3['value'];
-                                else
-                                    $aData[$aTmp3['object_id']] = $aTmp3;
-                            }
-                        }
-                    }
-                }
-                $aData = $this->sortArrayOfArraysAndSlice($aData, 'value', intval(getParam('bx_analytics_items_count')));
-                break;
         }
-              
+          
         if ($bDefaultFillData){
             foreach ($aData as $aValue) {
                 array_push($aValues['labels'], $this->getItemName($oModule->serviceGetTitle($aValue['object_id'])));

+ 3 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -3017,5 +3017,8 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_option_per_page_browse_showcase"><![CDATA[Number of items in showcase view]]></string>
 	<string name="_sys_option_per_page_browse_recommended"><![CDATA[Number of items in recommended view]]></string>
 	<string name="_sys_javascript_requred"><![CDATA[This site requires JavaScript! Please, enable it in the browser!]]></string>
+	<string name="_sys_wiki_system_title"><![CDATA[System WIKI]]></string>
+	<string name="_sys_wiki_error_page_exists"><![CDATA[Page with such name({0}) already exists]]></string>
+	<string name="_sys_wiki_error_missing_wiki_object"><![CDATA[Wiki object ({0}) wasn't found]]></string>
 	
 </resources>

+ 5 - 0
modules/boonex/invites/classes/BxInvConfig.php

@@ -31,14 +31,19 @@ class BxInvConfig extends BxBaseModGeneralConfig
             'URL_INVITE' => 'page.php?i=invites-invite',
             'URL_REQUEST' => 'page.php?i=invites-request',
             'URL_REQUESTS' => 'page.php?i=invites-requests',
+            'URL_INVITES' => 'page.php?i=invites-invites',
             
             'TABLE_REQUESTS' => $aModule['db_prefix'] . 'requests',
             'TABLE_INVITES' => $aModule['db_prefix'] . 'invites',
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'invites',
+            
+            'FIELD_ADDED' => 'date'
         );
 
         $this->_aObjects = array(
             'alert' => $this->_sName,
             'grid_requests' => $this->_sName . '_requests',
+            'grid_invites' => $this->_sName . '_invites',
             'form_invite' => $this->_sName . '_invite',
             'form_request' => $this->_sName . '_request',
             'form_display_invite_send' => $this->_sName . '_invite_send',

+ 38 - 0
modules/boonex/invites/classes/BxInvDb.php

@@ -67,6 +67,16 @@ class BxInvDb extends BxDolModuleDb
                 $sWhereClause = "AND joined_account_id IS NOT NULL AND `{$this->_sTableInvites}`.`request_id`=:request_id ";
                 $sLimitClause = "LIMIT 1";
                 break;
+            case 'profile_id_by_joined_account_id':
+                $aMethod['name'] = 'getOne';
+                $aMethod['params'][1] = array(
+                    'joined_account_id' => $aParams['value']
+                );
+
+                $sSelectClause = "MAX(`{$this->_sTableInvites}`.`profile_id`)";
+                $sWhereClause = "AND `{$this->_sTableInvites}`.`joined_account_id`=:joined_account_id ";
+                $sLimitClause = "LIMIT 1";
+                break;  
             case 'date_joined_by_request':
                 $aMethod['name'] = 'getOne';
                 $aMethod['params'][1] = array(
@@ -211,6 +221,34 @@ class BxInvDb extends BxDolModuleDb
         return array($aEntries, (int)call_user_func_array(array($this, $aMethod['name']), $aMethod['params']));
     }
     
+    public function getDataForCharts($iDateFrom, $iDateTo, $isInvited = false)
+    {
+        $aBindings = array(
+            'datefrom' => $iDateFrom,
+            'dateto' => $iDateTo
+        );
+        $sQuery = "SELECT DATE(FROM_UNIXTIME(`date`)) AS `period`, YEAR(FROM_UNIXTIME(`date`)) AS `year`, COUNT(*) AS `count` FROM `" . $this->_sTableInvites . "` WHERE `date` >= :datefrom AND `date` <= :dateto " . $this->getAddSqlForCharts($isInvited) . " GROUP BY `period`, `year` ORDER BY `year`, `period` ASC";
+        return $this->getAll($sQuery, $aBindings);
+    }
+    
+    public function getInitValueForCharts($iDateFrom, $isInvited = false)
+    {
+        $aBindings = array(
+            'datefrom' => $iDateFrom
+        );
+        $sQuery = "SELECT COUNT(*) AS `count` FROM " . $this->_sTableInvites . " WHERE `date` < :datefrom " . $this->getAddSqlForCharts($isInvited);
+        return $this->getOne($sQuery, $aBindings);
+    }
+    
+    private function getAddSqlForCharts($isInvited)
+    {
+        $sSqlAdd = "";
+        if ($isInvited){
+            $sSqlAdd = " AND `joined_account_id` IS NOT NULL ";
+        }
+        return $sSqlAdd;
+    }
+    
     private function updateRequestStatusByRequestId($iStatus, $iReqestId)
     {
         $aBindings = array(

+ 282 - 0
modules/boonex/invites/classes/BxInvGridInvites.php

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

+ 2 - 0
modules/boonex/invites/classes/BxInvGridRequests.php

@@ -28,6 +28,8 @@ class BxInvGridRequests extends BxTemplGrid
     {
         parent::__construct ($aOptions, $oTemplate);
 
+        $this->_aQueryReset = array('order_field', 'order_dir', $this->_aOptions['paginate_get_start'], $this->_aOptions['paginate_get_per_page']);
+        
         $this->_sModule = 'bx_invites';
         $this->_oModule = BxDolModule::getInstance($this->_sModule);
         

+ 60 - 26
modules/boonex/invites/classes/BxInvModule.php

@@ -216,15 +216,29 @@ class BxInvModule extends BxDolModule
      */
     public function serviceGetBlockManageRequests()
     {
-        $this->_oTemplate->addJs('jquery.form.min.js');
-        $this->_oTemplate->addJs('main.js');
-        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_requests'));
-        if(!$oGrid)
-            return '';
-
-        $this->_oTemplate->addCss(array('main.css'));
-        $this->_oTemplate->addJsTranslation(array('_sys_grid_search'));
-        return  $this->_oTemplate->getJsCode('main') . $oGrid->getCode();
+        return $this->getBlockManage('requests');
+    }
+    
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_manage_invites get_block_manage_requests
+     * 
+     * @code bx_srv('bx_invites', 'get_block_manage_invites', [...]); @endcode
+     * 
+     * Get page block with manage invitations table.
+     *
+     * @return HTML string with block content to display on the site or empty string if something is wrong. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockManageInvites
+     */
+    /** 
+     * @ref bx_invites-get_block_manage_invites "get_block_manage_invites"
+     */
+    public function serviceGetBlockManageInvites()
+    {
+        return $this->getBlockManage('invites');
     }
 
     /**
@@ -269,8 +283,6 @@ class BxInvModule extends BxDolModule
     public function serviceAccountAddFormCheck()
     {
         $sReturn = '';
-        if (!$this->_oConfig->isRegistrationByInvitation())
-            return $sReturn;
 
         $oSession = BxDolSession::getInstance();
         $sKeyCode = $this->_oConfig->getKeyCode();
@@ -345,8 +357,11 @@ class BxInvModule extends BxDolModule
     }
     
     
+    public function attachAccountIdToInvite($iAccountId, $sKey)
+    {
+        $this->_oDb->attachAccountIdToInvite($iAccountId, $sKey);
+    }
     
-
     public function invite($sType, $sEmails, $sText, $mixedLimit = false, $oForm = null)
     {
         $iProfileId = $this->getProfileId();
@@ -448,6 +463,12 @@ class BxInvModule extends BxDolModule
         $aCheckResult = checkActionModule($iProfileId, 'delete request', $this->getName(), $bPerform);
         return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
     }
+    
+    public function isAllowedDeleteInvite($iProfileId, $bPerform = false)
+    {
+        $aCheckResult = checkActionModule($iProfileId, 'delete invite', $this->getName(), $bPerform);
+        return $aCheckResult[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED ? $aCheckResult[CHECK_ACTION_MESSAGE] : true;
+    }
 
     public function getProfileId()
     {
@@ -472,15 +493,6 @@ class BxInvModule extends BxDolModule
         return $oProfile->getAccountId();
     }
 
-    protected function onInvite($iAccountId, $iProfileId)
-    {
-        $this->isAllowedInvite($iProfileId, true);
-
-        //--- Event -> Invite for Alerts Engine ---//
-        bx_alert($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
-        //--- Event -> Invite for Alerts Engine ---//
-    }
-
     public function onRequest($iRequestId)
     {
         //--- Event -> Request for Alerts Engine ---//
@@ -500,7 +512,33 @@ class BxInvModule extends BxDolModule
         bx_import('FormCheckerHelper', $this->_aModule);
         return BxDolForm::getObjectInstance($this->_oConfig->getObject('form_invite'), $sDisplay);
     }
+    
+    protected function getBlockManage($sType)
+    {
+        $this->_oTemplate->addJs('jquery.form.min.js');
+        $this->_oTemplate->addJs('main.js');
+        $oGrid = BxDolGrid::getObjectInstance($this->_oConfig->getObject('grid_' . $sType));
+        if(!$oGrid)
+            return '';
 
+        $this->_oTemplate->addCss(array('main.css'));
+        $this->_oTemplate->addJsTranslation(array('_sys_grid_search'));
+       
+        return array(
+           'menu' => $this->_oTemplate->getMenuForManageBlocks($sType),
+           'content' => $this->_oTemplate->getJsCode2('main', $sType) . $oGrid->getCode()
+       );
+    }
+
+    protected function onInvite($iAccountId, $iProfileId)
+    {
+        $this->isAllowedInvite($iProfileId, true);
+
+        //--- Event -> Invite for Alerts Engine ---//
+        bx_alert($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
+        //--- Event -> Invite for Alerts Engine ---//
+    }
+    
     protected function getJoinLink($sKey)
     {
         $sKeyCode = $this->_oConfig->getKeyCode();
@@ -513,11 +551,7 @@ class BxInvModule extends BxDolModule
     {
         return  BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'SetSeenMark/' . $sKey . "/";
     }
-    
-    public function attachAccountIdToInvite($iAccountId, $sKey)
-    {
-        $this->_oDb->attachAccountIdToInvite($iAccountId, $sKey);
-    }
+
 }
 
 /** @} */

+ 47 - 3
modules/boonex/invites/classes/BxInvResponse.php

@@ -45,9 +45,6 @@ class BxInvResponse extends BxDolAlertsResponse
 
     protected function _processAccountAdded($oAlert)
     {
-        if(!$this->_oModule->_oConfig->isRegistrationByInvitation())
-            return;
-
         $sKeyCode = $this->_oModule->_oConfig->getKeyCode();
         $sKey = BxDolSession::getInstance()->getUnsetValue($sKeyCode);
         if($sKey === false)
@@ -67,6 +64,22 @@ class BxInvResponse extends BxDolAlertsResponse
         return;
     }
 
+    protected function _processProfileAdd($oAlert)
+    {
+        if (getParam('bx_invites_automatically_befriend') != 'on')
+            return;
+        
+        $oProfile = BxDolProfile::getInstanceMagic($oAlert->iObject);
+        if ($oProfile && $oProfile->isActAsProfile()){
+            $iProfileInvitor = $this->_oModule->_oDb->getInvites(array('type' => 'profile_id_by_joined_account_id', 'value' => $oProfile->getAccountId()));
+            if ($iProfileInvitor){
+                $oConnFrinds = BxDolConnection::getObjectInstance('sys_profiles_friends');
+                $oConnFrinds->addConnection($oAlert->iObject, $iProfileInvitor);
+                $oConnFrinds->addConnection($iProfileInvitor, $oAlert->iObject);
+            }
+        }  
+    }
+    
     protected function _processProfileDelete($oAlert)
     {
         $this->_oModule->_oDb->deleteInvites(array('profile_id' => $oAlert->iObject));
@@ -76,6 +89,37 @@ class BxInvResponse extends BxDolAlertsResponse
     {
         $this->_oModule->_oDb->deleteInvitesByAccount(array('joined_account_id' => $oAlert->iObject));
     }
+    
+    protected function _processBxAnalyticsGetModules($oAlert)
+    {
+        $oAlert->aExtras['list'][$this->_oModule->_aModule['name']] = $this->_oModule->_aModule['title'];
+    }
+    
+    protected function _processBxAnalyticsGetReports($oAlert)
+    {
+        if ($this->_oModule->_aModule['name'] == $oAlert->aExtras['module']){
+            $oAlert->aExtras['list'] = array();
+            $oAlert->aExtras['list']['content_total_invited'] = _t('_bx_invites_reports_for_analytics_invited_total');
+            $oAlert->aExtras['list']['content_speed_invited'] = _t('_bx_invites_reports_for_analytics_invited_speed_grows');
+            $oAlert->aExtras['list']['content_total_invitation'] = _t('_bx_invites_reports_for_analytics_invitation_total');
+            $oAlert->aExtras['list']['content_speed_invitation'] = _t('_bx_invites_reports_for_analytics_invitation_speed_grows');
+        }
+    }
+    
+    protected function _processBxAnalyticsGetChartDataLine($oAlert)
+    {
+        if ($this->_oModule->_aModule['name'] == $oAlert->aExtras['module']){
+            $bIsInvited = false; 
+            if (substr_count($oAlert->aExtras['report_name'], '_invited') > 0)
+                $bIsInvited = true; 
+            
+            if (substr_count($oAlert->aExtras['report_name'], '_total_') > 0)
+                $oAlert->aExtras['report_type'] = BX_ANALYTICS_CONTENT_TOTAL;
+            
+            $oAlert->aExtras['data'] = $this->_oModule->_oDb->getDataForCharts($oAlert->aExtras['date_from'], $oAlert->aExtras['date_to'], $bIsInvited);
+            $oAlert->aExtras['prev_value'] = $this->_oModule->_oDb->getInitValueForCharts($oAlert->aExtras['date_from'], $bIsInvited);
+        }
+    }
 }
 
 /** @} */

+ 27 - 4
modules/boonex/invites/classes/BxInvTemplate.php

@@ -184,15 +184,38 @@ class BxInvTemplate extends BxBaseModGeneralTemplate
 
         return BxTemplFunctions::getInstance()->popupBox($sId, $sTitle, $sContent, true);
     }
-
-    public function getJsCode($sType, $aParams = array(), $bWrap = true)
+    
+    public function getJsCode2($sType, $sGridType)
     {
+        $aParams = array();
         $aParams = array_merge(array(
             'aHtmlIds' => $this->_oConfig->getHtmlIds(),
-            'sObjNameGrid' => $this->_oConfig->getObject('grid_requests'),
+            'sObjNameGrid' => $this->_oConfig->getObject('grid_' . $sGridType),
         ), $aParams);
 
-        return parent::getJsCode($sType, $aParams, $bWrap);
+        return parent::getJsCode($sType, $aParams);
+    }
+
+    public function getMenuForManageBlocks($sType)
+    {
+        $CNF = &$this->_oConfig->CNF;
+        
+        $sMenu = '';
+		$oPermalink = BxDolPermalinks::getInstance();
+
+		$aMenuItems = array();
+		$aMenuItems[] = array('id' => 'invites-requests', 'name' => 'invites-requests', 'class' => '', 'link' => $oPermalink->permalink($CNF['URL_REQUESTS']), 'target' => '_self', 'title' => _t('_bx_invites_menu_item_title_manage_requests'), 'active' => 1);
+		$aMenuItems[] = array('id' => 'invites-invites', 'name' => 'invites-invites', 'class' => '', 'link' => $oPermalink->permalink($CNF['URL_INVITES']), 'target' => '_self', 'title' => _t('_bx_invites_menu_item_title_manage_invites'), 'active' => 1);
+
+		if(count($aMenuItems) > 1) {
+	        $oMenu = new BxTemplMenu(array(
+	            'template' => 'menu_vertical.html', 
+	            'menu_items' => $aMenuItems
+	        ), $this);
+	        $oMenu->setSelected($this->getModule()->_aModule['name'], 'invites-' . $sType);
+	        $sMenu = $oMenu->getCode();
+		}
+        return $sMenu;
     }
     
     public function getProfilesByAccount($iAccountId, $iMaxVisible = 2)

+ 33 - 8
modules/boonex/invites/install/langs/en.xml

@@ -49,32 +49,46 @@
 	<string name="_bx_invites_grid_action_title_adm_delete"><![CDATA[Delete]]></string>
   <string name="_bx_invites_grid_action_title_adm_add"><![CDATA[Send invitations]]></string>
 
+  <string name="_bx_invites_grid_invites_column_title_email"><![CDATA[Email]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date"><![CDATA[Date]]></string>
+  <string name="_bx_invites_grid_invites_column_title_who_sent"><![CDATA[Who sent]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date_seen"><![CDATA[Date seen]]></string>
+  <string name="_bx_invites_grid_invites_column_title_joined_account"><![CDATA[Joined account]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date_joined"><![CDATA[Date joined]]></string>
+  <string name="_bx_invites_grid_invites_column_title_request"><![CDATA[Request]]></string>
+  <string name="_bx_invites_grid_txt_account_manager"><![CDATA[Redirect to manage account.]]></string>
+  <string name="_bx_invites_grid_txt_view_request"><![CDATA[View request]]></string>
 
   <!-- Pages and Blocks -->
 	<string name="_bx_invites_page_title_sys_invite"><![CDATA[Invite]]></string>
 	<string name="_bx_invites_page_title_invite"><![CDATA[Invite]]></string>
-        <string name="_bx_invites_page_block_title_system_invite_form"><![CDATA[Invite Form]]></string>
+<string name="_bx_invites_page_block_title_system_invite_form"><![CDATA[Invite Form]]></string>
 	<string name="_bx_invites_page_block_title_invite_form"><![CDATA[Invite]]></string>
 
 	<string name="_bx_invites_page_title_sys_request"><![CDATA[Request Invitation]]></string>
 	<string name="_bx_invites_page_title_request"><![CDATA[Request Invitation]]></string>
 	<string name="_bx_invites_page_block_title_request_form"><![CDATA[Request Invitation]]></string>
 
-	<string name="_bx_invites_page_title_sys_requests"><![CDATA[Manage Requests]]></string>
-	<string name="_bx_invites_page_title_requests"><![CDATA[Manage Requests]]></string>
-	<string name="_bx_invites_page_block_title_requests"><![CDATA[Manage Requests]]></string>
+	<string name="_bx_invites_page_title_sys_requests"><![CDATA[Manage Invites]]></string>
+	<string name="_bx_invites_page_title_invites"><![CDATA[Manage Invites]]></string>
+	<string name="_bx_invites_page_block_title_invites"><![CDATA[Manage Invites]]></string>
 
 	<string name="_bx_invites_page_block_title_invite"><![CDATA[Invite]]></string>
 
+  <string name="_bx_invites_page_title_sys_invites"><![CDATA[Manage Requests]]></string>
+  <string name="_bx_invites_page_title_requests"><![CDATA[Manage Requests]]></string>
+  <string name="_bx_invites_page_block_title_requests"><![CDATA[Manage Requests]]></string>
 
 	<!-- Menus -->
 	<string name="_bx_invites_menu_item_title_system_admt_requests"><![CDATA[Invitation requests]]></string>
 	<string name="_bx_invites_menu_item_title_admt_requests"><![CDATA[Invitations]]></string>
 	<string name="_bx_invites_menu_item_title_requests"><![CDATA[Requests]]></string>
   <string name="_bx_invites_menu_dashboard_manage_tools_addon_counter1_caption"><![CDATA[awaiting]]></string>
-
+  <string name="_bx_invites_menu_item_title_manage_requests"><![CDATA[Manage requests]]></string>
+  <string name="_bx_invites_menu_item_title_manage_invites"><![CDATA[Manage invites]]></string>
 
   <!-- Options -->
+  <string name="_bx_invites_option_automatically_befriend"><![CDATA[Enable automatically befriend inviter and invited]]></string>
 	<string name="_bx_invites_option_count_per_user"><![CDATA[How many invitations one user can send]]></string>
 	<string name="_bx_invites_option_key_lifetime"><![CDATA[Invitation key lifetime (in days)]]></string>
 	<string name="_bx_invites_option_enable_request_invite"><![CDATA[Enable invitation requests by email]]></string>
@@ -87,7 +101,7 @@
 	<string name="_bx_invites_acl_action_invite"><![CDATA[Invite]]></string>
 	<string name="_bx_invites_acl_action_request"><![CDATA[Request Invitation]]></string>
 	<string name="_bx_invites_acl_action_delete_request"><![CDATA[Delete invitation requests]]></string>
-
+  <string name="_bx_invites_acl_action_delete_invite"><![CDATA[Delete invite]]></string>
 
 	<!-- Email Templates -->
 	<string name="_bx_invites_et_invite_form_message"><![CDATA[Invite form message.]]></string>
@@ -137,7 +151,8 @@
 	<string name="_bx_invites_err_limit_reached"><![CDATA[The number of invitations sent by you reached the limit.]]></string>
 	<string name="_bx_invites_err_not_available"><![CDATA[The feature is not available now. Please, try again later.]]></string>
 	<string name="_bx_invites_err_invite"><![CDATA[Cannot send an invitation on request.]]></string>
-	<string name="_bx_invites_err_delete_request"><![CDATA[Cannot delete the request.]]></string>
+	<string name="_bx_invites_err_delete_invite"><![CDATA[Cannot delete the invite.]]></string>
+  <string name="_bx_invites_err_delete_request"><![CDATA[Cannot delete the request.]]></string>
 	<string name="_bx_invites_err_used"><![CDATA[The invitation link isn't available or already used.]]></string>
   <string name="_bx_invites_err_already_send"><![CDATA[The request already sent for this email.]]></string>
   <string name="_bx_invites_err_already_registed"><![CDATA[User with this email already registered. Please use  <a href="{0}">forgot password</a> to restore access to your account.]]></string>
@@ -150,9 +165,19 @@
   <string name="_bx_invites_request_status_for_filter_invited"><![CDATA[Requests with invites]]></string>
   <string name="_bx_invites_request_status_for_filter_seen"><![CDATA[Invite seen]]></string>
   <string name="_bx_invites_request_status_for_filter_joined"><![CDATA[Joined]]></string>
+
+  <string name="_bx_invites_invites_status_for_filter_all"><![CDATA[All invites]]></string>
+  <string name="_bx_invites_invites_status_for_filter_accepted"><![CDATA[Accepted invites]]></string>
+  <string name="_bx_invites_invites_status_for_filter_not_accepted"><![CDATA[Not accepted invites]]></string>
+
   <string name="_bx_invites_title_date_invite_sent"><![CDATA[Date sent]]></string>
   <string name="_bx_invites_title_date_invite_seen"><![CDATA[Date seen]]></string>
-  
+
+  <string name="_bx_invites_reports_for_analytics_invited_total"><![CDATA[Invited - Total numbers]]></string>
+  <string name="_bx_invites_reports_for_analytics_invited_speed_grows"><![CDATA[Invited - Grows speed]]></string>
+  <string name="_bx_invites_reports_for_analytics_invitation_total"><![CDATA[Invitation - Total numbers]]></string>
+  <string name="_bx_invites_reports_for_analytics_invitation_speed_grows"><![CDATA[Invitation - Grows speed]]></string>
+
   <string name="_bx_invites_alert_action_request"><![CDATA[<b class="bx-ntfs-content-profile">{entry_sample}</b> request invitation - <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
   <string name="_bx_invites_alert_action_request_notify_personal"><![CDATA[New requests]]></string>
 </resources>

+ 6 - 0
modules/boonex/invites/install/sql/disable.sql

@@ -25,6 +25,12 @@ DELETE `sys_acl_actions`, `sys_acl_matrix` FROM `sys_acl_actions`, `sys_acl_matr
 DELETE FROM `sys_acl_actions` WHERE `Module` = @sName;
 
 
+-- GRIDS
+DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_invites_requests', 'bx_invites_invites');
+DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_invites_requests', 'bx_invites_invites');
+DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_invites_requests', 'bx_invites_invites');
+
+
 -- EMAIL TEMPLATES
 DELETE FROM `sys_email_templates` WHERE `Module` = @sName;
 

+ 61 - 3
modules/boonex/invites/install/sql/enable.sql

@@ -20,6 +20,11 @@ INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `lay
 INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
 ('bx_invites_requests', 1, @sName, '_bx_invites_page_block_title_requests', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:25:"get_block_manage_requests";}', 0, 1, 1);
 
+INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `uri`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_invites_invites', '_bx_invites_page_title_sys_invites', '_bx_invites_page_title_invites', @sName, 5, 2147483647, 1, 'invites-invites', 'page.php?i=invites-invites', '', '', '', 0, 1, 0, '', '');
+
+INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
+('bx_invites_invites', 1, @sName, '_bx_invites_page_block_title_invites', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:24:"get_block_manage_invites";}', 0, 1, 1);
 
 -- PAGES: add page block on dashboard
 SET @iPBCellDashboard = 3;
@@ -50,8 +55,8 @@ INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `c
 ('bx_invites_enable_request_invite', 'on', @iCategId, '_bx_invites_option_enable_request_invite', 'checkbox', '', '', '', 3),
 ('bx_invites_requests_email', '', @iCategId, '_bx_invites_option_requests_email', 'digit', '', '', '', 4),
 ('bx_invites_enable_reg_by_inv', 'on', @iCategId, '_bx_invites_option_enable_reg_by_inv', 'checkbox', '', '', '', 5),
-('bx_invites_requests_notifications', 'on', @iCategId, '_bx_invites_option_requests_notifications', 'checkbox', '', '', '', 6);
-
+('bx_invites_requests_notifications', 'on', @iCategId, '_bx_invites_option_requests_notifications', 'checkbox', '', '', '', 6),
+('bx_invites_automatically_befriend', 'on', @iCategId, '_bx_invites_option_automatically_befriend', 'checkbox', '', '', '', 7);
 
 -- ACL
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
@@ -62,6 +67,10 @@ INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`,
 (@sName, 'delete request', NULL, '_bx_invites_acl_action_delete_request', '', 0, 1);
 SET @iIdActionDeleteRequest = LAST_INSERT_ID();
 
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+(@sName, 'delete invite', NULL, '_bx_invites_acl_action_delete_invite', '', 0, 1);
+SET @iIdActionDeleteInvite = LAST_INSERT_ID();
+
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
 (@sName, 'invite', NULL, '_bx_invites_acl_action_invite', '', 1, 1);
 SET @iIdActionInvite = LAST_INSERT_ID();
@@ -85,6 +94,10 @@ INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
 (@iModerator, @iIdActionDeleteRequest),
 (@iAdministrator, @iIdActionDeleteRequest),
 
+-- delete invite
+(@iModerator, @iIdActionDeleteInvite),
+(@iAdministrator, @iIdActionDeleteInvite),
+
 -- invite
 (@iAccount, @iIdActionInvite),
 (@iStandard, @iIdActionInvite),
@@ -96,6 +109,47 @@ INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
 (@iPremium, @iIdActionInvite);
 
 
+-- GRIDS
+INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
+('bx_invites_requests', 'Sql', 'SELECT `bx_inv_requests`.* FROM `bx_inv_requests` WHERE 1', 'bx_inv_requests', 'id', 'status, date', '', '', 20, NULL, 'start', '', 'bx_inv_requests`.`name, bx_inv_requests`.`email', '', 'like', '', '', 192, 'BxInvGridRequests', 'modules/boonex/invites/classes/BxInvGridRequests.php'),
+('bx_invites_invites', 'Sql', 'SELECT `bx_inv_invites`.* FROM `bx_inv_invites` WHERE 1', 'bx_inv_invites', 'id', 'date', '', '', 20, NULL, 'start', '', 'email', '', 'like', '', '', 192, 'BxInvGridInvites', 'modules/boonex/invites/classes/BxInvGridInvites.php');
+
+INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
+('bx_invites_requests', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_invites_requests', 'name', '_bx_invites_grid_column_title_name', '14%', 0, '', '', 2),
+('bx_invites_requests', 'email', '_bx_invites_grid_column_title_email', '14%', 1, '25', '', 3),
+('bx_invites_requests', 'nip', '_bx_invites_grid_column_title_nip', '10%', 0, '15', '', 4),
+('bx_invites_requests', 'date', '_bx_invites_grid_column_title_date', '10%', 0, '20', '', 5),
+('bx_invites_requests', 'joined_account', '_bx_invites_grid_column_title_joined_account', '20%', 0, '20', '', 6),
+('bx_invites_requests', 'status', '_bx_invites_grid_column_title_status', '10%', 0, '15', '', 7),
+('bx_invites_requests', 'actions', '', '20%', 0, '', '', 8),
+
+('bx_invites_invites', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_invites_invites', 'email', '_bx_invites_grid_invites_column_title_email', '15%', 1, '25', '', 2),
+('bx_invites_invites', 'who_send', '_bx_invites_grid_invites_column_title_who_sent', '15%', 0, '', '', 3),
+('bx_invites_invites', 'date', '_bx_invites_grid_invites_column_title_date', '10%', 0, '20', '', 4),
+('bx_invites_invites', 'date_seen', '_bx_invites_grid_invites_column_title_date_seen', '10%', 0, '20', '', 5),
+('bx_invites_invites', 'joined_account', '_bx_invites_grid_invites_column_title_joined_account', '15%', 0, '20', '', 6),
+('bx_invites_invites', 'date_joined', '_bx_invites_grid_invites_column_title_date_joined', '10%', 0, '20', '', 7),
+('bx_invites_invites', 'request', '_bx_invites_grid_invites_column_title_request', '13%', 0, '20', '', 8),
+('bx_invites_invites', 'actions', '', '20%', 0, '', '', 8);
+
+
+INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
+('bx_invites_requests', 'bulk', 'invite', '_bx_invites_grid_action_title_adm_invite', '', 0, 0, 1),
+('bx_invites_requests', 'bulk', 'delete', '_bx_invites_grid_action_title_adm_delete', '', 0, 1, 2),
+('bx_invites_requests', 'single', 'info', '_bx_invites_grid_action_title_adm_info', 'info-circle', 1, 0, 1),
+('bx_invites_requests', 'single', 'invite', '_bx_invites_grid_action_title_adm_invite', 'envelope', 1, 0, 2),
+('bx_invites_requests', 'single', 'delete', '_bx_invites_grid_action_title_adm_delete', 'remove', 1, 1, 3),
+('bx_invites_requests', 'single', 'invite_info', '_bx_invites_grid_action_title_adm_invite_info', 'info-circle', 1, 0, 4),
+('bx_invites_requests', 'independent', 'add', '_bx_invites_grid_action_title_adm_add', '', 0, 0, 5),
+
+('bx_invites_invites', 'bulk', 'delete', '_bx_invites_grid_action_title_adm_delete', '', 0, 1, 1),
+('bx_invites_invites', 'single', 'delete', '_bx_invites_grid_action_title_adm_delete', 'remove', 1, 1, 2),
+('bx_invites_invites', 'independent', 'add', '_bx_invites_grid_action_title_adm_add', '', 0, 0, 3);
+
+
+
 -- EMAIL TEMPLATES
 INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `Body`) VALUES 
 (@sName, '_bx_invites_et_invite_form_message', 'bx_invites_invite_form_message', '_bx_invites_et_invite_form_message_subject', '_bx_invites_et_invite_form_message_body'),
@@ -112,4 +166,8 @@ INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
 ('account', 'add_form', @iHandler),
 ('account', 'added', @iHandler),
 ('account', 'delete', @iHandler),
-('profile', 'delete', @iHandler);
+('profile', 'delete', @iHandler),
+('profile', 'add', @iHandler),
+('bx_analytics', 'get_modules', @iHandler),
+('bx_analytics', 'get_reports', @iHandler),
+('bx_analytics', 'get_chart_data_line', @iHandler);

+ 0 - 25
modules/boonex/invites/install/sql/install.sql

@@ -64,31 +64,6 @@ INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_fo
 ('bx_invites_request_send', 'text', 2147483647, 1, 3),
 ('bx_invites_request_send', 'ifr_do_submit', 2147483647, 1, 4);
 
-
--- GRIDS
-INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `field_active`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_fields_translatable`, `filter_mode`, `sorting_fields`, `sorting_fields_translatable`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
-('bx_invites_requests', 'Sql', 'SELECT `bx_inv_requests`.* FROM `bx_inv_requests` WHERE 1', 'bx_inv_requests', 'id', 'status, date', '', '', 20, NULL, 'start', '', 'bx_inv_requests`.`name, bx_inv_requests`.`email', '', 'like', '', '', 192, 'BxInvGridRequests', 'modules/boonex/invites/classes/BxInvGridRequests.php');
-
-INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
-('bx_invites_requests', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
-('bx_invites_requests', 'name', '_bx_invites_grid_column_title_name', '14%', 0, '', '', 2),
-('bx_invites_requests', 'email', '_bx_invites_grid_column_title_email', '14%', 1, '25', '', 3),
-('bx_invites_requests', 'nip', '_bx_invites_grid_column_title_nip', '10%', 0, '15', '', 4),
-('bx_invites_requests', 'date', '_bx_invites_grid_column_title_date', '10%', 0, '20', '', 5),
-('bx_invites_requests', 'joined_account', '_bx_invites_grid_column_title_joined_account', '20%', 0, '20', '', 6),
-('bx_invites_requests', 'status', '_bx_invites_grid_column_title_status', '10%', 0, '15', '', 7),
-('bx_invites_requests', 'actions', '', '20%', 0, '', '', 8);
-
-INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
-('bx_invites_requests', 'bulk', 'invite', '_bx_invites_grid_action_title_adm_invite', '', 0, 0, 1),
-('bx_invites_requests', 'bulk', 'delete', '_bx_invites_grid_action_title_adm_delete', '', 0, 1, 2),
-('bx_invites_requests', 'single', 'info', '_bx_invites_grid_action_title_adm_info', 'info-circle', 1, 0, 1),
-('bx_invites_requests', 'single', 'invite', '_bx_invites_grid_action_title_adm_invite', 'envelope', 1, 0, 2),
-('bx_invites_requests', 'single', 'delete', '_bx_invites_grid_action_title_adm_delete', 'remove', 1, 1, 3),
-('bx_invites_requests', 'single', 'invite_info', '_bx_invites_grid_action_title_adm_invite_info', 'info-circle', 1, 0, 4),
-('bx_invites_requests', 'independent', 'add', '_bx_invites_grid_action_title_adm_add', '', 0, 0, 5);
-
-
 -- STUDIO PAGE & WIDGET
 INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
 (3, @sName, '_bx_invites', '_bx_invites', 'bx_invites@modules/boonex/invites/|std-icon.svg');

+ 0 - 7
modules/boonex/invites/install/sql/uninstall.sql

@@ -10,13 +10,6 @@ DELETE FROM `sys_form_inputs` WHERE `module` = @sName;
 DELETE FROM `sys_form_displays` WHERE `module` = @sName;
 DELETE FROM `sys_objects_form` WHERE `module` = @sName;
 
-
--- GRIDS
-DELETE FROM `sys_objects_grid` WHERE `object` IN ('bx_invites_requests');
-DELETE FROM `sys_grid_fields` WHERE `object` IN ('bx_invites_requests');
-DELETE FROM `sys_grid_actions` WHERE `object` IN ('bx_invites_requests');
-
-
 -- 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`

+ 17 - 0
modules/boonex/protean/data/template/system/scripts/BxTemplServiceWiki.php

@@ -0,0 +1,17 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaTemplate UNA Template Classes
+ * @{
+ */
+
+/**
+ * @see BxBaseServiceWiki
+ */
+class BxTemplServiceWiki extends BxBaseServiceWiki
+{
+}
+
+/** @} */

+ 3 - 0
modules/boonex/russian/data/langs/bx_accounts/ru.xml

@@ -19,6 +19,8 @@
     <string name="_bx_accnt_menu_item_title_edit_email"><![CDATA[Изменить email]]></string>
     <string name="_bx_accnt_menu_item_title_system_resend_cemail"><![CDATA[Переслать подтверждение]]></string>
     <string name="_bx_accnt_menu_item_title_resend_cemail"><![CDATA[Переслать подтверждение]]></string>
+    <string name="_bx_accnt_menu_item_title_system_confirm"><![CDATA[Подтвердить]]></string>
+    <string name="_bx_accnt_menu_item_title_confirm"><![CDATA[Подтвердить]]></string>
     <string name="_bx_accnt_menu_item_title_system_reset_password"><![CDATA[Сбросить пароль]]></string>
     <string name="_bx_accnt_menu_item_title_reset_password"><![CDATA[Сбросить пароль]]></string>
     <string name="_bx_accnt_menu_item_title_system_unlock_account"><![CDATA[Разблокировать]]></string>
@@ -56,6 +58,7 @@
     <string name="_bx_accnt_grid_column_title_adm_logged"><![CDATA[Последнее посещение]]></string>
     <string name="_bx_accnt_grid_action_title_adm_activate"><![CDATA[Активировать]]></string>
     <string name="_bx_accnt_grid_action_title_adm_suspend"><![CDATA[Заблокировать]]></string>
+    <string name="_bx_accnt_grid_action_title_adm_confirm"><![CDATA[Подтвердить]]></string>
     <string name="_bx_accnt_grid_action_title_adm_edit_email"><![CDATA[Изменить email]]></string>
     <string name="_bx_accnt_grid_action_title_adm_resend_cemail"><![CDATA[Переслать подтверждение]]></string>
     <string name="_bx_accnt_grid_action_title_adm_reset_password"><![CDATA[Сбросить пароль]]></string>

+ 49 - 12
modules/boonex/russian/data/langs/bx_invites/ru.xml

@@ -37,9 +37,27 @@
 	<string name="_bx_invites_grid_column_title_nip"><![CDATA[IP]]></string>
 	<string name="_bx_invites_grid_column_title_date"><![CDATA[Дата]]></string>
 
-	<string name="_bx_invites_grid_action_title_adm_info"><![CDATA[Инфо]]></string>
-	<string name="_bx_invites_grid_action_title_adm_invite"><![CDATA[Пригласить]]></string>
-	<string name="_bx_invites_grid_action_title_adm_delete"><![CDATA[Удалить]]></string>
+  <string name="_bx_invites_grid_column_title_date_invite"><![CDATA[Дата приглашения]]></string>
+  <string name="_bx_invites_grid_column_title_date_seen"><![CDATA[Дата просмотра]]></string>
+  <string name="_bx_invites_grid_column_title_date_joined"><![CDATA[Дата присоединения]]></string>
+  <string name="_bx_invites_grid_column_title_joined_account"><![CDATA[Присоединился]]></string>
+  <string name="_bx_invites_grid_column_title_status"><![CDATA[Статус]]></string>
+
+  <string name="_bx_invites_grid_action_title_adm_info"><![CDATA[Инфо]]></string>
+  <string name="_bx_invites_grid_action_title_adm_invite_info"><![CDATA[Информация о приглашении]]></string>
+  <string name="_bx_invites_grid_action_title_adm_invite"><![CDATA[Пригласить]]></string>
+  <string name="_bx_invites_grid_action_title_adm_delete"><![CDATA[Удалить]]></string>
+  <string name="_bx_invites_grid_action_title_adm_add"><![CDATA[Отправить приглашения]]></string>
+
+  <string name="_bx_invites_grid_invites_column_title_email"><![CDATA[Эл. адрес]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date"><![CDATA[Дата]]></string>
+  <string name="_bx_invites_grid_invites_column_title_who_sent"><![CDATA[Кто отправил]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date_seen"><![CDATA[Дата отправки]]></string>
+  <string name="_bx_invites_grid_invites_column_title_joined_account"><![CDATA[Присоединившийся]]></string>
+  <string name="_bx_invites_grid_invites_column_title_date_joined"><![CDATA[Дата присоединения]]></string>
+  <string name="_bx_invites_grid_invites_column_title_request"><![CDATA[Запрос]]></string>
+  <string name="_bx_invites_grid_txt_account_manager"><![CDATA[К управлению аккаунтом]]></string>
+  <string name="_bx_invites_grid_txt_view_request"><![CDATA[Просмотреть запрос]]></string>
 
 
 	<!-- Pages and Blocks -->
@@ -52,22 +70,28 @@
 	<string name="_bx_invites_page_title_request"><![CDATA[Запросить приглашение]]></string>
 	<string name="_bx_invites_page_block_title_request_form"><![CDATA[Запросить приглашение]]></string>
 
-	<string name="_bx_invites_page_title_sys_requests"><![CDATA[Управление приглашениями]]></string>
-	<string name="_bx_invites_page_title_requests"><![CDATA[Управление приглашениями]]></string>
-	<string name="_bx_invites_page_block_title_requests"><![CDATA[Управление приглашениями]]></string>
-
-	<string name="_bx_invites_page_block_title_invite"><![CDATA[Пригласить]]></string>
+  <string name="_bx_invites_page_title_sys_requests"><![CDATA[Управление запросами]]></string>
+  <string name="_bx_invites_page_title_requests"><![CDATA[Управление запросами]]></string>
+  <string name="_bx_invites_page_block_title_requests"><![CDATA[Управление запросами]]></string>
 
+  <string name="_bx_invites_page_title_invites"><![CDATA[Управление приглашениями]]></string>
+  <string name="_bx_invites_page_block_title_invites"><![CDATA[Управление приглашениями]]></string>
+  <string name="_bx_invites_page_block_title_invite"><![CDATA[Пригласить]]></string>
+  <string name="_bx_invites_page_title_sys_invites"><![CDATA[Управление приглашениями]]></string>
 
+  
 	<!-- Menus -->
 	<string name="_bx_invites_menu_item_title_system_admt_requests"><![CDATA[Запросы на приглашение]]></string>
 	<string name="_bx_invites_menu_item_title_admt_requests"><![CDATA[Приглашения]]></string>
 	<string name="_bx_invites_menu_item_title_requests"><![CDATA[Запросы]]></string>
   <string name="_bx_invites_menu_dashboard_manage_tools_addon_counter1_caption"><![CDATA[в ожидании]]></string>
+  <string name="_bx_invites_menu_item_title_manage_requests"><![CDATA[Управление приглашениями]]></string>
+  <string name="_bx_invites_menu_item_title_manage_invites"><![CDATA[Управление запросами]]></string>
 
 
 	<!-- Options -->
-	<string name="_bx_invites_option_count_per_user"><![CDATA[Сколько приглашений может послать один пользователь]]></string>
+  <string name="_bx_invites_option_automatically_befriend"><![CDATA[Автоматическая дружба между приглашающим и приглашенным]]></string>
+  <string name="_bx_invites_option_count_per_user"><![CDATA[Сколько приглашений может послать один пользователь]]></string>
 	<string name="_bx_invites_option_key_lifetime"><![CDATA[Срок действия ключа приглашения (в днях)]]></string>
 	<string name="_bx_invites_option_enable_request_invite"><![CDATA[Разрешить запросы на приглашение]]></string>
 	<string name="_bx_invites_option_requests_email"><![CDATA[Эл. адреса для посылки запросов на приглашение (разделенение запятой)]]></string>
@@ -78,6 +102,7 @@
 	<string name="_bx_invites_acl_action_invite"><![CDATA[Пригласить]]></string>
 	<string name="_bx_invites_acl_action_request"><![CDATA[Запросить приглашение]]></string>
 	<string name="_bx_invites_acl_action_delete_request"><![CDATA[Удалить запросы на приглашение]]></string>
+  <string name="_bx_invites_acl_action_delete_invite"><![CDATA[Удалить приглашение]]></string>
 
 
 	<!-- Email Templates -->
@@ -126,6 +151,7 @@
 	<string name="_bx_invites_err_limit_reached"><![CDATA[Число посланных Вами приглашений достигло лимита.]]></string>
 	<string name="_bx_invites_err_not_available"><![CDATA[Эта функция сейчас недоступна. Пожалуйста, попытайтесь ещё раз позднее.]]></string>
 	<string name="_bx_invites_err_invite"><![CDATA[Невозможно послать приглашение по запросу.]]></string>
+  <string name="_bx_invites_err_delete_invite"><![CDATA[Невозможно удалить приглашение.]]></string>
 	<string name="_bx_invites_err_delete_request"><![CDATA[Невозможно удалить запрос.]]></string>
 	<string name="_bx_invites_err_used"><![CDATA[Приглашение не доступно или уже использовано.]]></string>
 	<string name="_bx_invites_err_already_send"><![CDATA[Приглашение уже было отправлено на этот эл. адрес]]></string>
@@ -139,9 +165,20 @@
 	<string name="_bx_invites_request_status_for_filter_invited"><![CDATA[Запросы с приглашениями]]></string>
 	<string name="_bx_invites_request_status_for_filter_seen"><![CDATA[Приглашение просмотрено]]></string>
 	<string name="_bx_invites_request_status_for_filter_joined"><![CDATA[Присоединился]]></string>
-	<string name="_bx_invites_title_date_invite_sent"><![CDATA[Дата отправки]]></string>
+
+  <string name="_bx_invites_invites_status_for_filter_all"><![CDATA[Все приглашения]]></string>
+  <string name="_bx_invites_invites_status_for_filter_accepted"><![CDATA[Принятые приглашения]]></string>
+  <string name="_bx_invites_invites_status_for_filter_not_accepted"><![CDATA[Не принятые приглашения]]></string>
+
+  <string name="_bx_invites_title_date_invite_sent"><![CDATA[Дата отправки]]></string>
 	<string name="_bx_invites_title_date_invite_seen"><![CDATA[Дата просмотра]]></string>
 
-	<string name="_bx_invites_alert_action_request"><![CDATA[<b class="bx-ntfs-content-profile">{entry_sample}</b> запросил приглашение - <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
-        <string name="_bx_invites_alert_action_request_notify_personal"><![CDATA[Новые запросы]]></string>
+  <string name="_bx_invites_reports_for_analytics_invited_total"><![CDATA[Приглашенные - Общее количество]]></string>
+  <string name="_bx_invites_reports_for_analytics_invited_speed_grows"><![CDATA[Приглашенные - Динамика роста]]></string>
+  <string name="_bx_invites_reports_for_analytics_invitation_total"><![CDATA[Приглашения - Общее количество]]></string>
+  <string name="_bx_invites_reports_for_analytics_invitation_speed_grows"><![CDATA[Приглашения - Динамика роста]]></string>
+
+
+  <string name="_bx_invites_alert_action_request"><![CDATA[<b class="bx-ntfs-content-profile">{entry_sample}</b> запросил приглашение - <b class="bx-ntfs-content-entry">{entry_caption}</b>]]></string>
+  <string name="_bx_invites_alert_action_request_notify_personal"><![CDATA[Новые запросы]]></string>
 </resources>

+ 4 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -3000,4 +3000,8 @@
 	<string name="_sys_option_per_page_browse_showcase"><![CDATA[Количество позиций при отображении витриной]]></string>
   <string name="_sys_option_per_page_browse_recommended"><![CDATA[Количество позиций при отображении рекомендованных]]></string>
   <string name="_sys_javascript_requred"><![CDATA[Для корректной работы нужен включенный JavaScript! Пожалуйста, включите его в барузере!]]></string>
+	<string name="_sys_wiki_system_title"><![CDATA[Системная Вики]]></string>
+	<string name="_sys_wiki_error_page_exists"><![CDATA[Страница с таким именем ({0}) уже существует]]></string>
+    <string name="_sys_wiki_error_missing_wiki_object"><![CDATA[Вики объект ({0}) не найден]]></string>
+
 </resources>

+ 2 - 6
page.php

@@ -14,18 +14,14 @@ bx_import('BxDolLanguages');
 
 check_logged();
 
-$oTemplate = BxDolTemplate::getInstance();
-
 $oPage = BxDolPage::getObjectInstanceByURI();
 if ($oPage) {
 
-    $oTemplate->setPageNameIndex (BX_PAGE_DEFAULT);
-    $oTemplate->setPageType ($oPage->getType());
-    $oTemplate->setPageContent ('page_main_code', $oPage->getCode());
-    $oTemplate->getPageCode();
+    $oPage->displayPage();
 
 } else {
 
+    $oTemplate = BxDolTemplate::getInstance();
     $oTemplate->displayPageNotFound();
 }
 

+ 32 - 0
r.php

@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaCore UNA Core
+ * @{
+ */
+
+require_once('./inc/header.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");
+
+bx_import('BxDolLanguages');
+
+check_logged();
+
+$sRequest = ltrim($_GET['_q'], '/');
+$sPath = parse_url(BX_DOL_URL_ROOT, PHP_URL_PATH);
+if ($sPath && '/' != $sPath)
+    $sRequest = bx_ltrim_str($sRequest, rtrim($sPath, '/'));
+
+$aRewriteRules = BxDolRewriteRulesQuery::getActiveRules();
+foreach ($aRewriteRules as $a) {
+    if (preg_match('#'.$a['preg'].'#i', $sRequest, $aMatches)) {
+        BxDolService::callSerialized($a['service'], $aMatches);
+        exit;
+    }
+}
+
+BxDolTemplate::getInstance()->displayPageNotFound();
+
+/** @} */

+ 21 - 0
template/scripts/BxBasePage.php

@@ -363,6 +363,27 @@ class BxBasePage extends BxDolPage
         return $s;
     }
 
+    /**
+     * Get content for 'wiki' block type.
+     * @return string
+     */
+    protected function _getBlockWiki ($aBlock)
+    {
+        $oWiki = BxDolWiki::getObjectInstance($this->_aObject['module']);
+        if (!$oWiki) {
+            $sContent = _t('_sys_wiki_error_missing_wiki_object', $this->_aObject['module']);
+        } 
+        else {
+            $sContent = $oWiki->getBlockContent($aBlock['id']);
+            $sContent = bx_process_macros($sContent);
+        }
+
+        $s = '<div class="bx-page-wiki-container">' . $sContent . '</div>';
+        $s = $this->_replaceMarkers($s);
+        $s = bx_process_macros($s);
+        return $s;
+    }
+
     /**
      * Get content for 'lang' block type.
      * @return string

+ 67 - 0
template/scripts/BxBaseServiceWiki.php

@@ -0,0 +1,67 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    UnaBaseView UNA Base Representation Classes
+ * @{
+ */
+
+/**
+ * Services for Wiki functionality
+ */
+class BxBaseServiceWiki extends BxDol
+{
+
+    /**
+     * @page service Service Calls
+     * @section bx_system_general System Services 
+     * @subsection bx_system_general-wiki Wiki
+     * @subsubsection bx_system_general-wiki_page wiki_page
+     * 
+     * @code bx_srv('system', 'wiki_page', ["index"], 'TemplServiceWiki'); @endcode
+     * @code {{~system:wiki_page:TemplServiceWiki["index"]~}} @endcode
+     * 
+     * Display WIKI page.
+     * @param $sUri categories object name
+     * 
+     * @see BxBaseServiceWiki::serviceWikiPage
+     */
+    /** 
+     * @ref bx_system_general-wiki_page "wiki_page"
+     */
+    public function serviceWikiPage ($sWikiObject, $sUri)
+    {
+        $oWiki = BxDolWiki::getObjectInstance($sWikiObject);
+        if (!$oWiki) {
+            $oTemplate = BxDolTemplate::getInstance();
+            $oTemplate->displayPageNotFound();
+            return;
+        }
+
+        $oPage = BxDolPage::getObjectInstanceByModuleAndURI($sWikiObject, $sUri);
+        if ($oPage) {
+
+            $oPage->displayPage();
+
+        } else {
+
+            if ($oWiki->isAllowed('add')) {
+                $oPage = BxDolPage::getObjectInstanceByURI($sUri);
+                if ($oPage) {
+                    $oTemplate = BxDolTemplate::getInstance();
+                    $oTemplate->displayErrorOccured(_t("_sys_wiki_error_page_exists", bx_process_output($sUri)));
+                } else {
+                    echo "TODO: wiki - suggest to create page with specified URI";
+                }
+            } 
+            else {
+                $oTemplate = BxDolTemplate::getInstance();
+                $oTemplate->displayPageNotFound();
+            }
+        }
+
+    }
+}
+
+/** @} */

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