Below you'll find a Symfony2 service I wrote to assist in handling the Library entity. Each user in my app has a personal library where one can upload items to and a purchased library, that contains items one has purchased. Both libraries fall under a parent library.
At several points in my controller, I need to get the library for the user to save data. If the library doesn't exist yet, I want to create it.
The two switch
es in the getUserLibrary()
function especially bother me.
<?php
namespace Smoovi\SmooviBundle\Entity\Manager;
use Doctrine\ORM\EntityManager;
use Smoovi\SmooviBundle\Entity\Library,
Smoovi\UserBundle\Entity\User;
class LibraryManager
{
const TYPE_PURCHASED = 1;
const TYPE_PERSONAL = 2;
protected $em;
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* Get a user's personal library
*
* @param \Smoovi\UserBundle\Entity\User $user
* @return Library
*/
protected function getPersonalLibrary($user)
{
return $this->getUserLibrary($user, self::TYPE_PERSONAL);
}
/**
* Get a user's library for purchased objects
*
* @param \Smoovi\UserBundle\Entity\User $user
* @return Library
*/
public function getPurchasedLibrary($user)
{
return $this->getUserLibrary($user, self::TYPE_PURCHASED);
}
/**
* Get or create a library based on $type
*
* @param User $user
* @param $type
* @return Library
* @throws \Exception
*/
protected function getUserLibrary(User $user, $type)
{
$libRepo = $this->em->getRepository('SmooviSmooviBundle:Library');
// we first try to find the user's parent library
// if not, create it
/** @var \Smoovi\SmooviBundle\Entity\Library $topLibrary */
$topLibrary = $libRepo->findOneBy(array('user' => $user, 'parent' => null));
if (is_null($topLibrary)) {
$library = new Library();
$library
->setUser($user)
->setName($user->getFirstname()."'s Library")
->setIndex(1)
;
$this->em->persist($library);
}
// look for the sublibrary
// create it if necessary
$where = array('user' => $user, 'parent' => $topLibrary);
switch($type) {
case self::TYPE_PURCHASED:
$where['purchased'] = true;
$libraryName = 'Purchases';
break;
case self::TYPE_PERSONAL:
$where['personal'] = true;
$libraryName = 'Objects';
break;
default:
throw new \Exception('Library subtype not implemented');
}
/** @var \Smoovi\SmooviBundle\Entity\Library $subLibrary */
$subLibrary = $libRepo->findOneBy($where);
if (is_null($subLibrary)) {
$subLibrary = new Library();
$subLibrary
->setParent($topLibrary)
->setUser($user)
->setName($libraryName)
->setIndex(1)
;
switch($type) {
case self::TYPE_PURCHASED:
$subLibrary->setPurchased(true);
break;
case self::TYPE_PERSONAL:
$subLibrary->setPersonal(true);
break;
default:
throw new \Exception('Library subtype not implemented');
}
$this->em->persist($subLibrary);
}
$this->em->flush();
return $subLibrary;
}
}