Skip to content

Commit

Permalink
Add support for creating attributes with values of type eztags
Browse files Browse the repository at this point in the history
  • Loading branch information
gggeek committed Nov 14, 2016
1 parent fa3295a commit 4abae71
Show file tree
Hide file tree
Showing 20 changed files with 271 additions and 27 deletions.
11 changes: 11 additions & 0 deletions API/Collection/TagCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Kaliop\eZMigrationBundle\API\Collection;

/**
* @todo add phpdoc to suggest typehinting
*/
class TagCollection extends AbstractCollection
{
protected $allowedClass = 'Netgen\TagsBundle\API\Repository\Values\Tags\Tag';
}
44 changes: 44 additions & 0 deletions Core/ComplexField/EzTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Kaliop\eZMigrationBundle\Core\ComplexField;

use Kaliop\eZMigrationBundle\API\ComplexFieldInterface;
use Kaliop\eZMigrationBundle\Core\Matcher\TagMatcher;

class EzTags extends AbstractComplexField implements ComplexFieldInterface
{
protected $tagMatcher;

public function __construct(TagMatcher $tagMatcher)
{
$this->tagMatcher = $tagMatcher;
}

/**
* Creates a value object to use as the field value when setting an eztags field type.
*
* @param array $fieldValue
* @param array $context The context for execution of the current migrations. Contains f.e. the path to the migration
* @return \Netgen\TagsBundle\Core\FieldType\Tags\Value
* @throws \Exception
*/
public function createValue($fieldValue, array $context = array())
{
$tags = array();
foreach($fieldValue as $def)
{
if (!is_array($def) || count($def) != 1) {
throw new \Exception('Definition of EzTags field is incorrect: each element of the tags array must be an array with one element');
}
$identifier = reset($def);
$type = key($def);


foreach($this->tagMatcher->match(array($type => $identifier)) as $id => $tag) {
$tags[$id] = $tag;
}
}

return new \Netgen\TagsBundle\Core\FieldType\Tags\Value(array_values($tags));
}
}
9 changes: 5 additions & 4 deletions Core/Executor/TagManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
namespace Kaliop\eZMigrationBundle\Core\Executor;

use Kaliop\eZMigrationBundle\Core\ReferenceResolver\ReferenceHandler;
use Netgen\TagsBundle\Core\SignalSlot\TagsService;
use Netgen\TagsBundle\API\Repository\Values\Tags\TagCreateStruct;

class TagManager extends RepositoryExecutor
{
protected $supportedStepTypes = array('tag');

protected $tagService;

public function __construct(TagsService $tagService=null)
/**
* @param \Netgen\TagsBundle\Core\SignalSlot\TagsService $tagService
*/
public function __construct($tagService=null)
{
$this->tagService = $tagService;
}
Expand Down Expand Up @@ -42,7 +43,7 @@ protected function create()
'mainLanguageCode' => $lang,
'alwaysAvailable' => $alwaysAvail,
);
$tagCreateStruct = new TagCreateStruct($tagCreateArray);
$tagCreateStruct = new \Netgen\TagsBundle\API\Repository\Values\Tags\TagCreateStruct($tagCreateArray);

