瀏覽代碼

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

# Conflicts:
#	template/scripts/BxBaseFormView.php
roman.lesnikov@gmail.com 2 年之前
父節點
當前提交
2020894c37

+ 59 - 1
inc/classes/BxDolLabel.php

@@ -66,10 +66,46 @@ class BxDolLabel extends BxDolFactory implements iBxDolSingleton
         echoJson($aResult);
         echoJson($aResult);
     }
     }
 
 
-    public function getLabels($aParams = array())
+    public function getLabels($aParams = [])
     {
     {
         return $this->_oDb->getLabels($aParams);
         return $this->_oDb->getLabels($aParams);
     }
     }
+    
+    public function getLabelsSystem()
+    {
+        $iParentId = $iLevel = 0;
+        return $this->_getLabelsSystem($iParentId, $iLevel);
+    }
+    
+    public function getLabelsContext($iProfileId = 0)
+    {
+        if(!$iProfileId)
+            $iProfileId = bx_get_logged_profile_id();
+
+        $aModules = bx_srv('system', 'get_modules_by_type', ['context']);
+
+        $aResults = [];
+        foreach($aModules as $aModule) {
+            if(bx_srv($aModule['name'], 'act_as_profile'))
+                continue;
+
+            $aContextPids = bx_srv($aModule['name'], 'get_participating_profiles', [$iProfileId]);
+            if(empty($aContextPids) || !is_array($aContextPids))
+                continue;
+
+            foreach($aContextPids as $iContextPid) {
+                $aContextInfo = bx_srv($aModule['name'], 'get_content_info_by_profile_id', [$iContextPid]);
+                if(empty($aContextInfo['hashtag']))
+                    continue;
+
+                $aResults[] = [
+                    'value' => $aContextInfo['hashtag']
+                ];
+            }
+        }
+
+        return $aResults;
+    }
 
 
     public function getLabelUrl($sKeyword, $mixedSection = false) 
     public function getLabelUrl($sKeyword, $mixedSection = false) 
     {   
     {   
@@ -123,6 +159,28 @@ class BxDolLabel extends BxDolFactory implements iBxDolSingleton
 
 
         bx_alert('label', 'deleted', $iId, false, array('label' => $aLabel));
         bx_alert('label', 'deleted', $iId, false, array('label' => $aLabel));
     }
     }
+
+    protected function _getLabelsSystem($iParentId, $iLevel)
+    {
+        $aLabels = $this->getLabels(['type' => 'parent', 'parent' => $iParentId]);
+        if(empty($aLabels) || !is_array($aLabels))
+            return [];
+
+        $aResults = [];
+        foreach($aLabels as $aLabel) {
+            $aResult = [
+                'value' => $aLabel['value']
+            ];
+
+            $aSubitems = $this->_getLabelsSystem($aLabel['id'], $iLevel + 1);
+            if(!empty($aSubitems) && is_array($aSubitems))
+                $aResult['subitems'] = $aSubitems;
+            
+            $aResults[] = $aResult;
+        }
+
+        return $aResults;
+    }
 }
 }
 
 
 /** @} */
 /** @} */

+ 15 - 4
inc/classes/BxDolSearch.php

@@ -522,17 +522,19 @@ class BxDolSearchResult implements iBxDolReplaceable
      */
      */
     function processing ()
     function processing ()
     {
     {
-        if (defined('BX_API')) {
-            return $this->processingAPI ();
+        if (bx_is_api()) {
+            return $this->processingAPI();
         }
         }
 
 
         $sCode = $this->displayResultBlock();
         $sCode = $this->displayResultBlock();
         if ($this->aCurrent['paginate']['num'] > 0) {
         if ($this->aCurrent['paginate']['num'] > 0) {
             $sPaginate = $this->showPagination();
             $sPaginate = $this->showPagination();
             $sCode = $this->displaySearchBox($sCode, $sPaginate);
             $sCode = $this->displaySearchBox($sCode, $sPaginate);
-        } else {
-            $sCode = $this->bDisplayEmptyMsg ? $this->displaySearchBox(MsgBox(_t($this->sDisplayEmptyMsgKey ? $this->sDisplayEmptyMsgKey : '_Empty'))) : '';
         }
         }
+        else {
+            $sCode = $this->bDisplayEmptyMsg ? $this->displaySearchBox($this->displayResultBlockEmpty()) : '';
+        }
+
         return $sCode;
         return $sCode;
     }
     }
 
 
@@ -597,6 +599,15 @@ class BxDolSearchResult implements iBxDolReplaceable
         return $sCode;
         return $sCode;
     }
     }
 
 
