Zend Framework 3 从工厂重定向
Zend Framework 3 Redirect from factory
我的 Controller 有一个 Factory 给它一个 Form
$formManager = $container->get('FormElementManager');
return new MyController(
$formManager->get(MyForm::class)
);
我的 Form 也有一个 Factory 给它一个 AuthenticationService
return new MyForm(
$container->get(AuthenticationService::class)
);
这样我就可以在表单中检查用户是否有身份。
但是我怎样才能将他从表单中重定向呢?
就像在控制器中一样?
if(!$authService->hasIdentity()) {
return $this->redirect()->toRoute('myRoute);
}
或者我如何从 (Controller and/or Form) Factory[=30 重定向=]?
您的问题的一个可能解决方案是在工厂调用中使用 build
方法。
你没有展示你的工厂,所以我将使用一些标准示例来解释解决方案。
第一种方法不是将整个表单注入控制器。相反,只需注入表单元素管理器。所以你可以在你的controller里面使用factory的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
}
}
由于表单不是直接注入到您的控制器而是注入到表单元素管理器,因此您可以在控制器内部使用表单元素管理器。这为您提供了使用构建功能的机会。使用此功能,您可以向表单工厂添加一些选项。在这种情况下,我使用表单工厂的用户 ID。
如果没有有效用户,则不会创建表单,因为之前会抛出异常。
模具厂
表单工厂创建了一个新的表单实例。所有需要的依赖项都应该在工厂中创建。这里build函数是如何工作的,我会在后面的回答中解释。
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;
}
}
这家工厂可以满足您的所有需求。通过构建方法,您交出用户 ID。如果存在用户 ID,则会创建一个 table 网关,您可以通过给定的用户 ID 检索 select 选项。这些选项将被设置到表单域。此逻辑保留在工厂中以保持表单 class 本身干净简单。
使用此解决方案,您不需要表单中的身份验证服务。您的表单仅在提供有效用户 ID 时生成。如果没有给定用户 ID,您的表单实例将不会崩溃。唯一可以想到的情况可能是特定字段具有默认选项或没有 select 选项的表单。
希望对您有所帮助。
我的 Controller 有一个 Factory 给它一个 Form
$formManager = $container->get('FormElementManager');
return new MyController(
$formManager->get(MyForm::class)
);
我的 Form 也有一个 Factory 给它一个 AuthenticationService
return new MyForm(
$container->get(AuthenticationService::class)
);
这样我就可以在表单中检查用户是否有身份。 但是我怎样才能将他从表单中重定向呢? 就像在控制器中一样?
if(!$authService->hasIdentity()) {
return $this->redirect()->toRoute('myRoute);
}
或者我如何从 (Controller and/or Form) Factory[=30 重定向=]?
您的问题的一个可能解决方案是在工厂调用中使用 build
方法。
你没有展示你的工厂,所以我将使用一些标准示例来解释解决方案。
第一种方法不是将整个表单注入控制器。相反,只需注入表单元素管理器。所以你可以在你的controller里面使用factory的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
}
}
由于表单不是直接注入到您的控制器而是注入到表单元素管理器,因此您可以在控制器内部使用表单元素管理器。这为您提供了使用构建功能的机会。使用此功能,您可以向表单工厂添加一些选项。在这种情况下,我使用表单工厂的用户 ID。
如果没有有效用户,则不会创建表单,因为之前会抛出异常。
模具厂
表单工厂创建了一个新的表单实例。所有需要的依赖项都应该在工厂中创建。这里build函数是如何工作的,我会在后面的回答中解释。
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;
}
}
这家工厂可以满足您的所有需求。通过构建方法,您交出用户 ID。如果存在用户 ID,则会创建一个 table 网关,您可以通过给定的用户 ID 检索 select 选项。这些选项将被设置到表单域。此逻辑保留在工厂中以保持表单 class 本身干净简单。
使用此解决方案,您不需要表单中的身份验证服务。您的表单仅在提供有效用户 ID 时生成。如果没有给定用户 ID,您的表单实例将不会崩溃。唯一可以想到的情况可能是特定字段具有默认选项或没有 select 选项的表单。
希望对您有所帮助。