/** * Checks if the given value is a valid DateTime object. * * @param mixed $value The value that should be validated * @return void * @api */ protected function isValid($value) { if ($value instanceof \DateTime) { return; } if (!isset($this->options['locale'])) { $locale = $this->localizationService->getConfiguration()->getDefaultLocale(); } elseif (is_string($this->options['locale'])) { $locale = new \TYPO3\Flow\I18n\Locale($this->options['locale']); } elseif ($this->options['locale'] instanceof \TYPO3\Flow\I18n\Locale) { $locale = $this->options['locale']; } else { $this->addError('The "locale" option can be only set to string identifier, or Locale object.', 1281454676); return; } $strictMode = $this->options['strictMode']; $formatLength = $this->options['formatLength']; \TYPO3\Flow\I18n\Cldr\Reader\DatesReader::validateFormatLength($formatLength); $formatType = $this->options['formatType']; \TYPO3\Flow\I18n\Cldr\Reader\DatesReader::validateFormatType($formatType); if ($formatType === \TYPO3\Flow\I18n\Cldr\Reader\DatesReader::FORMAT_TYPE_TIME) { if ($this->datetimeParser->parseTime($value, $locale, $formatLength, $strictMode) === FALSE) { $this->addError('A valid time is expected.', 1281454830); } } elseif ($formatType === \TYPO3\Flow\I18n\Cldr\Reader\DatesReader::FORMAT_TYPE_DATETIME) { if ($this->datetimeParser->parseDateAndTime($value, $locale, $formatLength, $strictMode) === FALSE) { $this->addError('A valid date and time is expected.', 1281454831); } } else { if ($this->datetimeParser->parseDate($value, $locale, $formatLength, $strictMode) === FALSE) { $this->addError('A valid date is expected.', 1281454832); } } }
/** * Checks if the given value is a valid number. * * @param mixed $value The value that should be validated * @return void * @api * @todo Currency support should be added when it will be supported by NumberParser */ protected function isValid($value) { if (!isset($this->options['locale'])) { $locale = $this->localizationService->getConfiguration()->getDefaultLocale(); } elseif (is_string($this->options['locale'])) { $locale = new \TYPO3\Flow\I18n\Locale($this->options['locale']); } elseif ($this->options['locale'] instanceof \TYPO3\Flow\I18n\Locale) { $locale = $this->options['locale']; } else { $this->addError('The "locale" option can be only set to string identifier, or Locale object.', 1281286579); return; } $strictMode = $this->options['strictMode']; $formatLength = $this->options['formatLength']; \TYPO3\Flow\I18n\Cldr\Reader\NumbersReader::validateFormatLength($formatLength); $formatType = $this->options['formatType']; \TYPO3\Flow\I18n\Cldr\Reader\NumbersReader::validateFormatType($formatType); if ($formatType === \TYPO3\Flow\I18n\Cldr\Reader\NumbersReader::FORMAT_TYPE_PERCENT) { if ($this->numberParser->parsePercentNumber($value, $locale, $formatLength, $strictMode) === false) { $this->addError('A valid percent number is expected.', 1281452093); } return; } else { if ($this->numberParser->parseDecimalNumber($value, $locale, $formatLength, $strictMode) === false) { $this->addError('A valid decimal number is expected.', 1281452094); } } }
/** * Return the json array for a given locale, sourceCatalog, xliffPath and package. * The json will be cached. * * @param Locale $locale The locale * @return Result * @throws Exception */ public function getCachedJson(Locale $locale) { $cacheIdentifier = md5($locale); if ($this->xliffToJsonTranslationsCache->has($cacheIdentifier)) { $json = $this->xliffToJsonTranslationsCache->get($cacheIdentifier); } else { $labels = []; $localeChain = $this->localizationService->getLocaleChain($locale); foreach ($this->packagesRegisteredForAutoInclusion as $packageKey => $sourcesToBeIncluded) { if (!is_array($sourcesToBeIncluded)) { continue; } $translationBasePath = Files::concatenatePaths([$this->packageManager->getPackage($packageKey)->getResourcesPath(), $this->xliffBasePath]); // We merge labels in the chain from the worst choice to best choice foreach (array_reverse($localeChain) as $allowedLocale) { $localeSourcePath = Files::getNormalizedPath(Files::concatenatePaths([$translationBasePath, $allowedLocale])); foreach ($sourcesToBeIncluded as $sourceName) { foreach (glob($localeSourcePath . $sourceName . '.xlf') as $xliffPathAndFilename) { $xliffPathInfo = pathinfo($xliffPathAndFilename); $sourceName = str_replace($localeSourcePath, '', $xliffPathInfo['dirname'] . '/' . $xliffPathInfo['filename']); $labels = Arrays::arrayMergeRecursiveOverrule($labels, $this->parseXliffToArray($xliffPathAndFilename, $packageKey, $sourceName)); } } } } $json = json_encode($labels); $this->xliffToJsonTranslationsCache->set($cacheIdentifier, $json); } return $json; }
/** * Initializes some basic stuff that will basically be needed for each and * every action that is executed later on. */ public function initializeAction() { // get the account of the authenticated user $this->account = $this->securityContext->getAccount(); // set the locale $this->locale = $this->localeDetector->detectLocaleFromLocaleTag($this->settings['defaultLanguage']); if ($this->l18nService->getConfiguration()->getCurrentLocale() !== $this->locale) { $this->l18nService->getConfiguration()->setCurrentLocale($this->locale); } }
/** * Returns the localized name of a country or - if no localization was found - the country code * * @param $countryCode * @return string */ public function getTerritoryNameForIsoCode($countryCode) { // get the localized country names from the CLDR data $i18nConfiguration = $this->i18nService->getConfiguration(); $cldrModel = $this->cldrRepository->getModel('main/' . $i18nConfiguration->getCurrentLocale()->getLanguage()); $countries = $cldrModel->findNodesWithinPath('localeDisplayNames/territories', 'territory'); if (array_key_exists('territory[@type="' . strtoupper($countryCode) . '"]', $countries)) { return $countries['territory[@type="' . strtoupper($countryCode) . '"]']; } else { return $countryCode; } }
/** * Translaterates UTF-8 string to ASCII. (北京 to 'Bei Jing') * * Accepts language parameter that maps to a configurable array of special transliteration rules if present. * * @param string $text Text to transliterate * @param string $language Optional language for specific rules (falls back to current locale if not provided) * @return string */ public function transliterate($text, $language = null) { $language = $language ?: $this->localizationService->getConfiguration()->getCurrentLocale()->getLanguage(); if (isset($this->transliterationRules[$language])) { // Apply special transliteration (not supported in library) $text = strtr($text, $this->transliterationRules[$language]); } // Transliterate (transform 北京 to 'Bei Jing') if (preg_match('/[\\x80-\\xff]/', $text) && Transliterator::validUtf8($text)) { $text = Transliterator::utf8ToAscii($text); } return $text; }
/** * Render the URI to the resource. The filename is used from child content. * * @param string $path The location of the resource, can be either a path relative to the Public resource directory of the package or a resource://... URI * @param string $package Target package key. If not set, the current package key will be used * @param Resource $resource If specified, this resource object is used instead of the path and package information * @param boolean $localize Whether resource localization should be attempted or not * @return string The absolute URI to the resource * @throws InvalidVariableException * @api */ public function render($path = null, $package = null, Resource $resource = null, $localize = true) { if ($resource !== null) { $uri = $this->resourceManager->getPublicPersistentResourceUri($resource); if ($uri === false) { $uri = '404-Resource-Not-Found'; } } else { if ($path === null) { throw new InvalidVariableException('The ResourceViewHelper did neither contain a valuable "resource" nor "path" argument.', 1353512742); } if ($package === null) { $package = $this->controllerContext->getRequest()->getControllerPackageKey(); } if (strpos($path, 'resource://') === 0) { try { list($package, $path) = $this->resourceManager->getPackageAndPathByPublicPath($path); } catch (Exception $exception) { throw new InvalidVariableException(sprintf('The specified path "%s" does not point to a public resource.', $path), 1386458851); } } if ($localize === true) { $resourcePath = 'resource://' . $package . '/Public/' . $path; $localizedResourcePathData = $this->i18nService->getLocalizedFilename($resourcePath); $matches = array(); if (preg_match('#resource://([^/]+)/Public/(.*)#', current($localizedResourcePathData), $matches) === 1) { $package = $matches[1]; $path = $matches[2]; } } $uri = $this->resourceManager->getPublicPackageResourceUri($package, $path); } return $uri; }
/** * Replaces all placeholders in text with corresponding values. * * A placeholder is a group of elements separated with comma. First element * is required and defines index of value to insert (numeration starts from * 0, and is directly used to access element from $values array). Second * element is a name of formatter to use. It's optional, and if not given, * value will be simply string-casted. Remaining elements are formatter- * specific and they are directly passed to the formatter class. * * @param string $textWithPlaceholders String message with placeholder(s) * @param array $arguments An array of values to replace placeholders with * @param \TYPO3\Flow\I18n\Locale $locale Locale to use (NULL for default one) * @return string The $text with placeholders resolved * @throws \TYPO3\Flow\I18n\Exception\InvalidFormatPlaceholderException When encountered incorrectly formatted placeholder * @throws \TYPO3\Flow\I18n\Exception\IndexOutOfBoundsException When trying to format nonexistent value * @api */ public function resolvePlaceholders($textWithPlaceholders, array $arguments, \TYPO3\Flow\I18n\Locale $locale = null) { if ($locale === null) { $locale = $this->localizationService->getConfiguration()->getDefaultLocale(); } $lastPlaceHolderAt = 0; while ($lastPlaceHolderAt < strlen($textWithPlaceholders) && ($startOfPlaceholder = strpos($textWithPlaceholders, '{', $lastPlaceHolderAt)) !== false) { $endOfPlaceholder = strpos($textWithPlaceholders, '}', $lastPlaceHolderAt); $startOfNextPlaceholder = strpos($textWithPlaceholders, '{', $startOfPlaceholder + 1); if ($endOfPlaceholder === false || $startOfPlaceholder + 1 >= $endOfPlaceholder || $startOfNextPlaceholder !== false && $startOfNextPlaceholder < $endOfPlaceholder) { // There is no closing bracket, or it is placed before the opening bracket, or there is nothing between brackets throw new \TYPO3\Flow\I18n\Exception\InvalidFormatPlaceholderException('Text provided contains incorrectly formatted placeholders. Please make sure you conform the placeholder\'s syntax.', 1278057790); } $contentBetweenBrackets = substr($textWithPlaceholders, $startOfPlaceholder + 1, $endOfPlaceholder - $startOfPlaceholder - 1); $placeholderElements = explode(',', str_replace(' ', '', $contentBetweenBrackets)); $valueIndex = $placeholderElements[0]; if (!array_key_exists($valueIndex, $arguments)) { throw new \TYPO3\Flow\I18n\Exception\IndexOutOfBoundsException('Placeholder "' . $valueIndex . '" was not provided, make sure you provide values for every placeholder.', 1278057791); } if (isset($placeholderElements[1])) { $formatterName = $placeholderElements[1]; $formatter = $this->getFormatter($formatterName); $formattedPlaceholder = $formatter->format($arguments[$valueIndex], $locale, array_slice($placeholderElements, 2)); } else { // No formatter defined, just string-cast the value $formattedPlaceholder = (string) $arguments[$valueIndex]; } $textWithPlaceholders = str_replace('{' . $contentBetweenBrackets . '}', $formattedPlaceholder, $textWithPlaceholders); $lastPlaceHolderAt = $startOfPlaceholder + strlen($formattedPlaceholder); } return $textWithPlaceholders; }
/** * Is called if authentication failed. * * @param AuthenticationRequiredException $exception The exception thrown while the authentication process * @return void */ protected function onAuthenticationFailure(AuthenticationRequiredException $exception = null) { $responseIdentifier = 0; /** @var TokenInterface $token */ foreach ($this->authenticationManager->getTokens() as $token) { if ($token->getAuthenticationStatus() > $responseIdentifier) { $responseIdentifier = $token->getAuthenticationStatus(); } } $locale = $this->localizationService->getConfiguration()->getCurrentLocale(); $package = $this->controllerContext->getRequest()->getControllerPackageKey(); $this->view->assign('value', array('responseText' => $this->translator->translateById('authentication.response.' . $responseIdentifier, array(), NULL, $locale, 'Main', $package), 'responseIdentifier' => $responseIdentifier)); if ($this->request->getHttpRequest()->getMethod() !== 'OPTIONS') { $this->response->setStatus(401); } }
/** * Renders an RSS feed * * @return string */ public function rssAction() { /** @var NodeInterface $blogDocumentNode */ $rssDocumentNode = $this->request->getInternalArgument('__documentNode'); if ($rssDocumentNode === NULL) { return 'Error: The Blog Post Plugin cannot determine the current document node. Please make sure to include this plugin only by inserting it into a page / document.'; } $blogDocumentNode = $rssDocumentNode->getParent(); $uriBuilder = new UriBuilder(); $uriBuilder->setRequest($this->request->getMainRequest()); $uriBuilder->setCreateAbsoluteUri(TRUE); if ($this->settings['feed']['uri'] !== '') { $feedUri = $this->settings['feed']['uri']; } else { $uriBuilder->setFormat('xml'); $feedUri = $uriBuilder->uriFor('show', array('node' => $rssDocumentNode), 'Frontend\\Node', 'TYPO3.Neos'); } $channel = new Channel(); $channel->setTitle($this->settings['feed']['title']); $channel->setDescription($this->settings['feed']['description']); $channel->setFeedUri($feedUri); $channel->setWebsiteUri($this->request->getHttpRequest()->getBaseUri()); $channel->setLanguage((string) $this->i18nService->getConfiguration()->getCurrentLocale()); foreach ($blogDocumentNode->getChildNodes('RobertLemke.Plugin.Blog:Post') as $postNode) { /* @var $postNode NodeInterface */ $uriBuilder->setFormat('html'); $postUri = $uriBuilder->uriFor('show', array('node' => $postNode), 'Frontend\\Node', 'TYPO3.Neos'); $item = new Item(); $item->setTitle($postNode->getProperty('title')); $item->setGuid($postNode->getIdentifier()); // TODO: Remove this once all old node properties are migrated: $publicationDate = $postNode->getProperty('datePublished'); if (is_string($publicationDate)) { $publicationDate = \DateTime::createFromFormat('Y-m-d', $publicationDate); $postNode->setProperty('datePublished', $publicationDate); } $item->setPublicationDate($postNode->getProperty('datePublished')); $item->setItemLink((string) $postUri); $item->setCommentsLink((string) $postUri . '#comments'); // TODO: Remove this once all old node properties are migrated: $author = $postNode->getProperty('author'); if ($author === NULL) { $author = 'Robert Lemke'; $postNode->setProperty('author', $author); } $item->setCreator($author); # $item->setCategories(array('test')); $description = $this->contentService->renderTeaser($postNode) . ' <a href="' . $postUri . '">Read more</a>'; $item->setDescription($description); $channel->addItem($item); } // This won't work yet (plugin sub responses can't set headers yet) but keep that as a reminder: $headers = $this->response->getHeaders(); $headers->setCacheControlDirective('s-max-age', 3600); $headers->set('Content-Type', 'application/rss+xml'); $feed = new Feed(); $feed->addChannel($channel); return $feed->render(); }
/** * Check if a form has a localized version and deliver it if available * * @param $formName * @param $localeOverride * @return string */ public function getFormNameRespectingLocale($formName, $localeOverride = '') { // if we override the locale anyway (and it isn't english), we return early if (!empty($localeOverride) && $localeOverride !== 'en') { return $formName . ucfirst($localeOverride); } $currentLanguage = $this->i18nService->getConfiguration()->getCurrentLocale()->getLanguage(); /* * a localized version has the language iso code as uppercased suffix, e.g. dataSheetFormFr * english is the default language and has no suffix, therefore we return the unchanged name if * no translation was found */ if ($this->formPersistenceManager->exists($formName . ucfirst($currentLanguage))) { $formName = $formName . ucfirst($currentLanguage); } return $formName; }
/** * Returns best-matching Locale object based on the template Locale object * provided as parameter. System default locale will be returned if no * successful matches were done. * * @param \TYPO3\Flow\I18n\Locale $locale The template Locale object * @return \TYPO3\Flow\I18n\Locale Best-matching existing Locale instance * @api */ public function detectLocaleFromTemplateLocale(\TYPO3\Flow\I18n\Locale $locale) { $bestMatchingLocale = $this->localeCollection->findBestMatchingLocale($locale); if ($bestMatchingLocale !== null) { return $bestMatchingLocale; } return $this->localizationService->getConfiguration()->getDefaultLocale(); }
/** * Override this method in your custom FormElements if needed * * @return void */ public function initializeFormElement() { // the not localized country codes and names $selectOptions = $this->getProperties()['options']; // get the localized country names from the CLDR data $i18nConfiguration = $this->i18nService->getConfiguration(); $cldrModel = $this->cldrRepository->getModel('main/' . $i18nConfiguration->getCurrentLocale()->getLanguage()); $countries = $cldrModel->findNodesWithinPath('localeDisplayNames/territories', 'territory'); // if the country is found in the CLDR data, use the localized name $localizedSelectOptions = array(); foreach ($selectOptions as $countryCode => $countryName) { if (array_key_exists('territory[@type="' . strtoupper($countryCode) . '"]', $countries)) { $localizedSelectOptions[$countryCode] = $countries['territory[@type="' . strtoupper($countryCode) . '"]']; } else { $localizedSelectOptions[$countryCode] = $countryName; } } $this->setProperty('options', $localizedSelectOptions); }
/** * Get the locale to use for all locale specific functionality. * * @throws InvalidVariableException * @return I18n\Locale The locale to use or NULL if locale should not be used */ protected function getLocale() { if (!$this->hasArgument('forceLocale')) { return null; } $forceLocale = $this->arguments['forceLocale']; $useLocale = null; if ($forceLocale instanceof I18n\Locale) { $useLocale = $forceLocale; } elseif (is_string($forceLocale)) { try { $useLocale = new I18n\Locale($forceLocale); } catch (I18n\Exception $exception) { throw new InvalidVariableException('"' . $forceLocale . '" is not a valid locale identifier.', 1342610148, $exception); } } elseif ($forceLocale === true) { $useLocale = $this->localizationService->getConfiguration()->getCurrentLocale(); } return $useLocale; }
/** * Returns a XliffModel instance representing desired XLIFF file. * * Will return existing instance if a model for given $sourceName was already * requested before. Returns FALSE when $sourceName doesn't point to existing * file. * * @param string $packageKey Key of the package containing the source file * @param string $sourceName Relative path to existing CLDR file * @param \TYPO3\Flow\I18n\Locale $locale Locale object * @return \TYPO3\Flow\I18n\Xliff\XliffModel New or existing instance * @throws \TYPO3\Flow\I18n\Exception */ protected function getModel($packageKey, $sourceName, \TYPO3\Flow\I18n\Locale $locale) { $sourcePath = \TYPO3\Flow\Utility\Files::concatenatePaths(array('resource://' . $packageKey, $this->xliffBasePath)); list($sourcePath, $foundLocale) = $this->localizationService->getXliffFilenameAndPath($sourcePath, $sourceName, $locale); if ($sourcePath === false) { throw new \TYPO3\Flow\I18n\Exception('No XLIFF file is available for ' . $packageKey . '::' . $sourceName . '::' . $locale . ' in the locale chain.', 1334759591); } if (isset($this->models[$sourcePath])) { return $this->models[$sourcePath]; } return $this->models[$sourcePath] = new \TYPO3\Flow\I18n\Xliff\XliffModel($sourcePath, $foundLocale); }
/** * Renders the view * * @return string The rendered view * @throws \Exception if no node is given * @api */ public function render() { $currentNode = $this->getCurrentNode(); $currentSiteNode = $currentNode->getContext()->getCurrentSiteNode(); $typoScriptRuntime = $this->getTypoScriptRuntime($currentSiteNode); $dimensions = $currentNode->getContext()->getDimensions(); if (array_key_exists('language', $dimensions) && $dimensions['language'] !== array()) { $currentLocale = new Locale($dimensions['language'][0]); $this->i18nService->getConfiguration()->setCurrentLocale($currentLocale); $this->i18nService->getConfiguration()->setFallbackRule(array('strict' => false, 'order' => array_reverse($dimensions['language']))); } $typoScriptRuntime->pushContextArray(array('node' => $currentNode, 'documentNode' => $this->getClosestDocumentNode($currentNode) ?: $currentNode, 'site' => $currentSiteNode, 'editPreviewMode' => isset($this->variables['editPreviewMode']) ? $this->variables['editPreviewMode'] : null)); try { $output = $typoScriptRuntime->render($this->typoScriptPath); $output = $this->mergeHttpResponseFromOutput($output, $typoScriptRuntime); } catch (RuntimeException $exception) { throw $exception->getPrevious(); } $typoScriptRuntime->popContext(); return $output; }
/** * Returns translated string found under the $labelId. * * Searches for a translation in the source as defined by $sourceName * (interpretation depends on concrete translation provider used). * * If any arguments are provided in the $arguments array, they will be inserted * to the translated string (in place of corresponding placeholders, with * format defined by these placeholders). * * If $quantity is provided, correct plural form for provided $locale will * be chosen and used to choose correct translation variant. * * @param string $labelId Key to use for finding translation * @param array $arguments An array of values to replace placeholders with * @param mixed $quantity A number to find plural form for (float or int), NULL to not use plural forms * @param \TYPO3\Flow\I18n\Locale $locale Locale to use (NULL for default one) * @param string $sourceName Name of file with translations, base path is $packageKey/Resources/Private/Locale/Translations/ * @param string $packageKey Key of the package containing the source file * @return string Translated message or $labelId on failure * @api * @see \TYPO3\Flow\I18n\Translator::translateByOriginalLabel() */ public function translateById($labelId, array $arguments = array(), $quantity = null, \TYPO3\Flow\I18n\Locale $locale = null, $sourceName = 'Main', $packageKey = 'TYPO3.Flow') { if ($locale === null) { $locale = $this->localizationService->getConfiguration()->getCurrentLocale(); } $pluralForm = $this->getPluralForm($quantity, $locale); $translatedMessage = $this->translationProvider->getTranslationById($labelId, $locale, $pluralForm, $sourceName, $packageKey); if ($translatedMessage === false) { return $labelId; } elseif (!empty($arguments)) { return $this->formatResolver->resolvePlaceholders($translatedMessage, $arguments, $locale); } return $translatedMessage; }
/** * @param mixed $stringToFormat * @param mixed $locale string or boolean or \TYPO3\Flow\I18n\Locale * @param string $currencySign * * @throws \TYPO3\Fluid\Core\ViewHelper\Exception\InvalidVariableException * @return string */ protected function renderUsingLocale($stringToFormat, $locale, $currencySign) { if ($locale instanceof I18n\Locale) { $useLocale = $locale; } elseif (is_string($locale)) { try { $useLocale = new I18n\Locale($locale); } catch (I18n\Exception $exception) { throw new InvalidVariableException('"' . $locale . '" is not a valid locale identifier.', 1342610148, $exception); } } else { $useLocale = $this->localizationService->getConfiguration()->getCurrentLocale(); } return $this->numberFormatter->formatCurrencyNumber($stringToFormat, $useLocale, $currencySign); }
/** * @param string $resourcePath * @return string */ protected function getStaticResourceWebBaseUri($resourcePath) { $localizedResourcePathData = $this->i18nService->getLocalizedFilename($resourcePath); $matches = array(); try { if (preg_match('#resource://([^/]+)/Public/(.*)#', current($localizedResourcePathData), $matches) === 1) { $packageKey = $matches[1]; $path = $matches[2]; return $this->resourceManager->getPublicPackageResourceUri($packageKey, $path); } } catch (\Exception $exception) { $this->systemLogger->logException($exception); } return ''; }
/** * Returns the absolute URL of a resource * * @return string * @throws TypoScriptException */ public function evaluate() { $resource = $this->getResource(); if ($resource !== null) { $uri = false; if ($resource instanceof Resource) { $uri = $this->resourceManager->getPublicPersistentResourceUri($resource); } if ($uri === false) { throw new TypoScriptException('The specified resource is invalid', 1386458728); } return $uri; } $path = $this->getPath(); if ($path === null) { throw new TypoScriptException('Neither "resource" nor "path" were specified', 1386458763); } if (strpos($path, 'resource://') === 0) { $matches = array(); if (preg_match('#^resource://([^/]+)/Public/(.*)#', $path, $matches) !== 1) { throw new TypoScriptException(sprintf('The specified path "%s" does not point to a public resource.', $path), 1386458851); } $package = $matches[1]; $path = $matches[2]; } else { $package = $this->getPackage(); if ($package === null) { $controllerContext = $this->tsRuntime->getControllerContext(); /** @var $actionRequest ActionRequest */ $actionRequest = $controllerContext->getRequest(); $package = $actionRequest->getControllerPackageKey(); } } $localize = $this->isLocalize(); if ($localize === true) { $resourcePath = 'resource://' . $package . '/Public/' . $path; $localizedResourcePathData = $this->i18nService->getLocalizedFilename($resourcePath); $matches = array(); if (preg_match('#resource://([^/]+)/Public/(.*)#', current($localizedResourcePathData), $matches) === 1) { $package = $matches[1]; $path = $matches[2]; } } return $this->resourceManager->getPublicPackageResourceUri($package, $path); }
/** * @test */ public function evaluateLocalizesFilenameIfLocalize() { $this->mockTsRuntime->expects($this->any())->method('evaluate')->will($this->returnCallback(function ($evaluatePath, $that) { $relativePath = str_replace('resourceUri/test/', '', $evaluatePath); switch ($relativePath) { case 'localize': return true; case 'path': return 'resource://Some.Package/Public/SomeResource'; case 'package': return 'Specified.Package'; } return null; })); $this->mockI18nService->expects($this->atLeastOnce())->method('getLocalizedFilename')->will($this->returnValue(array('resource://Some.Package/Public/LocalizedFilename'))); $this->mockResourceManager->expects($this->atLeastOnce())->method('getPublicPackageResourceUri')->will($this->returnValue('Static/Resources/Packages/Some.Package/LocalizedFilename')); $this->assertSame('Static/Resources/Packages/Some.Package/LocalizedFilename', $this->resourceUriImplementation->evaluate()); }
/** * Render the URI to the resource. The filename is used from child content. * * @param string $path The location of the resource, can be either a path relative to the Public resource directory of the package or a resource://... URI * @param string $package Target package key. If not set, the current package key will be used * @param Resource $resource If specified, this resource object is used instead of the path and package information * @param boolean $localize Whether resource localization should be attempted or not * @return string The absolute URI to the resource * @throws InvalidVariableException * @api */ public function render($path = NULL, $package = NULL, Resource $resource = NULL, $localize = TRUE) { if ($resource !== NULL) { $uri = $this->resourcePublisher->getPersistentResourceWebUri($resource); if ($uri === FALSE) { $uri = $this->resourcePublisher->getStaticResourcesWebBaseUri() . 'BrokenResource'; } } else { if ($path === NULL) { throw new InvalidVariableException('The ResourceViewHelper did neither contain a valuable "resource" nor "path" argument.', 1353512742); } if ($package === NULL) { $package = $this->controllerContext->getRequest()->getControllerPackageKey(); } if (strpos($path, 'resource://') === 0) { $matches = array(); if (preg_match('#^resource://([^/]+)/Public/(.*)#', $path, $matches) === 1) { $package = $matches[1]; $path = $matches[2]; } else { throw new InvalidVariableException(sprintf('The path "%s" which was given to the ResourceViewHelper must point to a public resource.', $path), 1353512639); } } if ($localize === TRUE) { $resourcePath = 'resource://' . $package . '/Public/' . $path; $localizedResourcePathData = $this->i18nService->getLocalizedFilename($resourcePath); $matches = array(); if (preg_match('#resource://([^/]+)/Public/(.*)#', current($localizedResourcePathData), $matches) === 1) { $package = $matches[1]; $path = $matches[2]; } } $uri = $this->resourcePublisher->getStaticResourcesWebBaseUri() . 'Packages/' . $package . '/' . $path; } return $uri; }
/** * @return string */ public function getNameByForCurrentLocale() { $locale = $this->i18nService->getConfiguration()->getCurrentLocale(); return $this->getNameForLocale($locale); }
/** * Reads a particular Xliff file and returns it's translation units as array entries * * @param string the package key * @param string the source name (e.g. filename) * @param \TYPO3\Flow\I18n\Locale the locale * * @return array */ protected function getXliffDataAsArray($packageKey, $sourceName, \TYPO3\Flow\I18n\Locale $locale) { $sourcePath = \TYPO3\Flow\Utility\Files::concatenatePaths(array('resource://' . $packageKey, 'Private/Translations')); list($sourcePath, $foundLocale) = $this->localizationService->getXliffFilenameAndPath($sourcePath, $sourceName, $locale); return $this->xliffParser->getParsedData($sourcePath); }
/** * @param \DateTime $dateTime * @param mixed $locale string or boolean or \TYPO3\Flow\I18n\Locale * @param array $formatConfiguration The format configuration to use, index 0 is the type, index 1 is the format length * * @throws \TYPO3\Fluid\Core\ViewHelper\Exception\InvalidVariableException * @throws \TYPO3\Fluid\Core\ViewHelper\Exception * @return string */ protected function renderUsingLocale(\DateTime $dateTime, $locale, array $formatConfiguration) { if ($locale instanceof I18n\Locale) { $useLocale = $locale; } elseif (is_string($locale)) { try { $useLocale = new I18n\Locale($locale); } catch (I18n\Exception $exception) { throw new ViewHelper\Exception\InvalidVariableException('"' . $locale . '" is not a valid locale identifier.', 1342610148, $exception); } } else { $useLocale = $this->localizationService->getConfiguration()->getCurrentLocale(); } try { $return = $this->formatter->format($dateTime, $useLocale, $formatConfiguration); } catch (I18n\Exception $exception) { throw new ViewHelper\Exception(sprintf('An error occurred while trying to format the given date/time: "%s"', $exception->getMessage()), 1342610987, $exception); } return $return; }
/** * Set the locale according to the user settings * * @return void */ protected function initializeObject() { $this->_localizationService->getConfiguration()->setCurrentLocale(new \TYPO3\Flow\I18n\Locale($this->_userService->getInterfaceLanguage())); }
/** * @return \TYPO3\Flow\I18n\Locale */ public function getLocale() { return $this->i18nService->getConfiguration()->getCurrentLocale(); }
/** * Tries to parse the input using the NumberParser. * * @param string $source * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return float|\TYPO3\Flow\Validation\Error Parsed float number or error * @throws \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException */ protected function parseUsingLocaleIfConfigured($source, \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration) { $configuration = $this->getConfigurationKeysAndValues($configuration, array('locale', 'strictMode', 'formatLength', 'formatType')); if ($configuration['locale'] === NULL) { return $source; } elseif ($configuration['locale'] === TRUE) { $locale = $this->localizationService->getConfiguration()->getCurrentLocale(); } elseif (is_string($configuration['locale'])) { $locale = new \TYPO3\Flow\I18n\Locale($configuration['locale']); } elseif ($configuration['locale'] instanceof \TYPO3\Flow\I18n\Locale) { $locale = $configuration['locale']; } if (!$locale instanceof \TYPO3\Flow\I18n\Locale) { $exceptionMessage = 'Determined locale is not of type "\\TYPO3\\Flow\\I18n\\Locale", but of type "' . (is_object($locale) ? get_class($locale) : gettype($locale)) . '".'; throw new InvalidPropertyMappingConfigurationException($exceptionMessage, 1334837413); } if ($configuration['strictMode'] === NULL || $configuration['strictMode'] === TRUE) { $strictMode = TRUE; } else { $strictMode = FALSE; } if ($configuration['formatLength'] !== NULL) { $formatLength = $configuration['formatLength']; NumbersReader::validateFormatLength($formatLength); } else { $formatLength = NumbersReader::FORMAT_LENGTH_DEFAULT; } if ($configuration['formatType'] !== NULL) { $formatType = $configuration['formatType']; \TYPO3\Flow\I18n\Cldr\Reader\NumbersReader::validateFormatType($formatType); } else { $formatType = NumbersReader::FORMAT_TYPE_DECIMAL; } if ($formatType === NumbersReader::FORMAT_TYPE_PERCENT) { $return = $this->numberParser->parsePercentNumber($source, $locale, $formatLength, $strictMode); if ($return === FALSE) { $return = new Error('A valid percent number is expected.', 1334839253); } } else { $return = $this->numberParser->parseDecimalNumber($source, $locale, $formatLength, $strictMode); if ($return === FALSE) { $return = new Error('A valid decimal number is expected.', 1334839260); } } return $return; }