+    /**
+     * Get html output of empty search result
+     * @return html code
+     */
+    function displayResultBlockEmpty ()
+    {
+        return MsgBox(_t($this->sDisplayEmptyMsgKey ? $this->sDisplayEmptyMsgKey : '_Empty'));
+    }
+            
     /**
     /**
      * Add different code before html output (usually redeclared)
      * Add different code before html output (usually redeclared)
      * no return result
      * no return result

+ 11 - 10
inc/js/jquery.dolPopup.js

@@ -245,21 +245,22 @@
                 }
                 }
 
 
                 setTimeout(function () {
                 setTimeout(function () {
-                	// Don't should popup with pointer if there is no parent. Checking after showing.
-                        if(typeof o.pointer.el == 'string')
-                            o.pointer.el = $(o.pointer.el);
+                    // Don't should popup with pointer if there is no parent. Checking after showing.
+                    if(typeof o.pointer.el == 'string')
+                        o.pointer.el = $(o.pointer.el);
 
 
-                	if($(o.pointer.el).length > 0 && !$.contains(document, o.pointer.el[0])) {
-                		$el.remove();
-                		return;
-                	}
+                    if($(o.pointer.el).length > 0 && !$.contains(document, o.pointer.el[0])) {
+                        $el.remove();
+                        return;
+                    }
 
 
-                	if(typeof(o.onShow) == 'function')
-                		o.onShow($el);
+                    if(typeof(o.onShow) == 'function')
+                        o.onShow($el);
                     else if(typeof(o.onShow) == 'string')
                     else if(typeof(o.onShow) == 'string')
                     	eval(o.onShow);
                     	eval(o.onShow);
+                    else
+                        $el.find('input[type=text]:first').focus(); //NOTE. Put cursor to the first input element, ONLY IF there is no any custom behaviour for onShow event.
 
 
-                    $el.find('input[type=text]:first').focus(); // put cursor to the first input element
                 }, o.speed);
                 }, o.speed);
 
 
             }, 100);
             }, 100);

+ 5 - 2
modules/base/general/classes/BxBaseModGeneralMenuViewActions.php

@@ -62,8 +62,11 @@ class BxBaseModGeneralMenuViewActions extends BxTemplMenuCustom
             if(empty($this->_oMenuSocialSharing))
             if(empty($this->_oMenuSocialSharing))
                 $this->_initMenuSocialSharing();
                 $this->_initMenuSocialSharing();
 
 
-            $this->_oMenuSocialSharing->addMarkers($a);
-            parent::addMarkers($this->_oMenuSocialSharing->getMarkers());
+            //it still may be false in case the sys_social_sharing menu is turned off
+            if (!empty($this->_oMenuSocialSharing)) {
+                $this->_oMenuSocialSharing->addMarkers($a);
+                parent::addMarkers($this->_oMenuSocialSharing->getMarkers());
+            }
         }
         }
 
 
         return $bResult;
         return $bResult;

+ 64 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -25,6 +25,8 @@ class BxBaseModGeneralModule extends BxDolModule
     protected $_aSearchableNamesExcept;
     protected $_aSearchableNamesExcept;
     protected $_aFormParams;
     protected $_aFormParams;
 
 
+    protected $_aBrowsingFiltersKeys;
+
     function __construct(&$aModule)
     function __construct(&$aModule)
     {
     {
         parent::__construct($aModule);
         parent::__construct($aModule);
@@ -44,6 +46,8 @@ class BxBaseModGeneralModule extends BxDolModule
             'context_id' => 0,
             'context_id' => 0,
             'custom' => array()
             'custom' => array()
         );
         );
+
+        $this->_aBrowsingFiltersKeys = ['mode'];
     }
     }
 
 
     // ====== ACTIONS METHODS
     // ====== ACTIONS METHODS
@@ -298,6 +302,66 @@ class BxBaseModGeneralModule extends BxDolModule
         echo(json_encode($a));
         echo(json_encode($a));
     }
     }
 
 
+    public function actionGetBrowsingFilters()
+    {
+        $aParams = $this->_prepareBrowsingFiltersParamsGet();
+
+        $sContent = $this->_oTemplate->getBrowsingFilters($aParams);
+        if(empty($sContent))
+            return echoJson([]);
+
+        echoJson([
+            'code' => 0,
+            'popup' => [
+                'html' => $sContent,
+                'options' => [
+                    'closeOnOuterClick' => false,
+                    'removeOnClose' => false,
+                ]
+            ],
+        ]);
+    }
+
+    public function actionApplyBrowsingFilters()
+    {
+        $aParams = $this->_prepareBrowsingFiltersParamsGet();
+
+        $aBrowseParams = ['mode' => $aParams['mode'], 'empty_message' => true];
+        unset($aParams['mode']);
+        $aBrowseParams['params'] = $aParams;
+
+        $mixedResult = $this->serviceBrowse($aBrowseParams);
+        if(empty($mixedResult))
+            return echoJson([]);
+
+        if(is_array($mixedResult) && isset($mixedResult['content']))
+            $mixedResult = $mixedResult['content'];
+
+        return echoJson([
+            'code' => 0, 
+            'content' => $mixedResult, 
+            'eval' => $this->_oConfig->getJsObject('main') . '.onApplyBrowsingFilter(oData)'
+        ]);
+    }
+
+    protected function _prepareBrowsingFiltersParamsGet($mParams = false)
+    {
+        $aParams = [];
+        $bParams = !empty($mParams) && is_array($mParams);
+
+        foreach($this->_aBrowsingFiltersKeys as $sKey)
+            if($bParams) {
+                if(isset($mParams[$sKey]))
+                    $aParams[$sKey] = $mParams[$sKey];
+            }
+            else {
+                if(($sValue = bx_get($sKey)) !== false)
+                    $aParams[$sKey] = $sValue;
+            }
+
+        return $aParams;
+    }
+
     // ====== SERVICE METHODS
     // ====== SERVICE METHODS
 
 
     public function serviceIsBadgesAvaliable()
     public function serviceIsBadgesAvaliable()

+ 20 - 0
modules/base/general/classes/BxBaseModGeneralSearchResult.php

@@ -218,6 +218,26 @@ class BxBaseModGeneralSearchResult extends BxTemplSearchResult
         return parent::displayResultBlock();
         return parent::displayResultBlock();
     }
     }
 
 
+    function displaySearchBox ($sContent, $sPaginate = '')
+    {
+        $aResult = parent::displaySearchBox($sContent, $sPaginate = '');
+
+        if(isset($this->_aParams['filters']) && is_array($this->_aParams['filters']))
+            $aResult['buttons'] = [
+                ['title' => _t('_Filters'), 'href' => 'javascript:void(0)', 'onclick' => 'javascript:' . $this->_aParams['filters']['onclick']]
+            ];
+
+        return $aResult;
+    }
+
+    function applyContainerId()
+    {
+        if(empty($this->aCurrent['name']) || empty($this->_sMode))
+            return parent::applyContainerId();
+
+        return str_replace('_', '-', $this->aCurrent['name'] . '-search-result-block-' . $this->_sMode);
+    }
+
     function decodeDataAPI($a)
     function decodeDataAPI($a)
     {
     {
         $bExtendedUnits = getParam('sys_api_extended_units') == 'on';
         $bExtendedUnits = getParam('sys_api_extended_units') == 'on';

+ 17 - 1
modules/base/general/classes/BxBaseModGeneralTemplate.php

@@ -363,7 +363,23 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
         
         
         return $this->parseHtmlByName('favorite-list-info.html', array('bx_repeat:items' => $aListsTmpl, 'author' => $oProfile->getUnit()));
         return $this->parseHtmlByName('favorite-list-info.html', array('bx_repeat:items' => $aListsTmpl, 'author' => $oProfile->getUnit()));
     }
     }
-    
+
+    public function getBrowsingFilters($aParams)
+    {
+        if(empty($aParams['mode']))
+            return '';
+
+        $sContent = $this->_getBrowsingFiltersContent($aParams);
+        if(empty($sContent))
+            return '';
+
+        $sPopupId = $this->_oConfig->getHtmlIds('popup_bfilters_' . $aParams['mode']);
+        $sPopupContent = $this->parseHtmlByName('browsing_filters.html', [
+            'content' => $sContent
+    	]);
+
+    	return BxTemplFunctions::getInstance()->transBox($sPopupId, $sPopupContent, true);
+    }
 
 
     function entryAllActions($sActions)
     function entryAllActions($sActions)
     {
     {

+ 3 - 0
modules/base/general/template/browsing_filters.html

@@ -0,0 +1,3 @@
+<div class="bx-base-general-browsing-filters">
+    <div class="bx-base-general-browsing-filters-cnt bx-def-padding">__content__</div>
+</div>

+ 72 - 0
modules/base/groups/js/main.js

@@ -18,8 +18,80 @@ function BxBaseModGroupsMain(oOptions) {
     this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
     this._iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
 
 
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
+
+    this._oBrowsingFiltersPopupOptions = {};
+    this._oBrowsingFiltersPopupOptionsDefaults = {};
 }
 }
 
 
+BxBaseModGroupsMain.prototype.changeBrowsingFilters = function(oElement, sSelector, oRequestParams) {
+    if($(sSelector).length)
+        return $(sSelector).dolPopup(this._oBrowsingFiltersPopupOptions);
+
+    var $this = this;
+    var oData = jQuery.extend({mode: ''}, this._getDefaultData());
+    if(oRequestParams != undefined)
+        oData = jQuery.extend({}, oData, oRequestParams);
+
+    this.loadingInButton(oElement, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'get_browsing_filters',
+        oData,
+        function(oResponse) {
+            if(oElement)
+                $this.loadingInButton(oElement, false);
+
+            if(oResponse && oResponse.popup != undefined) {
+                $this._oBrowsingFiltersPopupOptions = jQuery.extend($this._oBrowsingFiltersPopupOptionsDefaults, oResponse.popup.options, {
+                    pointer: { 
+                        el: $(oElement),
+                        align: 'right'
+                    }
+                });
+
+                oResponse.popup.options = $this._oBrowsingFiltersPopupOptions;
+            }
+
+            processJsonData(oResponse);
+        },
+        'json'
+    );
+};
+
+BxBaseModGroupsMain.prototype.applyBrowsingFilter = function(oElement, oRequestParams) {
+    var $this = this;
+
+    var oData = this._getDefaultData();
+    if(oRequestParams != undefined)
+        oData = jQuery.extend({}, oData, oRequestParams);
+
+    this.loadingInButton(oElement, true);
+
+    jQuery.get (
+        this._sActionsUrl + 'apply_browsing_filters',
+        oData,
+        function(oResponse) {
+            $this.loadingInButton(oElement, false);
+
+            $(oElement).parents('.bx-popup-applied:visible:first').dolPopupHide();
+
+            processJsonData(oResponse);
+        },
+        'json'
+    );
+};
+
+BxBaseModGroupsMain.prototype.onApplyBrowsingFilter = function(oData) {
+    if(!oData.content)
+        return;
+
+    var oContainer = $('.bx-db-content').has('#' + $(oData.content).find('.bx-search-result-block:first').attr('id'));
+    if(!oContainer || oContainer.length == 0)
+        return;
+
+    oContainer.html(oData.content).bxProcessHtml();
+};
+
 BxBaseModGroupsMain.prototype.connAction = function(oElement, sObject, sAction, iContentId) {
 BxBaseModGroupsMain.prototype.connAction = function(oElement, sObject, sAction, iContentId) {
     var $this = this;
     var $this = this;
     var oParams = this._getDefaultData();
     var oParams = this._getDefaultData();

+ 5 - 4
modules/boonex/english/data/langs/system/en.xml

@@ -49,13 +49,14 @@
 	<string name="_favorite_err_duplicate_favorite"><![CDATA[You already favorited this item.]]></string>
 	<string name="_favorite_err_duplicate_favorite"><![CDATA[You already favorited this item.]]></string>
 	<string name="_favorite_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
 	<string name="_favorite_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
 	<string name="_feature_do_feature"><![CDATA[Feature]]></string>
 	<string name="_feature_do_feature"><![CDATA[Feature]]></string>
-    <string name="_feature_do_unfeature"><![CDATA[Unfeature]]></string>
-    <string name="_feature_err_cannot_perform_action"><![CDATA[Cannot perform the action.]]></string>
-    <string name="_feature_err_duplicate_feature"><![CDATA[The item was already added in featured list.]]></string>
-    <string name="_feature_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
+        <string name="_feature_do_unfeature"><![CDATA[Unfeature]]></string>
+        <string name="_feature_err_cannot_perform_action"><![CDATA[Cannot perform the action.]]></string>
+        <string name="_feature_err_duplicate_feature"><![CDATA[The item was already added in featured list.]]></string>
+        <string name="_feature_err_not_enabled"><![CDATA[The feature is not available right now. Please, try again later.]]></string>
 	<string name="_Female"><![CDATA[Woman]]></string>
 	<string name="_Female"><![CDATA[Woman]]></string>
         <string name="_free"><![CDATA[free]]></string>
         <string name="_free"><![CDATA[free]]></string>
 	<string name="_From"><![CDATA[From]]></string>
 	<string name="_From"><![CDATA[From]]></string>
+        <string name="_Filters"><![CDATA[Filters]]></string>
 	<string name="_Header"><![CDATA[Header]]></string>
 	<string name="_Header"><![CDATA[Header]]></string>
 	<string name="_Incorrect Captcha"><![CDATA[Incorrect Captcha]]></string>
 	<string name="_Incorrect Captcha"><![CDATA[Incorrect Captcha]]></string>
 	<string name="_Incorrect Email"><![CDATA[Incorrect Email]]></string>
 	<string name="_Incorrect Email"><![CDATA[Incorrect Email]]></string>

+ 1 - 0
modules/boonex/events/classes/BxEventsConfig.php

@@ -319,6 +319,7 @@ class BxEventsConfig extends BxBaseModGroupsConfig
 
 
         $sHtmlPrefix = str_replace('_', '-', $this->_sName);
         $sHtmlPrefix = str_replace('_', '-', $this->_sName);
         $this->_aHtmlIds = array_merge($this->_aHtmlIds, [
         $this->_aHtmlIds = array_merge($this->_aHtmlIds, [
+            'popup_bfilters_recent' => $sHtmlPrefix . '-popup-bfilters-recent',
             'popup_question' => $sHtmlPrefix . '-popup-question',
             'popup_question' => $sHtmlPrefix . '-popup-question',
             'popup_questionnaire' => $sHtmlPrefix . '-popup-questionnaire',
             'popup_questionnaire' => $sHtmlPrefix . '-popup-questionnaire',
             'popup_session' => $sHtmlPrefix . '-popup-session'
             'popup_session' => $sHtmlPrefix . '-popup-session'

+ 20 - 3
modules/boonex/events/classes/BxEventsModule.php

@@ -19,13 +19,18 @@ class BxEventsModule extends BxBaseModGroupsModule implements iBxDolCalendarServ
     function __construct(&$aModule)
     function __construct(&$aModule)
     {
     {
         parent::__construct($aModule);
         parent::__construct($aModule);
-        
+
         $CNF = &$this->_oConfig->CNF;
         $CNF = &$this->_oConfig->CNF;
-        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, array(
+
+        $this->_aSearchableNamesExcept = array_merge($this->_aSearchableNamesExcept, [
             $CNF['FIELD_TIMEZONE'],
             $CNF['FIELD_TIMEZONE'],
             $CNF['FIELD_JOIN_CONFIRMATION'],
             $CNF['FIELD_JOIN_CONFIRMATION'],
             $CNF['FIELD_REMINDER']
             $CNF['FIELD_REMINDER']
-        ));
+        ]);
+
+        $this->_aBrowsingFiltersKeys = array_merge($this->_aBrowsingFiltersKeys, [
+            'by_date', 'date_start', 'date_end', 'timezone'
+        ]);
     }
     }
 
 
     public function actionCheckIn()
     public function actionCheckIn()
@@ -424,6 +429,18 @@ class BxEventsModule extends BxBaseModGroupsModule implements iBxDolCalendarServ
         return $this->_serviceBrowse ('upcoming_connected', array_merge($aDefaults, $aParams), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
         return $this->_serviceBrowse ('upcoming_connected', array_merge($aDefaults, $aParams), BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
     }
     }
 
 
+    public function serviceBrowseRecentProfiles ($bDisplayEmptyMsg = false, $bAjaxPaginate = true)
+    {
+        $sMode = 'recent';
+
+        $sFilterSelector = '#' . $this->_oConfig->getHtmlIds('popup_bfilters_recent');
+        $aFilterParams = ['mode' => $sMode];
+
+        return $this->_serviceBrowse ($sMode, [
+            'filters' => ['onclick' => $this->_oConfig->getJsObject('main') . ".changeBrowsingFilters(this, '" . $sFilterSelector . "', " . json_encode($aFilterParams) . ")"]
+        ], BX_DB_PADDING_DEF, $bDisplayEmptyMsg, $bAjaxPaginate);
+    }
+
     /**
     /**
      * @page service Service Calls
      * @page service Service Calls
      * @section bx_events Events
      * @section bx_events Events

+ 68 - 0
modules/boonex/events/classes/BxEventsSearchResult.php

@@ -83,6 +83,74 @@ class BxEventsSearchResult extends BxBaseModGroupsSearchResult
         $oJoinedProfile = null;
         $oJoinedProfile = null;
         $bProcessConditionsForPrivateContent = true;
         $bProcessConditionsForPrivateContent = true;
 
 
+        $iDateStart = $iDateEnd = 0;
+        if(isset($this->_aParams['by_date'])) {
+            $iTimezoneOffset = 0;
+            if(!empty($this->_aParams['timezone']) && in_array($this->_aParams['timezone'], timezone_identifiers_list()))
+                $iTimezoneOffset = date_offset_get(date_create('now', timezone_open($this->_aParams['timezone'])));
+
+            switch($this->_aParams['by_date']) {
+                case 'today':
+                    $iDateStart = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
+                    $iDateEnd = $iDateStart + 86399;
+                    break;
+
+                case 'tomorrow':
+                    $iDateStart = mktime(0, 0, 0, date("m"), date("d") + 1, date("Y"));
+                    $iDateEnd = $iDateStart + 86399;
+                    break;
+
+                case 'weekend':
+                    $iDayOfWeek = date("w");
+                    $iDateStart = mktime(0, 0, 0, date("m"), date("d") + ($iDayOfWeek > 0 ? 6 - $iDayOfWeek : -1), date("Y"));
+                    $iDateEnd = $iDateStart + 2 * 86400 - 1;
+                    break;
+
+                case 'this_week':
+                    $iDayOfWeek = date("w");
+                    $iDateStart = mktime(0, 0, 0, date("m"), date("d") - ($iDayOfWeek > 0 ? $iDayOfWeek - 1 : 6), date("Y"));
+                    $iDateEnd = $iDateStart + 7 * 86400 - 1;
+                    break;
+
+                case 'next_week':
+                    $iDayOfWeek = date("w");
+                    $iDateStart = mktime(0, 0, 0, date("m"), date("d") + ($iDayOfWeek > 0 ? 8 - $iDayOfWeek : 1), date("Y"));
+                    $iDateEnd = $iDateStart + 7 * 86400 - 1;
+                    break;
+
+                case 'this_month':
+                    $iDateStart = mktime(0, 0, 0, date("m"), 1, date("Y"));
+                    $iDateEnd = mktime(23, 59, 59, date("m") + 1, 0, date("Y"));
+                    break;
+
+                case 'date_range':
+                    if(!empty($this->_aParams['date_start'])) {
+                        list($iDsy, $iDsm, $iDsd,) = explode('-', $this->_aParams['date_start']);
+                        $iDateStart = mktime(0, 0, 0, $iDsm, $iDsd, $iDsy);
+                    }
+                    else
+                        $iDateStart = mktime(0, 0, 0, date("m"), date("d"), date("Y"));
+
+                    if(!empty($this->_aParams['date_end'])) {
+                        list($iDey, $iDem, $iDed,) = explode('-', $this->_aParams['date_end']);
+                        $iDateEnd = mktime(23, 59, 59, $iDem, $iDed, $iDey);
+                    }
+                    else
+                        $iDateEnd = mktime(23, 59, 59, date("m"), date("d"), date("Y"));
+                    break;
+            }
+
+            if($iDateStart != 0 && $iDateEnd != 0) {
+                $iDateStart -= $iTimezoneOffset;
+                $iDateEnd -= $iTimezoneOffset;
+
+                //--- 1. already started or will start in selected date interval
+                $this->aCurrent['restriction']['filter_date_start'] = ['value' => $iDateEnd, 'field' => 'date_start', 'operator' => '<', 'table' => 'bx_events_data'];
+                //--- 2. and didn't finished to the beginning of selected date interval
+                $this->aCurrent['restriction']['filter_date_end'] = ['value' => $iDateStart, 'field' => 'date_end', 'operator' => '>', 'table' => 'bx_events_data'];
+            }
+        }
+
         switch ($sMode) {
         switch ($sMode) {
             case 'created_entries':
             case 'created_entries':
                 if(!$this->_setAuthorConditions($sMode, $aParams, $oJoinedProfile)) {
                 if(!$this->_setAuthorConditions($sMode, $aParams, $oJoinedProfile)) {

+ 67 - 0
modules/boonex/events/classes/BxEventsTemplate.php

@@ -90,6 +90,73 @@ class BxEventsTemplate extends BxBaseModGroupsTemplate
 			'date_end_f' => $oDateEnd ? bx_time_js($oDateEnd->getTimestamp(), BX_FORMAT_DATE_TIME, true) : '',
 			'date_end_f' => $oDateEnd ? bx_time_js($oDateEnd->getTimestamp(), BX_FORMAT_DATE_TIME, true) : '',
         ));
         ));
     }
     }
+
+    protected function _getBrowsingFiltersContent($aParams)
+    {
+        $sJsObject = $this->_oConfig->getJsObject('main');
+
+        $aForm = [
+            'inputs' => [
+                'by_date' => [
+                    'name' => 'by_date',
+                    'type' => 'radio_set',
+                    'caption' => _t('_bx_events_form_filters_input_by_date'),
+                    'values' => [
+                        ['key' => 'all', 'value' => _t('_bx_events_form_filters_input_by_date_all')],
+                        ['key' => 'today', 'value' => _t('_bx_events_form_filters_input_by_date_today')],
+                        ['key' => 'tomorrow', 'value' => _t('_bx_events_form_filters_input_by_date_tomorrow')],
+                        ['key' => 'weekend', 'value' => _t('_bx_events_form_filters_input_by_date_weekend')],
+                        ['key' => 'this_week', 'value' => _t('_bx_events_form_filters_input_by_date_this_week')],
+                        ['key' => 'next_week', 'value' => _t('_bx_events_form_filters_input_by_date_next_week')],
+                        ['key' => 'this_month', 'value' => _t('_bx_events_form_filters_input_by_date_this_month')],
+                        ['key' => 'date_range', 'value' => _t('_bx_events_form_filters_input_by_date_date_range')],
+                        
+                    ],
+                    'value' => 'all',
+                    'attrs' => ['onchange' => $sJsObject . '.onChangeBrowsingFiltersByDate(this)'],
+                    'dv_thd' => 1
+                ],
+                'date_start' => [
+                    'name' => 'date_start',
+                    'type' => 'datepicker',
+                    'tr_attrs' => ['class' => 'date-range date-start', 'style' => 'display:none']
+                ],
+                'date_end' => [
+                    'name' => 'date_end',
+                    'type' => 'datepicker',
+                    'tr_attrs' => ['class' => 'date-range date-end', 'style' => 'display:none']
+                ],
+                'timezone' => [
+                    'name' => 'timezone',
+                    'type' => 'hidden',
+                    'value' => ''
+                ],
+                'controls' => [
+                    'name' => 'controls',
+                    'type' => 'input_set',
+                    [
+                        'name' => 'apply',
+                        'type' => 'button',
+                        'value' => _t('_bx_events_form_filters_input_do_apply'),
+                        'attrs' => ['onclick' => $sJsObject . '.applyBrowsingFilter(this, ' . json_encode($aParams) . ')']
+                    ], [
+                        'name' => 'cancel',
+                        'type' => 'button',
+                        'value' => _t('_Cancel'),
+                        'attrs' => [
+                            'class' => 'bx-def-margin-sec-left',
+                            'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()"
+                        ]
+                    ],
+                    
+                ],
+                
+            ]
+        ];
+
+        $oForm = new BxTemplFormView($aForm);
+        return $this->addJs(['moment-timezone-with-data-1970-2030.min.js'], true) . $oForm->getCode(true);
+    }
 }
 }
 
 
 /** @} */
 /** @} */

