- PVSM.RU - https://www.pvsm.ru -
В первой части [1] статьи мы создали кнопку в строке List View писем, которая переводит нас на форму создания ответа. Однако остались нерешенными по крайней мере два важных вопроса:
Существует как минимум три способа автоматической привязки ответа к письму на уровне SonataAdminBundle:
1) После создания формы перед сохранением сущности ответа в базу (для этого можно использовать метод prePersist объекта Admin). Главной особенностью этого способа является «непрозрачность» прикрепления одной сущности к другой для пользователя, работающего с формой, что может служить как достоинством, так и недостатком в зависимости от поставленных целей.
2) Во время создания формы путем настройки значения необходимого поля с помощью formBuilder. Этот подход может привести к нежелательному загромождению админ-класса кодом, реализующим логику формирования значения поля по умолчанию.
3) До создания формы. Для этого можно воспользоваться подходом, предлагаемым, например в [1] [2], который заключается в переопределении родительского метода getNewInstance Admin-класса. Альтернативой такому решению может являться наследование от CRUD-контроллера (процесс наследования подробно описан в [2] [2]) и определение в нем операции-зацепки [3] [2] preCreate. Одним из преимуществ такой альтернативы является «штатная» возможность возвратить полноценный объект SymfonyComponentHttpFoundationResponse() в случае, если это необходимо.
Какой из способов использовать, зависит от решаемой задачи, мы же рассмотрим третий с использованием наследования от CRUD-контроллера, поскольку, на наш взгляд, он является наименее очевидным с точки зрения реализации и наиболее гибким с точки зрения архитектуры.
В первую очередь, добавим третий аргумент в функцию admin.getRouteGenerator.generateUrl(). Это должен быть массив параметров запроса и мы добавим в него идентификатор письма, из строки которого создаем ответ. Для этого воспользуемся функцией admin.getUrlsafeIdentifier()
{# src/AppBundle/Resources/views/CRUD/list__action_create_other_admin.html.twig #}
<a href="{{ admin.getRouteGenerator.generateUrl(template_variables.otherAdmin, 'create', {'incoming_id': admin.getUrlsafeIdentifier(object)}) }}" class="btn btn-sm btn-default edit_link" title="Создать ответ">
<i class="fa fa-plus"></i>
Создать ответ
</a>
Таким образом, переход по ссылке позволит обратиться к createAction CRUD-контроллера, передав в качестве параметра запроса incoming_id идентификатор нужного нам письма. Теперь задача сводится к получению объекта письма по идентификатору и прикреплению к нему ответа. Мы ее будем решать путем определения пустого по умолчанию метода preCreate, который может возвращать объект SymfonyComponentHttpFoundationResponse() или не возвращать ничего, просто модифицируя $object.
namespace ApplicationSonataAdminBundleController;
use AppBundleEntityResponse;
use SonataAdminBundleControllerCRUDController as BaseController;
use SymfonyComponentHttpFoundationRequest;
class CRUDController extends BaseController
{
public function preCreate(Request $request, $object)
{
// Здесь Response - сущность нашего ответа, а не объект SymfonyComponentHttpFoundationResponse()
if ($object instanceof Response) {
// Если передан идентификатор письма
if ($incomingId = $request->get('incoming_id')) {
// Если по идентификатору получен объект письма
if($incoming = $this->getDoctrine()->getRepository('AppBundle:Incoming')->find($incomingId)) {
// Прикрепление письма к ответу
$object->setIncoming($incoming);
// Или ответа к письму, оба варианта ПРИКРЕПЛЕНИЯ равнозначны
$incoming->setResponse($object);
}
}
}
}
}
Главная задача, поставленная в начале статьи, а именно: создание сущности ответа из ListView писем — решена. Рассмотрим вопрос проверки прав пользователя на создание ответа.
Непосредственно вопрос установки прав пользователя на создание ответа лежит вне темы данной статьи и может быть решен на основе подробной информации, изложенной в [4] [2]. Мы же рассмотрим вопрос отображения или скрытия кнопки «Добавить ответ» в ListView ПИСЕМ в зависимости от наличия или отсутствия у пользователя прав на создание ОТВЕТА. Для этого нам снова придется внести изменения в файл list__action_create_other_admin.html.twig
{# src/AppBundle/Resources/views/CRUD/list__action_create_other_admin.html.twig #}
{% if template_variables.otherAdmin.securityHandler.isGranted(template_variables.otherAdmin, 'CREATE', template_variables.otherAdmin) and template_variables.otherAdmin.hasRoute('create') %}
<a href="{{ admin.getRouteGenerator.generateUrl(template_variables.otherAdmin, 'create', {'incoming_id': admin.getUrlsafeIdentifier(object)}) }}" class="btn btn-sm btn-default edit_link" title="Создать ответ">
<i class="fa fa-plus"></i>
Создать ответ
</a>
{% endif %}
При этом мы проверяем возможность создания ответа не только на уровне системы безопасности, но и на уровне системы роутинга.
В статье изложен вариант решения задачи по созданию в SonataAdminBundle некоторой сущности из ListView второй сущности, связанной с первой, с учетом наличия или отсутствия у пользователя соответствующих прав.
Автор: Good-cat
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/php-2/117445
Ссылки в тексте:
[1] первой части: https://habrahabr.ru/post/278987/
[2] [1]: #sources
[3] Populate resp. set default values on form resp. object or instance in SonataAdminBundle: http://blog.webdevilopers.net/populate-resp-set-default-values-on-form-resp-object-or-instance-in-sonataadminbundle/
[4] CREATING A CUSTOM ADMIN ACTION: https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_custom_action.html
[5] Операции-зацепки: http://www.codelab.ru/task/221#hooks
[6] Security: https://sonata-project.org/bundles/admin/master/doc/reference/security.html
[7] Источник: https://habrahabr.ru/post/279203/
Нажмите здесь для печати.