Просмотр исходного кода

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

romanlesnikov 1 год назад
Родитель
Сommit
79ab4d23f7

+ 107 - 81
modules/base/groups/classes/BxBaseModGroupsModule.php

@@ -472,95 +472,120 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
         return false;
     }
 
+    public function serviceAddInvitation ($iContextPid, $iPid, $iPerformerPid = 0)
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oGroupProfile = false;
+        if(!($oGroupProfile = BxDolProfile::getInstance($iContextPid)))
+            return false;
+
+        if(!($aContentInfo = $this->_oDb->getContentInfoById((int)$oGroupProfile->getContentId())))
+            return false;
+
+        $oConnection = false;
+        if(!isset($CNF['OBJECT_CONNECTIONS']) || !($oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS'])))
+            return false;
+
+        if($oConnection->isConnected((int)$iPid, $iContextPid) || $oConnection->isConnected($iContextPid, (int)$iPid))
+            return false;
+
+        if(!$iPerformerPid)
+            $iPerformerPid = bx_get_logged_profile_id();
+
+        $sEntryUrl = BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
+        if(!empty($CNF['TABLE_INVITES']) && !$this->_oDb->isInviteByInvited($iPid, $iContextPid)) {
+            $sKey = BxDolKey::getInstance()->getNewKey(false, $CNF['INVITES_KEYS_LIFETIME']);
+
+            $this->_oDb->insertInvite($sKey, $iContextPid, $iPerformerPid, $iPid);
+
+            $sEntryUrl = bx_append_url_params($sEntryUrl, [
+                'key' => $sKey
+            ]);
+        }
+
+        $sModule = $this->getName();
+
+        /**
+         * @hooks
+         * @hookdef hook-bx_base_groups-join_invitation '{module_name}', 'join_invitation' - hook before adding (sending) new join to context invitation
+         * - $unit_name - module name
+         * - $action - equals `join_invitation`
+         * - $object_id - context id
+         * - $sender_id - context profile id
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `content` - [array] context info array as key&value pairs
+         *      - `entry_title` - [string] context title
+         *      - `entry_url` - [string] context URL
+         *      - `group_profile` - [int] context profile id
+         *      - `profile` - [int] profile id who was invited
+         *      - `notification_subobject_id` - [int] profile id who was invited
+         *      - `object_author_id` - [int] context profile id
+         * @hook @ref hook-bx_base_groups-join_invitation
+         */
+        bx_alert($sModule, 'join_invitation', $aContentInfo[$CNF['FIELD_ID']], $iContextPid, [
+            'content' => $aContentInfo, 
+            'entry_title' => $aContentInfo[$CNF['FIELD_NAME']], 
+            'entry_url' => bx_absolute_url($sEntryUrl), 
+            'group_profile' => $iContextPid, 
+            'profile' => $iPid, 
+            'notification_subobject_id' => $iPid, 
+            'object_author_id' => $iContextPid
+        ]);
+
+        /**
+         * 'Invitation Received' alert for Notifications module.
+         * Note. It's essential to use Recipient ($iPid) in 'object_author_id' parameter. 
+         * In this case notification will be received by Recipient profile.
+         */
+        /**
+         * @hooks
+         * @hookdef hook-bx_base_groups-join_invitation_notif '{module_name}', 'join_invitation_notif' - hook before adding new join to context invitation. Is needed for Notifications module.
+         * - $unit_name - module name
+         * - $action - equals `join_invitation_notif`
+         * - $object_id - context id
+         * - $sender_id - context profile id
+         * - $extra_params - array of additional params with the following array keys:
+         *      - `object_author_id` - [int] profile id who was invited
+         *      - `privacy_view` - [int] or [string] privacy for view context action, @see BxDolPrivacy
+         * @hook @ref hook-bx_base_groups-join_invitation_notif
+         */
+        bx_alert($sModule, 'join_invitation_notif', $aContentInfo[$CNF['FIELD_ID']], $iContextPid, [
+            'object_author_id' => $iPid, 
+            'privacy_view' => isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) ? $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 3, 
+        ]);
+
+        return true;
+    }
+
     public function serviceAddMutualConnection ($iGroupProfileId, $iInitiatorId, $bSendInviteOnly = false)
     {        
         $CNF = &$this->_oConfig->CNF;
 
-        list ($iProfileId, $iGroupProfileId, $oGroupProfile) = $this->_prepareProfileAndGroupProfile($iGroupProfileId, $iInitiatorId);
-        if (!$oGroupProfile)
+        list($iProfileId, $iGroupProfileId, $oGroupProfile) = $this->_prepareProfileAndGroupProfile($iGroupProfileId, $iInitiatorId);
+        if(!$oGroupProfile)
             return false;
 
-        if (!($aContentInfo = $this->_oDb->getContentInfoById((int)BxDolProfile::getInstance($iGroupProfileId)->getContentId())))
+        if(!($aContentInfo = $this->_oDb->getContentInfoById((int)BxDolProfile::getInstance($iGroupProfileId)->getContentId())))
             return false;
 
         $oConnection = false;
-        if (!isset($CNF['OBJECT_CONNECTIONS']) || !($oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS'])))
+        if(!isset($CNF['OBJECT_CONNECTIONS']) || !($oConnection = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS'])))
             return false;
 
-        $oPermalinks = BxDolPermalinks::getInstance();
-
         $sEntryTitle = $aContentInfo[$CNF['FIELD_NAME']];
-        $sEntryUrl = bx_absolute_url($oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]));
+        $sEntryUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]));
 
         // send invitation to the group 
