我是Zend Framework 2的新手。我正在开始一个项目,我希望由ZfcAdmin,ZfcUser,ZfcUserAdmin和BjyAuthorize管理其安全性。我要做的第一件事是修改创建用户的流程。我希望能够在创建新用户后立即为新用户分配角色。

我面临的第一个问题是创建用户时,控制器将我重定向到用户的列表页面。我需要更改此行为,我想重定向到编辑页面,在这里我可以为最近创建的用户选择N个角色(这将与实体发生另一场战争...)。我选择覆盖UserAdminController(ZfcUserAdmin)。这就是我为实现这一目标所做的:

1.我将管理模块(MyAdministration)加载到application.config.php的最后一个位置,
为了能够覆盖其他模块的属性。

2.为了使用我的,我在MyAdministration / config / module.config.php中覆盖了ZfcUserAdmin控制器:

(...)
'controllers' => array(
    'invokables' => array(
        'zfcuseradmin' => 'MyAdministration\Controller\MyAdministrationController',
    ),
),
(...)


3.我创建了课程
MyAdministration / src / MyAdministration / Controller / MyAdministrationController.php

4.我已经声明要扩展ZfcUserAdmin一个

namespace Administracion\Controller;
(...)
use ZfcUserAdmin\Controller\UserAdminController;

class AdministracionController extends UserAdminController {
(...)


5.我重写了createAction函数来重定向到编辑页面

(...)
public function createAction() {
(...)
return $this->redirect()->toRoute('zfcadmin/zfcuseradmin/edit/:userId',
    array('userId' => $user->getId()));
}
(...)


那是我不知道我做对的地方。
搜索网络并进行调试,我了解到有一个名为InjectTemplateListener的类,该类将Controller的名称空间转换为所需模板的路径。我的控制器已“翻译”为
my-administration / my-administration / edit导致无效,这些模板属于ZfcUserAdmin模块。正确的路径是其控制器(ZfcUserAdmin \ Controller \ UserAdminController)获得的路径:
zfc-user-admin / user-admin / edit

我还了解到可以手动编写模板路径。这些路径被忽略
InjectTemplateListener。这就是我使用的方法。在
我写的MyAdministration / config / module.config.php:

(...)
'view_manager' => array(
    'template_map' => array(
        'my-administration/my-administration/list' => __DIR__ . '/../../../vendor/ZfcUserAdmin/view/zfc-user-admin/user-admin/list.phtml',
        'my-administration/my-administration/create' => __DIR__ . '/../../../vendor/ZfcUserAdmin/view/zfc-user-admin/user-admin/create.phtml',
        'my-administration/my-administration/edit' => __DIR__ . '/../../../vendor/ZfcUserAdmin/view/zfc-user-admin/user-admin/edit.phtml',
        'my-administration/my-administration/pagination_userlist' => __DIR__ . '/../../../vendor/ZfcUserAdmin/view/zfc-user-admin/user-admin/pagination_userlist.phtml',
    ),
    (...)
),


我不确定这是否是实现该目标的最佳方法。我觉得必须有更好的方法来做到这一点,而不是手动编写模板路径。我发现了有关覆盖的几件事
控制器,没有例子...可以吗?有谁有更好的方法来进行覆盖?

谢谢!

最佳答案

您是正确的,模板名称可以由侦听器注入。这是在一种情况下:如果未设置模板名称。

因此,对于此操作,注入模板侦听器注入模板名称:

namespace MyModule;

class MyController
{
  public function myAction()
  {
    return new ViewModel;
  }
}


模板将为my-module/my-controller/my-action。但是,如果您设置模板,则将跳过侦听器:

namespace MyModule;

class MyController
{
  public function myAction()
  {
    $view = new ViewModel;
    $view->setTemplate('another-module/my-controller/my-action');

    return $view;
  }
}


您可以在控制器中看到您正在覆盖returned data with the form is a simple array and not even a view model。重定向插件返回一个Response对象。

因此,您检查返回值是否为数组,如果是,则显式设置模板。这将跳过侦听器以注入模板名称:

namespace MyAdminModule;

use ZfcUserAdmin\Controller\UserAdminController as BaseUserAdminController;

use Zend\View\Model\ViewModel;
use Zend\Http\Response;

class UserAdminController extends BaseUserAdminController
{
    public function createAction()
    {
        $result = parent::createAction();

        if ($result instanceof Response) {
            // Old behaviour
            return $this->redirect()->toRoute('zfcadmin/zfcuseradmin/edit/:userId',
                                              array('userId' => $user->getId()));
        }

        // $result is array
        $view = new ViewModel;
        $view->setVariables($result);
        $view->setTemplate('zfc-user-admin/user-admin/create');

        return $view;
    }
}


由于您现在直接设置模板名称,因此可以在配置中跳过对模板映射的操作。这也提高了灵活性,因为您使用模块外部的路径对模板路径进行了硬编码。您现在还可以选择覆盖另一个模块中的zfcUserAdmin模板映射。

09-12 23:19