/**
  * Constructor
  *
  * @param \TYPO3\Flow\Package\PackageManager $packageManager the package manager which knows this package
  * @param string $packageKey Key of this package
  * @param string $packagePath Absolute path to the location of the package's composer manifest
  * @param string $classesPath Path the classes of the package are in, relative to $packagePath. Optional, read from Composer manifest if not set.
  * @param string $manifestPath Path the composer manifest of the package, relative to $packagePath. Optional, defaults to ''.
  * @throws \TYPO3\Flow\Package\Exception\InvalidPackageKeyException if an invalid package key was passed
  * @throws \TYPO3\Flow\Package\Exception\InvalidPackagePathException if an invalid package path was passed
  * @throws \TYPO3\Flow\Package\Exception\InvalidPackageManifestException if no composer manifest file could be found
  */
 public function __construct(\TYPO3\Flow\Package\PackageManager $packageManager, $packageKey, $packagePath, $classesPath = NULL, $manifestPath = '')
 {
     if (!\TYPO3\CMS\Core\Package\PackageManager::isPackageKeyValid($packageKey)) {
         throw new \TYPO3\Flow\Package\Exception\InvalidPackageKeyException('"' . $packageKey . '" is not a valid package key.', 1217959511);
     }
     if (!(@is_dir($packagePath) || \TYPO3\Flow\Utility\Files::is_link($packagePath) && is_dir(\TYPO3\Flow\Utility\Files::getNormalizedPath($packagePath)))) {
         throw new \TYPO3\Flow\Package\Exception\InvalidPackagePathException(sprintf('Tried to instantiate a package object for package "%s" with a non-existing package path "%s". Either the package does not exist anymore, or the code creating this object contains an error.', $packageKey, $packagePath), 1166631890);
     }
     if (substr($packagePath, -1, 1) !== '/') {
         throw new \TYPO3\Flow\Package\Exception\InvalidPackagePathException(sprintf('The package path "%s" provided for package "%s" has no trailing forward slash.', $packagePath, $packageKey), 1166633722);
     }
     if ($classesPath[1] === '/') {
         throw new \TYPO3\Flow\Package\Exception\InvalidPackagePathException(sprintf('The package classes path provided for package "%s" has a leading forward slash.', $packageKey), 1334841321);
     }
     if (!@file_exists($packagePath . $manifestPath . 'ext_emconf.php')) {
         throw new \TYPO3\Flow\Package\Exception\InvalidPackageManifestException(sprintf('No ext_emconf file found for package "%s". Please create one at "%sext_emconf.php".', $packageKey, $manifestPath), 1360403545);
     }
     $this->packageManager = $packageManager;
     $this->manifestPath = $manifestPath;
     $this->packageKey = $packageKey;
     $this->packagePath = \TYPO3\Flow\Utility\Files::getNormalizedPath($packagePath);
     $this->classesPath = \TYPO3\Flow\Utility\Files::getNormalizedPath(\TYPO3\Flow\Utility\Files::concatenatePaths(array($this->packagePath, self::DIRECTORY_CLASSES)));
     try {
         $this->getComposerManifest();
     } catch (\TYPO3\Flow\Package\Exception\MissingPackageManifestException $exception) {
         $this->getExtensionEmconf($packageKey, $this->packagePath);
     }
     $this->loadFlagsFromComposerManifest();
     if ($this->objectManagementEnabled === NULL) {
         $this->objectManagementEnabled = FALSE;
     }
 }
 /**
  * Because mirrorFile() uses touch() we can't use vfs to mock the file system.
  *
  * @test
  */
 public function mirrorFileSymLinksTheGivenFileIfTheSettingSaysSo()
 {
     $sourcePathAndFilename = tempnam('FlowFileSystemPublishingTargetTestSource', '');
     $targetPathAndFilename = tempnam('FlowFileSystemPublishingTargetTestTarget', '');
     file_put_contents($sourcePathAndFilename, 'some data');
     touch($sourcePathAndFilename, time() - 5);
     $settings = array('resource' => array('publishing' => array('fileSystem' => array('mirrorMode' => 'link'))));
     $publishingTarget = $this->getAccessibleMock('TYPO3\\Flow\\Resource\\Publishing\\FileSystemPublishingTarget', array('dummy'));
     $publishingTarget->_set('settings', $settings);
     $publishingTarget->_call('mirrorFile', $sourcePathAndFilename, $targetPathAndFilename, TRUE);
     $this->assertFileEquals($sourcePathAndFilename, $targetPathAndFilename);
     $this->assertTrue(Files::is_link($targetPathAndFilename));
     unlink($sourcePathAndFilename);
     unlink($targetPathAndFilename);
 }
 /**
  * @test
  */
 public function is_linkReturnsFalseForStreamWrapperPaths()
 {
     $targetPath = 'vfs://Foo/Bar';
     if (!is_dir($targetPath)) {
         Files::createDirectoryRecursively($targetPath);
     }
     $this->assertFalse(Files::is_link($targetPath));
 }
 /**
  * Constructor
  *
  * @param \TYPO3\Flow\Package\PackageManager $packageManager the package manager which knows this package
  * @param string $packageKey Key of this package
  * @param string $packagePath Absolute path to the location of the package's composer manifest
  * @param string $classesPath Path the classes of the package are in, relative to $packagePath. Optional, PSR-0/PSR-4 mappings of the composer manifest overrule this argument, if present
  * @param string $manifestPath Path the composer manifest of the package, relative to $packagePath. Optional, defaults to ''
  * @throws \TYPO3\Flow\Package\Exception\InvalidPackageKeyException if an invalid package key was passed
  * @throws \TYPO3\Flow\Package\Exception\InvalidPackagePathException if an invalid package path was passed
  * @throws \TYPO3\Flow\Package\Exception\InvalidPackageManifestException if no composer manifest file could be found
  */
 public function __construct(PackageManager $packageManager, $packageKey, $packagePath, $classesPath = null, $manifestPath = '')
 {
     if (preg_match(self::PATTERN_MATCH_PACKAGEKEY, $packageKey) !== 1) {
         throw new Exception\InvalidPackageKeyException('"' . $packageKey . '" is not a valid package key.', 1217959510);
     }
     if (!(is_dir($packagePath) || Files::is_link($packagePath) && is_dir(Files::getNormalizedPath($packagePath)))) {
         throw new Exception\InvalidPackagePathException(sprintf('Tried to instantiate a package object for package "%s" with a non-existing package path "%s". Either the package does not exist anymore, or the code creating this object contains an error.', $packageKey, $packagePath), 1166631889);
     }
     if (substr($packagePath, -1, 1) !== '/') {
         throw new Exception\InvalidPackagePathException(sprintf('The package path "%s" provided for package "%s" has no trailing forward slash.', $packagePath, $packageKey), 1166633720);
     }
     if (substr($classesPath, 0, 1) === '/') {
         throw new Exception\InvalidPackagePathException(sprintf('The package classes path provided for package "%s" has a leading forward slash.', $packageKey), 1334841320);
     }
     if (!file_exists($packagePath . $manifestPath . 'composer.json')) {
         throw new Exception\InvalidPackageManifestException(sprintf('No composer manifest file found for package "%s". Please create one at "%scomposer.json".', $packageKey, $packagePath . $manifestPath), 1349776393);
     }
     $this->packageManager = $packageManager;
     $this->manifestPath = $manifestPath;
     $this->packageKey = $packageKey;
     $this->packagePath = Files::getNormalizedPath($packagePath);
     $autoloadType = $this->getAutoloadType();
     if ($autoloadType === self::AUTOLOADER_TYPE_PSR0 || $autoloadType === self::AUTOLOADER_TYPE_PSR4) {
         $autoloadPath = $this->getComposerManifest('autoload')->{$autoloadType}->{$this->getNamespace()};
         if (is_array($autoloadPath)) {
             $autoloadPath = $autoloadPath[0];
         }
         $this->classesPath = Files::getNormalizedPath($this->packagePath . $autoloadPath);
     } else {
         $this->classesPath = Files::getNormalizedPath($this->packagePath . $classesPath);
     }
 }
 /**
  * Depending on the settings of this publishing target copies the specified file
  * or creates a symbolic link.
  *
  * @param string $sourcePathAndFilename
  * @param string $targetPathAndFilename
  * @param boolean $createDirectoriesIfNecessary
  * @return void
  * @throws \TYPO3\Flow\Resource\Exception
  */
 protected function mirrorFile($sourcePathAndFilename, $targetPathAndFilename, $createDirectoriesIfNecessary = FALSE)
 {
     if ($createDirectoriesIfNecessary === TRUE) {
         \TYPO3\Flow\Utility\Files::createDirectoryRecursively(dirname($targetPathAndFilename));
     }
     switch ($this->settings['resource']['publishing']['fileSystem']['mirrorMode']) {
         case 'copy':
             copy($sourcePathAndFilename, $targetPathAndFilename);
             touch($targetPathAndFilename, filemtime($sourcePathAndFilename));
             break;
         case 'link':
             if (file_exists($targetPathAndFilename)) {
                 if (\TYPO3\Flow\Utility\Files::is_link($targetPathAndFilename) && $this->realpath($targetPathAndFilename) === $this->realpath($sourcePathAndFilename)) {
                     break;
                 }
                 unlink($targetPathAndFilename);
                 symlink($sourcePathAndFilename, $targetPathAndFilename);
             } else {
                 symlink($sourcePathAndFilename, $targetPathAndFilename);
             }
             break;
         default:
             throw new \TYPO3\Flow\Resource\Exception('An invalid mirror mode (' . $this->settings['resource']['publishing']['fileSystem']['mirrorMode'] . ') has been configured.', 1256133400);
     }
     if (!file_exists($targetPathAndFilename)) {
         throw new \TYPO3\Flow\Resource\Exception('The resource "' . $sourcePathAndFilename . '" could not be mirrored.', 1207255453);
     }
 }
 /**
  * Publishes the specified directory to this target, with the given relative path.
  *
  * @param string $sourcePath Absolute path to the source directory
  * @param string $relativeTargetPathAndFilename relative path and filename in the target directory
  * @throws Exception
  * @return void
  */
 protected function publishDirectory($sourcePath, $relativeTargetPathAndFilename)
 {
     $targetPathAndFilename = $this->path . $relativeTargetPathAndFilename;
     if (@stat($sourcePath) === false) {
         throw new Exception(sprintf('Could not publish directory "%s" into resource publishing target "%s" because the source is not accessible (file stat failed).', $sourcePath, $this->name), 1416244512);
     }
     if (!file_exists(dirname($targetPathAndFilename))) {
         Files::createDirectoryRecursively(dirname($targetPathAndFilename));
     }
     try {
         if (Files::is_link($targetPathAndFilename)) {
             Files::unlink($targetPathAndFilename);
         }
         $temporaryTargetPathAndFilename = uniqid($targetPathAndFilename . '.') . '.tmp';
         symlink($sourcePath, $temporaryTargetPathAndFilename);
         $result = rename($temporaryTargetPathAndFilename, $targetPathAndFilename);
     } catch (\Exception $exception) {
         $result = false;
     }
     if ($result === false) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the source directory could not be symlinked at target location.', $sourcePath, $this->name), 1416244515, isset($exception) ? $exception : null);
     }
     $this->systemLogger->log(sprintf('FileSystemSymlinkTarget: Published directory. (target: %s, file: %s)', $this->name, $relativeTargetPathAndFilename), LOG_DEBUG);
 }
