<commit_before><?php
namespace watoki\curir\responder;

use watoki\curir\http\error\HttpError;
use watoki\curir\http\MimeTypes;
use watoki\curir\http\Request;
use watoki\curir\http\Response;
use watoki\curir\Resource;
use watoki\curir\resource\DynamicResource;
use watoki\curir\Responder;

class Presenter extends Responder {

    /** @var mixed */
    private $model;

    /** @var DynamicResource */
    private $resource;

    function __construct(DynamicResource $resource, $viewModel = array()) {
        $this->resource = $resource;
        $this->model = $viewModel;
    }

    /**
     * @param \watoki\curir\http\Request $request
     * @throws \watoki\curir\http\error\HttpError
     * @return \watoki\curir\http\Response
     */
    public function createResponse(Request $request) {
        $formats = $request->getFormats();

        foreach ($formats as $format) {
            try {
                $response = new Response($this->render($format));
                $response->getHeaders()->set(Response::HEADER_CONTENT_TYPE, MimeTypes::getType($format));
                return $response;
            } catch (\Exception $e) {}
        }

        throw new HttpError(Response::STATUS_NOT_ACCEPTABLE, "Could not render the resource in an accepted format",
            "Invalid accepted types for [" . get_class($this->resource) . "] aka [" . $this->resource->getUrl() . "]: " .
            "[" . implode(', ', $formats) . "]");
    }

    private function render($format) {
        $method = new \ReflectionMethod($this, 'render' . ucfirst($format));

        if (count($method->getParameters())) {
            return $method->invoke($this, $this->getTemplate($format));
        } else {
            return $method->invoke($this);
        }
    }

    /**
     * @return mixed
     */
    public function getModel() {
        return $this->model;
    }

    private function getTemplate($format) {
        $templateFile = $this->findFile($this->resource->getResourceDirectory(), $this->resource->getResourceName() . '.' . $format);

        if (!$templateFile) {
            throw new \Exception("Could not find template [$templateFile]");
        }
        return file_get_contents($templateFile);
    }

    protected function findFile($directory, $fileName) {
        foreach (glob($directory . DIRECTORY_SEPARATOR . '*') as $file) {
            if (strtolower(basename($file)) == strtolower($fileName)) {
                return $file;
            }
        }
        return null;
    }
}<commit_msg>Added custom renderers to Presenter<commit_after><?php
namespace watoki\curir\responder;

use watoki\curir\http\error\HttpError;
use watoki\curir\http\MimeTypes;
use watoki\curir\http\Request;
use watoki\curir\http\Response;
use watoki\curir\Resource;
use watoki\curir\resource\DynamicResource;
use watoki\curir\Responder;

abstract class Presenter extends Responder {

    /** @var mixed */
    private $model;

    /** @var DynamicResource */
    private $resource;

    /** @var array|callable[] indexed by format */
    private $renderers = array();

    function __construct(DynamicResource $resource, $viewModel = array()) {
        $this->resource = $resource;
        $this->model = $viewModel;
    }

    public function setRenderer($formats, $renderer) {
        if (!is_array($formats)) {
            $formats = array($formats);
        }
        foreach ($formats as $format) {
            $this->renderers[$format] = $renderer;
        }
    }

    /**
     * @param \watoki\curir\http\Request $request
     * @throws \watoki\curir\http\error\HttpError
     * @return \watoki\curir\http\Response
     */
    public function createResponse(Request $request) {
        $formats = $request->getFormats();

        foreach ($formats as $format) {
            try {
                $response = new Response($this->render($format));
                $response->getHeaders()->set(Response::HEADER_CONTENT_TYPE, MimeTypes::getType($format));
                return $response;
            } catch (\ReflectionException $e) {}
        }

        throw new HttpError(Response::STATUS_NOT_ACCEPTABLE, "Could not render the resource in an accepted format",
            "Invalid accepted types for [" . get_class($this->resource) . "] aka [" . $this->resource->getUrl() . "]: " .
            "[" . implode(', ', $formats) . "]");
    }

    private function render($format) {
        if (array_key_exists($format, $this->renderers)) {
            $renderer = $this->renderers[$format];
            return $renderer($this);
        }

        $method = new \ReflectionMethod($this, 'render' . ucfirst($format));

        if (count($method->getParameters())) {
            return $method->invoke($this, $this->getTemplate($format));
        } else {
            return $method->invoke($this);
        }
    }

    /**
     * @return mixed
     */
    public function getModel() {
        return $this->model;
    }

    public function getTemplate($format) {
        $fileName = $this->resource->getResourceName() . '.' . $format;
        $templateFile = $this->findFile($this->resource->getResourceDirectory(), $fileName);

        if (!$templateFile) {
            throw new \Exception("Could not find template [$fileName]");
        }
        return file_get_contents($templateFile);
    }

    protected function findFile($directory, $fileName) {
        foreach (glob($directory . DIRECTORY_SEPARATOR . '*') as $file) {
            if (strtolower(basename($file)) == strtolower($fileName)) {
                return $file;
            }
        }
        return null;
    }
}
{'fraction_non_alphanumeric': 0.14576998747987838, 'fraction_numerical': 0.0, 'mean_word_length': 2.4348894348894348, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 44, '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': '2753068', 'n_tokens_mistral': 1621, 'n_tokens_neox': 1579, 'n_words': 324}