-        $sModule = $this->getName();
         $iPerformerId = bx_get_logged_profile_id();
-        if ($bSendInviteOnly && !$oConnection->isConnected((int)$iInitiatorId, $oGroupProfile->id()) && !$oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId) && $iProfileId != $iPerformerId) {
-            /**
-             * Insert invitation.
-             */
-            if(!empty($CNF['TABLE_INVITES']) && !$this->_oDb->isInviteByInvited($iProfileId, $iGroupProfileId)) {
-                $sKey = BxDolKey::getInstance()->getNewKey(false, $CNF['INVITES_KEYS_LIFETIME']);
-
-                $this->_oDb->insertInvite($sKey, $iGroupProfileId, $iPerformerId, $iProfileId);
+        if($bSendInviteOnly)
+            return $iProfileId != $iPerformerId ? $this->serviceAddInvitation($oGroupProfile->id(), $iInitiatorId, $iPerformerId) : false;
 
-                $sEntryUrl = bx_absolute_url($oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'], [
-                    'id' => $aContentInfo[$CNF['FIELD_ID']],
-                    'key' => $sKey
-                ]));
-            }
-
-            /**
-             * @hooks
-             * @hookdef hook-bx_base_groups-join_invitation '{module_name}', 'join_invitation' - hook before adding (sending) new join to context invitation
-             * - $unit_name - module name
-             * - $action - equals `join_invitation`
-             * - $object_id - context id
-             * - $sender_id - context profile id
-             * - $extra_params - array of additional params with the following array keys:
-             *      - `content` - [array] context info array as key&value pairs
-             *      - `entry_title` - [string] context title
-             *      - `entry_url` - [string] context URL
-             *      - `group_profile` - [int] context profile id
-             *      - `profile` - [int] profile id who was invited
-             *      - `notification_subobject_id` - [int] profile id who was invited
-             *      - `object_author_id` - [int] context profile id
-             * @hook @ref hook-bx_base_groups-join_invitation
-             */
-            bx_alert($sModule, 'join_invitation', $aContentInfo[$CNF['FIELD_ID']], $iGroupProfileId, [
-                'content' => $aContentInfo, 
-                'entry_title' => $sEntryTitle, 
-                'entry_url' => $sEntryUrl, 
-                'group_profile' => $iGroupProfileId, 
-                'profile' => $iProfileId, 
-                'notification_subobject_id' => $iProfileId, 
-                'object_author_id' => $iGroupProfileId
-            ]);
+        $sModule = $this->getName();
+        $sModuleGroup = $oGroupProfile->getModule();
 
-            /**
-             * 'Invitation Received' alert for Notifications module.
-             * Note. It's essential to use Recipient ($iInitiatorId) in 'object_author_id' parameter. 
-             * In this case notification will be received by Recipient profile.
-             */
-            /**
-             * @hooks
-             * @hookdef hook-bx_base_groups-join_invitation_notif '{module_name}', 'join_invitation_notif' - hook before adding new join to context invitation. Is needed for Notifications module.
-             * - $unit_name - module name
-             * - $action - equals `join_invitation_notif`
-             * - $object_id - context id
-             * - $sender_id - context profile id
-             * - $extra_params - array of additional params with the following array keys:
-             *      - `object_author_id` - [int] profile id who was invited
-             *      - `privacy_view` - [int] or [string] privacy for view context action, @see BxDolPrivacy
-             * @hook @ref hook-bx_base_groups-join_invitation_notif
-             */
-            bx_alert($sModule, 'join_invitation_notif', $aContentInfo[$CNF['FIELD_ID']], $iGroupProfileId, [
-                'object_author_id' => $iInitiatorId, 
-                'privacy_view' => isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) ? $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']] : 3, 
-            ]);
-        }
         // send notification to group's admins that new connection is pending confirmation 