Ejemplo n.º 7
0
 /**
  * Check write permissions for folders used for writing files
  *
  * @return mixed
  */
 protected function checkFilePermissions()
 {
     foreach ($this->requiredWritableFolders as $folder) {
         $folderPath = FLOW_PATH_ROOT . $folder;
         if (!is_dir($folderPath) && !\TYPO3\Flow\Utility\Files::is_link($folderPath)) {
             try {
                 \TYPO3\Flow\Utility\Files::createDirectoryRecursively($folderPath);
             } catch (\TYPO3\Flow\Utility\Exception $exception) {
                 return new Error('Unable to create folder "%s". Check your file permissions (did you use flow:core:setfilepermissions?).', 1330363887, array($folderPath));
             }
         }
         if (!is_writable($folderPath)) {
             return new Error('The folder "%s" is not writable. Check your file permissions (did you use flow:core:setfilepermissions?)', 1330372964, array($folderPath));
         }
     }
     return NULL;
 }
 /**
  * Returns the publish path and filename to be used to publish the specified persistent resource
  *
  * @Flow\Around("method(TYPO3\Flow\Resource\Publishing\FileSystemPublishingTarget->buildPersistentResourcePublishPathAndFilename()) && setting(TYPO3.Flow.security.enable)")
  * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current join point
  * @return mixed Result of the target method
  */
 public function rewritePersistentResourcePublishPathAndFilenameForPrivateResources(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint)
 {
     $resource = $joinPoint->getMethodArgument('resource');
     /** @var $configuration \TYPO3\Flow\Security\Authorization\Resource\SecurityPublishingConfiguration */
     $configuration = $resource->getPublishingConfiguration();
     $returnFilename = $joinPoint->getMethodArgument('returnFilename');
     if ($configuration === NULL || $configuration instanceof \TYPO3\Flow\Security\Authorization\Resource\SecurityPublishingConfiguration === FALSE) {
         return $joinPoint->getAdviceChain()->proceed($joinPoint);
     }
     $publishingPath = FALSE;
     $allowedRoles = $configuration->getAllowedRoles();
     if (count(array_intersect($allowedRoles, $this->securityContext->getRoles())) > 0) {
         $publishingPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($joinPoint->getProxy()->getResourcesPublishingPath(), 'Persistent/', $this->session->getID())) . '/';
         $filename = $resource->getResourcePointer()->getHash() . '.' . $resource->getFileExtension();
         \TYPO3\Flow\Utility\Files::createDirectoryRecursively($publishingPath);
         $this->accessRestrictionPublisher->publishAccessRestrictionsForPath($publishingPath);
         if ($this->settings['resource']['publishing']['fileSystem']['mirrorMode'] === 'link') {
             foreach ($allowedRoles as $role) {
                 $roleDirectory = \TYPO3\Flow\Utility\Files::concatenatePaths(array($this->environment->getPathToTemporaryDirectory(), 'PrivateResourcePublishing/', $role));
                 \TYPO3\Flow\Utility\Files::createDirectoryRecursively($roleDirectory);
                 if (file_exists($publishingPath . $role)) {
                     if (\TYPO3\Flow\Utility\Files::is_link(\TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role))) && realpath(\TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role))) === $roleDirectory) {
                         continue;
                     }
                     unlink($publishingPath . $role);
                     symlink($roleDirectory, \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role)));
                 } else {
                     symlink($roleDirectory, \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role)));
                 }
             }
             $publishingPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $allowedRoles[0])) . '/';
         }
         if ($returnFilename === TRUE) {
             $publishingPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $filename));
         }
     }
     return $publishingPath;
 }