Skip to content

Instantly share code, notes, and snippets.

@dbu
Last active December 1, 2016 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save dbu/7639476 to your computer and use it in GitHub Desktop.
Save dbu/7639476 to your computer and use it in GitHub Desktop.
FOSUserBundle PHPCR-ODM binding
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/phpcr-odm/phpcr-mapping
https://github.com/doctrine/phpcr-odm/raw/master/doctrine-phpcr-odm-mapping.xsd">
<mapped-superclass name="FOS\UserBundle\Model\User">
<nodename name="usernameCanonical" />
<field name="username" type="string" />
<field name="email" type="string" />
<field name="emailCanonical" type="string" />
<field name="enabled" type="boolean" />
<field name="salt" type="string" />
<field name="password" type="string" />
<field name="lastLogin" type="date" nullable="true" />
<field name="locked" type="boolean" />
<field name="expired" type="boolean" />
<field name="expiresAt" type="date" nullable="true" />
<field name="confirmationToken" type="string" nullable="true" />
<field name="passwordRequestedAt" type="date" nullable="true" />
<field name="roles" type="string" multivalue="true" />
<field name="credentialsExpired" type="boolean" />
<field name="credentialsExpireAt" type="date" nullable="true" />
</mapped-superclass>
</doctrine-mapping>
<?php
namespace Liip\MyBundle\Document;
use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;
use FOS\UserBundle\Model\User as BaseUser;
/**
* @PHPCRODM\Document(repositoryClass="Liip\MyBundle\Document\UserRepository")
*/
class User extends BaseUser
{
/**
* @PHPCRODM\Id(strategy="REPOSITORY")
*/
protected $id;
}
<?php
namespace FOS\UserBundle\Doctrine\Phpcr;
use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
use Doctrine\ODM\PHPCR\Event;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Doctrine PHPCR-ODM listener updating the canonical fields and the password.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class UserListener implements EventSubscriber
{
/**
* @var \FOS\UserBundle\Model\UserManagerInterface
*/
private $userManager;
/**
* @var ContainerInterface
*/
private $container;
/**
* Constructor
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getSubscribedEvents()
{
return array(
Event::prePersist,
Event::preUpdate,
);
}
public function prePersist(LifecycleEventArgs $args)
{
$this->handleEvent($args);
}
public function preUpdate(LifecycleEventArgs $args)
{
$this->handleEvent($args);
}
private function handleEvent(LifecycleEventArgs $args)
{
$entity = $args->getObject();
if ($entity instanceof UserInterface) {
if (null === $this->userManager) {
$this->userManager = $this->container->get('fos_user.user_manager');
}
$this->userManager->updateCanonicalFields($entity);
$this->userManager->updatePassword($entity);
return;
//TODO: what about this?
if ($args instanceof PreUpdateEventArgs) {
// We are doing a update, so we must force Doctrine to update the
// changeset in case we changed something above
/** @var $dm \Doctrine\ODM\PHPCR\DocumentManager */
$dm = $args->getObjectManager();
$uow = $dm->getUnitOfWork();
$meta = $dm->getClassMetadata(get_class($entity));
// do we need this? is this sane?
$uow->computeSingleDocumentChangeSet($meta, $entity);
}
}
}
}
<?php
namespace Liip\MyBundle\Document;
use Doctrine\ODM\PHPCR\DocumentRepository;
use Doctrine\ODM\PHPCR\Id\RepositoryIdInterface;
class UserRepository extends DocumentRepository implements RepositoryIdInterface
{
protected static $basePath = '/cms/users/';
/**
* Generate a document id
*
* @param User $user
* @return string
*/
public function generateId($user, $parent = null)
{
return self::$basePath . $user->getUsernameCanonical();
}
public function findOneBy(array $criteria)
{
// some optimization as usernameCanonical is the nodename
// and id does not work in findBy
if (count($criteria) == 1) {
if (isset($criteria['usernameCanonical'])) {
return $this->dm->find($this->className, self::$basePath . $criteria['usernameCanonical']);
}
if (isset($criteria['id'])) {
return $this->dm->find($this->className, $criteria['id']);
}
}
return $this->findBy($criteria);
}
}
@rrrmity
Copy link

rrrmity commented Aug 26, 2015

Hi there!
Thanks for the information. It seems this is the only help when you try to use phpcr as the source for backend user authentication anywhere.
But could you give us some more hints on how to use this setup? I was not able to configure the config.yml (especially the fos_user->user_class) to use the new user class. Maybe you could add the relevant parts of your config.yml? Where do you put the dcm.xml file so it is used?

Best regards,
Michi

@Ludaa
Copy link

Ludaa commented Dec 1, 2016

@dbu Two years later is there still no easy way to integrate the fosuserbundle ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment