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 选项的表单。

希望对您有所帮助。