Как вывести фотографии из нескольких альбомов с возможностью сортировки по дате создания
Актуально для версии 2.9.5
Задача
Если Вы столкнулись с данной задачей, то решить её стандартными средствами нельзя. Необходимо написать кастомный макрос, пример оного дан ниже.
Решение
%photoalbum getMultiAlbums()% - выводит фотографии из указанных альбомов
Параметры: photoalbum getMultiAlbums([$template = 'default', $albums_ids, $i_need_sort = false, $i_need_deep = 1, $per_page = 10, $ignore_paging = false])
$template
Принимает имя шаблона, по которому выводится результат макроса. В XSLT-шаблонизаторе не используется. По-умолчанию равен 'default', шаблон необходимо поместить в директорию /tpls/photalbum/.
$albums_ids
Принимает id фотоальбома, из которого нужно вывести фотографии. Можно указать несколько идентификаторов через точку с запятой. Если параметр не указан, то берется id текущей страницы, макрос нельзя вызывать через HTTP SCHEME MODE без указания этого параметра.
$i_need_sort
Включает сортировку по дате создания фотографии (create_time). Если сортировка включена, то в результат попадут только фотографии с заполненным полем. По-умолчанию сортировка отключена.
$i_need_deep
Глубина поиска объектов списка (во вложенных подразделах). По умолчанию — только в текущем разделе.
$per_page
Принимает число, которое обозначает максимальное количество выводимых фотографий на страницу. По-умолчанию равен 10.
$ignore_paging
Включает игнорирование постраничной навигации, то есть параметра 'p'. По-умолчанию отключен.
Для применения этого макроса скопируйте содержимое листинга макроса в файл /classes/modules/photoalbum/__custom.php.
Листинг макроса
public function getMultiAlbums($template = 'default', $albums_ids, $i_need_sort = false, $i_need_deep = 1, $per_page = 10, $ignore_paging = false){
if(intval($i_need_deep) == 0){
$i_need_deep = 1;
}
$page_num = (int) getRequest('p');
list($items_template, $item_template, $empty) = def_module::loadTemplates('photalbum/'.$template, 'items', 'item', 'empty');
$current_page_id = cmsController::getInstance()->getCurrentElementId();
$hierarchy = umiHierarchy::getInstance();
if($albums_ids == false){
if($current_page_id == false && defined('VIA_HTTP_SCHEME')){
throw new publicException('cant get current element via HTTP SCHEME MODE');
}
$albums_ids = $current_page_id;
}
$albums_ids = explode(';', $albums_ids);
$pages = new selector('pages');
$pages->types('hierarchy-type')->name('photoalbum', 'photo');
foreach($albums_ids as $album_id){
if($hierarchy->getElement($album_id) !== false){
$pages->where('hierarchy')->page($album_id)->childs(intval($i_need_deep));
}
}
if($i_need_sort != false){
$pages->where('create_time')->isnotnull();
}
$total = $pages->length();
if($total == 0){
return def_module::parseTemplate($empty);
}
$photo_pages = $pages->result();
if($i_need_sort != false){
usort($photo_pages, function($a, $b){
$a_publishTime = $a->getValue('create_time');
$b_publishTime = $b->getValue('create_time');
if ($a_publishTime == $b_publishTime) {
return 0;
}
return ($a_publishTime > $b_publishTime) ? -1 : 1;
});
}
if($ignore_paging == false){
$offset = $page_num * intval($per_page);
$photo_pages = array_slice($photo_pages, $offset, intval($per_page));
}
$item = array();
$items = array();
foreach($photo_pages as $photo_page){
$item['attribute:id'] = $photo_page->id;
$item['attribute:link'] = $photo_page->link;
$item['attribute:name'] = $photo_page->getName();
$item['attribute:create_time'] = $photo_page->getValue('create_time');
$items[] = def_module::parseTemplate($item_template, $item);
}
$items = array('subnodes:items' => $items);
$items['total'] = $total;
$items['page_number'] = $page_num;
$items['per_page'] = $per_page;
return def_module::parseTemplate($items_template, $items);
}
Также, не забудь создать по пути /classes/modules/photoalbum/ файл permissions.custom.php со следующим содержанием:
<?php
$permissions = array(
'albums' => array('getMultiAlbums'),
);
?>
Дополнительно
Как Вы могли заметить, у фотографий есть поле дата создания (create_time), но оно везде не заполнено. Чтобы исправить данный факт, необходимо написать обработчик для события systemCreateElement, в котором записывать в это поле текущую дату. Пример обработчика дан ниже.
Пример обработчика события
Для применения обработчика, в первую очередь по пути /classes/modules/photoalbum/ создайте файл custom_events.php следующего содержания:
<?php
new umiEventListener('systemCreateElement', 'photoalbum', 'onCreatePhotoAdmin');
?>
Потом добавьте в файл /classes/modules/photoalbum/__custom.php код обработчика:
public function onCreatePhotoAdmin(iUmiEventPoint $event){
if($event->getMode() === "after") {
$page = $event->getRef("element");
$page_type = $page->getHierarchyType();
if ($page_type->getName() == 'photoalbum' && $page_type->getExt() == 'photo'){
$page->setValue('create_time', time());
$page->commit();
}
}
}
И, наконец, добавьте метод onCreatePhotoAdmin в /classes/modules/photoalbum/permissions.custom.php, после этого он примет вид:
<?php
$permissions = array(
'albums' => array('onCreatePhotoAdmin', 'getMultiAlbums'),
);
?>