%PDF- %PDF-
| Direktori : /www/varak.net/losik.varak.net/vendor/nette/application/src/Application/ |
| Current File : /www/varak.net/losik.varak.net/vendor/nette/application/src/Application/PresenterFactory.php |
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Nette\Application;
use Nette;
/**
* Default presenter loader.
*/
class PresenterFactory implements IPresenterFactory
{
use Nette\SmartObject;
/** @var array[] of module => splited mask */
private $mapping = [
'*' => ['', '*Module\\', '*Presenter'],
'Nette' => ['NetteModule\\', '*\\', '*Presenter'],
];
/** @var array */
private $cache = [];
/** @var callable */
private $factory;
/**
* @param callable(string): IPresenter $factory
*/
public function __construct(?callable $factory = null)
{
$this->factory = $factory ?: function (string $class): IPresenter { return new $class; };
}
/**
* Creates new presenter instance.
*/
public function createPresenter(string $name): IPresenter
{
return ($this->factory)($this->getPresenterClass($name));
}
/**
* Generates and checks presenter class name.
* @throws InvalidPresenterException
*/
public function getPresenterClass(string &$name): string
{
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
if (!Nette\Utils\Strings::match($name, '#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*$#D')) {
throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");
}
$class = $this->formatPresenterClass($name);
if (!class_exists($class)) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found.");
}
$reflection = new \ReflectionClass($class);
$class = $reflection->getName();
if (!$reflection->implementsInterface(IPresenter::class)) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");
} elseif ($reflection->isAbstract()) {
throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");
}
return $this->cache[$name] = $class;
}
/**
* Sets mapping as pairs [module => mask]
* @return static
*/
public function setMapping(array $mapping)
{
foreach ($mapping as $module => $mask) {
if (is_string($mask)) {
if (!preg_match('#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)$#D', $mask, $m)) {
throw new Nette\InvalidStateException("Invalid mapping mask '$mask'.");
}
$this->mapping[$module] = [$m[1], $m[2] ?: '*Module\\', $m[3]];
} elseif (is_array($mask) && count($mask) === 3) {
$this->mapping[$module] = [$mask[0] ? $mask[0] . '\\' : '', $mask[1] . '\\', $mask[2]];
} else {
throw new Nette\InvalidStateException("Invalid mapping mask for module $module.");
}
}
return $this;
}
/**
* Formats presenter class name from its name.
* @internal
*/
public function formatPresenterClass(string $presenter): string
{
$parts = explode(':', $presenter);
$mapping = isset($parts[1], $this->mapping[$parts[0]])
? $this->mapping[array_shift($parts)]
: $this->mapping['*'];
while ($part = array_shift($parts)) {
$mapping[0] .= str_replace('*', $part, $mapping[$parts ? 1 : 2]);
}
return $mapping[0];
}
/**
* Formats presenter name from class name.
* @internal
*/
public function unformatPresenterClass(string $class): ?string
{
trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED);
foreach ($this->mapping as $module => $mapping) {
$mapping = str_replace(['\\', '*'], ['\\\\', '(\w+)'], $mapping);
if (preg_match("#^\\\\?$mapping[0]((?:$mapping[1])*)$mapping[2]$#Di", $class, $matches)) {
return ($module === '*' ? '' : $module . ':')
. preg_replace("#$mapping[1]#iA", '$1:', $matches[1]) . $matches[3];
}
}
return null;
}
}