+ 12 - 0
modules/boonex/events/install/langs/en.xml

@@ -152,6 +152,18 @@
     <string name="_bx_events_form_price_input_sys_do_cancel"><![CDATA[Cancel]]></string>
     <string name="_bx_events_form_price_input_sys_do_cancel"><![CDATA[Cancel]]></string>
     <string name="_bx_events_form_price_input_do_cancel"><![CDATA[Cancel]]></string>
     <string name="_bx_events_form_price_input_do_cancel"><![CDATA[Cancel]]></string>
 
 
+    <string name="_bx_events_form_filters_input_by_date"><![CDATA[By date]]></string>
+    <string name="_bx_events_form_filters_input_by_date_all"><![CDATA[Any date]]></string>
+    <string name="_bx_events_form_filters_input_by_date_today"><![CDATA[Today]]></string>
+    <string name="_bx_events_form_filters_input_by_date_tomorrow"><![CDATA[Tomorrow]]></string>
+    <string name="_bx_events_form_filters_input_by_date_weekend"><![CDATA[This weekend]]></string>
+    <string name="_bx_events_form_filters_input_by_date_this_week"><![CDATA[This week]]></string>
+    <string name="_bx_events_form_filters_input_by_date_next_week"><![CDATA[Next week]]></string>
+    <string name="_bx_events_form_filters_input_by_date_this_month"><![CDATA[This month]]></string>
+    <string name="_bx_events_form_filters_input_by_date_date_range"><![CDATA[Custom date range]]></string>
+    <string name="_bx_events_form_filters_input_do_apply"><![CDATA[Apply]]></string>
+
+
     <string name="_bx_events_acl_action_create_profile"><![CDATA[Create Event]]></string>
     <string name="_bx_events_acl_action_create_profile"><![CDATA[Create Event]]></string>
     <string name="_bx_events_acl_action_use_paid_join"><![CDATA[Use paid join]]></string>
     <string name="_bx_events_acl_action_use_paid_join"><![CDATA[Use paid join]]></string>
     <string name="_bx_events_acl_action_delete_profile"><![CDATA[Delete Event]]></string>
     <string name="_bx_events_acl_action_delete_profile"><![CDATA[Delete Event]]></string>

