%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; } }