<?php
/**
 * Add MetaTagSet to Entities when ContentTypes change
 *
 * @author Elze Kool <info@visualmedia.nl>
 */

namespace VisualM\TagManagerBundle\Doctrine\EventListener;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use VisualM\TagManagerBundle\Content\TaggableContentInterface;
use VisualM\TagManagerBundle\Entity\MetaTag;
use VisualM\TagManagerBundle\Entity\MetaTagSet;


/**
 * Add MetaTagSet to Entities when ContentTypes change
 *
 * @author Elze Kool <info@visualmedia.nl>
 */
class AddMetaTagSetByContentNameSubscriber implements EventSubscriber, ContainerAwareInterface
{
    use ContainerAwareTrait;
    
    /**
     * Needs Flush
     * @var bool
     */
    private $needsFlush = false;

    /**
     * Sets where ContentTypes is changed
     * @var array
     */
    private $changedSets = [];
    
    /**
     * Specifies the list of events to listen
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        return array(
            'postPersist',
            'preUpdate',
            'postUpdate',
            'postFlush'
        );
    }

    /**
     * postPersist event
     *
     * @param LifecycleEventArgs $args Event Data
     */
    public function postPersist(LifecycleEventArgs $args)
    {
        if ($args->getEntity() instanceof MetaTagSet) {
            $this->changedSets[] = spl_object_hash($args->getEntity());
            $this->onMetaTagSetUpdate($args);
        }
    }

    /**
     * preUpdate event
     *
     * @param PreUpdateEventArgs $args Event Data
     */
    public function preUpdate(PreUpdateEventArgs $args)
    {
        if ($args->getEntity() instanceof MetaTagSet) {
            if ($args->hasChangedField('contentTypes')) {
                $this->changedSets[] = spl_object_hash($args->getEntity());
            }
        }
    }

    /**
     * postUpdate event
     *
     * @param LifecycleEventArgs $args Event Data
     */
    public function postUpdate(LifecycleEventArgs $args)
    {
        if ($args->getEntity() instanceof MetaTagSet) {
            $this->onMetaTagSetUpdate($args);
        }
    }

    /**
     * postFlush event
     *
     * @param PostFlushEventArgs $eventArgs Event Data
     */
    public function postFlush(PostFlushEventArgs $eventArgs)
    {
        if ($this->needsFlush) {
            $this->needsFlush = false;
            $eventArgs->getEntityManager()->flush();
        }
    }

    /**
     * MetaTagSet update
     * 
     * @param LifecycleEventArgs $args Event Data
     */
    protected function onMetaTagSetUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        /* @var $entity MetaTagSet */

        // When contentTypes unchanged return
        if (!in_array(spl_object_hash($entity), $this->changedSets)) {
            return;
        }

        // Get Managers
        $taggable_manager_registry = $this->container->get('visualm.tag_manager.util.taggable_manager_registry');
        $managers = [];
        foreach($entity->getContentTypes() as $content_name) {
            if (null !== ($manager = $taggable_manager_registry->getManager($content_name))) {
                $managers[] = $manager;
            }
        }

        // Get Id's to check
        $meta_tag_preset_ids = [];
        foreach($entity->getMetaTagPresets() as $meta_tag_preset) {
            $meta_tag_preset_ids[] = $meta_tag_preset->getId();
        }

        // Go trough managers
        $meta_tag_manager = $this->container->get('visualm.tag_manager.manager.meta_tag');
        foreach($managers as $manager) {

            // Get contentIds provided by manager
            $content_ids = $manager->getContentIds();

            // Go trough contentIds
            foreach($content_ids as $content_id) {

                // Check if content Item has set already
                if ($meta_tag_manager->getCount([ 'content_id' => $content_id, 'meta_tag_preset_id' => $meta_tag_preset_ids]) > 0) {
                    continue;
                }

                // Get MetaTagPresets for this set and add them
                foreach($entity->getMetaTagPresets() as $meta_tag_preset) {

                    // Create new tag from preset
                    $meta_tag = new MetaTag();
                    $meta_tag->setAutoAdded(true);
                    $meta_tag->setContentId($content_id);
                    $meta_tag->setInhoud($meta_tag_preset->getInhoud());
                    $meta_tag->setInhoudIsExpression($meta_tag_preset->getInhoudIsExpression());
                    $meta_tag->setInhoudGewijzigd(false);
                    $meta_tag->setZichtbaar($meta_tag_preset->getZichtbaar());
                    $meta_tag->setZichtbaarIsExpression($meta_tag_preset->getZichtbaarIsExpression());
                    $meta_tag->setZichtbaarGewijzigd(false);
                    $meta_tag->setMetaTagPreset($meta_tag_preset);

                    $args->getEntityManager()->persist($meta_tag);

                    $this->needsFlush = true;
                }
            }
        }
    }
}


