netglue/ZF2-Prismic-Module

View on GitHub
src/NetgluePrismic/Mvc/Listener/SelectedRefListener.php

Summary

Maintainability
A
45 mins
Test Coverage
<?php

namespace NetgluePrismic\Mvc\Listener;

use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\ListenerAggregateTrait;
use Zend\EventManager\EventManagerInterface;
use Zend\EventManager\EventInterface;
use Zend\Mvc\MvcEvent;
use NetgluePrismic\ContextAwareTrait;
use NetgluePrismic\ContextAwareInterface;
use NetgluePrismic\Session\PrismicContainer;
use Prismic\Api;

class SelectedRefListener implements
    ListenerAggregateInterface,
    ContextAwareInterface
{

    use ListenerAggregateTrait;
    use ContextAwareTrait;

    private $session;

    /**
     * Attach to specific events with the shared manager
     * @param  EventManagerInterface $events
     * @return void
     */
    public function attach(EventManagerInterface $events)
    {
        $shared = $events->getSharedManager();
        $this->listeners[] = $shared->attach('Zend\Mvc\Application', MvcEvent::EVENT_ROUTE, array($this, 'setPreviewRef'));
    }

    /**
     * If a preview cookie is found, set it as the ref in the global context, otherwise, set the ref that's stored in the session
     * @param EventInterface $event
     * @return void
     */
    public function setPreviewRef(MvcEvent $event)
    {
        $ref = $this->getSessionRef();

        $cookie = $this->getCookieRef($event);

        if(null !== $cookie) {
            $ref = $cookie;
        } else {
            /**
             * Check that $ref does not belong to a stale preview cookie
             * i.e. it exists amongst all available refs. If it is stale, unset it
             */
            $api = $this->getContext()->getPrismicApi();
            foreach($api->refs() as $cmp) {
                if( (string) $cmp === $ref) {
                    $ref = null;
                }
            }
        }

        if(null !== $ref) {
            $this->getContext()->setRefWithString($ref);
        }
    }

    /**
     * Return the ref set in the session if it can be found
     * @return string|null
     */
    public function getSessionRef()
    {
        if($this->session) {
            return $this->session->getRef();
        }
    }

    /**
     * Return the ref stored in the preview cookie if it can be found
     * @return string|null
     */
    public function getCookieRef(MvcEvent $event)
    {
        $request = $event->getApplication()->getRequest();
        $cookies = $request->getHeader('cookie');
        $cookieName = Api::PREVIEW_COOKIE;
        $cookieName = str_replace('.', '_', $cookieName);
        if (isset($cookies->{$cookieName}) && !empty($cookies->{$cookieName})) {

            return $cookies->{$cookieName};
        }

        return null;
    }

    public function setSession(PrismicContainer $session = null)
    {
        $this->session = $session;
    }

}