+ 37 - 1
modules/boonex/events/js/main.js

@@ -10,11 +10,47 @@
 
 
 function BxEventsMain(oOptions) {
 function BxEventsMain(oOptions) {
     BxBaseModGroupsMain.call(this, oOptions);
     BxBaseModGroupsMain.call(this, oOptions);
-    
+
     this._sObjName = oOptions.sObjName == undefined ? 'oBxEventsMain' : oOptions.sObjName;
     this._sObjName = oOptions.sObjName == undefined ? 'oBxEventsMain' : oOptions.sObjName;
+
+    this._oBrowsingFiltersPopupOptionsDefaults = jQuery.extend(this._oBrowsingFiltersPopupOptionsDefaults,  {
+        onShow: function(oPopup) {
+            var oTimezone = $(oPopup).find("[name = 'timezone']");
+            if(oTimezone && oTimezone.length != 0)
+                oTimezone.val(moment.tz.guess());
+    
+            console.log(oTimezone.val());
+    
+            $(oPopup).find("[name = 'cancel']").focus();
+        }
+    });   
 }
 }
 
 
 BxEventsMain.prototype = Object.create(BxBaseModGroupsMain.prototype);
 BxEventsMain.prototype = Object.create(BxBaseModGroupsMain.prototype);
 BxEventsMain.prototype.constructor = BxEventsMain;
 BxEventsMain.prototype.constructor = BxEventsMain;
 
 
