Symfony: сделать поле формы даты и времени действительно доступным только для чтения

Я пометил поле формы даты и времени как read_only. Поскольку этот шов не имеет никакого эффекта, я отменил шаблон ветки по умолчанию. Это прекрасно работает.

{% block datetime_widget %}
    {% if read_only %}
        {{ value.date.year }}-{{ value.date.month }}-{{ value.date.day }} {{ value.time.hour }}:{{ value.time.minute }}
    {% else %}
        {{ parent() }}
    {% endif %}
{% endblock %}

Это тип формы, который я использую:

/**
 * @ORM\Entity
 */
abstract class BusinessClass
{

    /**
     * @ORM\Column(type="datetime")
     * @var \DateTime
     */
    private $created;

    /**
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

}

А вот как поле datetime добавляется в конструктор форм:

$formBuilder->add('created', 'datetime', array('read_only' => true));

Тем не менее, symfony все еще пытается установить неизменное значение обратно в мой тип формы. Поскольку он доступен только для чтения, я реализовал только метод get, но не метод set. Вот почему я получаю это сообщение об ошибке:

InvalidPropertyException: Neither element "created" nor method "setCreated()" exists in class "Cinergy\ShopBundle\Tests\Functional\TestBundle\Entity\RecurringProduct"

    in /Users/ernst/Source/php/cinergy/shop/vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPath.php line 552
    at PropertyPath->writeProperty(object(RecurringProduct), 'created', null, false, null) in /Users/ernst/Source/php/cinergy/shop/vendor/symfony/symfony/src/Symfony/Component/Form/Util/PropertyPath.php line 318
    at PropertyPath->setValue(object(RecurringProduct), null) in /Users/ernst/Source/php/cinergy/shop/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php line 74
    at PropertyPathMapper->mapFormsToData(array('created' => object(Form), 'duration' => object(Form), 'id' => object(Form), 'name' => object(Form), 'price' => object(Form), 'sku' => object(Form), 'updated' => object(Form), '__entity' => object(Form), '__id' => object(Form)), object(RecurringProduct)) in /Users/ernst/Source/php/cinergy/shop/vendor/symfony/symfony/src/Symfony/Component/Form/Form.php line 569
    at Form->bind(object(Request)) in /Users/ernst/Source/php/cinergy/shop/src/Cinergy/DaylightBundle/Controller/BrowserController.php line 123
    at BrowserController->updateAction(object(Request))
    at call_user_func_array(array(object(BrowserController), 'updateAction'), array(object(Request))) in /Users/ernst/Source/php/cinergy/shop/src/Cinergy/CommonBundle/EventListener/TransactionWrapper.php line 34
    at TransactionWrapper->wrappedExecution(object(Request))
    at call_user_func_array(array(object(TransactionWrapper), 'wrappedExecution'), array(object(Request))) in /Users/ernst/Source/php/cinergy/shop/app/bootstrap.php.cache line 1426
    at HttpKernel->handleRaw(object(Request), '1') in /Users/ernst/Source/php/cinergy/shop/app/bootstrap.php.cache line 1390
    at HttpKernel->handle(object(Request), '1', true) in /Users/ernst/Source/php/cinergy/shop/app/bootstrap.php.cache line 1566
    at HttpKernel->handle(object(Request), '1', true) in /Users/ernst/Source/php/cinergy/shop/app/bootstrap.php.cache line 617
    at Kernel->handle(object(Request)) in /Users/ernst/Source/php/cinergy/shop/web/app_dev.php line 28

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

Любые идеи о том, как я могу запретить symfony устанавливать значение, если установлена ​​опция read_only?


person BetaRide    schedule 15.03.2013    source источник
comment
вы хотите установить mapped в false, если это просто для галочки. Если я правильно тебя понял. В противном случае опубликуйте некоторый код (больше, чем просто фрагмент ветки)   -  person Prisoner    schedule 15.03.2013
comment
Настройка, сопоставленная с false, делает многое, она также останавливает symfony от чтения значения.   -  person BetaRide    schedule 18.03.2013
comment
Добавлена ​​форма tyoe и обработка конструктора форм. Пожалуйста, обратите внимание, что то же самое отлично работает для текстовых полей.   -  person BetaRide    schedule 18.03.2013


Ответы (2)


Короткий ответ: используйте disabled вместо read_only.

Найдя соответствующую часть документации, я думаю, что рендеринг даты и времени для read_only неверен. Только установка read_only ничего не меняет. Согласно документам, он должен быть изменен как HTML только для чтения.

person BetaRide    schedule 18.03.2013

К сожалению, если отображаемое поле отключено, оно не сохраняется. Его значение становится нулевым, что, вероятно, не то, что ищет ОП. Альтернативное решение — сделать что-то вроде следующего в вашем шаблоне:

{% if household.dateAdded is not null %}{{ household.dateAdded|date('m/d/Y') }}
<input type="hidden" name="household[dateAdded]" value="{{ household.dateAdded|date('m/d/Y') }}">
{% endif %}

где домохозяйство — это имя формы, dateAdded — это имя сопоставленного поля.

person geoB    schedule 09.10.2013
comment
Это потенциально опасно, вы делаете поле доступным только для чтения, но на самом деле знающий пользователь может изменить значение скрытого поля, сохранить форму и, следовательно, изменить данные, которые вы не хотели. Вы никогда не должны принимать данные от пользователя, если вы не доверяете им в предоставлении этих данных. - person thelem; 03.10.2016
comment
@thelem Я соглашусь с тем, что знающий пользователь может изменить значение в скрытом поле. Приложение, в котором появляется ответ, находится за брандмауэром небольшой некоммерческой организации, пользователи которой недостаточно осведомлены в этом отношении. У вас есть альтернативное решение? - person geoB; 03.10.2016
comment
Из чтения документов я думаю, что disabled должен работать так, как вы этого хотите (как описано в другом ответе). Поле, имеющее значение в базе данных, помеченное как отключенное, не должно терять это значение при сохранении формы. Для моего варианта использования я в настоящее время передаю информацию в форму отдельно, поэтому форма никогда не обрабатывает это поле. - person thelem; 03.10.2016
comment
@thelem К сожалению, неверно, что отключенное поле формы будет сохранено для объекта. В этом можно убедиться, наблюдая за значением поля до и после отправки формы с отключенным полем (например, {{ form_row(form.housing, {'attr': {'disabled': 'disabled'}}) }}. При этом условии поле устанавливается равным нулю. Возможно, вы могли бы представить свой метод передачи информации в форму отдельно в виде отвечать? - person geoB; 03.10.2016
comment
@thelem Я опубликовал этот ответ некоторое время назад на мой аналогичный вопрос, который позволяет сохранять отключенные поля без риска скрытого поля. - person geoB; 04.10.2016