Ver código fonte

Merge branch 'master' of https://github.com/boonex/dolphin

AntonLV 10 anos atrás
pai
commit
ca3d6bef80

+ 3 - 2
inc/classes/BxDolPrivacy.php

@@ -207,9 +207,9 @@ class BxDolPrivacy extends BxDol implements iBxDolFactoryObject
      * @param $iProfileIdOwner owner profile ID
      * @return array of conditions, for now with 'restriction' part only is returned
      */
-    public function getContentPublicAsCondition($iProfileIdOwner = 0)
+    public function getContentPublicAsCondition($iProfileIdOwner = 0, $aCustomGroups = array())
     {
-        $mixedPrivacyGroups = BX_DOL_PG_ALL;
+        $mixedPrivacyGroups = array(BX_DOL_PG_ALL);
         if(isLogged()) {
             $iProfileIdLogged = bx_get_logged_profile_id();
             if($iProfileIdLogged == $iProfileIdOwner)
@@ -220,6 +220,7 @@ class BxDolPrivacy extends BxDol implements iBxDolFactoryObject
             else
                 $mixedPrivacyGroups = array(BX_DOL_PG_ALL, BX_DOL_PG_MEMBERS);
         }
+        $mixedPrivacyGroups = array_merge($mixedPrivacyGroups, $aCustomGroups);
         return $this->getContentByGroupAsCondition($mixedPrivacyGroups);
     }
 

+ 12 - 3
modules/base/general/classes/BxBaseModGeneralTemplate.php

