/** * @param array|NULL $backendUser * @param int $size * @param bool $showIcon * @return string */ public function render(array $backendUser = NULL, $size = 32, $showIcon = FALSE) { $size = (int) $size; if (!is_array($backendUser)) { $backendUser = $this->getBackendUser()->user; } $image = parent::render($backendUser, $size, $showIcon); if (!StringUtility::beginsWith($image, '<span class="avatar"><span class="avatar-image"></span>') || empty($backendUser['email'])) { return $image; } $cachedFilePath = PATH_site . 'typo3temp/t3gravatar/'; $cachedFileName = sha1($backendUser['email'] . $size) . '.jpg'; if (!file_exists($cachedFilePath . $cachedFileName)) { $gravatar = 'https://www.gravatar.com/avatar/' . md5(strtolower($backendUser['email'])) . '?s=' . $size . '&d=404'; $gravatarImage = GeneralUtility::getUrl($gravatar); if (empty($gravatarImage)) { return $image; } GeneralUtility::writeFileToTypo3tempDir($cachedFileName, $gravatarImage); } // Icon $icon = ''; if ($showIcon) { $icon = '<span class="avatar-icon">' . IconUtility::getSpriteIconForRecord('be_users', $backendUser) . '</span>'; } $relativeFilePath = PathUtility::getRelativePath(PATH_typo3, $cachedFilePath); return '<span class="avatar"><span class="avatar-image">' . '<img src="' . $relativeFilePath . $cachedFileName . '" width="' . $size . '" height="' . $size . '" /></span>' . $icon . '</span>'; }
/** * Handles the existing files of a Fine Uploader form. * The values are stored in the GET/POST var at the index "fieldValue". * * @return string */ public function getExistingFiles() { $files = array(); $fieldValue = GeneralUtility::_GP('fieldValue'); if ($fieldValue != '') { $imagePath = GeneralUtility::getFileAbsFileName($fieldValue); $imageName = PathUtility::basename($imagePath); $imageDirectoryPath = PathUtility::dirname($imagePath); $imageDirectoryPath = PathUtility::getRelativePath(PATH_site, $imageDirectoryPath); $imageUrl = GeneralUtility::locationHeaderUrl('/' . $imageDirectoryPath . $imageName); if (file_exists($imagePath)) { $files[] = array('name' => $imageName, 'uuid' => $imageUrl, 'thumbnailUrl' => $imageUrl); } } return json_encode($files); }
/** * Handles the existing files of a Fine Uploader form. * The values are stored in the GET/POST var at the index "fieldValue". * * @return string */ public function getExistingFiles() { $files = []; $fieldValue = GeneralUtility::_GP('fieldValue'); if ($fieldValue != '') { // $imagePath = GeneralUtility::getFileAbsFileName($fieldValue); $imagePath = str_replace('new:', '', $fieldValue); $imageName = PathUtility::basename($imagePath); $imageDirectoryPath = PathUtility::dirname($imagePath); $imageDirectoryPath = PathUtility::getRelativePath(PATH_site, $imageDirectoryPath); $imageUrl = GeneralUtility::locationHeaderUrl('/' . $imageDirectoryPath . $imageName); if (file_exists($imagePath)) { $files[] = ['name' => $imageName, 'uuid' => $imageUrl, 'thumbnailUrl' => $imageUrl]; } } return $files; }
/** * Call function if you need the requireJS library * this automatically adds the JavaScript path of all loaded extensions in the requireJS path option * so it resolves names like TYPO3/CMS/MyExtension/MyJsFile to EXT:MyExtension/Resources/Public/JavaScript/MyJsFile.js * when using requireJS * * @return void */ public function loadRequireJs() { // load all paths to map to package names / namespaces if (count($this->requireJsConfig) === 0) { // first, load all paths for the namespaces, and configure contrib libs. $this->requireJsConfig['paths'] = array('jquery-ui' => 'contrib/jqueryui', 'jquery' => 'contrib/jquery'); // get all extensions that are loaded $loadedExtensions = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray(); foreach ($loadedExtensions as $packageName) { $fullJsPath = 'EXT:' . $packageName . '/Resources/Public/JavaScript/'; $fullJsPath = GeneralUtility::getFileAbsFileName($fullJsPath); $fullJsPath = \TYPO3\CMS\Core\Utility\PathUtility::getRelativePath(PATH_typo3, $fullJsPath); $fullJsPath = rtrim($fullJsPath, '/'); if ($fullJsPath) { $this->requireJsConfig['paths']['TYPO3/CMS/' . GeneralUtility::underscoredToUpperCamelCase($packageName)] = $this->backPath . $fullJsPath; } } // check if additional AMD modules need to be loaded if a single AMD module is initialized if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules'])) { $this->addInlineSettingArray('RequireJS.PostInitializationModules', $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules']); } } $this->addRequireJs = TRUE; }
/** * Call function if you need the requireJS library * this automatically adds the JavaScript path of all loaded extensions in the requireJS path option * so it resolves names like TYPO3/CMS/MyExtension/MyJsFile to EXT:MyExtension/Resources/Public/JavaScript/MyJsFile.js * when using requireJS * * @return void */ public function loadRequireJs() { // load all paths to map to package names / namespaces if (empty($this->requireJsConfig)) { // In order to avoid browser caching of JS files, adding a GET parameter to the files loaded via requireJS if (GeneralUtility::getApplicationContext()->isDevelopment()) { $this->requireJsConfig['urlArgs'] = 'bust=' . $GLOBALS['EXEC_TIME']; } else { $this->requireJsConfig['urlArgs'] = 'bust=' . GeneralUtility::hmac(TYPO3_version . PATH_site); } // first, load all paths for the namespaces, and configure contrib libs. $this->requireJsConfig['paths'] = array('jquery-ui' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/jquery-ui', 'datatables' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/jquery.dataTables', 'nprogress' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/nprogress', 'moment' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/moment', 'cropper' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/cropper.min', 'imagesloaded' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/imagesloaded.pkgd.min', 'bootstrap' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap/bootstrap', 'twbs/bootstrap-datetimepicker' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap-datetimepicker', 'autosize' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/autosize', 'taboverride' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/taboverride.min', 'twbs/bootstrap-slider' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/bootstrap-slider.min', 'jquery/autocomplete' => $this->backPath . 'sysext/core/Resources/Public/JavaScript/Contrib/jquery.autocomplete'); // get all extensions that are loaded $loadedExtensions = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getLoadedExtensionListArray(); foreach ($loadedExtensions as $packageName) { $fullJsPath = 'EXT:' . $packageName . '/Resources/Public/JavaScript/'; $fullJsPath = GeneralUtility::getFileAbsFileName($fullJsPath); $fullJsPath = \TYPO3\CMS\Core\Utility\PathUtility::getRelativePath(PATH_typo3, $fullJsPath); $fullJsPath = rtrim($fullJsPath, '/'); if ($fullJsPath) { $this->requireJsConfig['paths']['TYPO3/CMS/' . GeneralUtility::underscoredToUpperCamelCase($packageName)] = $this->backPath . $fullJsPath; } } // check if additional AMD modules need to be loaded if a single AMD module is initialized if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules'])) { $this->addInlineSettingArray('RequireJS.PostInitializationModules', $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['RequireJS']['postInitializationModules']); } } $this->addRequireJs = true; }
/** * @param string $source * @param string $target * @param string $expected * @dataProvider isRelativePathResolvedCorrectlyDataProvider * @test */ public function isRelativePathResolvedCorrectly($source, $target, $expected) { $relativePath = \TYPO3\CMS\Core\Utility\PathUtility::getRelativePath($source, $target); $this->assertEquals($expected, $relativePath); }
/** * @return void */ protected function attachAssets() { if (FALSE === self::$assetsIncluded) { $doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate'); $doc->backPath = $GLOBALS['BACK_PATH']; /** @var PageRenderer $pageRenderer */ $pageRenderer = $doc->getPageRenderer(); $pageRenderer->addCssFile($doc->backPath . ExtensionManagementUtility::extRelPath('flux') . 'Resources/Public/css/grid.css'); // /typo3/sysext/backend/Resources/Public/JavaScript/LayoutModule/DragDrop.js // is not the perfect solution for Flux Grids! // an adapted version of DragDrop.js is used - Resources/Public/js/VersionSevenPointTwo/DragDrop.js // Also fluxCollapse.js is updated. $fullJsPath = PathUtility::getRelativePath(PATH_typo3, GeneralUtility::getFileAbsFileName('EXT:flux/Resources/Public/js/')); // requirejs $pageRenderer->addRequireJsConfiguration(array('paths' => array('FluidTypo3/Flux/DragDrop' => $fullJsPath . 'DragDrop'))); $pageRenderer->loadRequireJsModule('FluidTypo3/Flux/DragDrop'); // This is necessary for fluxCollapse.js $pageRenderer->loadExtJS(); $pageRenderer->addJsFile($doc->backPath . ExtensionManagementUtility::extRelPath('flux') . 'Resources/Public/js/fluxCollapse.js'); self::$assetsIncluded = TRUE; } }
/** * Bulk function, can be used for anything to get a file or folder * * 1. It's a UID * 2. It's a combined identifier * 3. It's just a path/filename (coming from the oldstyle/backwards compatibility) * * Files, previously laid on fileadmin/ or something, will be "mapped" to the storage the file is * in now. Files like typo3temp/ or typo3conf/ will be moved to the first writable storage * in its processing folder * * $input could be * - "2:myfolder/myfile.jpg" (combined identifier) * - "23" (file UID) * - "uploads/myfile.png" (backwards-compatibility, storage "0") * - "file:23" * * @param string $input * @return FileInterface|Folder */ public function retrieveFileOrFolderObject($input) { // Remove PATH_site because absolute paths under Windows systems contain ':' // This is done in all considered sub functions anyway $input = str_replace(PATH_site, '', $input); if (GeneralUtility::isFirstPartOfStr($input, 'file:')) { $input = substr($input, 5); return $this->retrieveFileOrFolderObject($input); } elseif (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($input)) { return $this->getFileObject($input); } elseif (strpos($input, ':') > 0) { list($prefix, $folderIdentifier) = explode(':', $input); if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($prefix)) { // path or folder in a valid storageUID return $this->getObjectFromCombinedIdentifier($input); } elseif ($prefix == 'EXT') { $input = GeneralUtility::getFileAbsFileName($input); if (empty($input)) { return NULL; } $input = PathUtility::getRelativePath(PATH_site, dirname($input)) . basename($input); return $this->getFileObjectFromCombinedIdentifier($input); } else { return NULL; } } else { // this is a backwards-compatible way to access "0-storage" files or folders // eliminate double slashes, /./ and /../ $input = \TYPO3\CMS\Core\Utility\PathUtility::getCanonicalPath(ltrim($input, '/')); if (@is_file(PATH_site . $input)) { // only the local file return $this->getFileObjectFromCombinedIdentifier($input); } else { // only the local path return $this->getFolderObjectFromCombinedIdentifier($input); } } }
/** * Decides whether a client can deal with gzipped content or not and returns the according file name, * based on HTTP_ACCEPT_ENCODING * * @param string $filename File name * @return string $filename suffixed with '.gzip' or not - dependent on HTTP_ACCEPT_ENCODING */ protected function returnFileReference($filename) { // if the client accepts gzip and we can create gzipped files, we give him compressed versions if ($this->createGzipped && strpos(GeneralUtility::getIndpEnv('HTTP_ACCEPT_ENCODING'), 'gzip') !== false) { $filename .= '.gzip'; } return PathUtility::getRelativePath($this->rootPath, PATH_site) . $filename; }
/** * Create the crop image (GifBuilder) * * @param $absoluteImageName * @param $focusWidth * @param $focusHeight * @param $sourceX * @param $sourceY * @param $absoluteTempImageName */ protected function createCropImageGifBuilder($absoluteImageName, $focusWidth, $focusHeight, $sourceX, $sourceY, $absoluteTempImageName) { $size = getimagesize($absoluteImageName); $relativeImagePath = rtrim(PathUtility::getRelativePath(GeneralUtility::getIndpEnv('TYPO3_DOCUMENT_ROOT'), $absoluteImageName), '/'); $configuration = ['format' => strtolower(PathUtility::pathinfo($absoluteImageName, PATHINFO_EXTENSION)), 'XY' => $size[0] . ',' . $size[1], 'transparentBackground' => '1', '10' => 'IMAGE', '10.' => ['file' => $relativeImagePath, 'file.' => ['quality' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality'], 'width' => $size[0], 'height' => $size[1]]], '20' => 'CROP', '20.' => ['crop' => $sourceX . ',' . $sourceY . ',' . $focusWidth . ',' . $focusHeight]]; /** @var \TYPO3\CMS\Frontend\Imaging\GifBuilder $gifBuilder */ $gifBuilder = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Imaging\\GifBuilder'); $gifBuilder->init(); $gifBuilder->start($configuration, []); $gifBuilder->createTempSubDir('focuscrop/'); $gifBuilder->make(); $gifBuilder->output($absoluteTempImageName); $gifBuilder->destroy(); }
/** * Loads the css and javascript files of all registered navigation widgets * * @return void */ protected function loadResourcesForRegisteredNavigationComponents() { if (!is_array($GLOBALS['TBE_MODULES']['_navigationComponents'])) { return; } $loadedComponents = []; foreach ($GLOBALS['TBE_MODULES']['_navigationComponents'] as $module => $info) { if (in_array($info['componentId'], $loadedComponents)) { continue; } $loadedComponents[] = $info['componentId']; $component = strtolower(substr($info['componentId'], strrpos($info['componentId'], '-') + 1)); $componentDirectory = 'components/' . $component . '/'; if ($info['isCoreComponent']) { $componentDirectory = 'Resources/Public/JavaScript/extjs/' . $componentDirectory; $info['extKey'] = 'backend'; } $absoluteComponentPath = ExtensionManagementUtility::extPath($info['extKey']) . $componentDirectory; $relativeComponentPath = PathUtility::getRelativePath(PATH_site . TYPO3_mainDir, $absoluteComponentPath); $cssFiles = GeneralUtility::getFilesInDir($absoluteComponentPath . 'css/', 'css'); if (file_exists($absoluteComponentPath . 'css/loadorder.txt')) { // Don't allow inclusion outside directory $loadOrder = str_replace('../', '', file_get_contents($absoluteComponentPath . 'css/loadorder.txt')); $cssFilesOrdered = GeneralUtility::trimExplode(LF, $loadOrder, true); $cssFiles = array_merge($cssFilesOrdered, $cssFiles); } foreach ($cssFiles as $cssFile) { $this->pageRenderer->addCssFile($relativeComponentPath . 'css/' . $cssFile); } $jsFiles = GeneralUtility::getFilesInDir($absoluteComponentPath . 'javascript/', 'js'); if (file_exists($absoluteComponentPath . 'javascript/loadorder.txt')) { // Don't allow inclusion outside directory $loadOrder = str_replace('../', '', file_get_contents($absoluteComponentPath . 'javascript/loadorder.txt')); $jsFilesOrdered = GeneralUtility::trimExplode(LF, $loadOrder, true); $jsFiles = array_merge($jsFilesOrdered, $jsFiles); } foreach ($jsFiles as $jsFile) { $this->pageRenderer->addJsFile($relativeComponentPath . 'javascript/' . $jsFile); } $this->pageRenderer->addInlineSetting('RecordHistory', 'moduleUrl', BackendUtility::getModuleUrl('record_history')); $this->pageRenderer->addInlineSetting('NewRecord', 'moduleUrl', BackendUtility::getModuleUrl('db_new')); $this->pageRenderer->addInlineSetting('FormEngine', 'moduleUrl', BackendUtility::getModuleUrl('record_edit')); } }