I have custom entity and tag field defined as:
/**
* @ORM\ManyToMany(targetEntity="Sulu\Bundle\TagBundle\Tag\TagInterface")
* @ORM\JoinTable(name="venue_tags",
* joinColumns={@ORM\JoinColumn(name="venue_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="idTags", referencedColumnName="id")}
* )
*/
private $tags;
Then I have setter (adder actually) like this:
public function addTag(TagInterface $tag)
{
$this->tags[] = $tag;
return $this;
}
Field is added to form details XML like:
<property name="tags" type="tag_selection">
<meta>
<title lang="de">Tags</title>
<title lang="en">Tags</title>
</meta>
<tag name="sulu.search.field" type="tags"/>
</property>
And inside my admin controller class I have mapping method:
protected function mapDataToEntity(array $data, Venue $entity): void
{
....
foreach ($data['tags'] as $tag) {
$entity->addTag($tag);
}
....
However as $data['tags']
I receive here array of string and my addTag()
requires instance of TagInterface
object. How can I create that object from string I have and generally is this the proper way for storing tags.
Update:
As @Johannes suggested added field:
/**
* @var TagManagerInterface
*/
private $tagManager;
and to constructor like:
public function __construct(
ViewHandlerInterface $viewHandler,
...
TagManagerInterface $tagManager
) {
$this->viewHandler = $viewHandler;
...
$this->tagManager = $tagManager;
parent::__construct($viewHandler);
}
And then trying to add tags like this:
$tagEntities = $this->tagManager->resolveTagNames($data['tags']);
foreach ($tagEntities as $tagEntity) {
$entity->addTag($tagEntity);
}
But then I get error:
Argument 1 passed to App\Entity\Venue::addTag() must implement interface Sulu\Bundle\TagBundle\Tag\TagInterface, int given, called in /var/www/html/src/Controller/Admin/VenueController.php on line 147
What I'm doing wrong? Like I'm getting tag ids? Should I load tags somehow?
Update 2:
After adding findById()
saving tags works. However, now I found 2 more problems:
Even relations are saved well in database just after saving tags are not displayed any more in tags field. Also if I go to overview page and get back to edit entity selected (saved) tags are not re-populated. What else I have to add so saved tags in database would be used actually?
If I fist select "Tag1" and click "Save" it's saved well. But if I edit entity again and select "Tag1" again Sulu tries to create new row with same keys and I get error message: "SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4-1' for key 'venue_tags.PRIMARY'". I guess previously saved keys should be deleted first but how and where would be the optimal way?
You can use the TagManager service (id: sulu_tag.tag_manager
or Sulu\Bundle\TagBundle\Tag\TagManagerInterface
):
$tagIds = $tagManager->resolveTagNames($data['tags']);
foreach ($tagIds as $tagId) {
$entity->addTag($tagManager->findById($tagId));
}