Seditio Source
Root |
./othercms/phpBB3/vendor/s9e/text-formatter/src/Configurator/JavaScript/Minifiers/ClosureCompilerService.php
<?php

/**
* @package   s9e\TextFormatter
* @copyright Copyright (c) 2010-2021 The s9e authors
* @license   http://www.opensource.org/licenses/mit-license.php The MIT License
*/
namespace s9e\TextFormatter\Configurator\JavaScript\Minifiers;

use
RuntimeException;
use
s9e\TextFormatter\Configurator\JavaScript\OnlineMinifier;

class
ClosureCompilerService extends OnlineMinifier
{
   
/**
    * @var string Closure Compiler's compilation level
    */
   
public $compilationLevel = 'ADVANCED_OPTIMIZATIONS';

   
/**
    * @var bool Whether to exclude Closure Compiler's default externs
    */
   
public $excludeDefaultExterns = true;

   
/**
    * @var string Externs used for compilation
    */
   
public $externs;

   
/**
    * @var string Closure Compiler Service's URL
    */
   
public $url = 'https://closure-compiler.appspot.com/compile';

   
/**
    * Constructor
    */
   
public function __construct()
    {
       
parent::__construct();
       
$this->externs = file_get_contents(__DIR__ . '/../externs.service.js');
    }

   
/**
    * {@inheritdoc}
    */
   
public function getCacheDifferentiator()
    {
       
$key = [$this->compilationLevel, $this->excludeDefaultExterns];

        if (
$this->excludeDefaultExterns)
        {
           
$key[] = $this->externs;
        }

        return
$key;
    }

   
/**
    * Compile given JavaScript source via the Closure Compiler Service
    *
    * @param  string $src JavaScript source
    * @return string      Compiled source
    */
   
public function minify($src)
    {
       
$body     = $this->generateRequestBody($src);
       
$response = $this->query($body);
        if (
$response === false)
        {
            throw new
RuntimeException('Could not contact the Closure Compiler service');
        }

        return
$this->decodeResponse($response);
    }

   
/**
    * Decode the response returned by the Closure Compiler service
    *
    * @param  string $response Response body
    * @return string           Minified code
    */
   
protected function decodeResponse($response)
    {
       
$response = json_decode($response, true);
        if (
is_null($response))
        {
            throw new
RuntimeException('Closure Compiler service returned invalid JSON: ' . json_last_error_msg());
        }

        if (isset(
$response['serverErrors'][0]))
        {
           
$error = $response['serverErrors'][0];

            throw new
RuntimeException('Server error ' . $error['code'] . ': ' . $error['error']);
        }

        if (isset(
$response['errors'][0]))
        {
           
$error = $response['errors'][0];

            throw new
RuntimeException('Compilation error: ' . $error['error']);
        }

        return
$response['compiledCode'];
    }

   
/**
    * Generate the request body for given code
    *
    * @param  string $src JavaScript source
    * @return string      Compiled source
    */
   
protected function generateRequestBody($src)
    {
       
$params = [
           
'compilation_level' => $this->compilationLevel,
           
'js_code'           => $src,
           
'output_format'     => 'json',
           
'output_info'       => 'compiled_code'
       
];

       
// Add our custom externs if default externs are disabled
       
if ($this->excludeDefaultExterns && $this->compilationLevel === 'ADVANCED_OPTIMIZATIONS')
        {
           
$params['exclude_default_externs'] = 'true';
           
$params['js_externs'] = $this->externs;
        }

       
// Add dupe variables by hand
       
$body = http_build_query($params) . '&output_info=errors';

        return
$body;
    }

   
/**
    * Query the Closure Compiler service
    *
    * @param  string       $body Request body
    * @return string|false       Response body, or FALSE
    */
   
protected function query($body)
    {
        return
$this->httpClient->post(
           
$this->url,
            [
'headers' => ['Content-Type: application/x-www-form-urlencoded']],
           
$body
       
);
    }
}