ZFCUser is a great module, really cleanly written, and while there are some modules out there that'll help you extend ZFCUser with custom profiles, my challenge was one where I had to retrofit an existing Doctrine entity for use with ZFCUser -- let me tell you it worked great.

There are a lot of posts on SO that have to do with granular pieces of extending the ZfcUser form, but nothing I could find that had a usable A to Z for Doctrine2 users.  I added a post on the ZFCUser Wiki about the storage piece, and thought I'd throw it in here to help the next wandering coder.

Assuming that you've done two things:

  •  set up your application.config.php to include ZfcBase, ZfcUser, ZfcUserDoctrineORM
  • created your own user Module (e.g., module/FooUser/) with your entities and schema already set up

Essentially, you have a working ZfcUser, but just need to know how to extend the form and store (quite a few reasonable tutorials out there if you're not here yet.  Find one, set it up, and then come back).

/module/FooUser/config/module.config.php

<?php

return array(
'doctrine' => array(
'driver' => array(
// overriding zfc-user-doctrine-orm's config
'zfcuser_entity' => array(
'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
'paths' => __DIR__ . '/../src/FooUser/Entity',
),

'orm_default' => array(
'drivers' => array(
'FooUser\Entity' => 'zfcuser_entity',
),
),
),
),

'zfcuser' => array(
// telling ZfcUser to use our own class
'user_entity_class' => 'FooUser\Entity\User',
// telling ZfcUserDoctrineORM to skip the entities it defines
'enable_default_entities' => false,
),
);

This tells your module config to use the entities you've set up in /modules/FooUser/src/FooUser/Entity/User.php for example, as the default ZfcUser User entity.

/module/FooUser/Module.php

<?php

namespace FooUser;

use Zend\Mvc\MvcEvent;

class Module {

public function getConfig()
{
return include __DIR__ . '/config/module.config.php';

}

public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}

public function onBootstrap( MVCEvent $e )
{
$eventManager = $e->getApplication()->getEventManager();
$em = $eventManager->getSharedManager();
$em->attach(
'ZfcUser\Form\RegisterFilter',
'init',
function( $e )
{
$filter = $e->getTarget();
// do your form filtering here
}
);

// custom form fields

$em->attach(
'ZfcUser\Form\Register',
'init',
function($e)
{
/* @var $form \ZfcUser\Form\Register */
$form = $e->getTarget();
$form->add(
array(
'name' => 'username',
'options' => array(
'label' => 'Username',
),
'attributes' => array(
'type' => 'text',
),
)
);

$form->add(
array(
'name' => 'favorite_ice_cream',
'options' => array(
'label' => 'Favorite Ice Cream',
),
'attributes' => array(
'type' => 'text',
),
)
);
}
);

// here's the storage bit

$zfcServiceEvents = $e->getApplication()->getServiceManager()->get('zfcuser_user_service')->getEventManager();

$zfcServiceEvents->attach('register', function($e) {
$form = $e->getParam('form');
$user = $e->getParam('user');
/* @var $user \FooUser\Entity\User */
$user->setUsername( $form->get('username')->getValue() );
$user->setFavoriteIceCream( $form->get('favorite_ice_cream')->getValue() );
});

// you can even do stuff after it stores
$zfcServiceEvents->attach('register.post', function($e) {
/*$user = $e->getParam('user');*/
});
}
}

Hopefully this helps another soul out!  This is one way to slice the pie that woulda saved me a bunch of time.

Tack BjyAuthorize on top of this, and you're off to the races.

https://packagist.org/packages/bjyoungblood/BjyAuthorize

Good Luck!