%PDF- %PDF-
Direktori : /proc/self/root/var/www/projetos/stb.ind.br/wp-content/plugins/webp-express/lib/classes/ |
Current File : //proc/self/root/var/www/projetos/stb.ind.br/wp-content/plugins/webp-express/lib/classes/Config.php |
<?php namespace WebPExpress; class Config { /** * @return object|false Returns config object if config file exists and can be read. Otherwise it returns false */ public static function loadConfig() { return FileHelper::loadJSONOptions(Paths::getConfigFileName()); } public static function getDefaultConfig($skipQualityAuto = false) { if ($skipQualityAuto) { $qualityAuto = null; } else { $qualityAuto = TestRun::isLocalQualityDetectionWorking(); } return [ 'operation-mode' => 'varied-image-responses', // general 'image-types' => 3, 'destination-folder' => 'separate', 'destination-extension' => 'append', 'destination-structure' => (PlatformInfo::isNginx() ? 'doc-root' : 'image-roots'), 'cache-control' => 'no-header', /* can be "no-header", "set" or "custom" */ 'cache-control-custom' => 'public, max-age=31536000, stale-while-revalidate=604800, stale-if-error=604800', 'cache-control-max-age' => 'one-week', 'cache-control-public' => false, 'scope' => ['themes', 'uploads'], // redirection rules 'enable-redirection-to-converter' => true, 'only-redirect-to-converter-on-cache-miss' => false, 'only-redirect-to-converter-for-webp-enabled-browsers' => true, 'do-not-pass-source-in-query-string' => false, // In 0.13 we can remove this. migration7.php depends on it 'redirect-to-existing-in-htaccess' => true, 'forward-query-string' => false, 'enable-redirection-to-webp-realizer' => true, // conversion options 'jpeg-encoding' => 'auto', 'jpeg-enable-near-lossless' => true, 'jpeg-near-lossless' => 60, 'quality-auto' => $qualityAuto, 'max-quality' => 80, 'quality-specific' => 70, 'png-encoding' => 'auto', 'png-enable-near-lossless' => true, 'png-near-lossless' => 60, 'png-quality' => 85, 'alpha-quality' => 80, 'converters' => [], 'metadata' => 'none', //'log-call-arguments' => true, 'convert-on-upload' => false, // serve options 'fail' => 'original', 'success-response' => 'converted', // alter html options 'alter-html' => [ 'enabled' => false, 'replacement' => 'picture', // "picture" or "url" 'hooks' => 'ob', // "content-hooks" or "ob" 'only-for-webp-enabled-browsers' => true, // If true, there will be two HTML versions of each page 'only-for-webps-that-exists' => false, 'alter-html-add-picturefill-js' => true, 'hostname-aliases' => [] ], // web service 'web-service' => [ 'enabled' => false, 'whitelist' => [ /*[ 'uid' => '', // for internal purposes 'label' => '', // ie website name. It is just for display 'ip' => '', // restrict to these ips. * pattern is allowed. 'api-key' => '', // Api key for the entry. Not neccessarily unique for the entry //'quota' => 60 ] */ ] ], 'environment-when-config-was-saved' => [ 'doc-root-available' => null, // null means unavailable 'doc-root-resolvable' => null, 'doc-root-usable-for-structuring' => null, 'image-roots' => null, ] ]; } /** * Apply operation mode (set the hidden defaults that comes along with the mode) * @return An altered configuration array */ public static function applyOperationMode($config) { if (!isset($config['operation-mode'])) { $config['operation-mode'] = 'varied-image-responses'; } if ($config['operation-mode'] == 'varied-image-responses') { $config = array_merge($config, [ //'redirect-to-existing-in-htaccess' => true, // this can now be configured, so do not apply //'enable-redirection-to-converter' => true, // this can now be configured, so do not apply 'only-redirect-to-converter-for-webp-enabled-browsers' => true, 'only-redirect-to-converter-on-cache-miss' => false, 'do-not-pass-source-in-query-string' => true, // Will be removed in 0.13 'fail' => 'original', 'success-response' => 'converted', ]); } elseif ($config['operation-mode'] == 'cdn-friendly') { $config = array_merge($config, [ 'redirect-to-existing-in-htaccess' => false, 'enable-redirection-to-converter' => false, /* 'only-redirect-to-converter-for-webp-enabled-browsers' => false, 'only-redirect-to-converter-on-cache-miss' => true, */ 'do-not-pass-source-in-query-string' => true, // Will be removed in 0.13 'fail' => 'original', 'success-response' => 'original', // cache-control => 'no-header' (we do not need this, as it is not important what it is set to in cdn-friendly mode, and we dont the value to be lost when switching operation mode) ]); } elseif ($config['operation-mode'] == 'no-conversion') { // TODO: Go through these... $config = array_merge($config, [ 'enable-redirection-to-converter' => false, 'destination-folder' => 'mingled', 'enable-redirection-to-webp-realizer' => false, ]); $config['alter-html']['only-for-webps-that-exists'] = true; $config['web-service']['enabled'] = false; $config['scope'] = ['uploads']; } return $config; } public static function fix($config, $checkQualityDetection = true) { if ($config === false) { $config = self::getDefaultConfig(!$checkQualityDetection); } else { if ($checkQualityDetection) { if (isset($config['quality-auto']) && ($config['quality-auto'])) { $qualityDetectionWorking = TestRun::isLocalQualityDetectionWorking(); if (!TestRun::isLocalQualityDetectionWorking()) { $config['quality-auto'] = false; } } } $defaultConfig = self::getDefaultConfig(true); $config = array_merge($defaultConfig, $config); // Make sure new defaults below "alter-html" are added into the existing array // (note that this will not remove old unused properties, if some key should become obsolete) $config['alter-html'] = array_replace_recursive($defaultConfig['alter-html'], $config['alter-html']); // Make sure new defaults below "environment-when-config-was-saved" are added into the existing array $config['environment-when-config-was-saved'] = array_replace_recursive($defaultConfig['environment-when-config-was-saved'], $config['environment-when-config-was-saved']); } if (!isset($config['base-htaccess-on-these-capability-tests'])) { self::runAndStoreCapabilityTests($config); } // Apparently, migrate7 did not fix old "operation-mode" values for all. // So fix here if ($config['operation-mode'] == 'just-redirect') { $config['operation-mode'] = 'no-conversion'; } if ($config['operation-mode'] == 'no-varied-responses') { $config['operation-mode'] = 'cdn-friendly'; } if ($config['operation-mode'] == 'varied-responses') { $config['operation-mode'] = 'varied-image-responses'; } // In case doc root no longer can be used, use image-roots // Or? No, changing here will not fix it for WebPOnDemand.php. // An invalid setting requires that config is saved again and .htaccess files regenerated. /* if (($config['operation-mode'] == 'doc-root') && (!Paths::canUseDocRootForRelPaths())) { $config['destination-structure'] = 'image-roots'; }*/ $config = self::applyOperationMode($config); // Fix scope: Remove invalid and put in correct order $fixedScope = []; foreach (Paths::getImageRootIds() as $rootId) { if (in_array($rootId, $config['scope'])) { $fixedScope[] = $rootId; } } $config['scope'] = $fixedScope; if (!isset($config['web-service'])) { $config['web-service'] = [ 'enabled' => false ]; } if (!is_array($config['web-service']['whitelist'])) { $config['web-service']['whitelist'] = []; } // remove whitelist entries without required fields (label, ip) $config['web-service']['whitelist'] = array_filter($config['web-service']['whitelist'], function($var) { return (isset($var['label']) && (isset($var['ip']))); }); if (($config['cache-control'] == 'set') && ($config['cache-control-max-age'] == '')) { $config['cache-control-max-age'] = 'one-week'; } /*if (is_null($config['alter-html']['hostname-aliases'])) { $config['alter-html']['hostname-aliases'] = []; }*/ if (!is_array($config['converters'])) { $config['converters'] = []; } if (count($config['converters']) > 0) { // merge missing converters in $config['converters'] = ConvertersHelper::mergeConverters( $config['converters'], ConvertersHelper::$defaultConverters ); } else { // This is first time visit! $config['converters'] = ConvertersHelper::$defaultConverters; } return $config; } public static function runAndStoreCapabilityTests(&$config) { $config['base-htaccess-on-these-capability-tests'] = [ 'passThroughHeaderWorking' => HTAccessCapabilityTestRunner::passThroughHeaderWorking(), 'passThroughEnvWorking' => HTAccessCapabilityTestRunner::passThroughEnvWorking(), 'modHeaderWorking' => HTAccessCapabilityTestRunner::modHeaderWorking(), //'grantAllAllowed' => HTAccessCapabilityTestRunner::grantAllAllowed(), 'canRunTestScriptInWOD' => HTAccessCapabilityTestRunner::canRunTestScriptInWOD(), 'canRunTestScriptInWOD2' => HTAccessCapabilityTestRunner::canRunTestScriptInWOD2(), ]; } /** * Loads Config (if available), fills in the rest with defaults * also applies operation mode. * If config is not saved yet, the default config will be returned */ public static function loadConfigAndFix($checkQualityDetection = true) { // PS: Yes, loadConfig may return false. "fix" handles this by returning default config return self::fix(Config::loadConfig(), $checkQualityDetection); } /** * Run a fresh test on all converters and update their statuses in the config. * * @param object config to be updated * @return object Updated config */ public static function updateConverterStatusWithFreshTest($config) { // Test converters $testResult = TestRun::getConverterStatus(); // Set "working" and "error" properties if ($testResult) { foreach ($config['converters'] as &$converter) { $converterId = $converter['converter']; $hasError = isset($testResult['errors'][$converterId]); $working = !$hasError; /* Don't print this stuff here. It can end up in the head tag. TODO: Move it somewhere if (isset($converter['working']) && ($converter['working'] != $working)) { // TODO: webpexpress_converterName($converterId) if ($working) { Messenger::printMessage( 'info', 'Hurray! - The <i>' . $converterId . '</i> conversion method is working now!' ); } else { Messenger::printMessage( 'warning', 'Sad news. The <i>' . $converterId . '</i> conversion method is not working anymore. What happened?' ); } } */ $converter['working'] = $working; if ($hasError) { $error = $testResult['errors'][$converterId]; if ($converterId == 'wpc') { if (preg_match('/Missing URL/', $error)) { $error = 'Not configured'; } if ($error == 'No remote host has been set up') { $error = 'Not configured'; } if (preg_match('/cloud service is not enabled/', $error)) { $error = 'The server is not enabled. Click the "Enable web service" on WebP Express settings on the site you are trying to connect to.'; } } $converter['error'] = $error; } else { unset($converter['error']); } } } return $config; } public static $configForOptionsPage = null; // cache the result (called twice, - also in enqueue_scripts) public static function getConfigForOptionsPage() { if (isset(self::$configForOptionsPage)) { return self::$configForOptionsPage; } $config = self::loadConfigAndFix(); // Remove keys in whitelist (so they cannot easily be picked up by examining the html) foreach ($config['web-service']['whitelist'] as &$whitelistEntry) { unset($whitelistEntry['api-key']); } // Remove keys from WPC converters foreach ($config['converters'] as &$converter) { if (isset($converter['converter']) && ($converter['converter'] == 'wpc')) { if (isset($converter['options']['api-key'])) { if ($converter['options']['api-key'] != '') { $converter['options']['_api-key-non-empty'] = true; } unset($converter['options']['api-key']); } } } if ($config['operation-mode'] != 'no-conversion') { $config = self::updateConverterStatusWithFreshTest($config); } self::$configForOptionsPage = $config; // cache the result return $config; } public static function isConfigFileThere() { return (FileHelper::fileExists(Paths::getConfigFileName())); } public static function isConfigFileThereAndOk() { return (self::loadConfig() !== false); } public static function loadWodOptions() { return FileHelper::loadJSONOptions(Paths::getWodOptionsFileName()); } /** * Some of the options in config needs to be quickly accessible * These are stored in wordpress autoloaded options */ public static function updateAutoloadedOptions($config) { $config = self::fix($config, false); Option::updateOption('webp-express-alter-html', $config['alter-html']['enabled'], true); Option::updateOption('webp-express-alter-html-hooks', $config['alter-html']['hooks'], true); Option::updateOption('webp-express-alter-html-replacement', $config['alter-html']['replacement'], true); Option::updateOption('webp-express-alter-html-add-picturefill-js', (($config['alter-html']['replacement'] == 'picture') && (isset($config['alter-html']['alter-html-add-picturefill-js']) && $config['alter-html']['alter-html-add-picturefill-js'])), true); //Option::updateOption('webp-express-alter-html', $config['alter-html']['enabled'], true); $obj = $config['alter-html']; unset($obj['enabled']); $obj['destination-folder'] = $config['destination-folder']; $obj['destination-extension'] = $config['destination-extension']; $obj['destination-structure'] = $config['destination-structure']; $obj['scope'] = $config['scope']; $obj['image-types'] = $config['image-types']; // 0=none,1=jpg, 2=png, 3=both Option::updateOption( 'webp-express-alter-html-options', json_encode($obj, JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK), true ); } public static function saveConfigurationFile($config) { $config['paths-used-in-htaccess'] = [ 'wod-url-path' => Paths::getWodUrlPath(), ]; if (Paths::createConfigDirIfMissing()) { $success = FileHelper::saveJSONOptions(Paths::getConfigFileName(), $config); if ($success) { State::setState('configured', true); self::updateAutoloadedOptions($config); } return $success; } return false; } public static function getCacheControlHeader($config) { $cacheControl = $config['cache-control']; switch ($cacheControl) { case 'custom': return $config['cache-control-custom']; case 'no-header': return ''; default: $public = (isset($config['cache-control-public']) ? $config['cache-control-public'] : true); $maxAge = (isset($config['cache-control-max-age']) ? $config['cache-control-max-age'] : $cacheControl); $maxAgeOptions = [ '' => 'max-age=604800', // it has happened, but I don't think it can happen again... 'one-second' => 'max-age=1', 'one-minute' => 'max-age=60', 'one-hour' => 'max-age=3600', 'one-day' => 'max-age=86400', 'one-week' => 'max-age=604800', 'one-month' => 'max-age=2592000', 'one-year' => 'max-age=31536000', ]; return ($public ? 'public, ' : 'private, ') . $maxAgeOptions[$maxAge]; } } public static function generateWodOptionsFromConfigObj($config) { // WebP convert options // -------------------- $wc = [ 'converters' => [] ]; // Add active converters foreach ($config['converters'] as $converter) { if (isset($converter['deactivated']) && ($converter['deactivated'])) { continue; } $wc['converters'][] = $converter; } // Clean the converter options from junk foreach ($wc['converters'] as &$c) { // In cwebp converter options (here in webp express), we have a checkbox "set size" // - there is no such option in webp-convert - so remove. if ($c['converter'] == 'cwebp') { if (isset($c['options']['set-size']) && $c['options']['set-size']) { unset($c['options']['set-size']); } else { unset($c['options']['set-size']); unset($c['options']['size-in-percentage']); } } if ($c['converter'] == 'ewww') { $c['options']['check-key-status-before-converting'] = false; } // 'id', 'working' and 'error' attributes are used internally in webp-express, // no need to have it in the wod configuration file. unset ($c['id']); unset($c['working']); unset($c['error']); if (isset($c['options']['quality']) && ($c['options']['quality'] == 'inherit')) { unset ($c['options']['quality']); } /* if (!isset($c['options'])) { $c = $c['converter']; }*/ } // Create jpeg options // https://github.com/rosell-dk/webp-convert/blob/master/docs/v2.0/converting/introduction-for-converting.md#png-og-jpeg-specific-options $auto = (isset($config['quality-auto']) && $config['quality-auto']); $wc['jpeg'] = [ 'encoding' => $config['jpeg-encoding'], 'quality' => ($auto ? 'auto' : $config['quality-specific']), ]; if ($auto) { $wc['jpeg']['default-quality'] = $config['quality-specific']; $wc['jpeg']['max-quality'] = $config['max-quality']; } if ($config['jpeg-encoding'] != 'lossy') { if ($config['jpeg-enable-near-lossless']) { $wc['jpeg']['near-lossless'] = $config['jpeg-near-lossless']; } else { $wc['jpeg']['near-lossless'] = 100; } } // Create png options // --- $wc['png'] = [ 'encoding' => $config['png-encoding'], 'quality' => $config['png-quality'], ]; if ($config['png-encoding'] != 'lossy') { if ($config['png-enable-near-lossless']) { $wc['png']['near-lossless'] = $config['png-near-lossless']; } else { $wc['png']['near-lossless'] = 100; } } if ($config['png-encoding'] != 'lossless') { // Only relevant for pngs, and only for "lossy" (and thus also "auto") $wc['png']['alpha-quality'] = $config['alpha-quality']; } // Other convert options $wc['metadata'] = $config['metadata']; $wc['log-call-arguments'] = true; // $config['log-call-arguments']; // Serve options // ------------- $serve = [ 'serve-image' => [ 'headers' => [ 'cache-control' => false, 'content-length' => true, 'content-type' => true, 'expires' => false, 'last-modified' => true, //'vary-accept' => false // This must be different for webp-on-demand and webp-realizer ] ] ]; if ($config['cache-control'] != 'no-header') { $serve['serve-image']['cache-control-header'] = self::getCacheControlHeader($config); $serve['serve-image']['headers']['cache-control'] = true; $serve['serve-image']['headers']['expires'] = true; } $serve['fail'] = $config['fail']; // WOD options // ------------- $wod = [ 'enable-redirection-to-converter' => $config['enable-redirection-to-converter'], 'enable-redirection-to-webp-realizer' => $config['enable-redirection-to-webp-realizer'], 'base-htaccess-on-these-capability-tests' => $config['base-htaccess-on-these-capability-tests'], 'destination-extension' => $config['destination-extension'], 'destination-folder' => $config['destination-folder'], 'forward-query-string' => $config['forward-query-string'], //'method-for-passing-source' => $config['method-for-passing-source'], 'image-roots' => Paths::getImageRootsDef(), 'success-response' => $config['success-response'], ]; // Put it all together // ------------- //$options = array_merge($wc, $serve, $wod); // I'd like to put the webp-convert options in its own key, // but it requires some work. Postponing it to another day that I can uncomment the two next lines (and remove the one above) //$wc = array_merge($wc, $serve); //$options = array_merge($wod, ['webp-convert' => $wc]); //$options = array_merge($wod, array_merge($serve, ['conversion' => $wc])); $options = [ 'wod' => $wod, 'webp-convert' => array_merge($serve, ['convert' => $wc]) ]; return $options; } public static function saveWodOptionsFile($options) { if (Paths::createConfigDirIfMissing()) { return FileHelper::saveJSONOptions(Paths::getWodOptionsFileName(), $options); } return false; } /** * Save both configuration files, but do not update htaccess * Returns success (boolean) */ public static function saveConfigurationFileAndWodOptions($config) { if (!isset($config['base-htaccess-on-these-capability-tests'])) { self::runAndStoreCapabilityTests($config); } if (!(self::saveConfigurationFile($config))) { return false; } $options = self::generateWodOptionsFromConfigObj($config); return (self::saveWodOptionsFile($options)); } /** * * $rewriteRulesNeedsUpdate: */ public static function saveConfigurationAndHTAccess($config, $forceRuleUpdating = false) { // Important to do this check before saving config, because the method // compares against existing config. if ($forceRuleUpdating) { $rewriteRulesNeedsUpdate = true; } else { $rewriteRulesNeedsUpdate = HTAccessRules::doesRewriteRulesNeedUpdate($config); } if (!isset($config['base-htaccess-on-these-capability-tests']) || $rewriteRulesNeedsUpdate) { self::runAndStoreCapabilityTests($config); } if (self::saveConfigurationFile($config)) { $options = self::generateWodOptionsFromConfigObj($config); if (self::saveWodOptionsFile($options)) { if ($rewriteRulesNeedsUpdate) { $rulesResult = HTAccess::saveRules($config, false); return [ 'saved-both-config' => true, 'saved-main-config' => true, 'rules-needed-update' => true, 'htaccess-result' => $rulesResult ]; } else { $rulesResult = HTAccess::saveRules($config, false); return [ 'saved-both-config' => true, 'saved-main-config' => true, 'rules-needed-update' => false, 'htaccess-result' => $rulesResult ]; } } else { return [ 'saved-both-config' => false, 'saved-main-config' => true, ]; } } else { return [ 'saved-both-config' => false, 'saved-main-config' => false, ]; } } public static function getConverterByName($config, $converterName) { foreach ($config['converters'] as $i => $converter) { if ($converter['converter'] == $converterName) { return $converter; } } } }