views:

74

answers:

1

I'm new to Doctrine 2 (and exceptions in PHP, really), but am trying to come up with a robust validation engine on Doctrine 2 (on top of CodeIgniter), following this page.

Right now I'm wondering where I would define the ValidateException class, and how to 'try' doing a save (persist?) on my entity (from a controller, library, etc).

I'd like to have something where, after doing this (in an 'authentication' library, for example):

$user->username = $username;
$user->email_address = $email_address;
$user->password = $password;

$em->persist($user);
$em->flush();

return $foo; //where $foo refers to whether $em->flush() worked...

I could simply return whether that persistence was successful (i.e., passed validation and saved), or not successful (i.e., failed validation).

A: 

I think you may want to look at having a User Factory. You could have methods that take an array of data (from a form's POST) and return a User object. This lets you encapsulate the entire process of creating a new User object for use within your application (and persists to your datastore). You can do all of your try/catches in this single place and all your controllers just call this one function (code isn't scattered in all of your controllers).

class UserFactory
{
  /** @var Doctrine Entity Manager */
  private $_em;

  function __construct(EntityManager $em) {
    $this->_em = $em;
  }

  function createUserFromArray($data) {
    $user = new User();
    $user->setUsername($data['username']);
    $user->setEmail($data['email']);

    $this->_em->persist($user);
    $this->_em->flush(); // Or this could be called from some other place

    return $user;
  }
}

Then in your controller all you do is something like this:

// Get the EntityManger from wherever (registry, session, etc)
$userFactory = new UserFactory($em);
$user = $userFactory->createFromArray($dataFromForm);

Two things additional things.

One, if you use explicit getters and setters for your properties (username and email) you can throw exceptions within those functions if they don't meet the criteria.

In your User class:

function setEmail($email) {
  // Do some validations on the email address
  if (!is_valid_email($email)) {
    throw new Exception('Invalid Email');
  }
  $this->email = $email;
}

Two, I think this is the question you were really asking is about the lifecycle callbacks. You define those on/in your Model/Entity classes themselves.

class User
{
  /** @PrePersist @PreUpdate */
  function ensureUniqueEmail()
  {
    // Do your check, else throw exception
  }
}
jsuggs