Basic Symfony components sample
<?php
namespace App\EventListener;
use App\DTO\Publisher\CreatedTransactionDTO;
use App\Event\TransactionEvent;
use App\Events;
use DataMapper\MapperInterface;
use MessageBusBundle\Publisher\MessagePublisherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class TransactionSubscriber
*/
class TransactionSubscriber implements EventSubscriberInterface
{
/**
* @var MessagePublisherInterface
*/
private $publisher;
/**
* @var MapperInterface
*/
private $mapper;
/**
* TransactionSubscriber constructor.
*
* @param MessagePublisherInterface $eventsPublisher
* @param MapperInterface $mapper
*/
public function __construct(MessagePublisherInterface $eventsPublisher, MapperInterface $mapper)
{
$this->publisher = $eventsPublisher;
$this->mapper = $mapper;
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents(): array
{
return [
Events::PAYMENT_TRANSACTION_CREATED => 'onTransactionCreated',
];
}
/**
* @param TransactionEvent $event
*
* @return void
*/
public function onTransactionCreated(TransactionEvent $event): void
{
$dto = $this->mapper->convert($event->getTransaction(), CreatedTransactionDTO::class);
$data = $this->mapper->extract($dto);
$this->publisher->publish('transaction.created', $data);
}
}
----------------
<?php
namespace App\Processor\Payment;
use App\Entity\AbstractPayment;
use App\Entity\Payment;
use App\Manager\AbstractPaymentsManager;
use App\Specification\AbstractPayment\PaymentCallbackSpecification;
use App\Exception as PaymentException;
use App\Specification\RecurringPayment\RecurringPaymentByObjectIdSpecification;
/**
* Class PaymentFinder
*/
class PaymentFinder
{
/**
* @var AbstractPaymentsManager
*/
private $paymentsManager;
/**
* PaymentFinder constructor.
*
* @param AbstractPaymentsManager $paymentsManager
*/
public function __construct(AbstractPaymentsManager $paymentsManager)
{
$this->paymentsManager = $paymentsManager;
}
/**
* @throws PaymentException\PaymentNotFoundException
*
* @param string $paymentId
*
* @return AbstractPayment
*/
public function lookupPayment(string $paymentId): AbstractPayment
{
$spec = new PaymentCallbackSpecification($paymentId);
/** @var Payment $payment */
if (!$payment = $this->paymentsManager->findOne($spec)) {
throw new PaymentException\PaymentNotFoundException();
}
return $payment;
}
/**
* @throws PaymentException\PaymentNotFoundException
*
* @param string $objectId
*
* @return AbstractPayment
*/
public function lookupPaymentByObjectId(string $objectId): AbstractPayment
{
$spec = new RecurringPaymentByObjectIdSpecification($objectId);
/** @var Payment $payment */
if (!$payment = $this->paymentsManager->findOne($spec)) {
throw new PaymentException\PaymentNotFoundException();
}
return $payment;
}
}
----------------
<?php
namespace App\Command;
use App\Entity\RecurringPayment;
use App\Manager\RecurringPaymentsManager;
use App\Provider\PaymentProviderLoader;
use App\Specification\RecurringPayment\RecurringPaymentByIdSpecification;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CancelSubscriptionCommand
*/
class CancelSubscriptionCommand extends Command
{
private const CANCEL_ACTION = 'cancel-subscription';
/**
* @var string
*/
protected static $defaultName = 'app:subscription:cancel';
/**
* @var PaymentProviderLoader
*/
private $paymentProviderLoader;
/**
* @var RecurringPaymentsManager
*/
private $recurringPaymentsManager;
/**
* CancelSubscriptionCommand constructor.
*
* @param null|string $name
* @param PaymentProviderLoader $paymentProviderLoader
* @param RecurringPaymentsManager $recurringPaymentsManager
*/
public function __construct(
?string $name = null,
PaymentProviderLoader $paymentProviderLoader,
RecurringPaymentsManager $recurringPaymentsManager
) {
parent::__construct($name);
$this->paymentProviderLoader = $paymentProviderLoader;
$this->recurringPaymentsManager = $recurringPaymentsManager;
}
/**
* @return void
*/
protected function configure(): void
{
$this
->setName('app:subscription:cancel')
->setDescription('Cancel subscription on payment provider side.')
->addOption(
'payment-id',
'p-id',
InputOption::VALUE_REQUIRED,
'Recurring payment id or external id'
);
}
/**
* @param InputInterface $input
* @param OutputInterface $output
*
* @return void
*
* @throws \Throwable
*/
protected function execute(InputInterface $input, OutputInterface $output): void
{
$paymentId = $input->getOption('payment-id');
/** @var RecurringPayment $recurringPayment */
$recurringPayment = $this->recurringPaymentsManager->findOne(new RecurringPaymentByIdSpecification($paymentId));
if (null !== $recurringPayment) {
$subscriptionCancelAction = $this->paymentProviderLoader->loadProviderAction(
$recurringPayment->getProvider(),
self::CANCEL_ACTION
);
$subscriptionCancelAction->handle(
function () {
},
$recurringPayment->getExtId()
);
$output->writeln(
"{$recurringPayment->getProvider()} subscription
for Recurring Payment with id: $paymentId was cancelled"
);
} else {
$output->writeln("Can't find Recurring Payment with following id or external id: $paymentId");
}
}
}
-------------
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Document\Player;
use App\DTO\Internal\PlayerDTO;
use App\DTO\Request\Player\UpdatePlayerDTO;
use App\DTO\Response\PlayerDTO as ResponsePlayerDTO;
use App\Manager\PlayerManager;
use RestBundle\Configuration\Entity;
use RestBundle\Configuration\MapperParamConverter;
use RestBundle\Controller\RestController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @IsGranted("IS_AUTHENTICATED_FULLY")
*/
class PlayerController extends RestController
{
/**
* @var PlayerManager
*/
private $playerManager;
/**
* PlayerController constructor.
*
* @param PlayerManager $playerManager
*/
public function __construct(PlayerManager $playerManager)
{
$this->playerManager = $playerManager;
}
/**
* @Route(
* path="/player/{id}",
* methods={"PUT"},
* name="update_player"
* )
*
* @MapperParamConverter("updateDTO", class="App\DTO\Request\Player\UpdatePlayerDTO")
*
* @Entity("player", expr="repository.findOneBy({id: id})")
*
* @param Player $player
* @param UpdatePlayerDTO $updateDTO
*
* @return Response
*/
public function updatePlayer(Player $player, UpdatePlayerDTO $updateDTO): Response
{
/** @var PlayerDTO $playerDTO */
$playerDTO = $this->mapper->convert($updateDTO, PlayerDTO::class);
$playerDTO->userId = $this->getUser();
$player = $this->playerManager->update($player, $playerDTO);
return $this->createResponse($player, ResponsePlayerDTO::class);
}
}
------------
<?php
namespace XXX\ElasticaBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* Class ElasticaExtension.
*/
class ElasticaExtension extends Extension
{
/**
* {@inheritdoc}
*
* @throws \LogicException
* @throws \ReflectionException
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
$loader->load('admin.yml');
$bundles = $container->getParameter('kernel.bundles');
if (isset($bundles['ElasticaBundle'])) {
$this->addCustomFormTypes($container);
}
$this->loadTypeMapping($config['types'], $container);
$this->loadWebhooksRegistry($config['webhooks'], $container);
}
/**
* @param array $webhooks
* @param ContainerBuilder $container
*/
private function loadWebhooksRegistry(array $webhooks, ContainerBuilder $container): void
{
$registryDef = $container->getDefinition(WebhookRegistry::class);
foreach ($webhooks as $webhook) {
$registryDef->addMethodCall('addWebhook', [$webhook]);
}
}
/**
* @param array $types
* @param ContainerBuilder $container
*
* @throws \LogicException
* @throws \ReflectionException
*/
private function loadTypeMapping(array $types, ContainerBuilder $container): void
{
foreach ($types as $name => $type) {
$typeConfig = [
'name' => $type['type_name'] ?? $name,
'transformer' => $type['transformer'],
'mapping' => [], // An array containing anything that gets sent directly to ElasticSearch
'config' => [],
];
foreach (['dynamic_templates', 'properties', '_all', '_id', '_parent', '_routing', '_source'] as $field) {
if (isset($type[$field])) {
$typeConfig['mapping'][$field] = $type[$field];
}
}
$this->loadModelTransformer($typeConfig, $container);
}
}
/**
* @param array $typeConfig
* @param ContainerBuilder $container
*
* @throws \LogicException
* @throws \ReflectionException
*/
private function loadModelTransformer(array $typeConfig, ContainerBuilder $container): void
{
$transformerDef = $container->getDefinition($transformerClass = $typeConfig['transformer']);
$reflClass = $container->getReflectionClass($transformerClass, false);
if (!$reflClass || !$reflClass->implementsInterface(ModelToElasticaTransformerInterface::class)) {
throw new \LogicException(
sprintf(
'%s should implement the %s interface when used as model transformer.',
$transformerClass,
ModelToElasticaTransformerInterface::class
)
);
}
$transformerDef->addMethodCall('setModelMapping', [$typeConfig['mapping']['properties']]);
$this->checkTransformerConfig($typeConfig['mapping']['properties'], $container);
}
/**
* @param array $typeConfig
* @param ContainerBuilder $container
*
* @throws \LogicException
* @throws \ReflectionException
*/
private function checkTransformerConfig(array $typeConfig, ContainerBuilder $container): void
{
$transformers = (new ArraySearch($typeConfig))->search(['transformer']);
foreach ($transformers as $transformerClass) {
$reflClass = $container->getReflectionClass($transformerClass, false);
if (!$reflClass || !$reflClass->implementsInterface(ElasticaTransformerInterface::class)) {
throw new \LogicException(
sprintf(
'%s should implement the %s interface when used as transformer.',
$transformerClass,
ElasticaTransformerInterface::class
)
);
}
}
}
/**
* @param ContainerBuilder $container
*/
private function addCustomFormTypes(ContainerBuilder $container): void
{
$resources = [];
if ($container->hasParameter('twig.form.resources')) {
$resources = $container->getParameter('twig.form.resources');
}
$resources[] = 'ElasticaBundle:Form:fields.html.twig';
$container->setParameter('twig.form.resources', $resources);
}
}