<commit_before><?php
/**
 * Spiral Framework.
 *
 * @license   MIT
 * @author    <NAME> (Wolfy-J)
 * @copyright ©2009-2015
 */
namespace Spiral\Profiler;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Spiral\Components\Debug\Debugger;
use Spiral\Components\Debug\Logger;
use Spiral\Components\Http\MiddlewareInterface;
use Spiral\Components\Http\Response;
use Spiral\Components\Modules\Definition;
use Spiral\Components\Modules\Installer;
use Spiral\Components\Modules\Module;
use Spiral\Components\View\ConfigWriter\ViewConfig;
use Spiral\Components\View\ViewManager;

class Profiler extends Module implements MiddlewareInterface
{
    /**
     * Constants used to describe benchmark records.
     */
    const BENCHMARK_STARTED        = 0;
    const BENCHMARK_ENDED          = 2;
    const BENCHMARK_MEMORY_STARTED = 1;
    const BENCHMARK_MEMORY_ENDED   = 3;
    /**
     * View component is required for rendering.
     *
     * @var ViewManager
     */
    protected $view = null;

    /**
     * New Profiler module instance.
     *
     * @param ViewManager $view
     */
    public function __construct(ViewManager $view)
    {
        $this->view = $view;
    }

    /**
     * Handle request generate response. Middleware used to alter incoming Request and/or Response
     * generated by inner pipeline layers.
     *
     * @param ServerRequestInterface $request Server request instance.
     * @param \Closure               $next    Next middleware/target.
     * @return ResponseInterface
     */
    public function __invoke(ServerRequestInterface $request, \Closure $next = null)
    {
        if ($request->getAttribute('profiler'))
        {
            //Already handled at top level
            return $next($request);
        }

        $started = microtime(true);
        $response = $next($request->withAttribute('profiler', $started));
        $elapsed = microtime(true) - $started;

        return $this->mount($request, $response, $started, $elapsed);
    }

    /**
     * Mount profiler panel to response.
     *
     * @param ServerRequestInterface   $request Server request instance.
     * @param ResponseInterface|string $response
     * @param float                    $started Time when profiler was activated.
     * @param float                    $elapsed Elapsed time.
     * @return mixed
     */
    protected function mount(
        ServerRequestInterface $request,
        ResponseInterface $response,
        $started = 0.0,
        $elapsed = 0.0
    )
    {
        if ($response->getHeader('Content-Type'))
        {
            //Profiler will not mount it's panel if content type is not empty
            return $response;
        }

        if ($response->getBody()->isWritable())
        {
            $panel = $this->view->render('profiler:panel', array(
                'profiler' => $this,
                'request'  => $request,
                'started'  => $started,
                'elapsed'  => $elapsed
            ));

            $response->getBody()->write($panel);
        }

        return $response;
    }

    /**
     * Get log messages fetched.
     *
     * @return array
     */
    public function logMessages()
    {
        return Logger::logMessages();
    }

    /**
     * Benchmarks will be returned in normalized form.
     *
     * @param float $lastEnding Last found ending.
     * @return array|null
     */
    public function getBenchmarks(&$lastEnding = null)
    {
        $result = array();
        foreach (Debugger::getBenchmarks() as $record => $benchmark)
        {
            if (!isset($benchmark[self::BENCHMARK_ENDED]))
            {
                $benchmark[self::BENCHMARK_ENDED] = microtime(true);
                $benchmark[self::BENCHMARK_MEMORY_ENDED] = memory_get_usage();
            }

            $elapsed = $benchmark[self::BENCHMARK_ENDED] - $benchmark[self::BENCHMARK_STARTED];
            $memory = $benchmark[self::BENCHMARK_MEMORY_ENDED] - $benchmark[self::BENCHMARK_MEMORY_STARTED];

            $name = $record;
            $context = '';
            if (strpos($record, '|') !== false)
            {
                list($name, $context) = explode('|', $record);
            }

            $result[$record] = array(
                'name'    => $name,
                'started' => $benchmark[self::BENCHMARK_STARTED],
                'ended'   => $lastEnding = $benchmark[self::BENCHMARK_ENDED],
                'elapsed' => $elapsed,
                'memory'  => $memory,
                'context' => $context
            );
        }

        return $result;
    }

    /**
     * Format message based on log container name.
     *
     * @param string $container
     * @param string $message
     * @param array  $context
     * @return string
     */
    public function formatMessage($container, $message, $context)
    {
        \SqlFormatter::$pre_attributes = '';
        if (strpos($container, 'Spiral\Components\DBAL\Drivers') === 0 && isset($context['query']))
        {
            //SQL queries from drivers
            return trim(substr(\SqlFormatter::highlight($message), 6, -6));
        }

        return $message;
    }

    /**
     * Module installer responsible for operations like copying resources, registering configs, view
     * namespaces and declaring that bootstrap() call is required.
     * This method is static as it should be called without constructing module object.
     *
     * @param Definition $definition Module definition fetched or generated of composer file.
     * @return Installer
     */
    public static function getInstaller(Definition $definition)
    {
        $installer = parent::getInstaller($definition);

        //Registering view namespace
        $installer->registerConfig(ViewConfig::make(array(
            'baseDirectory' => $definition->getLocation()
        ))->registerNamespace('profiler', 'views'));

        //Public resources
        $installer->registerDirectory('/', 'public');

        return $installer;
    }
}<commit_msg>public resources.<commit_after><?php
/**
 * Spiral Framework.
 *
 * @license   MIT
 * @author    <NAME> (Wolfy-J)
 * @copyright ©2009-2015
 */
namespace Spiral\Profiler;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Spiral\Components\Debug\Debugger;
use Spiral\Components\Debug\Logger;
use Spiral\Components\Http\MiddlewareInterface;
use Spiral\Components\Http\Response;
use Spiral\Components\Modules\Definition;
use Spiral\Components\Modules\Installer;
use Spiral\Components\Modules\Module;
use Spiral\Components\View\ConfigWriter\ViewConfig;
use Spiral\Components\View\ViewManager;

class Profiler extends Module implements MiddlewareInterface
{
    /**
     * Constants used to describe benchmark records.
     */
    const BENCHMARK_STARTED        = 0;
    const BENCHMARK_ENDED          = 2;
    const BENCHMARK_MEMORY_STARTED = 1;
    const BENCHMARK_MEMORY_ENDED   = 3;
    /**
     * View component is required for rendering.
     *
     * @var ViewManager
     */
    protected $view = null;

    /**
     * New Profiler module instance.
     *
     * @param ViewManager $view
     */
    public function __construct(ViewManager $view)
    {
        $this->view = $view;
    }

    /**
     * Handle request generate response. Middleware used to alter incoming Request and/or Response
     * generated by inner pipeline layers.
     *
     * @param ServerRequestInterface $request Server request instance.
     * @param \Closure               $next    Next middleware/target.
     * @return ResponseInterface
     */
    public function __invoke(ServerRequestInterface $request, \Closure $next = null)
    {
        if ($request->getAttribute('profiler'))
        {
            //Already handled at top level
            return $next($request);
        }

        $started = microtime(true);
        $response = $next($request->withAttribute('profiler', $started));
        $elapsed = microtime(true) - $started;

        return $this->mount($request, $response, $started, $elapsed);
    }

    /**
     * Mount profiler panel to response.
     *
     * @param ServerRequestInterface   $request Server request instance.
     * @param ResponseInterface|string $response
     * @param float                    $started Time when profiler was activated.
     * @param float                    $elapsed Elapsed time.
     * @return mixed
     */
    protected function mount(
        ServerRequestInterface $request,
        ResponseInterface $response,
        $started = 0.0,
        $elapsed = 0.0
    )
    {
        if ($response->getHeader('Content-Type'))
        {
            //Profiler will not mount it's panel if content type is not empty
            return $response;
        }

        if ($response->getBody()->isWritable())
        {
            $panel = $this->view->render('profiler:panel', array(
                'profiler' => $this,
                'request'  => $request,
                'started'  => $started,
                'elapsed'  => $elapsed
            ));

            $response->getBody()->write($panel);
        }

        return $response;
    }

    /**
     * Get log messages fetched.
     *
     * @return array
     */
    public function logMessages()
    {
        return Logger::logMessages();
    }

    /**
     * Benchmarks will be returned in normalized form.
     *
     * @param float $lastEnding Last found ending.
     * @return array|null
     */
    public function getBenchmarks(&$lastEnding = null)
    {
        $result = array();
        foreach (Debugger::getBenchmarks() as $record => $benchmark)
        {
            if (!isset($benchmark[self::BENCHMARK_ENDED]))
            {
                $benchmark[self::BENCHMARK_ENDED] = microtime(true);
                $benchmark[self::BENCHMARK_MEMORY_ENDED] = memory_get_usage();
            }

            $elapsed = $benchmark[self::BENCHMARK_ENDED] - $benchmark[self::BENCHMARK_STARTED];
            $memory = $benchmark[self::BENCHMARK_MEMORY_ENDED] - $benchmark[self::BENCHMARK_MEMORY_STARTED];

            $name = $record;
            $context = '';
            if (strpos($record, '|') !== false)
            {
                list($name, $context) = explode('|', $record);
            }

            $result[$record] = array(
                'name'    => $name,
                'started' => $benchmark[self::BENCHMARK_STARTED],
                'ended'   => $lastEnding = $benchmark[self::BENCHMARK_ENDED],
                'elapsed' => $elapsed,
                'memory'  => $memory,
                'context' => $context
            );
        }

        return $result;
    }

    /**
     * Format message based on log container name.
     *
     * @param string $container
     * @param string $message
     * @param array  $context
     * @return string
     */
    public function formatMessage($container, $message, $context)
    {
        \SqlFormatter::$pre_attributes = '';
        if (strpos($container, 'Spiral\Components\DBAL\Drivers') === 0 && isset($context['query']))
        {
            //SQL queries from drivers
            return trim(substr(\SqlFormatter::highlight($message), 6, -6));
        }

        return $message;
    }

    /**
     * Module installer responsible for operations like copying resources, registering configs, view
     * namespaces and declaring that bootstrap() call is required.
     * This method is static as it should be called without constructing module object.
     *
     * @param Definition $definition Module definition fetched or generated of composer file.
     * @return Installer
     */
    public static function getInstaller(Definition $definition)
    {
        $installer = parent::getInstaller($definition);

        //Registering view namespace
        $installer->registerConfig(ViewConfig::make(array(
            'baseDirectory' => $definition->getLocation()
        ))->registerNamespace('profiler', 'views'));

        //Public resources
        $installer->registerDirectory('/', '../public');

        return $installer;
    }
}
{'fraction_non_alphanumeric': 0.11690988539863138, 'fraction_numerical': 0.0031329870558166376, 'mean_word_length': 2.145746887966805, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 59, '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': '2087464', 'n_tokens_mistral': 3406, 'n_tokens_neox': 3306, 'n_words': 789}