mfilter2 - вывод значений фильтра в алфавитном порядке, с группировкой по первой букве

Добрый день, давно не писал ничего, вот делюсь рабочим вариантом группировки значений фильтра по первой букве.
Как это должно выглядеть:


Внешний вид оставим верстальщикам, перейдем к формированию фильтра.
Согласно документации расширяем фильтр.

1) Создаем файл myfilters.class.php в папке core/components/msearch2/custom/filters/myfilters.class.php

2) Вписываем туда следующий код

<?php

class myFilter extends mse2FiltersHandler {

    public function buildAlphabetFilter(array $values, $name = '') {
	if (count($values) < 2 && empty($this->config['showEmptyFilters'])) {
		return array();
	}

        $results = array();
        $this->alphabetsorting($values);    

	foreach ($values as $letter => $value) { 

            $results[$letter] = array(
                'title' => $letter,
                'value' => ''
            );

            foreach($value as $key => $ids) {
                if ($key !== '') {
                    $results[$key] = array(
                        'title' => $key,
                        'value' => $key,
                        'type' => 'default',
                        'resources' => $ids
                    );
                }
            }
        }       

	return $this->sortFilters($results, 'default', array('name' => $name));
    }
    


    public function alphabetsorting( & $array ) { 
        $memory = NULL;
        ksort( $array );        
        $sorting = array();
        
        // Обходим массив
        foreach( $array as $item => $value)  {
            # Получаем первую букву
            $letter = mb_substr( $item, 0, 1, 'utf-8' );
            
            // Если текущая буква не равна предыдущей
            if( $letter != $memory ) { 
                $memory = $letter; 
                $sorting[$memory] = array();
            }            
            // Дополняем массив
            $sorting[$memory][$item] = $value;
        }
         
        $array = $sorting;
    } 
}

3) Вписываем наш класс в системные настройки
mse2_filters_handler_class = myFilter

По итогу в чанке для row вы получите разделение на группы, достаточно будет сделать проверку
{if $value}
  // тут вот чанк обычный с чекбоксами (взято из родных чанков, перепишите на феном)
<label for="mse2_[[+table]][[+delimeter]][[+filter]]_[[+idx]]" class="[[+disabled]]">
	<input type="checkbox" name="[[+filter_key]]" id="mse2_[[+table]][[+delimeter]][[+filter]]_[[+idx]]" value="[[+value]]" [[+checked]] [[+disabled]]/> [[+title]] <sup>[[+num]]</sup>
</label>
{else}
// а тут вот вывод буквы
<div class="letter">{$title}</div>
{/if}

4) В вызове фильтра указывать так:
'filters' => 'tv|brands:alphabet',

Может где-то есть решение и получше, ищите
Евгений Webinmd
26 января 2021, 00:17
modx.pro
13
410
+27

Комментарии: 1

Иван Бочкарев
26 января 2021, 21:46
0
Молодец, дядь Жень.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    1