示例#1
0
 private function consolidationStepForResourceType($sType, $bExcludeExternal, $iPriority, $sKey, &$aConsolidatorInfo, &$resource_type, &$file_resource, &$location, &$content, &$template, &$media, $aResourceInfo)
 {
     $sSSLMode = 'default';
     if ($resource_type !== $sType && $resource_type !== "inline_{$sType}") {
         return;
     }
     //External location (no file_resource given) or location not determinable
     $bIsExternal = $file_resource === null && $content === null;
     // Files with external references should only be consolidated if explicitly requested (resource_includer.yml/general/consolidate_resources == 'internal' disables this)
     $bShouldNotBeConsolidated = $bIsExternal && ($bExcludeExternal || $location === null);
     // Files with an IE condition can’t be consolidated because the condition (unlike CSS media queries) can only be set in HTML
     $bShouldNotBeConsolidated = $bShouldNotBeConsolidated || isset($aResourceInfo['ie_condition']);
     if ($bShouldNotBeConsolidated) {
         $this->cleanupConsolidator($aConsolidatorInfo);
     } else {
         $this->initConsolidator($sType, $iPriority, $sKey, $aConsolidatorInfo);
         $oCache = new Cache('consolidated-' . $sKey, DIRNAME_PRELOAD, CachingStrategy::fromConfig('file'));
         if (!$oCache->entryExists()) {
             $sRelativeLocationRoot = null;
             $sContents = '';
             if ($file_resource !== null) {
                 // We have a file resource
                 $sContents = file_get_contents($file_resource->getFullPath());
                 $sRelativeLocationRoot = LinkUtil::absoluteLink($file_resource->getFrontendPath(), null, $sSSLMode, true);
             } else {
                 if ($location !== null) {
                     // No file resource given, we only have a URL to go on
                     if (StringUtil::startsWith($location, '//')) {
                         $location = substr($location, strlen('//'));
                         // The path is a protocol-relative URL. Absolutize for file_get_contents and relativize for linking (according to linking/always_link_absolutely)
                         $sRelativeLocationRoot = LinkUtil::getProtocol() . $location;
                         $mProtocolSetting = 'auto';
                         $location = LinkUtil::getProtocol($mProtocolSetting) . $location;
                     } else {
                         if (StringUtil::startsWith($location, '/')) {
                             // The path is a domain-relative-URL. Absolutize for file_get_contents and relativize for linking (according to linking/always_link_absolutely)
                             $sRelativeLocationRoot = LinkUtil::absoluteLink($location, null, $sSSLMode, true);
                             $location = LinkUtil::absoluteLink($location, null, LinkUtil::isSSL());
                         } else {
                             $sRelativeLocationRoot = $location;
                         }
                     }
                     $sContents = file_get_contents($location);
                 } else {
                     if ($content !== null) {
                         if ($content instanceof Template) {
                             $content = $content->render();
                         }
                         $sContents = $content;
                     }
                 }
             }
             if ($sType === self::RESOURCE_TYPE_CSS && $media) {
                 $sContents = "@media {$media} { {$sContents} }";
             }
             // Fix relative locations in CSS
             if ($sType === self::RESOURCE_TYPE_CSS && $sRelativeLocationRoot !== null) {
                 //Remove the protocol so our slash-detection logic works correctly (because the protocol may also contain slashes)
                 if (preg_match(',^([a-z][a-z.\\-+]*:)?//,', $sRelativeLocationRoot, $sProtocol) === 1) {
                     $sProtocol = $sProtocol[0];
                 } else {
                     $sProtocol = '';
                 }
                 $sRelativeLocationRoot = substr($sRelativeLocationRoot, strlen($sProtocol));
                 $sAbsoluteLocationRoot = $sRelativeLocationRoot;
                 $bHasTruncatedTail = false;
                 $iSlashPosition = null;
                 // Calculate the absolute location root (will be "" most of the time unless the CSS was loaded from an external domain or linking/always_link_absolutely is true)
                 while (($iSlashPosition = strrpos($sAbsoluteLocationRoot, '/')) !== false) {
                     $sAbsoluteLocationRoot = substr($sAbsoluteLocationRoot, 0, $iSlashPosition);
                     if (!$bHasTruncatedTail) {
                         // Remove the last part from the relative location as it’s the resource itself
                         $sRelativeLocationRoot = "{$sAbsoluteLocationRoot}/";
                         $bHasTruncatedTail = true;
                     }
                 }
                 // Re-add the protocol part
                 $sRelativeLocationRoot = $sProtocol . $sRelativeLocationRoot;
                 $sAbsoluteLocationRoot = $sProtocol . $sAbsoluteLocationRoot;
                 // Find url() tokens
                 $sContents = preg_replace_callback(',url\\s*\\(\\s*(\'[^\']+\'|\\"[^\\"]+\\"|[^(\'\\"]+?)\\s*\\),', function ($aMatches) use($sRelativeLocationRoot, $sAbsoluteLocationRoot) {
                     // Convert /something/../ to /
                     $sQuote = '';
                     $sUrl = $aMatches[1];
                     $sFirst = substr($sUrl, 0, 1);
                     if ($sFirst === '"' || $sFirst === "'") {
                         $sQuote = $sFirst;
                         $sUrl = substr($sUrl, 1, -1);
                     }
                     if (StringUtil::startsWith($sUrl, '//')) {
                         // URL is protocol-relative. Do nothing.
                         // If this were pointing to the local host, we’d need to respect linking/ssl_in_absolute_links
                         // but if it did come from a file resource, we’d already have that
                     } else {
                         if (StringUtil::startsWith($sUrl, '/')) {
                             // URL absolute. That means relative to $sAbsoluteLocationRoot
                             $sUrl = $sAbsoluteLocationRoot . $sUrl;
                         } else {
                             if (!preg_match(',^[a-z][a-z.\\-+]*:,', $sUrl)) {
                                 // URL is relative to the resource being changed. That means relative to $sRelativeLocationRoot
                                 // Absolutize only relative URLs (the ones not starting with a protocol)
                                 // Prepend the coomon root for the relative location
                                 $sUrl = $sRelativeLocationRoot . $sUrl;
                                 // Fix explicit relative URLs (./)
                                 $sUrl = preg_replace(',/\\./,', '/', $sUrl);
                                 // Resolve Uplinks (/some-place/../)
                                 $sParentPattern = ',/[^/]+/\\.\\./,';
                                 while (preg_match($sParentPattern, $sUrl) === 1) {
                                     $sUrl = preg_replace($sParentPattern, '/', $sUrl, 1);
                                 }
                             }
                         }
                     }
                     return "url({$sQuote}{$sUrl}{$sQuote})";
                 }, $sContents);
             }
             $oCache->setContents($sContents);
         }
         $aConsolidatorInfo['contents'][$sKey] = $oCache;
     }
 }