Skip to content

Instantly share code, notes, and snippets.

@antonmedv
Created October 22, 2017 07:43
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save antonmedv/94053086bc14b113962df175825a60a1 to your computer and use it in GitHub Desktop.
Facade in Symfony
<?php
namespace AppBundle\Entity;
use AppBundle\DependencyInjection\Container;
class ActiveRecord extends Container
{
protected static function getDoctrine()
{
if (!self::$container->has('doctrine')) {
throw new \LogicException('The DoctrineBundle is not registered in your application.');
}
return self::$container->get('doctrine');
}
protected static function getEntityManager()
{
return self::getDoctrine()->getManagerForClass(get_called_class());
}
protected static function getRepository()
{
return self::getDoctrine()->getRepository(get_called_class());
}
/**
* @param $id
* @return null|static
*/
public static function find($id)
{
return self::getRepository()->find($id);
}
/**
* @return static[]
*/
public static function findAll()
{
return self::getRepository()->findAll();
}
/**
* @return static[]
*/
public static function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{
return self::getRepository()->findBy($criteria, $orderBy, $limit, $offset);
}
/**
* @return null|static
*/
public static function findOneBy(array $criteria)
{
return self::getRepository()->findOneBy($criteria);
}
}
<?php
namespace AppBundle;
use AppBundle\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
Container::set($container);
}
}
<?php
namespace AppBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerInterface;
class Container
{
/**
* @var ContainerInterface
*/
static protected $container;
public static function set(ContainerInterface $container)
{
self::$container = $container;
}
}
@antonmedv
Copy link
Author

Many immediately start screaming what it's an anti-pattern. But give it a try. It's same service locator only less verbose. I'm writing end-user code, not general library/bundle, not gonna unit test it, only integration tests, definitely not gonna mock all the things.

$user = $this->getDoctrine()->getRepository('AppBundle:User')->findOneBy([...]);

// Now I can use it like this:

$user = User::findOneBy([...]);

Actually it's only syntax sugar, but I think it's really important to save readability. This code still uses service locator pattern, you still can mock everything. Yes, it does create hard dependency, but same true for first example.

@onnyprima
Copy link

how to implement this on symfony 5

@antonmedv
Copy link
Author

Don’t know. Use laravel)))

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