foreach ($this->dsl['keywords'] as $langCode => $keyword)
{
Expand Down
12 changes: 0 additions & 12 deletions Core/Matcher/AbstractMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Kaliop\eZMigrationBundle\Core\Matcher;

use eZ\Publish\API\Repository\Repository;
use Kaliop\eZMigrationBundle\API\MatcherInterface;

abstract class AbstractMatcher implements MatcherInterface
Expand All @@ -14,17 +13,6 @@ abstract class AbstractMatcher implements MatcherInterface
/** @var int $maxConditions the maximum number of conditions we allow to match on for a single match request */
protected $maxConditions = 1;

protected $repository;

/**
* @param Repository $repository
* @todo inject the services needed, not the whole repository
*/
public function __construct(Repository $repository)
{
$this->repository = $repository;
}

protected function validateConditions(array $conditions)
{
if (count($conditions) == 0) {
Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/ContentMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @todo extend to allow matching by visibility, subtree, depth, object state, section, creation/modification date...
* @todo extend to allow matching on multiple conditions (AND)
*/
class ContentMatcher extends AbstractMatcher
class ContentMatcher extends RepositoryMatcher
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/ContentTypeGroupMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Kaliop\eZMigrationBundle\API\Collection\ContentTypeGroupCollection;
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;

class ContentTypeGroupMatcher extends AbstractMatcher implements KeyMatcherInterface
class ContentTypeGroupMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/ContentTypeMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Note: disallowing matches by remote_id allows us to implement KeyMatcherInterface without the risk of users getting
* confused as to what they are matching...
*/
class ContentTypeMatcher extends AbstractMatcher implements KeyMatcherInterface
class ContentTypeMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/LocationMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* @todo extend to allow matching by visibility, subtree, depth, object state, section, creation/modification date...
* @todo extend to allow matching on multiple conditions (AND)
*/
class LocationMatcher extends AbstractMatcher
class LocationMatcher extends RepositoryMatcher
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/ObjectStateGroupMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use \eZ\Publish\API\Repository\Values\ObjectState\ObjectStateGroup;
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;

class ObjectStateGroupMatcher extends AbstractMatcher implements KeyMatcherInterface
class ObjectStateGroupMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/ObjectStateMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;
use eZ\Publish\Core\Base\Exceptions\NotFoundException;

class ObjectStateMatcher extends AbstractMatcher implements KeyMatcherInterface
class ObjectStateMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
19 changes: 19 additions & 0 deletions Core/Matcher/RepositoryMatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Kaliop\eZMigrationBundle\Core\Matcher;

use eZ\Publish\API\Repository\Repository;

abstract class RepositoryMatcher extends AbstractMatcher
{
protected $repository;

/**
* @param Repository $repository
* @todo inject the services needed, not the whole repository
*/
public function __construct(Repository $repository)
{
$this->repository = $repository;
}
}
2 changes: 1 addition & 1 deletion Core/Matcher/RoleMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Kaliop\eZMigrationBundle\API\Collection\RoleCollection;
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;

class RoleMatcher extends AbstractMatcher implements KeyMatcherInterface
class RoleMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/SectionMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Kaliop\eZMigrationBundle\API\Collection\SectionCollection;
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;

class SectionMatcher extends AbstractMatcher implements KeyMatcherInterface
class SectionMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
145 changes: 145 additions & 0 deletions Core/Matcher/TagMatcher.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

namespace Kaliop\eZMigrationBundle\Core\Matcher;

use Kaliop\eZMigrationBundle\API\Collection\TagCollection;
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;

/**
* @todo when matching by keyword, allow to pick the desired language
*/
class TagMatcher extends AbstractMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

const MATCH_TAG_ID = 'tag_id';
const MATCH_TAG_REMOTE_ID = 'tag_remote_id';
const MATCH_TAG_KEYWORD = 'tag_keyword';

protected $allowedConditions = array(
self::MATCH_TAG_ID, self::MATCH_TAG_REMOTE_ID, self::MATCH_TAG_KEYWORD,
// aliases
'id', 'remote_id', 'keyword'
);
protected $returns = 'Tag';

protected $translationHelper;
protected $tagService;

/**
* @param $translationHelper
* @param \Netgen\TagsBundle\API\Repository\TagsService $tagService
*/
public function __construct($translationHelper, $tagService=null)
{
$this->translationHelper = $translationHelper;
$this->tagService = $tagService;
}

/**
* @param array $conditions key: condition, value: int / string / int[] / string[]
* @return TagCollection
*/
public function match(array $conditions)
{
return $this->matchTag($conditions);
}

/**
* @param array $conditions key: condition, value: int / string / int[] / string[]
* @return TagCollection
* @throws \Exception
*/
public function matchTag(array $conditions)
{
if ($this->tagService == null) {
throw new \Exception('Netgen TAG Bundle is required to use tag matching');
}

$this->validateConditions($conditions);

foreach ($conditions as $key => $values) {

if (!is_array($values)) {
$values = array($values);
}

switch ($key) {
case 'id':
case self::MATCH_TAG_ID:
return new TagCollection($this->findTagsByIds($values));

case 'remote_id':
case self::MATCH_TAG_REMOTE_ID:
return new TagCollection($this->findTagsByRemoteIds($values));

case 'keyword':
case self::MATCH_TAG_KEYWORD:
return new TagCollection($this->findTagsByKeywords($values));
}
}
}

protected function getConditionsFromKey($key)
{
if (is_int($key) || ctype_digit($key)) {
return array(self::MATCH_TAG_ID => $key);
}

throw new \Exception("Tag matcher can not uniquely identify the type of key used to match: ".key);
}

/**
* @param int[] $tagIds
* @return \Netgen\TagsBundle\API\Repository\Values\Tags\Tag[]
*/
protected function findTagsByIds(array $tagIds)
{
$tags = [];

foreach ($tagIds as $tagId) {
// return unique contents
$tag = $this->tagService->loadTag($tagId);
$tags[$tag->id] = $tag;
}

return $tags;
}

/**
* @param string[] $tagRemoteIds
* @return \Netgen\TagsBundle\API\Repository\Values\Tags\Tag[]
*/
protected function findTagsByRemoteIds(array $tagRemoteIds)
{
$tags = [];

foreach ($tagRemoteIds as $tagRemoteId) {
// return unique contents
$tag = $this->tagService->loadTagByRemoteId($tagRemoteId);
$tags[$tag->id] = $tag;
}

return $tags;
}

/**
* @param string[] $tagKeywords
* @return \Netgen\TagsBundle\API\Repository\Values\Tags\Tag[]
*/
protected function findTagsByKeywords(array $tagKeywords)
{
$tags = [];

$availableLanguages = $this->translationHelper->getAvailableLanguages();

foreach ($tagKeywords as $tagKeyword) {
// return unique contents
foreach($this->tagService->loadTagsByKeyword($tagKeyword, $availableLanguages[0]) as $tag) {
$tags[$tag->id] = $tag;
}
}

return $tags;
}
}
2 changes: 1 addition & 1 deletion Core/Matcher/UserGroupMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* @todo add matching all groups of a user, all child groups of a group
*/
class UserGroupMatcher extends AbstractMatcher implements KeyMatcherInterface
class UserGroupMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
2 changes: 1 addition & 1 deletion Core/Matcher/UserMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Kaliop\eZMigrationBundle\API\Collection\UserCollection;
use Kaliop\eZMigrationBundle\API\KeyMatcherInterface;

class UserMatcher extends AbstractMatcher implements KeyMatcherInterface
class UserMatcher extends RepositoryMatcher implements KeyMatcherInterface
{
use FlexibleKeyMatcherTrait;

Expand Down
8 changes: 7 additions & 1 deletion Core/ReferenceResolver/TagResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

/**
* Handles references to tags
*
* @todo support custom languages
*/
class TagResolver extends AbstractResolver
{
Expand All @@ -15,7 +17,11 @@ class TagResolver extends AbstractResolver
protected $translationHelper;
protected $tagService;

public function __construct($translationHelper, $tagService)
/**
* @param $translationHelper
* @param \Netgen\TagsBundle\API\Repository\TagsService $tagService
*/
public function __construct($translationHelper, $tagService=null)
{
parent::__construct();

Expand Down
Loading

0 comments on commit 4abae71

Please sign in to comment.