Skip to content
This repository has been archived by the owner on Jun 28, 2022. It is now read-only.

Commit

Permalink
Merge pull request #65 from cultuurnet/feature/III-1768
Browse files Browse the repository at this point in the history
III-1768 Prevent removal of categories.
  • Loading branch information
Luc Wollants committed Jan 17, 2017
2 parents d45cd65 + 9095aa0 commit e4dad4c
Show file tree
Hide file tree
Showing 16 changed files with 691 additions and 140 deletions.
203 changes: 102 additions & 101 deletions composer.lock

Large diffs are not rendered by default.

39 changes: 39 additions & 0 deletions src/CultureFeed/CategoryListFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace CultuurNet\UDB3\CdbXmlService\CultureFeed;

use CultureFeed_Cdb_Data_CategoryList;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification\CategorySpecificationInterface;

class CategoryListFilter
{
/**
* @var CategorySpecificationInterface
*/
private $spec;

/**
* @param CategorySpecificationInterface $spec
*/
public function __construct(CategorySpecificationInterface $spec)
{
$this->spec = $spec;
}

/**
* @param CultureFeed_Cdb_Data_CategoryList $categories
* @return CultureFeed_Cdb_Data_CategoryList
*/
public function filter(CultureFeed_Cdb_Data_CategoryList $categories)
{
$matchingCategories = new CultureFeed_Cdb_Data_CategoryList();

foreach ($categories as $category) {
if ($this->spec->matches($category)) {
$matchingCategories->add($category);
}
}

return $matchingCategories;
}
}
42 changes: 42 additions & 0 deletions src/CultureFeed/CategorySpecification/AnyOff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification;

use CultureFeed_Cdb_Data_Category;

