Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/cakephp/debug_kit/src/ToolbarService.php
<?php
/**
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace DebugKit;

use
Cake\Core\Configure;
use
Cake\Core\InstanceConfigTrait;
use
Cake\Core\Plugin as CorePlugin;
use
Cake\Event\Event;
use
Cake\Event\EventManager;
use
Cake\Http\Response;
use
Cake\Http\ServerRequest;
use
Cake\Log\Log;
use
Cake\ORM\TableRegistry;
use
Cake\Routing\Router;
use
DebugKit\Panel\PanelRegistry;
use
Psr\Http\Message\ResponseInterface;

/**
 * Used to create the panels and inject a toolbar into
 * matching responses.
 *
 * Used by the Routing Filter and Middleware.
 */
class ToolbarService
{
    use
InstanceConfigTrait;

   
/**
     * The panel registry.
     *
     * @var \DebugKit\Panel\PanelRegistry
     */
   
protected $registry;

   
/**
     * Default configuration.
     *
     * @var array
     */
   
protected $_defaultConfig = [
       
'panels' => [
           
'DebugKit.Cache' => true,
           
'DebugKit.Session' => true,
           
'DebugKit.Request' => true,
           
'DebugKit.SqlLog' => true,
           
'DebugKit.Timer' => true,
           
'DebugKit.Log' => true,
           
'DebugKit.Variables' => true,
           
'DebugKit.Environment' => true,
           
'DebugKit.Include' => true,
           
'DebugKit.History' => true,
           
'DebugKit.Routes' => true,
           
'DebugKit.Packages' => true,
           
'DebugKit.Mail' => true,
           
'DebugKit.Deprecations' => true,
        ],
       
'forceEnable' => false,
       
'safeTld' => [],
    ];

   
/**
     * Constructor
     *
     * @param \Cake\Event\EventManager $events The event manager to use defaults to the global manager
     * @param array $config The configuration data for DebugKit.
     */
   
public function __construct(EventManager $events, array $config)
    {
       
$this->setConfig($config);
       
$this->registry = new PanelRegistry($events);
    }

   
/**
     * Fetch the PanelRegistry
     *
     * @return \DebugKit\Panel\PanelRegistry
     */
   
public function registry()
    {
        return
$this->registry;
    }

   
/**
     * Check whether or not debug kit is enabled.
     *
     * @return bool
     */
   
public function isEnabled()
    {
       
$enabled = (bool)Configure::read('debug');

        if (
$enabled && !$this->isSuspiciouslyProduction()) {
            return
true;
        }
       
$force = $this->getConfig('forceEnable');
        if (
is_callable($force)) {
            return
$force();
        }

        return
$force;
    }

   
/**
     * Returns true if this applications is being executed on a domain with a TLD
     * that is commonly associated with a production environment.
     *
     * @return bool
     */
   
protected function isSuspiciouslyProduction()
    {
       
$host = explode('.', parse_url('http://' . env('HTTP_HOST'), PHP_URL_HOST));
       
$first = current($host);
       
$isIP = is_numeric(implode('', $host));

        if (
count($host) === 1) {
            return
false;
        }

        if (
$isIP && in_array($first, ['192', '10', '127'])) {
           
// Accessing the app by private IP, this is safe
           
return false;
        }

       
$tld = end($host);
       
$safeTopLevelDomains = ['localhost', 'invalid', 'test', 'example', 'local'];
       
$safeTopLevelDomains = array_merge($safeTopLevelDomains, (array)$this->getConfig('safeTld'));

        if (!
in_array($tld, $safeTopLevelDomains, true) && !$this->getConfig('forceEnable')) {
           
$host = implode('.', $host);
           
$safeList = implode(', ', $safeTopLevelDomains);
           
Log::warning(
               
"DebugKit is disabling itself as your host `{$host}` " .
               
"is not in the known safe list of top-level-domains ({$safeList}). " .
               
"If you would like to force DebugKit on use the `DebugKit.forceEnable` Configure option."
           
);

            return
true;
        }

        return
false;
    }

   
/**
     * Get the list of loaded panels
     *
     * @return array
     */
   
public function loadedPanels()
    {
        return
$this->registry->loaded();
    }

   
/**
     * Get the a loaded panel
     *
     * @param string $name The name of the panel you want to get.
     * @return \DebugKit\DebugPanel|null The panel or null.
     */
   
public function panel($name)
    {
        return
$this->registry->{$name};
    }

   
/**
     * Load all the panels being used
     *
     * @return void
     */
   
public function loadPanels()
    {
        foreach (
$this->getConfig('panels') as $panel => $enabled) {
            list(
$panel, $enabled) = (is_numeric($panel)) ? [$enabled, true] : [$panel, $enabled];
            if (
$enabled) {
               
$this->registry->load($panel);
            }
        }
    }

   
/**
     * Call the initialize method onl all the loaded panels.
     *
     * @return void
     */
   
public function initializePanels()
    {
        foreach (
$this->registry->loaded() as $panel) {
           
$this->registry->{$panel}->initialize();
        }
    }

   
/**
     * Save the toolbar state.
     *
     * @param \Cake\Http\ServerRequest $request The request
     * @param \Psr\Http\Message\ResponseInterface $response The response
     * @return null|\DebugKit\Model\Entity\Request Saved request data.
     */
   
public function saveData(ServerRequest $request, ResponseInterface $response)
    {
       
// Skip debugkit requests and requestAction()
       
$path = $request->getUri()->getPath();
        if (
           
strpos($path, 'debug_kit') !== false ||
           
strpos($path, 'debug-kit') !== false ||
           
$request->is('requested')
        ) {
            return
null;
        }
       
$data = [
           
'url' => $request->getUri()->getPath(),
           
'content_type' => $response->getHeaderLine('Content-Type'),
           
'method' => $request->getMethod(),
           
'status_code' => $response->getStatusCode(),
           
'requested_at' => $request->getEnv('REQUEST_TIME'),
           
'panels' => [],
        ];
       
/* @var \DebugKit\Model\Table\RequestsTable $requests */
       
$requests = TableRegistry::get('DebugKit.Requests');
       
$requests->gc();

       
$row = $requests->newEntity($data);
       
$row->isNew(true);

        foreach (
$this->registry->loaded() as $name) {
           
$panel = $this->registry->{$name};
            try {
               
$content = serialize($panel->data());
            } catch (\
Exception $e) {
               
$content = serialize([
                   
'error' => $e->getMessage(),
                ]);
            }
           
$row->panels[] = $requests->Panels->newEntity([
               
'panel' => $name,
               
'element' => $panel->elementName(),
               
'title' => $panel->title(),
               
'summary' => $panel->summary(),
               
'content' => $content,
            ]);
        }

        return
$requests->save($row);
    }

   
/**
     * Reads the modified date of a file in the webroot, and returns the integer
     *
     * @return string
     */
   
public function getToolbarUrl()
    {
       
$url = 'js/toolbar.js';
       
$filePaths = [
           
str_replace('/', DIRECTORY_SEPARATOR, WWW_ROOT . 'debug_kit/' . $url),
           
str_replace('/', DIRECTORY_SEPARATOR, CorePlugin::path('DebugKit') . 'webroot/' . $url),
        ];
       
$url = '/debug_kit/' . $url;
        foreach (
$filePaths as $filePath) {
            if (
file_exists($filePath)) {
                return
$url . '?' . filemtime($filePath);
            }
        }

        return
$url;
    }

   
/**
     * Injects the JS to build the toolbar.
     *
     * The toolbar will only be injected if the response's content type
     * contains HTML and there is a </body> tag.
     *
     * @param \DebugKit\Model\Entity\Request $row The request data to inject.
     * @param \Psr\Http\Message\ResponseInterface $response The response to augment.
     * @return \Psr\Http\Message\ResponseInterface The modified response
     */
   
public function injectScripts($row, ResponseInterface $response)
    {
       
$response = $response->withHeader('X-DEBUGKIT-ID', $row->id);
        if (
strpos($response->getHeaderLine('Content-Type'), 'html') === false) {
            return
$response;
        }
       
$body = $response->getBody();
        if (!
$body->isSeekable() || !$body->isWritable()) {
            return
$response;
        }
       
$body->rewind();
       
$contents = $body->getContents();

       
$pos = strrpos($contents, '</body>');
        if (
$pos === false) {
            return
$response;
        }

       
$url = Router::url('/', true);
       
$script = sprintf(
           
'<script id="__debug_kit" data-id="%s" data-url="%s" src="%s"></script>',
           
$row->id,
           
$url,
           
Router::url($this->getToolbarUrl())
        );
       
$contents = substr($contents, 0, $pos) . $script . substr($contents, $pos);
       
$body->rewind();
       
$body->write($contents);

        return
$response->withBody($body);
    }
}