}
$data = false;
foreach ($this->pathStack as $path) {
if (file_exists($path . '/' . $filename)) {
// Load current file with parent data, if necessary:
$current = $this->loadParentData(
$this->reader->getTextDomain($path . '/' . $filename)
);
if ($data === false) {
$data = $current;
} else {
$data->merge($current);
}
}
}
if ($data === false) {
// Should we throw an exception? If not, return an empty result:
if ($failOnError) {
throw new InvalidArgumentException(
"Ini file '{$filename}' not found"
);
}
return new TextDomain();
}
return $data;
}
/**
* Support method for loadLanguageFile: retrieve parent data.
*
* @param TextDomain $data TextDomain to populate with parent information.
*
* @return TextDomain
*/
protected function loadParentData($data)
{
if (!isset($data['@parent_ini'])) {
return $data;
$this->loadedFiles[$filename] = true;
return false;
}
/**
* Load the language file for a given locale and domain.
*
* @param string $locale Locale name
* @param string $domain Text domain (if any)
*
* @return TextDomain
*/
protected function loadLanguageLocale($locale, $domain)
{
$filename = $this->getLanguageFilename($locale, $domain);
// Load the language file, and throw a fatal exception if it's missing
// and we're not dealing with text domains. A missing base file is an
// unexpected, fatal error; a missing domain-specific file is more likely
// due to the possibility of incomplete translations.
return $this->loadLanguageFile($filename, empty($domain));
}
/**
* Search the path stack for language files and merge them together.
*
* @param string $filename Name of file to search path stack for.
* @param bool $failOnError If true, throw an exception when file not found.
*
* @return TextDomain
*/
protected function loadLanguageFile($filename, $failOnError = true)
{
// Don't load a file that has already been loaded:
if ($this->checkAndMarkLoadedFile($filename)) {
return new TextDomain();
}
$data = false;
foreach ($this->pathStack as $path) {
if (file_exists($path . '/' . $filename)) {
$this->pathStack = array_merge($this->pathStack, (array)$pathStack);
}
/**
* Load method defined by FileLoaderInterface.
*
* @param string $locale Locale to read from language file
* @param string $filename Relative base path for language file (used for
* loading text domains; optional)
*
* @return TextDomain
* @throws InvalidArgumentException
*/
public function load($locale, $filename)
{
// Reset the loaded files list:
$this->resetLoadedFiles();
// Load base data:
$data = $this->loadLanguageLocale($locale, $filename);
// Load fallback data, if any:
if (!empty($this->fallbackLocales)) {
foreach ($this->fallbackLocales as $fallbackLocale) {
$newData = $this->loadLanguageLocale($fallbackLocale, $filename);
$newData->merge($data);
$data = $newData;
}
}
return $data;
}
/**
* Get the language file name for a language and domain
*
* @param string $locale Locale name
* @param string $domain Text domain (if any)
*
* @return string
protected function loadMessagesFromFiles($textDomain, $locale)
{
$messagesLoaded = false;
foreach ([$locale, '*'] as $currentLocale) {
if (! isset($this->files[$textDomain][$currentLocale])) {
continue;
}
foreach ($this->files[$textDomain][$currentLocale] as $file) {
$loader = $this->getPluginManager()->get($file['type']);
if (! $loader instanceof FileLoaderInterface) {
throw new Exception\RuntimeException('Specified loader is not a file loader');
}
if (isset($this->messages[$textDomain][$locale])) {
$this->messages[$textDomain][$locale]->merge($loader->load($locale, $file['filename']));
} else {
$this->messages[$textDomain][$locale] = $loader->load($locale, $file['filename']);
}
$messagesLoaded = true;
}
unset($this->files[$textDomain][$currentLocale]);
}
return $messagesLoaded;
}
/**
* Return all the messages.
*
* @param string $textDomain
* @param string|null $locale
* @return mixed
*/
public function getAllMessages($textDomain = 'default', $locale = null)
{
protected function loadMessages($textDomain, $locale)
{
if (! isset($this->messages[$textDomain])) {
$this->messages[$textDomain] = [];
}
if (null !== ($cache = $this->getCache())) {
$cacheId = $this->getCacheId($textDomain, $locale);
if (null !== ($result = $cache->getItem($cacheId))) {
$this->messages[$textDomain][$locale] = $result;
return;
}
}
$messagesLoaded = false;
$messagesLoaded |= $this->loadMessagesFromRemote($textDomain, $locale);
$messagesLoaded |= $this->loadMessagesFromPatterns($textDomain, $locale);
$messagesLoaded |= $this->loadMessagesFromFiles($textDomain, $locale);
if (! $messagesLoaded) {
$discoveredTextDomain = null;
if ($this->isEventManagerEnabled()) {
$until = static function ($r) {
return ($r instanceof TextDomain);
};
$event = new Event(self::EVENT_NO_MESSAGES_LOADED, $this, [
'locale' => $locale,
'text_domain' => $textDomain,
]);
$results = $this->getEventManager()->triggerEventUntil($until, $event);
$last = $results->last();
if ($last instanceof TextDomain) {
$discoveredTextDomain = $last;
}
}
/**
* Get a translated message.
*
* @triggers getTranslatedMessage.missing-translation
* @param string $message
* @param string $locale
* @param string $textDomain
* @return string|null
*/
protected function getTranslatedMessage(
$message,
$locale,
$textDomain = 'default'
) {
if ($message === '' || $message === null) {
return '';
}
if (! isset($this->messages[$textDomain][$locale])) {
$this->loadMessages($textDomain, $locale);
}
if (isset($this->messages[$textDomain][$locale][$message])) {
return $this->messages[$textDomain][$locale][$message];
}
/**
* issue https://github.com/zendframework/zend-i18n/issues/53
*
* storage: array:8 [▼
* "default\x04Welcome" => "Cześć"
* "default\x04Top %s Product" => array:3 [▼
* 0 => "Top %s Produkt"
* 1 => "Top %s Produkty"
* 2 => "Top %s Produktów"
* ]
* "Top %s Products" => ""
* ]
*/
{
if (! $this->pluginManager instanceof LoaderPluginManager) {
$this->setPluginManager(new LoaderPluginManager(new ServiceManager));
}
return $this->pluginManager;
}
/**
* Translate a message.
*
* @param string $message
* @param string $textDomain
* @param string|null $locale
* @return string
*/
public function translate($message, $textDomain = 'default', $locale = null)
{
$locale = ($locale ?: $this->getLocale());
$translation = $this->getTranslatedMessage($message, $locale, $textDomain);
if ($translation !== null && $translation !== '') {
return $translation;
}
if (null !== ($fallbackLocale = $this->getFallbackLocale())
&& $locale !== $fallbackLocale
) {
return $this->translate($message, $textDomain, $fallbackLocale);
}
return $message;
}
/**
* Translate a plural message.
*
* @param string $singular
* @param string $plural
* @param int $number
/**
* @return I18nTranslatorInterface
*/
public function getTranslator()
{
return $this->translator;
}
/**
* Translate a message using the given text domain and locale
*
* @param string $message
* @param string $textDomain
* @param string $locale
* @return string
*/
public function translate($message, $textDomain = 'default', $locale = null)
{
return $this->translator->translate($message, $textDomain, $locale);
}
/**
* Provide a pluralized translation of the given string using the given text domain and locale
*
* @param string $singular
* @param string $plural
* @param string $number
* @param string $textDomain
* @param string $locale
* @return string
*/
public function translatePlural($singular, $plural, $number, $textDomain = 'default', $locale = null)
{
return $this->translator->translatePlural($singular, $plural, $number, $textDomain, $locale);
}
}
}
return $this->translate($target, $tokens, $default);
}
/**
* Get translation for a string
*
* @param string $str String to translate
* @param array $tokens Tokens to inject into the translated string
* @param string $default Default value to use if no translation is found
* (null for no default).
* @param string $domain Text domain (omit for default)
*
* @return string
*/
protected function translateString($str, $tokens = [], $default = null,
$domain = 'default'
) {
$msg = (null === $this->translator)
? $str : $this->translator->translate($str, $domain);
// Did the translation fail to change anything? If so, use default:
if (null !== $default && $msg == $str) {
$msg = $default instanceof \VuFind\I18n\TranslatableStringInterface
? $default->getDisplayString() : $default;
}
// Do we need to perform substitutions?
if (!empty($tokens)) {
$in = $out = [];
foreach ($tokens as $key => $value) {
$in[] = $key;
$out[] = $value;
}
$msg = str_replace($in, $out, $msg);
}
return $msg;
}
->translateString((string)$str, $tokens, null, $domain);
if ($translated !== (string)$str) {
return $translated;
}
// Override $domain/$str using getDisplayString() before proceeding:
$str = $str->getDisplayString();
// Also the display string can be a TranslatableString. This makes it
// possible have multiple levels of translatable values while still
// providing a sane default string if translation is not found. Used at
// least with hierarchical facets where translation key can be the exact
// facet value (e.g. "0/Book/") or a displayable value (e.g. "Book").
if ($str instanceof \VuFind\I18n\TranslatableStringInterface) {
return $this->translate($str, $tokens, $default);
} else {
list($domain, $str) = $this->extractTextDomain($str);
}
}
// Default case: deal with ordinary strings (or string-castable objects):
return $this->translateString((string)$str, $tokens, $default, $domain);
}
/**
* Translate a string (or string-castable object) using a prefix, or without the
* prefix if a prefixed translation is not found.
*
* @param string $prefix Translation key prefix
* @param string|object|array $target String to translate or an array of text
* domain and string to translate
* @param array $tokens Tokens to inject into the translated
* string
* @param string $default Default value to use if no translation is
* found (null for no default).
*
* @return string
*/
public function translateWithPrefix($prefix, $target, $tokens = [],
$default = null
) {
if (is_string($target)) {
* @link https://vufind.org/wiki/development Wiki
*/
class Translate extends \Laminas\View\Helper\AbstractHelper
implements \VuFind\I18n\Translator\TranslatorAwareInterface
{
use \VuFind\I18n\Translator\TranslatorAwareTrait;
/**
* Translate a string
*
* @param string|object $str String to translate
* @param array $tokens Tokens to inject into the translated string
* @param string $default Default value to use if no translation is found
* (null for no default).
*
* @return string
*/
public function __invoke($str, $tokens = [], $default = null)
{
return $this->translate($str, $tokens, $default);
}
}
/**
* Overloading: proxy to helpers
*
* Proxies to the attached plugin manager to retrieve, return, and potentially
* execute helpers.
*
* * If the helper does not define __invoke, it will be returned
* * If the helper does define __invoke, it will be called as a functor
*
* @param string $method
* @param array $argv
* @return mixed
*/
public function __call($method, $argv)
{
$plugin = $this->plugin($method);
if (is_callable($plugin)) {
return call_user_func_array($plugin, $argv);
}
return $plugin;
}
/**
* Set filter chain
*
* @param FilterChain $filters
* @return PhpRenderer
*/
public function setFilterChain(FilterChain $filters)
{
$this->__filterChain = $filters;
return $this;
}
/**
* Retrieve filter chain for post-filtering script content
*
/**
* Overloading: proxy to helpers
*
* Proxies to the attached plugin manager to retrieve, return, and potentially
* execute helpers.
*
* * If the helper does not define __invoke, it will be returned
* * If the helper does define __invoke, it will be called as a functor
*
* @param string $method
* @param array $argv
* @return mixed
*/
public function __call($method, $argv)
{
$plugin = $this->plugin($method);
if (is_callable($plugin)) {
return call_user_func_array($plugin, $argv);
}
return $plugin;
}
/**
* Set filter chain
*
* @param FilterChain $filters
* @return PhpRenderer
*/
public function setFilterChain(FilterChain $filters)
{
$this->__filterChain = $filters;
return $this;
}
/**
* Retrieve filter chain for post-filtering script content
*
<?php $this->headTitle($this->translate('Help')); ?>
<?php if ($help = $this->helpText()->render($topic)): ?>
<?php foreach ($this->helpText()->getWarnings() as $warning): ?>
<p class="alert alert-warning"><?=$this->transEsc($warning)?></p>
<?php endforeach; ?>
<?=$help?>
<?php else: ?>
<p class="alert alert-danger"><?=$this->transEsc('help_page_missing')?></p>
<?php endif; ?>
$__vars = $this->vars()->getArrayCopy();
if (array_key_exists('this', $__vars)) {
unset($__vars['this']);
}
extract($__vars);
unset($__vars); // remove $__vars from local scope
$this->__content = '';
while ($this->__template = array_pop($this->__templates)) {
$this->__file = $this->resolver($this->__template);
if (! $this->__file) {
throw new Exception\RuntimeException(sprintf(
'%s: Unable to render template "%s"; resolver could not resolve to a file',
__METHOD__,
$this->__template
));
}
try {
ob_start();
$includeReturn = include $this->__file;
$this->__content = ob_get_clean();
} catch (\Throwable $ex) {
ob_end_clean();
throw $ex;
} catch (\Exception $ex) { // @TODO clean up once PHP 7 requirement is enforced
ob_end_clean();
throw $ex;
}
if ($includeReturn === false && empty($this->__content)) {
throw new Exception\UnexpectedValueException(sprintf(
'%s: Unable to render template "%s"; file include failed',
__METHOD__,
$this->__file
));
}
}
$this->setVars(array_pop($this->__varsCache));
if ($this->__filterChain instanceof FilterChain) {
// If EVENT_RENDERER or EVENT_RENDERER_POST changed the model, make sure
// we use this new model instead of the current $model
$model = $event->getModel();
// If we have children, render them first, but only if:
// a) the renderer does not implement TreeRendererInterface, or
// b) it does, but canRenderTrees() returns false
if ($model->hasChildren()
&& (! $renderer instanceof TreeRendererInterface
|| ! $renderer->canRenderTrees())
) {
$this->renderChildren($model);
}
// Reset the model, in case it has changed, and set the renderer
$event->setModel($model);
$event->setRenderer($renderer);
$rendered = $renderer->render($model);
// If this is a child model, return the rendered content; do not
// invoke the response strategy.
$options = $model->getOptions();
if (array_key_exists('has_parent', $options) && $options['has_parent']) {
return $rendered;
}
$event->setResult($rendered);
$event->setName(ViewEvent::EVENT_RESPONSE);
$events->triggerEvent($event);
}
/**
* Loop through children, rendering each
*
* @param Model $model
* @throws Exception\DomainException
* @return void
$event->setName(ViewEvent::EVENT_RESPONSE);
$events->triggerEvent($event);
}
/**
* Loop through children, rendering each
*
* @param Model $model
* @throws Exception\DomainException
* @return void
*/
protected function renderChildren(Model $model)
{
foreach ($model as $child) {
if ($child->terminate()) {
throw new Exception\DomainException('Inconsistent state; child view model is marked as terminal');
}
$child->setOption('has_parent', true);
$result = $this->render($child);
$child->setOption('has_parent', null);
$capture = $child->captureTo();
if (! empty($capture)) {
if ($child->isAppend()) {
$oldResult = $model->{$capture};
$model->setVariable($capture, $oldResult . $result);
} else {
$model->setVariable($capture, $result);
}
}
}
}
/**
* Create and return ViewEvent used by render()
*
* @return ViewEvent
*/
protected function getEvent()
{
__METHOD__
));
}
$event->setRenderer($renderer);
$event->setName(ViewEvent::EVENT_RENDERER_POST);
$events->triggerEvent($event);
// If EVENT_RENDERER or EVENT_RENDERER_POST changed the model, make sure
// we use this new model instead of the current $model
$model = $event->getModel();
// If we have children, render them first, but only if:
// a) the renderer does not implement TreeRendererInterface, or
// b) it does, but canRenderTrees() returns false
if ($model->hasChildren()
&& (! $renderer instanceof TreeRendererInterface
|| ! $renderer->canRenderTrees())
) {
$this->renderChildren($model);
}
// Reset the model, in case it has changed, and set the renderer
$event->setModel($model);
$event->setRenderer($renderer);
$rendered = $renderer->render($model);
// If this is a child model, return the rendered content; do not
// invoke the response strategy.
$options = $model->getOptions();
if (array_key_exists('has_parent', $options) && $options['has_parent']) {
return $rendered;
}
$event->setResult($rendered);
$event->setName(ViewEvent::EVENT_RESPONSE);
$events->triggerEvent($event);
}
if ($result instanceof Response) {
return $result;
}
// Martial arguments
$request = $e->getRequest();
$response = $e->getResponse();
$viewModel = $e->getViewModel();
if (! $viewModel instanceof ViewModel) {
return;
}
$view = $this->view;
$view->setRequest($request);
$view->setResponse($response);
$caughtException = null;
try {
$view->render($viewModel);
} catch (\Throwable $ex) {
$caughtException = $ex;
} catch (\Exception $ex) { // @TODO clean up once PHP 7 requirement is enforced
$caughtException = $ex;
}
if ($caughtException !== null) {
if ($e->getName() === MvcEvent::EVENT_RENDER_ERROR) {
throw $caughtException;
}
$application = $e->getApplication();
$events = $application->getEventManager();
$e->setError(Application::ERROR_EXCEPTION);
$e->setParam('exception', $caughtException);
$e->setName(MvcEvent::EVENT_RENDER_ERROR);
$events->triggerEvent($e);
}
}
if ($this->sharedManager) {
foreach ($this->sharedManager->getListeners($this->identifiers, $name) as $priority => $listeners) {
$listOfListenersByPriority[$priority][] = $listeners;
}
}
// Sort by priority in reverse order
krsort($listOfListenersByPriority);
// Initial value of stop propagation flag should be false
$event->stopPropagation(false);
// Execute listeners
$responses = new ResponseCollection();
foreach ($listOfListenersByPriority as $listOfListeners) {
foreach ($listOfListeners as $listeners) {
foreach ($listeners as $listener) {
$response = $listener($event);
$responses->push($response);
// If the event was asked to stop propagating, do so
if ($event->propagationIsStopped()) {
$responses->setStopped(true);
return $responses;
}
// If the result causes our validation callback to return true,
// stop propagation
if ($callback && $callback($response)) {
$responses->setStopped(true);
return $responses;
}
}
}
}
return $responses;
}
$event = clone $this->eventPrototype;
$event->setName($eventName);
if ($target !== null) {
$event->setTarget($target);
}
if ($argv) {
$event->setParams($argv);
}
return $this->triggerListeners($event, $callback);
}
/**
* @inheritDoc
*/
public function triggerEvent(EventInterface $event)
{
return $this->triggerListeners($event);
}
/**
* @inheritDoc
*/
public function triggerEventUntil(callable $callback, EventInterface $event)
{
return $this->triggerListeners($event, $callback);
}
/**
* @inheritDoc
*/
public function attach($eventName, callable $listener, $priority = 1)
{
if (! is_string($eventName)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a string for the event; received %s',
__METHOD__,
(is_object($eventName) ? get_class($eventName) : gettype($eventName))
return $this->completeRequest($event);
}
/**
* Complete the request
*
* Triggers "render" and "finish" events, and returns response from
* event object.
*
* @param MvcEvent $event
* @return Application
*/
protected function completeRequest(MvcEvent $event)
{
$events = $this->events;
$event->setTarget($this);
$event->setName(MvcEvent::EVENT_RENDER);
$event->stopPropagation(false); // Clear before triggering
$events->triggerEvent($event);
$event->setName(MvcEvent::EVENT_FINISH);
$event->stopPropagation(false); // Clear before triggering
$events->triggerEvent($event);
return $this;
}
}
// Trigger dispatch event
$event->setName(MvcEvent::EVENT_DISPATCH);
$event->stopPropagation(false); // Clear before triggering
$result = $events->triggerEventUntil($shortCircuit, $event);
// Complete response
$response = $result->last();
if ($response instanceof ResponseInterface) {
$event->setName(MvcEvent::EVENT_FINISH);
$event->setTarget($this);
$event->setResponse($response);
$event->stopPropagation(false); // Clear before triggering
$events->triggerEvent($event);
$this->response = $response;
return $this;
}
$response = $this->response;
$event->setResponse($response);
return $this->completeRequest($event);
}
/**
* Complete the request
*
* Triggers "render" and "finish" events, and returns response from
* event object.
*
* @param MvcEvent $event
* @return Application
*/
protected function completeRequest(MvcEvent $event)
{
$events = $this->events;
$event->setTarget($this);
$event->setName(MvcEvent::EVENT_RENDER);
$event->stopPropagation(false); // Clear before triggering
$events->triggerEvent($event);
$pathParts[] = APPLICATION_PATH . '/vendor';
$pathParts[] = get_include_path();
set_include_path(implode(PATH_SEPARATOR, $pathParts));
// Composer autoloading
if (file_exists('vendor/autoload.php')) {
$loader = include 'vendor/autoload.php';
}
if (!class_exists('Laminas\Loader\AutoloaderFactory')) {
throw new RuntimeException('Unable to load Laminas autoloader.');
}
// Run the application!
$app = Laminas\Mvc\Application::init(require 'config/application.config.php');
if (PHP_SAPI === 'cli') {
return $app->getServiceManager()
->get(\VuFindConsole\ConsoleRunner::class)->run();
} else {
$app->run();
}