Silverstripe: отношение-член много-много-ноль, формирует внешний интерфейс

Неустранимая ошибка: вызов функции-члена Services () при нулевом значении

class MemberProfileViewer extends Page_Controller {

    // ...

    public function Servizi() {
        $source = null;
        if ($id = (int)$this->urlParams['ID']) {
            $member = Member::get()->byID($id);
            if ($member instanceof Member) {
                return $source = $member->Services()->map('Title','Title');
            }
        } 

        if (is_null($id)) {
            return $this->redirect('/');
        }

        if (is_null($source)) {
            return $this->httpError(404);
        } 

    }

    public function form() {

        $fields = new FieldList(
            CheckboxSetField::create(
                $name = "ServiceID",
                $title = "Select",
                $source = $this->Servizi()
            ),
        )

        $actions = FieldList::create(
                FormAction::create('form', 'Send')
                    ->setUseButtonTag(true)
                    ->addExtraClass('btn btn-primary')
        );

        $validator = new RequiredFields('ServiceID');

        $form = new Form($this, 'form', $fields, $actions, $validator);
        $form->setFormMethod('POST', true);
        return $form;
    }

    public function doform($data, $form) {
        $form->sessionMessage(
            "Thank you, you will be contacted as soon as possible by our consultant.", 'good'
        );

        $submission = new RequestForm();
        $form->saveInto($submission);
        $submission->write();

        return $this->redirectBack();

    }

}

всегда равно нулю
Я не знаю, как решить

Да, проблема решена!

class MemberProfileViewer extends Page_Controller {

    // ...

    public function currentPageID() {
        $id = 0;
        $request = $this->getRequest();
        if(is_numeric($request->requestVar('ID')))  {
            $id = $request->requestVar('ID');
        } elseif (is_numeric($request->param('ID'))) {
            $id = $request->param('ID');
        }

        $id = (int)$id;
        return $id;
    }

    public function Servizi() {
        $source = null;
        if ($id = $this->currentPageID()) {
            Session::set('ID', $id);
            return $source = Member::get()->byID($id)->Services()->map('Title','Title')->toArray();
        } elseif (is_null($source)) {
           return $source = Member::get()->byID(Session::get('ID'))->Services()->map('Title','Title')->toArray();
        } 

    }

    public function form() {

        $fields = new FieldList(
            CheckboxSetField::create(
                $name = "Service",
                $title = "Select",
                $source = $this->Servizi()
            ),
        )

        $actions = FieldList::create(
                FormAction::create('form', 'Send')
                    ->setUseButtonTag(true)
                    ->addExtraClass('btn btn-primary')
        );

        $validator = new RequiredFields('Service');

        $form = new Form($this, 'form', $fields, $actions, $validator);
        $form->setFormMethod('POST', true);

        $data = Session::get("FormData.{$form->getName()}.data");
        return $data ? $form->loadDataFrom($data) : $form;
    }

    public function doform($data, $form) {
        Session::set("FormData.{$form->getName()}.data", $data);

        $submission = new RequestForm();
        $form->saveInto($submission);
        $submission->write();

        $form->sessionMessage(
            "Thank you, you will be contacted as soon as possible by our consultant.", 'good'
        );

        Session::clear("FormData.{$form->getName()}.data");
        return $this->redirectBack();

    }

}

person Bitshop    schedule 02.10.2017    source источник
comment
Какое значение $this->urlParams['ID']? Вы должны добавить некоторую обработку ошибок на случай, если член не найден, прежде чем пытаться его использовать.   -  person scrowler    schedule 02.10.2017
comment
Тебе нужно кодировать более оборонительно, чувак, ты не можешь просто рассчитывать на постоянное получение экземпляра Member. Что делать, если нет участника с таким идентификатором? Что делать, если в массиве urlParams не задан идентификатор?   -  person Ben Dubuisson    schedule 02.10.2017


Ответы (2)


Вероятно, ваша проблема связана с этой строкой

$fields = new FieldList(
    CheckboxSetField::create(
        $name = "ServiceID",
        $title = "Select",
        $source = $this->Servizi() // <--
    ),
)

Ваш метод Servizi() зависит от некоторой маршрутизации (вы пытаетесь получить идентификатор участника из URL-адреса). Этот метод не всегда возвращает хорошую карту для вашего CheckboxSetField. Если у вас нет маршрута для вашего Servizi() метода, вы, вероятно, не захотите перенаправлять или возвращать ошибку http.

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

public function servizi($memberId = 0)
{
    $array = [];

    if(! $memberId && ! ($memberId = Member::currentUserID())) // check current logged in Member
        return $array;

    if(! $member = Member::get()->byID($memberId))
        return $array;

    return $member->Services()->map('Title','Title');
}

Приведенный выше код не тестировался.

person Fatal Error    schedule 04.10.2017
comment
Должно быть так, что отношения не принадлежат зарегистрированному пользователю. Получите идентификатор участника из URL-адреса или иным образом - person Bitshop; 04.10.2017
comment
Затем найдите способ указать MemberID в параметрах метода servizi. Вы не предоставляете достаточно информации, чтобы помочь вам в этом вопросе. Просто убедитесь, что метод возвращает массив или карту, а не объект ответа ... - person Fatal Error; 05.10.2017
comment
Мне нужен идентификатор страницы, чтобы автоматически отображать взаимосвязь параметров, доступных в форме, а не currentUserID. Я не знаю, как это сделать. Используя значения для отправки, $ this- ›get Request () -› param ('ID') возвращает null. Вставка числа - ›byId (1) работает, Как мне получить параметр идентификатора пользователя страницы формы. большое спасибо @FatalError - person Bitshop; 05.10.2017

Я бы сделал:

$source = null;
if ($id = $this->urlParams['ID']) {
    $member = Member::get()->byId($id);
    if ($member instanceof Member) {
        $source = $member->Services()->map('Title','Title');
    }
}

if (is_null($source)) {
    //don't show that field, show a LiteralField with an error maybe
} else {
    //show your field with $source
}
person Ben Dubuisson    schedule 02.10.2017
comment
Привет @BenDubuisson, Шаг вперед, спасибо! Но проверка сообщения Выберите значение из предоставленного списка. {value} не является допустимым вариантом. Я пробовал использовать ручной идентификатор, и он работает, потому что в динамическом нет? - person Bitshop; 03.10.2017
comment
извини, я не понимаю твой вопрос - person Ben Dubuisson; 03.10.2017
comment
Пример: byId (7) работает | byId ($ id) return Выберите значение из предоставленного списка. значение не является допустимым вариантом. - person Bitshop; 03.10.2017
comment
Извините, я не понимаю, о чем вы говорите. Откуда приходят эти сообщения ?? - person Ben Dubuisson; 03.10.2017