Skip to content

jonocode – a developer's blog

I moved! –> http://pressreload.com

Symfony has automated the process of creating a CRUD application, and even has built-in CSRF protection.

However, for a site with multiple users, the generated CRUD code just won’t do.

In my schema, each row of a model is owned by a user, according to their user_id. In the dashboard application I am building, each user has a list of programs.

They can create, read, update and delete each program that they own.

But the generated actions would allow users access to other user’s programs, simply by changing the id in URLs such as /program/edit/id/1.

My solution? Store the user_id of the currently logged in user in myUser.class.php. Since the myUser class has ownership of the id of the currently logged in user, I thought it was appropriate to implement convenience getters and setters for the dashboard here.

So my list action would contain:

$this->programs = $this->getUser()->getPrograms();

The myUser::getPrograms() method is implemented like so:

public function getPrograms()
{
  return Doctrine::getTable('Program')->fetchByOwner($this->getId());
}

public function getProgram($pk)
{
  $program = Doctrine::getTable('Program')->find($pk);
  return $this->hasOwnershipOf($program) ? $program : false;
}

public function hasOwnershipOf($row)
{
  if ( isset($row['user_id']) )
  {
    if ( $row['user_id'] == $this->getId() )
    {
      return true;
    }
  }
  return false;
}

Adding the myUser::fetchByOwner() method leaves the model functionality open to being called from another administrative application other than the dashboard. You could use a Doctrine magic method here, however I would prefer to return programs in alphabetical order (or perhaps allow for other options to be passed in using a Doctrine_Query as a second parameter).

For myUser::getProgram($pk), I simply use the ::find() magic method in doctrine to retrieve the object by primary key, as usual, and then return it only if it matches the user_id of the logged-in user.

Writing for multiple users is common place for web-based applications. However, it’s something I don’t usually deal with at work where I write simple, single-user back ends for editing website content.

Is there a more elegant way of handling user ownership of database content? Perhaps by writing a doctrine behavior? How do you usually go about it?

Please comment.

Advertisements

%d bloggers like this: