Zend Framework 2:使用自己的字段扩展 ZfcUser


Zend Framework 2: Extend ZfcUser with own fields

我正在做我的第一个Zend Framework 2项目。为此,我需要一个用户模块和集成的ZfcUser。由于我的用户表略有不同,因此我必须使用自己的用户实体和用户映射器。我创建了一个名为ZfcUserExtension的新模块。

然后我从原始的ZfcUSer模块中复制了很多文件,例如:

  • 实体/用户.php
  • 实体/用户界面.php
  • 工厂/
  • 实体/索引控制器工厂.php
  • 工厂/
  • 映射器/用户水合器工厂.php
  • 映射器/执行/异常接口
  • Mapper/Exeption/InvalidArgumentException.php
  • Mapper/
  • Exeption/RuntimeException.php Mapper/HydratorInterface.php
  • 映射器/用户.php映射器/用户水合器.php映射器/用户水合器.php
  • 映射器/用户界面.php

在 zfcuser.global 中.php我将user_entity_class设置为使用我自己的实体。

'user_entity_class' => 'ZfcUserExtension'Entity'User',

在 module.config 中.php从 ZfcUserExtension 中添加以下内容以确保我使用自己的 User Mapper 和 UserHydrator。原因是我在用户表中使用"id"而不是"user_id"作为主键,所以我必须确保它也被覆盖。

<?php
 return array(
 'controllers' => array(
    'factories' => array(
        'ZfcUserExtension'Controller'Index' => function(Zend'Mvc  'Controller'ControllerManager $cm) {
            $sm = $cm->getServiceLocator();
            return new 'ZfcUserExtension'Controller'IndexController(
                $sm->get("doctrine.entitymanager.orm_default")
            );
        }
    ),
),
'service_manager' => array(
    'factories' => array(
        'zfcuser_user_mapper' => function ($sm) {
            $options = $sm->get('zfcuser_module_options');
            $mapper = new 'ZfcUserExtension'Mapper'User();
            // No db adapter present add below line
            $mapper->setDbAdapter($sm->get('zfcuser_zend_db_adapter'));
            $entityClass = $options->getUserEntityClass();
            // No entity prototype set add below line
            $mapper->setEntityPrototype(new $entityClass);
            $mapper->setHydrator($sm->get('zfcuser_user_hydrator'));
            $mapper->setTableName($options->getTableName());
            return $mapper;
        },
        //  'zfcuserextension_change_password_form' => 'ZfcUserExtension'Factory'Form'ChangePhoneFormFactory',
            ),
),

我终于让这一切工作了,直到我现在遇到了另一个问题。我想要用户的一些附加字段,例如电话号码。我将如何处理这个问题?我知道互联网上有一些想法,但我主要感兴趣的是知道我实际上如何提供"更换电话"表格的选项。我创建了一个表单,类似于"更改密码"和"更改电子邮件"。然后,我在我的ZfcUSerExtension中创建了一个IndexController.php再次遵循ZfcUser模块的用户控制器的设置。

class IndexController extends AbstractActionController {
const ROUTE_LOGIN        = 'zfcuser/login';

/**
 * @var 'Doctrine'ORM'EntityManager
 */
protected $em;
public function __construct('Doctrine'ORM'EntityManager $em)    
{
    $this->em = $em;
}

/**
 * @var Form
 */
protected $changeEmailForm;

public function indexAction() {
    if (!$this->zfcUserAuthentication()->hasIdentity()) {
         return $this->redirect()->toRoute(static::ROUTE_LOGIN);
    }
    return new ViewModel();
}
 public function changephoneAction() {
    // if the user isn't logged in, we can't change phone
    if (!$this->zfcUserAuthentication()->hasIdentity()) {
       return $this->redirect()->toRoute(static::ROUTE_LOGIN);
    }
    $form = $this->getChangePhoneForm();
    $request = $this->getRequest();
    $request->getPost()->set('PrevPhone', $this->getUserService()->getAuthService()->getIdentity()->getPrevPhone());
       return array(
            'status' => false,
            'changePhoneForm' => $form,
        );

    $fm = $this->flashMessenger()->setNamespace('change-phone')->getMessages();
    if (isset($fm[0])) {
        $status = $fm[0];
    } else {
        $status = null;
    }
    $prg = $this->prg(static::ROUTE_LOGIN);
    if ($prg instanceof Response) {
        return $prg;
    } elseif ($prg === false) {
        return array(
            'status' => $status,
            'changePhoneForm' => $form,
        );
    }
    $form->setData($prg);
    if (!$form->isValid()) {
        return array(
            'status' => false,
            'changePhoneForm' => $form,
        );
    }
    $change = $this->getUserService()->changeEmail($prg);
    if (!$change) {
        $this->flashMessenger()->setNamespace('change-email')->addMessage(false);
        return array(
            'status' => false,
            'changeEmailForm' => $form,
        );
    }
    $this->flashMessenger()->setNamespace('change-email')->addMessage(true);
    return $this->redirect()->toRoute(static::ROUTE_CHANGEEMAIL);
}

public function getChangePhoneForm()
{
      $sl = $this->getServiceLocator();
      $this->setChangePhoneForm($sl->get('zfcuserextension_change_phone_form'));
    return $this->changePhoneForm;
}
public function setChangePhoneForm($changePhoneForm)
{
    $this->changePhoneForm = $changePhoneForm;      
    return $this;
}

我现在注意到我将面临用户服务服务/用户.php的问题。该服务提供 changePassword() 和 changeEmail() 方法。我现在认为我需要将此文件复制到我自己的模块中。如果我从ZfcUser扩展用户服务,那么方法changePassword()和changeEmail()仍然可用,所以我会从刚刚复制的文件中删除它并添加changePhone()吗?

如果我的想法是正确的,用户服务目前是这样开始的:

class User extends EventProvider implements ServiceManagerAwareInterface

我必须如何更改它以扩展原始用户服务?我希望有人能帮忙,我仍然对这一切感到困惑。提前非常感谢你。

有两种可能的方法:

  1. 构建扩展 ZfcUser 的实体、表单和输入筛选器的自定义类,并添加自定义字段。在 ZfcUser 配置中,更改别名或覆盖工厂,以确保自定义类被实例化,而不是内置类。

  2. 如果您同意将自定义配置文件字段与 ZfcUser 用户实体分开存储和访问,请查看我在 GitHub 上的模块:LdcUserProfile。它为 ZfcUser 提供了一个配置文件系统,但也可以轻松添加链接到用户的您自己的自定义配置文件字段集。