Zend Framework 3 Redirect с завода
У моего контроллера есть фабрика, которая дает ему форму
$formManager = $container->get('FormElementManager');
return new MyController(
$formManager->get(MyForm::class)
);
Моя форма имеет также Фабрику, которая предоставляет ей AuthenticationService
return new MyForm(
$container->get(AuthenticationService::class)
);
Таким образом, я могу проверить в форме, есть ли у пользователя личность. Но как я могу перенаправить его из формы? Прямо как в контроллере?
if(!$authService->hasIdentity()) {
return $this->redirect()->toRoute('myRoute);
}
Или как я могу перенаправить сфабрики (контроллера и / или формы)?
1 ответ
Возможным решением вашей проблемы может быть возможность использования build
метод с фабричным вызовом.
Вы не показали свои фабрики, поэтому я буду использовать некоторые стандартные примеры, которые объясняют решение.
Первый подход не вводит всю форму в контроллер. Вместо этого просто введите менеджер элементов формы. Таким образом, вы можете использовать метод сборки фабрики внутри вашего контроллера.
Контроллер фабрики
namespace Application\Controller\Factory;
use Application\Controller\YourController;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class YourControllerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$formElementManager = $container->get('FormElementManager');
return new YourController($formElementManager);
}
}
Это отличается от вашей оригинальной фабрики. Только диспетчер элементов формы вводится в контроллер. Это имеет несколько преимуществ для вас. Одним из них является метод сборки менеджера.
Контроллер
namespace Application\Controller;
class YourController extends AbstractActionController
{
protected $formElementManager;
public function __construct($formElementManager)
{
$this->formElementManager = $formElementManager;
}
public function indexAction()
{
$user = $this->currentUser();
if ($user === null) {
$this->redirect('to/somewhere/the/user/belongs');
}
// here 's the magic!
$form = $this->formElementManager->build(YourForm::class, [
'userID' => $user->getUserId(),
]);
// some form stuff follows here
}
}
Поскольку форма была введена не непосредственно в ваш контроллер, а в диспетчер элементов формы, вы можете использовать диспетчер элементов формы внутри контроллера. Это дает вам возможность использовать функцию сборки. С помощью этой функции вы можете добавить некоторые параметры к вашей фабрике форм. В этом случае я использую идентификатор пользователя для фабрики форм.
Если нет действительного пользователя, форма не будет создана, потому что раньше было сгенерировано исключение.
Фабрика форм
Фабрика форм создает новый экземпляр вашей формы. Все необходимые зависимости должны быть созданы на заводе. Как работает функция сборки, я объясню позже в ответе.
namespace Application\Form\Factory;
use Application\Form\YourForm;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class YourFormFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$selectOptions = [];
if ($options !== null) {
if (isset($options['userID])) {
$tablegateway = $container->get(YourTableGateway::class);
$selectOptions = $tablegateway->findOptionsByUserId($options['userID]);
}
}
$form = $container->get(YourForm::class);
if (count($selectOptions))
$form->get('YourSelectElement')->setValueOptions($selectOptions);
return $form;
}
}
Этот завод делает все, что вам нужно. С помощью метода сборки вы передаете идентификатор пользователя. Если идентификатор пользователя присутствует, то создается шлюз таблицы, из которого вы получаете опции выбора по заданному идентификатору пользователя. Эти параметры будут установлены в поле формы. Эта логика сохраняется на фабрике, чтобы сохранить класс формы простым и понятным.
С этим решением вам не понадобится служба авторизации в вашей форме. Ваша форма генерируется только тогда, когда указан действительный идентификатор пользователя. Экземпляр формы не будет аварийно завершать работу, если не указан идентификатор пользователя. Единственным возможным вариантом может быть форма с параметрами по умолчанию или без параметров выбора для определенного поля.
Надеюсь это немного поможет.