+BxEventsMain.prototype.onChangeBrowsingFiltersByDate = function(oElement) {
+    var sAction = $(oElement).val() == 'date_range' ? 'show' : 'hide';
+
+    $(oElement).parents('.bx-form-element-wrapper:first').siblings('.date-range').each(function() {
+        $(this).bx_anim(sAction);
+    });
+};
+
+BxEventsMain.prototype.applyBrowsingFilter = function(oElement, oRequestParams)
+{
+    var oFilters = $(oElement).parents('.bx-base-general-browsing-filters:first');
+
+    if(oRequestParams == undefined)
+        oRequestParams = {};
+
+    oRequestParams.by_date = oFilters.find("input[name='by_date']:checked").val();
+    if(oRequestParams.by_date == 'date_range') {
+        oRequestParams.date_start = oFilters.find("input[name='date_start']").val();
+        oRequestParams.date_end = oFilters.find("input[name='date_end']").val();
+    }
+    oRequestParams.timezone = oFilters.find("input[name='timezone']").val();
+
+    BxBaseModGroupsMain.prototype.applyBrowsingFilter.call(this, oElement, oRequestParams);
+};
 /** @} */
 /** @} */

+ 6 - 5
modules/boonex/russian/data/langs/system/ru.xml

@@ -46,14 +46,15 @@
 	<string name="_favorite_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
 	<string name="_favorite_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
 	<string name="_favorite_err_duplicate_favorite"><![CDATA[Вы уже добавляли данный объект в избранное ранее.]]></string>
 	<string name="_favorite_err_duplicate_favorite"><![CDATA[Вы уже добавляли данный объект в избранное ранее.]]></string>
 	<string name="_favorite_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
 	<string name="_favorite_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