@@ -15,12 +15,22 @@
 class BxBaseModGeneralTemplate extends BxDolModuleTemplate
 {
     protected $MODULE;
+    protected $_oModule;
 
     function __construct(&$oConfig, &$oDb)
     {
-        parent::__construct($oConfig, $oDb);
+        parent::__construct($oConfig, $oDb);        
         $this->addCss ('main.css');
     }
+    
+    public function getModule()
+    {
+        if (!$this->_oModule) {
+            $sName = $this->_oConfig->getName();
+            $this->_oModule = BxDolModule::getInstance($sName);
+        }
+        return $this->_oModule;
+    }
 
 	public function getJsCode($sType, $aParams = array(), $bWrap = true)
     {
@@ -42,8 +52,7 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
 
     function entryLocation ($iContentId)
     {
-        $oModule = BxDolModule::getInstance($this->MODULE);
-        $CNF = &$oModule->_oConfig->CNF;
+        $CNF = &$this->getModule()->_oConfig->CNF;
 
         if (empty($CNF['OBJECT_METATAGS']))
             return '';

+ 0 - 6
modules/base/notifications/classes/BxBaseModNotificationsTemplate.php

@@ -48,12 +48,6 @@ class BxBaseModNotificationsTemplate extends BxBaseModGeneralTemplate
         $this->getCssJs();
         return parent::getJsCode($sType, $aParams, $bWrap);
     }
-
-	protected function getModule()
-    {
-        $sName = $this->_oConfig->getName();
-        return BxDolModule::getInstance($sName);
-    }
     
     public function getPost(&$aEvent, $aBrowseParams = array())
     {

+ 4 - 5
modules/base/profile/classes/BxBaseModProfileTemplate.php

@@ -56,7 +56,6 @@ class BxBaseModProfileTemplate extends BxBaseModGeneralTemplate
     {
         $CNF = &$this->_oConfig->CNF;
 
-        $oModule = BxDolModule::getInstance($this->MODULE);
         $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
 
         $sUrlPicture = $this->urlPicture ($aData);
@@ -72,7 +71,7 @@ class BxBaseModProfileTemplate extends BxBaseModGeneralTemplate
             $sCoverPopup = BxTemplFunctions::getInstance()->transBox($sCoverPopupId, $this->parseHtmlByName('image_popup.html', array (
                 'image_url' => $sUrlCover,
                 'bx_if:owner' => array (
-                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedChangeCover($aData),
+                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $this->getModule()->checkAllowedChangeCover($aData),
                     'content' => array (
                         'change_image_url' => $sUrlCoverChange,
                     ),
@@ -86,7 +85,7 @@ class BxBaseModProfileTemplate extends BxBaseModGeneralTemplate
             $sPicturePopup = BxTemplFunctions::getInstance()->transBox($sPicturePopupId, $this->parseHtmlByName('image_popup.html', array (
                 'image_url' => $sUrlPicture,
                 'bx_if:owner' => array (
-                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedEdit($aData),
+                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $this->getModule()->checkAllowedEdit($aData),
                     'content' => array (
                         'change_image_url' => $sUrlPictureChange,
                     ),
@@ -109,12 +108,12 @@ class BxBaseModProfileTemplate extends BxBaseModGeneralTemplate
             'picture_popup' => $sPicturePopup,
             'picture_popup_id' => $sPicturePopupId,
             'picture_url' => $sUrlPicture,
-            'picture_href' => !$aData[$CNF['FIELD_PICTURE']] && CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedEdit($aData) ? $sUrlPictureChange : 'javascript:void(0);',
+            'picture_href' => !$aData[$CNF['FIELD_PICTURE']] && CHECK_ACTION_RESULT_ALLOWED === $this->getModule()->checkAllowedEdit($aData) ? $sUrlPictureChange : 'javascript:void(0);',
 
             'cover_popup' => $sCoverPopup,
             'cover_popup_id' => $sCoverPopupId,
             'cover_url' => $sUrlCover,
-            'cover_href' => !$aData[$CNF['FIELD_COVER']] && CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedChangeCover($aData) ? $sUrlCoverChange : 'javascript:void(0);',
+            'cover_href' => !$aData[$CNF['FIELD_COVER']] && CHECK_ACTION_RESULT_ALLOWED === $this->getModule()->checkAllowedChangeCover($aData) ? $sUrlCoverChange : 'javascript:void(0);',
         );
 
         BxDolCover::getInstance($this)->set($aVars, $sTemplateName);

+ 8 - 17
modules/base/text/classes/BxBaseModTextTemplate.php

@@ -21,9 +21,7 @@ class BxBaseModTextTemplate extends BxBaseModGeneralTemplate
 
     function unit ($aData, $isCheckPrivateContent = true, $sTemplateName = 'unit.html', $aParams = array())
     {
-    	$oModule = BxDolModule::getInstance($this->MODULE);
-
-    	$sResult = $this->checkPrivacy ($aData, $isCheckPrivateContent, $oModule);
+    	$sResult = $this->checkPrivacy ($aData, $isCheckPrivateContent, $this->getModule());
     	if($sResult)
             return $sResult;
 
@@ -32,8 +30,7 @@ class BxBaseModTextTemplate extends BxBaseModGeneralTemplate
 
     function entryText ($aData, $sTemplateName = 'entry-text.html')
     {
-        $oModule = BxDolModule::getInstance($this->MODULE);
-        $CNF = &$oModule->_oConfig->CNF;
+        $CNF = &$this->getModule()->_oConfig->CNF;
 
         $aVars = $aData;
         $aVars['entry_title'] = isset($aData[$CNF['FIELD_TITLE']]) ? $aData[$CNF['FIELD_TITLE']] : '';
@@ -58,8 +55,7 @@ class BxBaseModTextTemplate extends BxBaseModGeneralTemplate
 
     function entryAuthor ($aData, $iProfileId = false, $sFuncAuthorDesc = 'getAuthorDesc', $sTemplateName = 'author.html', $sFuncAuthorAddon = 'getAuthorAddon')
     {
-        $oModule = BxDolModule::getInstance($this->MODULE);
-        $CNF = &$oModule->_oConfig->CNF;
+        $CNF = &$this->getModule()->_oConfig->CNF;
 
         if (!$iProfileId)
             $iProfileId = $aData[$CNF['FIELD_AUTHOR']];
@@ -90,25 +86,21 @@ class BxBaseModTextTemplate extends BxBaseModGeneralTemplate
 
     function getAuthorDesc ($aData)
     {
-        $oModule = BxDolModule::getInstance($this->MODULE);
-        return _t('_sys_txt_n_by', bx_time_js($aData[$oModule->_oConfig->CNF['FIELD_ADDED']], BX_FORMAT_DATE));
+        return _t('_sys_txt_n_by', bx_time_js($aData[$this->getModule()->_oConfig->CNF['FIELD_ADDED']], BX_FORMAT_DATE));
     }
 
     function getAuthorAddon ($aData, $oProfile)
     {
-        $oModule = BxDolModule::getInstance($this->MODULE);
-        $CNF = &$oModule->_oConfig->CNF;
+        $CNF = &$this->getModule()->_oConfig->CNF;
         $sUrl = 'page.php?i=' . $CNF['URI_AUTHOR_ENTRIES'] . '&profile_id=' . $oProfile->id();
         $sUrl = BxDolPermalinks::getInstance()->permalink($sUrl);
-        return _t($CNF['T']['txt_all_entries_by'], $sUrl, $oProfile->getDisplayName(), $oModule->_oDb->getEntriesNumByAuthor($oProfile->id()));
+        return _t($CNF['T']['txt_all_entries_by'], $sUrl, $oProfile->getDisplayName(), $this->getModule()->_oDb->getEntriesNumByAuthor($oProfile->id()));
     }
 
     function entryAttachments ($aData)
     {
-    	$oModule = BxDolModule::getInstance($this->MODULE);
-
     	return $this->parseHtmlByName('attachments.html', array(
-            'bx_repeat:attachments' => $this->getAttachments($oModule->_oConfig->CNF['OBJECT_STORAGE'], $aData),
+            'bx_repeat:attachments' => $this->getAttachments($this->getModule()->_oConfig->CNF['OBJECT_STORAGE'], $aData),
         ));
     }
 
@@ -217,8 +209,7 @@ class BxBaseModTextTemplate extends BxBaseModGeneralTemplate
 
 	protected function getAttachments ($sStorage, $aData)
     {
-        $oModule = BxDolModule::getInstance($this->MODULE);
-        $CNF = &$oModule->_oConfig->CNF;
+        $CNF = &$this->getModule()->_oConfig->CNF;
 
         $oStorage = BxDolStorage::getObjectInstance($sStorage);
         $oTranscoder = BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_IMAGES_TRANSCODER_PREVIEW']);

+ 2 - 99
modules/boonex/convos/classes/BxCnvFormEntry.php

@@ -20,10 +20,6 @@ class BxCnvFormEntry extends BxBaseModTextFormEntry
         parent::__construct($aInfo, $oTemplate);
 
         $oTemplate = BxDolTemplate::getInstance();
-        $oTemplate->addJs(array (
-            'jquery-ui/jquery-ui.custom.min.js',
-            'jquery.form.min.js',
-        ));
         $oTemplate->addJsTranslation(array(
             '_bx_cnv_draft_saving_error',
             '_bx_cnv_draft_saved_success',
@@ -88,101 +84,8 @@ class BxCnvFormEntry extends BxBaseModTextFormEntry
 
     protected function genCustomInputRecipients ($aInput)
     {
-        $sVals = '';
-        if (!empty($aInput['value']) && is_array($aInput['value'])) {
-            foreach ($aInput['value'] as $sVal) {
-                if (!$sVal || !($oProfile = BxDolProfile::getInstance($sVal)))
-                    continue;
-               $sVals .= '<b class="val bx-def-color-bg-hl bx-def-round-corners">' . $oProfile->getDisplayName() . '<input type="hidden" name="' . $aInput['name'] . '[]" value="' . $sVal . '" /></b>';
-            }
-            $sVals = trim($sVals, ',');
-        }
-        $sId = $aInput['name'] . time();
-        $sPlaceholderText = bx_html_attribute(_t('_bx_cnv_form_entry_input_recipients_placeholder'), BX_ESCAPE_STR_QUOTE);
-        $sUrlGetRecipients = BX_DOL_URL_ROOT . "modules/?r=convos/ajax_get_recipients";
-        return <<<EOS
-<script>
-    $(function() {
-
-        $('#{$sId} input[type=text]').autocomplete({
-            source: "{$sUrlGetRecipients}",
-            select: function(e, ui) {
-                $(this).val(ui.item.label);
-                $(this).trigger('superselect', ui.item);
-                e.preventDefault();
-            }
-        });
-
-        $('#{$sId} input[type=text]').on('superselect', function(e, item) {
-            $(this).hide();
-            if ('undefined' != typeof(item))
-                $(this).before('<b class="bx-def-color-bg-hl bx-def-round-corners">'+ item.label +'<input type="hidden" name="{$aInput['name']}[]" value="'+ item.value +'" /></b>');
-            fAutoShrinkInput();
-            $(this).show();
-            this.value = '';
-
-        }).on('keydown', function(e) {
-
-            // if: comma,enter (delimit more keyCodes with | pipe)
-            if (/(13)/.test(e.which))
-                e.preventDefault();
-
-        });
-
-        $('#{$sId}').on('click', 'b', function() {
-            $(this).remove();
-            fAutoShrinkInput();
-        });
-
-        fAutoShrinkInput = function () {
-            var iWidthCont = $('#{$sId}.bx-form-input-autotoken').innerWidth();
-            var iWidthExisting = 0;
-            $('#{$sId}.bx-form-input-autotoken b').each(function () {
-                iWidthExisting += $(this).outerWidth(true);
-            });
-            $('#{$sId}.bx-form-input-autotoken input').width(parseInt(iWidthCont - iWidthExisting > 180 ? iWidthCont - iWidthExisting : 180) - 5);
-        };
-
-        fAutoShrinkInput();
-    });
-</script>
-<style>
-    .bx-form-value .bx-form-input-autotoken {
-        float:left;
-        padding:0px;
-        height:auto;
-    }
-    .bx-form-value .bx-form-input-autotoken b {
-        cursor:pointer;
-        display:block;
-        float:left;
-        padding:0.3em 1.5em 0.3em 0.5em;
-        margin:0.1em;
-        font-weight:normal;
-    }
-    .bx-form-value .bx-form-input-autotoken b:hover {
-        opacity:0.7;
-    }
-    .bx-form-value .bx-form-input-autotoken b:after {
-        position:absolute;
-        content:"x";
-        padding:0 0.5em;
-        margin:0.2em 0 0.7em 0.5em;
-        font-size:0.7em;
-        font-weight:bold;
-    }
-    .bx-form-value .bx-form-input-autotoken input {
-        border:0;
-        margin:0;
-        padding:0 0 0 5px;
-        width:auto;
-    }
-</style>
-<div id="{$sId}" class="bx-form-input-autotoken bx-def-font-inputs bx-form-input-text">
-    {$sVals}
-    <input type="text" value="" placeholder="{$sPlaceholderText}" class="bx-def-font-inputs bx-form-input-text" />
-</div>
-EOS;
+        $aInput['ajax_get_suggestions'] = BX_DOL_URL_ROOT . "modules/?r=convos/ajax_get_recipients";
+        return $this->genCustomInputUsernamesSuggestions($aInput);
     }
 
     protected function genCustomInputSubmitText ($aInput)

+ 0 - 1
modules/boonex/convos/install/langs/en.xml

@@ -23,7 +23,6 @@
     <string name="_bx_cnv_form_entry_input_recipients"><![CDATA[Recipients]]></string>
     <string name="_bx_cnv_form_entry_input_sys_recipients"><![CDATA[Recipients]]></string>
     <string name="_bx_cnv_form_entry_input_recipients_err"><![CDATA[Recipients is mandatory]]></string>
-    <string name="_bx_cnv_form_entry_input_recipients_placeholder"><![CDATA[Type name here...]]></string>
     <string name="_bx_cnv_form_entry_input_sys_submit_text"><![CDATA[Draft status]]></string>
     <string name="_bx_cnv_form_entry_input_sys_submit_block"><![CDATA[Submit block]]></string>
 

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

@@ -1693,6 +1693,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_form_login_input_password"><![CDATA[Password]]></string>
 	<string name="_sys_form_login_input_remember_me"><![CDATA[Remember me]]></string>
 	<string name="_sys_form_login_input_submit"><![CDATA[Sign in]]></string>
+	<string name="_sys_form_paceholder_profiles_suggestions"><![CDATA[Type name here...]]></string>
 	<string name="_sys_form_report"><![CDATA[Report]]></string>
 	<string name="_sys_form_report_input_caption_submit"><![CDATA[Post]]></string>
 	<string name="_sys_form_report_input_caption_text"><![CDATA[Report Text]]></string>

+ 1 - 0
modules/boonex/groups/classes/BxGroupsConfig.php

@@ -54,6 +54,7 @@ class BxGroupsConfig extends BxBaseModProfileConfig
             'URI_VIEW_ENTRY' => 'view-group-profile',
             'URI_EDIT_ENTRY' => 'edit-group-profile',
             'URI_EDIT_COVER' => 'edit-group-cover',
+            'URI_JOINED_ENTRIES' => 'joined-groups',
         	'URI_MANAGE_COMMON' => 'groups-manage',
 
             'URL_HOME' => 'page.php?i=groups-home',

+ 6 - 0
modules/boonex/groups/classes/BxGroupsFormEntry.php

@@ -27,6 +27,12 @@ class BxGroupsFormEntry extends BxBaseModProfileFormEntry
 			$this->aInputs[$CNF['FIELD_ALLOW_VIEW_TO']]['db']['pass'] = 'Xss';
 		}
     }
+
+    protected function genCustomInputInitialMembers ($aInput)
+    {
+        $aInput['ajax_get_suggestions'] = BX_DOL_URL_ROOT . "modules/?r=groups/ajax_get_initial_members";
+        return $this->genCustomInputUsernamesSuggestions($aInput);
+    }
 }
 
 /** @} */

+ 16 - 0
modules/boonex/groups/classes/BxGroupsFormsEntryHelper.php

@@ -27,6 +27,22 @@ class BxGroupsFormsEntryHelper extends BxBaseModProfileFormsEntryHelper
 
         return $sMsg;
     }
+
+    public function onDataAddAfter ($iAccountId, $iContentId)
+    {
+        if ($s = parent::onDataAddAfter($iAccountId, $iContentId))
+            return $s;
+
+        // insert invited members, so they will join without confirmation
+        $aInitialProfiles = bx_get('initial_members');
+        foreach ($aInitialProfiles as $iProfileId) {
+            if (!($oProfile = BxDolProfile::getInstance($iProfileId)))
+                continue;
+            $this->_oModule->serviceAddMutualConnection ($iContentId, $oProfile->id(), true);
+        }
+        
+        return '';
+    }
 }
 
 /** @} */

+ 25 - 2
modules/boonex/groups/classes/BxGroupsModule.php

@@ -19,6 +19,19 @@ class BxGroupsModule extends BxBaseModProfileModule
         parent::__construct($aModule);
     }
 
+    /**
+     * Get possible recipients for start conversation form
+     */
+    public function actionAjaxGetInitialMembers ()
+    {
+        $sTerm = bx_get('term');
+
+        $a = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
+
+        header('Content-Type:text/javascript; charset=utf-8');
+        echo(json_encode($a));
+    }
+
     public function serviceActAsProfile ()
     {
         return false;
@@ -33,10 +46,10 @@ class BxGroupsModule extends BxBaseModProfileModule
         return $aFieldsProfile;
     }
 
-    public function serviceAddMutualConnection ($iContentId, $iInitiatorId)
+    public function serviceAddMutualConnection ($iContentId, $iInitiatorId, $iIgnoreJoinConfirmation = false)
     {
         $aContentInfo = $this->_oDb->getContentInfoById((int)$iContentId);
-        if (!$aContentInfo || $aContentInfo['join_confirmation'])
+        if (!$aContentInfo || (!$iIgnoreJoinConfirmation && $aContentInfo['join_confirmation']))
             return false;
 
         if (!($oConnection = BxDolConnection::getObjectInstance($this->_oConfig->CNF['OBJECT_CONNECTIONS'])))
@@ -72,6 +85,16 @@ class BxGroupsModule extends BxBaseModProfileModule
         return $s;
     }
 
+    public function serviceBrowseJoinedEntries ($iProfileId = 0, $bDisplayEmptyMsg = false)
+    {
+        if (!$iProfileId)
+            $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
+        if (!$iProfileId)
+            return '';
+
+        return $this->_serviceBrowse ('joined_entries', array('joined_profile' => $iProfileId), BX_DB_PADDING_DEF, $bDisplayEmptyMsg);
+    }
+
     /**
      * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden.
      */

+ 24 - 0
modules/boonex/groups/classes/BxGroupsPageJoinedEntries.php

@@ -0,0 +1,24 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Groups Groups
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+/**
+ * Entries user joined to.
+ */
+class BxGroupsPageJoinedEntries extends BxBaseModTextPageAuthor
+{
+    public function __construct($aObject, $oTemplate = false)
+    {
+        parent::__construct($aObject, $oTemplate);
+    }
+
+}
+
+/** @} */

+ 48 - 1
modules/boonex/groups/classes/BxGroupsSearchResult.php

@@ -36,7 +36,7 @@ class BxGroupsSearchResult extends BxBaseModProfileSearchResult
                     'table' => 'bx_groups_data',
                     'mainField' => 'content_id',
                     'onField' => 'id',
-                    'joinFields' => array('id', 'group_name', 'picture', 'cover', 'added'),
+                    'joinFields' => array('id', 'group_name', 'picture', 'cover', 'added', 'author', 'allow_view_to'),
                 ),
                 'account' => array(
                     'type' => 'INNER',
@@ -68,10 +68,41 @@ class BxGroupsSearchResult extends BxBaseModProfileSearchResult
         $this->sFilterName = 'bx_groups_data_filter';
         $this->oModule = $this->getMain();
 
+        $oJoinedProfile = null;
+        $bProcessConditionsForPrivateContent = true;
+
+        $CNF = &$this->oModule->_oConfig->CNF;
+
         switch ($sMode) {
 
+            case 'joined_entries':
+                $oJoinedProfile = BxDolProfile::getInstance((int)$aParams['joined_profile']);
+                if (!$oJoinedProfile) {
+                    $this->isError = true;
+                    break;
+                }
+
+                $bProcessConditionsForPrivateContent = false;
+
+                $this->aCurrent['join']['fans'] = array(
+                    'type' => 'INNER',
+                    'table' => 'bx_groups_fans',
+                    'mainField' => 'id',
+                    'mainTable' => 'bx_groups_data',
+                    'onField' => 'content',
+                    'joinFields' => array('initiator'),
+                );
+
+                $this->aCurrent['restriction']['fans'] = array('value' => $oJoinedProfile->id(), 'field' => 'initiator', 'operator' => '=', 'table' => 'bx_groups_fans');
+
+                $this->sBrowseUrl = 'page.php?i=' . $CNF['URI_JOINED_ENTRIES'] . '&profile_id={profile_id}';
+                $this->aCurrent['title'] = _t('_bx_groups_page_title_joined_entries');
+                $this->aCurrent['rss']['link'] = 'modules/?r=groups/rss/' . $sMode . '/' . $oJoinedProfile->id();
+                break;
+
             case 'connections':
                 if ($this->_setConnectionsConditions($aParams)) {
+                    $bProcessConditionsForPrivateContent = false;
                     $oProfile = BxDolProfile::getInstance($aParams['profile']);
                     $oProfile2 = isset($aParams['profile2']) ? BxDolProfile::getInstance($aParams['profile2']) : null;
 
@@ -109,9 +140,25 @@ class BxGroupsSearchResult extends BxBaseModProfileSearchResult
                 $this->isError = true;
         }
 
+        if ($bProcessConditionsForPrivateContent)
+            $this->addConditionsForPrivateContent($CNF, $oJoinedProfile);
+
         $this->sCenterContentUnitSelector = false;
     }
 
+    protected function addConditionsForPrivateContent($CNF, $oJoinedProfile) 
+    {
+        // add conditions for private content
+        $oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
+        $a = $oPrivacy ? $oPrivacy->getContentPublicAsCondition($oJoinedProfile ? $oJoinedProfile->id() : 0, array('c')) : array();
+        if (isset($a['restriction']))
+            $this->aCurrent['restriction'] = array_merge($this->aCurrent['restriction'], $a['restriction']);
+        if (isset($a['join']))
+            $this->aCurrent['join'] = array_merge($this->aCurrent['join'], $a['join']);
+
+        $this->setProcessPrivateContent(false);
+    }
+
     function getAlterOrder()
     {
         switch ($this->aCurrent['sorting']) {

+ 9 - 2
modules/boonex/groups/classes/BxGroupsTemplate.php

@@ -24,12 +24,19 @@ class BxGroupsTemplate extends BxBaseModProfileTemplate
     {
         $CNF = &$this->_oConfig->CNF;
 
+        $isPublic = CHECK_ACTION_RESULT_ALLOWED === $this->getModule()->checkAllowedView($aData) || 'c' == $aData[$CNF['FIELD_ALLOW_VIEW_TO']];
+
         $aVars = parent::unitVars ($aData, $isCheckPrivateContent, $sTemplateName);
 
         $oConn = BxDolConnection::getObjectInstance($CNF['OBJECT_CONNECTIONS']);
 
-        $aVars['cover_url'] = $this->urlCover ($aData, true);
-        $aVars['members'] = _t('_bx_groups_txt_N_fans', $oConn ? $oConn->getConnectedInitiatorsCount($aData[$CNF['FIELD_ID']], true) : 0);
+        if (!$isPublic) {
+            $aVars['thumb_url'] = $this->getImageUrl('no-picture-thumb.png');
+            $aVars['content_url'] = 'javascript:void(0);';
+            $aVars['title'] = _t('_bx_groups_txt_private_group');
+        }
+        $aVars['cover_url'] = $isPublic ? $this->urlCover ($aData, true) : $this->getImageUrl('cover.jpg');
+        $aVars['members'] = $isPublic ? _t('_bx_groups_txt_N_fans', $oConn ? $oConn->getConnectedInitiatorsCount($aData[$CNF['FIELD_ID']], true) : 0) : '&nbsp;';
         $aVars['bx_if:btn'] = array (
             'condition' => isLogged() && !$oConn->isConnected(bx_get_logged_profile_id(), $aData[$CNF['FIELD_ID']], true),
             'content' => array (

+ 1 - 0
modules/boonex/groups/install/config.php

@@ -52,6 +52,7 @@ $aConfig = array(
      * Menu triggers.
      */
     'menu_triggers' => array(
+    	'trigger_profile_view_submenu',
     	'trigger_group_view_submenu',
     ),
 

+ 7 - 0
modules/boonex/groups/install/langs/en.xml

@@ -47,6 +47,8 @@
 	<string name="_bx_groups_acl_action_view_profile"><![CDATA[View Group]]></string>
 	<string name="_bx_groups_acl_action_edit_any_profile"><![CDATA[Edit Any Group]]></string>
 
+	<string name="_bx_groups_page_title_sys_joined_entries"><![CDATA[Joined Groups]]></string>
+	<string name="_bx_groups_page_title_joined_entries"><![CDATA[Joined Groups]]></string>
 	<string name="_bx_groups_page_title_sys_create_profile"><![CDATA[Create Group]]></string>
 	<string name="_bx_groups_page_title_create_profile"><![CDATA[Create Group]]></string>
 	<string name="_bx_groups_page_title_sys_edit_profile"><![CDATA[Edit Group]]></string>
@@ -77,6 +79,8 @@
 	<string name="_bx_groups_page_title_sys_active"><![CDATA[Recently Active People]]></string>
 	<string name="_bx_groups_page_title_active"><![CDATA[Recently Active People]]></string>
 
+	<string name="_bx_groups_page_block_title_sys_joined_entries"><![CDATA[Joined Groups]]></string>
+	<string name="_bx_groups_page_block_title_joined_entries"><![CDATA[Joined Groups]]></string>
 	<string name="_bx_groups_page_block_title_create_profile"><![CDATA[Create Group]]></string>
 	<string name="_bx_groups_page_block_title_edit_profile"><![CDATA[Edit Group]]></string>
 	<string name="_bx_groups_page_block_title_edit_profile_cover"><![CDATA[Edit Cover]]></string>
@@ -128,6 +132,8 @@
     <string name="_bx_groups_menu_item_title_create_profile"><![CDATA[Create Group]]></string>
     <string name="_bx_groups_menu_item_title_system_view_profile_friends"><![CDATA[Friends]]></string>
     <string name="_bx_groups_menu_item_title_view_profile_friends"><![CDATA[Friends]]></string>
+    <string name="_bx_groups_menu_item_title_system_view_joined_groups"><![CDATA[Groups]]></string>
+    <string name="_bx_groups_menu_item_title_view_joined_groups"><![CDATA[Groups]]></string>
     <string name="_bx_groups_menu_item_title_system_view_fans"><![CDATA[Members]]></string>
     <string name="_bx_groups_menu_item_title_view_fans"><![CDATA[Members]]></string>
     <string name="_bx_groups_menu_item_title_system_view_profile_info"><![CDATA[Info]]></string>
@@ -198,6 +204,7 @@
     <string name="_bx_groups_txt_sample_single"><![CDATA[group]]></string>
     <string name="_bx_groups_txt_to_admins"><![CDATA[To Admins]]></string>
     <string name="_bx_groups_txt_from_admins"><![CDATA[From Admins]]></string>
+    <string name="_bx_groups_txt_private_group"><![CDATA[Private group]]></string>
 
     <string name="_bx_groups_privacy_group_closed"><![CDATA[Closed]]></string>
     <string name="_bx_groups_privacy_group_secret"><![CDATA[Secret]]></string>

+ 7 - 0
modules/boonex/groups/install/langs/ru.xml

@@ -47,6 +47,8 @@
 	<string name="_bx_groups_acl_action_view_profile"><![CDATA[Просмотреть группу]]></string>
 	<string name="_bx_groups_acl_action_edit_any_profile"><![CDATA[Редактировать любую группу]]></string>
 
+	<string name="_bx_groups_page_title_sys_joined_entries"><![CDATA[Участие в группах]]></string>
+	<string name="_bx_groups_page_title_joined_entries"><![CDATA[Участие в группах]]></string>
 	<string name="_bx_groups_page_title_sys_create_profile"><![CDATA[Создать группу]]></string>
 	<string name="_bx_groups_page_title_create_profile"><![CDATA[Создать группу]]></string>
 	<string name="_bx_groups_page_title_sys_edit_profile"><![CDATA[Редактировать группу]]></string>
@@ -78,6 +80,8 @@
 	<string name="_bx_groups_page_title_active"><![CDATA[Последние Активные Группы]]></string>
     <string name="_bx_groups_page_block_title_categories"><![CDATA[Категории групп]]></string>
 
+	<string name="_bx_groups_page_block_title_sys_joined_entries"><![CDATA[Участие в группах]]></string>
+	<string name="_bx_groups_page_block_title_joined_entries"><![CDATA[Участие в группах]]></string>
 	<string name="_bx_groups_page_block_title_create_profile"><![CDATA[Создать группу]]></string>
 	<string name="_bx_groups_page_block_title_edit_profile"><![CDATA[Редактировать группу]]></string>
 	<string name="_bx_groups_page_block_title_edit_profile_cover"><![CDATA[Редактировать обложку]]></string>
@@ -127,6 +131,8 @@
     <string name="_bx_groups_menu_item_title_create_profile"><![CDATA[Создать группу]]></string>
     <string name="_bx_groups_menu_item_title_system_view_profile_friends"><![CDATA[Друзья]]></string>
     <string name="_bx_groups_menu_item_title_view_profile_friends"><![CDATA[Друзья]]></string>
+    <string name="_bx_groups_menu_item_title_system_view_joined_groups"><![CDATA[Группы]]></string>
+    <string name="_bx_groups_menu_item_title_view_joined_groups"><![CDATA[Группы]]></string>
     <string name="_bx_groups_menu_item_title_system_view_fans"><![CDATA[Участники]]></string>
     <string name="_bx_groups_menu_item_title_view_fans"><![CDATA[Участники]]></string>
     <string name="_bx_groups_menu_item_title_system_view_profile_info"><![CDATA[Инфо]]></string>
@@ -197,6 +203,7 @@
     <string name="_bx_groups_txt_sample_single"><![CDATA[Группа]]></string>
     <string name="_bx_groups_txt_to_admins"><![CDATA[В админы]]></string>
     <string name="_bx_groups_txt_from_admins"><![CDATA[Из админов]]></string>
+    <string name="_bx_groups_txt_private_group"><![CDATA[Приватная группа]]></string>
 
     <string name="_bx_groups_privacy_group_closed"><![CDATA[Закрытая группа]]></string>
     <string name="_bx_groups_privacy_group_secret"><![CDATA[Секретная группа]]></string>

+ 1 - 1
modules/boonex/groups/install/sql/disable.sql

@@ -10,7 +10,7 @@ DELETE FROM `sys_options_types` WHERE `id` = @iTypeId;
 -- PAGES
 
 DELETE FROM `sys_objects_page` WHERE `module` = 'bx_groups';
-DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_groups' OR `object` IN('bx_groups_create_profile', 'bx_groups_delete_profile', 'bx_groups_edit_profile', 'bx_groups_edit_profile_cover', 'bx_groups_view_profile', 'bx_groups_view_profile_closed', 'bx_groups_profile_info', 'bx_groups_home', 'bx_groups_fans');
+DELETE FROM `sys_pages_blocks` WHERE `module` = 'bx_groups' OR `object` IN('bx_groups_create_profile', 'bx_groups_delete_profile', 'bx_groups_edit_profile', 'bx_groups_edit_profile_cover', 'bx_groups_view_profile', 'bx_groups_view_profile_closed', 'bx_groups_profile_info', 'bx_groups_home', 'bx_groups_fans', 'bx_groups_joined', 'bx_groups_active', 'bx_groups_manage', 'bx_groups_administration');
 
 -- MENU
 

+ 11 - 0
modules/boonex/groups/install/sql/enable.sql

@@ -112,6 +112,13 @@ INSERT INTO `sys_objects_page`(`object`, `title_system`, `title`, `module`, `lay
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
 ('bx_groups_administration', 1, 'bx_groups', '_bx_groups_page_block_title_system_manage_administration', '_bx_groups_page_block_title_manage', 11, 192, 'service', 'a:3:{s:6:\"module\";s:9:\"bx_groups\";s:6:\"method\";s:12:\"manage_tools\";s:6:\"params\";a:1:{i:0;s:14:\"administration\";}}', 0, 1, 0);
 
+-- PAGE: user's groups
+INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
+('bx_groups_joined', 'joined-groups', '_bx_groups_page_title_sys_joined_entries', '_bx_groups_page_title_joined_entries', 'bx_groups', 5, 2147483647, 1, '', '', '', '', 0, 1, 0, 'BxGroupsPageJoinedEntries', 'modules/boonex/groups/classes/BxGroupsPageJoinedEntries.php');
+
+INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
+('bx_groups_joined', 1, 'bx_groups', '_bx_groups_page_block_title_sys_joined_entries', '_bx_groups_page_block_title_joined_entries', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:9:\"bx_groups\";s:6:\"method\";s:21:\"browse_joined_entries\";}', 0, 0, 1, 1);
+
 -- PAGE: add block to homepage
 SET @iBlockOrder = (SELECT `order` FROM `sys_pages_blocks` WHERE `object` = 'sys_home' AND `cell_id` = 1 ORDER BY `order` DESC LIMIT 1);
 INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES
@@ -219,6 +226,10 @@ SET @iManageMenuOrder = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_menu_items` WH
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `addon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
 ('sys_account_dashboard_manage_tools', 'bx_groups', 'groups-administration', '_bx_groups_menu_item_title_system_admt_groups', '_bx_groups_menu_item_title_admt_groups', 'page.php?i=groups-administration', '', '_self', '', 'a:2:{s:6:"module";s:9:"bx_groups";s:6:"method";s:27:"get_menu_addon_manage_tools";}', '', 192, 1, 0, @iManageMenuOrder + 1);
 
+-- MENU: add menu item to profiles modules (trigger* menu sets are processed separately upon modules enable/disable)
+
+INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
+('trigger_profile_view_submenu', 'bx_groups', 'joined-groups', '_bx_groups_menu_item_title_system_view_joined_groups', '_bx_groups_menu_item_title_view_joined_groups', 'page.php?i=joined-groups&profile_id={profile_id}', '', '', 'group col-red2', '', 2147483647, 1, 0, 0);
 
 -- ACL
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES

+ 0 - 1
modules/boonex/russian/data/langs/bx_convos/ru.xml

@@ -23,7 +23,6 @@
     <string name="_bx_cnv_form_entry_input_recipients"><![CDATA[Получатели]]></string>
     <string name="_bx_cnv_form_entry_input_sys_recipients"><![CDATA[Получатели]]></string>
     <string name="_bx_cnv_form_entry_input_recipients_err"><![CDATA[Необходимо указать хотя бы одного получателя]]></string>
-    <string name="_bx_cnv_form_entry_input_recipients_placeholder"><![CDATA[Введите имя здесь...]]></string>
     <string name="_bx_cnv_form_entry_input_sys_submit_text"><![CDATA[Статус черновика]]></string>
     <string name="_bx_cnv_form_entry_input_sys_submit_block"><![CDATA[Блок отправки сообщения]]></string>
 

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

@@ -1693,6 +1693,7 @@
 	<string name="_sys_form_login_input_password"><![CDATA[Пароль]]></string>
 	<string name="_sys_form_login_input_remember_me"><![CDATA[Запомнить меня]]></string>
 	<string name="_sys_form_login_input_submit"><![CDATA[Вход]]></string>
+	<string name="_sys_form_paceholder_profiles_suggestions"><![CDATA[Введите имя...]]></string>
 	<string name="_sys_form_report"><![CDATA[Пожаловаться]]></string>
 	<string name="_sys_form_report_input_caption_submit"><![CDATA[Пожаловаться]]></string>
 	<string name="_sys_form_report_input_caption_text"><![CDATA[Текст жалобы]]></string>

+ 34 - 1
template/css/forms.css

@@ -473,4 +473,37 @@
 
 	border-radius: 20px;
 	border-radius: 1.25rem;
-}
+}
+
+/* auto-siggestion input */
+
+.bx-form-value .bx-form-input-autotoken {
+    float:left;
+    padding:0px;
+    height:auto;
+}
+.bx-form-value .bx-form-input-autotoken b {
+    cursor:pointer;
+    display:block;
+    float:left;
+    padding:0.3em 1.5em 0.3em 0.5em;
+    margin:0.1em;
+    font-weight:normal;
+}
+.bx-form-value .bx-form-input-autotoken b:hover {
+    opacity:0.7;
+}
+.bx-form-value .bx-form-input-autotoken b:after {
+    position:absolute;
+    content:"x";
+    padding:0 0.5em;
+    margin:0.2em 0 0.7em 0.5em;
+    font-size:0.7em;
+    font-weight:bold;
+}
+.bx-form-value .bx-form-input-autotoken input {
+    border:0;
+    margin:0;
+    padding:0 0 0 5px;
+    width:auto;
+}

+ 49 - 0
template/form_field_custom_suggestions.html

@@ -0,0 +1,49 @@
+<script>
+    $(function() {
+
+        $('#__id__ input[type=text]').autocomplete({
+            source: "__url_get_recipients__",
+            select: function(e, ui) {
+                $(this).val(ui.item.label);
+                $(this).trigger('superselect', ui.item);
+                e.preventDefault();
+            }
+        });
+
+        $('#__id__ input[type=text]').on('superselect', function(e, item) {
+            $(this).hide();
+            if ('undefined' != typeof(item))
+                $(this).before('<b class="bx-def-color-bg-hl bx-def-round-corners">'+ item.label +'<input type="hidden" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" name="__name__[]" value="'+ item.value +'" /></b>');
+            fAutoShrinkInput();
+            $(this).show();
+            this.value = '';
+
+        }).on('keydown', function(e) {
+
+            // if: comma,enter (delimit more keyCodes with | pipe)
+            if (/(13)/.test(e.which))
+                e.preventDefault();
+
+        });
+
+        $('#__id__').on('click', 'b', function() {
+            $(this).remove();
+            fAutoShrinkInput();
+        });
+
+        fAutoShrinkInput = function () {
+            var iWidthCont = $('#__id__.bx-form-input-autotoken').innerWidth();
+            var iWidthExisting = 0;
+            $('#__id__.bx-form-input-autotoken b').each(function () {
+                iWidthExisting += $(this).outerWidth(true);
+            });
+            $('#__id__.bx-form-input-autotoken input').width(parseInt(iWidthCont - iWidthExisting > 180 ? iWidthCont - iWidthExisting : 180) - 5);
+        };
+
+        fAutoShrinkInput();
+    });
+</script>
+<div id="__id__" class="bx-form-input-autotoken bx-def-font-inputs bx-form-input-text">
+    __vals__
+    <input type="text" value="" placeholder="__placeholder__" class="bx-def-font-inputs bx-form-input-text" />
+</div>

+ 26 - 0
template/scripts/BxBaseFormView.php

@@ -872,6 +872,32 @@ BLAH;
         ));
     }
 
+    protected function genCustomInputUsernamesSuggestions ($aInput)
+    {
+        $this->oTemplate->addJs(array(
+            'jquery-ui/jquery-ui.custom.min.js',
+            'jquery.form.min.js',
+        ));
+
+        $sVals = '';
+        if (!empty($aInput['value']) && is_array($aInput['value'])) {
+            foreach ($aInput['value'] as $sVal) {
+                if (!$sVal || !($oProfile = BxDolProfile::getInstance($sVal)))
+                    continue;
+               $sVals .= '<b class="val bx-def-color-bg-hl bx-def-round-corners">' . $oProfile->getDisplayName() . '<input type="hidden" name="' . $aInput['name'] . '[]" value="' . $sVal . '" /></b>';
+            }
+            $sVals = trim($sVals, ',');
+        }
+
+        return $this->oTemplate->parseHtmlByName('form_field_custom_suggestions.html', array(
+            'id' => $aInput['name'] . time(),
+            'url_get_recipients' => $aInput['ajax_get_suggestions'],
+            'name' => $aInput['name'],
+            'placeholder' => bx_html_attribute(isset($aInput['placeholder']) ? $aInput['placeholder'] : _t('_sys_form_paceholder_profiles_suggestions'), BX_ESCAPE_STR_QUOTE),
+            'vals' => $sVals,
+        ));
+    }
+
     /**
      * Generate Select Element
      *