* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace App\Form\DataTransformer; use App\Entity\Tag; use App\Repository\TagRepository; use Symfony\Component\Form\DataTransformerInterface; use function Symfony\Component\String\u; /** * This data transformer is used to translate the array of tags into a comma separated format * that can be displayed and managed by Bootstrap-tagsinput js plugin (and back on submit). * * See https://symfony.com/doc/current/form/data_transformers.html * * @author Yonel Ceruto * @author Jonathan Boyer */ class TagArrayToStringTransformer implements DataTransformerInterface { private $tags; public function __construct(TagRepository $tags) { $this->tags = $tags; } /** * {@inheritdoc} */ public function transform($tags): string { // The value received is an array of Tag objects generated with // Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer::transform() // The value returned is a string that concatenates the string representation of those objects /* @var Tag[] $tags */ return implode(',', $tags); } /** * {@inheritdoc} */ public function reverseTransform($string): array { if (null === $string || u($string)->isEmpty()) { return []; } $names = array_filter(array_unique(array_map('trim', u($string)->split(',')))); // Get the current tags and find the new ones that should be created. $tags = $this->tags->findBy([ 'name' => $names, ]); $newNames = array_diff($names, $tags); foreach ($newNames as $name) { $tag = new Tag(); $tag->setName($name); $tags[] = $tag; // There's no need to persist these new tags because Doctrine does that automatically // thanks to the cascade={"persist"} option in the App\Entity\Post::$tags property. } // Return an array of tags to transform them back into a Doctrine Collection. // See Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer::reverseTransform() return $tags; } }