-    <string name="_feature_do_feature"><![CDATA[В продвинутые]]></string>
-    <string name="_feature_do_unfeature"><![CDATA[Из продвинутых]]></string>
-    <string name="_feature_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
-    <string name="_feature_err_duplicate_feature"><![CDATA[Данный объект уже добавлен в список продвинутых.]]></string>
-    <string name="_feature_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
+        <string name="_feature_do_feature"><![CDATA[В продвинутые]]></string>
+        <string name="_feature_do_unfeature"><![CDATA[Из продвинутых]]></string>
+        <string name="_feature_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие.]]></string>
+        <string name="_feature_err_duplicate_feature"><![CDATA[Данный объект уже добавлен в список продвинутых.]]></string>
+        <string name="_feature_err_not_enabled"><![CDATA[Действие не доступно в данный момент. Пожалуйста, попробуйте позднее.]]></string>
 	<string name="_Female"><![CDATA[Женщина]]></string>
 	<string name="_Female"><![CDATA[Женщина]]></string>
         <string name="_free"><![CDATA[бесплатно]]></string>
         <string name="_free"><![CDATA[бесплатно]]></string>
 	<string name="_From"><![CDATA[От]]></string>
 	<string name="_From"><![CDATA[От]]></string>
+        <string name="_Filters"><![CDATA[Фильтры]]></string>
 	<string name="_Header"><![CDATA[Заголовок]]></string>
 	<string name="_Header"><![CDATA[Заголовок]]></string>
 	<string name="_Incorrect Captcha"><![CDATA[Неправильная капча]]></string>
 	<string name="_Incorrect Captcha"><![CDATA[Неправильная капча]]></string>
 	<string name="_Incorrect Email"><![CDATA[Введите правильный адрес электронной почты]]></string>
 	<string name="_Incorrect Email"><![CDATA[Введите правильный адрес электронной почты]]></string>

