Skip to content

Instantly share code, notes, and snippets.

@thunderer
Created February 17, 2015 09:52
Show Gist options
  • Save thunderer/6b730c9711e364113c8e to your computer and use it in GitHub Desktop.
Save thunderer/6b730c9711e364113c8e to your computer and use it in GitHub Desktop.
PHPers: Fetching data to entities which belong to many external sources, see: https://www.facebook.com/groups/223889134481096/permalink/337805749756100/ .
<?php
namespace PHPers;
use GuzzleHttp\Client as GuzzleClient;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
// Entities: Just a place to store runtime data
class Repository
{
private $id;
private $name;
private $url;
public function __construct($name, $url) {}
public function getId() {}
public function getName() {}
public function getUrl() {}
}
class User
{
private $id;
private $email;
private $repositories = array();
public function __construct($email) {}
public function addRepository(Repository $repository) {}
public function hasRepository(Repository $repository) {}
public function getId() {}
public function getEmail() {}
public function getRepositories() {}
}
// Services: Interact with external sources using proper connector
interface RepositoryHostInterface
{
public function fetchRepositoriesByEmail($email);
}
class Github implements RepositoryHostInterface
{
private $guzzle;
public function __construct(GuzzleClient $guzzle) {}
public function fetchRepositoriesByEmail($email) {}
}
class BitBucket implements RepositoryHostInterface
{
private $guzzle;
public function __construct(GuzzleClient $guzzle) {}
public function fetchRepositoriesByEmail($email) {}
}
// Repositories: Management of application storage
class UserCommandRepository
{
public function persist(User $user) {}
}
class UserQueryRepository
{
public function findById($id) {}
public function findByEmail($email) {}
}
// Application: Handle user actions and defer external requests to commands
class UserController
{
private $userCommandRepository;
private $userQueryRepository;
public function __construct(
UserCommandRepository $userCommandRepository,
UserQueryRepository $userQueryRepository) {}
public function createAction()
{
$user = new User('user@host.tld');
$this->userCommandRepository->persist($user);
$this->queueCommand('user:repositories:fetch', array(
'id' => $user->getId(),
));
}
public function viewAction($id)
{
return $this->render('view.twig', array(
'user' => $this->userQueryRepository->findById($id),
));
}
}
// Command: Use services fetch data from external sources and put them in an application storage
class UserFetchRepositoriesCommand extends Command
{
private $github;
private $bitbucket;
private $userCommandRepository;
private $userQueryRepository;
public function __construct(
Github $github,
BitBucket $bitbucket,
UserCommandRepository $userCommandRepository,
UserQueryRepository $userQueryRepository) {}
protected function configure()
{
$this
->setName('user:repositories:fetch')
->setDefinition(array(new InputArgument('id', InputArgument::REQUIRED, 'User ID')));
}
public function execute(InputInterface $input, OutputInterface $output)
{
$id = $input->getArgument('id');
$user = $this->userQueryRepository->findById($id);
$repositories = $this->github->fetchByEmail($user->getEmail());
$output->writeln(sprintf('Found %s repositories!', count($repositories)));
array_map(function(Repository $repository) use($user) {
$user->addRepository($repository);
}, $repositories);
// same for bitbucket
$this->userCommandRepository->persist($user);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment