1

This is a follow up question to my previous question Zend Framework 2: How to create own User mapper for ZfcUser.

What was the problem? In my User Database Table, I use id as primary key in comparison to user_id which ZfcUser is normally using. This was of course not possible.

Ok, so what have I done? Here a summary. I have created a new Module called ZfcUserExtension. I then copied the Mapper and Entity folder from ZfcUser. I then overwrote the factory in the module.config.php. In the zfcuser.global.php I changed user_entity_class to reflect my Entity.

I then changed user_id to id in the 3 Functions inside the User Mapper and UserHydrator.php

I can now log in with now problem and register. After that I tried to "Change-Password" and "Change-Email" and that is when I get the Error Message occurred:
Unknown column 'user_id' in 'field list'.

The way it looks, it actually goes into ZfcUser and uses this. So my question now is, what else do I have to change or copy? Am I right that I have to set up a route in my Module ZfcUserExtension for User/change-password and User/change-email? But does it not mean I then have to copy the Controller Folder from ZfcUser as well or how can I use the controller from ZfcUser, but then use the Mapper again from my Module?

Does someone got an idea how I can solve it? I am really lost here. Thank you very much in advance.

EDIT: after receiving help from bitWorking I have a running solution

The below solution from bitWorking worked with only 1 change. I had to include the mapField calls and change the mapfield in the extract function. I don't fully understand why I had to do that, because I would have thought that if I change user_id to id in both functions it should work, but figured out that the update then doesn't work because there is no id available. I also assumed that I then had to turn the mapping in the Hydrate function around, but that is not the case. All in all, if I have not overseen any other issue, I would say it now works with id instead of user_id as a primary key. Thanks a lot again to bitWorking for his great help !

ZfcUserExtension/Mapper/UserHydrator.php

<?php 
namespace ZfcUserExtension\Mapper;

use Zend\Crypt\Password\PasswordInterface as ZendCryptPassword;
use Zend\Stdlib\Hydrator\ClassMethods;
use ZfcUser\Mapper\UserHydrator as ZfcUserUserHydrator;

class UserHydrator extends ZfcUserUserHydrator
{

  public function extract($object)
  {
    $this->guardUserObject($object);
    $data = parent::extract($object);

    // return $this->mapField('id', 'user_id', $data); //original from ZfcUser
    return $this->mapField('user_id', 'id', $data); // now it works
  }

  public function hydrate(array $data, $object)
  {
    $this->guardUserObject($object);        
    $data = $this->mapField('user_id', 'id', $data);
    return parent::hydrate($data, $object);
  }
}
Community
  • 1
  • 1
Luka
  • 748
  • 2
  • 9
  • 36
  • look at [this](https://github.com/ZF-Commons/ZfcUser/issues/506) issue – bitWorking Sep 26 '14 at 22:57
  • Thanks bitWorking, thats great. Now I only have to find out how I "Override hydrator service by extending ZfcUser\Mapper\UserHydrator." But I got a direction at least, thats fantastic. Thanks again. – Luka Sep 26 '14 at 23:01
  • This should work by overriding the key `factories->zfcuser_user_hydrator` in your own module config with your own factory class. Have a look at the Module.php in ZfcUser. – bitWorking Sep 26 '14 at 23:08
  • Ok, I guess it's not as easy as I thought. In module.php I have only the entry `'zfcuser_user_hydrator'=> 'ZfcUser\Factory\Mapper\UserHydratorFactory'`, but if I would change this, then I would have to copy the Factory folder as well or do I misunderstand? I don't have a Factory class yet. All I copied is Entity and Mapper Folder, not the Factory Folder, which got another Mapper Folder inside. – Luka Sep 26 '14 at 23:25

1 Answers1

1

Step by step:

First override the factory in your Module.php or module.config.php. You don't have to place it in the folder/namespace Factory\Mapper but for now I assume the same structure as ZfcUser.

'factories' => array(
    'zfcuser_user_hydrator' => 'ZfcUserExtension\Factory\Mapper\UserHydratorFactory',
),

Copy ZfcUser/Factory/Mapper/UserHydratorFactory.php to ZfcUserExtension/Factory/Mapper/UserHydratorFactory.php and change it:

namespace ZfcUserExtension\Factory\Mapper;

use Zend\Crypt\Password\Bcrypt;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use ZfcUserExtension\Mapper;

class UserHydratorFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $options = $serviceLocator->get('zfcuser_module_options');
        $crypto  = new Bcrypt;
        $crypto->setCost($options->getPasswordCost());
        return new Mapper\UserHydrator($crypto);
    }
}

Now create the file ZfcUserExtension/Mapper/UserHydrator.php (extend it and override the methods)

namespace ZfcUserExtension\Mapper;

use Zend\Crypt\Password\PasswordInterface as ZendCryptPassword;
use Zend\Stdlib\Hydrator\ClassMethods;
use ZfcUser\Mapper\UserHydrator as ZfcUserUserHydrator;

class UserHydrator extends ZfcUserUserHydrator
{
    public function extract($object)
    {
        $this->guardUserObject($object);
        return parent::extract($object);
    }

    public function hydrate(array $data, $object)
    {
        $this->guardUserObject($object);
        return parent::hydrate($data, $object);
    }
}

That should work if you want to change user_id to id. Else look at UserHydrator.php and change the mapField calls. Note: Not tested..

bitWorking
  • 12,485
  • 1
  • 32
  • 38
  • It works !!! Thanks so much for your help. I had to do a small change in UserHydrator.php. I have added the change to my first post. Thank you so much again. – Luka Sep 27 '14 at 11:25