+ 3 - 5
template/scripts/BxBaseFormView.php

@@ -1778,11 +1778,8 @@ BLAH;
 
 
         $sKeyPlaceholder = $aInput['caption_src'] . '_placeholder';
         $sKeyPlaceholder = $aInput['caption_src'] . '_placeholder';
         if(strcmp($sKeyPlaceholder, _t($sKeyPlaceholder)) != 0)
         if(strcmp($sKeyPlaceholder, _t($sKeyPlaceholder)) != 0)
-            $sValue .= $oLabel->getLabelPlaceholder($sKeyPlaceholder);           
+            $sValue .= $oLabel->getLabelPlaceholder($sKeyPlaceholder);                   
 
 
-       // print_r($aInput);
-         
-        
         $aInputLabels = array(
         $aInputLabels = array(
             'type' => 'custom',
             'type' => 'custom',
             'name' => $sName,
             'name' => $sName,
@@ -1801,8 +1798,9 @@ BLAH;
             $aInput['type'] = 'labels';
             $aInput['type'] = 'labels';
             //$aInput['ajax_get_suggestions'] = 'system/select_labels/TemplLabelsServices&params[]=';
             //$aInput['ajax_get_suggestions'] = 'system/select_labels/TemplLabelsServices&params[]=';
             $aInput['values'] = bx_srv('system', 'get_labels', [], 'TemplLabelsServices');
             $aInput['values'] = bx_srv('system', 'get_labels', [], 'TemplLabelsServices');
+
         }
         }
