Вызов класса через __invoke() и можно ли сделать лучше?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Вызов класса через __invoke() и можно ли сделать лучше?

Сообщение andku83 »

При помощи $model->getListAsTree() получается многоуровневое дерево категорий, вида:

Код: Выделить всё

[
    [1] => [
        'id' => 1,
        'name' => 'Категория1',
        'children' => [
            [2] => [
                'id' => 2,
                'name' => 'Подкатегория2',
                'children' => [
                    [3] => [
                        'id' => 3,
                        'name' => 'Подподкатегория3'.
                        'children' => [
                            ...
                        ]
                    ]
                ]
            ]
        ]
    ]
] 
Как правильно вызывать такой хелпер для построения древовидного радиоЛиста?
Или может есть какие-то более удобные инструменты для этих целей?

Код: Выделить всё

<?php
namespace yii\helpers;

use common\models\query\CategoryQuery;
use Yii;

/**
 * Class RadioTreeBuilder
 *
 * @package yii\helpers
 */
class RadioTreeBuilder
{
    /**
     * @var
     */
    private $_id;

    /**
     * @var
     */
    private $_parent_id;

    /**
     * @param $model
     * @param int $exception_id
     * @return string
     */
    public function __invoke($model, $exception_id = 0)
    {
        /* @var $model CategoryQuery */
        $model = new $model();
        if ((int)$exception_id !== 0) {
            $entity = $model->one((int)$exception_id);
            if ($entity !== false) {
                $this->_id = $entity->id;
                $this->_parent_id = $entity->parent_id;
            }
        }
        return $this->render($model->getListAsTree(0, $exception_id));
    }

    /**
     * @param array $rowset
     * @return string
     */
    protected function render(array $rowset)
    {
        $tree
            = '<ul class="admin-form-radio-tree"><li>' .
            '<label><input type="radio" value="0" name="pid" checked="checked"/>'.Yii::t('common', 'Catalog').'</label>' .
            '</li>';
        $tree .= $this->combine($rowset);
        $tree .= '</ul>';
        return $tree;
    }

    /**
     * @param array $rowset
     *
     * @return string
     */
    protected function combine(array $rowset = array())
    {
        $list = '';
        if (!empty($rowset)) {
            foreach ($rowset as $item) {
//                if ($this->_id != $item['id']) {
                    $checked = $this->_parent_id == $item['id'] ? ' checked' : '';
                    $list.= '<li><label><input type="radio" value="' . $item['id'] . '" name="parent_id"' . $checked . '/>' . $item['name'] .'</label>';
                    if (!empty($item['children'])) {
                        $list .= '<ul>';
                        $list .= $this->combine($item['children']);
                        $list .= '</ul>';
                    }
                    $list .= '</li>';
//                }
            }
        }
        return $list;
    }
} 
При вот таком вызове:

Код: Выделить всё

<?= \yii\helpers\RadioTreeBuilder::getRadioTree('Category', $model->id); ?>
выдает ошибку:

Код: Выделить всё

Class 'yii\helper\RadioTreeBuilder' not found
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Вызов класса через __invoke() и можно ли сделать лучше?

Сообщение ElisDN »

Положите в папку common/helpers и поменяйте namespace на common\helpers.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Вызов класса через __invoke() и можно ли сделать лучше?

Сообщение andku83 »

В этой папке он и лежал, в предыдущем посте неправильно написал вызов (пытался сделать статическим метод), теперь:

Код: Выделить всё

<?= \common\helpers\RadioTreeBuilder('Category', $model->id); ?>
Смена неймспейса не помогла, ошибка:

Код: Выделить всё

Call to undefined function common\helpers\RadioTreeBuilder() 
Restlin
Сообщения: 139
Зарегистрирован: 2011.09.09, 18:12

Re: Вызов класса через __invoke() и можно ли сделать лучше?

Сообщение Restlin »

shnir писал(а):В этой папке он и лежал, в предыдущем посте неправильно написал вызов (пытался сделать статическим метод), теперь:

Код: Выделить всё

<?= \common\helpers\RadioTreeBuilder('Category', $model->id); ?>
Смена неймспейса не помогла, ошибка:

Код: Выделить всё

Call to undefined function common\helpers\RadioTreeBuilder() 
Вы обращаетесь к классу как к функции. Забыли вызов статического метода указать
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Вызов класса через __invoke() и можно ли сделать лучше?

Сообщение zelenin »

invoke не так работает.
Надо так:
$builder = new RadioTreeBuilder(...);
$builder();
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Вызов класса через __invoke() и можно ли сделать лучше?

Сообщение andku83 »

zelenin писал(а):$builder = new RadioTreeBuilder(...);
$builder();
Спасибо, так и решил.
Ответить