Для изменения и дополнения классов используется наследование, однако здесь его применить не удается. Если я создам наследника какого-то класса, то остальные классы системы об этом не узнают, и будут продолжать использовать оригинальный класс. Проблемы можно избежать, если методы будут манипулировать не конкретными классами, а интерфейсами, а объекты будут создаваться не по месту использования с указанием конкретного класса, а при помощи некого настраиваемого программного механизма, и можно будет указать, какой класс для реализации какого интерфейса использовать.
По ссылкам более детально о том, что я имею в виду:
https://ru.wikipedia.org/wiki/%D0%98%D0 … 0%B8%D1%8F
https://habrahabr.ru/post/132084/

Задача: добавить в фильтр товаров в категории фильтрацию по наличию скидки.

Сначала нужно добавить настройку - выводить ли этот фильтр.
В классе Catalog\Controller\Block\SideFilters в методе getParamObject задаются настройки. В массив с настройками нужно добавить еще один элемент:

'show_is_discount' => new Type\Integer(array(
    'description' => t('Отображать фильтр по наличию скидки'),
    'checkboxView' => array(1,0)
)),

Теперь в filters.tpl можно написать:

{if $param.show_is_discount}
    <div class="filter">
        <h4>{t}Скидка{/t}:</h4>
        <select class="yesno" name="bfilter[isdiscount]" data-start-value="">
             <option value="">{t}Неважно{/t}</option>
             <option value="1" {if $basefilters.isdiscount == '1'}selected{/if}>{t}Есть{/t}</option>
             <option value="0" {if $basefilters.isdiscount == '0'}selected{/if}>{t}Нет{/t}</option>
        </select>
    </div>
{/if}

Осталось добавить в класс Catalog\Model\Api метод isDiscountFilter, где добавлять условия на выборку товаров со скидкой.

protected function isDiscountFilter($filter)
{
    $old_cost_id = \Catalog\Model\CostApi::getOldCostId();
    if ($old_cost_id) {
        $q = $this->queryObj();
        $q->leftjoin(new Xcost(), "A.id = XCO.product_id AND XCO.cost_id='{$old_cost_id}'", 'XCO');
        if ($filter) {
            $q->where('XCO.cost_val>0');
        } else {
            $q->where('XCO.cost_val=0');
        }
    }
}

Правильно ли я понимаю, что на данный момент единственный способ решить эту задачу - это подмена оригинальных классов с потерей возможности их обновления?

3

(1 ответов, оставленных в Сайт ReadyScript)

В статье http://readyscript.ru/text-blog/Kak-pra … adyScript/ ошибка.
В файле module.xml должен быть тег defaultValues, а не defaultvalues, иначе при установке модуля выдается ошибка, что не заданы название, описание и другие значения, задаваемые в этой секции (кстати, лучше бы в таком случае выдавать сообщение, что секция defaultValues не найдена, а то сложно понять причину ошибки).

Хотел оставить этот комментарий прямо к статье, но виджет контакта в моем Firefox почему-то бесконечно открывает всплывающее окно с авторизацией, и сразу его закрывает, а в Edge авторизоваться удалось, но комментарий так и не отправился. И еще мне совершенно не нравится идея размещать вашу рекламу на своей странице при таком комментировании. Может, вы лучше сделаете комментарии непосредственно на своем сайте для зарегистрированных пользователей?