/**
  * Publishes the given source stream to this target, with the given relative path.
  *
  * @param resource $sourceStream Stream of the source to publish
  * @param string $relativeTargetPathAndFilename relative path and filename in the target directory
  * @throws Exception
  * @throws \TYPO3\Flow\Utility\Exception
  */
 protected function publishFile($sourceStream, $relativeTargetPathAndFilename)
 {
     $pathInfo = UnicodeFunctions::pathinfo($relativeTargetPathAndFilename);
     if (isset($pathInfo['extension']) && array_key_exists(strtolower($pathInfo['extension']), $this->extensionBlacklist) && $this->extensionBlacklist[strtolower($pathInfo['extension'])] === true) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the filename extension "%s" is blacklisted.', $sourceStream, $this->name, strtolower($pathInfo['extension'])), 1447152230);
     }
     $streamMetaData = stream_get_meta_data($sourceStream);
     if ($streamMetaData['wrapper_type'] !== 'plainfile' || $streamMetaData['stream_type'] !== 'STDIO') {
         throw new Exception(sprintf('Could not publish stream "%s" into resource publishing target "%s" because the source is not a local file.', $streamMetaData['uri'], $this->name), 1416242392);
     }
     $sourcePathAndFilename = $streamMetaData['uri'];
     $targetPathAndFilename = $this->path . $relativeTargetPathAndFilename;
     if (@stat($sourcePathAndFilename) === false) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the source file is not accessible (file stat failed).', $sourcePathAndFilename, $this->name), 1415716366);
     }
     if (!file_exists(dirname($targetPathAndFilename))) {
         Files::createDirectoryRecursively(dirname($targetPathAndFilename));
     }
     try {
         if (Files::is_link($targetPathAndFilename)) {
             Files::unlink($targetPathAndFilename);
         }
         $temporaryTargetPathAndFilename = uniqid($targetPathAndFilename . '.') . '.tmp';
         symlink($sourcePathAndFilename, $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 file could not be symlinked at target location.', $sourcePathAndFilename, $this->name), 1415716368, isset($exception) ? $exception : null);
     }
     $this->systemLogger->log(sprintf('FileSystemSymlinkTarget: Published file. (target: %s, file: %s)', $this->name, $relativeTargetPathAndFilename), LOG_DEBUG);
 }
 /**
  * Checks if the given value is a valid string (or can be cast to a string
  * if an object is given) and its length is between minimum and maximum
  * specified in the validation options.
  *
  * @param mixed $value The value that should be validated
  * @return void
  * @throws \TYPO3\Flow\Validation\Exception\InvalidValidationOptionsException
  * @api
  */
 protected function isValid($value)
 {
     if ($this->options['maximum'] < $this->options['minimum']) {
         throw new \TYPO3\Flow\Validation\Exception\InvalidValidationOptionsException('The \'maximum\' is less than the \'minimum\' in the StringLengthValidator.', 1238107096);
     }
     if (is_object($value)) {
         if (!method_exists($value, '__toString')) {
             $this->addError('The given object could not be converted to a string.', 1238110957);
             return;
         }
     } elseif (!is_string($value)) {
         $this->addError('The given value was not a valid string.', 1269883975);
         return;
     }
     $stringLength = \TYPO3\Flow\Utility\Unicode\Functions::strlen($value);
     $isValid = TRUE;
     if ($stringLength < $this->options['minimum']) {
         $isValid = FALSE;
     }
     if ($stringLength > $this->options['maximum']) {
         $isValid = FALSE;
     }
     if ($isValid === FALSE) {
         if ($this->options['minimum'] > 0 && $this->options['maximum'] < PHP_INT_MAX) {
             $this->addError('The length of this text must be between %1$d and %2$d characters.', 1238108067, array($this->options['minimum'], $this->options['maximum']));
         } elseif ($this->options['minimum'] > 0) {
             $this->addError('This field must contain at least %1$d characters.', 1238108068, array($this->options['minimum']));
         } else {
             $this->addError('This text may not exceed %1$d characters.', 1238108069, array($this->options['maximum']));
         }
     }
 }
 /**
  * Returns a random string with alpha-numeric characters.
  *
  * @param integer $count Number of characters to generate
  * @param string $characters Allowed characters, defaults to alpha-numeric (a-zA-Z0-9)
  * @return string A random string
  */
 public static function generateRandomString($count, $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
 {
     $characterCount = \TYPO3\Flow\Utility\Unicode\Functions::strlen($characters);
     $string = '';
     for ($i = 0; $i < $count; $i++) {
         $string .= \TYPO3\Flow\Utility\Unicode\Functions::substr($characters, random_int(0, $characterCount - 1), 1);
     }
     return $string;
 }
 /**
  * Render a node label
  *
  * @param NodeInterface $node
  * @param boolean $crop This argument is deprecated as of Neos 1.2 and will be removed. Don't rely on this behavior and crop labels in the view.
  * @return string
  */
 public function getLabel(NodeInterface $node, $crop = true)
 {
     $label = \TYPO3\Eel\Utility::evaluateEelExpression($this->getExpression(), $this->eelEvaluator, array('node' => $node), $this->defaultContextConfiguration);
     if ($crop === false) {
         return $label;
     }
     $croppedLabel = \TYPO3\Flow\Utility\Unicode\Functions::substr($label, 0, 30);
     return $croppedLabel . (strlen($croppedLabel) < strlen($label) ? ' …' : '');
 }
 /**
  * @param array $arguments
  * @param callable $renderChildrenClosure
  * @param \TYPO3\Fluid\Core\Rendering\RenderingContextInterface $renderingContext
  * @return string
  */
 public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
 {
     $value = $arguments['value'];
     if ($value === null) {
         $value = $renderChildrenClosure();
     }
     if (UnicodeUtilityFunctions::strlen($value) > $arguments['maxCharacters']) {
         return UnicodeUtilityFunctions::substr($value, 0, $arguments['maxCharacters']) . $arguments['append'];
     }
     return $value;
 }
 /**
  * @param string $key
  * @param string $value
  * @return void
  * @throws Exception
  */
 public function addTag($key, $value)
 {
     $key = trim($key);
     if ($key === '') {
         throw new Exception('Tag Key must not be empty', 1448264366);
     }
     $value = trim($value);
     if ($value === '') {
         throw new Exception('Tag Value must not be empty', 1448264367);
     }
     $tag = Functions::ucfirst($key) . 'DynamicTag_' . $value;
     $this->tags[$tag] = true;
 }
 /**
  * Render a node label
  *
  * @param \TYPO3\TYPO3CR\Domain\Model\AbstractNodeData $nodeData
  * @param boolean $crop This argument is deprecated as of Neos 1.2 and will be removed. Don't rely on this behavior and crop labels in the view.
  * @return string
  */
 public function getLabel(AbstractNodeData $nodeData, $crop = true)
 {
     if ($nodeData->hasProperty('title') === true && $nodeData->getProperty('title') !== '') {
         $label = strip_tags($nodeData->getProperty('title'));
     } elseif ($nodeData->hasProperty('text') === true && $nodeData->getProperty('text') !== '') {
         $label = strip_tags($nodeData->getProperty('text'));
     } else {
         $label = ($nodeData->getNodeType()->getLabel() ?: $nodeData->getNodeType()->getName()) . ' (' . $nodeData->getName() . ')';
     }
     if ($crop === false) {
         return $label;
     }
     $croppedLabel = \TYPO3\Flow\Utility\Unicode\Functions::substr($label, 0, 30);
     return $croppedLabel . (strlen($croppedLabel) < strlen($label) ? ' …' : '');
 }
 /**
  * Render a node label
  *
  * @param \TYPO3\TYPO3CR\Domain\Model\AbstractNodeData $nodeData
  * @param boolean $crop
  * @return string
  */
 public function getLabel(AbstractNodeData $nodeData, $crop = TRUE)
 {
     if ($nodeData->hasProperty('title') === TRUE && $nodeData->getProperty('title') !== '') {
         $label = strip_tags($nodeData->getProperty('title'));
     } elseif ($nodeData->hasProperty('text') === TRUE && $nodeData->getProperty('text') !== '') {
         $label = strip_tags($nodeData->getProperty('text'));
     } else {
         $label = ($nodeData->getNodeType()->getLabel() ?: $nodeData->getNodeType()->getName()) . ' (' . $nodeData->getName() . ')';
     }
     if ($crop === FALSE) {
         return $label;
     }
     $croppedLabel = \TYPO3\Flow\Utility\Unicode\Functions::substr($label, 0, NodeInterface::LABEL_MAXIMUM_CHARACTERS);
     return $croppedLabel . (strlen($croppedLabel) < strlen($label) ? ' …' : '');
 }
 /**
  * Return all Objects stored in this storage filtered by the given directory / filename pattern
  *
  * @param string $pattern A glob compatible directory / filename pattern
  * @param callable $callback Function called after each object
  * @return \Generator<StorageObject>
  */
 public function getObjectsByPathPattern($pattern, callable $callback = null)
 {
     $directories = [];
     if (strpos($pattern, '/') !== false) {
         list($packageKeyPattern, $directoryPattern) = explode('/', $pattern, 2);
     } else {
         $packageKeyPattern = $pattern;
         $directoryPattern = '*';
     }
     // $packageKeyPattern can be used in a future implementation to filter by package key
     $packages = $this->packageManager->getActivePackages();
     foreach ($packages as $packageKey => $package) {
         /** @var PackageInterface $package */
         if ($directoryPattern === '*') {
             $directories[$packageKey][] = $package->getPackagePath();
         } else {
             $directories[$packageKey] = glob($package->getPackagePath() . $directoryPattern, GLOB_ONLYDIR);
         }
     }
     $iteration = 0;
     foreach ($directories as $packageKey => $packageDirectories) {
         foreach ($packageDirectories as $directoryPath) {
             foreach (Files::getRecursiveDirectoryGenerator($directoryPath) as $resourcePathAndFilename) {
                 $pathInfo = UnicodeFunctions::pathinfo($resourcePathAndFilename);
                 $object = new Object();
                 $object->setFilename($pathInfo['basename']);
                 $object->setSha1(sha1_file($resourcePathAndFilename));
                 $object->setMd5(md5_file($resourcePathAndFilename));
                 $object->setFileSize(filesize($resourcePathAndFilename));
                 if (isset($pathInfo['dirname'])) {
                     list(, $path) = explode('/', str_replace($packages[$packageKey]->getResourcesPath(), '', $pathInfo['dirname']), 2);
                     $object->setRelativePublicationPath($packageKey . '/' . $path . '/');
                 }
                 $object->setStream(function () use($resourcePathAndFilename) {
                     return fopen($resourcePathAndFilename, 'r');
                 });
                 (yield $object);
                 if (is_callable($callback)) {
                     call_user_func($callback, $iteration, $object);
                 }
                 $iteration++;
             }
         }
     }
 }
 /**
  * Constructs the URI object from a string
  *
  * @param string $uriString String representation of the URI
  * @throws \InvalidArgumentException
  * @api
  */
 public function __construct($uriString)
 {
     if (!is_string($uriString)) {
         throw new \InvalidArgumentException('The URI must be a valid string.', 1176550571);
     }
     $parseUrlException = null;
     try {
         $uriParts = \TYPO3\Flow\Utility\Unicode\Functions::parse_url($uriString);
     } catch (\TYPO3\Flow\Error\Exception $exception) {
         $parseUrlException = $exception;
     }
     if (is_array($uriParts)) {
         $this->scheme = isset($uriParts['scheme']) ? $uriParts['scheme'] : null;
         $this->username = isset($uriParts['user']) ? $uriParts['user'] : null;
         $this->password = isset($uriParts['pass']) ? $uriParts['pass'] : null;
         $this->host = isset($uriParts['host']) ? $uriParts['host'] : null;
         $this->port = isset($uriParts['port']) ? $uriParts['port'] : null;
         if ($this->port === null) {
             switch ($this->scheme) {
                 case 'http':
                     $this->port = 80;
                     break;
                 case 'https':
                     $this->port = 443;
                     break;
             }
         }
         $this->path = isset($uriParts['path']) ? $uriParts['path'] : null;
         if (isset($uriParts['query'])) {
             $this->setQuery($uriParts['query']);
         }
         $this->fragment = isset($uriParts['fragment']) ? $uriParts['fragment'] : null;
     } else {
         throw new \InvalidArgumentException('The given URI "' . $uriString . '" is not a valid one.', 1351594202, $parseUrlException);
     }
 }
Пример #11
0
 /**
  * Returns a like criterion used for matching objects against a query.
  * Matches if the property named $propertyName is like the $operand, using
  * standard SQL wildcards.
  *
  * @param string $propertyName The name of the property to compare against
  * @param string $operand The value to compare with
  * @param boolean $caseSensitive Whether the matching should be done case-sensitive
  * @return object
  * @throws \TYPO3\Flow\Persistence\Exception\InvalidQueryException if used on a non-string property
  * @api
  */
 public function like($propertyName, $operand, $caseSensitive = TRUE)
 {
     $aliasedPropertyName = $this->getPropertyNameWithAlias($propertyName);
     if ($caseSensitive === TRUE) {
         return $this->queryBuilder->expr()->like($aliasedPropertyName, $this->getParamNeedle($operand));
     }
     return $this->queryBuilder->expr()->like($this->queryBuilder->expr()->lower($aliasedPropertyName), $this->getParamNeedle(UnicodeFunctions::strtolower($operand)));
 }
 /**
  * @return string
  */
 protected function getNormalizedIdentifier()
 {
     return str_replace("\\", ".", Functions::strtolower($this->getIdentifier()));
 }
 /**
  * Evaluates the absolute path and filename of the resource file specified
  * by the given path.
  *
  * @param string $requestedPath
  * @param boolean $checkForExistence Whether a (non-hash) path should be checked for existence before being returned
  * @return mixed The full path and filename or FALSE if the file doesn't exist
  * @throws \InvalidArgumentException|Exception
  */
 protected function evaluateResourcePath($requestedPath, $checkForExistence = true)
 {
     if (substr($requestedPath, 0, strlen(self::SCHEME)) !== self::SCHEME) {
         throw new \InvalidArgumentException('The ' . __CLASS__ . ' only supports the \'' . self::SCHEME . '\' scheme.', 1256052544);
     }
     $uriParts = Functions::parse_url($requestedPath);
     if (!is_array($uriParts) || !isset($uriParts['host'])) {
         return false;
     }
     if (preg_match('/^[0-9a-f]{40}$/i', $uriParts['host']) === 1) {
         $resource = $this->resourceManager->getResourceBySha1($uriParts['host']);
         return $this->resourceManager->getStreamByResource($resource);
     }
     if (!$this->packageManager->isPackageAvailable($uriParts['host'])) {
         throw new Exception(sprintf('Invalid resource URI "%s": Package "%s" is not available.', $requestedPath, $uriParts['host']), 1309269952);
     }
     $package = $this->packageManager->getPackage($uriParts['host']);
     $resourceUri = Files::concatenatePaths(array($package->getResourcesPath(), $uriParts['path']));
     if ($checkForExistence === false || file_exists($resourceUri)) {
         return $resourceUri;
     }
     return false;
 }
 /**
  * Find nodes by a value in properties
  *
  * This method is internal and will be replaced with better search capabilities.
  *
  * @param string $term Search term
  * @param string $nodeTypeFilter Node type filter
  * @param Workspace $workspace
  * @param array $dimensions
  * @param string $pathStartingPoint
  * @return array<\TYPO3\TYPO3CR\Domain\Model\NodeData>
  */
 public function findByProperties($term, $nodeTypeFilter, $workspace, $dimensions, $pathStartingPoint = null)
 {
     $pathStartingPoint = strtolower($pathStartingPoint);
     if (strlen($term) === 0) {
         throw new \InvalidArgumentException('"term" cannot be empty: provide a term to search for.', 1421329285);
     }
     $workspaces = array();
     while ($workspace !== null) {
         $workspaces[] = $workspace;
         $workspace = $workspace->getBaseWorkspace();
     }
     $queryBuilder = $this->createQueryBuilder($workspaces);
     $this->addDimensionJoinConstraintsToQueryBuilder($queryBuilder, $dimensions);
     $this->addNodeTypeFilterConstraintsToQueryBuilder($queryBuilder, $nodeTypeFilter);
     // Convert to lowercase, then to json, and then trim quotes from json to have valid JSON escaping.
     $likeParameter = '%' . trim(json_encode(UnicodeFunctions::strtolower($term), JSON_UNESCAPED_UNICODE), '"') . '%';
     $queryBuilder->andWhere("LOWER(CONCAT('', n.properties)) LIKE :term")->setParameter('term', $likeParameter);
     if (strlen($pathStartingPoint) > 0) {
         $pathConstraint = $queryBuilder->expr()->orx()->add($queryBuilder->expr()->like('n.parentPath', ':parentPath'))->add($queryBuilder->expr()->eq('n.pathHash', ':pathHash'));
         $queryBuilder->setParameter('parentPath', $pathStartingPoint . '%')->setParameter('pathHash', md5($pathStartingPoint));
         $queryBuilder->getDQLPart('where')->add($pathConstraint);
     }
     $query = $queryBuilder->getQuery();
     $foundNodes = $query->getResult();
     $foundNodes = $this->reduceNodeVariantsByWorkspacesAndDimensions($foundNodes, $workspaces, $dimensions);
     $foundNodes = $this->filterRemovedNodes($foundNodes, false);
     return $foundNodes;
 }
 /**
  * Order current job list, order by name by default
  *
  * @param array $jobConfigurations
  * @param string $orderBy
  * @return array
  */
 protected function orderJobs(array $jobConfigurations, $orderBy = 'name')
 {
     usort($jobConfigurations, function ($a, $b) use($orderBy) {
         $a = Functions::strtolower(trim($a[$orderBy]));
         $b = Functions::strtolower(trim($b[$orderBy]));
         if ($a == $b) {
             return 0;
         }
         return $a < $b ? -1 : 1;
     });
     $result = [];
     foreach ($jobConfigurations as $jobConfiguration) {
         $result[] = $jobConfiguration['implementation'];
     }
     return $result;
 }
 /**
  * Get the length of a string
  *
  * @param string $string The input string
  * @return integer Length of the string
  */
 public function length($string)
 {
     return UnicodeFunctions::strlen($string);
 }
 /**
  * Prepare an uploaded file to be imported as resource object. Will check the validity of the file,
  * move it outside of upload folder if open_basedir is enabled and check the filename.
  *
  * @param array $uploadInfo
  * @return array Array of string with the two keys "filepath" (the path to get the filecontent from) and "filename" the filename of the originally uploaded file.
  * @throws Exception
  */
 protected function prepareUploadedFileForImport(array $uploadInfo)
 {
     $openBasedirEnabled = (bool) ini_get('open_basedir');
     $temporaryTargetPathAndFilename = $uploadInfo['tmp_name'];
     $pathInfo = UnicodeFunctions::pathinfo($uploadInfo['name']);
     if (!is_uploaded_file($temporaryTargetPathAndFilename)) {
         throw new Exception('The given upload file "' . strip_tags($pathInfo['basename']) . '" was not uploaded through PHP. As it could pose a security risk it cannot be imported.', 1422461503);
     }
     if ($openBasedirEnabled === TRUE) {
         // Move uploaded file to a readable folder before trying to read sha1 value of file
         $newTemporaryTargetPathAndFilename = $this->environment->getPathToTemporaryDirectory() . 'ResourceUpload.' . uniqid() . '.tmp';
         if (move_uploaded_file($temporaryTargetPathAndFilename, $newTemporaryTargetPathAndFilename) === FALSE) {
             throw new Exception(sprintf('The uploaded file "%s" could not be moved to the temporary location "%s".', $temporaryTargetPathAndFilename, $newTemporaryTargetPathAndFilename), 1375199056);
         }
         $temporaryTargetPathAndFilename = $newTemporaryTargetPathAndFilename;
     }
     if (!is_file($temporaryTargetPathAndFilename)) {
         throw new Exception(sprintf('The temporary file "%s" of the file upload does not exist (anymore).', $temporaryTargetPathAndFilename), 1375198998);
     }
     return array('filepath' => $temporaryTargetPathAndFilename, 'filename' => $pathInfo['basename']);
 }
 /**
  * @param FlowResource $originalResource
  * @param array $adjustments
  * @return array resource, width, height as keys
  * @throws ImageFileException
  * @throws InvalidConfigurationException
  * @throws \TYPO3\Flow\Resource\Exception
  */
 public function processImage(FlowResource $originalResource, array $adjustments)
 {
     $additionalOptions = array();
     $adjustmentsApplied = false;
     // TODO: Special handling for SVG should be refactored at a later point.
     if ($originalResource->getMediaType() === 'image/svg+xml') {
         $originalResourceStream = $originalResource->getStream();
         $resource = $this->resourceManager->importResource($originalResourceStream, $originalResource->getCollectionName());
         fclose($originalResourceStream);
         $resource->setFilename($originalResource->getFilename());
         return ['width' => null, 'height' => null, 'resource' => $resource];
     }
     $resourceUri = $originalResource->createTemporaryLocalCopy();
     $resultingFileExtension = $originalResource->getFileExtension();
     $transformedImageTemporaryPathAndFilename = $this->environment->getPathToTemporaryDirectory() . uniqid('ProcessedImage-') . '.' . $resultingFileExtension;
     if (!file_exists($resourceUri)) {
         throw new ImageFileException(sprintf('An error occurred while transforming an image: the resource data of the original image does not exist (%s, %s).', $originalResource->getSha1(), $resourceUri), 1374848224);
     }
     $imagineImage = $this->imagineService->open($resourceUri);
     if ($this->imagineService instanceof \Imagine\Imagick\Imagine && $originalResource->getFileExtension() === 'gif' && $this->isAnimatedGif(file_get_contents($resourceUri)) === true) {
         $imagineImage->layers()->coalesce();
         $layers = $imagineImage->layers();
         $newLayers = array();
         foreach ($layers as $index => $imagineFrame) {
             $imagineFrame = $this->applyAdjustments($imagineFrame, $adjustments, $adjustmentsApplied);
             $newLayers[] = $imagineFrame;
         }
         $imagineImage = array_shift($newLayers);
         $layers = $imagineImage->layers();
         foreach ($newLayers as $imagineFrame) {
             $layers->add($imagineFrame);
         }
         $additionalOptions['animated'] = true;
     } else {
         $imagineImage = $this->applyAdjustments($imagineImage, $adjustments, $adjustmentsApplied);
     }
     if ($adjustmentsApplied === true) {
         $imagineImage->save($transformedImageTemporaryPathAndFilename, $this->getOptionsMergedWithDefaults($additionalOptions));
         $imageSize = $imagineImage->getSize();
         // TODO: In the future the collectionName of the new resource should be configurable.
         $resource = $this->resourceManager->importResource($transformedImageTemporaryPathAndFilename, $originalResource->getCollectionName());
         if ($resource === false) {
             throw new ImageFileException('An error occurred while importing a generated image file as a resource.', 1413562208);
         }
         unlink($transformedImageTemporaryPathAndFilename);
         $pathInfo = UnicodeFunctions::pathinfo($originalResource->getFilename());
         $resource->setFilename(sprintf('%s-%ux%u.%s', $pathInfo['filename'], $imageSize->getWidth(), $imageSize->getHeight(), $pathInfo['extension']));
     } else {
         $originalResourceStream = $originalResource->getStream();
         $resource = $this->resourceManager->importResource($originalResourceStream, $originalResource->getCollectionName());
         fclose($originalResourceStream);
         $resource->setFilename($originalResource->getFilename());
         $imageSize = $this->getImageSize($originalResource);
         $imageSize = new Box($imageSize['width'], $imageSize['height']);
     }
     $this->imageSizeCache->set($resource->getCacheEntryIdentifier(), array('width' => $imageSize->getWidth(), 'height' => $imageSize->getHeight()));
     $result = array('width' => $imageSize->getWidth(), 'height' => $imageSize->getHeight(), 'resource' => $resource);
     return $result;
 }
 /**
  * Sets the filename which is used when this resource is downloaded or saved as a file
  *
  * @param string $filename
  * @return void
  * @api
  */
 public function setFilename($filename)
 {
     $this->throwExceptionIfProtected();
     $pathInfo = UnicodeFunctions::pathinfo($filename);
     $extension = isset($pathInfo['extension']) ? '.' . strtolower($pathInfo['extension']) : '';
     $this->filename = $pathInfo['filename'] . $extension;
     $this->mediaType = MediaTypes::getMediaTypeFromFilename($this->filename);
 }
Пример #20
0
 /**
  * Converts a (simple) YAML file to Python instructions.
  *
  * Note: First tried to use 3rd party libraries:
  * - spyc: http://code.google.com/p/spyc/
  * - Symfony2 YAML: http://symfony.com/doc/current/components/yaml/introduction.html
  * but none of them were able to parse our Settings.yml Sphinx configuration files.
  *
  * @param string $filename Absolute filename to Settings.yml
  * @return string Python instruction set
  */
 public function yamlToPython($filename)
 {
     $contents = file_get_contents($filename);
     $lines = explode(PHP_EOL, $contents);
     $pythonConfiguration = array();
     $i = 0;
     while ($lines[$i] !== 'conf.py:' && $i < count($lines)) {
         $i++;
     }
     while ($i < count($lines)) {
         if (preg_match('/^(\\s+)([^:]+):\\s*(.*)$/', $lines[$i], $matches)) {
             switch ($matches[2]) {
                 case 'latex_documents':
                     $pythonLine = 'latex_documents = [(' . PHP_EOL;
                     if (preg_match('/^(\\s+)- - /', $lines[$i + 1], $matches)) {
                         $indent = $matches[1];
                         $firstLine = TRUE;
                         while (preg_match('/^' . $indent . '(- -|  -) (.+)$/', $lines[++$i], $matches)) {
                             if (!$firstLine) {
                                 $pythonLine .= ',' . PHP_EOL;
                             }
                             $pythonLine .= sprintf('u\'%s\'', addcslashes($matches[2], "\\'"));
                             $firstLine = FALSE;
                         }
                     }
                     $pythonLine .= PHP_EOL . ')]';
                     $i--;
                     break;
                 case 'latex_elements':
                     $pythonLine = 'latex_elements = {' . PHP_EOL;
                     if (preg_match('/^(\\s+)/', $lines[$i + 1], $matches)) {
                         $indent = $matches[1];
                         $firstLine = TRUE;
                         while (preg_match('/^' . $indent . '([^:]+):\\s*(.*)$/', $lines[++$i], $matches)) {
                             if (!$firstLine) {
                                 $pythonLine .= ',' . PHP_EOL;
                             }
                             $pythonLine .= sprintf('\'%s\': \'%s\'', $matches[1], addcslashes($matches[2], "\\'"));
                             $firstLine = FALSE;
                         }
                     }
                     $pythonLine .= PHP_EOL . '}';
                     $i--;
                     break;
                 case 'extensions':
                     $pythonLine = 'extensions = [';
                     if (preg_match('/^(\\s+)/', $lines[$i + 1], $matches)) {
                         $indent = $matches[1];
                         $firstItem = TRUE;
                         while (preg_match('/^' . $indent . '- (.+)/', $lines[++$i], $matches)) {
                             if (Functions::substr($matches[1], 0, 9) === 't3sphinx.') {
                                 // Extension t3sphinx is not compatible with JSON output
                                 continue;
                             }
                             if (!$firstItem) {
                                 $pythonLine .= ', ';
                             }
                             $pythonLine .= sprintf('\'%s\'', $matches[1]);
                             $firstItem = FALSE;
                         }
                         $i--;
                     }
                     $pythonLine .= ']';
                     break;
                 case 'intersphinx_mapping':
                     $pythonLine = 'intersphinx_mapping = {' . PHP_EOL;
                     if (preg_match('/^(\\s+)/', $lines[$i + 1], $matches)) {
                         $indent = $matches[1];
                         $firstLine = TRUE;
                         while (preg_match('/^' . $indent . '(.+):/', $lines[++$i], $matches)) {
                             if (!$firstLine) {
                                 $pythonLine .= ',' . PHP_EOL;
                             }
                             $pythonLine .= sprintf('\'%s\': (', $matches[1]);
                             $firstItem = TRUE;
                             while (preg_match('/^' . $indent . '- (.+)/', $lines[++$i], $matches)) {
                                 if (!$firstItem) {
                                     $pythonLine .= ', ';
                                 }
                                 if ($matches[1] === 'null') {
                                     $pythonLine .= 'None';
                                 } else {
                                     $pythonLine .= sprintf('\'%s\'', $matches[1]);
                                 }
                                 $firstItem = FALSE;
                             }
                             $pythonLine .= ')';
                             $firstLine = FALSE;
                             $i--;
                         }
                     }
                     $pythonLine .= PHP_EOL . '}';
                     $i--;
                     break;
                 default:
                     $pythonLine = sprintf('%s = u\'%s\'', $matches[2], addcslashes($matches[3], "\\'"));
                     break;
             }
             if (!empty($pythonLine)) {
                 $pythonConfiguration[] = $pythonLine;
             }
         }
         $i++;
     }
     return $pythonConfiguration;
 }
 /**
  * Publishes the given source stream to this target, with the given relative path.
  *
  * @param resource $sourceStream Stream of the source to publish
  * @param string $relativeTargetPathAndFilename relative path and filename in the target directory
  * @return void
  * @throws Exception
  * @throws \Exception
  * @throws \TYPO3\Flow\Utility\Exception
  */
 protected function publishFile($sourceStream, $relativeTargetPathAndFilename)
 {
     $pathInfo = UnicodeFunctions::pathinfo($relativeTargetPathAndFilename);
     if (isset($pathInfo['extension']) && array_key_exists(strtolower($pathInfo['extension']), $this->extensionBlacklist) && $this->extensionBlacklist[strtolower($pathInfo['extension'])] === true) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the filename extension "%s" is blacklisted.', $sourceStream, $this->name, strtolower($pathInfo['extension'])), 1447148472);
     }
     $targetPathAndFilename = $this->path . $relativeTargetPathAndFilename;
     if (@fstat($sourceStream) === false) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the source file is not accessible (file stat failed).', $sourceStream, $this->name), 1375258499);
     }
     if (!file_exists(dirname($targetPathAndFilename))) {
         Files::createDirectoryRecursively(dirname($targetPathAndFilename));
     }
     if (!is_writable(dirname($targetPathAndFilename))) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the target file "%s" is not writable.', $sourceStream, $this->name, $targetPathAndFilename), 1428917322, isset($exception) ? $exception : null);
     }
     try {
         $targetFileHandle = fopen($targetPathAndFilename, 'w');
         $result = stream_copy_to_stream($sourceStream, $targetFileHandle);
         fclose($targetFileHandle);
     } catch (\Exception $exception) {
         $result = false;
     }
     if ($result === false) {
         throw new Exception(sprintf('Could not publish "%s" into resource publishing target "%s" because the source file could not be copied to the target location.', $sourceStream, $this->name), 1375258399, isset($exception) ? $exception : null);
     }
     $this->systemLogger->log(sprintf('FileSystemTarget: Published file. (target: %s, file: %s)', $this->name, $relativeTargetPathAndFilename), LOG_DEBUG);
 }
 /**
  * Checks if our version of strpos can handle some common special characters
  *
  * @test
  */
 public function strposWorksWithCertainSpecialChars()
 {
     $testString = 'Åeugiat tincidunt duo id, 23 quam delenit vocibus nam eu';
     $this->assertEquals(8, \TYPO3\Flow\Utility\Unicode\Functions::strpos($testString, 'tincidunt'), 'strpos() did not return the correct positions for a unicode string.');
 }
 /**
  * @Flow\Around("setting(TYPO3.Neos.userInterface.scrambleTranslatedLabels) && method(TYPO3\Flow\I18n\Translator->translate.*())")
  * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current join point
  * @return string A scrambled translation string
  */
 public function scrambleTranslatedStrings(JoinPointInterface $joinPoint)
 {
     $translatedString = $joinPoint->getAdviceChain()->proceed($joinPoint);
     return str_repeat('#', UnicodeFunctions::strlen($translatedString));
 }
 /**
  * Find nodes by a value in properties
  *
  * This method is internal and will be replaced with better search capabilities.
  *
  * @param string|array $term Search term
  * @param string $nodeTypeFilter Node type filter
  * @param Workspace $workspace
  * @param array $dimensions
  * @param string $pathStartingPoint
  * @return array<\TYPO3\TYPO3CR\Domain\Model\NodeData>
  */
 public function findByProperties($term, $nodeTypeFilter, $workspace, $dimensions, $pathStartingPoint = null)
 {
     if (empty($term)) {
         throw new \InvalidArgumentException('"term" cannot be empty: provide a term to search for.', 1421329285);
     }
     $workspaces = $this->collectWorkspaceAndAllBaseWorkspaces($workspace);
     $queryBuilder = $this->createQueryBuilder($workspaces);
     $this->addDimensionJoinConstraintsToQueryBuilder($queryBuilder, $dimensions);
     $this->addNodeTypeFilterConstraintsToQueryBuilder($queryBuilder, $nodeTypeFilter);
     if (is_array($term)) {
         if (count($term) !== 1) {
             throw new \InvalidArgumentException('Currently only a 1-dimensional key => value array term is supported.', 1460437584);
         }
         // Build the like parameter as "key": "value" to search by a specific key and value
         $likeParameter = '%' . UnicodeFunctions::strtolower(trim(json_encode($term, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT | JSON_UNESCAPED_UNICODE), "{}\n\t ")) . '%';
     } else {
         // Convert to lowercase, then to json, and then trim quotes from json to have valid JSON escaping.
         $likeParameter = '%' . trim(json_encode(UnicodeFunctions::strtolower($term), JSON_UNESCAPED_UNICODE), '"') . '%';
     }
     $queryBuilder->andWhere("LOWER(NEOSCR_TOSTRING(n.properties)) LIKE :term")->setParameter('term', $likeParameter);
     if (strlen($pathStartingPoint) > 0) {
         $pathStartingPoint = strtolower($pathStartingPoint);
         $queryBuilder->andWhere($queryBuilder->expr()->orx()->add($queryBuilder->expr()->eq('n.parentPathHash', ':parentPathHash'))->add($queryBuilder->expr()->eq('n.pathHash', ':pathHash'))->add($queryBuilder->expr()->like('n.parentPath', ':parentPath')))->setParameter('parentPathHash', md5($pathStartingPoint))->setParameter('pathHash', md5($pathStartingPoint))->setParameter('parentPath', rtrim($pathStartingPoint, '/') . '/%');
     }
     $query = $queryBuilder->getQuery();
     $foundNodes = $query->getResult();
     $foundNodes = $this->reduceNodeVariantsByWorkspacesAndDimensions($foundNodes, $workspaces, $dimensions);
     $foundNodes = $this->filterRemovedNodes($foundNodes, false);
     return $foundNodes;
 }
 /**
  * Helper function to do the splitting by sentence. Note: one punctuations
  * mark belongs to the preceding sentence. Whitespace between sentences is
  * marked as boundary.
  *
  */
 private function parseSubjectBySentence()
 {
     $i = 0;
     $j = 0;
     $count = 0;
     $delimitersMatches = array();
     preg_match_all('/' . self::REGEXP_SENTENCE_DELIMITERS . '/', $this->subject, $delimitersMatches);
     $splittedSentence = preg_split('/' . self::REGEXP_SENTENCE_DELIMITERS . '/', $this->subject);
     if (count($splittedSentence) == 1) {
         $this->iteratorCache->append(new \TYPO3\Flow\Utility\Unicode\TextIteratorElement($splittedSentence[0], 0, \TYPO3\Flow\Utility\Unicode\Functions::strlen($splittedSentence[0]), FALSE));
         return;
     }
     foreach ($splittedSentence as $currentPart) {
         $currentPart = preg_replace('/^\\s|\\s$/', '', $currentPart, -1, $count);
         $whiteSpace = '';
         for ($k = 0; $k < $count; $k++) {
             $whiteSpace .= ' ';
         }
         if ($whiteSpace != '') {
             $this->iteratorCache->append(new \TYPO3\Flow\Utility\Unicode\TextIteratorElement($whiteSpace, $i, $count, TRUE));
         }
         $i += $count;
         if ($currentPart != '' && $j < count($delimitersMatches[0])) {
             $this->iteratorCache->append(new \TYPO3\Flow\Utility\Unicode\TextIteratorElement($currentPart . $delimitersMatches[0][$j], $i, \TYPO3\Flow\Utility\Unicode\Functions::strlen($currentPart . $delimitersMatches[0][$j]), FALSE));
             $i += \TYPO3\Flow\Utility\Unicode\Functions::strlen($currentPart . $delimitersMatches[0][$j]);
             $j++;
         } elseif ($j < count($delimitersMatches[0])) {
             $this->iteratorCache->append(new \TYPO3\Flow\Utility\Unicode\TextIteratorElement($delimitersMatches[0][$j], $i, 1, TRUE));
             $i++;
             $j++;
         }
     }
 }