-        elseif (!$bSendInviteOnly && $oConnection->isConnected((int)$iInitiatorId, $oGroupProfile->id()) && !$oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId) && $aContentInfo['join_confirmation'] && $aContentInfo[$CNF['FIELD_AUTHOR']] != $iProfileId) {
+        if($oConnection->isConnected((int)$iInitiatorId, $oGroupProfile->id()) && !$oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId) && $aContentInfo['join_confirmation'] && $aContentInfo[$CNF['FIELD_AUTHOR']] != $iProfileId) {
             /**
              * @hooks
              * @hookdef hook-bx_base_groups-join_request '{module_name}', 'join_request' - hook before adding new join to context request
@@ -591,7 +616,7 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
             ]);
         }
         // send notification that join request was accepted 
-        else if (!$bSendInviteOnly && $oConnection->isConnected((int)$iInitiatorId, $oGroupProfile->id(), true) && $oGroupProfile->getModule() != $this->getName() && bx_get_logged_profile_id() != $iProfileId) {
+        else if($oConnection->isConnected((int)$iInitiatorId, $oGroupProfile->id(), true) && $sModuleGroup != $sModule && $iProfileId != $iPerformerId) {
             /**
              * @hooks
              * @hookdef hook-bx_base_groups-join_request_accepted '{module_name}', 'join_request_accepted' - hook before accepting join to context request
@@ -612,16 +637,14 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
         }
 
         // new fan was added
-        if ($oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId, true)) {
+        if($oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId, true)) {
             // follow group on join
-            if (BxDolService::call($oGroupProfile->getModule(), 'act_as_profile')){
+            if(bx_srv($sModuleGroup, 'act_as_profile'))
                  $this->addFollower($oGroupProfile->id(), (int)$iInitiatorId);
-            }
-            else{
+            else
                  $this->addFollower((int)$iInitiatorId, $oGroupProfile->id()); 
-            }
 
-            if ($aContentInfo[$CNF['FIELD_AUTHOR']] != $iProfileId) {
+            if($aContentInfo[$CNF['FIELD_AUTHOR']] != $iProfileId) {
                 /**
                  * @hooks
                  * @hookdef hook-bx_base_groups-fan_added '{module_name}', 'fan_added' - hook before adding (registering) new context member
@@ -647,14 +670,14 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
         }
 
         // don't automatically add connection (mutual) if group requires manual join confirmation
-        if ($bSendInviteOnly || $aContentInfo['join_confirmation'])
+        if($aContentInfo['join_confirmation'])
             return false;
 
         // check if connection already exists
-        if ($oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId, true) || $oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId))
+        if($oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId, true) || $oConnection->isConnected($oGroupProfile->id(), (int)$iInitiatorId))
             return false;
 
-        if (!$oConnection->addConnection($oGroupProfile->id(), (int)$iInitiatorId))
+        if(!$oConnection->addConnection($oGroupProfile->id(), (int)$iInitiatorId))
             return false;
 
         return true;
@@ -725,6 +748,9 @@ class BxBaseModGroupsModule extends BxBaseModProfileModule
             return false;
 
         $aInvites = $this->_oDb->getInvites(['sample' => 'invited_pid', 'invited_pid' => $iInvitedPid]);
+        if(empty($aInvites) || !is_array($aInvites))
+            return false;
+
         if($bAsArray)
             return $aInvites;
 

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

@@ -50,6 +50,7 @@ class BxInvConfig extends BxBaseModGeneralConfig
             'form_invite' => $this->_sName . '_invite',
             'form_request' => $this->_sName . '_request',
             'form_display_invite_send' => $this->_sName . '_invite_send',
+            'form_display_invite_accept_by_code' => $this->_sName . '_invite_accept_by_code',
             'form_display_request_send' => $this->_sName . '_request_send',
         );
 

+ 50 - 5
modules/boonex/invites/classes/BxInvModule.php

@@ -247,6 +247,39 @@ class BxInvModule extends BxDolModule
         ];
     }
 
+    /**
+     * @page service Service Calls
+     * @section bx_invites Invitations
+     * @subsection bx_invites-page_blocks Page Blocks
+     * @subsubsection bx_invites-get_block_accept_by_code get_block_accept_by_code
+     * 
+     * @code bx_srv('bx_invites', 'get_block_accept_by_code', [...]); @endcode
+     * 
+     * Get page block with accept invitation (by code) form.
+     *
+     * @return an array describing a block to display on the site. All necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * 
+     * @see BxInvModule::serviceGetBlockAcceptByCode
+     */
+    /** 
+     * @ref bx_invites-get_block_accept_by_code "get_block_accept_by_code"
+     */
+    public function serviceGetBlockAcceptByCode()
+    {
+        $mixedResult = $this->_oTemplate->getBlockAcceptByCode();
+        if($this->_bIsApi)
+            return $mixedResult;
+
+        if(is_array($mixedResult)) {
+            echoJson($mixedResult);
+            exit;
+        }
+
+        return [
+            'content' => $mixedResult
+        ];
+    }
+
     /**
      * @page service Service Calls
      * @section bx_invites Invitations
@@ -602,6 +635,19 @@ class BxInvModule extends BxDolModule
         return $sResult;
     }
 
+    public function processInviteToContext($iPid, $iContextPid)
+    {
+        $oContext = null;
+        if(!$iPid || !$iContextPid || !($oContext = BxDolProfile::getInstance($iContextPid)))
+            return false;
+
+        $sContext = $oContext->getModule();
+        if(!bx_srv('system', 'is_module_context', [$sContext]))
+            return false;
+
+        return bx_srv($sContext, 'add_invitation', [$iContextPid, $iPid]);
+    }
+
     public function isAllowedInvite($iProfileId, $bPerform = false)
     {
         $aCheckResult = checkActionModule($iProfileId, 'invite', $this->getName(), $bPerform);
@@ -724,13 +770,12 @@ class BxInvModule extends BxDolModule
          */
         bx_alert($this->_oConfig->getObject('alert'), 'invite', 0, $iProfileId);
     }
