Skip to content

Commit

Permalink
Merge branch 'master' of github.com:superdesk/web-publisher into impr…
Browse files Browse the repository at this point in the history
…ove_multitenancy
  • Loading branch information
ahilles107 committed Mar 6, 2017
2 parents 42dc3b0 + d03694b commit 8b3caf6
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 0 deletions.
94 changes: 94 additions & 0 deletions EventListener/OrganizationSubscriber.php
@@ -0,0 +1,94 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Superdesk Web Publisher MultiTenancy Bundle.
*
* Copyright 2017 Sourcefabric z.ú. and contributors.
*
* For the full copyright and license information, please see the
* AUTHORS and LICENSE files distributed with this source code.
*
* @copyright 2017 Sourcefabric z.ú
* @license http://www.superdesk.org/license
*/

namespace SWP\Bundle\MultiTenancyBundle\EventListener;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
use SWP\Component\Common\Exception\UnexpectedTypeException;
use SWP\Component\MultiTenancy\Model\OrganizationAwareInterface;
use SWP\Component\MultiTenancy\Model\OrganizationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

final class OrganizationSubscriber implements EventSubscriber
{
/**
* @var ContainerInterface
*/
protected $container;

/**
* Constructor.
*
* @param ContainerInterface $container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

/**
* {@inheritdoc}
*/
public function getSubscribedEvents()
{
return [
Events::prePersist,
];
}

/**
* @param LifecycleEventArgs $args
*/
public function prePersist(LifecycleEventArgs $args)
{
$this->addOrganization($args);
}

/**
* @param LifecycleEventArgs $args
*/
public function addOrganization(LifecycleEventArgs $args)
{
$entity = $args->getEntity();

if ($entity instanceof OrganizationAwareInterface) {
// skip when organization is already set
if (null !== $entity->getOrganization()) {
return;
}

$tenantContext = $this->container->get('swp_multi_tenancy.tenant_context');
$organization = $tenantContext->getTenant()->getOrganization();
$this->ensureOrganizationExists($organization);

/** @var OrganizationInterface $organization */
$organization = $args->getObjectManager()->merge($organization);
$entity->setOrganization($organization);
}
}

private function ensureOrganizationExists(OrganizationInterface $organization = null)
{
if (!$organization instanceof OrganizationInterface) {
throw UnexpectedTypeException::unexpectedType(
is_object($organization) ? get_class($organization) : gettype($organization),
OrganizationInterface::class
);
}
}
}
7 changes: 7 additions & 0 deletions Resources/config/listeners.yml
Expand Up @@ -14,3 +14,10 @@ services:
- '@service_container'
tags:
- { name: doctrine.event_subscriber }

swp_multi_tenancy.organization_subscriber:
class: SWP\Bundle\MultiTenancyBundle\EventListener\OrganizationSubscriber
arguments:
- '@service_container'
tags:
- { name: doctrine.event_subscriber }
130 changes: 130 additions & 0 deletions spec/EventListener/OrganizationSubscriberSpec.php
@@ -0,0 +1,130 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Superdesk Web Publisher MultiTenancy Bundle.
*
* Copyright 2017 Sourcefabric z.ú. and contributors.
*
* For the full copyright and license information, please see the
* AUTHORS and LICENSE files distributed with this source code.
*
* @copyright 2017 Sourcefabric z.ú
* @license http://www.superdesk.org/license
*/

namespace spec\SWP\Bundle\MultiTenancyBundle\EventListener;

use Doctrine\Common\EventSubscriber;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Events;
use PhpSpec\ObjectBehavior;
use SWP\Bundle\MultiTenancyBundle\EventListener\OrganizationSubscriber;
use SWP\Component\Common\Exception\UnexpectedTypeException;
use SWP\Component\MultiTenancy\Context\TenantContextInterface;
use SWP\Component\MultiTenancy\Model\Organization;
use SWP\Component\MultiTenancy\Model\OrganizationAwareInterface;
use SWP\Component\MultiTenancy\Model\Tenant;
use Symfony\Component\DependencyInjection\ContainerInterface;

final class OrganizationSubscriberSpec extends ObjectBehavior
{
public function let(ContainerInterface $container)
{
$this->beConstructedWith($container);
}

public function it_is_initializable()
{
$this->shouldHaveType(OrganizationSubscriber::class);
}

public function it_implements_event_subscriber_interface()
{
$this->shouldImplement(EventSubscriber::class);
}

public function it_subscribes_to_an_event()
{
$this->getSubscribedEvents()->shouldReturn([Events::prePersist]);
}

public function it_should_skip_when_organization_is_already_set_on_organization_aware_object(
LifecycleEventArgs $event,
OrganizationAwareInterface $organizationAware
) {
$organization = new Organization();
$organization->setName('org1');
$organization->setEnabled(true);
$organization->setCode('123456');

$organizationAware->getOrganization()->shouldBeCalled()->willReturn($organization);
$event->getEntity()->willReturn($organizationAware);

$this->prePersist($event);
}

public function it_sets_the_organization_on_pre_persist_doctrine_event(
TenantContextInterface $tenantContext,
LifecycleEventArgs $event,
OrganizationAwareInterface $organizationAware,
ContainerInterface $container,
ObjectManager $objectManager
) {
$organization = new Organization();
$organization->setName('org1');
$organization->setEnabled(true);
$organization->setCode('123456');

$tenant = new Tenant();
$tenant->setSubdomain('example.com');
$tenant->setName('Example');
$tenant->setCode('avc2334');
$tenant->setOrganization($organization);

$organizationAware->getOrganization()->shouldBeCalled()->willReturn(null);
$event->getEntity()->willReturn($organizationAware);
$objectManager->merge($organization)->willReturn($organization);
$event->getObjectManager()->willReturn($objectManager);
$tenantContext->getTenant()->shouldBeCalled()->willReturn($tenant);

$organizationAware->setOrganization($organization)->shouldBeCalled();

$container->get('swp_multi_tenancy.tenant_context')->willReturn($tenantContext);

$this->prePersist($event);
}

public function it_throws_exception_when_no_organization_on_pre_persist_doctrine_event(
TenantContextInterface $tenantContext,
LifecycleEventArgs $event,
OrganizationAwareInterface $organizationAware,
ContainerInterface $container
) {
$tenant = new Tenant();
$tenant->setSubdomain('example.com');
$tenant->setName('Example');
$tenant->setCode('avc2334');

$organizationAware->getOrganization()->shouldBeCalled()->willReturn(null);
$event->getEntity()->willReturn($organizationAware);
$tenantContext->getTenant()->shouldBeCalled()->willReturn($tenant);
$container->get('swp_multi_tenancy.tenant_context')->willReturn($tenantContext);

$this->shouldThrow(UnexpectedTypeException::class)
->duringAddOrganization($event);
}

public function it_sets_only_organization_aware_interface_implementation_on_pre_presist(
OrganizationAwareInterface $organizationAware,
LifecycleEventArgs $event
) {
$item = new \stdClass();
$event->getEntity()->willReturn($item);
$organizationAware->getOrganization()->shouldNotBeCalled();

$this->prePersist($event);
}
}

0 comments on commit 8b3caf6

Please sign in to comment.