/** * Generates configuration. Locks configuration file for exclusive access to avoid collisions. Will not be stabe on Windows. * * @return void */ public function generateConfiguration() { $fileName = PATH_site . self::AUTOCONFIGURTION_FILE; if (class_exists('TYPO3\\CMS\\Core\\Locking\\LockFactory')) { $lockFactory = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Locking\\LockFactory'); $lockObject = $lockFactory->createLocker($fileName, LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE | LockingStrategyInterface::LOCK_CAPABILITY_NOBLOCK); $lockObject->acquire(); } else { // @deprecated since 7.6, will be removed once 6.2 support is removed $lockObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Locking\\Locker', $fileName, $GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode']); $lockObject->setEnableLogging(false); $lockObject->acquireExclusiveLock(); } $fd = @fopen($fileName, 'a+'); if ($fd) { // Check size fseek($fd, 0, SEEK_END); if (ftell($fd) == 0) { $this->doGenerateConfiguration($fd); } fclose($fd); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($fileName); } $lockObject->release(); }
/** * Creates the INSTALL_TOOL_ENABLE file * * @return bool */ public static function createInstallToolEnableFile() { $installEnableFilePath = self::getInstallToolEnableFilePath(); $result = touch($installEnableFilePath); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($installEnableFilePath); return $result; }
/** * Creates the INSTALL_TOOL_ENABLE file * * @return bool */ public static function createInstallToolEnableFile() { $installEnableFilePath = self::getInstallToolEnableFilePath(); if (!is_file($installEnableFilePath)) { $result = touch($installEnableFilePath); } else { $result = true; self::extendInstallToolEnableFileLifetime(); } \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($installEnableFilePath); return $result; }
/** * Get local absolute file path to preview image * * @param File $file * @return string */ public function getPreviewImage(File $file) { $videoId = $this->getOnlineMediaId($file); $temporaryFileName = $this->getTempFolderPath() . 'youtube_' . md5($videoId) . '.jpg'; if (!file_exists($temporaryFileName)) { $previewImage = GeneralUtility::getUrl(sprintf('https://img.youtube.com/vi/%s/0.jpg', $videoId)); if ($previewImage !== false) { file_put_contents($temporaryFileName, $previewImage); GeneralUtility::fixPermissions($temporaryFileName); } } return $temporaryFileName; }
/** * Get local absolute file path to preview image * * @param File $file * @return string */ public function getPreviewImage(File $file) { $soundCloudId = $this->getOnlineMediaId($file); $temporaryFileName = $this->getTempFolderPath() . 'soundcloud_' . md5($soundCloudId) . '.jpg'; if (!file_exists($temporaryFileName)) { $oEmbedData = $this->getOEmbedData($soundCloudId); $previewImage = GeneralUtility::getUrl($oEmbedData['thumbnail_url']); if ($previewImage !== false) { file_put_contents($temporaryFileName, $previewImage); GeneralUtility::fixPermissions($temporaryFileName); } } return $temporaryFileName; }
/** * Generates configuration. Locks configuration file for exclusive access to avoid collisions. Will not be stabe on Windows. * * @return void */ public function generateConfiguration() { $fileName = PATH_site . self::AUTOCONFIGURTION_FILE; $lockObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Locking\\Locker', $fileName, $GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode']); /** @var \TYPO3\CMS\Core\Locking\Locker $lockObject */ $lockObject->setEnableLogging(FALSE); $lockObject->acquireExclusiveLock(); $fd = @fopen($fileName, 'a+'); if ($fd) { // Check size fseek($fd, 0, SEEK_END); if (ftell($fd) == 0) { $this->doGenerateConfiguration($fd); } fclose($fd); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($fileName); } $lockObject->release(); }
/** * myFunction which is called over cli * */ function massSend() { // Check if cronjob is already running: if (@file_exists(PATH_site . 'typo3temp/tx_directmail_cron.lock')) { // If the lock is not older than 1 day, skip index creation: if (filemtime(PATH_site . 'typo3temp/tx_directmail_cron.lock') > time() - 60 * 60 * 24) { die('TYPO3 Direct Mail Cron: Aborting, another process is already running!' . LF); } else { echo 'TYPO3 Direct Mail Cron: A .lock file was found but it is older than 1 day! Processing mails ...' . LF; } } $lockfile = PATH_site . 'typo3temp/tx_directmail_cron.lock'; touch($lockfile); // Fixing filepermissions \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($lockfile); /** @var $htmlmail \DirectMailTeam\DirectMail\Dmailer */ $htmlmail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('DirectMailTeam\\DirectMail\\Dmailer'); $htmlmail->start(); $htmlmail->runcron(); unlink($lockfile); }
/** * Writes the input GDlib image pointer to file * * @param resource $destImg The GDlib image resource pointer * @param string $theImage The filename to write to * @param int $quality The image quality (for JPEGs) * @return bool The output of either imageGif, imagePng or imageJpeg based on the filename to write * @see maskImageOntoImage(), scale(), output() */ public function ImageWrite($destImg, $theImage, $quality = 0) { imageinterlace($destImg, 0); $ext = strtolower(substr($theImage, strrpos($theImage, '.') + 1)); $result = false; switch ($ext) { case 'jpg': case 'jpeg': if (function_exists('imageJpeg')) { if ($quality == 0) { $quality = $this->jpegQuality; } $result = imageJpeg($destImg, $theImage, $quality); } break; case 'gif': if (function_exists('imageGif')) { imagetruecolortopalette($destImg, true, 256); $result = imageGif($destImg, $theImage); } break; case 'png': if (function_exists('imagePng')) { $result = ImagePng($destImg, $theImage); } break; } if ($result) { GeneralUtility::fixPermissions($theImage); } return $result; }
/** * Creates a new (empty) file and returns the identifier. * * @param string $fileName * @param string $parentFolderIdentifier * @return string * @throws Exception\InvalidFileNameException * @throws \RuntimeException */ public function createFile($fileName, $parentFolderIdentifier) { if (!$this->isValidFilename($fileName)) { throw new Exception\InvalidFileNameException('Invalid characters in fileName "' . $fileName . '"', 1320572272); } $parentFolderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier); $fileIdentifier = $this->canonicalizeAndCheckFileIdentifier($parentFolderIdentifier . $this->sanitizeFileName(ltrim($fileName, '/'))); $absoluteFilePath = $this->getAbsolutePath($fileIdentifier); $result = touch($absoluteFilePath); GeneralUtility::fixPermissions($absoluteFilePath); clearstatcache(); if ($result !== true) { throw new \RuntimeException('Creating file ' . $fileIdentifier . ' failed.', 1320569854); } return $fileIdentifier; }
/** * Try to acquire an exclusive lock * * @throws \RuntimeException * @return bool Returns TRUE if the lock was acquired successfully */ public function acquireExclusiveLock() { if ($this->isAcquired) { return true; } $this->isAcquired = false; switch ($this->method) { case self::LOCKING_METHOD_SIMPLE: if (file_exists($this->resource)) { $this->sysLog('Waiting for a different process to release the lock'); $maxExecutionTime = (int) ini_get('max_execution_time'); $maxAge = time() - ($maxExecutionTime ?: 120); if (@filectime($this->resource) < $maxAge) { @unlink($this->resource); $this->sysLog('Unlinking stale lockfile', GeneralUtility::SYSLOG_SEVERITY_WARNING); } } for ($i = 0; $i < $this->loops; $i++) { $filePointer = @fopen($this->resource, 'x'); if ($filePointer !== false) { fclose($filePointer); GeneralUtility::fixPermissions($this->resource); $this->sysLog('Lock acquired'); $this->isAcquired = true; break; } usleep($this->step * 1000); } break; case self::LOCKING_METHOD_FLOCK: $this->filePointer = fopen($this->resource, 'c'); if ($this->filePointer === false) { throw new \RuntimeException('Lock file could not be opened', 1294586099); } if (flock($this->filePointer, LOCK_EX)) { $this->isAcquired = true; } break; case self::LOCKING_METHOD_SEMAPHORE: $this->getSemaphore(); if (@sem_acquire($this->resource)) { $this->isAcquired = true; } break; case self::LOCKING_METHOD_DISABLED: break; default: // will never be reached } return $this->isAcquired; }
/** * Create the thumbnail * Will exit before return if all is well. * * @return void * @todo Define visibility */ public function main() { // Clean output buffer to ensure no extraneous output exists ob_clean(); // If file exists, we make a thumbnail of the file. if (is_object($this->image)) { // Check file extension: if ($this->image->getExtension() == 'ttf') { // Make font preview... (will not return) $this->fontGif($this->image); } elseif ($this->image->getType() != File::FILETYPE_IMAGE && !GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $this->image->getExtension())) { $this->errorGif('Not imagefile!', 'No ext!', $this->image->getName()); } // ... so we passed the extension test meaning that we are going to make a thumbnail here: // default if (!$this->size) { $this->size = $this->sizeDefault; } // I added extra check, so that the size input option could not be fooled to pass other values. // That means the value is exploded, evaluated to an integer and the imploded to [value]x[value]. // Furthermore you can specify: size=340 and it'll be translated to 340x340. // explodes the input size (and if no "x" is found this will add size again so it is the same for both dimensions) $sizeParts = explode('x', $this->size . 'x' . $this->size); // Cleaning it up, only two parameters now. $sizeParts = array(MathUtility::forceIntegerInRange($sizeParts[0], 1, 1000), MathUtility::forceIntegerInRange($sizeParts[1], 1, 1000)); // Imploding the cleaned size-value back to the internal variable $this->size = implode('x', $sizeParts); // Getting max value $sizeMax = max($sizeParts); // Init $outpath = PATH_site . $this->outdir; // Should be - ? 'png' : 'gif' - , but doesn't work (ImageMagick prob.?) // René: png work for me $thmMode = MathUtility::forceIntegerInRange($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails_png'], 0); $outext = $this->image->getExtension() != 'jpg' || $thmMode & 2 ? $thmMode & 1 ? 'png' : 'gif' : 'jpg'; $outfile = 'tmb_' . substr(md5($this->image->getName() . $this->mtime . $this->size), 0, 10) . '.' . $outext; $this->output = $outpath . $outfile; if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) { // If thumbnail does not exist, we generate it if (!file_exists($this->output)) { $parameters = '-sample ' . $this->size . ' ' . $this->wrapFileName($this->image->getForLocalProcessing(FALSE)) . '[0] ' . $this->wrapFileName($this->output); $cmd = GeneralUtility::imageMagickCommand('convert', $parameters); \TYPO3\CMS\Core\Utility\CommandUtility::exec($cmd); if (!file_exists($this->output)) { $this->errorGif('No thumb', 'generated!', $this->image->getName()); } else { GeneralUtility::fixPermissions($this->output); } } // The thumbnail is read and output to the browser if ($fd = @fopen($this->output, 'rb')) { $fileModificationTime = filemtime($this->output); header('Content-Type: image/' . ($outext === 'jpg' ? 'jpeg' : $outext)); header('Last-Modified: ' . date('r', $fileModificationTime)); header('ETag: ' . md5($this->output) . '-' . $fileModificationTime); // Expiration time is chosen arbitrary to 1 month header('Expires: ' . date('r', $fileModificationTime + 30 * 24 * 60 * 60)); fpassthru($fd); fclose($fd); } else { $this->errorGif('Read problem!', '', $this->output); } } else { die; } } else { $this->errorGif('No valid', 'inputfile!', basename($this->image)); } }
/** * Write session data. See @session_set_save_handler * * @param string $id The session id * @param string $sessionData The data to be stored * @throws Exception * @return bool */ public function write($id, $sessionData) { $sessionFile = $this->getSessionFile($id); $result = false; $changePermissions = !@is_file($sessionFile); if ($fd = fopen($sessionFile, 'cb')) { if (flock($fd, LOCK_EX)) { ftruncate($fd, 0); $res = fwrite($fd, $sessionData); if ($res !== false) { fflush($fd); $result = true; } flock($fd, LOCK_UN); } fclose($fd); // Change the permissions only if the file has just been created if ($changePermissions) { GeneralUtility::fixPermissions($sessionFile); } } if (!$result) { throw new Exception('Session file not writable. Please check permission on typo3temp/var/InstallToolSessions and its subdirectories.', 1424355157); } return $result; }
/** * Closes the file handler and fixes permissions. * * @return void */ protected function closeFile() { fclose($this->filePointer); $this->filePointer = false; \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($this->targetFilePath); }
/** * @test */ public function fixPermissionsSetsDefaultPermissionsToDirectory() { if (TYPO3_OS == 'WIN') { $this->markTestSkipped('fixPermissions() tests not available on Windows'); } $directory = PATH_site . 'typo3temp/' . $this->getUniqueId('test_'); GeneralUtility::mkdir($directory); $this->testFilesToDelete[] = $directory; chmod($directory, 1551); unset($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']); $fixPermissionsResult = GeneralUtility::fixPermissions($directory); clearstatcache(); $this->assertTrue($fixPermissionsResult); $this->assertEquals('0755', substr(decoct(fileperms($directory)), 1)); }
/** * Write the icon in $im pointer to $path * * @param pointer $im Pointer to GDlib image resource * @param string $path Absolute path to the filename in which to write the icon. * @return void * @access private */ public static function imagemake($im, $path) { if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png']) { @ImagePng($im, $path); } else { @ImageGif($im, $path); } if (@is_file($path)) { GeneralUtility::fixPermissions($path); } }
/** * @test */ public function fixPermissionsSetsPermissionsWithRelativeFileReference() { if (TYPO3_OS === 'WIN') { $this->markTestSkipped('fixPermissions() tests not available on Windows'); } $filename = 'typo3temp/' . $this->getUniqueId('test_'); GeneralUtility::writeFileToTypo3tempDir(PATH_site . $filename, '42'); $this->testFilesToDelete[] = PATH_site . $filename; chmod(PATH_site . $filename, 482); // Set target permissions and run method $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] = '0660'; $fixPermissionsResult = GeneralUtility::fixPermissions($filename); clearstatcache(); $this->assertTrue($fixPermissionsResult); $this->assertEquals('0660', substr(decoct(fileperms(PATH_site . $filename)), 2)); }
/** * Saves the configuration. * * @param array $configuration * @return void */ protected function saveConfiguration(array $configuration) { $extensionConfiguration = @unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['realurl']); $fileName = PATH_site . TX_REALURL_AUTOCONF_FILE; if ($extensionConfiguration['autoConfFormat'] == 0) { file_put_contents($fileName, '<' . '?php' . chr(10) . '$GLOBALS[\'TYPO3_CONF_VARS\'][\'EXTCONF\'][\'realurl\']=' . 'unserialize(\'' . str_replace('\'', '\\\'', serialize($configuration)) . '\');' . chr(10)); } else { file_put_contents($fileName, '<' . '?php' . chr(10) . '$GLOBALS[\'TYPO3_CONF_VARS\'][\'EXTCONF\'][\'realurl\']=' . var_export($configuration, TRUE) . ';' . chr(10)); } GeneralUtility::fixPermissions($fileName); }
/** * This method actually does the processing of files locally * * takes the original file (on remote storages this will be fetched from the remote server) * does the IM magic on the local server by creating a temporary typo3temp/ file * copies the typo3temp/ file to the processingfolder of the target storage * removes the typo3temp/ file * * @param \TYPO3\CMS\Core\Resource\ProcessedFile $processedFile * @param \TYPO3\CMS\Core\Resource\FileInterface $file * @param array $configuration * @return void */ protected function processImageCropResizeMask(\TYPO3\CMS\Core\Resource\ProcessedFile $processedFile, \TYPO3\CMS\Core\Resource\FileInterface $file, array $configuration) { // checks to see if m (the mask array) is defined $doMasking = is_array($configuration['maskImages']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']; // @todo: is it ok that we use tslib (=FE) here? /** @var $gifBuilder tslib_gifbuilder */ $gifBuilder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tslib_gifbuilder'); $gifBuilder->init(); // @todo: this is not clean yet if (!trim($configuration['fileExtension'])) { $configuration['fileExtension'] = 'web'; $targetFileExtension = $file->getExtension(); } elseif ($doMasking) { $targetFileExtension = $file->getExtension() == $gifBuilder->gifExtension ? $gifBuilder->gifExtension : 'jpg'; } else { $targetFileExtension = $configuration['fileExtension']; } $originalFileName = $file->getForLocalProcessing(FALSE); $targetFolder = $this->storage->getProcessingFolder(); $targetFileName = 'previewcrm_' . $processedFile->calculateChecksum() . '.' . $targetFileExtension; // @todo: implement meaningful TempFileIndex if ($configuration['useSample']) { $gifBuilder->scalecmd = '-sample'; } $options = array(); if ($configuration['maxWidth']) { $options['maxW'] = $configuration['maxWidth']; } if ($configuration['maxHeight']) { $options['maxH'] = $configuration['maxHeight']; } if ($configuration['minWidth']) { $options['minW'] = $configuration['minWidth']; } if ($configuration['minHeight']) { $options['minH'] = $configuration['minHeight']; } $options['noScale'] = $configuration['noScale']; $configuration['additionalParameters'] = $this->modifyImageMagickStripProfileParameters($configuration['additionalParameters'], $configuration); // Do the actual processing if (!$targetFolder->hasFile($targetFileName)) { if (!$doMasking) { // Normal situation (no masking) // the result info is an array with 0=width,1=height,2=extension,3=filename list($targetWidth, $targetHeight, $targetExtension, $temporaryFileName) = $gifBuilder->imageMagickConvert($originalFileName, $configuration['fileExtension'], $configuration['width'], $configuration['height'], $configuration['additionalParameters'], $configuration['frame'], $options); } else { $temporaryFileName = $gifBuilder->tempPath . $targetFileName; $maskImage = $configuration['maskImages']['maskImage']; $maskBackgroundImage = $configuration['maskImages']['backgroundImage']; if ($maskImage instanceof \TYPO3\CMS\Core\Resource\FileInterface && $maskBackgroundImage instanceof \TYPO3\CMS\Core\Resource\FileInterface) { $negate = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_negate_mask'] ? ' -negate' : ''; $temporaryExtension = 'png'; if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_gif']) { // If ImageMagick version 5+ $temporaryExtension = $gifBuilder->gifExtension; } $tempFileInfo = $gifBuilder->imageMagickConvert($originalFileName, $temporaryExtension, $configuration['width'], $configuration['height'], $configuration['additionalParameters'], $configuration['frame'], $options); if (is_array($tempFileInfo)) { $maskBottomImage = $configuration['maskImages']['maskBottomImage']; if ($maskBottomImage instanceof $maskBottomImage) { $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask']; } // Scaling: **** $tempScale = array(); $command = '-geometry ' . $tempFileInfo[0] . 'x' . $tempFileInfo[1] . '!'; $command = $this->modifyImageMagickStripProfileParameters($command, $configuration); $tmpStr = $gifBuilder->randomName(); // m_mask $tempScale['m_mask'] = $tmpStr . '_mask.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskImage->getForLocalProcessing(TRUE), $tempScale['m_mask'], $command . $negate); // m_bgImg $tempScale['m_bgImg'] = $tmpStr . '_bgImg.' . trim($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_mask_temp_ext_noloss']); $gifBuilder->imageMagickExec($maskBackgroundImage->getForLocalProcessing(), $tempScale['m_bgImg'], $command); // m_bottomImg / m_bottomImg_mask if ($maskBottomImage instanceof \TYPO3\CMS\Core\Resource\FileInterface && $maskBottomImageMask instanceof \TYPO3\CMS\Core\Resource\FileInterface) { $tempScale['m_bottomImg'] = $tmpStr . '_bottomImg.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskBottomImage->getForLocalProcessing(), $tempScale['m_bottomImg'], $command); $tempScale['m_bottomImg_mask'] = $tmpStr . '_bottomImg_mask.' . $temporaryExtension; $gifBuilder->imageMagickExec($maskBottomImageMask->getForLocalProcessing(), $tempScale['m_bottomImg_mask'], $command . $negate); // BEGIN combining: // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempScale['m_bottomImg'], $tempScale['m_bottomImg_mask'], $tempScale['m_bgImg']); } // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempFileInfo[3], $tempScale['m_mask'], $temporaryFileName); // Unlink the temp-images... foreach ($tempScale as $file) { if (@is_file($file)) { unlink($file); } } } } // Finish off list($targetWidth, $targetHeight) = $gifBuilder->getImageDimensions($temporaryFileName); } // Temporary image was created if (file_exists($temporaryFileName)) { $updatedProperties = array('width' => $targetWidth, 'height' => $targetHeight); // ImageMagick did not have to do anything, as it is already there... if ($originalFileName !== $temporaryFileName) { \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryFileName); // Copy the temporary file to the processedFolder // this is done here, as the driver can do this without worrying // about existing ProcessedFile objects // or permissions in the storage // for "remote" storages this means "uploading" the file to the storage again // for the virtual storage, it is merely a thing of "copying a file from typo3temp/ to typo3temp/_processed_" $this->driver->addFile($temporaryFileName, $targetFolder, $targetFileName, $processedFile); // Remove the temporary file as it's not needed anymore \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($temporaryFileName); } else { } $processedFile->updateProperties($updatedProperties); $processedFile->setProcessed(TRUE); } } }
/** * Saves data in a cache file. * * @param string $entryIdentifier An identifier for this specific cache entry * @param string $data The data to be stored * @param array $tags Tags to associate with this cache entry * @param int $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited lifetime. * @return void * @throws \TYPO3\CMS\Core\Cache\Exception if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set. * @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException if the data to bes stored is not a string. * @throws \InvalidArgumentException * @api */ public function set($entryIdentifier, $data, array $tags = array(), $lifetime = null) { if (!is_string($data)) { throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1334756734); } if ($entryIdentifier !== basename($entryIdentifier)) { throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1334756735); } if ($entryIdentifier === '') { throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1334756736); } $temporaryCacheEntryPathAndFilename = $this->cacheDirectory . StringUtility::getUniqueId() . '.temp'; $result = file_put_contents($temporaryCacheEntryPathAndFilename, $data); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename); if ($result === false) { throw new \TYPO3\CMS\Core\Cache\Exception('The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.', 1334756737); } $cacheEntryPathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename); if ($this->cacheEntryFileExtension === '.php') { GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive($cacheEntryPathAndFilename); } }
/** * Adds a file from the local server hard disk to a given path in TYPO3s virtual file system. * * This assumes that the local file exists, so no further check is done here! * * @param string $localFilePath * @param \TYPO3\CMS\Core\Resource\Folder $targetFolder * @param string $fileName The name to add the file under * @param \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject File object to update (instead of creating a new object). With this parameter, this function can be used to "populate" a dummy file object with a real file underneath. * @todo \TYPO3\CMS\Core\Resource\File $updateFileObject should be \TYPO3\CMS\Core\Resource\FileInterface, but indexer logic is only in \TYPO3\CMS\Core\Resource\File * @return \TYPO3\CMS\Core\Resource\FileInterface */ public function addFile($localFilePath, \TYPO3\CMS\Core\Resource\Folder $targetFolder, $fileName, \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject = NULL) { // as for the "virtual storage" for backwards-compatibility, this check always fails, as the file probably lies under PATH_site // thus, it is not checked here if (\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($localFilePath, $this->absoluteBasePath) && $this->storage->getUid() > 0) { throw new \InvalidArgumentException('Cannot add a file that is already part of this storage.', 1314778269); } $relativeTargetPath = ltrim($targetFolder->getIdentifier(), '/'); $relativeTargetPath .= $fileName ? $fileName : basename($localFilePath); $targetPath = $this->absoluteBasePath . $relativeTargetPath; if (is_uploaded_file($localFilePath)) { $moveResult = move_uploaded_file($localFilePath, $targetPath); } else { $moveResult = rename($localFilePath, $targetPath); } if ($moveResult !== TRUE) { throw new \RuntimeException('Moving file ' . $localFilePath . ' to ' . $targetPath . ' failed.', 1314803096); } clearstatcache(); // Change the permissions of the file \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($targetPath); $fileInfo = $this->getFileInfoByIdentifier($relativeTargetPath); if ($updateFileObject) { $updateFileObject->updateProperties($fileInfo); return $updateFileObject; } else { $fileObject = $this->getFileObject($fileInfo); return $fileObject; } }
/** * Saves data in a cache file. * * @param string $entryIdentifier An identifier for this specific cache entry * @param string $data The data to be stored * @param array $tags Tags to associate with this cache entry * @param int $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited lifetime. * @return void * @throws \RuntimeException * @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set. * @throws \TYPO3\CMS\Core\Cache\Exception if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set. * @throws \InvalidArgumentException * @api */ public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) { if (!is_string($data)) { throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1204481674); } if ($entryIdentifier !== basename($entryIdentifier)) { throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1282073032); } if ($entryIdentifier === '') { throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1298114280); } if ($this->frozen === TRUE) { throw new \RuntimeException(sprintf('Cannot add or modify cache entry because the backend of cache "%s" is frozen.', $this->cacheIdentifier), 1323344192); } $this->remove($entryIdentifier); $temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid('', TRUE) . '.temp'; $lifetime = $lifetime === NULL ? $this->defaultLifetime : $lifetime; $expiryTime = $lifetime === 0 ? 0 : $GLOBALS['EXEC_TIME'] + $lifetime; $metaData = str_pad($expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad(strlen($data), self::DATASIZE_DIGITS); $result = file_put_contents($temporaryCacheEntryPathAndFilename, $data . $metaData); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename); if ($result === FALSE) { throw new \TYPO3\CMS\Core\Cache\Exception('The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.', 1204026251); } $i = 0; $cacheEntryPathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; while (($result = rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename)) === FALSE && $i < 5) { $i++; } if ($result === FALSE) { throw new \TYPO3\CMS\Core\Cache\Exception('The cache file "' . $cacheEntryPathAndFilename . '" could not be written.', 1222361632); } if ($this->cacheEntryFileExtension === '.php') { GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive($cacheEntryPathAndFilename); } }
/** * Moves uploaded files from temporary upload folder to a specified new folder. * This enables you to move the files from a successful submission to another folder and clean the files in temporary upload folder from time to time. * * TypoScript example: * * 1. Set the temporary upload folder * <code> * plugin.Tx_Formhandler.settings.files.tmpUploadFolder = uploads/formhandler/tmp * </code> * * 2. Set the folder to move the files to after submission * <code> * plugin.Tx_Formhandler.settings.finishers.1.class = Tx_Formhandler_Finisher_StoreUploadedFiles * plugin.Tx_Formhandler.settings.finishers.1.config.finishedUploadFolder = uploads/formhandler/finishedFiles/ * plugin.Tx_Formhandler.settings.finishers.1.config.renameScheme = [filename]_[md5]_[time] * </code> * * @return void */ protected function moveUploadedFiles() { $sessionFiles = $this->globals->getSession()->get('files'); if (is_array($sessionFiles) && !empty($sessionFiles)) { foreach ($sessionFiles as $field => $files) { $this->gp[$field] = array(); $uploadPath = $this->getNewFolderPath($field); if (strlen($uploadPath) > 0) { foreach ($files as $key => $file) { if ($file['uploaded_path'] != $uploadPath) { $newFilename = $this->getNewFilename($file['uploaded_name']); $filename = substr($newFilename, 0, strrpos($newFilename, '.')); $ext = substr($newFilename, strrpos($newFilename, '.')); $suffix = 1; //rename if exists while (file_exists($uploadPath . $newFilename)) { $newFilename = $filename . '_' . $suffix . $ext; $suffix++; } $this->utilityFuncs->debugMessage('copy_file', array($file['uploaded_path'] . $file['uploaded_name'], $uploadPath . $newFilename)); copy($file['uploaded_path'] . $file['uploaded_name'], $uploadPath . $newFilename); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($uploadPath . $newFilename); unlink($file['uploaded_path'] . $file['uploaded_name']); $newFolder = str_replace($this->utilityFuncs->getDocumentRoot(), '', $uploadPath); $sessionFiles[$field][$key]['uploaded_path'] = $uploadPath; $sessionFiles[$field][$key]['uploaded_name'] = $newFilename; $sessionFiles[$field][$key]['uploaded_folder'] = $newFolder; $sessionFiles[$field][$key]['uploaded_url'] = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $newFolder . $newFilename; if (!is_array($this->gp[$field])) { $this->gp[$field] = array(); } array_push($this->gp[$field], $newFilename); } else { array_push($this->gp[$field], $file['uploaded_name']); } } } } $this->globals->getSession()->set('files', $sessionFiles); } }
/** * Outputs the mail to a text file according to RFC 4155. * * @param Swift_Mime_Message $message The message to send * @param string[] &$failedRecipients To collect failures by-reference, nothing will fail in our debugging case * @return int * @throws \RuntimeException */ public function send(\Swift_Mime_Message $message, &$failedRecipients = NULL) { $message->generateId(); // Create a mbox-like header $mboxFrom = $this->getReversePath($message); $mboxDate = strftime('%c', $message->getDate()); $messageStr = sprintf('From %s %s', $mboxFrom, $mboxDate) . LF; // Add the complete mail inclusive headers $messageStr .= $message->toString(); $messageStr .= LF . LF; $lockObject = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Locking\\Locker', $this->debugFile, $GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode']); /** @var \TYPO3\CMS\Core\Locking\Locker $lockObject */ $lockObject->acquire(); // Write the mbox file $file = @fopen($this->debugFile, 'a'); if (!$file) { $lockObject->release(); throw new \RuntimeException(sprintf('Could not write to file "%s" when sending an email to debug transport', $this->debugFile), 1291064151); } @fwrite($file, $messageStr); @fclose($file); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($this->debugFile); $lockObject->release(); // Return every receipient as "delivered" $count = count((array) $message->getTo()) + count((array) $message->getCc()) + count((array) $message->getBcc()); return $count; }
/** * Saves data in a cache file. * * @param string $entryIdentifier An identifier for this specific cache entry * @param string $data The data to be stored * @param array $tags Tags to associate with this cache entry * @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited lifetime. * @return void * @throws \TYPO3\CMS\Core\Cache\Exception if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set. * @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException if the data to bes stored is not a string. * @throws \InvalidArgumentException * @api */ public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) { if (!is_string($data)) { throw new \t3lib_cache_Exception_InvalidData('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1334756734); } if ($entryIdentifier !== basename($entryIdentifier)) { throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1334756735); } if ($entryIdentifier === '') { throw new \InvalidArgumentException('The specified entry identifier must not be empty.', 1334756736); } $temporaryCacheEntryPathAndFilename = $this->cacheDirectory . uniqid() . '.temp'; $result = file_put_contents($temporaryCacheEntryPathAndFilename, $data); \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($temporaryCacheEntryPathAndFilename); if ($result === FALSE) { throw new \TYPO3\CMS\Core\Cache\Exception('The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.', 1334756737); } $cacheEntryPathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename); }
/** * Try to acquire an exclusive lock * * @param int $mode LOCK_CAPABILITY_EXCLUSIVE or LOCK_CAPABILITY_SHARED or self::LOCK_CAPABILITY_NOBLOCK * @return bool Returns TRUE if the lock was acquired successfully * @throws LockAcquireException if the lock could not be acquired * @throws LockAcquireWouldBlockException if the acquire would have blocked and NOBLOCK was set */ public function acquire($mode = self::LOCK_CAPABILITY_EXCLUSIVE) { if ($this->isAcquired) { return TRUE; } $this->filePointer = fopen($this->filePath, 'c'); if ($this->filePointer === FALSE) { throw new LockAcquireException('Lock file could not be opened', 1294586099); } GeneralUtility::fixPermissions($this->filePath); $operation = $mode & self::LOCK_CAPABILITY_EXCLUSIVE ? LOCK_EX : LOCK_SH; if ($mode & self::LOCK_CAPABILITY_NOBLOCK) { $operation |= LOCK_NB; } $wouldBlock = 0; $this->isAcquired = flock($this->filePointer, $operation, $wouldBlock); if ($mode & self::LOCK_CAPABILITY_NOBLOCK && !$this->isAcquired && $wouldBlock) { throw new LockAcquireWouldBlockException('Failed to acquire lock because the request would block.', 1428700748); } return $this->isAcquired; }
/** * Outputs the mail to a text file according to RFC 4155. * * @param \Swift_Mime_Message $message The message to send * @param string[] &$failedRecipients To collect failures by-reference, nothing will fail in our debugging case * @return int * @throws \RuntimeException */ public function send(\Swift_Mime_Message $message, &$failedRecipients = null) { $message->generateId(); // Create a mbox-like header $mboxFrom = $this->getReversePath($message); $mboxDate = strftime('%c', $message->getDate()); $messageStr = sprintf('From %s %s', $mboxFrom, $mboxDate) . LF; // Add the complete mail inclusive headers $messageStr .= $message->toString(); $messageStr .= LF . LF; $lockFactory = GeneralUtility::makeInstance(LockFactory::class); $lockObject = $lockFactory->createLocker('mbox'); $lockObject->acquire(); // Write the mbox file $file = @fopen($this->debugFile, 'a'); if (!$file) { $lockObject->release(); throw new \RuntimeException(sprintf('Could not write to file "%s" when sending an email to debug transport', $this->debugFile), 1291064151); } @fwrite($file, $messageStr); @fclose($file); GeneralUtility::fixPermissions($this->debugFile); $lockObject->release(); // Return every recipient as "delivered" $count = count((array) $message->getTo()) + count((array) $message->getCc()) + count((array) $message->getBcc()); return $count; }
/** * @test */ public function copyFolderWithinStorageCopiesFileInSingleSubFolderToNewFolderName() { list($basePath, $fixture) = $this->prepareRealTestEnvironment(); GeneralUtility::mkdir_deep($basePath, '/sourceFolder/subFolder'); GeneralUtility::mkdir_deep($basePath, '/targetFolder'); file_put_contents($basePath . '/sourceFolder/subFolder/file', uniqid()); GeneralUtility::fixPermissions($basePath . '/sourceFolder/subFolder/file'); $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName'); $this->assertTrue(is_file($basePath . '/targetFolder/newFolderName/subFolder/file')); }
/** * Removes all expired path cache entries * * @return void */ protected function removeExpiredPathCacheEntries() { $lastCleanUpFileName = PATH_site . 'typo3temp/realurl_last_clean_up'; $lastCleanUpTime = @filemtime($lastCleanUpFileName); if ($lastCleanUpTime === false || time() - $lastCleanUpTime >= 6 * 60 * 60) { touch($lastCleanUpFileName); GeneralUtility::fixPermissions($lastCleanUpFileName); /** @noinspection PhpUndefinedMethodInspection */ $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_realurl_pathcache', 'expire>0 AND expire<' . $this->makeExpirationTime()); } }
/** * @test */ public function fixPermissionsSetsPermissionsWithRelativeFileReference() { if (TYPO3_OS == 'WIN') { $this->markTestSkipped('fixPermissions() tests not available on Windows'); } $filename = 'typo3temp/' . uniqid('test_'); Utility\GeneralUtility::writeFileToTypo3tempDir(PATH_site . $filename, '42'); chmod(PATH_site . $filename, 482); // Set target permissions and run method $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660'; $fixPermissionsResult = Utility\GeneralUtility::fixPermissions($filename); // Get actual permissions and clean up clearstatcache(); $resultFilePermissions = substr(decoct(fileperms(PATH_site . $filename)), 2); unlink(PATH_site . $filename); // Test if everything was ok $this->assertTrue($fixPermissionsResult); $this->assertEquals($resultFilePermissions, '0660'); }
/** * Sets the file system mode and group ownership of a file or a folder. * * @param string $path Path of file or folder, must not be escaped. Path can be absolute or relative * @param bool $recursive If set, also fixes permissions of files and folders in the folder (if $path is a folder) * @return mixed TRUE on success, FALSE on error, always TRUE on Windows OS */ public function fixPermissions($path, $recursive = FALSE) { return GeneralUtility::fixPermissions($path, $recursive); }