/** * Compresses and minifies a javascript file * * @param string $filename Source filename, relative to requested page * @return string Filename of the compressed file, relative to requested page */ public function compressJsFile($filename) { // generate the unique name of the file $filenameAbsolute = GeneralUtility::resolveBackPath($this->rootPath . $this->getFilenameFromMainDir($filename)); if (@file_exists($filenameAbsolute)) { $fileStatus = stat($filenameAbsolute); $unique = $filenameAbsolute . $fileStatus['mtime'] . $fileStatus['size']; } else { $unique = $filenameAbsolute; } $pathinfo = PathUtility::pathinfo($filename); $targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.js'; // only create it, if it doesn't exist, yet if (!file_exists(PATH_site . $targetFile) || $this->createGzipped && !file_exists(PATH_site . $targetFile . '.gzip')) { $contents = file_get_contents($filenameAbsolute); try { $minifiedContents = Minifier::minify($contents); } catch (\Exception $e) { // Log error and use un-minified content as fallback /** @var $logger Logger */ $logger = GeneralUtility::makeInstance(LogManager::class)->getLogger(__CLASS__); $logger->error($e->getMessage(), ['filename' => $filename]); $minifiedContents = $contents; } $this->writeFileAndCompressed($targetFile, $minifiedContents); } return $this->relativePath . $this->returnFileReference($targetFile); }
/** * Just makes path absolute. * * @param $file * * @return string * * @todo add typehinting */ protected static function fixPathForInput($file) { if (TYPO3_MODE === 'FE') { $file = GeneralUtility::getFileAbsFileName($file); } elseif (TYPO3_MODE === 'BE' && !TYPO3_cliMode) { $file = GeneralUtility::resolveBackPath(PATH_typo3 . $file); } return $file; }
/** * Interface function. This will be called from the sprite manager to * refresh all caches. * * @return void */ public function generate() { $this->generatorInstance = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Sprite\SpriteGenerator::class, 'GeneratorHandler'); $this->generatorInstance->setOmitSpriteNameInIconName(TRUE)->setIncludeTimestampInCSS(TRUE)->setSpriteFolder(SpriteManager::$tempPath)->setCSSFolder(SpriteManager::$tempPath); $iconsToProcess = array_merge((array) $GLOBALS['TBE_STYLES']['spritemanager']['singleIcons'], $this->collectTcaSpriteIcons()); foreach ($iconsToProcess as $iconName => $iconFile) { $iconsToProcess[$iconName] = GeneralUtility::resolveBackPath('typo3/' . $iconFile); } $generatorResponse = $this->generatorInstance->generateSpriteFromArray($iconsToProcess); $this->iconNames = array_merge($this->iconNames, $generatorResponse['iconNames']); parent::generate(); }
/** * This function builds an css class for every single icon registered via * \TYPO3\CMS\Backend\Utility\IconUtility::addSingleIcons to use them via * \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon and TCA-Icons for * "classic" record Icons to be uses via * \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord * In the simpleHandler the icon just will be added as css-background-image. * * @return void */ protected function buildCssAndRegisterIcons() { // Backpath from the stylesheet file ($cssTcaFile) to PATH_site dir // in order to set the background-image URL paths correct $iconPath = '../../' . TYPO3_mainDir; $iconsToProcess = array_merge((array) $GLOBALS['TBE_STYLES']['spritemanager']['singleIcons'], $this->collectTcaSpriteIcons()); foreach ($iconsToProcess as $iconName => $iconFile) { $css = str_replace('###NAME###', str_replace(array('extensions-', 'tcarecords-'), array('', ''), $iconName), $this->styleSheetTemplateExtIcons); $css = str_replace('###IMAGE###', \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath($iconPath . $iconFile), $css); $this->iconNames[] = $iconName; $this->styleSheetData .= $css; } }
/** * renders the actual logo code * * @return string Logo html code snippet to use in the backend */ public function render() { // Default $logoFile = 'gfx/alt_backend_logo.gif'; if (is_string($this->logo)) { // Overwrite $logoFile = $this->logo; } $imgInfo = getimagesize(PATH_site . TYPO3_mainDir . $logoFile); $logo = '<a href="' . TYPO3_URL_GENERAL . '" target="_blank">' . '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg('', $logoFile, $imgInfo[3]) . ' title="TYPO3 Content Management System" alt="" />' . '</a>'; // Overwrite with custom logo if ($GLOBALS['TBE_STYLES']['logo']) { $imgInfo = @getimagesize(\TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_typo3 . $GLOBALS['TBE_STYLES']['logo'], 3)); $logo = '<a href="' . TYPO3_URL_GENERAL . '" target="_blank">' . '<img src="' . $GLOBALS['TBE_STYLES']['logo'] . '" ' . $imgInfo[3] . ' title="TYPO3 Content Management System" alt="" />' . '</a>'; } return $logo; }
/** * renders the actual logo code * * @return string Logo html code snippet to use in the backend */ public function render() { $imgInfo = getimagesize(PATH_site . TYPO3_mainDir . $this->logo); $imgUrl = $this->logo; // Overwrite with custom logo if ($GLOBALS['TBE_STYLES']['logo']) { $imgInfo = @getimagesize(\TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_typo3 . $GLOBALS['TBE_STYLES']['logo'], 3)); $imgUrl = $GLOBALS['TBE_STYLES']['logo']; } // High-res? $width = $imgInfo[0]; $height = $imgInfo[1]; if (strpos($imgUrl, '@2x.')) { $width = $width / 2; $height = $height / 2; } $logoTag = '<img src="' . $imgUrl . '" width="' . $width . '" height="' . $height . '" title="TYPO3 Content Management System" alt="" />'; return '<a href="' . TYPO3_URL_GENERAL . '" target="_blank">' . $logoTag . '</a>'; }
/** * renders the actual logo code * * @return string Logo html code snippet to use in the backend */ public function render() { $imgInfo = getimagesize(PATH_site . TYPO3_mainDir . $this->logo); $imgUrl = $this->logo; // Overwrite with custom logo if ($GLOBALS['TBE_STYLES']['logo']) { $imgInfo = @getimagesize(\TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_typo3 . $GLOBALS['TBE_STYLES']['logo'], 3)); $imgUrl = $GLOBALS['TBE_STYLES']['logo']; } // High-res? $width = $imgInfo[0]; $height = $imgInfo[1]; if (strpos($imgUrl, '@2x.')) { $width = $width / 2; $height = $height / 2; } $logoTag = '<img src="' . $imgUrl . '" width="' . $width . '" height="' . $height . '" title="TYPO3 Content Management System" alt="" />'; return '<a class="typo3-topbar-site-logo" href="' . htmlspecialchars(TYPO3_URL_GENERAL) . '" target="_blank">' . $logoTag . '</a> <span class="typo3-topbar-site-name">' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . ' [' . TYPO3_version . ']</span>'; }
/** * renders the actual logo code * * @return string Logo html code snippet to use in the backend */ public function render() { if (!$GLOBALS['TBE_STYLES']['logo']) { return parent::render(); } // Overwrite with custom logo if ($GLOBALS['TBE_STYLES']['logo']) { $imgInfo = @getimagesize(GeneralUtility::resolveBackPath(PATH_typo3 . $GLOBALS['TBE_STYLES']['logo'], 3)); $imgUrl = $GLOBALS['TBE_STYLES']['logo']; } // High-res? $width = $imgInfo[0]; $height = $imgInfo[1]; if (strpos($imgUrl, '@2x.')) { $width = $width / 2; $height = $height / 2; } $logoTag = '<img src="' . $imgUrl . '" width="' . $width . '" height="' . $height . '" title="' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . '" alt="" />' . '<span class="typo3-sitename">' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . ' [' . TYPO3_version . ']</span>'; return '<a href="http://' . GeneralUtility::getIndpEnv('HTTP_HOST') . '/" target="_blank">' . $logoTag . '</a>'; }
/** * renders the actual logo code * * @return string Logo html code snippet to use in the backend */ public function render() { if (!$GLOBALS['TBE_STYLES']['logo']) { return parent::render(); } // Overwrite with custom logo if ($GLOBALS['TBE_STYLES']['logo']) { $imgInfo = @getimagesize(\TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_typo3 . $GLOBALS['TBE_STYLES']['logo'], 3)); $imgUrl = $GLOBALS['TBE_STYLES']['logo']; } // High-res? $width = $imgInfo[0]; $height = $imgInfo[1]; if (strpos($imgUrl, '@2x.')) { $width = $width / 2; $height = $height / 2; } $logoTag = '<img src="' . $imgUrl . '" width="' . $width . '" height="' . $height . '" title="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '" alt="" />'; $siteName = '<span class="typo3-sitename"><a style="color:#fff;" href="http://' . $GLOBALS['_SERVER']['HTTP_HOST'] . '/" target="_blank">' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ' [' . TYPO3_version . ']</a></span>'; return '<a href="http://typo3.org/" target="_blank">' . $logoTag . '</a>' . $siteName; }
/** * Return JS configuration of the htmlArea plugins registered by the extension * * @param integer Relative id of the RTE editing area in the form * @return string JS configuration for registered plugins */ public function buildJavascriptConfiguration($RTEcounter) { $registerRTEinJavascriptString = ''; $schema = array('types' => array(), 'properties' => array()); // Parse configured schemas if (is_array($this->thisConfig['schema.']) && is_array($this->thisConfig['schema.']['sources.'])) { foreach ($this->thisConfig['schema.']['sources.'] as $source) { $fileName = $this->htmlAreaRTE->getFullFileName($source); $absolutePath = $fileName ? \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_site . ($this->htmlAreaRTE->is_FE() || $this->htmlAreaRTE->isFrontendEditActive() ? '' : TYPO3_mainDir) . $fileName) : ''; // Fallback to default schema file if configured file does not exists or is of zero size if (!$fileName || !file_exists($absolutePath) || !filesize($absolutePath)) { $fileName = $this->htmlAreaRTE->getFullFileName('EXT:' . $this->ID . '/extensions/MicrodataSchema/res/schemaOrgAll.rdf'); } $rdf = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($fileName); if ($rdf) { $this->parseSchema($rdf, $schema); } } } uasort($schema['types'], array($this, 'compareLabels')); uasort($schema['properties'], array($this, 'compareLabels')); // Insert no type and no property entries if ($this->htmlAreaRTE->is_FE()) { $noSchema = $GLOBALS['TSFE']->getLLL('No type', $this->LOCAL_LANG); $noProperty = $GLOBALS['TSFE']->getLLL('No property', $this->LOCAL_LANG); } else { $noSchema = $GLOBALS['LANG']->getLL('No type'); $noProperty = $GLOBALS['LANG']->getLL('No property'); } array_unshift($schema['types'], array('name' => 'none', 'label' => $noSchema)); array_unshift($schema['properties'], array('name' => 'none', 'label' => $noProperty)); // Convert character set if ($this->htmlAreaRTE->is_FE()) { $GLOBALS['TSFE']->csConvObj->convArray($schema, $this->htmlAreaRTE->outputCharset, 'utf-8'); } // Store json encoded array in temporary file $registerRTEinJavascriptString = LF . TAB . 'RTEarea[editornumber].schemaUrl = "' . ($this->htmlAreaRTE->is_FE() && $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . $this->htmlAreaRTE->writeTemporaryFile('', 'schema_' . $this->htmlAreaRTE->language, 'js', json_encode($schema), TRUE) . '";'; return $registerRTEinJavascriptString; }
/** * If it is an URL, nothing to do, if it is a file, check if path is allowed and prepend current url * * @param string $url * @return string * @throws \UnexpectedValueException */ public static function getCorrectUrl($url) { if (empty($url)) { throw new \UnexpectedValueException('An empty url is given'); } $url = self::getFalFilename($url); // check URL $urlInfo = parse_url($url); // means: it is no external url if (!isset($urlInfo['scheme'])) { // resolve paths like ../ $url = GeneralUtility::resolveBackPath($url); // absolute path is used to check path $absoluteUrl = GeneralUtility::getFileAbsFileName($url); if (!GeneralUtility::isAllowedAbsPath($absoluteUrl)) { throw new \UnexpectedValueException('The path "' . $url . '" is not allowed.'); } // append current domain $url = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $url; } return $url; }
/** * Sends a header "Location" to jumpUrl, if jumpurl is set. * Will exit if a location header is sent (for instance if jumpUrl was triggered) * * "jumpUrl" is a concept where external links are redirected from the index_ts.php script, which first logs the URL. * * @return void * @todo Define visibility */ public function jumpUrl() { if ($this->jumpurl) { if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('juSecure')) { $locationData = (string) \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('locationData'); // Need a type cast here because mimeType is optional! $mimeType = (string) \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('mimeType'); $hArr = array($this->jumpurl, $locationData, $mimeType); $calcJuHash = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac(serialize($hArr)); $juHash = (string) \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('juHash'); if ($juHash === $calcJuHash) { if ($this->locDataCheck($locationData)) { // 211002 - goes with cObj->filelink() rawurlencode() of filenames so spaces can be allowed. $this->jumpurl = rawurldecode($this->jumpurl); // Deny access to files that match TYPO3_CONF_VARS[SYS][fileDenyPattern] and whose parent directory is typo3conf/ (there could be a backup file in typo3conf/ which does not match against the fileDenyPattern) $absoluteFileName = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName(\TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath($this->jumpurl), FALSE); if (\TYPO3\CMS\Core\Utility\GeneralUtility::isAllowedAbsPath($absoluteFileName) && \TYPO3\CMS\Core\Utility\GeneralUtility::verifyFilenameAgainstDenyPattern($absoluteFileName) && !\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($absoluteFileName, PATH_site . 'typo3conf')) { if (@is_file($absoluteFileName)) { $mimeType = $mimeType ? $mimeType : 'application/octet-stream'; header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Content-Type: ' . $mimeType); header('Content-Disposition: attachment; filename="' . basename($absoluteFileName) . '"'); readfile($absoluteFileName); die; } else { throw new \Exception('jumpurl Secure: "' . $this->jumpurl . '" was not a valid file!', 1294585193); } } else { throw new \Exception('jumpurl Secure: The requested file was not allowed to be accessed through jumpUrl (path or file not allowed)!', 1294585194); } } else { throw new \Exception('jumpurl Secure: locationData, ' . $locationData . ', was not accessible.', 1294585195); } } else { throw new \Exception('jumpurl Secure: Calculated juHash did not match the submitted juHash.', 1294585196); } } else { $TSConf = $this->getPagesTSconfig(); if ($TSConf['TSFE.']['jumpUrl_transferSession']) { $uParts = parse_url($this->jumpurl); $params = '&FE_SESSION_KEY=' . rawurlencode($this->fe_user->id . '-' . md5($this->fe_user->id . '/' . $this->TYPO3_CONF_VARS['SYS']['encryptionKey'])); // Add the session parameter ... $this->jumpurl .= ($uParts['query'] ? '' : '?') . $params; } if ($TSConf['TSFE.']['jumpURL_HTTPStatusCode']) { switch (intval($TSConf['TSFE.']['jumpURL_HTTPStatusCode'])) { case 301: $statusCode = \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_301; break; case 302: $statusCode = \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_302; break; case 307: $statusCode = \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_307; break; case 303: default: $statusCode = \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_303; break; } } \TYPO3\CMS\Core\Utility\HttpUtility::redirect($this->jumpurl, $statusCode); } } }
/** * Generates the spriteicon name for a given path or fileExtension * usually called from mapFileExtensionToSpriteIconClass and tceforms * * @param string $fileExtension FileExtension can be jpg, gif etc, but also be 'mount' or 'folder', but can also be a full path which will be resolved then * @return string The string of the CSS class, see \TYPO3\CMS\Backend\Utility\IconUtility::$fileSpriteIconNames * @access private */ public static function mapFileExtensionToSpriteIconName($fileExtension) { // If the file is a whole file with name etc (mainly, if it has a "." or a "/"), // then it is checked whether it is a valid directory if (strpos($fileExtension, '.') !== FALSE || strpos($fileExtension, '/') !== FALSE) { // Check if it is a directory $filePath = dirname(GeneralUtility::getIndpEnv('SCRIPT_FILENAME')) . '/' . $GLOBALS['BACK_PATH'] . $fileExtension; $path = GeneralUtility::resolveBackPath($filePath); if (is_dir($path) || substr($fileExtension, -1) === '/' || substr($fileExtension, -1) === '\\') { $fileExtension = 'folder'; } else { if (($pos = strrpos($fileExtension, '.')) !== FALSE) { $fileExtension = strtolower(substr($fileExtension, $pos + 1)); } else { $fileExtension = 'default'; } } } // If the file extension is not valid // then use the default one if (!isset(self::$fileSpriteIconNames[$fileExtension])) { $fileExtension = 'default'; } $iconName = self::$fileSpriteIconNames[$fileExtension]; return $iconName; }
/** * Make a file name relative to the PATH_site or to the PATH_typo3 * * @param string $filename: a file name of the form EXT:.... or relative to the PATH_site * @return string the file name relative to the PATH_site if in frontend or relative to the PATH_typo3 if in backend */ protected function getFullFileName($filename) { if (substr($filename, 0, 4) === 'EXT:') { // extension list($extKey, $local) = explode('/', substr($filename, 4), 2); $newFilename = ''; if ((string) $extKey !== '' && ExtensionManagementUtility::isLoaded($extKey) && (string) $local !== '') { $newFilename = ($this->isFrontendEditActive() ? ExtensionManagementUtility::siteRelPath($extKey) : ExtensionManagementUtility::extRelPath($extKey)) . $local; } } else { $path = $this->isFrontendEditActive() ? '' : '../'; $newFilename = $path . ($filename[0] === '/' ? substr($filename, 1) : $filename); } return GeneralUtility::resolveBackPath($newFilename); }
/** * wrapCssFile * * @param string $cssFile * @return string */ private function wrapCssFile($cssFile) { $cssFile = GeneralUtility::resolveBackPath($cssFile); $cssFile = GeneralUtility::createVersionNumberedFilename($cssFile); return '<link rel="stylesheet" type="text/css" href="' . htmlspecialchars($cssFile) . '" media="screen" />'; }
/** * Create file in directory and return the new (unique) filename * * @param string $origDirPrefix Directory prefix, relative, with trailing slash * @param string $fileName Filename (without path) * @param string $fileID File ID from import memory * @param string $table Table for which the processing occurs * @param string $uid UID of record from table * @return string|NULL New relative filename, if any */ public function processSoftReferences_saveFile_createRelFile($origDirPrefix, $fileName, $fileID, $table, $uid) { // If the fileID map contains an entry for this fileID then just return the relative filename of that entry; // we don't want to write another unique filename for this one! if (isset($this->fileIDMap[$fileID])) { return PathUtility::stripPathSitePrefix($this->fileIDMap[$fileID]); } if ($this->legacyImport) { // set dirPrefix to fileadmin because the right target folder is set and checked for permissions later $dirPrefix = $this->fileadminFolderName . '/'; } else { // Verify FileMount access to dir-prefix. Returns the best alternative relative path if any $dirPrefix = $this->verifyFolderAccess($origDirPrefix); } if ($dirPrefix && (!$this->update || $origDirPrefix === $dirPrefix) && $this->checkOrCreateDir($dirPrefix)) { $fileHeaderInfo = $this->dat['header']['files'][$fileID]; $updMode = $this->update && $this->import_mapId[$table][$uid] === $uid && $this->import_mode[$table . ':' . $uid] !== 'as_new'; // Create new name for file: // Must have same ID in map array (just for security, is not really needed) and NOT be set "as_new". // Write main file: if ($this->legacyImport) { $fileWritten = $this->writeSysFileResourceForLegacyImport($fileName, $fileID); if ($fileWritten) { $newName = 'file:' . $fileName; return $newName; // no support for HTML/CSS file resources attached ATM - see below } } else { if ($updMode) { $newName = PATH_site . $dirPrefix . $fileName; } else { // Create unique filename: $fileProcObj = $this->getFileProcObj(); $newName = $fileProcObj->getUniqueName($fileName, PATH_site . $dirPrefix); } if ($this->writeFileVerify($newName, $fileID)) { // If the resource was an HTML/CSS file with resources attached, we will write those as well! if (is_array($fileHeaderInfo['EXT_RES_ID'])) { $tokenizedContent = $this->dat['files'][$fileID]['tokenizedContent']; $tokenSubstituted = false; $fileProcObj = $this->getFileProcObj(); if ($updMode) { foreach ($fileHeaderInfo['EXT_RES_ID'] as $res_fileID) { if ($this->dat['files'][$res_fileID]['filename']) { // Resolve original filename: $relResourceFileName = $this->dat['files'][$res_fileID]['parentRelFileName']; $absResourceFileName = GeneralUtility::resolveBackPath(PATH_site . $origDirPrefix . $relResourceFileName); $absResourceFileName = GeneralUtility::getFileAbsFileName($absResourceFileName); if ($absResourceFileName && GeneralUtility::isFirstPartOfStr($absResourceFileName, PATH_site . $this->fileadminFolderName . '/')) { $destDir = PathUtility::stripPathSitePrefix(PathUtility::dirname($absResourceFileName) . '/'); if ($this->verifyFolderAccess($destDir, true) && $this->checkOrCreateDir($destDir)) { $this->writeFileVerify($absResourceFileName, $res_fileID); } else { $this->error('ERROR: Could not create file in directory "' . $destDir . '"'); } } else { $this->error('ERROR: Could not resolve path for "' . $relResourceFileName . '"'); } $tokenizedContent = str_replace('{EXT_RES_ID:' . $res_fileID . '}', $relResourceFileName, $tokenizedContent); $tokenSubstituted = true; } } } else { // Create the resouces directory name (filename without extension, suffixed "_FILES") $resourceDir = PathUtility::dirname($newName) . '/' . preg_replace('/\\.[^.]*$/', '', PathUtility::basename($newName)) . '_FILES'; if (GeneralUtility::mkdir($resourceDir)) { foreach ($fileHeaderInfo['EXT_RES_ID'] as $res_fileID) { if ($this->dat['files'][$res_fileID]['filename']) { $absResourceFileName = $fileProcObj->getUniqueName($this->dat['files'][$res_fileID]['filename'], $resourceDir); $relResourceFileName = substr($absResourceFileName, strlen(PathUtility::dirname($resourceDir)) + 1); $this->writeFileVerify($absResourceFileName, $res_fileID); $tokenizedContent = str_replace('{EXT_RES_ID:' . $res_fileID . '}', $relResourceFileName, $tokenizedContent); $tokenSubstituted = true; } } } } // If substitutions has been made, write the content to the file again: if ($tokenSubstituted) { GeneralUtility::writeFile($newName, $tokenizedContent); } } return PathUtility::stripPathSitePrefix($newName); } } } return null; }
/** * @test * @dataProvider resolveBackPathDataProvider * @param string $input the input for resolveBackPath * @param $expectedValue Expected return value from resolveBackPath */ public function resolveBackPathWithDataProvider($input, $expectedValue) { $this->assertEquals($expectedValue, Utility\GeneralUtility::resolveBackPath($input)); }
/** * Wraps the directory-titles ($code) in a link to filelist/mod1/index.php (id=$path) and sorting commands... * * @param string $code String to be wrapped * @param string $folderIdentifier ID (path) * @param string $col Sorting column * @return string HTML */ public function linkWrapSort($code, $folderIdentifier, $col) { if ($this->sort === $col) { // Check reverse sorting $params = '&SET[sort]=' . $col . '&SET[reverse]=' . ($this->sortRev ? '0' : '1'); $sortArrow = IconUtility::getSpriteIcon('status-status-sorting-light-' . ($this->sortRev ? 'desc' : 'asc')); } else { $params = '&SET[sort]=' . $col . '&SET[reverse]=0'; $sortArrow = ''; } $href = GeneralUtility::resolveBackPath($GLOBALS['BACK_PATH'] . $this->script) . '&id=' . rawurlencode($folderIdentifier) . $params; return '<a href="' . htmlspecialchars($href) . '">' . $code . ' ' . $sortArrow . '</a>'; }
/** * Writes contents in a file in typo3temp and returns the file name * * @param string $label: A label to insert at the beginning of the name of the file * @param string $fileExtension: The file extension of the file, defaulting to 'js' * @param string $contents: The contents to write into the file * @return string The name of the file written to typo3temp * @throws \RuntimeException If writing to file failed */ protected function writeTemporaryFile($label, $fileExtension = 'js', $contents = '') { $relativeFilename = 'typo3temp/RteHtmlArea/' . str_replace('-', '_', $label) . '_' . GeneralUtility::shortMD5($contents, 20) . '.' . $fileExtension; $destination = PATH_site . $relativeFilename; if (!file_exists($destination)) { $minifiedJavaScript = ''; if ($fileExtension === 'js' && $contents !== '') { $minifiedJavaScript = GeneralUtility::minifyJavaScript($contents); } $failure = GeneralUtility::writeFileToTypo3tempDir($destination, $minifiedJavaScript ? $minifiedJavaScript : $contents); if ($failure) { throw new \RuntimeException($failure, 1294585668); } } if ($this->isFrontend() || $this->isFrontendEditActive()) { $fileName = $relativeFilename; } else { $fileName = '../' . $relativeFilename; } return GeneralUtility::resolveBackPath($fileName); }
/** * If the submitted hash is correct and the user has access to the * related content element the contents of the submitted file will * be output to the user. * * @param string $jumpUrl The URL to the file that should be output to the user * @throws \Exception */ protected function forwardJumpUrlSecureFileData($jumpUrl) { // Set the parameters required for handling a secure jumpUrl link // The locationData GET parameter, containing information about the record that created the URL $locationData = (string) GeneralUtility::_GP('locationData'); // The optional mimeType GET parameter $mimeType = (string) GeneralUtility::_GP('mimeType'); // The jump Url Hash GET parameter $juHash = (string) GeneralUtility::_GP('juHash'); // validate the hash GET parameter against the other parameters if ($juHash !== JumpUrlUtility::calculateHashSecure($jumpUrl, $locationData, $mimeType)) { throw new \Exception('The calculated Jump URL secure hash ("juHash") did not match the submitted "juHash" query parameter.', 1294585196); } if (!$this->isLocationDataValid($locationData)) { throw new \Exception('The calculated secure location data "' . $locationData . '" is not accessible.', 1294585195); } // Allow spaces / special chars in filenames. $jumpUrl = rawurldecode($jumpUrl); // Deny access to files that match TYPO3_CONF_VARS[SYS][fileDenyPattern] and whose parent directory // is typo3conf/ (there could be a backup file in typo3conf/ which does not match against the fileDenyPattern) $absoluteFileName = GeneralUtility::getFileAbsFileName(GeneralUtility::resolveBackPath($jumpUrl), false); if (!GeneralUtility::isAllowedAbsPath($absoluteFileName) || !GeneralUtility::verifyFilenameAgainstDenyPattern($absoluteFileName) || GeneralUtility::isFirstPartOfStr($absoluteFileName, PATH_site . 'typo3conf')) { throw new \Exception('The requested file was not allowed to be accessed through Jump URL. The path or file is not allowed.', 1294585194); } try { $resourceFactory = $this->getResourceFactory(); $file = $resourceFactory->retrieveFileOrFolderObject($absoluteFileName); $this->readFileAndExit($file, $mimeType); } catch (\Exception $e) { throw new \Exception('The requested file "' . $jumpUrl . '" for Jump URL was not found..', 1294585193); } }
/** * Creating the module output. * * @throws \UnexpectedValueException * @return void */ public function main() { $lang = $this->getLanguageService(); $this->content .= '<form action="" name="editForm" id="NewContentElementController"><input type="hidden" name="defValues" value="" />'; if ($this->id && $this->access) { // Init position map object: $posMap = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\View\ContentCreationPagePositionMap::class); $posMap->cur_sys_language = $this->sys_language; // If a column is pre-set: if (isset($this->colPos)) { if ($this->uid_pid < 0) { $row = array(); $row['uid'] = abs($this->uid_pid); } else { $row = ''; } $this->onClickEvent = $posMap->onClickInsertRecord($row, $this->colPos, '', $this->uid_pid, $this->sys_language); } else { $this->onClickEvent = ''; } // *************************** // Creating content // *************************** $this->content .= '<h1>' . $lang->getLL('newContentElement') . '</h1>'; // Wizard $wizardItems = $this->wizardArray(); // Wrapper for wizards $this->elementWrapper['section'] = array('', ''); // Hook for manipulating wizardItems, wrapper, onClickEvent etc. if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms']['db_new_content_el']['wizardItemsHook'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms']['db_new_content_el']['wizardItemsHook'] as $classData) { $hookObject = GeneralUtility::getUserObj($classData); if (!$hookObject instanceof NewContentElementWizardHookInterface) { throw new \UnexpectedValueException('$hookObject must implement interface ' . NewContentElementWizardHookInterface::class, 1227834741); } $hookObject->manipulateWizardItems($wizardItems, $this); } } // Add document inline javascript $this->moduleTemplate->addJavaScriptCode('NewContentElementWizardInlineJavascript', ' function goToalt_doc() { // ' . $this->onClickEvent . ' } if(top.refreshMenu) { top.refreshMenu(); } else { top.TYPO3ModuleMenu.refreshMenu(); }'); $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class); // Traverse items for the wizard. // An item is either a header or an item rendered with a radio button and title/description and icon: $cc = $key = 0; $menuItems = array(); foreach ($wizardItems as $k => $wInfo) { if ($wInfo['header']) { $menuItems[] = array('label' => htmlspecialchars($wInfo['header']), 'content' => $this->elementWrapper['section'][0]); $key = count($menuItems) - 1; } else { $content = ''; if (!$this->onClickEvent) { // Radio button: $oC = 'document.editForm.defValues.value=unescape(' . GeneralUtility::quoteJSvalue(rawurlencode($wInfo['params'])) . ');goToalt_doc();' . (!$this->onClickEvent ? 'window.location.hash=\'#sel2\';' : ''); $content .= '<div class="media-left"><input type="radio" name="tempB" value="' . htmlspecialchars($k) . '" onclick="' . htmlspecialchars($oC) . '" /></div>'; // Onclick action for icon/title: $aOnClick = 'document.getElementsByName(\'tempB\')[' . $cc . '].checked=1;' . $oC . 'return false;'; } else { $aOnClick = "document.editForm.defValues.value=unescape('" . rawurlencode($wInfo['params']) . "');goToalt_doc();" . (!$this->onClickEvent ? "window.location.hash='#sel2';" : ''); } if (isset($wInfo['icon'])) { GeneralUtility::deprecationLog('The PageTS-Config: mod.wizards.newContentElement.wizardItems.*.elements.*.icon' . ' is deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8.' . ' Register your icon in IconRegistry::registerIcon and use the new setting:' . ' mod.wizards.newContentElement.wizardItems.*.elements.*.iconIdentifier'); $wInfo['iconIdentifier'] = 'content-' . $k; $icon = $wInfo['icon']; if (StringUtility::beginsWith($icon, '../typo3conf/ext/')) { $icon = str_replace('../typo3conf/ext/', 'EXT:', $icon); } if (!StringUtility::beginsWith($icon, 'EXT:') && strpos($icon, '/') !== false) { $icon = TYPO3_mainDir . GeneralUtility::resolveBackPath($wInfo['icon']); } $iconRegistry->registerIcon($wInfo['iconIdentifier'], BitmapIconProvider::class, array('source' => $icon)); } $icon = $this->moduleTemplate->getIconFactory()->getIcon($wInfo['iconIdentifier'])->render(); $menuItems[$key]['content'] .= ' <div class="media"> <a href="#" onclick="' . htmlspecialchars($aOnClick) . '"> ' . $content . ' <div class="media-left"> ' . $icon . ' </div> <div class="media-body"> <strong>' . htmlspecialchars($wInfo['title']) . '</strong>' . '<br />' . nl2br(htmlspecialchars(trim($wInfo['description']))) . '</div> </a> </div>'; $cc++; } } // Add closing section-tag foreach ($menuItems as $key => $val) { $menuItems[$key]['content'] .= $this->elementWrapper['section'][1]; } // Add the wizard table to the content, wrapped in tabs $code = '<p>' . $lang->getLL('sel1', 1) . '</p>' . $this->moduleTemplate->getDynamicTabMenu($menuItems, 'new-content-element-wizard'); $this->content .= !$this->onClickEvent ? '<h2>' . $lang->getLL('1_selectType', true) . '</h2>' : ''; $this->content .= '<div>' . $code . '</div>'; // If the user must also select a column: if (!$this->onClickEvent) { // Add anchor "sel2" $this->content .= '<div><a name="sel2"></a></div>'; // Select position $code = '<p>' . $lang->getLL('sel2', 1) . '</p>'; // Load SHARED page-TSconfig settings and retrieve column list from there, if applicable: $colPosArray = GeneralUtility::callUserFunction(BackendLayoutView::class . '->getColPosListItemsParsed', $this->id, $this); $colPosIds = array_column($colPosArray, 1); // Removing duplicates, if any $colPosList = implode(',', array_unique(array_map('intval', $colPosIds))); // Finally, add the content of the column selector to the content: $code .= $posMap->printContentElementColumns($this->id, 0, $colPosList, 1, $this->R_URI); $this->content .= '<h2>' . $lang->getLL('2_selectPosition', true) . '</h2><div>' . $code . '</div>'; } } else { // In case of no access: $this->content = ''; $this->content .= '<h1>' . $lang->getLL('newContentElement') . '</h1>'; } $this->content .= '</form>'; // Setting up the buttons and markers for docheader $this->getButtons(); }
/** * Adds a javscript file to the backend after it has been checked that it exists * * @param string $javascriptFile Javascript file reference * @return bool TRUE if the javascript file was successfully added, FALSE otherwise */ public function addJavascriptFile($javascriptFile) { $jsFileAdded = false; // @todo add more checks if necessary if (file_exists(GeneralUtility::resolveBackPath(PATH_typo3 . $javascriptFile))) { $this->jsFiles[] = $javascriptFile; $jsFileAdded = true; } return $jsFileAdded; }
/** * This function acts as a wrapper to allow relative and paths starting with EXT: to be dealt with * in this very case to always return the absolute web path to be included directly before output. * * This is mainly added so the EXT: syntax can be resolved for PageRenderer in one central place, * and hopefully removed in the future by one standard API call. * * @param string $file the filename to process * @param bool $prepareForOutput whether the file should be prepared as version numbered file and prefixed as absolute webpath * @return string * @internal */ protected function getStreamlinedFileName($file, $prepareForOutput = true) { if (strpos($file, 'EXT:') === 0) { $file = GeneralUtility::getFileAbsFileName($file); // as the path is now absolute, make it "relative" to the current script to stay compatible $file = PathUtility::getRelativePathTo($file); $file = rtrim($file, '/'); } else { $file = GeneralUtility::resolveBackPath($file); } if ($prepareForOutput) { $file = GeneralUtility::createVersionNumberedFilename($file); $file = PathUtility::getAbsoluteWebPath($file); } return $file; }
/** * Indexing External URL * * @param string URL, http://.... * @param int Page id to relate indexing to. * @param array Rootline array to relate indexing to * @param int Configuration UID * @param int Set ID value * @return array URLs found on this page */ public function indexExtUrl($url, $pageId, $rl, $cfgUid, $setId) { // Index external URL: $indexerObj = GeneralUtility::makeInstance(\TYPO3\CMS\IndexedSearch\Indexer::class); $indexerObj->backend_initIndexer($pageId, 0, 0, '', $rl); $indexerObj->backend_setFreeIndexUid($cfgUid, $setId); $indexerObj->hash['phash'] = -1; // To avoid phash_t3 being written to file sections (otherwise they are removed when page is reindexed!!!) $indexerObj->indexExternalUrl($url); $url_qParts = parse_url($url); $baseAbsoluteHref = $url_qParts['scheme'] . '://' . $url_qParts['host']; $baseHref = $indexerObj->extractBaseHref($indexerObj->indexExternalUrl_content); if (!$baseHref) { // Extract base href from current URL $baseHref = $baseAbsoluteHref; $baseHref .= substr($url_qParts['path'], 0, strrpos($url_qParts['path'], '/')); } $baseHref = rtrim($baseHref, '/'); // Get URLs on this page: $subUrls = array(); $list = $indexerObj->extractHyperLinks($indexerObj->indexExternalUrl_content); // Traverse links: foreach ($list as $count => $linkInfo) { // Decode entities: $subUrl = htmlspecialchars_decode($linkInfo['href']); $qParts = parse_url($subUrl); if (!$qParts['scheme']) { $relativeUrl = GeneralUtility::resolveBackPath($subUrl); if ($relativeUrl[0] === '/') { $subUrl = $baseAbsoluteHref . $relativeUrl; } else { $subUrl = $baseHref . '/' . $relativeUrl; } } $subUrls[] = $subUrl; } return $subUrls; }
/** * Creates a link to the deprecation log file with the absolute path as the * link text. * * @return string Link to the deprecation log file */ protected function getDeprecationLogFileLink() { $logFile = GeneralUtility::getDeprecationLogFileName(); $relativePath = GeneralUtility::resolveBackPath($this->backPath . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($logFile)); $link = '<a href="' . $relativePath . '">' . $logFile . '</a>'; return $link; }
/** * Compares image path to CSS path and creates the relative backpath from css to the sprites * * @return string */ protected function resolveSpritePath() { // Fix window paths $this->cssFolder = str_replace('\\', '/', $this->cssFolder); $this->spriteFolder = str_replace('\\', '/', $this->spriteFolder); $cssPathSegments = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('/', trim($this->cssFolder, '/')); $graphicPathSegments = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('/', trim($this->spriteFolder, '/')); $i = 0; while (isset($cssPathSegments[$i]) && isset($graphicPathSegments[$i]) && $cssPathSegments[$i] == $graphicPathSegments[$i]) { unset($cssPathSegments[$i]); unset($graphicPathSegments[$i]); ++$i; } foreach ($cssPathSegments as $key => $value) { $cssPathSegments[$key] = '..'; } $completePath = array_merge($cssPathSegments, $graphicPathSegments); $path = implode('/', $completePath); return \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath($path); }
/** * Renders the actual image * * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject * @param $file * @param array $fileConfiguration * @return array */ public function getImgResource(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $contentObject, $file, array $fileConfiguration) { if ($fileConfiguration['import.']) { $ifile = $contentObject->stdWrap('', $fileConfiguration['import.']); if ($ifile) { $file = $fileConfiguration['import'] . $ifile; } } if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($file)) { $file = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory')->getFileObject($file); } if ($file instanceof \TYPO3\CMS\Core\Resource\FileInterface) { $theImage = $file->getForLocalProcessing(FALSE); } else { // clean ../ sections of the path and resolve to proper string. // This is necessary for the \TYPO3\CMS\Core\Resource\Service\FrontendContentAdapterService to work. $file = \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath($file); $theImage = $GLOBALS['TSFE']->tmpl->getFileName($file); if (!$theImage) { return array(); } } $fileConfiguration = $this->processFileConfiguration($fileConfiguration, $contentObject); $maskArray = $fileConfiguration['m.']; $maskImages = array(); // Must render mask images and include in hash-calculating - else we // cannot be sure the filename is unique for the setup! if (is_array($maskArray)) { $maskImages['m_mask'] = $this->getImgResource($contentObject, $maskArray['mask'], $maskArray['mask.']); $maskImages['m_bgImg'] = $this->getImgResource($contentObject, $maskArray['bgImg'], $maskArray['bgImg.']); $maskImages['m_bottomImg'] = $this->getImgResource($contentObject, $maskArray['bottomImg'], $maskArray['bottomImg.']); $maskImages['m_bottomImg_mask'] = $this->getImgResource($contentObject, $maskArray['bottomImg_mask'], $maskArray['bottomImg_mask.']); } // TODO use \TYPO3\CMS\Core\Resource\FileInterface here if ($file instanceof \TYPO3\CMS\Core\Resource\FileReference) { $hash = $file->getOriginalFile()->calculateChecksum(); } else { $hash = \TYPO3\CMS\Core\Utility\GeneralUtility::shortMD5($theImage . serialize($fileConfiguration) . serialize($maskImages)); } if (isset($GLOBALS['TSFE']->tmpl->fileCache[$hash])) { return $GLOBALS['TSFE']->tmpl->fileCache[$hash]; } /** @var $gifCreator tslib_gifbuilder */ $gifCreator = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tslib_gifbuilder'); $gifCreator->init(); if ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']) { $filename = basename($theImage); // Remove extension $filename = substr($filename, 0, strrpos($filename, '.')); $tempFilePrefixLength = intval($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']); if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) { /** @var $t3libCsInstance \TYPO3\CMS\Core\Charset\CharsetConverter */ $t3libCsInstance = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Charset\\CharsetConverter'); $filenamePrefix = $t3libCsInstance->substr('utf-8', $filename, 0, $tempFilePrefixLength); } else { // Strip everything non-ascii $filename = preg_replace('/[^A-Za-z0-9_-]/', '', trim($filename)); $filenamePrefix = substr($filename, 0, $tempFilePrefixLength); } $gifCreator->filenamePrefix = $filenamePrefix . '_'; unset($filename); } if ($fileConfiguration['sample']) { $gifCreator->scalecmd = '-sample'; $GLOBALS['TT']->setTSlogMessage('Sample option: Images are scaled with -sample.'); } if ($fileConfiguration['alternativeTempPath'] && \TYPO3\CMS\Core\Utility\GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['FE']['allowedTempPaths'], $fileConfiguration['alternativeTempPath'])) { $gifCreator->tempPath = $fileConfiguration['alternativeTempPath']; $GLOBALS['TT']->setTSlogMessage('Set alternativeTempPath: ' . $fileConfiguration['alternativeTempPath']); } if (!trim($fileConfiguration['ext'])) { $fileConfiguration['ext'] = 'web'; } $options = array(); if ($fileConfiguration['maxW']) { $options['maxW'] = $fileConfiguration['maxW']; } if ($fileConfiguration['maxH']) { $options['maxH'] = $fileConfiguration['maxH']; } if ($fileConfiguration['minW']) { $options['minW'] = $fileConfiguration['minW']; } if ($fileConfiguration['minH']) { $options['minH'] = $fileConfiguration['minH']; } if ($fileConfiguration['noScale']) { $options['noScale'] = $fileConfiguration['noScale']; } $fileInformation = \TYPO3\CMS\Core\Utility\GeneralUtility::split_fileref($theImage); $imgExt = strtolower($fileInformation['fileext']) == $gifCreator->gifExtension ? $gifCreator->gifExtension : 'jpg'; // If no mask is used or ImageMagick is disabled, processing is quite simple if (!is_array($maskArray) || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) { $fileConfiguration['params'] = $this->modifyImageMagickStripProfileParameters($fileConfiguration['params'], $fileConfiguration); $GLOBALS['TSFE']->tmpl->fileCache[$hash] = $gifCreator->imageMagickConvert($theImage, $fileConfiguration['ext'], $fileConfiguration['width'], $fileConfiguration['height'], $fileConfiguration['params'], $fileConfiguration['frame'], $options); if (($fileConfiguration['reduceColors'] || $imgExt === 'png' && !$gifCreator->png_truecolor) && is_file($GLOBALS['TSFE']->tmpl->fileCache[$hash][3])) { $reduced = $gifCreator->IMreduceColors($GLOBALS['TSFE']->tmpl->fileCache[$hash][3], \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fileConfiguration['reduceColors'], 256, $gifCreator->truecolorColors, 256)); if (is_file($reduced)) { unlink($GLOBALS['TSFE']->tmpl->fileCache[$hash][3]); rename($reduced, $GLOBALS['TSFE']->tmpl->fileCache[$hash][3]); } } } else { // Filename: $fileDestination = $gifCreator->tempPath . $hash . '.' . $imgExt; // Generate! if (!file_exists($fileDestination)) { $this->processMask($maskImages, $gifCreator, $theImage, $fileConfiguration, $options, $fileDestination); } // Finish off if (($fileConfiguration['reduceColors'] || $imgExt === 'png' && !$gifCreator->png_truecolor) && is_file($fileDestination)) { $reduced = $gifCreator->IMreduceColors($fileDestination, \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($fileConfiguration['reduceColors'], 256, $gifCreator->truecolorColors, 256)); if (is_file($reduced)) { unlink($fileDestination); rename($reduced, $fileDestination); } } $GLOBALS['TSFE']->tmpl->fileCache[$hash] = $gifCreator->getImageDimensions($fileDestination); } $GLOBALS['TSFE']->tmpl->fileCache[$hash]['origFile'] = $theImage; // This is needed by tslib_gifbuilder, in order for the setup-array to create a unique filename hash. $GLOBALS['TSFE']->tmpl->fileCache[$hash]['origFile_mtime'] = @filemtime($theImage); $GLOBALS['TSFE']->tmpl->fileCache[$hash]['fileCacheHash'] = $hash; if ($file instanceof \TYPO3\CMS\Core\Resource\FileInterface && \TYPO3\CMS\Core\Utility\GeneralUtility::isAbsPath($GLOBALS['TSFE']->tmpl->fileCache[$hash][3])) { $GLOBALS['TSFE']->tmpl->fileCache[$hash][3] = $file->getPublicUrl(); } $imageResource = $GLOBALS['TSFE']->tmpl->fileCache[$hash]; return $imageResource; }
/** * Render JavaScript files * * @return array<string> jsFiles and jsFooterFiles strings */ protected function renderJavaScriptFiles() { $jsFiles = ''; $jsFooterFiles = ''; if (count($this->jsFiles)) { foreach ($this->jsFiles as $file => $properties) { $file = GeneralUtility::resolveBackPath($file); $file = GeneralUtility::createVersionNumberedFilename($file); $tag = '<script src="' . htmlspecialchars($file) . '" type="' . htmlspecialchars($properties['type']) . '"></script>'; if ($properties['allWrap']) { $wrapArr = explode($properties['splitChar'] ?: '|', $properties['allWrap'], 2); $tag = $wrapArr[0] . $tag . $wrapArr[1]; } $tag .= LF; if ($properties['forceOnTop']) { if ($properties['section'] === self::PART_HEADER) { $jsFiles = $tag . $jsFiles; } else { $jsFooterFiles = $tag . $jsFooterFiles; } } else { if ($properties['section'] === self::PART_HEADER) { $jsFiles .= $tag; } else { $jsFooterFiles .= $tag; } } } } if ($this->moveJsFromHeaderToFooter) { $jsFooterFiles = $jsFiles . $jsFooterFiles; $jsFiles = ''; } return array($jsFiles, $jsFooterFiles); }
/** * Get relative path for $destDir compared to $baseDir * * @param string $baseDir Base directory * @param string $destDir Destination directory * @return string The relative path of destination compared to base. */ public function getRelativePath($baseDir, $destDir) { // A special case, the dirs are equal if ($baseDir === $destDir) { return './'; } // Remove beginning $baseDir = ltrim($baseDir, '/'); $destDir = ltrim($destDir, '/'); $found = true; do { $slash_pos = strpos($destDir, '/'); if ($slash_pos !== false && substr($destDir, 0, $slash_pos) == substr($baseDir, 0, $slash_pos)) { $baseDir = substr($baseDir, $slash_pos + 1); $destDir = substr($destDir, $slash_pos + 1); } else { $found = false; } } while ($found); $slashes = strlen($baseDir) - strlen(str_replace('/', '', $baseDir)); for ($i = 0; $i < $slashes; $i++) { $destDir = '../' . $destDir; } return GeneralUtility::resolveBackPath($destDir); }
/** * Returns absolute path * * @param string $relativePath * @throws ExtensionManagerException * @return string */ protected function getAbsolutePath($relativePath) { $absolutePath = GeneralUtility::getFileAbsFileName(GeneralUtility::resolveBackPath(PATH_site . $relativePath)); if (empty($absolutePath)) { throw new ExtensionManagerException('Illegal relative path given', 1350742864); } return $absolutePath; }