<commit_before><?php
namespace Tonis\Mvc\Subscriber;

use Interop\Container\ContainerInterface;
use Tonis\Event\EventManager;
use Tonis\Event\SubscriberInterface;
use Tonis\Mvc\LifecycleEvent;
use Tonis\Mvc\Tonis;
use Tonis\Router\RouteMatch;
use Tonis\View\Model\JsonModel;
use Tonis\View\Strategy\JsonStrategy;
use Tonis\View\ViewManager;

final class ApiSubscriber implements SubscriberInterface
{
    /** @var ContainerInterface */
    private $di;

    /**
     * @param ContainerInterface $di
     */
    public function __construct(ContainerInterface $di)
    {
        $this->di = $di;
    }

    /**
     * @param EventManager $events
     * @return void
     */
    public function subscribe(EventManager $events)
    {
        $events->on(Tonis::EVENT_BOOTSTRAP, [$this, 'bootstrapViewManager']);
        $events->on(Tonis::EVENT_ROUTE_ERROR, [$this, 'onRouteError']);
        $events->on(Tonis::EVENT_DISPATCH, [$this, 'onDispatch']);
        $events->on(Tonis::EVENT_DISPATCH_EXCEPTION, [$this, 'onDispatchException']);
        $events->on(Tonis::EVENT_RESPOND, [$this, 'onRespond']);
    }

    public function bootstrapViewManager()
    {
        $vm = $this->di->get(ViewManager::class);
        $vm->addStrategy(new JsonStrategy());
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onDispatch(LifecycleEvent $event)
    {
        $result = $event->getDispatchResult();
        if (is_array($result)) {
            $event->setDispatchResult(new JsonModel($result));
        }
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onDispatchException(LifecycleEvent $event)
    {
        $event->setResponse($event->getResponse()->withStatus(500));

        $model = new JsonModel([
            'error' => 'An error has occurred',
            'exception' => $event->getException()->getMessage(),
            'trace' => $event->getException()->getTrace()
        ]);
        $event->setDispatchResult($model);
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onRouteError(LifecycleEvent $event)
    {
        $event->setResponse($event->getResponse()->withStatus(404));

        $match = $event->getRouteMatch();
        if (!$match instanceof RouteMatch) {
            $event->setDispatchResult(
                new JsonModel([
                    'error' => 'Route could not be matched',
                    'path' => $event->getRequest()->getUri()->getPath()
                ])
            );
        }
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onRespond(LifecycleEvent $event)
    {
        $response = $event->getResponse();
        $event->setResponse($response->withHeader('Content-Type', 'application/json'));
    }
}<commit_msg>Moar coverage<commit_after><?php
namespace Tonis\Mvc\Subscriber;

use Interop\Container\ContainerInterface;
use Tonis\Event\EventManager;
use Tonis\Event\SubscriberInterface;
use Tonis\Mvc\LifecycleEvent;
use Tonis\Mvc\Tonis;
use Tonis\Router\RouteMatch;
use Tonis\View\Model\JsonModel;
use Tonis\View\Strategy\JsonStrategy;
use Tonis\View\ViewManager;

final class ApiSubscriber implements SubscriberInterface
{
    /** @var ContainerInterface */
    private $di;

    /**
     * @param ContainerInterface $di
     */
    public function __construct(ContainerInterface $di)
    {
        $this->di = $di;
    }

    /**
     * @param EventManager $events
     * @return void
     */
    public function subscribe(EventManager $events)
    {
        $events->on(Tonis::EVENT_BOOTSTRAP, [$this, 'bootstrapViewManager']);
        $events->on(Tonis::EVENT_ROUTE_ERROR, [$this, 'onRouteError']);
        $events->on(Tonis::EVENT_DISPATCH, [$this, 'onDispatch']);
        $events->on(Tonis::EVENT_DISPATCH_EXCEPTION, [$this, 'onDispatchException']);
        $events->on(Tonis::EVENT_RESPOND, [$this, 'onRespond']);
    }

    public function bootstrapViewManager()
    {
        $vm = $this->di->get(ViewManager::class);
        $vm->addStrategy(new JsonStrategy());
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onDispatch(LifecycleEvent $event)
    {
        $result = $event->getDispatchResult();
        if (is_array($result)) {
            $event->setDispatchResult(new JsonModel($result));
        }
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onDispatchException(LifecycleEvent $event)
    {
        $event->setResponse($event->getResponse()->withStatus(500));

        $model = new JsonModel([
            'error' => 'An error has occurred',
            'exception' => $event->getException()->getMessage(),
            'trace' => $event->getException()->getTrace()
        ]);
        $event->setDispatchResult($model);
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onRouteError(LifecycleEvent $event)
    {
        $event->setResponse($event->getResponse()->withStatus(404));
        $event->setDispatchResult(
            new JsonModel([
                'error' => 'Route could not be matched',
                'path' => $event->getRequest()->getUri()->getPath()
            ])
        );
    }

    /**
     * @param LifecycleEvent $event
     */
    public function onRespond(LifecycleEvent $event)
    {
        $response = $event->getResponse();
        $event->setResponse($response->withHeader('Content-Type', 'application/json'));
    }
}
{'fraction_non_alphanumeric': 0.14786135693215338, 'fraction_numerical': 0.0022123893805309734, 'mean_word_length': 2.6779661016949152, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5087090', 'n_tokens_mistral': 1620, 'n_tokens_neox': 1561, 'n_words': 275}