class AnyOff implements CategorySpecificationInterface
{
/**
* @var CategorySpecificationInterface[]
*/
private $wrapped;

public function __construct()
{
$args = func_get_args();

foreach ($args as $index => $arg) {
if (!$arg instanceof CategorySpecificationInterface) {
throw new \InvalidArgumentException(
"Invalid argument received at position $index, expected an implementation of CategorySpecificationInterface"
);
}
}

$this->wrapped = $args;
}

/**
* @inheritdoc
*/
public function matches(CultureFeed_Cdb_Data_Category $category)
{
foreach ($this->wrapped as $wrapped) {
if ($wrapped->matches($category)) {
return true;
}
}

return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification;

use CultureFeed_Cdb_Data_Category;

interface CategorySpecificationInterface
{
/**
* @param CultureFeed_Cdb_Data_Category $category
* @return bool
*/
public function matches(CultureFeed_Cdb_Data_Category $category);
}
30 changes: 30 additions & 0 deletions src/CultureFeed/CategorySpecification/Not.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification;

use CultureFeed_Cdb_Data_Category;

class Not implements CategorySpecificationInterface
{
/**
* @var CategorySpecificationInterface
*/
private $wrapped;

/**
* Not constructor.
* @param CategorySpecificationInterface $wrapped
*/
public function __construct(CategorySpecificationInterface $wrapped)
{
$this->wrapped = $wrapped;
}

/**
* @inheritdoc
*/
public function matches(CultureFeed_Cdb_Data_Category $category)
{
return !$this->wrapped->matches($category);
}
}
29 changes: 29 additions & 0 deletions src/CultureFeed/CategorySpecification/Type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification;

use CultureFeed_Cdb_Data_Category;

class Type implements CategorySpecificationInterface
{
/**
* @var string
*/
private $type;

/**
* @param string $type
*/
public function __construct($type)
{
$this->type = $type;
}

/**
* @inheritdoc
*/
public function matches(CultureFeed_Cdb_Data_Category $category)
{
return $category->getType() == $this->type;
}
}
32 changes: 15 additions & 17 deletions src/CultureFeed/FlandersRegionCategoryService.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
use CultureFeed_Cdb_Data_Address_PhysicalAddress;
use CultureFeed_Cdb_Data_Category;
use CultureFeed_Cdb_Item_Base;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\FlandersRegionCategoryServiceInterface;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification\Not;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification\Type;
use SimpleXMLElement;

class FlandersRegionCategoryService implements FlandersRegionCategoryServiceInterface
Expand Down Expand Up @@ -56,23 +57,20 @@ public function findFlandersRegionCategory(CultureFeed_Cdb_Data_Address_Physical
* @param CultureFeed_Cdb_Item_Base $item
* @param CultureFeed_Cdb_Data_Category|null $newCategory
*/
public function updateFlandersRegionCategories(CultureFeed_Cdb_Item_Base $item, CultureFeed_Cdb_Data_Category $newCategory = null)
{
$updated = false;
foreach ($item->getCategories() as $key => $category) {
if ($category->getType() == CultureFeed_Cdb_Data_Category::CATEGORY_TYPE_FLANDERS_REGION) {
if ($newCategory && !$updated) {
$category->setId($newCategory->getId());
$category->setName($newCategory->getName());
$updated = true;
} else {
$item->getCategories()->delete($key);
}
}
}
public function updateFlandersRegionCategories(
CultureFeed_Cdb_Item_Base $item,
CultureFeed_Cdb_Data_Category $newCategory = null
) {
$filter = new CategoryListFilter(
new Not(new Type('flandersregion'))
);

if (!$updated && $newCategory) {
$item->getCategories()->add($newCategory);
$categories = $filter->filter($item->getCategories());

if ($newCategory) {
$categories->add($newCategory);
}

$item->setCategories($categories);
}
}
43 changes: 21 additions & 22 deletions src/ReadModel/OfferToCdbXmlProjector.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
use CultuurNet\UDB3\CdbXmlService\CultureFeed\AddressFactoryInterface;
use CultuurNet\UDB3\CdbXmlService\CdbXmlDocument\CdbXmlDocument;
use CultuurNet\UDB3\CdbXmlService\CdbXmlDocument\CdbXmlDocumentFactoryInterface;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategoryListFilter;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification\AnyOff;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification\Not;
use CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification\Type;
use CultuurNet\UDB3\CdbXmlService\Labels\LabelApplierInterface;
use CultuurNet\UDB3\CdbXmlService\ReadModel\Repository\DocumentRepositoryInterface;
use CultuurNet\UDB3\ContactPoint;
Expand Down Expand Up @@ -1844,38 +1848,33 @@ private function updateCategories(
EventType $eventType,
Theme $theme = null
) {
// Set event type and theme.
$updatedTheme = false;
foreach ($item->getCategories() as $key => $category) {
if ($category->getType() == 'eventtype') {
$category->setId($eventType->getId());
$category->setName($eventType->getLabel());
}
$filter = new CategoryListFilter(
new Not(
new AnyOff(new Type('eventtype'), new Type('theme'))
)
);

// update the theme
if ($theme && $category->getType() == 'theme') {
$category->setId($theme->getId());
$category->setName($theme->getLabel());
$updatedTheme = true;
}
$categories = $filter->filter($item->getCategories());

// remove the theme if exists
if (!$theme && $category->getType() == 'theme') {
$item->getCategories()->delete($key);
$updatedTheme = true;
}
}
$categories->add(
new CultureFeed_Cdb_Data_Category(
'eventtype',
$eventType->getId(),
$eventType->getLabel()
)
);

// add new theme if it didn't exist
if (!$updatedTheme && $theme) {
$item->getCategories()->add(
if ($theme) {
$categories->add(
new CultureFeed_Cdb_Data_Category(
'theme',
$theme->getId(),
$theme->getLabel()
)
);
}

$item->setCategories($categories);
}

/**
Expand Down
84 changes: 84 additions & 0 deletions tests/CultureFeed/CategorySpecification/AnyOffTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace CultuurNet\UDB3\CdbXmlService\CultureFeed\CategorySpecification;

use CultureFeed_Cdb_Data_Category;

class AnyOffTest extends \PHPUnit_Framework_TestCase
{
/**
* @var CategorySpecificationInterface
*/
private $trueCategorySpecification;

/**
* @var CategorySpecificationInterface
*/
private $falseCategorySpecification;

/**
* @var AnyOff
*/
private $anyOff;

protected function setUp()
{
$this->falseCategorySpecification = $this->createCategorySpecification(false);

$this->trueCategorySpecification = $this->createCategorySpecification(true);

$this->anyOff = new AnyOff(
$this->falseCategorySpecification,
$this->trueCategorySpecification
);
}

/**
* @test
*/
public function it_matches_when_at_least_one_specification_matches()
{
$category = new CultureFeed_Cdb_Data_Category(
'eventtype',
'0.50.4.0.0',
'concert'
);

$this->assertTrue($this->anyOff->matches($category));
}

/**
* @test
*/
public function it_throws_exception_when_parameter_has_wrong_type()
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(
'Invalid argument received at position 2, expected an implementation of CategorySpecificationInterface'
);

$this->anyOff = new AnyOff(
$this->falseCategorySpecification,
$this->trueCategorySpecification,
'I am a string'
);
}

/**
* @param bool $result
* @return CategorySpecificationInterface
*/
private function createCategorySpecification($result)
{
/** @var CategorySpecificationInterface|\PHPUnit_Framework_MockObject_MockObject $categorySpecification */
$categorySpecification = $this->createMock(
CategorySpecificationInterface::class
);

$categorySpecification
->method('matches')
->willReturn($result);

return $categorySpecification;
}
}
Loading

0 comments on commit e4dad4c

Please sign in to comment.