Zend framework2 ZF2中的控制器重写

Zend framework2 ZF2中的控制器重写,zend-framework2,Zend Framework2,我是Zend Framework 2的新手。我正在启动一个项目,我希望它的安全性由ZfcAdmin、ZfcUser、ZfcUserAdmin和BjyAuthorize管理。我要做的第一件事是修改创建用户的过程。我希望能够在新用户创建后立即为其分配角色 我面临的第一个问题是,当创建用户时,控制器会将我重定向到用户列表页面。我需要改变这种行为,我希望被重定向到编辑页面,在那里我可以为最近创建的用户选择N个角色(这将是与实体的另一场战争…)。我选择覆盖UserAdminController(ZfcUs

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

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

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

2.I在MyAdministration/config/module.config.php中重写ZfcUserAdmin控制器以使用我的:

(...)
'controllers' => array(
    'invokables' => array(
        'zfcuseradmin' => 'MyAdministration\Controller\MyAdministrationController',
    ),
),
(...)
3.我已经创建了这个类 MyAdministration/src/MyAdministration/Controller/MyAdministrationController.php

4.我已经声明要扩展ZfcUserAdmin one

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的类,它将控制器的名称空间转换为所需模板的路径。我的控制器“已翻译”为 my administration/my administration/edit没有结果,模板属于ZfcUserAdmin模块。正确的路径是由其控制器(ZfcUserAdmin\controller\UserAdminController)获得的路径: zfc用户管理/用户管理/编辑

我还了解到,模板路径可以手动编写。这些路径将被忽略 他是一名听众。这就是我使用的方法。在里面 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;
  }
}
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;
    }
}
模板将是
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;
  }
}
您可以在控制器中看到您正在覆盖。重定向插件返回一个响应对象

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

namespace MyModule;

class MyController
{
  public function myAction()
  {
    return new ViewModel;
  }
}
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模板映射。

我将此作为注释,因为我不知道它是否是您所需要的全部。将加载的模板就在您的命名空间域上。含义:
module/MyAdministration/view/my administration/my administration/edit.phtml
。我认为您不需要覆盖ZfcUsers模板映射,因为它们与您覆盖的控制器无关。这些映射遵循默认映射。但总而言之,这是一个‘我想’不需要编写新模块来定制另一个模块以满足您的需要,如果模块提供了在注册后配置重定向的选项,请尝试使用它,否则最好直接修改zfcusradmin控制器以适合您的需要need@Sam:问题是我的模块/MyAdministration/view/my administration/my administration/中没有edit.phtml。它仅存在于ZfcUserAdmin/view/zfc user admin/user admin中。如果我复制模块中的文件,我认为你是对的,但我不需要它,因为我不需要更改它的逻辑。谢谢@拉杰:我试试看。我已经用ZfcUserAdmin的创建用户方式修复了。此模块没有任何属性来配置重定向。我可以试试ZfcUser中的注册系统,它的属性可能适合我的需要。关于修改ZfcUserAdmin,我不希望对供应商目录中的任何模块进行更改。谢谢我只是说,如果覆盖控制器,也需要一个新的视图脚本。否则,您可以从该操作返回一个ViewModel,该操作从ZfcUserAdmin模块获取模板。比如
$vm->setTemplate('zfc-user-admin/controllername/edit.phtml')
或者类似的东西。由于我不知道模块配置选项,我只能支持这种方法;)一般来说,Raj是正确的,如果有配置,就使用它,但您知道这一点;)是否还要编写一个路由,使其仅在创建操作时调用UserAdminController,在所有其他操作时调用zfcuseradmin控制器,这是可能的?@Raj如果覆盖zfcuseradmin控制器,并将“可调用”指向类,这已经是可能的。因为
MyAdminModule\Controller\UserAdminController
会覆盖ZfcUserAdmin控制器,因此如果尝试在
UserAdminController
上调用
editAction()
,则实际上会调用来自原始控制器的操作。