-    
+
     public function getJoinLink($sKey)
     {
-        $sKeyCode = $this->_oConfig->getKeyCode();
-
-        $sJoinUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=create-account'));
-        return bx_append_url_params($sJoinUrl, array($sKeyCode => $sKey));
+        return bx_absolute_url(BxDolPermalinks::getInstance()->permalink('page.php?i=create-account', [
+            $this->_oConfig->getKeyCode() => $sKey
+        ]));
     }
     
     public function getSeenImageUrl($sKey)

+ 2 - 5
modules/boonex/invites/classes/BxInvResponse.php

@@ -131,11 +131,8 @@ class BxInvResponse extends BxDolAlertsResponse
         $bInvite = !empty($aInvite) && is_array($aInvite);
 
         //--- Check 'invite_to_context'
-        if($bInvite && !empty($aInvite['aj_action']) && $aInvite['aj_action'] == 'invite_to_context' && ($iContextPid = (int)$aInvite['aj_params']) != 0) {
-            $oContext = BxDolProfile::getInstance($iContextPid);
-            if($oContext && ($sContext = $oContext->getModule()) && bx_srv('system', 'is_module_context', [$sContext]))
-                bx_srv($sContext, 'add_mutual_connection', [$iContextPid, $oAlert->iObject, true]);
-        }
+        if($bInvite && !empty($aInvite['aj_action']) && $aInvite['aj_action'] == 'invite_to_context')
+            $this->_oModule->processInviteToContext($oAlert->iObject, (int)$aInvite['aj_params']);
 
         //--- Check automatic befriending
         if(getParam('bx_invites_automatically_befriend') == 'on') {

+ 59 - 0
modules/boonex/invites/classes/BxInvTemplate.php

@@ -132,6 +132,65 @@ class BxInvTemplate extends BxBaseModGeneralTemplate
         ]);
     }
 
