Skip to content

Instantly share code, notes, and snippets.

@tentacode
Created August 19, 2014 09:04
Show Gist options
  • Save tentacode/ef4d19b390a599be74a6 to your computer and use it in GitHub Desktop.
Save tentacode/ef4d19b390a599be74a6 to your computer and use it in GitHub Desktop.
PHP DI + Trait + Symfony service === <3 ?
<?php
namespace Tentacode\App\Security;
trait ConnectedUser
{
/**
* @Inject
* @var Symfony\Component\Security\Core\SecurityContext
*/
private $securityContext;
public function getConnectedUser()
{
$token = $this->securityContext->getToken();
if (!$token) {
throw new \RuntimeException('No user is connected.');
}
return $token->getUser();
}
}
<?php
return [
'Symfony\Component\Security\Core\SecurityContext' => DI\link('security.context'),
// ...
];
<?php
namespace Tentacode\App\Controller\Person;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Tentacode\App\Security\ConnectedUser;
use Tentacode\App\Templating\Templating;
use Tentacode\Domain\Person\PersonRepository;
use Tentacode\Domain\User;
class ProfileController
{
use ConnectedUser;
protected $templating;
protected $personRepository;
public function __construct(Templating $templating, PersonRepository $personRepository)
{
$this->templating = $templating;
$this->personRepository = $personRepository;
}
public function myProfileAction()
{
$user = $this->getConnectedUser();
return $this->templating->render('TentacodeAppBundle:Person:profile.html.twig', [
'user' => $user
]);
}
}
@mnapoli
Copy link

mnapoli commented Aug 19, 2014

Also, an alternative to traits (beberlei: http://www.whitewashing.de/2013/06/27/extending_symfony2__controller_utilities.html): having a ControllerUtils class that can be injected and that exposes methods like shown above.

Though I'd rather use your solution because shoving everything into a generic ControllerUtils doesn't look good for separation of concerns and all.

@tentacode
Copy link
Author

Yeah well, and any class with Utils in its name is just "some big class I'm going to put everything in it"

@tentacode
Copy link
Author

But yeah, the solution is probably the best, but I won't use a single Utils class, more like several services that do their own stuff.

@mrclay
Copy link

mrclay commented Aug 19, 2014

Why not move the other two dependencies to traits to follow this to its conclusion. Here traits are just making up for the fact that it's overly verbose to have a property and a constructor arg and and assignment for every damn dependency. The bad is that it does cause your constructor to lie about dependencies so this can only be safely built in a PHP-DI environment. So it would be somewhat better to move ALL dependencies to PHP-DI-injected and make the constructor private (or have it throw an exception).

Cleaner would be to move getConnectedUser to a direct dependency and inject that instead of security context. Then you really just have a clean set of dependencies each in a trait for less verbosity.

@tentacode
Copy link
Author

yeah, that's what I'll be doing in practice, @Inject on properties, and utility services

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