1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-05-19 17:28:23 +03:00

Переработка поиска по пользователям

This commit is contained in:
Mzhelskiy Maxim 2014-03-06 19:34:13 +07:00
parent ecf8f0a8b7
commit 57d58dc2b5
16 changed files with 189 additions and 173 deletions

View file

@ -50,8 +50,6 @@ class ActionPeople extends Action {
*
*/
protected function RegisterEvent() {
$this->AddEvent('online','EventOnline');
$this->AddEvent('new','EventNew');
$this->AddEventPreg('/^(index)?$/i','/^(page([1-9]\d{0,5}))?$/i','/^$/i','EventIndex');
$this->AddEventPreg('/^ajax-search$/i','EventAjaxSearch');
@ -73,6 +71,19 @@ class ActionPeople extends Action {
* Устанавливаем формат Ajax ответа
*/
$this->Viewer_SetResponseAjax('json');
/**
* Формируем фильтр
*/
$aFilter=array(
'activate' => 1
);
$sOrderWay=in_array(getRequestStr('order'),array('desc','asc')) ? getRequestStr('order') : 'desc';
$sOrderField=in_array(getRequestStr('sort_by'),array('user_rating','user_date_register','user_login','user_skill','user_profile_name')) ? getRequestStr('sort_by') : 'user_rating';
if (is_numeric(getRequestStr('pageNext')) and getRequestStr('pageNext')>0) {
$iPage=getRequestStr('pageNext');
} else {
$iPage=1;
}
/**
* Получаем из реквеста первые быквы для поиска пользователей по логину
*/
@ -80,23 +91,41 @@ class ActionPeople extends Action {
if (is_string($sTitle) and mb_strlen($sTitle,'utf-8')) {
$sTitle=str_replace(array('_','%'),array('\_','\%'),$sTitle);
} else {
$this->Viewer_AssignAjax('bShowOriginal',true);
return;
$sTitle='';
}
/**
* Как именно искать: совпадение в любой частилогина, или только начало или конец логина
*/
if (getRequest('isPrefix')) {
$sTitle.='%';
} elseif (getRequest('isPostfix')) {
$sTitle='%'.$sTitle;
} else {
$sTitle='%'.$sTitle.'%';
if ($sTitle) {
if (getRequest('isPrefix')) {
$sTitle.='%';
} elseif (getRequest('isPostfix')) {
$sTitle='%'.$sTitle;
} else {
$sTitle='%'.$sTitle.'%';
}
}
if ($sTitle) {
$aFilter['login']=$sTitle;
}
/**
* Пол
*/
if (in_array(getRequestStr('sex'),array('man','woman','other'))) {
$aFilter['profile_sex']=getRequestStr('sex');
}
/**
* Онлайн
* date_last
*/
if (getRequest('is_online')) {
$aFilter['date_last_more']=date('Y-m-d H:i:s',time()-Config::Get('module.user.time_onlive'));
}
/**
* Ищем пользователей
*/
$aResult=$this->User_GetUsersByFilter(array('activate' => 1,'login'=>$sTitle),array('user_rating'=>'desc'),1,50);
$aResult=$this->User_GetUsersByFilter($aFilter,array($sOrderField=>$sOrderWay),$iPage,Config::Get('module.user.per_page'));
$bHideMore=$iPage*Config::Get('module.user.per_page')>=$aResult['count'];
/**
* Формируем ответ
*/
@ -104,9 +133,16 @@ class ActionPeople extends Action {
$oViewer->Assign('aUsersList',$aResult['collection']);
$oViewer->Assign('oUserCurrent',$this->User_GetUserCurrent());
$oViewer->Assign('sUserListEmpty',$this->Lang_Get('search.alerts.empty'));
$oViewer->Assign('bIsSearch', true);
$oViewer->Assign('iSearchCount', count($aResult['collection']));
$oViewer->Assign('bUseMore', true);
$oViewer->Assign('bHideMore', $bHideMore);
$oViewer->Assign('iSearchCount', $aResult['count']);
$this->Viewer_AssignAjax('sText',$oViewer->Fetch("user_list.tpl"));
/**
* Для подгрузки
*/
$this->Viewer_AssignAjax('iCountLoaded',count($aResult['collection']));
$this->Viewer_AssignAjax('pageNext',count($aResult['collection'])>0 ? $iPage+1 : $iPage);
$this->Viewer_AssignAjax('bHideMore',$bHideMore);
}
/**
* Показывает юзеров по стране
@ -192,38 +228,6 @@ class ActionPeople extends Action {
$this->Viewer_Assign('oCity',$oCity);
$this->Viewer_Assign('aUsersCity',$aUsersCity);
}
/**
* Показываем последних на сайте
*
*/
protected function EventOnline() {
$this->sMenuItemSelect='online';
/**
* Последние по визиту на сайт
*/
$aUsersLast=$this->User_GetUsersByDateLast(15);
$this->Viewer_Assign('aUsersLast',$aUsersLast);
/**
* Получаем статистику
*/
$this->GetStats();
}
/**
* Показываем новых на сайте
*
*/
protected function EventNew() {
$this->sMenuItemSelect='new';
/**
* Последние по регистрации
*/
$aUsersRegister=$this->User_GetUsersByDateRegister(15);
$this->Viewer_Assign('aUsersRegister',$aUsersRegister);
/**
* Получаем статистику
*/
$this->GetStats();
}
/**
* Показываем юзеров
*
@ -233,36 +237,13 @@ class ActionPeople extends Action {
* Получаем статистику
*/
$this->GetStats();
/**
* По какому полю сортировать
*/
$sOrder='user_rating';
if (getRequest('order')) {
$sOrder=getRequestStr('order');
}
/**
* В каком направлении сортировать
*/
$sOrderWay='desc';
if (getRequest('order_way')) {
$sOrderWay=getRequestStr('order_way');
}
$aFilter=array(
'activate' => 1
);
/**
* Передан ли номер страницы
*/
$iPage=$this->GetParamEventMatch(0,2) ? $this->GetParamEventMatch(0,2) : 1;
/**
* Получаем список юзеров
*/
$aResult=$this->User_GetUsersByFilter($aFilter,array($sOrder=>$sOrderWay),$iPage,Config::Get('module.user.per_page'));
$aUsers=$aResult['collection'];
/**
* Формируем постраничность
*/
$aPaging=$this->Viewer_MakePaging($aResult['count'],$iPage,Config::Get('module.user.per_page'),Config::Get('pagination.pages.count'),Router::GetPath('people').'index',array('order'=>$sOrder,'order_way'=>$sOrderWay));
$aResult=$this->User_GetUsersByFilter($aFilter,array('user_rating'=>'desc'),1,Config::Get('module.user.per_page'));
/**
* Получаем алфавитный указатель на список пользователей
*/
@ -270,12 +251,9 @@ class ActionPeople extends Action {
/**
* Загружаем переменные в шаблон
*/
$this->Viewer_Assign('aPaging',$aPaging);
$this->Viewer_Assign('aUsers',$aUsers);
$this->Viewer_Assign('aUsers',$aResult['collection']);
$this->Viewer_Assign('iSearchCount', $aResult['count']);
$this->Viewer_Assign('aPrefixUser',$aPrefixUser);
$this->Viewer_Assign("sUsersOrder",htmlspecialchars($sOrder));
$this->Viewer_Assign("sUsersOrderWay",htmlspecialchars($sOrderWay));
$this->Viewer_Assign("sUsersOrderWayNext",htmlspecialchars($sOrderWay=='desc' ? 'asc' : 'desc'));
/**
* Устанавливаем шаблон вывода
*/
@ -307,5 +285,4 @@ class ActionPeople extends Action {
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
$this->Viewer_Assign('sMenuItemSelect',$this->sMenuItemSelect);
}
}
?>
}

View file

@ -671,7 +671,11 @@ class ModuleUser extends Module {
$sKey="user_filter_".serialize($aFilter).serialize($aOrder)."_{$iCurrPage}_{$iPerPage}";
if (false === ($data = $this->Cache_Get($sKey))) {
$data = array('collection'=>$this->oMapper->GetUsersByFilter($aFilter,$aOrder,$iCount,$iCurrPage,$iPerPage),'count'=>$iCount);
$this->Cache_Set($data, $sKey, array("user_update","user_new"), 60*60*24*2);
/**
* Если есть фильтр по "кто онлайн", то уменьшаем время кеширования до 10 минут
*/
$iTimeCache=isset($aFilter['date_last_more']) ? 60*10 : 60*60*24*2;
$this->Cache_Set($data, $sKey, array("user_update","user_new"), $iTimeCache);
}
$data['collection']=$this->GetUsersAdditionalData($data['collection'],$aAllowData);
return $data;

View file

@ -354,7 +354,7 @@ class ModuleUser_EntityUser extends Entity {
*/
public function isOnline() {
if ($oSession=$this->getSession()) {
if (time()-strtotime($oSession->getDateLast())<60*10) { // 10 минут
if (time()-strtotime($oSession->getDateLast())<Config::Get('module.user.time_onlive')) { // 10 минут
return true;
}
}

View file

@ -1209,34 +1209,37 @@ class ModuleUser_MapperUser extends Mapper {
if (!in_array($key,$aOrderAllow)) {
unset($aOrder[$key]);
} elseif (in_array($value,array('asc','desc'))) {
$sOrder.=" {$key} {$value},";
$sOrder.=" u.{$key} {$value},";
}
}
$sOrder=trim($sOrder,',');
if ($sOrder=='') {
$sOrder=' user_id desc ';
$sOrder=' u.user_id desc ';
}
$sql = "SELECT
user_id
u.user_id
FROM
".Config::Get('db.table.user')."
".Config::Get('db.table.user')." as u
LEFT JOIN ".Config::Get('db.table.session')." as s ON u.user_id=s.user_id
WHERE
1 = 1
{ AND user_id = ?d }
{ AND user_mail = ? }
{ AND user_password = ? }
{ AND user_ip_register = ? }
{ AND user_activate = ?d }
{ AND user_activate_key = ? }
{ AND user_profile_sex = ? }
{ AND user_login LIKE ? }
{ AND user_profile_name LIKE ? }
{ AND s.session_date_last >= ? }
{ AND u.user_id = ?d }
{ AND u.user_mail = ? }
{ AND u.user_password = ? }
{ AND u.user_ip_register = ? }
{ AND u.user_activate = ?d }
{ AND u.user_activate_key = ? }
{ AND u.user_profile_sex = ? }
{ AND u.user_login LIKE ? }
{ AND u.user_profile_name LIKE ? }
ORDER by {$sOrder}
LIMIT ?d, ?d ;
";
$aResult=array();
if ($aRows=$this->oDb->selectPage($iCount,$sql,
isset($aFilter['date_last_more']) ? $aFilter['date_last_more'] : DBSIMPLE_SKIP,
isset($aFilter['id']) ? $aFilter['id'] : DBSIMPLE_SKIP,
isset($aFilter['mail']) ? $aFilter['mail'] : DBSIMPLE_SKIP,
isset($aFilter['password']) ? $aFilter['password'] : DBSIMPLE_SKIP,

View file

@ -129,6 +129,7 @@ $config['module']['user']['login']['min_size'] = 3; // Минимальное к
$config['module']['user']['login']['max_size'] = 30; // Максимальное количество символов в логине
$config['module']['user']['login']['charset'] = '0-9a-z_\-'; // Допустимые в имени пользователя символы
$config['module']['user']['time_active'] = 60*60*24*7; // Число секунд с момента последнего посещения пользователем сайта, в течение которых он считается активным
$config['module']['user']['time_onlive'] = 60*10; // Число секунд с момента последнего посещения пользователем сайта, в течение которых он считается "онлайн"
$config['module']['user']['usernote_text_max'] = 250; // Максимальный размер заметки о пользователе
$config['module']['user']['usernote_per_page'] = 20; // Число заметок на одну страницу
$config['module']['user']['userfield_max_identical'] = 2; // Максимальное число контактов одного типа

View file

@ -27,7 +27,9 @@
// Название переменной с результатом
result: 'sHtml',
// Параметры запроса
params: {}
params: {},
// Проксирующие параметры
proxy: {}
},
/**
@ -38,6 +40,7 @@
*/
_create: function () {
this.options = $.extend({}, this.options, ls.utils.getDataOptions(this.element, this.widgetName));
this.options.proxy = $.extend({}, this.options.proxy, ls.utils.getDataOptions(this.element, 'proxy'));
this.target = $( this.options.target );
this.counter = this.element.find('.js-more-count');
@ -72,12 +75,18 @@
load: function () {
this._trigger("beforeload", null, this);
this.options.params = ls.utils.getDataOptions(this.element, 'param');
this.options.params = $.extend({}, this.options.params, ls.utils.getDataOptions(this.element, 'param'));
this.lock();
ls.ajax.load(this.options.url, this.options.params, function (oResponse) {
var params=$.extend({}, this.options.params, this.options.proxy);
ls.ajax.load(this.options.url, params, function (oResponse) {
if (oResponse.iCountLoaded > 0) {
this.target[ this.options.append ? 'append' : 'prepend' ]($.trim(oResponse[this.options.result]));
var html=$('<div></div>').html($.trim(oResponse[this.options.result]));
if (html.find(this.options.target).length) {
html=html.find(this.options.target).first();
}
this.target[ this.options.append ? 'append' : 'prepend' ](html.html());
this.element.data('param-i-last-id', oResponse.iLastId);
// Обновляем счетчик
@ -90,6 +99,16 @@
this.counter.text(iCountLeft);
}
}
// Обновляем параметры
$.each(this.options.proxy,function(k,v){
if (oResponse[k]) {
this.options.proxy[k]=oResponse[k];
}
}.bind(this));
if (oResponse.bHideMore) {
this.element.remove();
}
} else {
// Для блоков без счетчиков
ls.msg.notice(null, 'Больше нечего подгружать');

View file

@ -66,7 +66,11 @@ ls.search = (function ($) {
oSearchAlhpabetItems.removeClass(ls.options.classes.states.active);
oElement.addClass(ls.options.classes.states.active);
oSearchText.val((sLetter ? '%' : '') + sLetter).keyup();
_this.setParam(oSearchAlhpabetType, 'isPrefix', sLetter ? 1 : 0);
_this.setParam(oSearchAlhpabetType, 'sText', sLetter);
_this.search(oSearchAlhpabetType);
oSearchText.val('');
e.preventDefault();
});
@ -79,7 +83,7 @@ ls.search = (function ($) {
oElement.on('keyup', function () {
_this.setParam(sType, 'sText', oElement.val());
_this.resetAlhpabet();
ls.timer.run(_this, _this.search, 'search_type_' + sType, [sType], 300);
});
});
@ -142,6 +146,19 @@ ls.search = (function ($) {
e.preventDefault();
});
// More loader
$('.js-more-search').livequery(function () {
$(this).more({
result: 'sText', // тут лучше на дефолтный sHtml заменить
beforeload: function (e, context) {
var sSearchType = context.element.data('search-type');
context.options.url = ls.search.options.type[sSearchType].url;
context.options.params = $.extend({}, context.options.params, ls.search.options.type[sSearchType].params);
}
});
});
};
/**
@ -163,6 +180,10 @@ ls.search = (function ($) {
}.bind(this));
};
this.resetAlhpabet = function() {
$(this.options.selectors.alphabet).eq(0).find(this.options.selectors.alphabet_item).removeClass(ls.options.classes.states.active).first().addClass(ls.options.classes.states.active);
}
/**
* Получает контейнер в который будут выводится результаты поиска
*

View file

@ -102,8 +102,10 @@ return array(
*/
'sort' => array(
'label' => 'Сортировать',
'by_login' => 'по логину',
'by_name' => 'по имени',
'by_date' => 'по дате',
'by_date_registration' => 'по дате регистрации',
'by_rating' => 'по рейтингу',
),

View file

@ -12,12 +12,15 @@
{* Сортировка *}
{include 'sort.ajax.tpl'
sSortName = 'sort-user-list'
aSortList = [ [ name => 'user_login', text => $aLang.sort.by_name ],
[ name => 'user_date_register', text => $aLang.user_date_registration ],
[ name => 'user_rating', text => $aLang.user_rating ] ]}
sSortName = 'sort-user-list'
aSortList = [
[ name => 'user_rating', text => $aLang.sort.by_rating, order => 'asc'],
[ name => 'user_login', text => $aLang.sort.by_login ],
[ name => 'user_date_register', text => $aLang.sort.by_date_registration ]
]
}
<div class="js-search-ajax-container" data-type="users">
{include file='user_list.tpl' aUsersList=$aUsers}
{include file='user_list.tpl' aUsersList=$aUsers bUseMore=true}
</div>
{/block}

View file

@ -9,19 +9,6 @@
{block name='block_title'}Поиск по пользователям{/block}
{block name='block_content'}
{$aSex = [
[ 'value' => 'man', 'text' => $aLang.settings_profile_sex_man ],
[ 'value' => 'woman', 'text' => $aLang.settings_profile_sex_woman ],
[ 'value' => 'other', 'text' => $aLang.settings_profile_sex_other ]
]}
{include file='forms/fields/form.field.select.tpl'
sFieldName = 'profile_sex'
sFieldLabel = $aLang.settings_profile_sex
aFieldItems = $aSex
sFieldClasses = 'width-full js-search-ajax-option'
sFieldInputAttributes = 'data-search-type="users"'}
{* Сейчас на сайте *}
{include file='forms/fields/form.field.checkbox.tpl'
sFieldName = 'is_online'
@ -32,7 +19,7 @@
{* Пол *}
<p class="mb-10">Пол</p>
{include 'forms/fields/form.field.radio.tpl' sFieldInputClasses='js-search-ajax-option' sFieldInputAttributes='data-search-type="users"' sFieldName='sex' sFieldValue='null' bFieldChecked=true sFieldLabel='Любой'}
{include 'forms/fields/form.field.radio.tpl' sFieldInputClasses='js-search-ajax-option' sFieldInputAttributes='data-search-type="users"' sFieldName='sex' sFieldValue='male' sFieldLabel='Мужской'}
{include 'forms/fields/form.field.radio.tpl' sFieldInputClasses='js-search-ajax-option' sFieldInputAttributes='data-search-type="users"' sFieldName='sex' sFieldValue='female' sFieldLabel='Женский'}
{include 'forms/fields/form.field.radio.tpl' sFieldInputClasses='js-search-ajax-option' sFieldInputAttributes='data-search-type="users"' sFieldName='sex' sFieldValue='' bFieldChecked=true sFieldLabel='Любой'}
{include 'forms/fields/form.field.radio.tpl' sFieldInputClasses='js-search-ajax-option' sFieldInputAttributes='data-search-type="users"' sFieldName='sex' sFieldValue='man' sFieldLabel='Мужской'}
{include 'forms/fields/form.field.radio.tpl' sFieldInputClasses='js-search-ajax-option' sFieldInputAttributes='data-search-type="users"' sFieldName='sex' sFieldValue='woman' sFieldLabel='Женский'}
{/block}

View file

@ -34,20 +34,6 @@
</div>
{/block}
{block name='search_input_after'}{/block}
{if $aPrefixes}
<div class="search-form-alphabet">
<ul>
<li class="active"><a href="#" class="link-dotted" data-letter="">{$aLang.user_search_filter_all}</a></li>
{foreach $aPrefixes as $sPrefixUser}
<li><a href="#" class="link-dotted" data-letter="{$sPrefixUser}">{$sPrefixUser}</a></li>
{/foreach}
</ul>
</div>
{/if}
{block name='search_end'}{/block}
</form>

View file

@ -13,8 +13,8 @@
<div class="more {$sLoadClasses}"
data-more-append="{$bLoadAppend|default:'true'}"
{if $iLoadLastId}data-param-i-last-id="{$iLoadLastId}"{/if}
data-param-i-target-id="{$iLoadTargetId|default:0}"
{if $sLoadTarget}data-more-target="{$sLoadTarget}"{/if}
{$sLoadAttributes}>
{$sLoadText|default:'Подгрузить еще'}

View file

@ -20,7 +20,7 @@
<ul class="dropdown-menu js-search-sort-menu" id="js-dropdown-sort-{$sSortName}">
{foreach $aSortList as $aSortItem}
<li class="sort-item {if $aSortItem@index == 0}active{/if}" data-search-type="users" data-name="sort_by" data-value="{$aSortItem['name']}" data-order="asc">
<li class="sort-item {if $aSortItem@index == 0}active{/if}" data-search-type="users" data-name="sort_by" data-value="{$aSortItem['name']}" data-order="{if $aSortItem['order']}{$aSortItem['order']}{else}desc{/if}">
<a href="#">
{$aSortItem['text']}
</a>

View file

@ -0,0 +1,34 @@
{foreach $aUsersList as $oUser}
{* TODO: Убрать костыль для блогов *}
{if $oUser->getUser()}{$oUser = $oUser->getUser()}{/if}
{$oSession = $oUser->getSession()}
{$oUserNote = $oUser->getUserNote()}
<li class="object-list-item">
{* Аватар *}
<a href="{$oUser->getUserWebPath()}">
<img src="{$oUser->getProfileAvatarPath(100)}" width="100" height="100" alt="{$oUser->getLogin()}" class="object-list-item-image" />
</a>
{* Заголовок *}
<h2 class="object-list-item-title">
<a href="{$oUser->getUserWebPath()}">{$oUser->getDisplayName()}</a>
</h2>
{* Заметка *}
{if $oUserNote}
{include 'user_note.tpl' oUserNote=$oUserNote iUserNoteId=$oUser->getId()}
{/if}
{* Информация *}
{$aUserInfo = [
[ 'label' => "{$aLang.user_date_last}:",
'content' => ($oSession) ? {date_format date=$oSession->getDateLast() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"} : '&mdash;' ],
[ 'label' => "{$aLang.user_date_registration}:", 'content' => {date_format date=$oUser->getDateRegister() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"} ],
[ 'label' => "{$aLang.vote.rating}:", 'content' => $oUser->getRating() ]
]}
{include 'info_list.tpl' aInfoList=$aUserInfo sInfoListClasses='object-list-item-info'}
</li>
{/foreach}

View file

@ -3,49 +3,28 @@
*}
{if $aUsersList}
{if $bIsSearch}
{if $iSearchCount}
<h3 class="h3">Найдено {$iSearchCount} человек</h3>
{/if}
{* Список пользователей *}
<ul class="object-list user-list">
{foreach $aUsersList as $oUser}
{* TODO: Убрать костыль для блогов *}
{if $oUser->getUser()}{$oUser = $oUser->getUser()}{/if}
{$oSession = $oUser->getSession()}
{$oUserNote = $oUser->getUserNote()}
<li class="object-list-item">
{* Аватар *}
<a href="{$oUser->getUserWebPath()}">
<img src="{$oUser->getProfileAvatarPath(100)}" width="100" height="100" alt="{$oUser->getLogin()}" class="object-list-item-image" />
</a>
{* Заголовок *}
<h2 class="object-list-item-title">
<a href="{$oUser->getUserWebPath()}">{$oUser->getDisplayName()}</a>
</h2>
{* Заметка *}
{if $oUserNote}
{include 'user_note.tpl' oUserNote=$oUserNote iUserNoteId=$oUser->getId()}
{/if}
{* Информация *}
{$aUserInfo = [
[ 'label' => "{$aLang.user_date_last}:",
'content' => ($oSession) ? {date_format date=$oSession->getDateLast() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"} : '&mdash;' ],
[ 'label' => "{$aLang.user_date_registration}:", 'content' => {date_format date=$oUser->getDateRegister() hours_back="12" minutes_back="60" now="60" day="day H:i" format="j F Y, H:i"} ],
[ 'label' => "{$aLang.vote.rating}:", 'content' => $oUser->getRating() ]
]}
{include 'info_list.tpl' aInfoList=$aUserInfo sInfoListClasses='object-list-item-info'}
</li>
{/foreach}
<ul class="object-list user-list js-more-users-container">
{include 'user_list.items.tpl' aUsersList=$aUsersList}
</ul>
{if $bUseMore}
{if !$bHideMore}
{include 'more.tpl'
sLoadClasses = 'js-more-search'
sLoadTarget = '.js-more-users-container'
sLoadAttributes = 'data-search-type="users" data-proxy-page-next="2" '}
{/if}
{else}
{include 'pagination.tpl' aPaging=$aPaging}
{/if}
{else}
{include 'alert.tpl' mAlerts=(($sUserListEmpty) ? $sUserListEmpty : $aLang.blog.alerts.empty) sAlertStyle='empty'}
{/if}
{include 'pagination.tpl' aPaging=$aPaging}

@ -1 +1 @@
Subproject commit 9fcc2814b0830dcd631173662f7b986d43c49450
Subproject commit bb1e9297a361f7cee3391029cb53cb6bac5ecba7