+    public function getBlockAcceptByCode()
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $oModule = $this->getModule();
+        $sJsObject = $this->_oConfig->getJsObject('main');
+
+        $oForm = $oModule->getFormObjectInvite($this->_oConfig->getObject('form_display_invite_accept_by_code'));
+        $sFormId = $oForm->getId();
+
+        $oForm->initChecker();
+        if(!$oForm->isSubmittedAndValid()) {
+            $sForm = $oForm->getCode();
+
+            if(!$oForm->isSubmitted()) {
+                $this->getCssJs();
+                return $this->_bIsApi ? [bx_api_get_block('form', $oForm->getCodeAPI(), ['ext' => ['request' => ['url' => '/api.php?r=' . $this->_oModule->getName() . '/get_block_accept_by_code', 'immutable' => true]]])] : $this->parseHtmlByName('block_accept_form.html', [
+                    'style_prefix' => $this->_oConfig->getPrefix('style'),
+                    'js_object' => $sJsObject,
+                    'js_code' => $this->getJsCode('main'),
+                    'form' => $sForm,
+                    'form_id' => $sFormId,
+                ]);
+            }
+
+            if(!$oForm->isValid())
+                return $this->_bIsApi ? [bx_api_get_block('form', $oForm->getCodeAPI(), ['ext' => ['request' => ['url' => '/api.php?r=' . $this->_oModule->getName() . '/get_block_accept_by_code', 'immutable' => true]]])] : ['form' => $sForm, 'form_id' => $sFormId];
+        }
+
+        $sKey = $oForm->getCleanValue('key');
+
+        $aInvite = $this->_oDb->getInvites(['type' => 'by_key', 'key' => $sKey]);
+        if(empty($aInvite) || !is_array($aInvite))
+            return ($sMsg = _t('_bx_invites_err_code_not_found')) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : ['msg' => $sMsg];
+
+        if(!isLogged())
+            return ($sJoinLink = $oModule->getJoinLink($sKey)) && $this->_bIsApi ? [bx_api_get_msg('TODO: Need redirect to join.')] : ['redirect' => $sJoinLink];
+
+        $iProfileId = bx_get_logged_profile_id();
+
+        $sRedirectUrl = '';
+        if(!empty($aInvite['aj_action']))
+            switch($aInvite['aj_action']) {
+                case 'redirect':
+                    $sRedirectUrl = $aInvite['aj_params'];
+                    break;
+
+                case 'invite_to_context':
+                    if(($iContextPid = (int)$aInvite['aj_params']) && ($oContext = BxDolProfile::getInstanceMagic($iContextPid)) && $oModule->processInviteToContext($iProfileId, $iContextPid))
+                        $sRedirectUrl = $oContext->getUrl();
+                    break;
+            }
+
+        if(!$sRedirectUrl)
+            return ($sMsg = _t('_bx_invites_err_code_not_applicable')) && $this->_bIsApi ? [bx_api_get_msg($sMsg)] : ['msg' => $sMsg];
+
+        return $this->_bIsApi ? [bx_api_get_msg('TODO: Need redirect to ' . $sRedirectUrl)] : ['redirect' => $sRedirectUrl];
+    }
+
     public function getBlockRequest()
     {
         $sUrl = bx_absolute_url(BxDolPermalinks::getInstance()->permalink($this->_oConfig->CNF['URL_REQUEST']));

+ 19 - 6
modules/boonex/invites/install/langs/en.xml

@@ -6,6 +6,7 @@
     <!-- Forms -->
     <string name="_bx_invites_form_invite"><![CDATA[Invite]]></string>
     <string name="_bx_invites_form_invite_display_send"><![CDATA[Send]]></string>
+    <string name="_bx_invites_form_invite_display_accept_by_code"><![CDATA[Accept (by code)]]></string>
     <string name="_bx_invites_form_invite_input_sys_emails"><![CDATA[Emails]]></string>
     <string name="_bx_invites_form_invite_input_emails"><![CDATA[Emails]]></string>
     <string name="_bx_invites_form_invite_input_emails_inf"><![CDATA[Use semicolon to separate emails.]]></string>
@@ -15,8 +16,13 @@
     <string name="_bx_invites_form_invite_input_sys_text"><![CDATA[Text]]></string>
     <string name="_bx_invites_form_invite_input_text"><![CDATA[Text]]></string>
     <string name="_bx_invites_form_invite_input_text_err"><![CDATA[You need to type the text which will be added to invitation email.]]></string>
-    <string name="_bx_invites_form_invite_input_sys_do_submit"><![CDATA[Send]]></string>
-    <string name="_bx_invites_form_invite_input_do_submit"><![CDATA[Send]]></string>
+    <string name="_bx_invites_form_invite_input_sys_key"><![CDATA[Code]]></string>
+    <string name="_bx_invites_form_invite_input_key"><![CDATA[Code]]></string>
+    <string name="_bx_invites_form_invite_input_key_err"><![CDATA[You need to enter a valid invitation code here.]]></string>
+    <string name="_bx_invites_form_invite_input_sys_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_invites_form_invite_input_do_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_invites_form_invite_input_sys_do_send"><![CDATA[Send]]></string>
+    <string name="_bx_invites_form_invite_input_do_send"><![CDATA[Send]]></string>
 
     <string name="_bx_invites_form_request"><![CDATA[Request Invitation]]></string>
     <string name="_bx_invites_form_request_display_send"><![CDATA[Send]]></string>
@@ -72,16 +78,21 @@
     <string name="_bx_invites_page_title_request"><![CDATA[Request Invitation]]></string>
     <string name="_bx_invites_page_block_title_request_form"><![CDATA[Request Invitation]]></string>
 
-    <string name="_bx_invites_page_title_sys_requests"><![CDATA[Manage Invites]]></string>
+    <string name="_bx_invites_page_title_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_invites"><![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_system_invite_with_redirect"><![CDATA[Invite (with redirect)]]></string>
+    <string name="_bx_invites_page_block_title_system_invite_to_context"><![CDATA[Invite (to context)]]></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>
+    <string name="_bx_invites_page_block_title_system_accept_by_code"><![CDATA[Accept Invitation (by code)]]></string>
+    <string name="_bx_invites_page_block_title_accept_by_code"><![CDATA[Accept Invitation]]></string>
+
 
     <!-- Menus -->
     <string name="_bx_invites_menu_item_title_system_admt_requests"><![CDATA[Invitation requests]]></string>
@@ -161,6 +172,8 @@
     <string name="_bx_invites_err_delete_request"><![CDATA[Cannot delete the request.]]></string>
     <string name="_bx_invites_err_wrong_email"><![CDATA[Email address from invitation can be used only.]]></string>
     <string name="_bx_invites_err_used"><![CDATA[The invitation link isn't available or already used.]]></string>
+    <string name="_bx_invites_err_code_not_found"><![CDATA[The invitation code is invalid.]]></string>
+    <string name="_bx_invites_err_code_not_applicable"><![CDATA[The invitation code isn't applicable.]]></string>
     <string name="_bx_invites_err_already_send"><![CDATA[The request already sent for this email.]]></string>
     <string name="_bx_invites_err_already_registed"><![CDATA[User with this email already registered. Please use  <a href="{0}">forgot password</a> to restore access to your account.]]></string>
     <string name="_bx_invites_request_status_new"><![CDATA[New]]></string>

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

@@ -41,7 +41,9 @@ INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designb
 -- PAGE: service blocks
 SET @iBlockOrder = (SELECT `order` FROM `sys_pages_blocks` WHERE `object` = '' AND `cell_id` = 0 ORDER BY `order` DESC LIMIT 1);
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
-('', 0, @sName, '_bx_invites_page_block_title_system_invite_with_redirect', '_bx_invites_page_block_title_invite', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:10:"bx_invites";s:6:"method";s:16:"get_block_invite";s:6:"params";a:1:{i:0;b:1;}}', 0, 1, 1, @iBlockOrder + 1);
+('', 0, @sName, '_bx_invites_page_block_title_system_invite_with_redirect', '_bx_invites_page_block_title_invite', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:10:"bx_invites";s:6:"method";s:16:"get_block_invite";s:6:"params";a:1:{i:0;b:1;}}', 0, 1, 1, @iBlockOrder + 1),
+('', 0, @sName, '_bx_invites_page_block_title_system_invite_to_context', '_bx_invites_page_block_title_invite', 11, 2147483647, 'service', 'a:3:{s:6:"module";s:10:"bx_invites";s:6:"method";s:27:"get_block_invite_to_context";s:6:"params";a:1:{i:0;s:12:"{profile_id}";}}', 0, 1, 1, @iBlockOrder + 2),
+('', 0, @sName, '_bx_invites_page_block_title_system_accept_by_code', '_bx_invites_page_block_title_accept_by_code', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_invites";s:6:"method";s:24:"get_block_accept_by_code";}', 0, 1, 1, @iBlockOrder + 3);
 
 
 -- MENU: dashboard manage tools

+ 10 - 4
modules/boonex/invites/install/sql/install.sql

@@ -34,22 +34,28 @@ CREATE TABLE IF NOT EXISTS `bx_inv_requests` (
 
 -- FORMS
 INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES
-('bx_invites_invite', @sName, '_bx_invites_form_invite', '', '', 'ifi_do_submit', 'bx_inv_invites', 'id', '', '', 'a:1:{s:14:"checker_helper";s:22:"BxInvFormCheckerHelper";}', 0, 1, '', '');
+('bx_invites_invite', @sName, '_bx_invites_form_invite', '', '', 'a:2:{i:0;s:13:"ifi_do_submit";i:1;s:11:"ifi_do_send";}', 'bx_inv_invites', 'id', '', '', 'a:1:{s:14:"checker_helper";s:22:"BxInvFormCheckerHelper";}', 0, 1, '', '');
 
 INSERT INTO `sys_form_displays` (`display_name`, `module`, `object`, `title`, `view_mode`) VALUES
-('bx_invites_invite_send', @sName, 'bx_invites_invite', '_bx_invites_form_invite_display_send', 0);
+('bx_invites_invite_send', @sName, 'bx_invites_invite', '_bx_invites_form_invite_display_send', 0),
+('bx_invites_invite_accept_by_code', @sName, 'bx_invites_invite', '_bx_invites_form_invite_display_accept_by_code', 0);
 
 INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `checked`, `type`, `caption_system`, `caption`, `info`, `required`, `collapsed`, `html`, `attrs`, `attrs_tr`, `attrs_wrapper`, `checker_func`, `checker_params`, `checker_error`, `db_pass`, `db_params`, `editable`, `deletable`) VALUES
 ('bx_invites_invite', @sName, 'emails', '', '', 0, 'textarea', '_bx_invites_form_invite_input_sys_emails', '_bx_invites_form_invite_input_emails', '_bx_invites_form_invite_input_emails_inf', 1, 0, 0, '', '', '', 'Emails', '', '_bx_invites_form_invite_input_emails_err', '', '', 0, 0),
 ('bx_invites_invite', @sName, 'email_use', 1, '', 0, 'switcher', '_bx_invites_form_invite_input_sys_email_use', '_bx_invites_form_invite_input_email_use', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_invites_invite', @sName, 'text', '', '', 0, 'textarea', '_bx_invites_form_invite_input_sys_text', '_bx_invites_form_invite_input_text', '', 1, 0, 0, '', '', '', 'Length', 'a:2:{s:3:"min";i:10;s:3:"max";i:5000;}', '_bx_invites_form_invite_input_text_err', '', '', 0, 0),
-('bx_invites_invite', @sName, 'ifi_do_submit', '_bx_invites_form_invite_input_do_submit', '', 0, 'submit', '_bx_invites_form_invite_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0);
+('bx_invites_invite', @sName, 'key', '', '', 0, 'text', '_bx_invites_form_invite_input_sys_key', '_bx_invites_form_invite_input_key', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_invites_form_invite_input_key_err', '', '', 0, 0),
+('bx_invites_invite', @sName, 'ifi_do_submit', '_bx_invites_form_invite_input_do_submit', '', 0, 'submit', '_bx_invites_form_invite_input_sys_do_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_invites_invite', @sName, 'ifi_do_send', '_bx_invites_form_invite_input_do_send', '', 0, 'submit', '_bx_invites_form_invite_input_sys_do_send', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0);
 
 INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
 ('bx_invites_invite_send', 'emails', 2147483647, 1, 1),
 ('bx_invites_invite_send', 'email_use', 2147483647, 1, 2),
 ('bx_invites_invite_send', 'text', 2147483647, 1, 3),
-('bx_invites_invite_send', 'ifi_do_submit', 2147483647, 1, 4);
+('bx_invites_invite_send', 'ifi_do_send', 2147483647, 1, 4),
+
+('bx_invites_invite_accept_by_code', 'key', 2147483647, 1, 1),
+('bx_invites_invite_accept_by_code', 'ifi_do_submit', 2147483647, 1, 2);
 
 
 INSERT INTO `sys_objects_form` (`object`, `module`, `title`, `action`, `form_attrs`, `submit_name`, `table`, `key`, `uri`, `uri_title`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES

+ 32 - 12
modules/boonex/invites/js/main.js

@@ -1,5 +1,5 @@
 function BxInvMain(oOptions) {
-	this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUri = oOptions.sActionUri;
     this._sActionsUrl = oOptions.sActionUrl;
     this._sObjName = oOptions.sObjName == undefined ? 'oInvMain' : oOptions.sObjName;
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
@@ -11,32 +11,52 @@ function BxInvMain(oOptions) {
 }
 
 BxInvMain.prototype.initRequestForm = function(sFormId) {
-	var oForm = $('#' + sFormId);
-	if(!oForm.length)
-		return;
+    var oForm = $('#' + sFormId);
+    if(!oForm.length)
+        return;
 
-	oForm.ajaxForm({ 
+    oForm.ajaxForm({
         dataType: 'json',
         beforeSubmit: function (formData, jqForm, options) {
             bx_loading(oForm, true);
         },
         success: function (oData) {
+            bx_loading(oForm, false);
+
             processJsonData(oData);
         }
     });
 };
 
 BxInvMain.prototype.onRequestFormSubmit = function(oData) {
-	var $this = this;
+    var $this = this;
+
+    if(!oData || !oData.content || !oData.content_id)
+        return;
+
+    $('#' + oData.content_id).bx_anim('hide', this._sAnimationEffect, this._iAnimationSpeed, function() {
+        $(this).replaceWith(oData.content);
+
+        $this.initRequestForm(oData.content_id);
+    });
+};
 
-	if(!oData || !oData.content || !oData.content_id)
-		return;
+BxInvMain.prototype.initAcceptForm = function(sFormId) {
+    var oForm = $('#' + sFormId);
+    if(!oForm.length)
+        return;
 
-	$('#' + oData.content_id).bx_anim('hide', this._sAnimationEffect, this._iAnimationSpeed, function() {
-		$(this).replaceWith(oData.content);
+    oForm.ajaxForm({
+        dataType: 'json',
+        beforeSubmit: function (formData, jqForm, options) {
+            bx_loading(oForm, true);
+        },
+        success: function (oData) {
+            bx_loading(oForm, false);
 
-		$this.initRequestForm(oData.content_id);
-	});
+            processJsonData(oData);
+        }
+    });
 };
 
 BxInvMain.prototype.showLinkPopup = function(oElement) {

+ 11 - 0
modules/boonex/invites/template/block_accept_form.html

@@ -0,0 +1,11 @@
+<div class="__style_prefix__-accept-form">
+    <div class="__style_prefix__-accept-form-cnt">
+        __form__
+        <script language="javascript">
+        $(document).ready(function() {
+            __js_object__.initAcceptForm('__form_id__');
+        });
+        </script>
+        __js_code__
+    </div>
+</div>

+ 17 - 4
modules/boonex/russian/data/langs/bx_invites/ru.xml

@@ -6,6 +6,7 @@
     <!-- Forms -->
     <string name="_bx_invites_form_invite"><![CDATA[Пригласить]]></string>
     <string name="_bx_invites_form_invite_display_send"><![CDATA[Послать]]></string>
+    <string name="_bx_invites_form_invite_display_accept_by_code"><![CDATA[Принять (по коду)]]></string>
     <string name="_bx_invites_form_invite_input_sys_emails"><![CDATA[Электронные адреса]]></string>
     <string name="_bx_invites_form_invite_input_emails"><![CDATA[Электронные адреса]]></string>
     <string name="_bx_invites_form_invite_input_emails_inf"><![CDATA[Для разделения адресов используйте точку с запятой.]]></string>
@@ -15,8 +16,13 @@
     <string name="_bx_invites_form_invite_input_sys_text"><![CDATA[Текст]]></string>
     <string name="_bx_invites_form_invite_input_text"><![CDATA[Текст]]></string>
     <string name="_bx_invites_form_invite_input_text_err"><![CDATA[Нужно ввести текст, который будет добавлен в приглашение.]]></string>
-    <string name="_bx_invites_form_invite_input_sys_do_submit"><![CDATA[Послать]]></string>
-    <string name="_bx_invites_form_invite_input_do_submit"><![CDATA[Послать]]></string>
+    <string name="_bx_invites_form_invite_input_sys_key"><![CDATA[Код]]></string>
+    <string name="_bx_invites_form_invite_input_key"><![CDATA[Код]]></string>
+    <string name="_bx_invites_form_invite_input_key_err"><![CDATA[Здесь вам необходимо ввести действительный код приглашения.]]></string>
+    <string name="_bx_invites_form_invite_input_sys_do_submit"><![CDATA[Выполнить]]></string>
+    <string name="_bx_invites_form_invite_input_do_submit"><![CDATA[Выполнить]]></string>
+    <string name="_bx_invites_form_invite_input_sys_do_send"><![CDATA[Послать]]></string>
+    <string name="_bx_invites_form_invite_input_do_send"><![CDATA[Послать]]></string>
 
     <string name="_bx_invites_form_request"><![CDATA[Запросить приглашение]]></string>
     <string name="_bx_invites_form_request_display_send"><![CDATA[Послать]]></string>
@@ -78,13 +84,18 @@
     <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_sys_invites"><![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_system_invite_with_redirect"><![CDATA[Пригласить (с перенаправлением)]]></string>
+    <string name="_bx_invites_page_block_title_system_invite_to_context"><![CDATA[Пригласить (в контекст)]]></string>
     <string name="_bx_invites_page_block_title_invite"><![CDATA[Пригласить]]></string>
-    <string name="_bx_invites_page_title_sys_invites"><![CDATA[Управление приглашениями]]></string>
 
-  
+    <string name="_bx_invites_page_block_title_system_accept_by_code"><![CDATA[Принять приглашение (по коду)]]></string>
+    <string name="_bx_invites_page_block_title_accept_by_code"><![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>
@@ -162,6 +173,8 @@
     <string name="_bx_invites_err_delete_request"><![CDATA[Невозможно удалить запрос.]]></string>
     <string name="_bx_invites_err_wrong_email"><![CDATA[Можно использовать только эл. адрес, указанный в приглашении.]]></string>
     <string name="_bx_invites_err_used"><![CDATA[Приглашение не доступно или уже использовано.]]></string>
+    <string name="_bx_invites_err_code_not_found"><![CDATA[Код приглашения недействителен.]]></string>
+    <string name="_bx_invites_err_code_not_applicable"><![CDATA[Код приглашения не применим.]]></string>
     <string name="_bx_invites_err_already_send"><![CDATA[Приглашение уже было отправлено на этот эл. адрес]]></string>
     <string name="_bx_invites_err_already_registed"><![CDATA[Пользователь с таким  эл. адресом уже зарегистрирован. Пожалуйста, воспользуйтесь <a href="{0}">восстановлением пароля</a> чтобы получить доступ к аккаунту.]]></string>
     <string name="_bx_invites_request_status_new"><![CDATA[Новый]]></string>