-        
+
         return $this->oTemplate->parseHtmlByName('label_select_field.html', array(
         return $this->oTemplate->parseHtmlByName('label_select_field.html', array(
             'js_object' => $oLabel->getJsObjectName(),
             'js_object' => $oLabel->getJsObjectName(),
             'js_code' => $oLabel->getJsCodeForm(),
             'js_code' => $oLabel->getJsCodeForm(),

+ 26 - 39
template/scripts/BxBaseLabel.php

@@ -307,47 +307,34 @@ class BxBaseLabel extends BxDolLabel
         $aCheckbox = $aInput;
         $aCheckbox = $aInput;
         $aCheckbox['type'] = 'checkbox';
         $aCheckbox['type'] = 'checkbox';
         $aCheckbox['name'] .= '[]';
         $aCheckbox['name'] .= '[]';
-        
-        $aModules = bx_srv('system', 'get_modules_by_type', ['context']);
+
+        $aLabels = $this->getLabelsContext($iProfileId);
 
 
         $aTmplVarsLabels = [];
         $aTmplVarsLabels = [];
-        foreach($aModules as $aModule) {
-            if(bx_srv($aModule['name'], 'act_as_profile'))
-                continue;
-
-            $aContextPids = bx_srv($aModule['name'], 'get_participating_profiles', [$iProfileId]);
-            if(empty($aContextPids) || !is_array($aContextPids))
-                continue;
-
-            foreach($aContextPids as $iContextPid) {
-                $aContextInfo = bx_srv($aModule['name'], 'get_content_info_by_profile_id', [$iContextPid]);
-                if(empty($aContextInfo['hashtag']))
-                    continue;
-
-                $sLabelValue = $aContextInfo['hashtag'];
-
-                $sHtmlId = 'sys_label_' . $sLabelValue;
-                $bChecked = $bInputValue && in_array($sLabelValue, $aInput['value']);
-
-                $aCheckbox['value'] = $sLabelValue;
-                $aCheckbox['checked'] = $bChecked ? 1 : 0;
-                $aCheckbox['attrs']['id'] = $sHtmlId;
-
-                $aTmplVarsLabels[] = [
-                    'checkbox' => $oForm->genInput($aCheckbox),
-                    'html_id_label' => $sHtmlId,
-                    'title' => $sLabelValue,
-                    'title_attr' => bx_html_attribute($sLabelValue),
-                    'bx_if:show_sublist_link' => [
-                        'condition' => false,
-                        'content' => []
-                    ],
-                    'bx_if:show_sublist' => [
-                        'condition' => false,
-                        'content' => [],
-                    ]
-                ];
-            }
+        foreach($aLabels as $aLabel) {
+            $sLabelValue = $aLabel['value'];
+
+            $sHtmlId = 'sys_label_' . $sLabelValue;
+            $bChecked = $bInputValue && in_array($sLabelValue, $aInput['value']);
+
+            $aCheckbox['value'] = $sLabelValue;
+            $aCheckbox['checked'] = $bChecked ? 1 : 0;
+            $aCheckbox['attrs']['id'] = $sHtmlId;
+
+            $aTmplVarsLabels[] = [
+                'checkbox' => $oForm->genInput($aCheckbox),
+                'html_id_label' => $sHtmlId,
+                'title' => $sLabelValue,
+                'title_attr' => bx_html_attribute($sLabelValue),
+                'bx_if:show_sublist_link' => [
+                    'condition' => false,
+                    'content' => []
+                ],
+                'bx_if:show_sublist' => [
+                    'condition' => false,
+                    'content' => [],
+                ]
+            ];
         }
         }
 
 
         $sContent = $this->_oTemplate->parseHtmlByName('label_select_list_level.html', [
         $sContent = $this->_oTemplate->parseHtmlByName('label_select_list_level.html', [

+ 6 - 2
template/scripts/BxBaseLabelsServices.php

@@ -17,10 +17,14 @@ class BxBaseLabelsServices extends BxDol
         parent::__construct();
         parent::__construct();
     }
     }
 
 
-    public function serviceSelectLabels()
+    public function serviceGetLabels()
     {
     {
         $oLabel = BxDolLabel::getInstance();
         $oLabel = BxDolLabel::getInstance();
-        return 'todo';
+
+        return [
+            'system' => $oLabel->getLabelsSystem(),
+            'context' => $oLabel->getLabelsContext()
+        ];
     }
     }
 }
 }
 
 

+ 24 - 1
template/scripts/BxBaseSearchResult.php

@@ -59,7 +59,7 @@ class BxBaseSearchResult extends BxDolSearchResult
             foreach ($aData as $aValue)
             foreach ($aData as $aValue)
                 $sCode .= $this->displaySearchUnit($aValue);
                 $sCode .= $this->displaySearchUnit($aValue);
 
 
-            $sHtmlId = 'bx-search-result-block-' . rand(0, PHP_INT_MAX);
+            $sHtmlId = $this->applyContainerId();
             $sClasses = $this->applyContainerClass();
             $sClasses = $this->applyContainerClass();
 
 
             $sAttributes = '';
             $sAttributes = '';
@@ -91,6 +91,20 @@ class BxBaseSearchResult extends BxDolSearchResult
         return $sCode;
         return $sCode;
     }
     }
 
 
+    function displayResultBlockEmpty ()
+    {
+        return BxDolTemplate::getInstance()->parseHtmlByName('search_result_block.html', [
+            'html_id' => $this->applyContainerId(),
+            'class' => 'bx-search-result-block bx-search-result-block-empty',
+            'attrs' => '',
+            'content' => parent::displayResultBlockEmpty(),
+            'bx_if:do_center' => [
+                'condition' => false,
+                'content' => []
+            ]
+        ]);
+    }
+
     function displaySearchBox ($sContent, $sPaginate = '')
     function displaySearchBox ($sContent, $sPaginate = '')
     {
     {
 		$sContent = BxDolTemplate::getInstance()->parseHtmlByName('paginate_block.html', array(
 		$sContent = BxDolTemplate::getInstance()->parseHtmlByName('paginate_block.html', array(
@@ -369,6 +383,15 @@ class BxBaseSearchResult extends BxDolSearchResult
         $this->sCenterContentUnitSelector = $s;
         $this->sCenterContentUnitSelector = $s;
     }
     }
 
 
+    /**
+     * Add ID to search result container 
+     * @param $string HTML ID
+     */
+    function applyContainerId()
+    {
+        return 'bx-search-result-block-' . rand(0, PHP_INT_MAX);
+    }
+
     /**
     /**
      * Add class to search result container 
      * Add class to search result container 
      * @param $mixed CSS class name string or array of classes
      * @param $mixed CSS class name string or array of classes