Пример #26
0
 /**
  * Crop a string to $maximumCharacters length, taking sentences into account,
  * optionally appending $suffix if cropping was necessary.
  *
  * @param string $string the input string
  * @param integer $maximumCharacters number of characters where cropping should happen
  * @param string $suffix optional suffix to be appended if cropping was necessary
  * @return string the cropped string
  */
 public function cropAtSentence($string, $maximumCharacters, $suffix = '')
 {
     if (UnicodeFunctions::strlen($string) > $maximumCharacters) {
         $iterator = new TextIterator($string, TextIterator::SENTENCE);
         $string = UnicodeFunctions::substr($string, 0, $iterator->preceding($maximumCharacters));
         $string .= $suffix;
     }
     return $string;
 }
 /**
  * Read the xliff file and create the desired json
  *
  * @param string $xliffPathAndFilename The file to read
  * @param string $packageKey
  * @param string $sourceName
  * @return array
  *
  * @todo remove the override handling once Flow takes care of that, see FLOW-61
  */
 public function parseXliffToArray($xliffPathAndFilename, $packageKey, $sourceName)
 {
     /** @var array $parsedData */
     $parsedData = $this->xliffParser->getParsedData($xliffPathAndFilename);
     $arrayData = array();
     foreach ($parsedData['translationUnits'] as $key => $value) {
         $valueToStore = !empty($value[0]['target']) ? $value[0]['target'] : $value[0]['source'];
         if ($this->scrambleTranslatedLabels) {
             $valueToStore = str_repeat('#', UnicodeFunctions::strlen($valueToStore));
         }
         $this->setArrayDataValue($arrayData, str_replace('.', '_', $packageKey) . '.' . str_replace('/', '_', $sourceName) . '.' . str_replace('.', '_', $key), $valueToStore);
     }
     return $arrayData;
 }
 /**
  * Checks if our version of pathinfo can handle some common special characters
  *
  * @test
  */
 public function pathinfoWorksWithCertainSpecialChars()
 {
     $testString = 'кириллическийПуть/кириллическоеИмя.расширение';
     $this->assertEquals('кириллическийПуть', \TYPO3\Flow\Utility\Unicode\Functions::pathinfo($testString, PATHINFO_DIRNAME), 'pathinfo() did not return the correct dirname for a unicode path.');
     $this->assertEquals('кириллическоеИмя.расширение', \TYPO3\Flow\Utility\Unicode\Functions::pathinfo($testString, PATHINFO_BASENAME), 'pathinfo() did not return the correct basename for a unicode path.');
     $this->assertEquals('расширение', \TYPO3\Flow\Utility\Unicode\Functions::pathinfo($testString, PATHINFO_EXTENSION), 'pathinfo() did not return the correct extension for a unicode path.');
     $this->assertEquals('кириллическоеИмя', \TYPO3\Flow\Utility\Unicode\Functions::pathinfo($testString, PATHINFO_FILENAME), 'pathinfo() did not return the correct filename for a unicode path.');
 }