Changeset 3040365
- Timestamp:
- 02/23/2024 06:04:25 PM (2 years ago)
- Location:
- jch-optimize/trunk
- Files:
-
- 3 added
- 66 edited
-
jch-optimize.php (modified) (1 diff)
-
lib/src/Admin/AbstractHtml.php (modified) (2 diffs)
-
lib/src/Admin/Ajax/Ajax.php (modified) (2 diffs)
-
lib/src/Admin/Ajax/FileTree.php (modified) (1 diff)
-
lib/src/Admin/Helper.php (modified) (2 diffs)
-
lib/src/Admin/Icons.php (modified) (2 diffs)
-
lib/src/Admin/Tasks.php (modified) (2 diffs)
-
lib/src/Cdn.php (modified) (2 diffs)
-
lib/src/Combiner.php (modified) (2 diffs)
-
lib/src/Container/ContainerAwareTrait.php (added)
-
lib/src/Css/Callbacks/AbstractCallback.php (modified) (1 diff)
-
lib/src/Css/Callbacks/CorrectUrls.php (modified) (8 diffs)
-
lib/src/Css/Callbacks/ExtractCriticalCss.php (modified) (11 diffs)
-
lib/src/Css/Callbacks/FormatCss.php (modified) (1 diff)
-
lib/src/Css/Callbacks/HandleAtRules.php (modified) (2 diffs)
-
lib/src/Css/Parser.php (modified) (10 diffs)
-
lib/src/Css/Processor.php (modified) (3 diffs)
-
lib/src/Css/Sprite/Controller.php (modified) (16 diffs)
-
lib/src/Css/Sprite/Generator.php (modified) (3 diffs)
-
lib/src/Css/Sprite/Handler/Gd.php (modified) (5 diffs)
-
lib/src/Css/Sprite/Handler/Imagick.php (modified) (1 diff)
-
lib/src/Debugger.php (modified) (2 diffs)
-
lib/src/Exception/PropertyNotFoundException.php (added)
-
lib/src/FileInfosUtilsTrait.php (modified) (2 diffs)
-
lib/src/Helper.php (modified) (3 diffs)
-
lib/src/Html/CacheManager.php (modified) (14 diffs)
-
lib/src/Html/Callbacks/AbstractCallback.php (modified) (3 diffs)
-
lib/src/Html/Callbacks/BuildHtmlElement.php (modified) (4 diffs)
-
lib/src/Html/Callbacks/Cdn.php (modified) (6 diffs)
-
lib/src/Html/Callbacks/LazyLoad.php (modified) (6 diffs)
-
lib/src/Html/ElementObject.php (modified) (1 diff)
-
lib/src/Html/Elements/BaseElement.php (modified) (7 diffs)
-
lib/src/Html/FilesManager.php (modified) (16 diffs)
-
lib/src/Html/HtmlElementBuilder.php (modified) (1 diff)
-
lib/src/Html/HtmlElementInterface.php (modified) (2 diffs)
-
lib/src/Html/HtmlManager.php (modified) (10 diffs)
-
lib/src/Html/Parser.php (modified) (4 diffs)
-
lib/src/Html/Processor.php (modified) (3 diffs)
-
lib/src/Http2Preload.php (modified) (6 diffs)
-
lib/src/Interfaces/Paths.php (modified) (4 diffs)
-
lib/src/Laminas/ArrayPaginator.php (modified) (1 diff)
-
lib/src/Laminas/Plugins/ClearExpiredByFactor.php (modified) (7 diffs)
-
lib/src/Mvc/Controller.php (modified) (1 diff)
-
lib/src/Mvc/Model.php (modified) (1 diff)
-
lib/src/Optimize.php (modified) (5 diffs)
-
lib/src/Output.php (modified) (2 diffs)
-
lib/src/PageCache/PageCache.php (modified) (4 diffs)
-
lib/src/Service/CachingProvider.php (modified) (1 diff)
-
lib/src/Service/CoreProvider.php (modified) (4 diffs)
-
lib/src/StorageTaggingTrait.php (modified) (3 diffs)
-
lib/src/Uri/UriComparator.php (modified) (1 diff)
-
lib/src/Uri/UriConverter.php (modified) (3 diffs)
-
lib/src/Uri/Utils.php (modified) (3 diffs)
-
lib/src/class_map.php (modified) (2 diffs)
-
lib/vendor/composer/autoload_classmap.php (modified) (4 diffs)
-
lib/vendor/composer/autoload_static.php (modified) (4 diffs)
-
lib/vendor/composer/installed.php (modified) (1 diff)
-
lib/vendor/symfony/polyfill-mbstring/bootstrap.php (modified) (1 diff)
-
lib/vendor/symfony/polyfill-mbstring/bootstrap80.php (modified) (1 diff)
-
media/core/icons/responsive_images.png (added)
-
media/filetree/jquery.filetree.css (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
-
src/Html/Helper.php (modified) (3 diffs)
-
src/Html/Renderer/Section.php (modified) (2 diffs)
-
src/Html/Renderer/Setting.php (modified) (3 diffs)
-
src/Html/TabSettings.php (modified) (6 diffs)
-
src/Platform/Paths.php (modified) (8 diffs)
-
vendor/composer/installed.php (modified) (2 diffs)
-
version.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
jch-optimize/trunk/jch-optimize.php
r3007001 r3040365 5 5 * Plugin URI: http://www.jch-optimize.net/ 6 6 * Description: Boost your WordPress site's performance with JCH Optimize as measured on PageSpeed 7 * Version: 4. 1.17 * Version: 4.2.0 8 8 * Author: Samuel Marshall 9 9 * License: GNU/GPLv3 -
jch-optimize/trunk/lib/src/Admin/AbstractHtml.php
r3007001 r3040365 18 18 use _JchOptimizeVendor\Joomla\DI\Container; 19 19 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 20 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;21 20 use _JchOptimizeVendor\Psr\Http\Client\ClientInterface; 22 21 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; … … 26 25 use _JchOptimizeVendor\Spatie\Crawler\CrawlProfiles\CrawlInternalUrls; 27 26 use JchOptimize\Core\Admin\API\MessageEventInterface; 27 use JchOptimize\Core\Container\ContainerAwareTrait; 28 28 use JchOptimize\Core\Interfaces\Html; 29 29 use JchOptimize\Core\Registry; -
jch-optimize/trunk/lib/src/Admin/Ajax/Ajax.php
r3007001 r3040365 14 14 15 15 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 16 use _JchOptimizeVendor\Joomla\Input\Input; 18 17 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; … … 21 20 use JchOptimize\ContainerFactory; 22 21 use JchOptimize\Core\Admin\Json; 22 use JchOptimize\Core\Container\ContainerAwareTrait; 23 23 24 24 \defined('_JCH_EXEC') or exit('Restricted access'); -
jch-optimize/trunk/lib/src/Admin/Ajax/FileTree.php
r2997317 r3040365 36 36 $j = 0; 37 37 foreach ($files as $file) { 38 if (\is_dir($root.$dir.$file) && 'jch_optimize_backup_images' != $file && '.jch' != $file) { 39 /*if ($i > 500) { 40 if ($j > 1000) { 41 break; 42 } 43 44 continue; 45 }*/ 38 if (\is_dir($root.$dir.$file) && !\in_array($file, ['jch_optimize_backup_images', '.jch', 'jch-optimize'])) { 46 39 $directories[$i]['name'] = $file; 47 40 $directories[$i]['file_path'] = $dir.$file; 48 41 ++$i; 49 } elseif ('tree' != $view && \preg_match('#\\.(?:gif|jpe?g|png)$#i', $file) && @\file_exists($root.$dir.$file)) { 50 /* if ($j > 1000) { 51 if ($i > 500) { 52 break; 53 } 54 55 continue; 56 } */ 42 } elseif ('tree' != $view && \preg_match('#'.\JchOptimize\Core\Admin\Ajax\OptimizeImage::$fileExtRegex.'#i', $file) && @\file_exists($root.$dir.$file)) { 57 43 $imageFiles[$j]['ext'] = \preg_replace('/^.*\\./', '', $file); 58 44 $imageFiles[$j]['name'] = $file; -
jch-optimize/trunk/lib/src/Admin/Helper.php
r3007001 r3040365 34 34 * @deprecated 35 35 */ 36 public static function expandFileNameLegacy( $sFile)36 public static function expandFileNameLegacy(string $sFile) 37 37 { 38 38 $sSanitizedFile = \str_replace('//', '/', $sFile); … … 52 52 } 53 53 54 /** 55 * @param null|(mixed|string)[]|string $dest 56 * 57 * @psalm-param array<mixed|string>|null|string $dest 58 */ 59 public static function copyImage(string $src, $dest): bool 54 public static function copyImage(string $src, string $dest): bool 60 55 { 61 56 try { -
jch-optimize/trunk/lib/src/Admin/Icons.php
r2997317 r3040365 15 15 use _JchOptimizeVendor\Joomla\CMS\Language\Text; 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 use JchOptimize\Core\Container\ContainerAwareTrait; 18 18 use JchOptimize\Core\Registry; 19 19 use JchOptimize\Model\ModeSwitcher; … … 164 164 $pageCacheTooltip .= Utility::translate('Toggles on/off the Page Cache feature.'); 165 165 166 return [['name' => 'Add Image Attributes', 'setting' => $setting = 'img_attributes_enable', 'icon' => 'img_attributes.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Adds \'height\' and/or \'width\' attributes to <:img>\'s, if missing, to reduce CLS.')], ['name' => 'Sprite Generator', 'setting' => $setting = 'csg_enable', 'icon' => 'sprite_gen.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Combines select background images into a sprite.')], ['name' => 'Http/2 Push', 'setting' => $setting = 'http2_push_enable', 'icon' => 'http2_push.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Preloads critical assets using the http/2 protocol to improve LCP.')], ['name' => 'Lazy Load Images', 'setting' => $setting = 'lazyload_enable', 'icon' => 'lazyload.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Defer images that fall below the fold.')], ['name' => 'Optimize CSS Delivery', 'setting' => $setting = 'optimizeCssDelivery_enable', 'icon' => 'optimize_css_delivery.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Eliminates CSS render-blocking')], ['name' => 'Optimize Fonts', 'setting' => $setting = 'pro_optimizeFonts_enable', 'icon' => 'optimize_gfont.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Optimizes the loading of fonts, including Google Fonts.')], ['name' => 'CDN', 'setting' => $setting = 'cookielessdomain_enable', 'icon' => 'cdn.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Loads static assets from a CDN server. Requires the CDN domain(s) to be configured on the Configuration tab.')], ['name' => 'Smart Combine', 'setting' => $setting = 'pro_smart_combine', 'icon' => 'smart_combine.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Intelligently combines files in a number of smaller files, instead of one large file for better http2 delivery.')], ['name' => 'Load Webp', 'setting' => $setting = 'pro_load_webp_images', 'icon' => 'webp.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Loads generated WEBP images in place of the original ones. These images must be generated on the Optimize Image tab first.')], ['name' => 'L CP Images', 'setting' => $setting = 'pro_lcp_images_enable', 'icon' => 'lcp_images.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Preload LCP images with a high fetch priority. These images must be added on the Options page to be discovered.')], ['name' => 'Preconnects', 'setting' => $setting = 'pro_preconnect_domains_enable', 'icon' => 'preconnect.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Preconnect external origins to reduce the impact of third-party domains.')], ['name' => 'Page Cache', 'setting' => 'integrated_page_cache_enable', 'icon' => 'cache.png', 'enabled' => Cache::isPageCacheEnabled($this->params), 'tooltip' => $pageCacheTooltip]];166 return [['name' => 'Add Image Attributes', 'setting' => $setting = 'img_attributes_enable', 'icon' => 'img_attributes.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Adds \'height\' and/or \'width\' attributes to <:img>\'s, if missing, to reduce CLS.')], ['name' => 'Sprite Generator', 'setting' => $setting = 'csg_enable', 'icon' => 'sprite_gen.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Combines select background images into a sprite.')], ['name' => 'Http/2 Push', 'setting' => $setting = 'http2_push_enable', 'icon' => 'http2_push.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Preloads critical assets using the http/2 protocol to improve LCP.')], ['name' => 'Lazy Load Images', 'setting' => $setting = 'lazyload_enable', 'icon' => 'lazyload.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Defer images that fall below the fold.')], ['name' => 'Optimize CSS Delivery', 'setting' => $setting = 'optimizeCssDelivery_enable', 'icon' => 'optimize_css_delivery.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Eliminates CSS render-blocking')], ['name' => 'Optimize Fonts', 'setting' => $setting = 'pro_optimizeFonts_enable', 'icon' => 'optimize_gfont.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Optimizes the loading of fonts, including Google Fonts.')], ['name' => 'CDN', 'setting' => $setting = 'cookielessdomain_enable', 'icon' => 'cdn.png', 'enabled' => $this->params->get($setting, '0'), 'tooltip' => Utility::translate('Loads static assets from a CDN server. Requires the CDN domain(s) to be configured on the Configuration tab.')], ['name' => 'Smart Combine', 'setting' => $setting = 'pro_smart_combine', 'icon' => 'smart_combine.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Intelligently combines files in a number of smaller files, instead of one large file for better http2 delivery.')], ['name' => 'Load Webp', 'setting' => $setting = 'pro_load_webp_images', 'icon' => 'webp.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Loads generated WEBP images in place of the original ones. These images must be generated on the Optimize Image tab first.')], ['name' => 'Load Responsive', 'setting' => $setting = 'pro_load_responsive_images', 'icon' => 'responsive_images.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Use responsive images where available. These images must be generated on the Optimize Image tab first.')], ['name' => 'LCP Images', 'setting' => $setting = 'pro_lcp_images_enable', 'icon' => 'lcp_images.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Preload LCP images with a high fetch priority. These images must be added on the Options page to be discovered.')], ['name' => 'Preconnects', 'setting' => $setting = 'pro_preconnect_domains_enable', 'icon' => 'preconnect.png', 'enabled' => $this->params->get($setting, '0'), 'proonly' => \true, 'tooltip' => Utility::translate('Preconnect external origins to reduce the impact of third-party domains.')], ['name' => 'Page Cache', 'setting' => 'integrated_page_cache_enable', 'icon' => 'cache.png', 'enabled' => Cache::isPageCacheEnabled($this->params), 'tooltip' => $pageCacheTooltip]]; 167 167 } 168 168 -
jch-optimize/trunk/lib/src/Admin/Tasks.php
r2997317 r3040365 172 172 } 173 173 174 /** 175 * @return string|true 176 * 177 * @psalm-return 'BACKUPPATHDOESNTEXIST'|'SOMEIMAGESDIDNTRESTORE'|true 178 */ 179 public static function restoreBackupImages(?LoggerInterface $logger = null) 174 public static function restoreBackupImages(?LoggerInterface $logger = null): bool|string 180 175 { 181 176 if (\is_null($logger)) { … … 190 185 foreach ($aFiles as $backupContractedFile) { 191 186 $success = \false; 187 188 /** @var string[] $aPotentialOriginalFilePaths */ 192 189 $aPotentialOriginalFilePaths = [AdminHelper::expandFileName($backupContractedFile), AdminHelper::expandFileNameLegacy($backupContractedFile)]; 193 190 foreach ($aPotentialOriginalFilePaths as $originalFilePath) { -
jch-optimize/trunk/lib/src/Cdn.php
r2997317 r3040365 16 16 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 17 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 18 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;19 18 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 19 use JchOptimize\Core\Container\ContainerAwareTrait; 20 20 use JchOptimize\Core\Exception\RuntimeException; 21 21 use JchOptimize\Core\FeatureHelpers\CdnDomains; … … 47 47 $this->params = $params; 48 48 $this->enabled = (bool) $this->params->get('cookielessdomain_enable', '0'); 49 50 switch ($params->get('cdn_scheme', '0')) { 51 case '1': 52 $this->scheme = 'http'; 53 54 break; 55 56 case '2': 57 $this->scheme = 'https'; 58 59 break; 60 61 case '0': 62 default: 63 $this->scheme = ''; 64 65 break; 66 } 49 $this->scheme = match ((string) $params->get('cdn_scheme', '0')) { 50 '1' => 'http', 51 '2' => 'https', 52 default => '', 53 }; 67 54 } 68 55 -
jch-optimize/trunk/lib/src/Combiner.php
r2997317 r3040365 19 19 use _JchOptimizeVendor\GuzzleHttp\RequestOptions; 20 20 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 21 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;22 21 use _JchOptimizeVendor\Laminas\Cache\Pattern\CallbackCache; 23 22 use _JchOptimizeVendor\Laminas\Cache\Storage\IterableInterface; … … 31 30 use CodeAlfa\Minify\Js; 32 31 use CodeAlfa\RegexTokenizer\Debug\Debug; 32 use JchOptimize\Core\Container\ContainerAwareTrait; 33 33 use JchOptimize\Core\Css\Processor as CssProcessor; 34 34 use JchOptimize\Core\Css\Sprite\Generator; -
jch-optimize/trunk/lib/src/Css/Callbacks/AbstractCallback.php
r2997317 r3040365 14 14 15 15 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 16 use JchOptimize\Core\Container\Container; 17 use JchOptimize\Core\Container\ContainerAwareTrait; 18 18 use JchOptimize\Core\Registry; 19 19 -
jch-optimize/trunk/lib/src/Css/Callbacks/CorrectUrls.php
r2997317 r3040365 19 19 use JchOptimize\Core\Css\Parser; 20 20 use JchOptimize\Core\FeatureHelpers\LazyLoadExtended; 21 use JchOptimize\Core\FeatureHelpers\ResponsiveImages; 21 22 use JchOptimize\Core\FeatureHelpers\Webp; 22 23 use JchOptimize\Core\Helper; … … 44 45 private array $preconnects = []; 45 46 46 private array $cssInfos ;47 private array $cssInfos = []; 47 48 private array $lcpImages = []; 49 private array $responsiveImages = []; 48 50 49 51 public function __construct(Container $container, Registry $params, Cdn $cdn, Http2Preload $http2Preload) … … 68 70 return $this->getContainer()->get(LazyLoadExtended::class)->handleCssBgImages($this, $css); 69 71 } 72 $rsCss = ''; 73 if (JCH_PRO && !empty($this->responsiveImages)) { 74 $rsImages = \array_reverse($this->responsiveImages, \true); 75 foreach ($rsImages as $breakpoint => $rsImage) { 76 $tmpCss = \preg_replace_callback('#'.Parser::cssUrlWithCaptureValueToken(\true).'#', fn ($match) => \str_replace($match[1], $rsImage, $match[0]), $css); 77 $rsCss .= "@media (max-width: {$breakpoint}px){{$tmpCss}}"; 78 } 79 } 70 80 71 return $css ;81 return $css.$rsCss; 72 82 } 73 83 74 public function setCssInfos( $cssInfos): void84 public function setCssInfos(array $cssInfos): void 75 85 { 76 86 $this->cssInfos = $cssInfos; … … 99 109 /** 100 110 * @param string[] $matches 101 * @param mixed $context102 *103 * @psalm-param array<string> $matches104 111 */ 105 protected function processInnerMatches(array $matches, $context)112 protected function processInnerMatches(array $matches, string $context): string|bool 106 113 { 107 114 if (empty($matches[0])) { … … 111 118 if ('data' !== $originalUri->getScheme() && '' != $originalUri->getPath() && '/' != $originalUri->getPath()) { 112 119 if ($this->isHttp2) { 113 // The urls were already corrected on a previous run, we're only preloading assets in critical CSS and return 120 // The urls were already corrected on a previous run, 121 // we're only preloading assets in critical CSS and return 114 122 $fileType = 'font-face' == $context ? 'font' : 'image'; 115 123 // LCP Images would have already been processed, we can skip those … … 117 125 $lcpImages = Helper::getArray($this->params->get('pro_lcp_images', [])); 118 126 if (Helper::findMatches($lcpImages, $originalUri)) { 127 return \true; 128 } 129 // Don't preload responsive images 130 if (\str_contains((string) $originalUri, 'jch-optimize/rs')) { 119 131 return \true; 120 132 } … … 142 154 } 143 155 if ('font-face' != $context && 'import' != $context) { 156 if (JCH_PRO && $this->params->get('pro_load_responsive_images', '0')) { 157 $this->responsiveImages = $this->getContainer()->get(ResponsiveImages::class)->getResponsiveImages($imageUri); 158 } 144 159 if (JCH_PRO && $this->params->get('pro_load_webp_images', '0')) { 145 160 /** @see Webp::getWebpImages() */ … … 149 164 $lcpImages = Helper::getArray($this->params->get('pro_lcp_images', [])); 150 165 if (Helper::findMatches($lcpImages, $imageUri)) { 151 $this->lcpImages[] = $imageUri;166 $this->lcpImages[] = ['src' => $imageUri, 'srcset' => $this->responsiveImages ? $this->getContainer()->get(ResponsiveImages::class)->createSrcsetString($this->responsiveImages, $imageUri) : '']; 152 167 } 153 168 } -
jch-optimize/trunk/lib/src/Css/Callbacks/ExtractCriticalCss.php
r2997317 r3040365 15 15 use CodeAlfa\RegexTokenizer\Debug\Debug; 16 16 use JchOptimize\Core\Css\Parser; 17 use JchOptimize\Core\Exception\PropertyNotFoundException; 17 18 use JchOptimize\Core\FeatureHelpers\DynamicSelectors; 18 19 … … 23 24 { 24 25 use Debug; 25 public string $sHtmlAboveFold; 26 public string $sFullHtml; 27 public \DOMXPath $oXPath; 26 public string $htmlAboveFold = ''; 27 public string $fullHtml = ''; 28 28 public string $postCss = ''; 29 29 public string $preCss = ''; 30 30 public bool $isPostProcessing = \false; 31 31 protected string $criticalCss = ''; 32 private ?\DOMXPath $xPath = null; 32 33 33 34 public function processMatches(array $matches, string $context): string … … 36 37 if ('font-face' == $context || 'keyframes' == $context) { 37 38 if (!$this->isPostProcessing) { 38 // If we're not processing font-face or keyframes yet let's just save them for later until after we've done getting all the39 // critical css39 // If we're not processing font-face or keyframes yet, let's just save them for later until 40 // after we've done getting all the // critical css 40 41 $this->postCss .= $matches[0]; 41 42 … … 99 100 } 100 101 // Check CSS selector chain against HTMl above the fold to find a match 101 if ($this->checkCssAgainstHtml($sSelectorChain, $this-> sHtmlAboveFold)) {102 if ($this->checkCssAgainstHtml($sSelectorChain, $this->htmlAboveFold)) { 102 103 // Match found, add selector chain to array 103 104 $aFoundSelectorChains[] = $sSelectorChain; … … 122 123 $aXPaths = \array_unique(\explode(' | ', \str_replace('\\', '', $sXPath))); 123 124 foreach ($aXPaths as $sXPathValue) { 124 $ oElement = $this->oXPath->query($sXPathValue);125 // if ($ oElement === FALSE)125 $element = $this->getDOMXPath()->query($sXPathValue); 126 // if ($element === FALSE) 126 127 // { 127 128 // echo $aMatches[1] . "\n"; … … 131 132 // } 132 133 // Match found! Add to critical CSS 133 if (\false !== $ oElement && $oElement->length) {134 if (\false !== $element && $element->length) { 134 135 $this->appendToCriticalCss($matches[0]); 135 136 $this->_debug($sXPathValue, $matches[0], 'afterCriticalCssFound'); … … 149 150 } 150 151 151 /**152 * @return string153 */154 152 public function convertCss2XPath(string $sSelector, ?bool &$success = null): ?string 155 153 { … … 163 161 } 164 162 $sSelectorRegex = '#(?!$)([>+~, ]?)([*_a-z0-9-]*)(?:(([.\\#])((?:[_a-z0-9-]|\\\\[^\\r\\n\\f0-9a-z])+))(([.\\#])((?:[_a-z0-9-]|\\\\[^\\r\\n\\f0-9a-z])+))?|(\\[((?:[_a-z0-9-]|\\\\[^\\r\\n\\f0-9a-z])+)(([~|^$*]?=)["\']?([^\\]"\']+)["\']?)?\\]))*#i'; 165 $result = \preg_replace_callback($sSelectorRegex, [$this, ' _tokenizer'], $sSelector).'[1]';166 if ( null === $result) {163 $result = \preg_replace_callback($sSelectorRegex, [$this, 'tokenizer'], $sSelector).'[1]'; 164 if (\PREG_NO_ERROR !== \preg_last_error()) { 167 165 $success = \false; 168 166 … … 171 169 172 170 return $result; 171 } 172 173 public function setDOMXPath(\DOMXPath $xPath): void 174 { 175 $this->xPath = $xPath; 173 176 } 174 177 … … 236 239 * @param string[] $aM 237 240 */ 238 protected function _tokenizer(array $aM): string241 protected function tokenizer(array $aM): string 239 242 { 240 243 $sXPath = ''; … … 341 344 return $sXPath; 342 345 } 346 347 protected function getDOMXPath(): \DOMXPath 348 { 349 if ($this->xPath instanceof \DOMXPath) { 350 return $this->xPath; 351 } 352 353 throw new PropertyNotFoundException('DOMXPath not found in '.\get_class($this)); 354 } 343 355 } -
jch-optimize/trunk/lib/src/Css/Callbacks/FormatCss.php
r2997317 r3040365 16 16 class FormatCss extends \JchOptimize\Core\Css\Callbacks\AbstractCallback 17 17 { 18 public string $validCssRules ;18 public string $validCssRules = ''; 19 19 20 20 public function processMatches(array $matches, string $context): string -
jch-optimize/trunk/lib/src/Css/Callbacks/HandleAtRules.php
r2997317 r3040365 24 24 private array $fontFace = []; 25 25 26 private array $cssInfos ;26 private array $cssInfos = []; 27 27 28 28 public function processMatches(array $matches, string $context): string … … 35 35 $matches[0] = \preg_replace('#;?\\s*}$#', ';font-display:swap;}', $matches[0]); 36 36 } elseif (\preg_match('#font-display#i', $matches[0]) && $this->params->get('pro_force_swap_policy', '1')) { 37 $matches[0] = \preg_replace('#font-display[^;} ]++#i', 'font-display:swap', $matches[0]);37 $matches[0] = \preg_replace('#font-display[^;}/\'"]++([;}])#i', '_JchOptimizeVendor\\font-display:swap\\1', $matches[0]); 38 38 } 39 39 /*if ($this->params->get('pro_optimizeFonts_enable', '0') && empty($this->cssInfos['combining-fontface'])) { -
jch-optimize/trunk/lib/src/Css/Parser.php
r2997317 r3040365 14 14 15 15 use CodeAlfa\RegexTokenizer\Css; 16 use JchOptimize\Core\Css\Callbacks\AbstractCallback; 16 17 use JchOptimize\Core\Exception; 18 use JchOptimize\Core\Exception\PregErrorException; 17 19 18 20 \defined('_JCH_EXEC') or exit('Restricted access'); … … 21 23 use Css; 22 24 protected array $aExcludes = []; 23 24 /** @var CssSearchObject */ 25 protected \JchOptimize\Core\Css\CssSearchObject $oCssSearchObject; 25 protected ?\JchOptimize\Core\Css\CssSearchObject $cssSearchObject = null; 26 26 protected bool $bBranchReset = \true; 27 27 protected string $sParseTerm = '\\s*+'; 28 protected static int $subroutines = 0; 28 29 29 30 public function __construct() … … 57 58 // language=RegExp 58 59 /** 59 * @param (mixed|string)[] $a AtRules60 * @param (mixed|string)[] $atRulesArray 60 61 * 61 * @psalm-param list{0?: 'font-face'|'media'|mixed, 1?: 'keyframes'|mixed, 2?: 'page'|mixed, 3?: 'font-feature-values'|mixed, 4?: 'counter-style'|mixed, 5?: 'viewport'|mixed, 6?: 'property'|mixed,...} $a AtRules62 * @psalm-param list{0?: 'font-face'|'media'|mixed, 1?: 'keyframes'|mixed, 2?: 'page'|mixed, 3?: 'font-feature-values'|mixed, 4?: 'counter-style'|mixed, 5?: 'viewport'|mixed, 6?: 'property'|mixed,...} $atRulesArray 62 63 */ 63 public static function cssNestedAtRulesWithCaptureValueToken(array $a AtRules = [], bool $bCV = \false, bool $bEmpty = \false): string64 { 65 $ sAtRules = !empty($aAtRules) ? '(?>'.\implode('|', $aAtRules).')' : '';66 $i N = $bCV ? 2 : 1;67 $sValue = $ bEmpty ? '\\s*+' : '(?>'.self::parse('', \true).'|(?-'.$iN.'))*+';68 $ sAtRules = '<<@(?:-[^-]++-)??'.$sAtRules.'[^{};]*+>>(\\{<<'.$sValue.'>>\\})';69 70 return self::prepare($ sAtRules, $bCV);64 public static function cssNestedAtRulesWithCaptureValueToken(array $atRulesArray = [], bool $shouldCaptureValue = \false, bool $empty = \false): string 65 { 66 $atRulesString = !empty($atRulesArray) ? '(?>'.\implode('|', $atRulesArray).')' : ''; 67 $i = self::$subroutines++; 68 $sValue = $empty ? '\\s*+' : '(?>'.self::parse('', \true)."|(?P>css{$i}))*+"; 69 $atRulesString = "<<@(?:-[^-]++-)??{$atRulesString}[^{};]*+>>(?P<css{$i}>\\{<<{$sValue}>>\\})"; 70 71 return self::prepare($atRulesString, $shouldCaptureValue); 71 72 } 72 73 … … 132 133 133 134 /** 134 * @param Callbacks\CombineMediaQueries|Callbacks\CorrectUrls|Callbacks\ExtractCriticalCss|Callbacks\FormatCss|Callbacks\HandleAtRules $oCallback135 *136 135 * @throws Exception\PregErrorException 137 136 */ 138 public function processMatchesWithCallback(string $sCss, $oCallback, string $sContext = 'global'): ?string137 public function processMatchesWithCallback(string $sCss, AbstractCallback $oCallback, string $sContext = 'global'): ?string 139 138 { 140 139 $sRegex = $this->getCssSearchRegex(); … … 143 142 return $aMatches[0]; 144 143 } 145 if ( '@' == \substr($aMatches[0], 0, 1)) {144 if (\str_starts_with($aMatches[0], '@')) { 146 145 $sContext = $this->getContext($aMatches[0]); 147 foreach ($this-> oCssSearchObject->getCssNestedRuleNames() as $aAtRule) {146 foreach ($this->getCssSearchObject()->getCssNestedRuleNames() as $aAtRule) { 148 147 if ($aAtRule['name'] == $sContext) { 149 148 if ($aAtRule['recurse']) { … … 169 168 170 169 /** 171 * @psalm-param '' $sReplace 172 * 173 * @param mixed $sCss 174 * 175 * @throws Exception\PregErrorException 170 * @throws PregErrorException 176 171 */ 177 public function replaceMatches( $sCss, string $sReplace): ?string178 { 179 $ sProcessedCss = \preg_replace('#'.$this->getCssSearchRegex().'#i', $sReplace, $sCss);172 public function replaceMatches(string $css, string $replace): ?string 173 { 174 $processedCss = \preg_replace('#'.$this->getCssSearchRegex().'#i', $replace, $css); 180 175 181 176 try { … … 184 179 throw new Exception\PregErrorException($exception->getMessage()); 185 180 } 186 187 return $sProcessedCss; 188 } 189 190 public function setCssSearchObject(CssSearchObject $oCssSearchObject): void 191 { 192 $this->oCssSearchObject = $oCssSearchObject; 181 if (\is_string($processedCss)) { 182 return $processedCss; 183 } 184 185 throw new PregErrorException('Unknown error processing regex'); 186 } 187 188 public function setCssSearchObject(CssSearchObject $cssSearchObject): void 189 { 190 $this->cssSearchObject = $cssSearchObject; 193 191 } 194 192 … … 212 210 // language=RegExp 213 211 /** 214 * @psalm-param '' $ sInclude212 * @psalm-param '' $include 215 213 */ 216 protected static function parse(string $ sInclude = '', bool $bNoEmpty = \false): string217 { 218 $ sRepeat = $bNoEmpty ? '+' : '*';219 220 return '(?>(?:[^{}"\'/'.$sInclude.']++|/)(?>'.self::blockCommentToken().'|'.self::stringWithCaptureValueToken().')?)'.$sRepeat.'?';214 protected static function parse(string $include = '', bool $noEmpty = \false): string 215 { 216 $repeat = $noEmpty ? '+' : '*'; 217 218 return "(?>[^{}\"'/{$include}]{$repeat}+(?>".self::blockCommentToken().'|'.self::stringWithCaptureValueToken()."|/)*+){$repeat}?"; 221 219 } 222 220 … … 250 248 protected function getCriteria(): string 251 249 { 252 $oObj = $this-> oCssSearchObject;250 $oObj = $this->getCssSearchObject(); 253 251 $aCriteria = []; 254 252 // We need to add Nested Rules criteria first to avoid trouble with recursion and branch capture reset … … 309 307 return !empty($aMatches[1]) ? \strtolower($aMatches[1]) : 'global'; 310 308 } 309 310 protected function getCssSearchObject(): CssSearchObject 311 { 312 if ($this->cssSearchObject instanceof \JchOptimize\Core\Css\CssSearchObject) { 313 return $this->cssSearchObject; 314 } 315 316 throw new Exception\PropertyNotFoundException('CssSearchObject not set in '.\get_class($this)); 317 } 311 318 } -
jch-optimize/trunk/lib/src/Css/Processor.php
r2997317 r3040365 14 14 15 15 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 16 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 18 17 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 19 18 use CodeAlfa\RegexTokenizer\Debug\Debug; 19 use JchOptimize\Core\Container\ContainerAwareTrait; 20 20 use JchOptimize\Core\Css\Callbacks\CombineMediaQueries; 21 21 use JchOptimize\Core\Css\Callbacks\CorrectUrls; … … 39 39 use FileInfosUtilsTrait; 40 40 use SerializableTrait; 41 protected string $css ;41 protected string $css = ''; 42 42 43 43 private Registry $params; … … 254 254 $oCssSearchObject->setCssAtRuleCriteria(\JchOptimize\Core\Css\Parser::cssAtNameSpaceToken()); 255 255 $oCssSearchObject->setCssRuleCriteria('.'); 256 $this->extractCriticalCss-> sHtmlAboveFold = $sHtmlAboveFold;257 $this->extractCriticalCss-> sFullHtml = $sFullHtml;258 $this->extractCriticalCss-> oXPath = $oXPath;256 $this->extractCriticalCss->htmlAboveFold = $sHtmlAboveFold; 257 $this->extractCriticalCss->fullHtml = $sFullHtml; 258 $this->extractCriticalCss->setDOMXPath($oXPath); 259 259 $oParser->setCssSearchObject($oCssSearchObject); 260 260 $sCriticalCss = $oParser->processMatchesWithCallback($css, $this->extractCriticalCss); -
jch-optimize/trunk/lib/src/Css/Sprite/Controller.php
r2997317 r3040365 15 15 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;18 17 use _JchOptimizeVendor\Joomla\Filesystem\Folder; 19 18 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; … … 21 20 use _JchOptimizeVendor\Psr\Log\LoggerInterface; 22 21 use Exception; 22 use JchOptimize\Core\Container\ContainerAwareTrait; 23 23 use JchOptimize\Core\Exception\MissingDependencyException; 24 24 use JchOptimize\Core\Registry; … … 38 38 use LoggerAwareTrait; 39 39 public array $options = []; 40 public bool $bTransparent ;40 public bool $bTransparent = \false; 41 41 protected array $imageTypes = []; 42 42 protected array $aFormErrors = []; … … 44 44 protected $sCss; 45 45 protected string $sTempSpriteName = ''; 46 protected bool $bValidImages ;46 protected bool $bValidImages = \false; 47 47 protected array $aBackground = []; 48 48 protected array $aPosition = []; … … 109 109 public function GetSpriteFormats() 110 110 { 111 // @phpstan-ignore-next-line 111 112 return $this->imageHandler->spriteFormats; 112 113 } … … 154 155 $fileUri = UriResolver::resolve(SystemUri::currentUri(), $fileUri); 155 156 $filePath = \str_replace(SystemUri::baseFull(), '', (string) $fileUri); 156 $sFilePath = Paths::rootPath().\DIRECTORY_SEPARATOR.$filePath; 157 $bFileExists = \true; 158 if (@\file_exists($sFilePath)) { 157 $filePath = Paths::rootPath().\DIRECTORY_SEPARATOR.$filePath; 158 $aPathParts = \pathinfo($filePath); 159 $fileBaseName = $aPathParts['basename']; 160 $width = 0; 161 $height = 0; 162 $imageTypes = []; 163 $bFileExists = \false; 164 if (@\file_exists($filePath)) { 165 $bFileExists = \true; 159 166 // do we want to scale down the source images 160 167 // scaling up isn't supported as that would result in poorer quality images 161 168 $bResize = 100 != $this->options['width-resize'] && 100 != $this->options['height-resize']; 162 169 // grab path information 163 // $sFilePath = $sFolderMD5.$sFile; 164 $aPathParts = \pathinfo($sFilePath); 165 $sFileBaseName = $aPathParts['basename']; 166 $aImageInfo = @\getimagesize($sFilePath); 170 // $filePath = $sFolderMD5.$sFile; 171 $aImageInfo = @\getimagesize($filePath); 167 172 if ($aImageInfo) { 168 $ iWidth = $aImageInfo[0];169 $ iHeight = $aImageInfo[1];170 $i ImageType= $aImageInfo[2];173 $width = $aImageInfo[0]; 174 $height = $aImageInfo[1]; 175 $imageTypes = $aImageInfo[2]; 171 176 // are we matching filenames against a regular expression 172 177 // if so it's likely not all images from the ZIP file will end up in the generated sprite image … … 176 181 $this->options['file-regex'] = \str_replace('/', '\\/', $this->options['file-regex']); 177 182 // if the regular expression matches grab the first match and store for use as the class name 178 if (\preg_match('/^'.$this->options['file-regex'].'$/i', $ sFileBaseName, $aMatches)) {179 $ sFileClass = $aMatches[1];183 if (\preg_match('/^'.$this->options['file-regex'].'$/i', $fileBaseName, $aMatches)) { 184 $fileClass = $aMatches[1]; 180 185 } else { 181 $ sFileClass = '';186 $fileClass = ''; 182 187 } 183 188 } else { 184 // not using regular expressions - set the class name to the base part of the filename (excluding extension) 185 $sFileClass = $aPathParts['basename']; 189 // not using regular expressions - set the class name to the base part of the 190 // filename (excluding extension) 191 $fileClass = $aPathParts['basename']; 186 192 } 187 193 // format the class name - it should only contain certain characters 188 194 // this strips out any which aren't 189 $ sFileClass = $this->FormatClassName($sFileClass);195 $fileClass = $this->formatClassName($fileClass); 190 196 } else { 191 197 $bFileExists = \false; 192 198 } 193 } else {194 $bFileExists = \false;195 199 } 196 200 // the file also isn't valid if its extension doesn't match one of the image formats supported by the tool 197 201 // discard images whose height or width is greater than 50px 198 if ($bFileExists && !empty($ sFileClass) && \in_array(\strtoupper($aPathParts['extension']), $this->imageTypes) && \in_array($iImageType, [\IMAGETYPE_GIF, \IMAGETYPE_JPEG, \IMAGETYPE_PNG]) && '.' != \substr($sFileBaseName, 0, 1) && $iWidth < 50 && $iHeight < 50 && $iWidth > 0 && $iHeight > 0) {202 if ($bFileExists && !empty($fileClass) && \in_array(\strtoupper($aPathParts['extension']), $this->imageTypes) && \in_array($imageTypes, [\IMAGETYPE_GIF, \IMAGETYPE_JPEG, \IMAGETYPE_PNG]) && !\str_starts_with($fileBaseName, '.') && $width < 50 && $height < 50 && $width > 0 && $height > 0) { 199 203 // grab the file extension 200 204 $sExtension = $aPathParts['extension']; 201 205 // get MD5 of file (this can be used to compare if a file's content is exactly the same as another's) 202 $sFileMD5 = \md5(\file_get_contents($ sFilePath));206 $sFileMD5 = \md5(\file_get_contents($filePath)); 203 207 // check if this file's MD5 already exists in array of MD5s recorded so far 204 208 // if so it's a duplicate of another file in the ZIP … … 208 212 if ('merge' == $this->options['ignore-duplicates']) { 209 213 if (isset($aFilesInfo[$sKey]['class'])) { 210 $aFilesInfo[$sKey]['class'] = $aFilesInfo[$sKey]['class'].$this->options['selector-suffix'].', '.$this->options['selector-prefix'].'.'.$this->options['class-prefix'].$ sFileClass;214 $aFilesInfo[$sKey]['class'] = $aFilesInfo[$sKey]['class'].$this->options['selector-suffix'].', '.$this->options['selector-prefix'].'.'.$this->options['class-prefix'].$fileClass; 211 215 } 212 216 $this->aBackground[$k] = $sKey; … … 222 226 $aFilesMD5[$i] = $sFileMD5; 223 227 // store generated class selector details 224 // $aFilesInfo[$i]['class'] = ".{$this->aFormValues['class-prefix']}$ sFileClass";228 // $aFilesInfo[$i]['class'] = ".{$this->aFormValues['class-prefix']}$fileClass"; 225 229 // store file path information and extension 226 $aFilesInfo[$i]['path'] = $ sFilePath;230 $aFilesInfo[$i]['path'] = $filePath; 227 231 $aFilesInfo[$i]['ext'] = $sExtension; 228 232 if ('horizontal' == $this->options['build-direction']) { 229 233 // get the current width of the sprite image - after images processed so far 230 $iCurrentWidth = $iTotalWidth + $this->options['horizontal-offset'] + $ iWidth;234 $iCurrentWidth = $iTotalWidth + $this->options['horizontal-offset'] + $width; 231 235 // store the maximum width reached so far 232 236 // if we're on a new column current height might be less than the maximum … … 236 240 } else { 237 241 // get the current height of the sprite image - after images processed so far 238 $iCurrentHeight = $iTotalHeight + $this->options['vertical-offset'] + $ iHeight;242 $iCurrentHeight = $iTotalHeight + $this->options['vertical-offset'] + $height; 239 243 // store the maximum height reached so far 240 244 // if we're on a new column current height might be less than the maximum … … 245 249 // store the original width and height of the image 246 250 // we'll need this later if the image is to be resized 247 $aFilesInfo[$i]['original-width'] = $ iWidth;248 $aFilesInfo[$i]['original-height'] = $ iHeight;251 $aFilesInfo[$i]['original-width'] = $width; 252 $aFilesInfo[$i]['original-height'] = $height; 249 253 // store the width and height of the image 250 254 // if we're resizing they'll be less than the original 251 $aFilesInfo[$i]['width'] = $bResize ? \round($ iWidth / 100 * $this->options['width-resize']) : $iWidth;252 $aFilesInfo[$i]['height'] = $bResize ? \round($ iHeight / 100 * $this->options['height-resize']) : $iHeight;255 $aFilesInfo[$i]['width'] = $bResize ? \round($width / 100 * $this->options['width-resize']) : $width; 256 $aFilesInfo[$i]['height'] = $bResize ? \round($height / 100 * $this->options['height-resize']) : $height; 253 257 if ('horizontal' == $this->options['build-direction']) { 254 258 // opera (9.0 and below) has a bug which prevents it recognising offsets of less than -2042px … … 260 264 $iTotalWidth = 0; 261 265 } 262 // if the current image is higher than any other in the current row then set the maximum height to that 266 // if the current image is higher than any other in the current row then set 267 // the maximum height to that 263 268 // it will be used to set the height of the current row 264 269 if ($aFilesInfo[$i]['height'] > $iMaxHeight) { … … 285 290 $iTotalHeight = 0; 286 291 } 287 // if the current image is wider than any other in the current column then set the maximum width to that 292 // if the current image is wider than any other in the current column then set 293 // the maximum width to that 288 294 // it will be used to set the width of the current column 289 295 if ($aFilesInfo[$i]['width'] > $iMaxWidth) { … … 405 411 JCH_DEBUG ? Profiler::stop('CreateSprite', \true) : null; 406 412 } 407 } 408 409 public function ValidImages(): bool 413 414 return null; 415 } 416 417 public function validImages(): bool 410 418 { 411 419 return $this->bValidImages; 412 420 } 413 421 414 public function GetSpriteFilename(): string422 public function getSpriteFileName(): string 415 423 { 416 424 $aFileParts = \pathinfo($this->sTempSpriteName); … … 419 427 } 420 428 421 public function GetSpriteHash(): void429 public function getSpriteHash(): void 422 430 { 423 431 // return md5($this->GetSpriteFilename().ConfigHelper::Get('/checksum')); 424 432 } 425 433 426 public function GetCss(): array434 public function getCss(): array 427 435 { 428 436 return $this->aCss; 429 437 } 430 438 431 public function GetAllErrors(): array439 public function getAllErrors(): array 432 440 { 433 441 return $this->aFormErrors; 434 442 } 435 443 436 public function GetZipFolder(): string444 public function getZipFolder(): string 437 445 { 438 446 return $this->sZipFolder; 439 447 } 440 448 441 public function GetCssBackground(): array449 public function getCssBackground(): array 442 450 { 443 451 $aCssBackground = []; … … 452 460 } 453 461 454 protected function FormatClassName(string $sClassName): ?string462 protected function formatClassName(string $sClassName): ?string 455 463 { 456 464 $aExtensions = []; -
jch-optimize/trunk/lib/src/Css/Sprite/Generator.php
r2997317 r3040365 14 14 15 15 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 16 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 18 17 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 19 18 use JchOptimize\Core\Cdn; 19 use JchOptimize\Core\Container\ContainerAwareTrait; 20 20 use JchOptimize\Core\Exception; 21 21 use JchOptimize\Core\Helper; … … 170 170 $aImages = $matches[1]; 171 171 $this->spriteController->CreateSprite($aImages); 172 $aSpriteCss = $this->spriteController-> GetCssBackground();172 $aSpriteCss = $this->spriteController->getCssBackground(); 173 173 $aPatterns = []; 174 174 $aPatterns[0] = '#background-position:[^;}]+;?#i'; … … 179 179 $aPatterns[3] = '#(background:[^;}]*)\\burl\\((?=[^\\)]+\\.(?:png|gif|jpe?g))[^\\)]+\\)([^;}]*[;}])#i'; 180 180 // Background image regex 181 $sSpriteName = $this->spriteController-> GetSpriteFilename();181 $sSpriteName = $this->spriteController->getSpriteFileName(); 182 182 $aSearch = []; 183 183 $sRelSpritePath = Paths::spritePath(\true).\DIRECTORY_SEPARATOR.$sSpriteName; -
jch-optimize/trunk/lib/src/Css/Sprite/Handler/Gd.php
r2997317 r3040365 36 36 } 37 37 38 /** 39 * @param mixed $spriteWidth 40 * @param mixed $spriteHeight 41 * @param mixed $bgColour 42 * @param mixed $outputFormat 43 * 44 * @return false|resource 45 */ 46 public function createSprite($spriteWidth, $spriteHeight, $bgColour, $outputFormat) 38 public function createSprite($spriteWidth, $spriteHeight, $bgColour, $outputFormat): \GdImage|false 47 39 { 48 40 if ($this->options['is-transparent'] && !empty($this->options['background'])) { … … 74 66 } 75 67 76 /** 77 * @param mixed $fileInfos 78 * 79 * @return false|resource 80 */ 81 public function createBlankImage($fileInfos) 68 public function createBlankImage($fileInfos): \GdImage|false 82 69 { 83 70 $oCurrentImage = \imagecreatetruecolor($fileInfos['original-width'], $fileInfos['original-height']); … … 87 74 } 88 75 89 /** 90 * @param mixed $spriteObject 91 * @param mixed $currentImage 92 * @param mixed $fileInfos 93 */ 94 public function resizeImage($spriteObject, $currentImage, $fileInfos) 76 public function resizeImage($spriteObject, $currentImage, $fileInfos): void 95 77 { 96 78 \imagecopyresampled($spriteObject, $currentImage, $fileInfos['x'], $fileInfos['y'], 0, 0, $fileInfos['width'], $fileInfos['height'], $fileInfos['original-width'], $fileInfos['original-height']); 97 79 } 98 80 99 /** 100 * @param mixed $spriteObject 101 * @param mixed $currentImage 102 * @param mixed $fileInfos 103 * @param mixed $resize 104 */ 105 public function copyImageToSprite($spriteObject, $currentImage, $fileInfos, $resize) 81 public function copyImageToSprite($spriteObject, $currentImage, $fileInfos, $resize): void 106 82 { 107 83 // if already resized the image will have been copied as part of the resize … … 111 87 } 112 88 113 /** 114 * @param mixed $imageObject 115 */ 116 public function destroy($imageObject) 89 public function destroy($imageObject): void 117 90 { 118 91 \imagedestroy($imageObject); 119 92 } 120 93 121 /** 122 * @param mixed $fileInfos 123 * 124 * @return false|resource 125 */ 126 public function createImage($fileInfos) 94 public function createImage($fileInfos): \GdImage|false 127 95 { 128 96 $sFile = $fileInfos['path']; … … 152 120 } 153 121 154 /** 155 * @param mixed $imageObject 156 * @param mixed $extension 157 * @param mixed $fileName 158 */ 159 public function writeImage($imageObject, $extension, $fileName) 122 public function writeImage($imageObject, $extension, $fileName): void 160 123 { 161 124 // check if we want to resample image to lower number of colours (to reduce file size) -
jch-optimize/trunk/lib/src/Css/Sprite/Handler/Imagick.php
r2997317 r3040365 22 22 try { 23 23 $oImagick = new \Imagick(); 24 $ aImageFormats = $oImagick->queryFormats();24 $imageFormats = $oImagick->queryFormats(); 25 25 } catch (\ImagickException $e) { 26 26 $this->logger->error($e->getMessage()); 27 28 return []; 27 29 } 28 30 // store supported formats for populating drop downs etc later 29 if (\in_array('PNG', $ aImageFormats)) {31 if (\in_array('PNG', $imageFormats)) { 30 32 $imageTypes[] = 'PNG'; 31 33 $this->spriteFormats[] = 'PNG'; 32 34 } 33 if (\in_array('GIF', $ aImageFormats)) {35 if (\in_array('GIF', $imageFormats)) { 34 36 $imageTypes[] = 'GIF'; 35 37 $this->spriteFormats[] = 'GIF'; 36 38 } 37 if (\in_array('JPG', $ aImageFormats) || \in_array('JPEG', $aImageFormats)) {39 if (\in_array('JPG', $imageFormats) || \in_array('JPEG', $imageFormats)) { 38 40 $imageTypes[] = 'JPG'; 39 41 } -
jch-optimize/trunk/lib/src/Debugger.php
r2997317 r3040365 43 43 } 44 44 45 public static function debuggerErrorHandler(int $errno, string $errstr, string $errfile , int $errline): void45 public static function debuggerErrorHandler(int $errno, string $errstr, string $errfile = '', int $errline = 0): bool 46 46 { 47 47 /** @var LoggerInterface $logger */ … … 49 49 $msg = 'Error no: '.$errno.', Message: '.$errstr.' in file: '.$errfile.' at line: '.$errline."\n"; 50 50 $logger->error($msg); 51 if (self::$dieOnError) { 52 exit; 53 } 51 52 return \true; 54 53 } 55 54 -
jch-optimize/trunk/lib/src/FileInfosUtilsTrait.php
r2997317 r3040365 13 13 namespace JchOptimize\Core; 14 14 15 use JchOptimize\Core\Exception\PropertyNotFoundException; 16 15 17 \defined('_JCH_EXEC') or exit('Restricted access'); 16 18 trait FileInfosUtilsTrait 17 19 { 18 20 /** 19 * @var FileUtils21 * @var null|FileUtils 20 22 */ 21 private \JchOptimize\Core\FileUtils $fileUtils;23 private ?\JchOptimize\Core\FileUtils $fileUtils = null; 22 24 23 25 /** … … 26 28 public function prepareFileUrl(array $fileInfos, string $type): string 27 29 { 28 return isset($fileInfos['url']) ? $this->fileUtils->prepareForDisplay($fileInfos['url'], '', \true, 40) : ('css' == $type ? 'Style' : 'Script').' Declaration'; 30 $fileUtils = $this->getFileUtils(); 31 32 return isset($fileInfos['url']) ? $fileUtils->prepareForDisplay($fileInfos['url'], '', \true, 40) : ('css' == $type ? 'Style' : 'Script').' Declaration'; 33 } 34 35 private function getFileUtils(): FileUtils 36 { 37 if ($this->fileUtils instanceof \JchOptimize\Core\FileUtils) { 38 return $this->fileUtils; 39 } 40 41 throw new PropertyNotFoundException('FileUtils not set in '.\get_class($this)); 29 42 } 30 43 } -
jch-optimize/trunk/lib/src/Helper.php
r2997317 r3040365 41 41 public static function isMsieLT10(): bool 42 42 { 43 // $browser = Browser::getInstance( 'Mozilla/5.0 (Macintosh; Intel Mac OS X10_15_7) AppleWebkit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15' );44 /** @var Browser $browser */45 43 $browser = \JchOptimize\Core\Browser::getInstance(); 46 44 … … 63 61 public static function strReplace(string $search, string $replace, string $subject): string 64 62 { 65 return \str_replace(self::cleanPath($search), $replace, self::cleanPath($subject)); 66 } 67 68 /** 69 * @return string|string[] 70 */ 71 public static function cleanPath(string $str) 63 return (string) \str_replace(self::cleanPath($search), $replace, self::cleanPath($subject)); 64 } 65 66 public static function cleanPath(string $str): string 72 67 { 73 68 return \str_replace(['\\\\', '\\'], '/', $str); … … 92 87 } 93 88 94 /**95 * Splits a string into an array using any regular delimiter or whitespace.96 *97 * @param null|array|string $string |array $string Delimited string of components98 *99 * @return string[] An array of the components100 */101 89 public static function getArray(string|array|null $string): array 102 90 { -
jch-optimize/trunk/lib/src/Html/CacheManager.php
r3007001 r3040365 15 15 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\ Joomla\DI\ContainerAwareTrait;17 use _JchOptimizeVendor\Laminas\Cache\Exception\ExceptionInterface; 18 18 use _JchOptimizeVendor\Laminas\Cache\Pattern\CallbackCache; 19 19 use _JchOptimizeVendor\Laminas\Cache\Storage\IterableInterface; … … 24 24 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 25 25 use JchOptimize\Core\Combiner; 26 use JchOptimize\Core\Container\ContainerAwareTrait; 26 27 use JchOptimize\Core\Css\Processor as CssProcessor; 27 28 use JchOptimize\Core\Exception as CoreException; … … 29 30 use JchOptimize\Core\FeatureHelpers\Fonts; 30 31 use JchOptimize\Core\FeatureHelpers\LazyLoadExtended; 32 use JchOptimize\Core\FeatureHelpers\ResponsiveImages; 31 33 use JchOptimize\Core\Helper; 32 34 use JchOptimize\Core\Html\Elements\Img; … … 100 102 } 101 103 102 /**103 * @throws CoreException\ExceptionInterface104 */105 104 public function handleCombineJsCss(): void 106 105 { … … 132 131 $lazyLoadExtended->cssBgImagesSelectors = \array_merge($lazyLoadExtended->cssBgImagesSelectors, $aCssCache['bgselectors']); 133 132 foreach ($aCssCache['lcpImages'] as $lcpImage) { 134 $this->http2Preload->preload($lcpImage, 'image', '', 'high'); 133 $attributes = []; 134 if ($lcpImage['srcset']) { 135 $attributes = ['imagesrcset' => $lcpImage['srcset'], 'imagesizes' => ResponsiveImages::$sizes]; 136 } 137 $this->http2Preload->preload($lcpImage['src'], 'image', '', 'high', $attributes); 135 138 } 136 139 } … … 195 198 * @param string $type css or js 196 199 * 197 * @return array|string Contents in array from cache containing combined file(s)198 */ 199 public function getCombinedFiles(array $links, ?string &$id, string $type) 200 * @return null|mixed 201 */ 202 public function getCombinedFiles(array $links, ?string &$id, string $type): mixed 200 203 { 201 204 !JCH_DEBUG ?: Profiler::start('GetCombinedFiles - '.$type); … … 217 220 * @param array $fileMatches Array matches of file to be appended to the combined file 218 221 * 219 * @return array|bool|string 220 */ 221 public function getAppendedFiles(array $ids, array $fileMatches, ?string &$id) 222 * @return null|mixed 223 * 224 * @throws ExceptionInterface 225 */ 226 public function getAppendedFiles(array $ids, array $fileMatches, ?string &$id): mixed 222 227 { 223 228 !JCH_DEBUG ?: Profiler::start('GetAppendedFiles'); … … 249 254 $aImgAttributes = []; 250 255 foreach ($aImages[0] as $imgHtml) { 251 // @var Img $imgObj252 256 try { 257 /** @var Img $imgObj */ 253 258 $imgObj = \JchOptimize\Core\Html\HtmlElementBuilder::load($imgHtml); 254 259 } catch (CoreException\PregErrorException $e) { … … 295 300 if ($iWidthAttrValue && 0 == $count) { 296 301 // Value found so we try to add the height attribute 297 $height = \round($aSize[1] / $aSize[0] * (int) $iWidthAttrValue);302 $height = (string) \round($aSize[1] / $aSize[0] * (int) $iWidthAttrValue); 298 303 // If add attributes not enabled put data-height instead 299 304 $isImageAttrEnabled ? $imgObj->height($height) : $imgObj->data('height', $height); … … 312 317 // Check if a value was found for the height 313 318 if ($iHeightAttrValue && 0 == $count) { 314 $width = \round($aSize[0] / $aSize[1] * (int) $iHeightAttrValue);319 $width = (string) \round($aSize[0] / $aSize[1] * (int) $iHeightAttrValue); 315 320 // if add attributes not enabled put data-width instead 316 321 $isImageAttrEnabled ? $imgObj->width($width) : $imgObj->data('width', $width); … … 326 331 if (!$existingAttributes) { 327 332 if ($isImageAttrEnabled) { 328 $imgObj->width( $aSize[0]);329 $imgObj->height( $aSize[1]);333 $imgObj->width((string) $aSize[0]); 334 $imgObj->height((string) $aSize[1]); 330 335 } else { 331 336 $imgObj->data('width', $aSize[0]); … … 340 345 341 346 /** 342 * @return array|bool|string343 *344 347 * @throws CoreException\MissingDependencyException 345 348 */ … … 374 377 * @param null|string $id Generated id to identify cached file 375 378 * 376 * @return array|bool|string377 * 378 * @throw sCoreException\RuntimeException379 */ 380 private function loadCache(callable $function, array $args, ?string &$id) 379 * @return null|mixed 380 * 381 * @throw CoreException\RuntimeException 382 */ 383 private function loadCache(callable $function, array $args, ?string &$id): mixed 381 384 { 382 385 try { … … 394 397 // Returns the contents of the combined file or false if failure 395 398 return $results; 396 } catch (\Exception $e) {399 } catch (\Exception|ExceptionInterface $e) { 397 400 throw new CoreException\RuntimeException('Error creating cache files: '.$e->getMessage()); 398 401 } -
jch-optimize/trunk/lib/src/Html/Callbacks/AbstractCallback.php
r2997317 r3040365 15 15 use _JchOptimizeVendor\Joomla\DI\Container; 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 use JchOptimize\Core\Container\ContainerAwareTrait; 18 18 use JchOptimize\Core\Html\CallbackInterface; 19 19 use JchOptimize\Core\Registry; … … 27 27 * @var string RegEx used to process HTML 28 28 */ 29 protected string $regex ;29 protected string $regex = ''; 30 30 31 31 /** … … 34 34 protected Registry $params; 35 35 36 /**37 * Constructor.38 *39 * @param null|Container $container40 * @param null|Registry $params41 */42 36 public function __construct(Container $container, Registry $params) 43 37 { -
jch-optimize/trunk/lib/src/Html/Callbacks/BuildHtmlElement.php
r2997317 r3040365 8 8 use JchOptimize\Core\Html\Elements\BaseElement; 9 9 use JchOptimize\Core\Html\HtmlElementBuilder; 10 use JchOptimize\Core\Html\HtmlElementInterface; 10 11 use JchOptimize\Core\Html\Parser; 11 12 … … 41 42 } 42 43 43 public function getElement(): BaseElement44 public function getElement(): HtmlElementInterface 44 45 { 45 46 return $this->element; 46 47 } 47 48 48 /** 49 * @param string[] $matches 50 */ 51 public function loadElementAttributes(array $matches): void 49 public function loadElementAttributes(array $matches): string 52 50 { 53 51 $parts = \preg_split('#\\s*=\\s*#', $matches[0]); … … 55 53 $delimiter = $matches[1] ?? '"'; 56 54 $this->element->attribute($parts[0], $value, $delimiter); 55 56 return ''; 57 57 } 58 58 … … 80 80 } 81 81 if (!empty($match[2])) { 82 $this->element->addChild(HtmlElementBuilder::load($match[2])); 82 $child = HtmlElementBuilder::load($match[2]); 83 $child->setParent($this->element->getElementName()); 84 $this->element->addChild($child); 83 85 } 84 86 } -
jch-optimize/trunk/lib/src/Html/Callbacks/Cdn.php
r2997317 r3040365 19 19 use JchOptimize\Core\Css\Parser as CssParser; 20 20 use JchOptimize\Core\Exception\PregErrorException; 21 use JchOptimize\Core\Exception\PropertyNotFoundException; 21 22 use JchOptimize\Core\Html\Elements\BaseElement; 22 23 use JchOptimize\Core\Html\Elements\Style; … … 30 31 { 31 32 protected string $context = 'default'; 32 protected UriInterface $baseUri;33 protected ?UriInterface $baseUri = null; 33 34 protected string $searchRegex = ''; 34 35 protected string $localhost = ''; … … 111 112 } 112 113 113 protected function loadCdnInCssStyle( $css): string114 protected function loadCdnInCssStyle(string $css): string 114 115 { 115 116 \preg_match_all('#url\\([\'"]?('.$this->searchRegex.CssParser::cssUrlValueToken().')([\'"]?\\))#i', $css, $matches, \PREG_SET_ORDER); … … 134 135 protected function resolvePathToBase(UriInterface $uri): UriInterface 135 136 { 136 return UriResolver::resolve($this-> baseUri, $uri);137 return UriResolver::resolve($this->getBaseUri(), $uri); 137 138 } 138 139 … … 156 157 } 157 158 158 protected function cdnInContentAttributes( $value): string159 protected function cdnInContentAttributes(string $value): string 159 160 { 160 161 \preg_match_all('#'.$this->searchRegex.'#i', $value, $matches, \PREG_SET_ORDER); … … 168 169 return $value; 169 170 } 171 172 protected function getBaseUri(): UriInterface 173 { 174 if ($this->baseUri instanceof UriInterface) { 175 return $this->baseUri; 176 } 177 178 throw new PropertyNotFoundException('Base URI not set in '.\get_class($this)); 179 } 170 180 } -
jch-optimize/trunk/lib/src/Html/Callbacks/LazyLoad.php
r3007001 r3040365 18 18 use JchOptimize\Core\Exception\PregErrorException; 19 19 use JchOptimize\Core\FeatureHelpers\LazyLoadExtended; 20 use JchOptimize\Core\FeatureHelpers\ResponsiveImages; 20 21 use JchOptimize\Core\FeatureHelpers\Webp; 21 22 use JchOptimize\Core\Helper; 22 23 use JchOptimize\Core\Html\Elements\Audio; 23 use JchOptimize\Core\Html\Elements\BaseElement;24 24 use JchOptimize\Core\Html\Elements\Iframe; 25 25 use JchOptimize\Core\Html\Elements\Img; … … 49 49 public int $height = 1; 50 50 51 protected array $excludes ;52 53 protected array $args ;51 protected array $excludes = []; 52 53 protected array $args = []; 54 54 55 55 public function __construct(Container $container, Registry $params, Http2Preload $http2Preload) … … 86 86 return $element->render(); 87 87 } 88 if (\JCH_PRO && $this->params->get('pro_load_responsive_images', '0')) { 89 $this->loadResponsiveImages($element); 90 } 88 91 if (\JCH_PRO && $this->params->get('pro_load_webp_images', '0')) { 89 92 $this->loadWebpImages($element); … … 150 153 } 151 154 152 private function lazyLoadElement( BaseElement $element, array $options): BaseElement155 private function lazyLoadElement(HtmlElementInterface $element, array $options): HtmlElementInterface 153 156 { 154 157 if ($options['lazyload']) { … … 289 292 } 290 293 294 private function loadResponsiveImages(HtmlElementInterface $element): void 295 { 296 if ($element->hasChildren()) { 297 foreach ($element->getChildren() as $child) { 298 if ($child instanceof HtmlElementInterface) { 299 $this->loadResponsiveImages($child); 300 } 301 } 302 } 303 $this->getContainer()->get(ResponsiveImages::class)->convert($element); 304 } 305 291 306 private function lcpImageProcessed(HtmlElementInterface $element): bool 292 307 { … … 323 338 } else { 324 339 if (($src = $element->getSrc()) !== \false && Helper::findMatches($lcpImages, $src)) { 325 $this->http2Preload->preload($src, 'image', '', 'high'); 340 if ('picture' == $element->getParent()) { 341 $element->fetchpriority('high'); 342 } else { 343 $this->http2Preload->preload($src, 'image', '', 'high'); 344 } 326 345 if ($element->hasAttribute('loading')) { 327 346 $element->loading('eager'); -
jch-optimize/trunk/lib/src/Html/ElementObject.php
r2997317 r3040365 27 27 public bool $negateAggregatedPosCriteria = \false; 28 28 public bool $bCaptureAttributes = \false; 29 30 /**31 * @var false32 */33 29 public bool $bParseContentLazily = \true; 34 30 -
jch-optimize/trunk/lib/src/Html/Elements/BaseElement.php
r2997317 r3040365 28 28 * @method BaseElement title(string $value) 29 29 * @method bool|string getId() 30 * @method bool|stringgetClass()30 * @method array|bool getClass() 31 31 * @method bool|string getHidden() 32 32 * @method bool|string getStyle() … … 38 38 protected string $name = ''; 39 39 protected bool $isXhtml; 40 protected string $parent = ''; 40 41 41 42 /** … … 107 108 } 108 109 109 public function data( $name,$value = ''): static110 public function data(string $name, UriInterface|array|string $value = ''): static 110 111 { 111 112 $this->attribute('data-'.$name, $value); … … 114 115 } 115 116 116 /**117 * @return $this118 */119 117 public function addChild(HtmlElementInterface|string $child): static 120 118 { … … 136 134 137 135 return $this; 136 } 137 138 public function getElementName(): string 139 { 140 return $this->name; 138 141 } 139 142 … … 152 155 } 153 156 154 public function firstOfAttributes(array $attributes) 157 public function firstOfAttributes(array $attributes): UriInterface|bool|array|string 155 158 { 156 159 foreach ($attributes as $name => $value) { … … 200 203 } 201 204 205 public function setParent(string $name): static 206 { 207 $this->parent = $name; 208 209 return $this; 210 } 211 212 public function getParent(): string 213 { 214 return $this->parent; 215 } 216 202 217 private function renderChildren(): string 203 218 { -
jch-optimize/trunk/lib/src/Html/FilesManager.php
r3007001 r3040365 16 16 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 17 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 18 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;19 18 use _JchOptimizeVendor\Psr\Http\Client\ClientInterface; 20 19 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 21 20 use CodeAlfa\Minify\Html; 21 use JchOptimize\Core\Container\ContainerAwareTrait; 22 22 use JchOptimize\Core\Exception\ExcludeException; 23 use JchOptimize\Core\Exception\PropertyNotFoundException; 23 24 use JchOptimize\Core\FeatureHelpers\Fonts; 24 25 use JchOptimize\Core\FileUtils; … … 137 138 */ 138 139 public array $jsMarker = []; 139 protected \JchOptimize\Core\Html\HtmlElementInterface $element;140 protected ?\JchOptimize\Core\Html\HtmlElementInterface $element = null; 140 141 141 142 /** … … 147 148 * @var HtmlElementInterface|string String to replace the matched link 148 149 */ 149 protected $replacement = '';150 protected string|\JchOptimize\Core\Html\HtmlElementInterface $replacement = ''; 150 151 151 152 /** … … 209 210 $this->element = $element; 210 211 // By default, we'll return the match and save info later and what is to be removed 211 $this->replacement = $ this->element;212 $this->replacement = $element; 212 213 213 214 try { … … 265 266 $this->sJsExcludeType = 'ieo'; 266 267 if ($addToExcludes) { 267 $this->aExcludedJs[] = $this-> element;268 $this->aExcludedJs[] = $this->getElement(); 268 269 } 269 270 270 271 throw new ExcludeException(); 272 } 273 274 protected function getElement(): HtmlElementInterface 275 { 276 if ($this->element instanceof \JchOptimize\Core\Html\HtmlElementInterface) { 277 return $this->element; 278 } 279 280 throw new PropertyNotFoundException('HTMLElement not set in '.\get_class($this)); 271 281 } 272 282 … … 278 288 // Exclude invalid urls 279 289 if ('data' == $uri->getScheme()) { 280 if ($this-> elementinstanceof Script) {290 if ($this->getElement() instanceof Script) { 281 291 $this->excludeJsIEO(); 282 292 } else { … … 303 313 // for different browsers and creates problems when we try to cache it. 304 314 if ('fonts.googleapis.com' == $uri->getHost() && !$this->params->get('pro_optimizeFonts_enable', '0')) { 305 $this->replacement = $this-> element;315 $this->replacement = $this->getElement(); 306 316 } 307 317 $this->excludeCssIEO(); … … 327 337 $this->aCss[$this->iIndex_css][] = ['url' => $uri, 'media' => $media]; 328 338 // Record match to be replaced 329 $this->cssReplacements[$this->iIndex_css][] = $this-> element;339 $this->cssReplacements[$this->iIndex_css][] = $this->getElement(); 330 340 } 331 341 332 342 private function getMediaAttribute(): string 333 343 { 334 return $this->element->attributeValue('media') ?: '';344 return (string) $this->getElement()->attributeValue('media') ?: ''; 335 345 } 336 346 … … 381 391 { 382 392 // if previous file was not excluded increment css index 383 if (!$this->cssExcludedPeo ) {393 if (!$this->cssExcludedPeo && !empty($this->cssReplacements[0])) { 384 394 ++$this->iIndex_css; 385 395 } … … 393 403 { 394 404 if ($this->params->get('pro_smart_combine', '0')) { 395 $type = $this-> elementinstanceof Script ? 'js' : 'css';405 $type = $this->getElement() instanceof Script ? 'js' : 'css'; 396 406 $fileUri = UriResolver::resolve(SystemUri::currentUri(), $uri); 397 407 $filePath = $fileUri->getPath(); … … 436 446 $this->cssExcludedIeo = \false; 437 447 $this->aCss[$this->iIndex_css][] = ['content' => Html::cleanScript($content, 'css'), 'media' => $media]; 438 $this->cssReplacements[$this->iIndex_css][] = $this-> element;448 $this->cssReplacements[$this->iIndex_css][] = $this->getElement(); 439 449 } 440 450 … … 463 473 } 464 474 } 465 if (($attributeType = $this-> element->firstofAttributes($deferAttributes)) !== \false) {475 if (($attributeType = $this->getElement()->firstofAttributes($deferAttributes)) !== \false) { 466 476 if ($attributeType != $this->prevDeferMatches) { 467 477 ++$this->deferIndex; 468 478 $this->prevDeferMatches = $attributeType; 469 479 } 470 $this->defers[$this->deferIndex][] = ['attributeType' => $attributeType, 'script' => $this-> element, 'url' => $uri];480 $this->defers[$this->deferIndex][] = ['attributeType' => $attributeType, 'script' => $this->getElement(), 'url' => $uri]; 471 481 $this->bLoadJsAsync = \false; 472 482 $this->excludeJsIEO(\false); … … 480 490 $this->jsExcludedIeo = \false; 481 491 $this->aJs[$this->iIndex_js][] = ['url' => $uri]; 482 $this->jsReplacements[$this->iIndex_js][] = $this-> element;492 $this->jsReplacements[$this->iIndex_js][] = $this->getElement(); 483 493 } 484 494 … … 494 504 // If previous file was not excluded, update marker 495 505 if (!$this->jsExcludedPeo) { 496 $marker = $this-> element->data('jch', 'js'.$this->iIndex_js);506 $marker = $this->getElement()->data('jch', 'js'.$this->iIndex_js); 497 507 $this->jsMarker = \array_pad($this->jsMarker, $this->iIndex_js + 1, $marker); 498 508 } 499 509 if ($addToExcludes) { 500 $this->aExcludedJs[] = $this-> element;510 $this->aExcludedJs[] = $this->getElement(); 501 511 } 502 512 // Record index of last excluded file … … 535 545 // different type is encountered. The defer and async attribute on inline scripts are ignored 536 546 $deferAttributes = ['type' => 'module', 'nomodule' => \true]; 537 if (($attributeType = $this-> element->firstOfAttributes($deferAttributes)) !== \false) {547 if (($attributeType = $this->getElement()->firstOfAttributes($deferAttributes)) !== \false) { 538 548 if ($attributeType != $this->prevDeferMatches) { 539 549 ++$this->deferIndex; 540 550 $this->prevDeferMatches = $attributeType; 541 551 } 542 $this->defers[$this->deferIndex][] = ['attributeType' => $attributeType, 'script' => $this-> element, 'content' => $content];552 $this->defers[$this->deferIndex][] = ['attributeType' => $attributeType, 'script' => $this->getElement(), 'content' => $content]; 543 553 $this->bLoadJsAsync = \false; 544 554 $this->excludeJsIEO(\false); … … 548 558 $this->jsExcludedIeo = \false; 549 559 $this->aJs[$this->iIndex_js][] = ['content' => Html::cleanScript($content, 'js')]; 550 $this->jsReplacements[$this->iIndex_js][] = $this-> element;560 $this->jsReplacements[$this->iIndex_js][] = $this->getElement(); 551 561 } 552 562 -
jch-optimize/trunk/lib/src/Html/HtmlElementBuilder.php
r2997317 r3040365 46 46 * @throws PregErrorException 47 47 */ 48 public static function load(string $html): BaseElement48 public static function load(string $html): HtmlElementInterface 49 49 { 50 50 $parser = new \JchOptimize\Core\Html\Parser(); -
jch-optimize/trunk/lib/src/Html/HtmlElementInterface.php
r2997317 r3040365 14 14 15 15 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 16 use JchOptimize\Core\Html\Elements\BaseElement; 16 17 18 /** 19 * @method BaseElement id(string $value) 20 * @method BaseElement class(string $value) 21 * @method BaseElement hidden(string $value) 22 * @method BaseElement style(string $value) 23 * @method BaseElement title(string $value) 24 * @method bool|string getId() 25 * @method array|bool getClass() 26 * @method bool|string getHidden() 27 * @method bool|string getStyle() 28 * @method bool|string getTitle() 29 */ 17 30 interface HtmlElementInterface 18 31 { … … 34 47 35 48 public function render(): string; 49 50 public function firstOfAttributes(array $attributes): UriInterface|array|string|bool; 51 52 public function data(string $name, UriInterface|array|string $value = ''): static; 53 54 public function getChildren(): array; 55 56 public function setParent(string $name): static; 57 58 public function getParent(): string; 36 59 } -
jch-optimize/trunk/lib/src/Html/HtmlManager.php
r2997317 r3040365 16 16 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 17 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 18 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;19 18 use _JchOptimizeVendor\Joomla\Filesystem\File; 20 19 use _JchOptimizeVendor\Laminas\Cache\Storage\FlushableInterface; … … 23 22 use _JchOptimizeVendor\Laminas\EventManager\EventManagerAwareInterface; 24 23 use _JchOptimizeVendor\Laminas\EventManager\EventManagerAwareTrait; 24 use _JchOptimizeVendor\Laminas\EventManager\EventManagerInterface; 25 25 use _JchOptimizeVendor\Laminas\EventManager\SharedEventManagerInterface; 26 26 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 27 27 use JchOptimize\Core\Cdn; 28 use JchOptimize\Core\Container\ContainerAwareTrait; 28 29 use JchOptimize\Core\Exception; 29 30 use JchOptimize\Core\FeatureHelpers\DynamicJs; … … 45 46 46 47 /** 48 * @var null|EventManagerInterface 49 */ 50 protected $events; 51 52 /** 47 53 * @var Processor 48 54 */ … … 54 60 * @var AsyncManager 55 61 */ 56 private \JchOptimize\Core\Html\AsyncManager $asyncManager;62 private ?\JchOptimize\Core\Html\AsyncManager $asyncManager = null; 57 63 58 64 /** … … 146 152 $html = \str_replace($defersRemoveArray, '', $html); 147 153 $this->oProcessor->setFullHtml($html); 148 // If we're loading javascript dynamically add the deferred javascript files to array of files to load dynamically instead 154 // If we're loading javascript dynamically add the deferred javascript files to array 155 // of files to load dynamically instead 149 156 if ($this->params->get('pro_reduce_unused_js_enable', '0')) { 150 157 // @see DynamicJs::prepareJsDynamicUrls() 151 158 $this->container->get(DynamicJs::class)->prepareJsDynamicUrls($defers); 152 159 } elseif (!empty($defers[0])) { 160 // Otherwise if there are any defers we just add them to the bottom of the page 153 161 foreach ($defers as $deferGroup) { 154 162 foreach ($deferGroup as $deferArray) { … … 323 331 } 324 332 } elseif (JCH_PRO) { 325 $this-> asyncManager->loadCssAsync($cssUrls);333 $this->getAsyncManager()->loadCssAsync($cssUrls); 326 334 } 327 335 } … … 350 358 { 351 359 if (JCH_PRO) { 352 $script = $this->cleanScript($this-> asyncManager->printHeaderScript());360 $script = $this->cleanScript($this->getAsyncManager()->printHeaderScript()); 353 361 if ($script) { 354 362 $this->appendChildToHead($script); … … 424 432 $css .= <<<CSS 425 433 426 @media (max-width: 991.98px) {434 @media (max-width: 767.98px) { 427 435 {$mobileCss} 428 436 } … … 433 441 $css .= <<<CSS 434 442 435 @media (min-width: 992px) {443 @media (min-width: 768px) { 436 444 {$desktopCss} 437 445 } … … 485 493 return $script; 486 494 } 495 496 protected function getAsyncManager(): AsyncManager 497 { 498 if ($this->asyncManager instanceof \JchOptimize\Core\Html\AsyncManager) { 499 return $this->asyncManager; 500 } 501 502 throw new Exception\PropertyNotFoundException('AsyncManager not set in '.\get_class($this)); 503 } 487 504 } -
jch-optimize/trunk/lib/src/Html/Parser.php
r2997317 r3040365 15 15 use CodeAlfa\RegexTokenizer\Html; 16 16 use JchOptimize\Core\Exception; 17 use JchOptimize\Core\Exception\PregErrorException; 17 18 use JchOptimize\Core\Html\Callbacks\AbstractCallback; 18 19 … … 21 22 { 22 23 use Html; 23 24 /**25 * @var true26 */27 24 public bool $alsoExcludeStringsAndComments = \false; 28 25 … … 80 77 81 78 /** 82 * @param AbstractCallback $callbackObject 83 * 84 * @return null|array|string|string[] 85 * 86 * @throws Exception\PregErrorException 79 * @throws PregErrorException 87 80 */ 88 public function processMatchesWithCallback(string $html, CallbackInterface $callbackObject) 81 public function processMatchesWithCallback(string $html, CallbackInterface $callbackObject): string 89 82 { 90 83 $regex = $this->getHtmlSearchRegex(); … … 92 85 $callbackObject->setRegex($regex); 93 86 } 94 $sProcessedHtml = \preg_replace_callback('#'.$regex.'#six', [$callbackObject, 'processMatches'], $html);87 $sProcessedHtml = (string) \preg_replace_callback('#'.$regex.'#six', [$callbackObject, 'processMatches'], $html); 95 88 96 89 try { -
jch-optimize/trunk/lib/src/Html/Processor.php
r2997317 r3040365 14 14 15 15 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 16 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 18 17 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 19 18 use JchOptimize\Core\Cdn as CdnCore; 19 use JchOptimize\Core\Container\ContainerAwareTrait; 20 20 use JchOptimize\Core\Css\Parser as CssParser; 21 21 use JchOptimize\Core\Exception; … … 207 207 { 208 208 $bLazyLoad = $this->params->get('lazyload_enable', '0') && !$this->isAmpPage; 209 if ($bLazyLoad || $this->params->get('pro_http2_push_enable', '0') || $this->params->get('pro_load_webp_images', '0') || $this->params->get('pro_l cp_images_enable', '0') || \JCH_DEBUG && $this->params->get('elements_above_fold_marker', '0')) {209 if ($bLazyLoad || $this->params->get('pro_http2_push_enable', '0') || $this->params->get('pro_load_webp_images', '0') || $this->params->get('pro_load_responsive_images', '0') || $this->params->get('pro_lcp_images_enable', '0') || \JCH_DEBUG && $this->params->get('elements_above_fold_marker', '0')) { 210 210 !\JCH_DEBUG ?: Profiler::start('LazyLoadImages'); 211 211 $sHtml = $this->getBodyHtml(); … … 258 258 public function processImageAttributes(): void 259 259 { 260 if ($this->params->get('img_attributes_enable', '0') || $this->params->get('lazyload_enable', '0') && $this->params->get('lazyload_autosize', '0') ) {260 if ($this->params->get('img_attributes_enable', '0') || $this->params->get('lazyload_enable', '0') && $this->params->get('lazyload_autosize', '0') || JCH_PRO && $this->params->get('pro_load_responsive_images', '0')) { 261 261 !\JCH_DEBUG ?: Profiler::start('ProcessImageAttributes'); 262 262 $oParser = new \JchOptimize\Core\Html\Parser(); -
jch-optimize/trunk/lib/src/Http2Preload.php
r3007001 r3040365 15 15 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;18 17 use _JchOptimizeVendor\Laminas\EventManager\Event; 19 18 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 19 use JchOptimize\Core\Container\ContainerAwareTrait; 20 20 use JchOptimize\Core\FeatureHelpers\Http2Excludes; 21 21 use JchOptimize\Core\Html\HtmlManager; … … 65 65 66 66 /** 67 * @param UriInterface $uri Url of file 67 * @param UriInterface $uri Url of file 68 * @param string[] $attributes 68 69 * 69 70 * @return false|void 70 71 */ 71 public function add(UriInterface $uri, string $type, string $fetchPriority = 'auto' )72 public function add(UriInterface $uri, string $type, string $fetchPriority = 'auto', array $attributes = []) 72 73 { 73 74 if (!$this->enable) { … … 92 93 return \false; 93 94 } 94 $this->internalAdd($uri, $type, $this->extension($uri), $fetchPriority );95 } 96 97 public function preload(UriInterface $uri, $type, $fontExt, $fetchPriority = ''): void95 $this->internalAdd($uri, $type, $this->extension($uri), $fetchPriority, $attributes); 96 } 97 98 public function preload(UriInterface $uri, string $type, string $fontExt, string $fetchPriority = '', array $attributes = []): void 98 99 { 99 100 if ($this->validateUri($uri)) { 100 $this->internalAdd($uri, $type, $fontExt, $fetchPriority );101 } 102 } 103 104 public function addAdditional(UriInterface $uri, string $type, string $fontExt, $fetchPriority = 'auto'): void101 $this->internalAdd($uri, $type, $fontExt, $fetchPriority, $attributes); 102 } 103 } 104 105 public function addAdditional(UriInterface $uri, string $type, string $fontExt, string $fetchPriority = 'auto', array $attributes = []): void 105 106 { 106 107 if ($this->enable) { 107 $this-> internalAdd($uri, $type, $fontExt, $fetchPriority);108 $this->preload($uri, $type, $fontExt, $fetchPriority, $attributes); 108 109 } 109 110 } … … 204 205 } 205 206 206 private function internalAdd(UriInterface $uri, string $type, string $fontExt = '', string $fetchPriority = 'auto'): void 207 /** 208 * @param string[] $attributes 209 */ 210 private function internalAdd(UriInterface $uri, string $type, string $fontExt = '', string $fetchPriority = 'auto', array $attributes = []): void 207 211 { 208 212 $RR_uri = $this->cdn->loadCdnResource(UriNormalizer::normalize($uri)); … … 211 215 $RR_uri = UriConverter::absToNetworkPathReference($RR_uri); 212 216 } 213 $preload = ['href' => (string) $RR_uri, 'as' => $type];217 $preload = \array_merge(['href' => (string) $RR_uri, 'as' => $type], $attributes); 214 218 if ('auto' != $fetchPriority) { 215 219 $preload['fetchpriority'] = $fetchPriority; … … 279 283 } 280 284 } 281 // We need to decide how we're going to preload this file. If it's loaded by CDN or if we're using Capture cache we need 285 // We need to decide how we're going to preload this file. 286 // If it's loaded by CDN or if we're using Capture cache we need 282 287 // to put it in the HTML, otherwise we can send a link header, better IMO. 283 288 // Let's make the default method 'link' 284 289 $method = 'link'; 285 if ($this->cdn->isFileOnCdn($RR_uri) || UriComparator::isCrossOrigin($RR_uri) || Cache::isPageCacheEnabled($this->params, \true) && JCH_PRO && $this->params->get('pro_capture_cache_enable', '1') && !$this->params->get('pro_cache_platform', '0') || 'auto' != $fetchPriority ) {290 if ($this->cdn->isFileOnCdn($RR_uri) || UriComparator::isCrossOrigin($RR_uri) || Cache::isPageCacheEnabled($this->params, \true) && JCH_PRO && $this->params->get('pro_capture_cache_enable', '1') && !$this->params->get('pro_cache_platform', '0') || 'auto' != $fetchPriority || !empty($attributes)) { 286 291 $method = 'html'; 287 292 } -
jch-optimize/trunk/lib/src/Interfaces/Paths.php
r2997317 r3040365 33 33 * Path to the directory where generated sprite images are saved. 34 34 * 35 * @param bool $isRootRelative if true, return the root relative path with trailing slash; if false, return the absolute path without trailing slash 35 * @param bool $isRootRelative if true, return the root relative path with trailing slash; 36 * if false, return the absolute path without trailing slash 36 37 */ 37 38 public static function spritePath(bool $isRootRelative = \false): string; … … 45 46 46 47 /** 47 * The base folder for rewrites when the combined files are delivered with PHP using mod_rewrite. Generally the parent directory for the48 * /media/ folder with a root relative path.48 * The base folder for rewrites when the combined files are delivered with PHP using mod_rewrite. 49 * Generally the parent directory for the /media/ folder with a root relative path. 49 50 */ 50 51 public static function rewriteBaseFolder(): string; … … 61 62 */ 62 63 public static function rootPath(): string; 64 65 public static function basePath(): string; 63 66 64 67 /** … … 123 126 */ 124 127 public static function templateCachePath(): string; 128 129 public static function responsiveImagePath(bool $isRootRelative = \false): string; 125 130 } -
jch-optimize/trunk/lib/src/Laminas/ArrayPaginator.php
r2997317 r3040365 6 6 use _JchOptimizeVendor\Laminas\Paginator\Paginator; 7 7 8 /** 9 * @psalm-suppress PropertyNotSetInConstructor 10 */ 8 11 class ArrayPaginator extends Paginator 9 12 { -
jch-optimize/trunk/lib/src/Laminas/Plugins/ClearExpiredByFactor.php
r3007001 r3040365 14 14 15 15 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;17 16 use _JchOptimizeVendor\Joomla\Filesystem\File; 18 17 use _JchOptimizeVendor\Laminas\Cache\Exception\ExceptionInterface; … … 26 25 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 27 26 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 27 use JchOptimize\Core\Container\ContainerAwareTrait; 28 28 use JchOptimize\Core\PageCache\PageCache; 29 29 use JchOptimize\Core\Registry; … … 32 32 use JchOptimize\Platform\Paths; 33 33 use JchOptimize\Platform\Profiler; 34 use Throwable; 34 35 35 36 use function time; … … 100 101 $ttl = $cache->getOptions()->getTtl(); 101 102 $time = \time(); 102 // Get ids of all files used on this page 103 $fileIds = $taggableCache->getTags(\md5($pageCache->getCurrentPage())); 104 foreach ($fileIds as $fileId) { 105 $metaData = $taggableCache->getMetadata($fileId); 103 $itemDeletedFlag = \false; 104 foreach ($taggableCache->getIterator() as $item) { 105 $metaData = $taggableCache->getMetadata($item); 106 106 if (!\is_array($metaData) || empty($metaData)) { 107 107 continue; 108 108 } 109 $tags = $taggableCache->getTags($item); 110 if (!\is_array($tags) || empty($tags)) { 111 continue; 112 } 113 if ('pagecache' == $tags[0]) { 114 continue; 115 } 109 116 $mtime = (int) $metaData['mtime']; 110 if ($time >= $mtime + $ttl) { 111 $pageCacheUrls = $taggableCache->getTags($fileId); 112 foreach ($pageCacheUrls as $pageCacheUrl) { 117 if ($time > $mtime + $ttl) { 118 foreach ($tags as $pageCacheUrl) { 113 119 $pageCacheId = $pageCache->getPageCacheId(Utils::uriFor($pageCacheUrl)); 114 120 if (!$pageCache->deleteItemById($pageCacheId)) { … … 116 122 } 117 123 } 118 $cache->removeItem($fileId); 119 $deleteTag = !$cache->hasItem($fileId); 124 $cache->removeItem($item); 125 $deleteTag = !$cache->hasItem($item); 126 if ($deleteTag) { 127 $itemDeletedFlag = \true; 128 } 120 129 // We need to also delete the static css/js file if that option is set 121 130 if ('2' == $params->get('htaccess', '2')) { 122 $files = [Paths::cachePath(\false).'/css/'.$ fileId.'.css', Paths::cachePath(\false).'/js/'.$fileId.'.js'];131 $files = [Paths::cachePath(\false).'/css/'.$item.'.css', Paths::cachePath(\false).'/js/'.$item.'.js']; 123 132 124 133 try { … … 134 143 } 135 144 } 136 } catch ( \Throwable $e) {145 } catch (Throwable) { 137 146 // Don't bother to delete the tags if this didn't work 138 147 $deleteTag = \false; … … 140 149 } 141 150 if ($deleteTag) { 142 $taggableCache->removeItem($ fileId);151 $taggableCache->removeItem($item); 143 152 } 144 153 } 145 154 } 146 if ( !empty($itemsOnPages)) {155 if ($itemDeletedFlag) { 147 156 // Finally attempt to clean any third party page cache 148 157 Cache::cleanThirdPartyPageCache(); -
jch-optimize/trunk/lib/src/Mvc/Controller.php
r2997317 r3040365 5 5 use _JchOptimizeVendor\Joomla\Controller\AbstractController; 6 6 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 7 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;8 7 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 9 8 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 9 use JchOptimize\Core\Container\ContainerAwareTrait; 10 10 11 11 abstract class Controller extends AbstractController implements ContainerAwareInterface, LoggerAwareInterface -
jch-optimize/trunk/lib/src/Mvc/Model.php
r2997317 r3040365 4 4 5 5 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 6 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;7 6 use _JchOptimizeVendor\Joomla\Model\DatabaseModelInterface; 8 7 use _JchOptimizeVendor\Joomla\Model\DatabaseModelTrait; 9 8 use _JchOptimizeVendor\Joomla\Model\StatefulModelInterface; 10 9 use _JchOptimizeVendor\Joomla\Model\StatefulModelTrait; 10 use JchOptimize\Core\Container\ContainerAwareTrait; 11 11 12 12 class Model implements ContainerAwareInterface, DatabaseModelInterface, StatefulModelInterface -
jch-optimize/trunk/lib/src/Optimize.php
r2997317 r3040365 15 15 // No direct access 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;18 17 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 19 18 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 20 19 use CodeAlfa\Minify\Html; 20 use JchOptimize\Core\Container\ContainerAwareTrait; 21 21 use JchOptimize\Core\FeatureHelpers\ReduceDom; 22 22 use JchOptimize\Core\Html\CacheManager; … … 36 36 use ContainerAwareTrait; 37 37 38 private Registry $params; 38 /** 39 * @var Registry 40 */ 41 private \JchOptimize\Core\Registry $params; 39 42 40 43 private HtmlProcessor $htmlProcessor; … … 44 47 private HtmlManager $htmlManager; 45 48 46 private string $html ;49 private string $html = ''; 47 50 48 51 private string $jit = '1'; … … 69 72 } 70 73 if (\version_compare(\PHP_VERSION, '7.3', '<')) { 71 throw new Exception\RuntimeException('PHP Version less than 7.3, Exiting plugin...');74 throw new \JchOptimize\Core\Exception\RuntimeException('PHP Version less than 7.3, Exiting plugin...'); 72 75 } 73 76 $pcre_version = \preg_replace('#(^\\d++\\.\\d++).++$#', '$1', \PCRE_VERSION); 74 77 if (\version_compare($pcre_version, '7.2', '<')) { 75 throw new Exception\RuntimeException('PCRE Version less than 7.2. Exiting plugin...');78 throw new \JchOptimize\Core\Exception\RuntimeException('PCRE Version less than 7.2. Exiting plugin...'); 76 79 } 77 80 $this->params = $params; … … 108 111 JCH_DEBUG ? Profiler::stop('Process', \true) : null; 109 112 JCH_DEBUG ? Profiler::attachProfiler($optimizedHtml, $this->htmlProcessor->isAmpPage) : null; 110 } catch ( Exception\ExceptionInterface $e) {113 } catch (\JchOptimize\Core\Exception\ExceptionInterface $e) { 111 114 $this->logger->error((string) $e); 112 115 $optimizedHtml = $this->html; -
jch-optimize/trunk/lib/src/Output.php
r2997317 r3040365 57 57 return \false; 58 58 } 59 if ($bSend) {60 $aTimeMFile = self::RFC1123DateAdd($results[0]['filemtime'], '1 year');61 $timeMfile = $aTimeMFile['filemtime'].' GMT';62 $expiryDate = $aTimeMFile['expiry'].' GMT';63 $modifiedSinceTime = '';64 $noneMatch = '';65 if (\function_exists('apache_request_headers')) {66 $headers = \apache_request_headers();67 if (isset($headers['If-Modified-Since'])) {68 $modifiedSinceTime = \strtotime($headers['If-Modified-Since']);69 }70 if (isset($headers['If-None-Match'])) {71 $noneMatch = $headers['If-None-Match'];72 }73 }74 if ('' == $modifiedSinceTime && !\is_null($input->server->getString('HTTP_IF_MODIFIED_SINCE'))) {75 $modifiedSinceTime = \strtotime($input->server->getString('HTTP_IF_MODIFIED_SINCE'));76 }77 if ('' == $noneMatch && !\is_null($input->server->getString('HTTP_IF_NONE_MATCH'))) {78 $noneMatch = $input->server->getString('HTTP_IF_NONE_MATCH');79 }80 $etag = $results[0]['etag'];81 if ($modifiedSinceTime == \strtotime($timeMfile) || \trim($noneMatch) == $etag) {82 // Client's cache IS current, so we just respond '304 Not Modified'.83 \header('HTTP/1.1 304 Not Modified');84 \header('Content-Length: 0');85 86 return;87 }88 \header('Last-Modified: '.$timeMfile);89 }90 59 $file = $results[0]['contents']; 91 60 // Return file if we're not outputting to browser … … 93 62 return $file; 94 63 } 64 $aTimeMFile = self::RFC1123DateAdd($results[0]['filemtime'], '1 year'); 65 $timeMFile = $aTimeMFile['filemtime'].' GMT'; 66 $expiryDate = $aTimeMFile['expiry'].' GMT'; 67 $modifiedSinceTime = ''; 68 $noneMatch = ''; 69 if (\function_exists('apache_request_headers')) { 70 $headers = \apache_request_headers(); 71 if (isset($headers['If-Modified-Since'])) { 72 $modifiedSinceTime = \strtotime($headers['If-Modified-Since']); 73 } 74 if (isset($headers['If-None-Match'])) { 75 $noneMatch = $headers['If-None-Match']; 76 } 77 } 78 if ('' == $modifiedSinceTime && !\is_null($input->server->getString('HTTP_IF_MODIFIED_SINCE'))) { 79 $modifiedSinceTime = \strtotime($input->server->getString('HTTP_IF_MODIFIED_SINCE')); 80 } 81 if ('' == $noneMatch && !\is_null($input->server->getString('HTTP_IF_NONE_MATCH'))) { 82 $noneMatch = $input->server->getString('HTTP_IF_NONE_MATCH'); 83 } 84 $etag = $results[0]['etag']; 85 if ($modifiedSinceTime == \strtotime($timeMFile) || \trim($noneMatch) == $etag) { 86 // Client's cache IS current, so we just respond '304 Not Modified'. 87 \header('HTTP/1.1 304 Not Modified'); 88 \header('Content-Length: 0'); 89 90 return; 91 } 92 \header('Last-Modified: '.$timeMFile); 93 95 94 if ('css' == $vars['type']) { 96 95 \header('Content-type: text/css'); -
jch-optimize/trunk/lib/src/PageCache/PageCache.php
r3007001 r3040365 15 15 use _JchOptimizeVendor\GuzzleHttp\Psr7\Uri; 16 16 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 17 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;18 17 use _JchOptimizeVendor\Joomla\Input\Input; 19 18 use _JchOptimizeVendor\Laminas\Cache\Exception\ExceptionInterface; … … 24 23 use _JchOptimizeVendor\Psr\Log\LoggerAwareInterface; 25 24 use _JchOptimizeVendor\Psr\Log\LoggerAwareTrait; 25 use JchOptimize\Core\Container\ContainerAwareTrait; 26 26 use JchOptimize\Core\Helper; 27 27 use JchOptimize\Core\Laminas\Plugins\ClearExpiredByFactor; … … 48 48 * Cache id. 49 49 */ 50 protected string $cacheId ;50 protected string $cacheId = ''; 51 51 52 52 /** … … 306 306 } 307 307 308 public function removeHtmlTag( $html): ?string308 public function removeHtmlTag(string $html): ?string 309 309 { 310 310 $search = '#<!-- Cached by JCH Optimize on .*? GMT -->\\n#'; -
jch-optimize/trunk/lib/src/Service/CachingProvider.php
r3007001 r3040365 139 139 { 140 140 $params = $container->get(Registry::class); 141 // Use whichever lifetime is greater to ensure page cache expires before142 $pageCacheTtl = (int) $params->get('page_cache_lifetime', '900');143 $globalTtl = (int) $params->get('cache_lifetime', '900');144 $lifetime = \max($pageCacheTtl, $globalTtl);145 141 $cache = $this->getCacheAdapter($container, $container->get(Registry::class)->get('pro_cache_storage_adapter', 'filesystem')); 146 $cache->getOptions()->setNamespace(Cache::getGlobalCacheNamespace())->setTtl( $lifetime);142 $cache->getOptions()->setNamespace(Cache::getGlobalCacheNamespace())->setTtl((int) $params->get('cache_lifetime', '900')); 147 143 if ($cache instanceof PluginAwareInterface) { 148 144 if ($params->get('delete_expiry', '1')) { -
jch-optimize/trunk/lib/src/Service/CoreProvider.php
r2997317 r3040365 116 116 } 117 117 118 /** 119 * @psalm-suppress InvalidArgument 120 */ 118 121 public function getCacheManagerService(Container $container): CacheManager 119 122 { … … 156 159 } 157 160 161 /** 162 * @psalm-suppress InvalidArgument 163 */ 158 164 public function getCombinerService(Container $container): Combiner 159 165 { … … 182 188 } 183 189 190 /** 191 * @psalm-suppress InvalidArgument 192 */ 184 193 public function getPageCacheService(Container $container): PageCache 185 194 { … … 194 203 } 195 204 205 /** 206 * @psalm-suppress InvalidArgument 207 */ 196 208 public function getCaptureCacheService(Container $container): CoreCaptureCache 197 209 { -
jch-optimize/trunk/lib/src/StorageTaggingTrait.php
r3007001 r3040365 16 16 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 17 17 use JchOptimize\Core\PageCache\PageCache; 18 19 use function md5; 18 20 19 21 \defined('_JCH_EXEC') or exit('Restricted access'); … … 36 38 $this->setStorageTags($id, $currentUrl); 37 39 // create an id for currentUrl and tag the cache ids saved on that page 38 $tagPageId = \md5($currentUrl);40 // $tagPageId = md5($currentUrl); 39 41 // Record ids of all files used on this page 40 $this->taggableCache->addItem($tagPageId, (string)$currentUrl);41 $this->setStorageTags($tagPageId, $id);42 // $this->taggableCache->addItem($tagPageId, (string)$currentUrl); 43 // $this->setStorageTags($tagPageId, $id); 42 44 } 43 45 … … 47 49 // If current tag not yet included, add it. 48 50 if (\is_array($tags) && !\in_array($tag, $tags)) { 49 // Limit tags to the first 100 50 if (\count($tags) < 100) { 51 $this->taggableCache->setTags($id, \array_merge($tags, [$tag])); 52 } 51 $this->taggableCache->setTags($id, \array_merge($tags, [$tag])); 53 52 } elseif (empty($tags)) { 54 53 $this->taggableCache->setTags($id, [$tag]); -
jch-optimize/trunk/lib/src/Uri/UriComparator.php
r2997317 r3040365 4 4 * JCH Optimize - Performs several front-end optimizations for fast downloads. 5 5 * 6 * @author Samuel Marshall <samuel@jch-optimize.net>7 * @copyright Copyright (c) 2023 Samuel Marshall / JCH Optimize8 * @license GNU/GPLv3, or later. See LICENSE file6 * @author Samuel Marshall <samuel@jch-optimize.net> 7 * @copyright Copyright (c) 2023 Samuel Marshall / JCH Optimize 8 * @license GNU/GPLv3, or later. See LICENSE file 9 9 * 10 10 * If LICENSE file missing, see <http://www.gnu.org/licenses/>. -
jch-optimize/trunk/lib/src/Uri/UriConverter.php
r2997317 r3040365 16 16 use _JchOptimizeVendor\GuzzleHttp\Psr7\UriResolver; 17 17 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 18 use JchOptimize\Core\Cdn; 18 19 use JchOptimize\Core\SystemUri; 19 20 use JchOptimize\Platform\Paths; … … 24 25 { 25 26 $resolvedUri = UriResolver::resolve(SystemUri::currentUri(), $uri); 26 $path = \str_replace(\JchOptimize\Core\Uri\Utils::originDomains(), Paths:: rootPath().'/', (string) $resolvedUri->withQuery('')->withFragment(''));27 $path = \str_replace(\JchOptimize\Core\Uri\Utils::originDomains(), Paths::basePath().'/', (string) $resolvedUri->withQuery('')->withFragment('')); 27 28 // convert all directory to unix style 28 29 return \strtr(\rawurldecode($path), '\\', '/'); … … 40 41 return $uri->withScheme('')->withHost('')->withPort(null); 41 42 } 43 44 public static function filePathToUri(string|UriInterface $path, Cdn $cdn): UriInterface 45 { 46 $uri = \JchOptimize\Core\Uri\Utils::uriFor($path); 47 $uri = $uri->withPath(SystemUri::basePath().\ltrim(\str_replace(Paths::basePath(), '', $uri->getPath()), '/\\')); 48 $uri = UriResolver::resolve(SystemUri::currentUri(), $uri->withScheme('')); 49 50 return $cdn->loadCdnResource($uri); 51 } 42 52 } -
jch-optimize/trunk/lib/src/Uri/Utils.php
r2997317 r3040365 17 17 use _JchOptimizeVendor\GuzzleHttp\Psr7\Utils as GuzzleUtils; 18 18 use _JchOptimizeVendor\Psr\Http\Message\UriInterface; 19 use InvalidArgumentException; 19 20 use JchOptimize\ContainerFactory; 20 21 use JchOptimize\Core\Cdn; … … 46 47 * received value, an '_invalidUri' string is returned, 47 48 * Use this whenever possible as Windows paths are converted to unix style so Uris can be created. 48 *49 * @param string|UriInterface $uri50 49 */ 51 public static function uriFor( $uri): UriInterface50 public static function uriFor(UriInterface|string $uri): UriInterface 52 51 { 53 52 // convert Window directory to unix style … … 58 57 try { 59 58 return \JchOptimize\Core\Uri\UriNormalizer::normalize(GuzzleUtils::uriFor($uri)); 60 } catch ( \InvalidArgumentException $e) {59 } catch (InvalidArgumentException) { 61 60 return new Uri('_invalidUri'); 62 61 } -
jch-optimize/trunk/lib/src/class_map.php
r3007001 r3040365 20 20 use _JchOptimizeVendor\Joomla\DI\Container; 21 21 use _JchOptimizeVendor\Joomla\DI\ContainerAwareInterface; 22 use _JchOptimizeVendor\Joomla\DI\ContainerAwareTrait;23 22 use _JchOptimizeVendor\Joomla\DI\ServiceProviderInterface; 24 23 use _JchOptimizeVendor\Joomla\Filesystem\File; … … 57 56 if (!\interface_exists('\\JchOptimize\\Core\\Container\\ContainerAwareInterface', \false)) { 58 57 \class_alias(ContainerAwareInterface::class, '\\JchOptimize\\Core\\Container\\ContainerAwareInterface'); 59 }60 if (!\trait_exists('\\JchOptimize\\Core\\Container\\ContainerAwareTrait', \false)) {61 \class_alias(ContainerAwareTrait::class, '\\JchOptimize\\Core\\Container\\ContainerAwareTrait');62 58 } 63 59 if (!\interface_exists('\\JchOptimize\\Core\\Container\\ServiceProviderInterface', \false)) { -
jch-optimize/trunk/lib/vendor/composer/autoload_classmap.php
r3007001 r3040365 22 22 'JchOptimize\\Core\\Admin\\API\\MessageEventFactory' => $baseDir . '/src/Admin/API/MessageEventFactory.php', 23 23 'JchOptimize\\Core\\Admin\\API\\MessageEventInterface' => $baseDir . '/src/Admin/API/MessageEventInterface.php', 24 'JchOptimize\\Core\\Admin\\API\\NullEventMessenger' => $baseDir . '/src/Admin/API/NullEventMessenger.php', 24 25 'JchOptimize\\Core\\Admin\\API\\ProcessImagesByFolders' => $baseDir . '/src/Admin/API/ProcessImagesByFolders.php', 25 26 'JchOptimize\\Core\\Admin\\API\\ProcessImagesByUrls' => $baseDir . '/src/Admin/API/ProcessImagesByUrls.php', … … 40 41 'JchOptimize\\Core\\Combiner' => $baseDir . '/src/Combiner.php', 41 42 'JchOptimize\\Core\\Container\\AbstractContainerFactory' => $baseDir . '/src/Container/AbstractContainerFactory.php', 43 'JchOptimize\\Core\\Container\\ContainerAwareTrait' => $baseDir . '/src/Container/ContainerAwareTrait.php', 42 44 'JchOptimize\\Core\\Css\\Callbacks\\AbstractCallback' => $baseDir . '/src/Css/Callbacks/AbstractCallback.php', 43 45 'JchOptimize\\Core\\Css\\Callbacks\\CombineMediaQueries' => $baseDir . '/src/Css/Callbacks/CombineMediaQueries.php', … … 62 64 'JchOptimize\\Core\\Exception\\MissingDependencyException' => $baseDir . '/src/Exception/MissingDependencyException.php', 63 65 'JchOptimize\\Core\\Exception\\PregErrorException' => $baseDir . '/src/Exception/PregErrorException.php', 66 'JchOptimize\\Core\\Exception\\PropertyNotFoundException' => $baseDir . '/src/Exception/PropertyNotFoundException.php', 64 67 'JchOptimize\\Core\\Exception\\RuntimeException' => $baseDir . '/src/Exception/RuntimeException.php', 65 68 'JchOptimize\\Core\\Exception\\StringableTrait' => $baseDir . '/src/Exception/StringableTrait.php', … … 72 75 'JchOptimize\\Core\\FeatureHelpers\\LazyLoadExtended' => $baseDir . '/src/FeatureHelpers/LazyLoadExtended.php', 73 76 'JchOptimize\\Core\\FeatureHelpers\\ReduceDom' => $baseDir . '/src/FeatureHelpers/ReduceDom.php', 77 'JchOptimize\\Core\\FeatureHelpers\\ResponsiveImages' => $baseDir . '/src/FeatureHelpers/ResponsiveImages.php', 74 78 'JchOptimize\\Core\\FeatureHelpers\\Webp' => $baseDir . '/src/FeatureHelpers/Webp.php', 75 79 'JchOptimize\\Core\\FileInfosUtilsTrait' => $baseDir . '/src/FileInfosUtilsTrait.php', -
jch-optimize/trunk/lib/vendor/composer/autoload_static.php
r3007001 r3040365 285 285 'JchOptimize\\Core\\Admin\\API\\MessageEventFactory' => __DIR__ . '/../..' . '/src/Admin/API/MessageEventFactory.php', 286 286 'JchOptimize\\Core\\Admin\\API\\MessageEventInterface' => __DIR__ . '/../..' . '/src/Admin/API/MessageEventInterface.php', 287 'JchOptimize\\Core\\Admin\\API\\NullEventMessenger' => __DIR__ . '/../..' . '/src/Admin/API/NullEventMessenger.php', 287 288 'JchOptimize\\Core\\Admin\\API\\ProcessImagesByFolders' => __DIR__ . '/../..' . '/src/Admin/API/ProcessImagesByFolders.php', 288 289 'JchOptimize\\Core\\Admin\\API\\ProcessImagesByUrls' => __DIR__ . '/../..' . '/src/Admin/API/ProcessImagesByUrls.php', … … 303 304 'JchOptimize\\Core\\Combiner' => __DIR__ . '/../..' . '/src/Combiner.php', 304 305 'JchOptimize\\Core\\Container\\AbstractContainerFactory' => __DIR__ . '/../..' . '/src/Container/AbstractContainerFactory.php', 306 'JchOptimize\\Core\\Container\\ContainerAwareTrait' => __DIR__ . '/../..' . '/src/Container/ContainerAwareTrait.php', 305 307 'JchOptimize\\Core\\Css\\Callbacks\\AbstractCallback' => __DIR__ . '/../..' . '/src/Css/Callbacks/AbstractCallback.php', 306 308 'JchOptimize\\Core\\Css\\Callbacks\\CombineMediaQueries' => __DIR__ . '/../..' . '/src/Css/Callbacks/CombineMediaQueries.php', … … 325 327 'JchOptimize\\Core\\Exception\\MissingDependencyException' => __DIR__ . '/../..' . '/src/Exception/MissingDependencyException.php', 326 328 'JchOptimize\\Core\\Exception\\PregErrorException' => __DIR__ . '/../..' . '/src/Exception/PregErrorException.php', 329 'JchOptimize\\Core\\Exception\\PropertyNotFoundException' => __DIR__ . '/../..' . '/src/Exception/PropertyNotFoundException.php', 327 330 'JchOptimize\\Core\\Exception\\RuntimeException' => __DIR__ . '/../..' . '/src/Exception/RuntimeException.php', 328 331 'JchOptimize\\Core\\Exception\\StringableTrait' => __DIR__ . '/../..' . '/src/Exception/StringableTrait.php', … … 335 338 'JchOptimize\\Core\\FeatureHelpers\\LazyLoadExtended' => __DIR__ . '/../..' . '/src/FeatureHelpers/LazyLoadExtended.php', 336 339 'JchOptimize\\Core\\FeatureHelpers\\ReduceDom' => __DIR__ . '/../..' . '/src/FeatureHelpers/ReduceDom.php', 340 'JchOptimize\\Core\\FeatureHelpers\\ResponsiveImages' => __DIR__ . '/../..' . '/src/FeatureHelpers/ResponsiveImages.php', 337 341 'JchOptimize\\Core\\FeatureHelpers\\Webp' => __DIR__ . '/../..' . '/src/FeatureHelpers/Webp.php', 338 342 'JchOptimize\\Core\\FileInfosUtilsTrait' => __DIR__ . '/../..' . '/src/FileInfosUtilsTrait.php', -
jch-optimize/trunk/lib/vendor/composer/installed.php
r3007001 r3040365 3 3 namespace _JchOptimizeVendor; 4 4 5 return array('root' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'reference' => ' de0f05ea1fea90b0cae6c3abfdf52f3d1180cca3', 'name' => 'jchoptimize/lib', 'dev' => \false), 'versions' => array('codealfa/minify' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../codealfa/minify', 'aliases' => array(0 => '9999999-dev'), 'reference' => 'a11d3fc4da27e170ca8cb9f966915ff9cfdc519d', 'dev_requirement' => \false), 'codealfa/regextokenizer' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../codealfa/regextokenizer', 'aliases' => array(0 => '9999999-dev'), 'reference' => 'b660bf5d561078f40bcbf1a68eeb63428a14b17d', 'dev_requirement' => \false), 'composer/ca-bundle' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(0 => '1.x-dev'), 'reference' => '4d0ae9807cf38e759b6f10b09195b3addd7d8685', 'dev_requirement' => \false), 'container-interop/container-interop' => array('dev_requirement' => \false, 'replaced' => array(0 => '^1.2.0')), 'guzzlehttp/guzzle' => array('pretty_version' => '7.5.x-dev', 'version' => '7.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), 'reference' => '584d1f06b5caa07b0587f5054d551ed65460ce5d', 'dev_requirement' => \false), 'guzzlehttp/promises' => array('pretty_version' => '1.5.x-dev', 'version' => '1.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), 'reference' => '67ab6e18aaa14d753cc148911d273f6e6cb6721e', 'dev_requirement' => \false), 'guzzlehttp/psr7' => array('pretty_version' => '1.9.x-dev', 'version' => '1.9.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), 'reference' => 'e4490cabc77465aaee90b20cfc9a770f8c04be6b', 'dev_requirement' => \false), 'illuminate/collections' => array('pretty_version' => '8.x-dev', 'version' => '8.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/collections', 'aliases' => array(), 'reference' => '705a4e1ef93cd492c45b9b3e7911cccc990a07f4', 'dev_requirement' => \false), 'illuminate/contracts' => array('pretty_version' => '8.x-dev', 'version' => '8.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/contracts', 'aliases' => array(), 'reference' => '5e0fd287a1b22a6b346a9f7cd484d8cf0234585d', 'dev_requirement' => \false), 'illuminate/macroable' => array('pretty_version' => '8.x-dev', 'version' => '8.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/macroable', 'aliases' => array(), 'reference' => 'aed81891a6e046fdee72edd497f822190f61c162', 'dev_requirement' => \false), 'intervention/image' => array('pretty_version' => '2.7.2', 'version' => '2.7.2.0', 'type' => 'library', 'install_path' => __DIR__ . '/../intervention/image', 'aliases' => array(), 'reference' => '04be355f8d6734c826045d02a1079ad658322dad', 'dev_requirement' => \false), 'jchoptimize/lib' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'reference' => 'de0f05ea1fea90b0cae6c3abfdf52f3d1180cca3', 'dev_requirement' => \false), 'joomla/controller' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/controller', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '6a5a386246f6e67ab0c3a4e71d27f0f208720b65', 'dev_requirement' => \false), 'joomla/di' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/di', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'b68f8de6c3a214eac22c2172f966d8965fd47f9c', 'dev_requirement' => \false), 'joomla/filesystem' => array('pretty_version' => 'dev-1.x-dev', 'version' => 'dev-1.x-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/filesystem', 'aliases' => array(), 'reference' => '9ad5d9b64960f0ea56fb71364a33622843b95c27', 'dev_requirement' => \false), 'joomla/filter' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/filter', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '9102630f9069351c1259b6f585a704fde7029d2a', 'dev_requirement' => \false), 'joomla/input' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/input', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '80d2b6384d60307a11b9af39bdc9a8d254949e94', 'dev_requirement' => \false), 'joomla/model' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/model', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'f322645993346efa5505500f59d6471cbd0d564b', 'dev_requirement' => \false), 'joomla/registry' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/registry', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'fde95733e7e2634d64bff71f611ee02b9ceff354', 'dev_requirement' => \false), 'joomla/renderer' => array('pretty_version' => '2.0.1', 'version' => '2.0.1.0', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/renderer', 'aliases' => array(), 'reference' => '0b514c40d3858fbbbf3bf3347832bc4fc3e776da', 'dev_requirement' => \false), 'joomla/string' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/string', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'c7a9330f7316a574f3ff538053fa65dc38bafbe6', 'dev_requirement' => \false), 'joomla/utilities' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/utilities', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '2baa8af18fd2ee5a185606b91ab2e273f77e5e4b', 'dev_requirement' => \false), 'joomla/view' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/view', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '7d5e706b29cac01d0b1ee11b871eabaa823f9063', 'dev_requirement' => \false), 'laminas/laminas-cache' => array('pretty_version' => '3.0.x-dev', 'version' => '3.0.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache', 'aliases' => array(), 'reference' => '86b47eb7b05bc4d24edafb3039494ba81405983b', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-apcu' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-apcu', 'aliases' => array(), 'reference' => '344aa69ff029788bd340a3bda63754d24623bd85', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-blackhole' => array('pretty_version' => '2.0.x-dev', 'version' => '2.0.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-blackhole', 'aliases' => array(), 'reference' => 'fdb6c4b9813cc7365d72c002b09dc808e34b7002', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-filesystem' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-filesystem', 'aliases' => array(), 'reference' => 'd9712a8292fc0a84219e4aba97b6b04b95057cb6', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-memcached' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-memcached', 'aliases' => array(), 'reference' => '5d6795281f388842ed96acbfc3f8659d0742282f', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-redis' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-redis', 'aliases' => array(), 'reference' => '289717d10a89755d3f36f799565a3fb9c7e9ab24', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'laminas/laminas-eventmanager' => array('pretty_version' => '3.11.x-dev', 'version' => '3.11.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-eventmanager', 'aliases' => array(), 'reference' => '9cfa79ce247c567f05ce4b7c975c6bdf9698c5dd', 'dev_requirement' => \false), 'laminas/laminas-json' => array('pretty_version' => '3.5.x-dev', 'version' => '3.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-json', 'aliases' => array(), 'reference' => '7a8a1d7bf2d05dd6c1fbd7c0868d3848cf2b57ec', 'dev_requirement' => \false), 'laminas/laminas-log' => array('pretty_version' => '2.14.x-dev', 'version' => '2.14.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-log', 'aliases' => array(), 'reference' => '39f3dcbd77fd0d84b190ff1332f5d3d28d56527e', 'dev_requirement' => \false), 'laminas/laminas-paginator' => array('pretty_version' => '2.11.x-dev', 'version' => '2.11.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-paginator', 'aliases' => array(), 'reference' => '7f00d5fdecd1b4f67c8e84e6f6d57bbabda4b7d8', 'dev_requirement' => \false), 'laminas/laminas-serializer' => array('pretty_version' => '2.12.x-dev', 'version' => '2.12.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-serializer', 'aliases' => array(), 'reference' => '2826fd71f202569c169456a4b84297da9ff630cd', 'dev_requirement' => \false), 'laminas/laminas-servicemanager' => array('pretty_version' => '3.20.x-dev', 'version' => '3.20.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-servicemanager', 'aliases' => array(), 'reference' => 'bc2c2cbe2dd90db8b9d16b0618f542692b76ab59', 'dev_requirement' => \false), 'laminas/laminas-stdlib' => array('pretty_version' => '3.16.x-dev', 'version' => '3.16.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-stdlib', 'aliases' => array(), 'reference' => 'f4f773641807c7ccee59b758bfe4ac4ba33ecb17', 'dev_requirement' => \false), 'league/flysystem' => array('pretty_version' => '2.x-dev', 'version' => '2.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../league/flysystem', 'aliases' => array(), 'reference' => '8aaffb653c5777781b0f7f69a5d937baf7ab6cdb', 'dev_requirement' => \false), 'league/glide' => array('pretty_version' => '2.3.0', 'version' => '2.3.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../league/glide', 'aliases' => array(), 'reference' => '2ff92c8f1edc80b74e2d3c5efccfc7223f74d407', 'dev_requirement' => \false), 'league/mime-type-detection' => array('pretty_version' => '1.14.0', 'version' => '1.14.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../league/mime-type-detection', 'aliases' => array(), 'reference' => 'b6a5854368533df0295c5761a0253656a2e52d9e', 'dev_requirement' => \false), 'nicmart/tree' => array('pretty_version' => '0.3.1', 'version' => '0.3.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../nicmart/tree', 'aliases' => array(), 'reference' => 'c55ba47c64a3cb7454c22e6d630729fc2aab23ff', 'dev_requirement' => \false), 'paragi/php-websocket-client' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../paragi/php-websocket-client', 'aliases' => array(0 => '9999999-dev'), 'reference' => 'a40a6bf0525a1e76950d19b41201ccccb80bf9cd', 'dev_requirement' => \false), 'psr/cache' => array('pretty_version' => '1.0.1', 'version' => '1.0.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/cache', 'aliases' => array(), 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', 'dev_requirement' => \false), 'psr/cache-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'psr/container' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', 'dev_requirement' => \false), 'psr/container-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '~1.0', 1 => '^1.0')), 'psr/http-client' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(0 => '1.0.x-dev'), 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', 'dev_requirement' => \false), 'psr/http-client-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'psr/http-message' => array('pretty_version' => '1.1', 'version' => '1.1.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', 'dev_requirement' => \false), 'psr/http-message-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'dev_requirement' => \false), 'psr/log-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0.0')), 'psr/simple-cache' => array('pretty_version' => '1.0.1', 'version' => '1.0.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', 'dev_requirement' => \false), 'psr/simple-cache-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'ralouphie/getallheaders' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'dev_requirement' => \false), 'slim/php-view' => array('pretty_version' => 'dev-joomla', 'version' => 'dev-joomla', 'type' => 'library', 'install_path' => __DIR__ . '/../slim/php-view', 'aliases' => array(), 'reference' => 'ab25024a44b3c65a4c2a9968ce283233b490fcb9', 'dev_requirement' => \false), 'spatie/browsershot' => array('pretty_version' => '3.60.1', 'version' => '3.60.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/browsershot', 'aliases' => array(), 'reference' => '8779b2cd10dcd9dab4abd0127429e5578da3f9ab', 'dev_requirement' => \false), 'spatie/crawler' => array('pretty_version' => 'v6.x-dev', 'version' => '6.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/crawler', 'aliases' => array(), 'reference' => '276ecb429a770474695a1278a9ad3e719fbef259', 'dev_requirement' => \false), 'spatie/image' => array('pretty_version' => '2.2.7', 'version' => '2.2.7.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/image', 'aliases' => array(), 'reference' => '2f802853aab017aa615224daae1588054b5ab20e', 'dev_requirement' => \false), 'spatie/image-optimizer' => array('pretty_version' => '1.7.2', 'version' => '1.7.2.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/image-optimizer', 'aliases' => array(), 'reference' => '62f7463483d1bd975f6f06025d89d42a29608fe1', 'dev_requirement' => \false), 'spatie/robots-txt' => array('pretty_version' => '2.0.3', 'version' => '2.0.3.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/robots-txt', 'aliases' => array(), 'reference' => 'dacba2ba159364987392aa1b0002e196c5923970', 'dev_requirement' => \false), 'spatie/temporary-directory' => array('pretty_version' => '2.2.0', 'version' => '2.2.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/temporary-directory', 'aliases' => array(), 'reference' => 'efc258c9f4da28f0c7661765b8393e4ccee3d19c', 'dev_requirement' => \false), 'symfony/deprecation-contracts' => array('pretty_version' => '2.5.x-dev', 'version' => '2.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'reference' => '80d075412b557d41002320b96a096ca65aa2c98d', 'dev_requirement' => \false), 'symfony/dom-crawler' => array('pretty_version' => '5.4.x-dev', 'version' => '5.4.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dom-crawler', 'aliases' => array(), 'reference' => '728f1fc136252a626ba5a69c02bd66a3697ff201', 'dev_requirement' => \false), 'symfony/polyfill-ctype' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', 'dev_requirement' => \false), 'symfony/polyfill-mbstring' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'reference' => '42292d99c55abe617799667f454222c54c60e229', 'dev_requirement' => \false), 'symfony/polyfill-php80' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', 'dev_requirement' => \false), 'symfony/process' => array('pretty_version' => '5.4.x-dev', 'version' => '5.4.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'reference' => '8fa22178dfc368911dbd513b431cd9b06f9afe7a', 'dev_requirement' => \false), 'webmozart/assert' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../webmozart/assert', 'aliases' => array(), 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', 'dev_requirement' => \false)));5 return array('root' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'reference' => '857797bdb745daf47b8f4e5410bcdc902b7b7341', 'name' => 'jchoptimize/lib', 'dev' => \false), 'versions' => array('codealfa/minify' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../codealfa/minify', 'aliases' => array(0 => '9999999-dev'), 'reference' => 'a11d3fc4da27e170ca8cb9f966915ff9cfdc519d', 'dev_requirement' => \false), 'codealfa/regextokenizer' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../codealfa/regextokenizer', 'aliases' => array(0 => '9999999-dev'), 'reference' => 'b660bf5d561078f40bcbf1a68eeb63428a14b17d', 'dev_requirement' => \false), 'composer/ca-bundle' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'type' => 'library', 'install_path' => __DIR__ . '/./ca-bundle', 'aliases' => array(0 => '1.x-dev'), 'reference' => '4d0ae9807cf38e759b6f10b09195b3addd7d8685', 'dev_requirement' => \false), 'container-interop/container-interop' => array('dev_requirement' => \false, 'replaced' => array(0 => '^1.2.0')), 'guzzlehttp/guzzle' => array('pretty_version' => '7.5.x-dev', 'version' => '7.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), 'reference' => '584d1f06b5caa07b0587f5054d551ed65460ce5d', 'dev_requirement' => \false), 'guzzlehttp/promises' => array('pretty_version' => '1.5.x-dev', 'version' => '1.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), 'reference' => '67ab6e18aaa14d753cc148911d273f6e6cb6721e', 'dev_requirement' => \false), 'guzzlehttp/psr7' => array('pretty_version' => '1.9.x-dev', 'version' => '1.9.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), 'reference' => 'e4490cabc77465aaee90b20cfc9a770f8c04be6b', 'dev_requirement' => \false), 'illuminate/collections' => array('pretty_version' => '8.x-dev', 'version' => '8.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/collections', 'aliases' => array(), 'reference' => '705a4e1ef93cd492c45b9b3e7911cccc990a07f4', 'dev_requirement' => \false), 'illuminate/contracts' => array('pretty_version' => '8.x-dev', 'version' => '8.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/contracts', 'aliases' => array(), 'reference' => '5e0fd287a1b22a6b346a9f7cd484d8cf0234585d', 'dev_requirement' => \false), 'illuminate/macroable' => array('pretty_version' => '8.x-dev', 'version' => '8.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/macroable', 'aliases' => array(), 'reference' => 'aed81891a6e046fdee72edd497f822190f61c162', 'dev_requirement' => \false), 'intervention/image' => array('pretty_version' => '2.7.2', 'version' => '2.7.2.0', 'type' => 'library', 'install_path' => __DIR__ . '/../intervention/image', 'aliases' => array(), 'reference' => '04be355f8d6734c826045d02a1079ad658322dad', 'dev_requirement' => \false), 'jchoptimize/lib' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'reference' => '857797bdb745daf47b8f4e5410bcdc902b7b7341', 'dev_requirement' => \false), 'joomla/controller' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/controller', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '6a5a386246f6e67ab0c3a4e71d27f0f208720b65', 'dev_requirement' => \false), 'joomla/di' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/di', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'b68f8de6c3a214eac22c2172f966d8965fd47f9c', 'dev_requirement' => \false), 'joomla/filesystem' => array('pretty_version' => 'dev-1.x-dev', 'version' => 'dev-1.x-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/filesystem', 'aliases' => array(), 'reference' => '9ad5d9b64960f0ea56fb71364a33622843b95c27', 'dev_requirement' => \false), 'joomla/filter' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/filter', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '9102630f9069351c1259b6f585a704fde7029d2a', 'dev_requirement' => \false), 'joomla/input' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/input', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '80d2b6384d60307a11b9af39bdc9a8d254949e94', 'dev_requirement' => \false), 'joomla/model' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/model', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'f322645993346efa5505500f59d6471cbd0d564b', 'dev_requirement' => \false), 'joomla/registry' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/registry', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'fde95733e7e2634d64bff71f611ee02b9ceff354', 'dev_requirement' => \false), 'joomla/renderer' => array('pretty_version' => '2.0.1', 'version' => '2.0.1.0', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/renderer', 'aliases' => array(), 'reference' => '0b514c40d3858fbbbf3bf3347832bc4fc3e776da', 'dev_requirement' => \false), 'joomla/string' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/string', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => 'c7a9330f7316a574f3ff538053fa65dc38bafbe6', 'dev_requirement' => \false), 'joomla/utilities' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/utilities', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '2baa8af18fd2ee5a185606b91ab2e273f77e5e4b', 'dev_requirement' => \false), 'joomla/view' => array('pretty_version' => 'dev-2.0-dev', 'version' => 'dev-2.0-dev', 'type' => 'joomla-package', 'install_path' => __DIR__ . '/../joomla/view', 'aliases' => array(0 => '2.0.x-dev'), 'reference' => '7d5e706b29cac01d0b1ee11b871eabaa823f9063', 'dev_requirement' => \false), 'laminas/laminas-cache' => array('pretty_version' => '3.0.x-dev', 'version' => '3.0.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache', 'aliases' => array(), 'reference' => '86b47eb7b05bc4d24edafb3039494ba81405983b', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-apcu' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-apcu', 'aliases' => array(), 'reference' => '344aa69ff029788bd340a3bda63754d24623bd85', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-blackhole' => array('pretty_version' => '2.0.x-dev', 'version' => '2.0.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-blackhole', 'aliases' => array(), 'reference' => 'fdb6c4b9813cc7365d72c002b09dc808e34b7002', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-filesystem' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-filesystem', 'aliases' => array(), 'reference' => 'd9712a8292fc0a84219e4aba97b6b04b95057cb6', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-memcached' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-memcached', 'aliases' => array(), 'reference' => '5d6795281f388842ed96acbfc3f8659d0742282f', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-adapter-redis' => array('pretty_version' => '2.1.x-dev', 'version' => '2.1.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-cache-storage-adapter-redis', 'aliases' => array(), 'reference' => '289717d10a89755d3f36f799565a3fb9c7e9ab24', 'dev_requirement' => \false), 'laminas/laminas-cache-storage-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'laminas/laminas-eventmanager' => array('pretty_version' => '3.11.x-dev', 'version' => '3.11.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-eventmanager', 'aliases' => array(), 'reference' => '9cfa79ce247c567f05ce4b7c975c6bdf9698c5dd', 'dev_requirement' => \false), 'laminas/laminas-json' => array('pretty_version' => '3.5.x-dev', 'version' => '3.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-json', 'aliases' => array(), 'reference' => '7a8a1d7bf2d05dd6c1fbd7c0868d3848cf2b57ec', 'dev_requirement' => \false), 'laminas/laminas-log' => array('pretty_version' => '2.14.x-dev', 'version' => '2.14.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-log', 'aliases' => array(), 'reference' => '39f3dcbd77fd0d84b190ff1332f5d3d28d56527e', 'dev_requirement' => \false), 'laminas/laminas-paginator' => array('pretty_version' => '2.11.x-dev', 'version' => '2.11.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-paginator', 'aliases' => array(), 'reference' => '7f00d5fdecd1b4f67c8e84e6f6d57bbabda4b7d8', 'dev_requirement' => \false), 'laminas/laminas-serializer' => array('pretty_version' => '2.12.x-dev', 'version' => '2.12.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-serializer', 'aliases' => array(), 'reference' => '2826fd71f202569c169456a4b84297da9ff630cd', 'dev_requirement' => \false), 'laminas/laminas-servicemanager' => array('pretty_version' => '3.20.x-dev', 'version' => '3.20.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-servicemanager', 'aliases' => array(), 'reference' => 'bc2c2cbe2dd90db8b9d16b0618f542692b76ab59', 'dev_requirement' => \false), 'laminas/laminas-stdlib' => array('pretty_version' => '3.16.x-dev', 'version' => '3.16.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../laminas/laminas-stdlib', 'aliases' => array(), 'reference' => 'f4f773641807c7ccee59b758bfe4ac4ba33ecb17', 'dev_requirement' => \false), 'league/flysystem' => array('pretty_version' => '2.x-dev', 'version' => '2.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../league/flysystem', 'aliases' => array(), 'reference' => '8aaffb653c5777781b0f7f69a5d937baf7ab6cdb', 'dev_requirement' => \false), 'league/glide' => array('pretty_version' => '2.3.0', 'version' => '2.3.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../league/glide', 'aliases' => array(), 'reference' => '2ff92c8f1edc80b74e2d3c5efccfc7223f74d407', 'dev_requirement' => \false), 'league/mime-type-detection' => array('pretty_version' => '1.14.0', 'version' => '1.14.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../league/mime-type-detection', 'aliases' => array(), 'reference' => 'b6a5854368533df0295c5761a0253656a2e52d9e', 'dev_requirement' => \false), 'nicmart/tree' => array('pretty_version' => '0.3.1', 'version' => '0.3.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../nicmart/tree', 'aliases' => array(), 'reference' => 'c55ba47c64a3cb7454c22e6d630729fc2aab23ff', 'dev_requirement' => \false), 'paragi/php-websocket-client' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../paragi/php-websocket-client', 'aliases' => array(0 => '9999999-dev'), 'reference' => 'a40a6bf0525a1e76950d19b41201ccccb80bf9cd', 'dev_requirement' => \false), 'psr/cache' => array('pretty_version' => '1.0.1', 'version' => '1.0.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/cache', 'aliases' => array(), 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', 'dev_requirement' => \false), 'psr/cache-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'psr/container' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', 'dev_requirement' => \false), 'psr/container-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '~1.0', 1 => '^1.0')), 'psr/http-client' => array('pretty_version' => 'dev-master', 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(0 => '1.0.x-dev'), 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', 'dev_requirement' => \false), 'psr/http-client-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'psr/http-message' => array('pretty_version' => '1.1', 'version' => '1.1.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba', 'dev_requirement' => \false), 'psr/http-message-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'dev_requirement' => \false), 'psr/log-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0.0')), 'psr/simple-cache' => array('pretty_version' => '1.0.1', 'version' => '1.0.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', 'dev_requirement' => \false), 'psr/simple-cache-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0')), 'ralouphie/getallheaders' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'dev_requirement' => \false), 'slim/php-view' => array('pretty_version' => 'dev-joomla', 'version' => 'dev-joomla', 'type' => 'library', 'install_path' => __DIR__ . '/../slim/php-view', 'aliases' => array(), 'reference' => 'ab25024a44b3c65a4c2a9968ce283233b490fcb9', 'dev_requirement' => \false), 'spatie/browsershot' => array('pretty_version' => '3.60.1', 'version' => '3.60.1.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/browsershot', 'aliases' => array(), 'reference' => '8779b2cd10dcd9dab4abd0127429e5578da3f9ab', 'dev_requirement' => \false), 'spatie/crawler' => array('pretty_version' => 'v6.x-dev', 'version' => '6.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/crawler', 'aliases' => array(), 'reference' => '276ecb429a770474695a1278a9ad3e719fbef259', 'dev_requirement' => \false), 'spatie/image' => array('pretty_version' => '2.2.7', 'version' => '2.2.7.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/image', 'aliases' => array(), 'reference' => '2f802853aab017aa615224daae1588054b5ab20e', 'dev_requirement' => \false), 'spatie/image-optimizer' => array('pretty_version' => '1.7.2', 'version' => '1.7.2.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/image-optimizer', 'aliases' => array(), 'reference' => '62f7463483d1bd975f6f06025d89d42a29608fe1', 'dev_requirement' => \false), 'spatie/robots-txt' => array('pretty_version' => '2.0.3', 'version' => '2.0.3.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/robots-txt', 'aliases' => array(), 'reference' => 'dacba2ba159364987392aa1b0002e196c5923970', 'dev_requirement' => \false), 'spatie/temporary-directory' => array('pretty_version' => '2.2.0', 'version' => '2.2.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/temporary-directory', 'aliases' => array(), 'reference' => 'efc258c9f4da28f0c7661765b8393e4ccee3d19c', 'dev_requirement' => \false), 'symfony/deprecation-contracts' => array('pretty_version' => '2.5.x-dev', 'version' => '2.5.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'reference' => '80d075412b557d41002320b96a096ca65aa2c98d', 'dev_requirement' => \false), 'symfony/dom-crawler' => array('pretty_version' => '5.4.x-dev', 'version' => '5.4.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dom-crawler', 'aliases' => array(), 'reference' => '728f1fc136252a626ba5a69c02bd66a3697ff201', 'dev_requirement' => \false), 'symfony/polyfill-ctype' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', 'dev_requirement' => \false), 'symfony/polyfill-mbstring' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'reference' => '42292d99c55abe617799667f454222c54c60e229', 'dev_requirement' => \false), 'symfony/polyfill-php80' => array('pretty_version' => '1.x-dev', 'version' => '1.9999999.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', 'dev_requirement' => \false), 'symfony/process' => array('pretty_version' => '5.4.x-dev', 'version' => '5.4.9999999.9999999-dev', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'reference' => '8fa22178dfc368911dbd513b431cd9b06f9afe7a', 'dev_requirement' => \false), 'webmozart/assert' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'type' => 'library', 'install_path' => __DIR__ . '/../webmozart/assert', 'aliases' => array(), 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', 'dev_requirement' => \false))); -
jch-optimize/trunk/lib/vendor/symfony/polyfill-mbstring/bootstrap.php
r3007001 r3040365 245 245 } 246 246 } 247 if (!\function_exists(' _JchOptimizeVendor\\mb_str_pad')) {247 if (!\function_exists('mb_str_pad')) { 248 248 function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) : string 249 249 { -
jch-optimize/trunk/lib/vendor/symfony/polyfill-mbstring/bootstrap80.php
r3007001 r3040365 242 242 } 243 243 } 244 if (!\function_exists(' _JchOptimizeVendor\\mb_str_pad')) {244 if (!\function_exists('mb_str_pad')) { 245 245 function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) : string 246 246 { -
jch-optimize/trunk/media/filetree/jquery.filetree.css
r2748708 r3040365 271 271 } 272 272 273 .jqueryFileTree LI.ext_webp { 274 background: url(images/picture.png) left 2px no-repeat; 275 } 276 273 277 .jqueryFileTree LI.ext_wmv { 274 278 background: url(images/film.png) left top no-repeat; -
jch-optimize/trunk/readme.txt
r3007001 r3040365 3 3 Contributors: codealfa 4 4 Tags: performance, pagespeed, cache, optimize, seo 5 Tested up to: 6.4. 26 Stable tag: 4. 1.15 Tested up to: 6.4.3 6 Stable tag: 4.2.0 7 7 License: GPLv3 or later 8 8 Requires at least: 5.0 … … 80 80 81 81 == Changelog == 82 = 4.2.0 = 83 * Add responsive image feature to further boost LCP 84 * Add support for resizing WEBP images to create responsive images 85 * Bug Fix: Backup images were only saved when WEBP images were generated 86 * Bug Fix: Fix fatal error on servers without mbstring support 87 82 88 = 4.1.1 = 83 89 * Removed support for deprecated Wincache storage. -
jch-optimize/trunk/src/Html/Helper.php
r2997317 r3040365 171 171 /** 172 172 * @param array<string|int, string> $options 173 * @param string|null $activeValue174 * @param array $conditions173 * @param string|null $activeValue 174 * @param array $conditions 175 175 * 176 176 * @return string … … 394 394 395 395 /** 396 * @param string $settingName397 * @param array $activeValues398 * @param array<string, string> $options399 * @param string $class396 * @param string $settingName 397 * @param array $activeValues 398 * @param array<string, string> $options 399 * @param string $class 400 400 */ 401 401 public static function checkboxes( … … 430 430 <?php 431 431 } 432 433 public static function textarea(string $settingName, $activeValues): void 434 { 435 ?> 436 <textarea name="<?= "jch-optimize_settings[{$settingName}]"; ?>" cols="35" rows="3"> 437 <?= $activeValues ?> 438 </textarea> 439 <?php 440 } 432 441 } -
jch-optimize/trunk/src/Html/Renderer/Section.php
r2997317 r3040365 108 108 } 109 109 110 public static function customCssSection(): void 111 { 112 $title = __('Custom CSS', 'jch-optimize'); 113 $description = __( 114 'This section is for adding CSS to correct Cumulative Layout Shift (CLS) issues caused by the page shifting around because the space wasn\'t allocated to accomodate the HTML elements rendering, such as some slideshows. The appropriate media queries will be generated for mobile and/or desktop, so you\'ll only need to add simple CSS declarations for e.g., #slideshow-container {min-height: 300px;}', 115 'jch-optimize' 116 ); 117 118 echo TabContent::addSection($title, $description); 119 } 120 110 121 public static function optimizeCssDeliverySection(): void 111 122 { … … 248 259 { 249 260 $title = __('Preconnect Third-party Origins', 'jch-optimize'); 250 $description = __('Reduce the impact of third-party code by establising early connections with the external origins. The origin is the part of the URL containing the scheme, hostname, and port. The plugin will add preconnects to the top of the page to reduce performance impacts of thrid-party providers. CDNs and third-party origins in CSS files can be automatically detected, but you may need to manually add preconnect for scripts in the main thread.'); 261 $description = __( 262 'Reduce the impact of third-party code by establising early connections with the external origins. The origin is the part of the URL containing the scheme, hostname, and port. The plugin will add preconnects to the top of the page to reduce performance impacts of thrid-party providers. CDNs and third-party origins in CSS files can be automatically detected, but you may need to manually add preconnect for scripts in the main thread.' 263 ); 251 264 252 265 echo TabContent::addSection($title, $description); -
jch-optimize/trunk/src/Html/Renderer/Setting.php
r3007001 r3040365 271 271 272 272 /* 273 Custom CSS section 274 */ 275 public static function mobile_css(): void 276 { 277 Helper::_('textarea', __FUNCTION__, ''); 278 } 279 280 public static function desktop_css(): void 281 { 282 Helper::_('textarea', __FUNCTION__, ''); 283 } 284 285 /* 273 286 Optimize CSS Delivery Section 274 287 */ … … 380 393 Helper::_('multiselect.pro', __FUNCTION__, [], 'js', 'script'); 381 394 } 395 396 public static function pro_defer_criticalJs(): void 397 { 398 Helper::_('radio.pro', __FUNCTION__, '1'); 399 } 400 382 401 383 402 ## Page Cache Tab … … 716 735 } 717 736 737 public static function pro_gen_responsive_images(): void 738 { 739 Helper::_('radio.pro', __FUNCTION__, '1'); 740 } 741 742 public static function pro_load_responsive_images(): void 743 { 744 Helper::_('radio.pro', __FUNCTION__, '0'); 745 } 746 718 747 public static function lossy(): void 719 748 { -
jch-optimize/trunk/src/Html/TabSettings.php
r2997317 r3040365 346 346 ) 347 347 ] 348 ], 349 /** 350 * Custom CSS 351 */ 352 'customCssSection' => [ 353 'mobile_css' => [ 354 __('Mobile', 'jch-optimize'), 355 __( 356 'Add simple CSS declarations to allocate space for elements rendering on mobile.', 357 'jch-optimize' 358 ) 359 ], 360 'desktop_css' => [ 361 __('Desktop', 'jch-optimize'), 362 __( 363 'Add CSS for preventing CLS issues on desktop devices here.', 364 'jch-optimize' 365 ) 366 ] 348 367 ] 349 368 ]; … … 478 497 __('Critical inline modules', 'jch-optimize'), 479 498 __('You can exclude inline modules in a similar manner as outlined above.') 499 ], 500 'pro_defer_criticalJs' => [ 501 __('Defer critical js'), 502 __( 503 'The critical JavaScript will be deferred or loaded asynchronously by default to avoid render-blocking. However, if your template uses JavaScript to perform any of the initial render above the fold, you may want to disable this to ensure the critical JavaScript loads before the page starts rendering.' 504 ) 480 505 ] 481 506 ], … … 825 850 */ 826 851 'globalSection' => [ 827 'ignore_optimized' => [852 'ignore_optimized' => [ 828 853 __('Ignore optimized images', 'jch-optimize'), 829 854 __( … … 832 857 ) 833 858 ], 834 'pro_next_gen_images' => [859 'pro_next_gen_images' => [ 835 860 __('Next-Gen images', 'jch-optimize'), 836 861 __( … … 843 868 sprintf( __( 'Plugin will wrap WEBP image in a %s element along with original image so browsers without WEBP support can fall back to the original image.', 'jch-optimize' ), '<picture>' ) 844 869 ], */ 845 'pro_load_webp_images' => [870 'pro_load_webp_images' => [ 846 871 __('Load WEBP images', 'jch-optimize'), 847 872 __('Loads available WEBP images in place of the original ones on your web pages.', 'jch-optimize') 848 873 ], 849 'lossy' => [ 874 'pro_gen_responsive_images' => [ 875 __('Generate responsive images', 'jch-optimize'), 876 __( 877 'While optimizing images, will also create different sized images to be used at different CSS breakpoints' 878 ) 879 ], 880 'pro_load_responsive_images' => [ 881 __('Load responsive images', 'jch-optimize'), 882 __( 883 'Use responsive images where available by adding srcset attributes on image elements and creating CSS breakpoints for background images.' 884 ) 885 ], 886 'lossy' => [ 850 887 __('Lossy optimization', 'jch-optimize'), 851 888 __( … … 854 891 ) 855 892 ], 856 'save_metadata' => [893 'save_metadata' => [ 857 894 __('Save metadata', 'jch-optimize'), 858 895 __( -
jch-optimize/trunk/src/Platform/Paths.php
r3007001 r3040365 16 16 defined('_WP_EXEC') or die('Restricted access'); 17 17 18 use Exception;19 18 use JchOptimize\Core\Interfaces\Paths as PathsInterface; 20 19 use JchOptimize\Core\SystemUri; … … 54 53 { 55 54 $home_path = trailingslashit(self::rootPath()); 56 $rootPath = str_replace('/\\', DIRECTORY_SEPARATOR, $home_path);55 $rootPath = str_replace('/\\', DIRECTORY_SEPARATOR, $home_path); 57 56 58 57 //We can now concatenate root path to url path to get absolute path on filesystem … … 65 64 public static function rootPath(): string 66 65 { 67 $home = set_url_scheme((string)get_option('home'), 'http');68 $site_url = set_url_scheme((string) get_option('siteurl'), 'http');69 70 if (! empty($home) && 0 < strcasecmp($home, $site_url)) {66 $home = set_url_scheme((string)get_option('home'), 'http'); 67 $site_url = set_url_scheme((string)get_option('siteurl'), 'http'); 68 69 if (!empty($home) && 0 < strcasecmp($home, $site_url)) { 71 70 $wp_path_rel_to_home = str_ireplace($home, '', $site_url); /* $site_url - $home */ 72 $pos = strripos(71 $pos = strripos( 73 72 str_replace('\\', '/', $_SERVER['SCRIPT_FILENAME']), 74 73 trailingslashit($wp_path_rel_to_home) 75 74 ); 76 $home_path = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos);77 } elseif (! empty($home) && 0 > strcasecmp($home, $site_url)) {75 $home_path = substr($_SERVER['SCRIPT_FILENAME'], 0, $pos); 76 } elseif (!empty($home) && 0 > strcasecmp($home, $site_url)) { 78 77 $wp_path_rel_to_home = str_ireplace($home, '', $site_url); /* $site_url - $home */ 79 $pos = strripos(str_replace('\\', '/', ABSPATH), trailingslashit($wp_path_rel_to_home));80 $home_path = substr(ABSPATH, 0, $pos);78 $pos = strripos(str_replace('\\', '/', ABSPATH), trailingslashit($wp_path_rel_to_home)); 79 $home_path = substr(ABSPATH, 0, $pos); 81 80 } else { 82 81 $home_path = ABSPATH; … … 86 85 } 87 86 87 public static function basePath(): string 88 { 89 return self::rootPath(); 90 } 91 88 92 /** 89 93 * Returns root relative path to the /assets/ folder … … 112 116 static $rewrite_base; 113 117 114 if (! isset($rewrite_base)) {115 $uri = Utils::uriFor(plugins_url());118 if (!isset($rewrite_base)) { 119 $uri = Utils::uriFor(plugins_url()); 116 120 $rewrite_base = trailingslashit($uri->getPath()); 117 121 } … … 145 149 public static function path2Url(string $path): string 146 150 { 147 $oUri = Utils::uriFor(SystemUri::toString());151 $oUri = Utils::uriFor(SystemUri::toString()); 148 152 $sBaseFolder = SystemUri::basePath(); 149 153 150 154 $abs_path = str_replace(DIRECTORY_SEPARATOR, '/', self::rootPath()); 151 $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); 152 153 $sUriPath = (string)$oUri->withPath($sBaseFolder . 154 (str_replace($abs_path . DIRECTORY_SEPARATOR, '', $path))); 155 $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); 156 157 $sUriPath = (string)$oUri->withPath( 158 $sBaseFolder . 159 (str_replace($abs_path . DIRECTORY_SEPARATOR, '', $path)) 160 ); 155 161 156 162 return $sUriPath; … … 169 175 public static function nextGenImagesPath(bool $isRootRelative = false): string 170 176 { 171 $wp_upload_dir = wp_upload_dir(null, true, true);177 $wp_upload_dir = wp_upload_dir(null, true, true); 172 178 $sRelJchUploadPath = '/jch-optimize/ng'; 173 179 … … 276 282 return dirname(__FILE__, 3) . '/tmpl'; 277 283 } 284 285 public static function responsiveImagePath(bool $isRootRelative = false): string 286 { 287 $wp_upload_dir = wp_upload_dir(null, true, true); 288 $sRelJchUploadPath = '/jch-optimize/rs'; 289 290 if ($isRootRelative) { 291 $uri = Utils::uriFor($wp_upload_dir['baseurl'] . $sRelJchUploadPath); 292 293 return (string)$uri->withScheme('')->withHost('')->withUserInfo(''); 294 } 295 296 return $wp_upload_dir['basedir'] . $sRelJchUploadPath; 297 } 278 298 } -
jch-optimize/trunk/vendor/composer/installed.php
r3007001 r3040365 6 6 'install_path' => __DIR__ . '/../../', 7 7 'aliases' => array(), 8 'reference' => ' de0f05ea1fea90b0cae6c3abfdf52f3d1180cca3',8 'reference' => '857797bdb745daf47b8f4e5410bcdc902b7b7341', 9 9 'name' => 'jchoptimize/wordpress-platform', 10 10 'dev' => false, … … 17 17 'install_path' => __DIR__ . '/../../', 18 18 'aliases' => array(), 19 'reference' => ' de0f05ea1fea90b0cae6c3abfdf52f3d1180cca3',19 'reference' => '857797bdb745daf47b8f4e5410bcdc902b7b7341', 20 20 'dev_requirement' => false, 21 21 ), -
jch-optimize/trunk/version.php
r3007001 r3040365 15 15 defined('_JCH_EXEC') or die; 16 16 17 const JCH_VERSION = '4. 1.1';18 const JCH_DATE = '202 3-12-07';17 const JCH_VERSION = '4.2.0'; 18 const JCH_DATE = '2024-02-23'; 19 19 const JCH_PRO = '0'; 20 20 const JCH_DEVELOP = '0';
Note: See TracChangeset
for help on using the changeset viewer.