From 7eae7a7326897d574c649351f6f053e5234f393f Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 6 Apr 2024 18:58:09 +0200 Subject: [PATCH 01/23] tests: simplified tests --- ....control.phpt => UIExtension.nonce.control.phpt} | 13 +++---------- ...senter.phpt => UIExtension.nonce.presenter.phpt} | 13 +++---------- tests/Bridges.Latte3/expected/isLinkCurrent.php | 2 +- tests/Bridges.Latte3/isLinkCurrent().phpt | 10 ++-------- tests/Bridges.Latte3/{ifCurrent}.phpt | 8 ++------ 5 files changed, 11 insertions(+), 35 deletions(-) rename tests/Bridges.Latte3/{TemplateFactory.nonce.control.phpt => UIExtension.nonce.control.phpt} (70%) rename tests/Bridges.Latte3/{TemplateFactory.nonce.presenter.phpt => UIExtension.nonce.presenter.phpt} (74%) diff --git a/tests/Bridges.Latte3/TemplateFactory.nonce.control.phpt b/tests/Bridges.Latte3/UIExtension.nonce.control.phpt similarity index 70% rename from tests/Bridges.Latte3/TemplateFactory.nonce.control.phpt rename to tests/Bridges.Latte3/UIExtension.nonce.control.phpt index 2a7c94cb2..9248da8af 100644 --- a/tests/Bridges.Latte3/TemplateFactory.nonce.control.phpt +++ b/tests/Bridges.Latte3/UIExtension.nonce.control.phpt @@ -1,13 +1,12 @@ shouldReceive('create')->andReturn($latte); - $response = Mockery::mock(Nette\Http\IResponse::class); $response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); @@ -28,10 +22,9 @@ $control = Mockery::mock(UI\Control::class); $control->shouldReceive('getPresenterIfExists')->andReturn(null); $control->shouldIgnoreMissing(); -$factory = new ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($control); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($control)); Assert::match( '', diff --git a/tests/Bridges.Latte3/TemplateFactory.nonce.presenter.phpt b/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt similarity index 74% rename from tests/Bridges.Latte3/TemplateFactory.nonce.presenter.phpt rename to tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt index 23297efce..2f2a8d254 100644 --- a/tests/Bridges.Latte3/TemplateFactory.nonce.presenter.phpt +++ b/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt @@ -1,13 +1,12 @@ shouldReceive('create')->andReturn($latte); - $response = Mockery::mock(Nette\Http\IResponse::class); $response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); @@ -31,10 +25,9 @@ $presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); $presenter->shouldReceive('getHttpResponse')->andReturn($response); $presenter->shouldIgnoreMissing(); -$factory = new ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($presenter)); Assert::match( '', diff --git a/tests/Bridges.Latte3/expected/isLinkCurrent.php b/tests/Bridges.Latte3/expected/isLinkCurrent.php index 3871205c8..a86390a52 100644 --- a/tests/Bridges.Latte3/expected/isLinkCurrent.php +++ b/tests/Bridges.Latte3/expected/isLinkCurrent.php @@ -26,7 +26,7 @@ global->fn->isLinkCurrent)('default') ? 'current' : null])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line 9 */; + echo ($ʟ_tmp = array_filter([($this->global->fn->isLinkCurrent)(%a%'default') ? 'current' : null])) ? ' class="' . LR\Filters::escapeHtmlAttr(implode(" ", array_unique($ʟ_tmp))) . '"' : "" /* line 9 */; echo '>custom function '; %A% diff --git a/tests/Bridges.Latte3/isLinkCurrent().phpt b/tests/Bridges.Latte3/isLinkCurrent().phpt index b297db9bd..1ca37dcb3 100644 --- a/tests/Bridges.Latte3/isLinkCurrent().phpt +++ b/tests/Bridges.Latte3/isLinkCurrent().phpt @@ -16,20 +16,14 @@ if (version_compare(Latte\Engine::VERSION, '3', '<')) { Tester\Environment::bypassFinals(); -$latte = new Latte\Engine; - -$latteFactory = Mockery::mock(Nette\Bridges\ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); $presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); $presenter->shouldReceive('getHttpResponse')->andReturn((Mockery::mock(Nette\Http\IResponse::class))->shouldIgnoreMissing()); $presenter->shouldIgnoreMissing(); -$factory = new Nette\Bridges\ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($presenter)); Assert::matchFile( __DIR__ . '/expected/isLinkCurrent.php', diff --git a/tests/Bridges.Latte3/{ifCurrent}.phpt b/tests/Bridges.Latte3/{ifCurrent}.phpt index 2d2451c50..3c9ee133e 100644 --- a/tests/Bridges.Latte3/{ifCurrent}.phpt +++ b/tests/Bridges.Latte3/{ifCurrent}.phpt @@ -14,18 +14,14 @@ Tester\Environment::bypassFinals(); $latte = new Latte\Engine; -$latteFactory = Mockery::mock(Nette\Bridges\ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); $presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); $presenter->shouldReceive('getHttpResponse')->andReturn((Mockery::mock(Nette\Http\IResponse::class))->shouldIgnoreMissing()); $presenter->shouldIgnoreMissing(); -$factory = new Nette\Bridges\ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - +$latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension($presenter)); Assert::matchFile( __DIR__ . '/expected/ifCurrent.php', From a795f73d64a8048593d49da700c858cd125a0dd4 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 18 Mar 2024 15:18:05 +0100 Subject: [PATCH 02/23] Control::flashMessage() enhanced type hint --- src/Application/UI/Control.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Application/UI/Control.php b/src/Application/UI/Control.php index 7c1141a09..a768fa550 100644 --- a/src/Application/UI/Control.php +++ b/src/Application/UI/Control.php @@ -90,7 +90,7 @@ public function templatePrepareFilters(Template $template): void /** * Saves the message to template, that can be displayed after redirect. */ - public function flashMessage(string|\stdClass|Nette\HtmlStringable $message, string $type = 'info'): \stdClass + public function flashMessage(string|\stdClass|\Stringable $message, string $type = 'info'): \stdClass { $id = $this->getParameterId('flash'); $flash = $message instanceof \stdClass ? $message : (object) [ From e7425684861f0ccdd8fd9707ea1a1f3e1649980d Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 27 Mar 2024 18:59:43 +0100 Subject: [PATCH 03/23] Revert "ApplicationExtension: $catchExceptions can be '4xx' in addition to bool" This reverts commit d16847f445e683fc6b7be9d233652b2532ac9a97. --- src/Bridges/ApplicationDI/ApplicationExtension.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Bridges/ApplicationDI/ApplicationExtension.php b/src/Bridges/ApplicationDI/ApplicationExtension.php index fcf8ce463..4591cef68 100644 --- a/src/Bridges/ApplicationDI/ApplicationExtension.php +++ b/src/Bridges/ApplicationDI/ApplicationExtension.php @@ -47,7 +47,7 @@ public function getConfigSchema(): Nette\Schema\Schema ])->castTo('array'), Expect::string()->dynamic(), )->firstIsDefault(), - 'catchExceptions' => Expect::anyOf('4xx', true, false)->firstIsDefault()->dynamic(), + 'catchExceptions' => Expect::bool(false)->dynamic(), 'mapping' => Expect::anyOf( Expect::string(), Expect::arrayOf('string|array'), @@ -77,8 +77,6 @@ public function loadConfiguration(): void ->setFactory(Nette\Application\Application::class); if ($config->catchExceptions || !$this->debugMode) { $application->addSetup('$error4xxPresenter', [is_array($config->errorPresenter) ? $config->errorPresenter['4xx'] : $config->errorPresenter]); - } - if ($config->catchExceptions === true || !$this->debugMode) { $application->addSetup('$errorPresenter', [is_array($config->errorPresenter) ? $config->errorPresenter['5xx'] : $config->errorPresenter]); } From 6833458cb2921b11db4a8496f6f9f95b7a07b42b Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 6 Apr 2024 17:37:58 +0200 Subject: [PATCH 04/23] Latte: |modifyDate moved to UIExtension --- .../ApplicationLatte/TemplateFactory.php | 9 ++++--- src/Bridges/ApplicationLatte/UIExtension.php | 10 ++++++++ ....filters.phpt => UIExtension.filters.phpt} | 25 +++---------------- 3 files changed, 18 insertions(+), 26 deletions(-) rename tests/Bridges.Latte3/{TemplateFactory.filters.phpt => UIExtension.filters.phpt} (63%) diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index bc7b0c042..d194a1c55 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -66,10 +66,6 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul } } - $latte->addFilter('modifyDate', fn($time, $delta, $unit = null) => $time - ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) - : null); - if (!isset($latte->getFilters()['translate'])) { $latte->addFilter('translate', function (Latte\Runtime\FilterInfo $fi): void { throw new Nette\InvalidStateException('Translator has not been set. Set translator using $template->setTranslator().'); @@ -148,5 +144,10 @@ private function setupLatte2( $latte->addFunction('isLinkCurrent', [$presenter, 'isLinkCurrent']); $latte->addFunction('isModuleCurrent', [$presenter, 'isModuleCurrent']); } + + $latte->addFilter('modifyDate', fn($time, $delta, $unit = null) => $time + ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) + : null); + } } diff --git a/src/Bridges/ApplicationLatte/UIExtension.php b/src/Bridges/ApplicationLatte/UIExtension.php index 2071a69fd..bc18af2bc 100644 --- a/src/Bridges/ApplicationLatte/UIExtension.php +++ b/src/Bridges/ApplicationLatte/UIExtension.php @@ -29,6 +29,16 @@ public function __construct( } + public function getFilters(): array + { + return [ + 'modifyDate' => fn($time, $delta, $unit = null) => $time + ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) + : null, + ]; + } + + public function getFunctions(): array { if ($presenter = $this->control?->getPresenterIfExists()) { diff --git a/tests/Bridges.Latte3/TemplateFactory.filters.phpt b/tests/Bridges.Latte3/UIExtension.filters.phpt similarity index 63% rename from tests/Bridges.Latte3/TemplateFactory.filters.phpt rename to tests/Bridges.Latte3/UIExtension.filters.phpt index 27d45ba94..952f5a760 100644 --- a/tests/Bridges.Latte3/TemplateFactory.filters.phpt +++ b/tests/Bridges.Latte3/UIExtension.filters.phpt @@ -1,12 +1,11 @@ engine = $engine; - } - - - public function create(): Latte\Engine - { - return $this->engine; - } -} - -$factory = new TemplateFactory(new LatteFactory(new Latte\Engine)); -$latte = $factory->createTemplate()->getLatte(); - +$latte = new Latte\Engine; +$latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(null)); setlocale(LC_TIME, 'C'); date_default_timezone_set('Europe/Prague'); From 436fd041a4dd1f5ba349b9b87f9a3ee5ca029b06 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 6 Apr 2024 17:41:19 +0200 Subject: [PATCH 05/23] Latte: removed error message for missing |translate Warning doesn't catch that {_} doesn't work either --- src/Bridges/ApplicationLatte/TemplateFactory.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index d194a1c55..5c2381864 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -66,12 +66,6 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul } } - if (!isset($latte->getFilters()['translate'])) { - $latte->addFilter('translate', function (Latte\Runtime\FilterInfo $fi): void { - throw new Nette\InvalidStateException('Translator has not been set. Set translator using $template->setTranslator().'); - }); - } - // default parameters $baseUrl = $this->httpRequest ? rtrim($this->httpRequest->getUrl()->withoutUserInfo()->getBaseUrl(), '/') From 0c584358b155dd27cc674e5a56553a9c05d73365 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 6 Apr 2024 17:54:06 +0200 Subject: [PATCH 06/23] Latte: CacheExtension & FormExtension are added before user extensions [Closes #320] https://forum.nette.org/cs/35525-latte-3-lze-ovlivnit-poradi-registrace-extension-v-config-neon --- src/Bridges/ApplicationDI/LatteExtension.php | 12 ++++++++++-- src/Bridges/ApplicationLatte/TemplateFactory.php | 9 --------- tests/Bridges.DI/LatteExtension.basic.phpt | 1 + 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Bridges/ApplicationDI/LatteExtension.php b/src/Bridges/ApplicationDI/LatteExtension.php index 6fffe737a..44e66888f 100644 --- a/src/Bridges/ApplicationDI/LatteExtension.php +++ b/src/Bridges/ApplicationDI/LatteExtension.php @@ -12,6 +12,7 @@ use Latte; use Nette; use Nette\Bridges\ApplicationLatte; +use Nette\DI\Definitions\Statement; use Nette\Schema\Expect; use Tracy; @@ -67,6 +68,13 @@ public function loadConfiguration(): void $latteFactory->addSetup('setStrictParsing', [$config->strictParsing]) ->addSetup('enablePhpLinter', [$config->phpLinter]); + if ($cache = $builder->getByType(Nette\Caching\Storage::class)) { + $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class, [$builder->getDefinition($cache)])); + } + if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) { + $this->addExtension(new Statement(Nette\Bridges\FormsLatte\FormsExtension::class)); + } + foreach ($config->extensions as $extension) { $this->addExtension($extension); } @@ -146,10 +154,10 @@ public function addMacro(string $macro): void } - public function addExtension(Nette\DI\Definitions\Statement|string $extension): void + public function addExtension(Statement|string $extension): void { $extension = is_string($extension) - ? new Nette\DI\Definitions\Statement($extension) + ? new Statement($extension) : $extension; $builder = $this->getContainerBuilder(); diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index 5c2381864..9fab76531 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -53,17 +53,8 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul if (version_compare(Latte\Engine::VERSION, '3', '<')) { $this->setupLatte2($latte, $control, $presenter, $template); - } else { $latte->addExtension(new UIExtension($control)); - - if ($this->cacheStorage && class_exists(Nette\Bridges\CacheLatte\CacheExtension::class)) { - $latte->addExtension(new Nette\Bridges\CacheLatte\CacheExtension($this->cacheStorage)); - } - - if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) { - $latte->addExtension(new Nette\Bridges\FormsLatte\FormsExtension); - } } // default parameters diff --git a/tests/Bridges.DI/LatteExtension.basic.phpt b/tests/Bridges.DI/LatteExtension.basic.phpt index 1ee2f1416..1e856d14a 100644 --- a/tests/Bridges.DI/LatteExtension.basic.phpt +++ b/tests/Bridges.DI/LatteExtension.basic.phpt @@ -66,6 +66,7 @@ $extensions = Assert::with($latte, fn() => $this->extensions); Assert::equal([ new Latte\Essential\CoreExtension, new Latte\Sandbox\SandboxExtension, + new Nette\Bridges\FormsLatte\FormsExtension, new MyExtension, new MyExtension(1), new MyExtension(2), From f6d36ec2a70a464bda036cbc3baecfdc3dc1f35b Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 11 Oct 2023 16:48:03 +0200 Subject: [PATCH 07/23] Latte: UIExtension is added before user extensions if $control is passed to LatteFactory::create() --- src/Bridges/ApplicationDI/LatteExtension.php | 4 ++++ src/Bridges/ApplicationLatte/LatteFactory.php | 2 +- src/Bridges/ApplicationLatte/TemplateFactory.php | 4 ++-- tests/Bridges.DI/LatteExtension.basic.phpt | 15 +++++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Bridges/ApplicationDI/LatteExtension.php b/src/Bridges/ApplicationDI/LatteExtension.php index 44e66888f..736dbd57a 100644 --- a/src/Bridges/ApplicationDI/LatteExtension.php +++ b/src/Bridges/ApplicationDI/LatteExtension.php @@ -68,6 +68,10 @@ public function loadConfiguration(): void $latteFactory->addSetup('setStrictParsing', [$config->strictParsing]) ->addSetup('enablePhpLinter', [$config->phpLinter]); + $builder->getDefinition($this->prefix('latteFactory')) + ->getResultDefinition() + ->addSetup('?', [$builder::literal('func_num_args() && $service->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(func_get_arg(0)))')]); + if ($cache = $builder->getByType(Nette\Caching\Storage::class)) { $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class, [$builder->getDefinition($cache)])); } diff --git a/src/Bridges/ApplicationLatte/LatteFactory.php b/src/Bridges/ApplicationLatte/LatteFactory.php index a215f3261..e6d2c8842 100644 --- a/src/Bridges/ApplicationLatte/LatteFactory.php +++ b/src/Bridges/ApplicationLatte/LatteFactory.php @@ -14,7 +14,7 @@ interface LatteFactory { - function create(): Latte\Engine; + function create(/*?Control $control = null*/): Latte\Engine; } diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index 9fab76531..2fdcbc9b4 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -47,13 +47,13 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul throw new Nette\InvalidArgumentException("Class $class does not implement " . Template::class . ' or it does not exist.'); } - $latte = $this->latteFactory->create(); + $latte = $this->latteFactory->create($control); $template = new $class($latte); $presenter = $control?->getPresenterIfExists(); if (version_compare(Latte\Engine::VERSION, '3', '<')) { $this->setupLatte2($latte, $control, $presenter, $template); - } else { + } elseif (!Nette\Utils\Arrays::some($latte->getExtensions(), fn($e) => $e instanceof UIExtension)) { $latte->addExtension(new UIExtension($control)); } diff --git a/tests/Bridges.DI/LatteExtension.basic.phpt b/tests/Bridges.DI/LatteExtension.basic.phpt index 1e856d14a..09dc0d292 100644 --- a/tests/Bridges.DI/LatteExtension.basic.phpt +++ b/tests/Bridges.DI/LatteExtension.basic.phpt @@ -72,3 +72,18 @@ Assert::equal([ new MyExtension(2), new MyExtension, ], $extensions); + +// UIExtension is added +$latte = $container->getService('nette.latteFactory')->create(null); +$extensions = Assert::with($latte, fn() => $this->extensions); + +Assert::equal([ + new Latte\Essential\CoreExtension, + new Latte\Sandbox\SandboxExtension, + new Nette\Bridges\ApplicationLatte\UIExtension(null), + new Nette\Bridges\FormsLatte\FormsExtension, + new MyExtension, + new MyExtension(1), + new MyExtension(2), + new MyExtension, +], $extensions); From 863eb7d4554a6f9cca704258b762bdcef2213952 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 14 Dec 2023 22:21:35 +0100 Subject: [PATCH 08/23] opened 4.0-dev --- composer.json | 2 +- readme.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8a6a031c6..5bfe8226d 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "4.0-dev" } } } diff --git a/readme.md b/readme.md index d8e52ef86..b4b61840e 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ Nette Application MVC ===================== [![Downloads this Month](https://img.shields.io/packagist/dm/nette/application.svg)](https://packagist.org/packages/nette/application) -[![Tests](https://github.com/nette/application/actions/workflows/tests.yml/badge.svg?branch=v3.2)](https://github.com/nette/application/actions) +[![Tests](https://github.com/nette/application/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/nette/application/actions) [![Latest Stable Version](https://poser.pugx.org/nette/application/v/stable)](https://github.com/nette/application/releases) [![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/application/blob/master/license.md) From e785bc96b58cd218bb3d3c44d4e1a3232e6631dd Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 6 Apr 2024 18:50:00 +0200 Subject: [PATCH 09/23] removed support for Latte 2 --- composer.json | 4 +- src/Bridges/ApplicationDI/LatteExtension.php | 65 ++---- .../ApplicationLatte/SnippetBridge.php | 95 --------- src/Bridges/ApplicationLatte/Template.php | 11 +- .../ApplicationLatte/TemplateFactory.php | 57 +----- src/Bridges/ApplicationLatte/UIMacros.php | 187 ------------------ src/Bridges/ApplicationLatte/UIRuntime.php | 84 -------- tests/Bridges.DI/LatteExtension.2.phpt | 122 ------------ tests/Bridges.DI/LatteExtension.basic.phpt | 4 - .../Template.getParentName().phpt | 58 ------ .../TemplateFactory.customTemplate.phpt | 75 ------- .../TemplateFactory.filters.phpt | 47 ----- .../TemplateFactory.nonce.control.phpt | 39 ---- .../TemplateFactory.nonce.presenter.phpt | 42 ---- .../TemplateFactory.onCompile.phpt | 80 -------- .../TemplateFactory.onCreate.phpt | 36 ---- tests/Bridges.Latte2/UIMacros.control.2.phpt | 86 -------- tests/Bridges.Latte2/UIMacros.control.3.phpt | 51 ----- tests/Bridges.Latte2/UIMacros.control.phpt | 88 --------- .../UIMacros.isLinkCurrent.phpt | 54 ----- tests/Bridges.Latte2/UIMacros.link.2.phpt | 122 ------------ tests/Bridges.Latte2/UIMacros.link.phpt | 68 ------- .../UIMacros.renderSnippets.phpt | 97 --------- .../UIMacros.renderSnippets2.phpt | 84 -------- .../UIMacros.renderSnippets3.phpt | 73 ------- .../UIMacros.renderSnippets4.phpt | 54 ----- .../UIMacros.renderSnippets5.phpt | 59 ------ .../UIMacros.renderSnippets6.phpt | 45 ----- .../expected/UIMacros.isLinkCurrent.php | 22 --- .../expected/UIMacros.renderSnippets.html | 20 -- tests/Bridges.Latte2/templates/include3.latte | 1 - .../templates/snippet-include.latte | 25 --- .../templates/snippet-included.latte | 1 - .../Template.getParentName().phpt | 4 - .../TemplateFactory.customTemplate.phpt | 4 - .../TemplateFactory.onCreate.phpt | 4 - tests/Bridges.Latte3/UIExtension.filters.phpt | 4 - .../UIExtension.nonce.control.phpt | 4 - .../UIExtension.nonce.presenter.phpt | 4 - tests/Bridges.Latte3/isLinkCurrent().phpt | 4 - tests/Bridges.Latte3/n-snippet.2.phpt | 4 - tests/Bridges.Latte3/n-snippet.block.phpt | 4 - tests/Bridges.Latte3/n-snippet.dynamic.phpt | 4 - tests/Bridges.Latte3/n-snippet.phpt | 3 - tests/Bridges.Latte3/renderSnippets.phpt | 4 - tests/Bridges.Latte3/renderSnippets2.phpt | 4 - tests/Bridges.Latte3/renderSnippets3.phpt | 4 - tests/Bridges.Latte3/renderSnippets4.phpt | 4 - tests/Bridges.Latte3/renderSnippets5.phpt | 4 - tests/Bridges.Latte3/renderSnippets6.phpt | 4 - tests/Bridges.Latte3/renderSnippets7.phpt | 4 - tests/Bridges.Latte3/{control}.2.phpt | 4 - tests/Bridges.Latte3/{control}.3.phpt | 3 - tests/Bridges.Latte3/{control}.phpt | 4 - tests/Bridges.Latte3/{ifCurrent}.phpt | 4 - tests/Bridges.Latte3/{link}.2.phpt | 4 - tests/Bridges.Latte3/{link}.phpt | 4 - tests/Bridges.Latte3/{snippet}.dynamic.phpt | 4 - tests/Bridges.Latte3/{snippet}.phpt | 4 - 59 files changed, 17 insertions(+), 2041 deletions(-) delete mode 100644 src/Bridges/ApplicationLatte/SnippetBridge.php delete mode 100644 src/Bridges/ApplicationLatte/UIMacros.php delete mode 100644 src/Bridges/ApplicationLatte/UIRuntime.php delete mode 100644 tests/Bridges.DI/LatteExtension.2.phpt delete mode 100644 tests/Bridges.Latte2/Template.getParentName().phpt delete mode 100644 tests/Bridges.Latte2/TemplateFactory.customTemplate.phpt delete mode 100644 tests/Bridges.Latte2/TemplateFactory.filters.phpt delete mode 100644 tests/Bridges.Latte2/TemplateFactory.nonce.control.phpt delete mode 100644 tests/Bridges.Latte2/TemplateFactory.nonce.presenter.phpt delete mode 100644 tests/Bridges.Latte2/TemplateFactory.onCompile.phpt delete mode 100644 tests/Bridges.Latte2/TemplateFactory.onCreate.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.control.2.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.control.3.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.control.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.isLinkCurrent.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.link.2.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.link.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.renderSnippets.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.renderSnippets2.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.renderSnippets3.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.renderSnippets4.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.renderSnippets5.phpt delete mode 100644 tests/Bridges.Latte2/UIMacros.renderSnippets6.phpt delete mode 100644 tests/Bridges.Latte2/expected/UIMacros.isLinkCurrent.php delete mode 100644 tests/Bridges.Latte2/expected/UIMacros.renderSnippets.html delete mode 100644 tests/Bridges.Latte2/templates/include3.latte delete mode 100644 tests/Bridges.Latte2/templates/snippet-include.latte delete mode 100644 tests/Bridges.Latte2/templates/snippet-included.latte diff --git a/composer.json b/composer.json index 5bfe8226d..62864986e 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "nette/forms": "^3.2", "nette/robot-loader": "^4.0", "nette/security": "^3.2", - "latte/latte": "^2.10.2 || ^3.0.12", + "latte/latte": "^3.0.12", "tracy/tracy": "^2.9", "mockery/mockery": "^1.6", "phpstan/phpstan-nette": "^1.0", @@ -42,7 +42,7 @@ "nette/di": "<3.2", "nette/forms": "<3.2", "nette/schema": "<1.3", - "latte/latte": "<2.7.1 || >=3.0.0 <3.0.12 || >=3.1", + "latte/latte": "<3.0.12", "tracy/tracy": "<2.9" }, "autoload": { diff --git a/src/Bridges/ApplicationDI/LatteExtension.php b/src/Bridges/ApplicationDI/LatteExtension.php index 736dbd57a..18d1362ee 100644 --- a/src/Bridges/ApplicationDI/LatteExtension.php +++ b/src/Bridges/ApplicationDI/LatteExtension.php @@ -33,7 +33,6 @@ public function getConfigSchema(): Nette\Schema\Schema { return Expect::structure([ 'debugger' => Expect::anyOf(true, false, 'all'), - 'macros' => Expect::arrayOf('string'), 'extensions' => Expect::arrayOf('string|Nette\DI\Definitions\Statement'), 'templateClass' => Expect::string(), 'strictTypes' => Expect::bool(false), @@ -52,36 +51,26 @@ public function loadConfiguration(): void $config = $this->config; $builder = $this->getContainerBuilder(); - $latteFactory = $builder->addFactoryDefinition($this->prefix('latteFactory')) + $builder->addFactoryDefinition($this->prefix('latteFactory')) ->setImplement(ApplicationLatte\LatteFactory::class) ->getResultDefinition() ->setFactory(Latte\Engine::class) ->addSetup('setTempDirectory', [$this->tempDir]) ->addSetup('setAutoRefresh', [$this->debugMode]) - ->addSetup('setStrictTypes', [$config->strictTypes]); - - if (version_compare(Latte\Engine::VERSION, '3', '<')) { - foreach ($config->macros as $macro) { - $this->addMacro($macro); - } - } else { - $latteFactory->addSetup('setStrictParsing', [$config->strictParsing]) - ->addSetup('enablePhpLinter', [$config->phpLinter]); - - $builder->getDefinition($this->prefix('latteFactory')) - ->getResultDefinition() + ->addSetup('setStrictTypes', [$config->strictTypes]) + ->addSetup('setStrictParsing', [$config->strictParsing]) + ->addSetup('enablePhpLinter', [$config->phpLinter]) ->addSetup('?', [$builder::literal('func_num_args() && $service->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(func_get_arg(0)))')]); - if ($cache = $builder->getByType(Nette\Caching\Storage::class)) { - $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class, [$builder->getDefinition($cache)])); - } - if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) { - $this->addExtension(new Statement(Nette\Bridges\FormsLatte\FormsExtension::class)); - } + if ($cache = $builder->getByType(Nette\Caching\Storage::class)) { + $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class, [$builder->getDefinition($cache)])); + } + if (class_exists(Nette\Bridges\FormsLatte\FormsExtension::class)) { + $this->addExtension(new Statement(Nette\Bridges\FormsLatte\FormsExtension::class)); + } - foreach ($config->extensions as $extension) { - $this->addExtension($extension); - } + foreach ($config->extensions as $extension) { + $this->addExtension($extension); } $builder->addDefinition($this->prefix('templateFactory')) @@ -124,40 +113,12 @@ public static function initLattePanel( $control = $template->getLatte()->getProviders()['uiControl'] ?? null; if ($all || $control instanceof Nette\Application\UI\Presenter) { $name = $all && $control ? (new \ReflectionObject($control))->getShortName() : ''; - if (version_compare(Latte\Engine::VERSION, '3', '<')) { - $bar->addPanel(new Latte\Bridges\Tracy\LattePanel($template->getLatte(), $name)); - } else { - $template->getLatte()->addExtension(new Latte\Bridges\Tracy\TracyExtension($name)); - } + $template->getLatte()->addExtension(new Latte\Bridges\Tracy\TracyExtension($name)); } }; } - public function addMacro(string $macro): void - { - $builder = $this->getContainerBuilder(); - $definition = $builder->getDefinition($this->prefix('latteFactory'))->getResultDefinition(); - - if (($macro[0] ?? null) === '@') { - if (str_contains($macro, '::')) { - [$macro, $method] = explode('::', $macro); - } else { - $method = 'install'; - } - - $definition->addSetup('?->onCompile[] = function ($engine) { ?->' . $method . '($engine->getCompiler()); }', ['@self', $macro]); - - } else { - if (!str_contains($macro, '::') && class_exists($macro)) { - $macro .= '::install'; - } - - $definition->addSetup('?->onCompile[] = function ($engine) { ' . $macro . '($engine->getCompiler()); }', ['@self']); - } - } - - public function addExtension(Statement|string $extension): void { $extension = is_string($extension) diff --git a/src/Bridges/ApplicationLatte/SnippetBridge.php b/src/Bridges/ApplicationLatte/SnippetBridge.php deleted file mode 100644 index f5d62ef80..000000000 --- a/src/Bridges/ApplicationLatte/SnippetBridge.php +++ /dev/null @@ -1,95 +0,0 @@ -control = $control; - } - - - public function isSnippetMode(): bool - { - return (bool) $this->control->snippetMode; - } - - - public function setSnippetMode($snippetMode) - { - $this->control->snippetMode = $snippetMode; - } - - - public function needsRedraw($name): bool - { - return $this->control->isControlInvalid($name); - } - - - public function markRedrawn($name): void - { - if ($name !== '') { - $this->control->redrawControl($name, false); - } - } - - - public function getHtmlId($name): string - { - return $this->control->getSnippetId($name); - } - - - public function addSnippet($name, $content): void - { - if (!isset($this->payload)) { - $this->payload = $this->control->getPresenter()->getPayload(); - } - - $this->payload->snippets[$this->control->getSnippetId($name)] = $content; - } - - - public function renderChildren(): void - { - $queue = [$this->control]; - do { - foreach (array_shift($queue)->getComponents() as $child) { - if ($child instanceof Renderable) { - if ($child->isControlInvalid()) { - $child->snippetMode = true; - $child->render(); - $child->snippetMode = false; - } - } elseif ($child instanceof Nette\ComponentModel\IContainer) { - $queue[] = $child; - } - } - } while ($queue); - } -} diff --git a/src/Bridges/ApplicationLatte/Template.php b/src/Bridges/ApplicationLatte/Template.php index 4912b27c2..b9850a6f5 100644 --- a/src/Bridges/ApplicationLatte/Template.php +++ b/src/Bridges/ApplicationLatte/Template.php @@ -90,16 +90,7 @@ public function addFunction(string $name, callable $callback): static */ public function setTranslator(?Nette\Localization\Translator $translator, ?string $language = null): static { - if (version_compare(Latte\Engine::VERSION, '3', '<')) { - $this->latte->addFilter( - 'translate', - fn(Latte\Runtime\FilterInfo $fi, ...$args): string => $translator === null - ? $args[0] - : $translator->translate(...$args), - ); - } else { - $this->latte->addExtension(new Latte\Essential\TranslatorExtension($translator, $language)); - } + $this->latte->addExtension(new Latte\Essential\TranslatorExtension($translator, $language)); return $this; } diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index 2fdcbc9b4..5ae96343d 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -9,7 +9,6 @@ namespace Nette\Bridges\ApplicationLatte; -use Latte; use Nette; use Nette\Application\UI; @@ -28,7 +27,6 @@ public function __construct( private readonly LatteFactory $latteFactory, private readonly ?Nette\Http\IRequest $httpRequest = null, private readonly ?Nette\Security\User $user = null, - private readonly ?Nette\Caching\Storage $cacheStorage = null, $templateClass = null, ) { if ($templateClass && (!class_exists($templateClass) || !is_a($templateClass, Template::class, true))) { @@ -51,9 +49,7 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul $template = new $class($latte); $presenter = $control?->getPresenterIfExists(); - if (version_compare(Latte\Engine::VERSION, '3', '<')) { - $this->setupLatte2($latte, $control, $presenter, $template); - } elseif (!Nette\Utils\Arrays::some($latte->getExtensions(), fn($e) => $e instanceof UIExtension)) { + if (!Nette\Utils\Arrays::some($latte->getExtensions(), fn($e) => $e instanceof UIExtension)) { $latte->addExtension(new UIExtension($control)); } @@ -84,55 +80,4 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul return $template; } - - - private function setupLatte2( - Latte\Engine $latte, - ?UI\Control $control, - ?UI\Presenter $presenter, - Template $template, - ): void - { - if ($latte->onCompile instanceof \Traversable) { - $latte->onCompile = iterator_to_array($latte->onCompile); - } - - array_unshift($latte->onCompile, function (Latte\Engine $latte) use ($control, $template): void { - if ($this->cacheStorage) { - $latte->getCompiler()->addMacro('cache', new Nette\Bridges\CacheLatte\CacheMacro); - } - - UIMacros::install($latte->getCompiler()); - if (class_exists(Nette\Bridges\FormsLatte\FormMacros::class)) { - Nette\Bridges\FormsLatte\FormMacros::install($latte->getCompiler()); - } - - $control?->templatePrepareFilters($template); - }); - - $latte->addProvider('cacheStorage', $this->cacheStorage); - - if ($control) { - $latte->addProvider('uiControl', $control); - $latte->addProvider('uiPresenter', $presenter); - $latte->addProvider('snippetBridge', new SnippetBridge($control)); - if ($presenter) { - $header = $presenter->getHttpResponse()->getHeader('Content-Security-Policy') - ?: $presenter->getHttpResponse()->getHeader('Content-Security-Policy-Report-Only'); - } - - $nonce = $presenter && preg_match('#\s\'nonce-([\w+/]+=*)\'#', (string) $header, $m) ? $m[1] : null; - $latte->addProvider('uiNonce', $nonce); - } - - if ($presenter) { - $latte->addFunction('isLinkCurrent', [$presenter, 'isLinkCurrent']); - $latte->addFunction('isModuleCurrent', [$presenter, 'isModuleCurrent']); - } - - $latte->addFilter('modifyDate', fn($time, $delta, $unit = null) => $time - ? Nette\Utils\DateTime::from($time)->modify($delta . $unit) - : null); - - } } diff --git a/src/Bridges/ApplicationLatte/UIMacros.php b/src/Bridges/ApplicationLatte/UIMacros.php deleted file mode 100644 index 131c30075..000000000 --- a/src/Bridges/ApplicationLatte/UIMacros.php +++ /dev/null @@ -1,187 +0,0 @@ -addMacro('control', [$me, 'macroControl']); - - $me->addMacro('href', null, null, fn(MacroNode $node, PhpWriter $writer): string => ' ?> href="macroLink($node, $writer) . ' ?>"addMacro('plink', [$me, 'macroLink']); - $me->addMacro('link', [$me, 'macroLink']); - $me->addMacro('ifCurrent', [$me, 'macroIfCurrent'], '}'); // deprecated; use n:class="$presenter->linkCurrent ? ..." - $me->addMacro('extends', [$me, 'macroExtends']); - $me->addMacro('layout', [$me, 'macroExtends']); - $me->addMacro('nonce', null, null, 'echo $this->global->uiNonce ? " nonce=\"{$this->global->uiNonce}\"" : "";'); - $me->addMacro('templatePrint', [$me, 'macroTemplatePrint'], null, null, self::ALLOWED_IN_HEAD); - } - - - /** - * Initializes before template parsing. - */ - public function initialize(): void - { - $this->extends = false; - } - - - /** - * Finishes template parsing. - * @return array(prolog, epilog) - */ - public function finalize() - { - if ($this->printTemplate) { - return ["Nette\\Bridges\\ApplicationLatte\\UIRuntime::printClass(\$this, $this->printTemplate); exit;"]; - } - - return [$this->extends . 'Nette\Bridges\ApplicationLatte\UIRuntime::initialize($this, $this->parentName, $this->blocks);']; - } - - - /********************* macros ****************d*g**/ - - - /** - * {control name[:method] [params]} - */ - public function macroControl(MacroNode $node, PhpWriter $writer) - { - if ($node->context !== [Latte\Compiler::CONTENT_HTML, Latte\Compiler::CONTEXT_HTML_TEXT]) { - $escapeMod = Latte\Helpers::removeFilter($node->modifiers, 'noescape') ? '' : '|escape'; - } - - if ($node->modifiers) { - trigger_error('Modifiers are deprecated in ' . $node->getNotation(), E_USER_DEPRECATED); - } - - $node->modifiers .= $escapeMod ?? ''; - - $words = $node->tokenizer->fetchWords(); - if (!$words) { - throw new CompileException('Missing control name in {control}'); - } - - $name = $writer->formatWord($words[0]); - $method = ucfirst($words[1] ?? ''); - $method = Strings::match($method, '#^\w*$#D') - ? "render$method" - : "{\"render$method\"}"; - - $tokens = $node->tokenizer; - $pos = $tokens->position; - $wrap = false; - while ($tokens->nextToken()) { - if ($tokens->isCurrent('=>', '(expand)') && !$tokens->depth) { - $wrap = true; - break; - } - } - - $tokens->position = $pos; - $param = $wrap ? $writer->formatArray() : $writer->formatArgs(); - - return "/* line $node->startLine */ " - . ($name[0] === '$' ? "if (is_object($name)) \$_tmp = $name; else " : '') - . '$_tmp = $this->global->uiControl->getComponent(' . $name . '); ' - . 'if ($_tmp instanceof Nette\Application\UI\Renderable) $_tmp->redrawControl(null, false); ' - . ($node->modifiers === '' - ? "\$_tmp->$method($param);" - : $writer->write( - "ob_start(fn() => null); \$_tmp->$method($param); \$ʟ_fi = new LR\\FilterInfo(%var); echo %modifyContent(ob_get_clean());", - Latte\Engine::CONTENT_HTML, - ) - ); - } - - - /** - * {link destination [,] [params]} - * {plink destination [,] [params]} - * n:href="destination [,] [params]" - */ - public function macroLink(MacroNode $node, PhpWriter $writer) - { - $node->modifiers = preg_replace('#\|safeurl\s*(?=\||$)#Di', '', $node->modifiers); - return $writer->using($node, $this->getCompiler()) - ->write( - 'echo %escape(%modify(' - . ($node->name === 'plink' ? '$this->global->uiPresenter' : '$this->global->uiControl') - . '->link(%node.word, %node.array?)))' - . ($node->startLine ? " /* line $node->startLine */;" : ';'), - ); - } - - - /** - * {ifCurrent destination [,] [params]} - */ - public function macroIfCurrent(MacroNode $node, PhpWriter $writer) - { - if ($node->modifiers) { - throw new CompileException('Modifiers are not allowed in ' . $node->getNotation()); - } - - return $writer->write( - $node->args - ? 'if ($this->global->uiPresenter->isLinkCurrent(%node.word, %node.array?)) {' - : 'if ($this->global->uiPresenter->getLastCreatedRequestFlag("current")) {', - ); - } - - - /** - * {extends auto} - */ - public function macroExtends(MacroNode $node, PhpWriter $writer) - { - if ($node->modifiers || $node->parentNode || $node->args !== 'auto') { - return $this->extends = false; - } - - $this->extends = $writer->write('$this->parentName = $this->global->uiPresenter->findLayoutTemplateFile();'); - } - - - /** - * {templatePrint [parentClass | default]} - */ - public function macroTemplatePrint(MacroNode $node): void - { - if ($node->modifiers) { - throw new CompileException('Modifiers are not allowed in ' . $node->getNotation()); - } - - $this->printTemplate = var_export($node->tokenizer->fetchWord() ?: null, true); - } -} diff --git a/src/Bridges/ApplicationLatte/UIRuntime.php b/src/Bridges/ApplicationLatte/UIRuntime.php deleted file mode 100644 index ace3af72d..000000000 --- a/src/Bridges/ApplicationLatte/UIRuntime.php +++ /dev/null @@ -1,84 +0,0 @@ -global; - $blocks = array_filter(array_keys($blocks), fn(string $s): bool => $s[0] !== '_'); - if ( - $parentName === null - && $blocks - && !$template->getReferringTemplate() - && ($providers->uiControl ?? null) instanceof Nette\Application\UI\Presenter - ) { - $parentName = $providers->uiControl->findLayoutTemplateFile(); - } - } - - - public static function printClass(Latte\Runtime\Template $template, ?string $parent = null): void - { - $blueprint = new Latte\Runtime\Blueprint; - $name = 'Template'; - $params = $template->getParameters(); - $control = $params['control'] ?? $params['presenter'] ?? null; - if ($control) { - $name = preg_replace('#(Control|Presenter)$#', '', $control::class) . 'Template'; - unset($params[$control instanceof Presenter ? 'control' : 'presenter']); - } - - if ($parent) { - if (!class_exists($parent)) { - $blueprint->printHeader("{templatePrint}: Class '$parent' doesn't exist."); - return; - } - - $params = array_diff_key($params, get_class_vars($parent)); - } - - $funcs = array_diff_key((array) $template->global->fn, (new Latte\Runtime\Defaults)->getFunctions()); - unset($funcs['isLinkCurrent'], $funcs['isModuleCurrent']); - - $namespace = new Php\PhpNamespace(Php\Helpers::extractNamespace($name)); - $class = $namespace->addClass(Php\Helpers::extractShortName($name)); - $class->setExtends($parent ?: Template::class); - if (!$parent) { - $class->addTrait(Nette\SmartObject::class); - } - - $blueprint->addProperties($class, $params, true); - $blueprint->addFunctions($class, $funcs); - - $end = $blueprint->printCanvas(); - $blueprint->printHeader('Native types'); - $blueprint->printCode((string) $namespace); - - $blueprint->addProperties($class, $params, false); - - $blueprint->printHeader('phpDoc types'); - $blueprint->printCode((string) $namespace); - echo $end; - } -} diff --git a/tests/Bridges.DI/LatteExtension.2.phpt b/tests/Bridges.DI/LatteExtension.2.phpt deleted file mode 100644 index 8144950b6..000000000 --- a/tests/Bridges.DI/LatteExtension.2.phpt +++ /dev/null @@ -1,122 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class LoremIpsumMacros extends Latte\Macros\MacroSet -{ - public static function install(Latte\Compiler $compiler) - { - $me = new static($compiler); - $me->addMacro('lorem', 'lorem'); - Notes::add($me::class); - } -} - - -class IpsumLoremMacros extends Latte\Macros\MacroSet -{ - public static function install(Latte\Compiler $compiler) - { - $me = new static($compiler); - $me->addMacro('ipsum', 'ipsum'); - Notes::add($me::class); - } -} - - -class FooMacros extends Latte\Macros\MacroSet -{ - public static function install(Latte\Compiler $compiler) - { - $me = new static($compiler); - $me->addMacro('foo', 'foo'); - Notes::add($me::class); - } -} - - -class NonStaticMacrosFactory -{ - private string $parameter; - - - public function __construct($parameter) - { - $this->parameter = $parameter; - } - - - public function install(Latte\Compiler $compiler) - { - $macros = new Latte\Macros\MacroSet($compiler); - $macros->addMacro('foo', 'foo ' . $this->parameter); - Notes::add(static::class . '::install'); - } - - - public function create(Latte\Compiler $compiler) - { - $macros = new Latte\Macros\MacroSet($compiler); - $macros->addMacro('foo2', 'foo ' . $this->parameter); - Notes::add(static::class . '::create'); - } -} - - -class AnotherExtension extends Nette\DI\CompilerExtension -{ - public function beforeCompile() - { - foreach ($this->compiler->getExtensions(Nette\Bridges\ApplicationDI\LatteExtension::class) as $extension) { - $extension->addMacro('FooMacros::install'); - } - } -} - - -$loader = new DI\Config\Loader; -$config = $loader->load(Tester\FileMock::create(' -latte: - macros: - - LoremIpsumMacros - - IpsumLoremMacros::install - - @macroFactory - - @macroFactory::create - -services: - macroFactory: NonStaticMacrosFactory(foo) -', 'neon')); - -$compiler = new DI\Compiler; -$compiler->addExtension('latte', new Nette\Bridges\ApplicationDI\LatteExtension('', false)); -$compiler->addExtension('another', new AnotherExtension); -$code = $compiler->addConfig($config)->compile(); -eval($code); - -$container = new Container; - - -Assert::type(Nette\Bridges\ApplicationLatte\LatteFactory::class, $container->getService('nette.latteFactory')); -$container->getService('nette.latteFactory')->create()->setLoader(new Latte\Loaders\StringLoader)->compile(''); - -Assert::same([ - 'LoremIpsumMacros', - 'IpsumLoremMacros', - 'NonStaticMacrosFactory::install', - 'NonStaticMacrosFactory::create', - 'FooMacros', -], Notes::fetch()); diff --git a/tests/Bridges.DI/LatteExtension.basic.phpt b/tests/Bridges.DI/LatteExtension.basic.phpt index 09dc0d292..34ea641d5 100644 --- a/tests/Bridges.DI/LatteExtension.basic.phpt +++ b/tests/Bridges.DI/LatteExtension.basic.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class MyExtension extends Latte\Extension { diff --git a/tests/Bridges.Latte2/Template.getParentName().phpt b/tests/Bridges.Latte2/Template.getParentName().phpt deleted file mode 100644 index 1253c4a4e..000000000 --- a/tests/Bridges.Latte2/Template.getParentName().phpt +++ /dev/null @@ -1,58 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -$presenter = Mockery::mock(Nette\Application\UI\Presenter::class) - ->shouldReceive('findLayoutTemplateFile')->andReturn('layout.latte') - ->mock(); - -$latte = new Latte\Engine; -$latte->setLoader(new Latte\Loaders\StringLoader); -$latte->addProvider('uiControl', $presenter); -UIMacros::install($latte->getCompiler()); - -$template = $latte->createTemplate(''); -$template->prepare(); -Assert::null($template->getParentName()); - -$template = $latte->createTemplate('{block}...{/block}'); -$template->prepare(); -Assert::null($template->getParentName()); - -$template = $latte->createTemplate('{block name}...{/block}'); -$template->prepare(); -Assert::same('layout.latte', $template->getParentName()); - -$template = $latte->createTemplate('{extends "file.latte"} {block name}...{/block}'); -$template->prepare(); -Assert::same('file.latte', $template->getParentName()); - -$template = $latte->createTemplate('{extends "file.latte"}'); -$template->prepare(); -Assert::same('file.latte', $template->getParentName()); - -$template = $latte->createTemplate( - '{extends $file} {block name}...{/block}', - ['file' => 'file.latte'], -); -$template->prepare(); -Assert::same('file.latte', $template->getParentName()); - -$template = $latte->createTemplate('{extends none}'); -$template->prepare(); -Assert::null($template->getParentName()); - -$latte->addProvider('uiPresenter', $presenter); -$template = $latte->createTemplate('{extends auto}'); -$template->prepare(); -Assert::same('layout.latte', $template->getParentName()); diff --git a/tests/Bridges.Latte2/TemplateFactory.customTemplate.phpt b/tests/Bridges.Latte2/TemplateFactory.customTemplate.phpt deleted file mode 100644 index 011d5b52f..000000000 --- a/tests/Bridges.Latte2/TemplateFactory.customTemplate.phpt +++ /dev/null @@ -1,75 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - -Tester\Environment::bypassFinals(); - - -class TemplateMock extends Template -{ - private $file = 'ko'; - - - public function render(?string $file = null, array $params = []): void - { - echo strrev($this->file); - } - - - public function setFile(string $file): static - { - $this->file = $file; - return $this; - } - - - public function getFile(): string - { - return $this->file; - } -} - - -test('', function () { - $latteFactory = Mockery::mock(LatteFactory::class); - $latteFactory->shouldReceive('create')->andReturn(new Latte\Engine); - $factory = new TemplateFactory($latteFactory); - Assert::type(Template::class, $factory->createTemplate()); -}); - -Assert::exception(function () { - $factory = new TemplateFactory(Mockery::mock(LatteFactory::class), null, null, null, stdClass::class); -}, Nette\InvalidArgumentException::class, 'Class stdClass does not implement Nette\Bridges\ApplicationLatte\Template or it does not exist.'); - - -test('', function () { - $latteFactory = Mockery::mock(LatteFactory::class); - $latteFactory->shouldReceive('create')->andReturn(new Latte\Engine); - $factory = new TemplateFactory($latteFactory, null, null, null, TemplateMock::class); - $template = $factory->createTemplate(); - Assert::type(TemplateMock::class, $template); - Assert::type(UI\Template::class, $template); - ob_start(); - $template->render(); - Assert::same('ok', ob_get_clean()); - $template->setFile('bla'); - ob_start(); - $template->render(); - Assert::same('alb', ob_get_clean()); -}); diff --git a/tests/Bridges.Latte2/TemplateFactory.filters.phpt b/tests/Bridges.Latte2/TemplateFactory.filters.phpt deleted file mode 100644 index 57e879543..000000000 --- a/tests/Bridges.Latte2/TemplateFactory.filters.phpt +++ /dev/null @@ -1,47 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class LatteFactory implements Nette\Bridges\ApplicationLatte\LatteFactory -{ - private $engine; - - - public function __construct(Latte\Engine $engine) - { - $this->engine = $engine; - } - - - public function create(): Latte\Engine - { - return $this->engine; - } -} - -$factory = new TemplateFactory(new LatteFactory(new Latte\Engine)); -$latte = $factory->createTemplate()->getLatte(); - - -setlocale(LC_TIME, 'C'); -date_default_timezone_set('Europe/Prague'); - -Assert::null($latte->invokeFilter('modifyDate', [null, null])); -Assert::same('1978-01-24 11:40:00', (string) $latte->invokeFilter('modifyDate', [254_400_000, '+1 day'])); -Assert::same('1978-05-06 00:00:00', (string) $latte->invokeFilter('modifyDate', ['1978-05-05', '+1 day'])); -Assert::same('1978-05-06 00:00:00', (string) $latte->invokeFilter('modifyDate', [new DateTime('1978-05-05'), '1day'])); -Assert::same('1978-01-22 11:40:00', (string) $latte->invokeFilter('modifyDate', [254_400_000, -1, 'day'])); diff --git a/tests/Bridges.Latte2/TemplateFactory.nonce.control.phpt b/tests/Bridges.Latte2/TemplateFactory.nonce.control.phpt deleted file mode 100644 index 850629b36..000000000 --- a/tests/Bridges.Latte2/TemplateFactory.nonce.control.phpt +++ /dev/null @@ -1,39 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - -$latte = new Latte\Engine; - -$latteFactory = Mockery::mock(ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - -$response = Mockery::mock(Nette\Http\IResponse::class); -$response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); - -$control = Mockery::mock(UI\Control::class); -$control->shouldReceive('getPresenter')->andReturn(null); -$control->shouldIgnoreMissing(); - -$factory = new ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($control); - -$latte->setLoader(new Latte\Loaders\StringLoader); - -Assert::match( - '', - $latte->renderToString(''), -); diff --git a/tests/Bridges.Latte2/TemplateFactory.nonce.presenter.phpt b/tests/Bridges.Latte2/TemplateFactory.nonce.presenter.phpt deleted file mode 100644 index 1ef2df0e8..000000000 --- a/tests/Bridges.Latte2/TemplateFactory.nonce.presenter.phpt +++ /dev/null @@ -1,42 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - -Tester\Environment::bypassFinals(); - -$latte = new Latte\Engine; - -$latteFactory = Mockery::mock(ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - -$response = Mockery::mock(Nette\Http\IResponse::class); -$response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); - -$presenter = Mockery::mock(UI\Presenter::class); -$presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); -$presenter->shouldReceive('getHttpResponse')->andReturn($response); -$presenter->shouldIgnoreMissing(); - -$factory = new ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - -$latte->setLoader(new Latte\Loaders\StringLoader); - -Assert::match( - '', - $latte->renderToString(''), -); diff --git a/tests/Bridges.Latte2/TemplateFactory.onCompile.phpt b/tests/Bridges.Latte2/TemplateFactory.onCompile.phpt deleted file mode 100644 index b60ebd8e1..000000000 --- a/tests/Bridges.Latte2/TemplateFactory.onCompile.phpt +++ /dev/null @@ -1,80 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -test('', function () { - $engine = new Latte\Engine; - $latteFactory = Mockery::mock(LatteFactory::class); - $latteFactory->shouldReceive('create')->andReturn($engine); - $factory = new TemplateFactory($latteFactory, new Http\Request(new Http\UrlScript('http://nette.org'))); - $engine->onCompile[] = $callback = function () {}; - - $factory->createTemplate(); - - Assert::type('array', $engine->onCompile); - Assert::type(Closure::class, $engine->onCompile[0]); // prepended by TemplateFactory - Assert::same($callback, $engine->onCompile[1]); // our callback -}); - - -test('', function () { - $engine = new Latte\Engine; - $latteFactory = Mockery::mock(LatteFactory::class); - $latteFactory->shouldReceive('create')->andReturn($engine); - $factory = new TemplateFactory($latteFactory, new Http\Request(new Http\UrlScript('http://nette.org'))); - $engine->onCompile = new ArrayIterator([$callback = function () {}]); - - $factory->createTemplate(); - - Assert::type('array', $engine->onCompile); - Assert::type(Closure::class, $engine->onCompile[0]); // prepended by TemplateFactory - Assert::same($callback, $engine->onCompile[1]); // our callback -}); - - -test('', function () { - class Event implements IteratorAggregate - { - public $events; - - - public function __construct($events) - { - $this->events = $events; - } - - - public function getIterator(): ArrayIterator - { - return new ArrayIterator($this->events); - } - } - - $engine = new Latte\Engine; - $latteFactory = Mockery::mock(LatteFactory::class); - $latteFactory->shouldReceive('create')->andReturn($engine); - $factory = new TemplateFactory($latteFactory, new Http\Request(new Http\UrlScript('http://nette.org'))); - $engine->onCompile = new Event([$callback = function () {}]); - - $factory->createTemplate(); - - Assert::type('array', $engine->onCompile); - Assert::type(Closure::class, $engine->onCompile[0]); // prepended by TemplateFactory - Assert::same($callback, $engine->onCompile[1]); // our callback -}); diff --git a/tests/Bridges.Latte2/TemplateFactory.onCreate.phpt b/tests/Bridges.Latte2/TemplateFactory.onCreate.phpt deleted file mode 100644 index 8f86ef42d..000000000 --- a/tests/Bridges.Latte2/TemplateFactory.onCreate.phpt +++ /dev/null @@ -1,36 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -test('', function () { - $engine = new Latte\Engine; - $latteFactory = Mockery::mock(LatteFactory::class); - $latteFactory->shouldReceive('create')->andReturn($engine); - $factory = new TemplateFactory($latteFactory, new Http\Request(new Http\UrlScript('http://nette.org'))); - $factory->onCreate[] = $callback = function (Template $template) { - $template->add('foo', 'bar'); - }; - - $template = $factory->createTemplate(); - - Assert::type('array', $factory->onCreate); - Assert::same($callback, $factory->onCreate[0]); // our callback - Assert::equal('bar', $template->foo); -}); diff --git a/tests/Bridges.Latte2/UIMacros.control.2.phpt b/tests/Bridges.Latte2/UIMacros.control.2.phpt deleted file mode 100644 index 9449e00e3..000000000 --- a/tests/Bridges.Latte2/UIMacros.control.2.phpt +++ /dev/null @@ -1,86 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class MockComponent -{ - public function getComponent($name) - { - Notes::add(__METHOD__); - Notes::add(func_get_args()); - return new MockControl; - } -} - - -class MockControl -{ - public function __call($name, $args) - { - Notes::add(__METHOD__); - Notes::add(func_get_args()); - } -} - - -$latte = new Latte\Engine; -$latte->setLoader(new Latte\Loaders\StringLoader); -UIMacros::install($latte->getCompiler()); - -$latte->addProvider('uiControl', new MockComponent); -$params['form'] = new MockControl; -$params['name'] = 'form'; - -$latte->renderToString(' -{control \'name\'} - -{control form} - -{control form:test} - -{control $form:test} - -{control $name:test} - -{control $name:$name} - -{control form var1} - -{control form var1, 1, 2} - -{control form var1 => 5, 1, 2} -', $params); - -Assert::same([ - 'MockComponent::getComponent', ['name'], - 'MockControl::__call', ['render', []], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['render', []], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['renderTest', []], - 'MockControl::__call', ['renderTest', []], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['renderTest', []], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['renderform', []], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['render', ['var1']], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['render', ['var1', 1, 2]], - 'MockComponent::getComponent', ['form'], - 'MockControl::__call', ['render', [['var1' => 5, 0 => 1, 1 => 2]]], -], Notes::fetch()); diff --git a/tests/Bridges.Latte2/UIMacros.control.3.phpt b/tests/Bridges.Latte2/UIMacros.control.3.phpt deleted file mode 100644 index f5d6e23d2..000000000 --- a/tests/Bridges.Latte2/UIMacros.control.3.phpt +++ /dev/null @@ -1,51 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -$latte = new Latte\Engine; -$latte->setLoader(new Latte\Loaders\StringLoader); -UIMacros::install($latte->getCompiler()); -$latte->addProvider('uiControl', new class { - public function render() - { - echo '<>&'; - } - - - public function __call($name, $args) - { - return new self; - } -}); - -Assert::exception(function () use ($latte) { - $latte->renderToString('
&', - $latte->renderToString('
', - $latte->renderToString('
'), -); - -Assert::exception(function () use ($latte) { - $latte->renderToString(''); -}, Latte\RuntimeException::class, 'Filters: unable to convert content type HTML to HTMLCSS'); diff --git a/tests/Bridges.Latte2/UIMacros.control.phpt b/tests/Bridges.Latte2/UIMacros.control.phpt deleted file mode 100644 index 559895322..000000000 --- a/tests/Bridges.Latte2/UIMacros.control.phpt +++ /dev/null @@ -1,88 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -$latte = new Latte\Engine; -$latte->setLoader(new Latte\Loaders\StringLoader); -UIMacros::install($latte->getCompiler()); - -// {control ...} -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->render();%A%', - $latte->compile('{control form}'), -); - -@Assert::match( - <<<'XX' - %A% - /* line 1 */ $_tmp = $this->global->uiControl->getComponent("form"); - if ($_tmp instanceof Nette\Application\UI\Renderable) $_tmp->redrawControl(null, false); - ob_start(fn() => null); - $_tmp->render(); - $ʟ_fi = new LR\FilterInfo('html'); - echo $this->filters->filterContent('filter', $ʟ_fi, ob_get_clean()); - %A% - XX, - $latte->compile('{control form|filter}'), -); // @deprecated - -Assert::match( - <<<'XX' - %A% - /* line 1 */ if (is_object($form)) $_tmp = $form; - else $_tmp = $this->global->uiControl->getComponent($form); - if ($_tmp instanceof Nette\Application\UI\Renderable) $_tmp->redrawControl(null, false); - $_tmp->render(); - %A% - XX, - $latte->compile('{control $form}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->renderType();%A%', - $latte->compile('{control form:type}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->{"render$type"}();%A%', - $latte->compile('{control form:$type}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->renderType(\'param\');%A%', - $latte->compile('{control form:type param}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->render(array_merge([], $params, []));%A%', - $latte->compile('{control form (expand) $params}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->renderType([\'param\' => 123]);%A%', - $latte->compile('{control form:type param => 123}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->renderType([\'param\' => 123]);%A%', - $latte->compile('{control form:type, param => 123}'), -); - -Assert::match( - '%A% $this->global->uiControl->getComponent("form");%A%->renderType(param: 123);%A%', - $latte->compile('{control form:type, param: 123}'), -); diff --git a/tests/Bridges.Latte2/UIMacros.isLinkCurrent.phpt b/tests/Bridges.Latte2/UIMacros.isLinkCurrent.phpt deleted file mode 100644 index 579a8fd4b..000000000 --- a/tests/Bridges.Latte2/UIMacros.isLinkCurrent.phpt +++ /dev/null @@ -1,54 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - -Tester\Environment::bypassFinals(); - -$latte = new Latte\Engine; - -$latteFactory = Mockery::mock(Nette\Bridges\ApplicationLatte\LatteFactory::class); -$latteFactory->shouldReceive('create')->andReturn($latte); - -$presenter = Mockery::mock(Nette\Application\UI\Presenter::class); -$presenter->shouldReceive('getPresenterIfExists')->andReturn($presenter); -$presenter->shouldReceive('getHttpResponse')->andReturn((Mockery::mock(Nette\Http\IResponse::class))->shouldIgnoreMissing()); -$presenter->shouldIgnoreMissing(); - -$factory = new Nette\Bridges\ApplicationLatte\TemplateFactory($latteFactory); -$factory->createTemplate($presenter); - -$latte->setLoader(new Latte\Loaders\StringLoader); - -Assert::matchFile( - __DIR__ . '/expected/UIMacros.isLinkCurrent.php', - $latte->compile( - <<<'XX' - n:href before n:class - - n:href after n:class - - href before n:class - - href after n:class - - {ifCurrent}empty{/ifCurrent} - - {ifCurrent default}default{/ifCurrent} - - custom function - - XX, - ), -); diff --git a/tests/Bridges.Latte2/UIMacros.link.2.phpt b/tests/Bridges.Latte2/UIMacros.link.2.phpt deleted file mode 100644 index 83a441c31..000000000 --- a/tests/Bridges.Latte2/UIMacros.link.2.phpt +++ /dev/null @@ -1,122 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class MockControl -{ - public function link($destination, $args = []) - { - if (!is_array($args)) { - $args = array_slice(func_get_args(), 1); - } - - array_unshift($args, $destination); - return 'link:' . strtr(json_encode($args), '"', "'"); - } -} - - -class MockPresenter extends MockControl -{ - public function link($destination, $args = []) - { - if (!is_array($args)) { - $args = array_slice(func_get_args(), 1); - } - - array_unshift($args, $destination); - return 'plink:' . strtr(json_encode($args), '"', "'"); - } - - - public function isAjax() - { - return false; - } -} - - -$latte = new Latte\Engine; -$latte->setLoader(new Latte\Loaders\StringLoader); -UIMacros::install($latte->getCompiler()); - -$latte->addProvider('uiControl', new MockControl); -$latte->addProvider('uiPresenter', new MockPresenter); -$params['action'] = 'login'; -$params['arr'] = ['link' => 'login', 'param' => 123]; - -Assert::match(<<<'EOD' - plink:['Homepage:'] - - plink:['Homepage:'] - - plink:['Homepage:action'] - - plink:['Homepage:action'] - - plink:['Homepage:action',10,20,'{one}&two'] - - plink:['Homepage:action#hash',10,20,'{one}&two'] - - plink:['#hash'] - - plink:[':',10] - - plink:{'0':'default','1':10,'a':20,'b':30} - - link:['login'] - - - - - - - - - - - EOD, strtr($latte->renderToString(<<<'EOD' - {plink Homepage:} - - {plink Homepage: } - - {plink Homepage:action } - - {plink 'Homepage:action' } - - {plink Homepage:action 10, 20, '{one}&two'} - - {plink Homepage:action#hash 10, 20, '{one}&two'} - - {plink #hash} - - {plink : 10 } - - {plink default 10, 'a' => 20, 'b' => 30} - - {link $action} - - - - - - - - - - - EOD, $params), [''' => "'", ''' => "'", '{' => '{'])); diff --git a/tests/Bridges.Latte2/UIMacros.link.phpt b/tests/Bridges.Latte2/UIMacros.link.phpt deleted file mode 100644 index 52fda3fb0..000000000 --- a/tests/Bridges.Latte2/UIMacros.link.phpt +++ /dev/null @@ -1,68 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -$latte = new Latte\Engine; -$latte->setLoader(new Latte\Loaders\StringLoader); -UIMacros::install($latte->getCompiler()); - -// {link ...} -Assert::contains( - '$this->global->uiControl->link("p")', - $latte->compile('{link p}'), -); -Assert::contains( - '($this->filters->filter)($this->global->uiControl->link("p"))', - $latte->compile('{link p|filter}'), -); -Assert::contains( - '$this->global->uiControl->link("p:a")', - $latte->compile('{link p:a}'), -); -Assert::contains( - '$this->global->uiControl->link($dest)', - $latte->compile('{link $dest}'), -); -Assert::contains( - '$this->global->uiControl->link($p:$a)', - $latte->compile('{link $p:$a}'), -); -Assert::contains( - '$this->global->uiControl->link("$p:$a")', - $latte->compile('{link "$p:$a"}'), -); -Assert::contains( - '$this->global->uiControl->link("p:a")', - $latte->compile('{link "p:a"}'), -); -Assert::contains( - '$this->global->uiControl->link(\'p:a\')', - $latte->compile('{link \'p:a\'}'), -); - -Assert::contains( - '$this->global->uiControl->link("p", [\'param\'])', - $latte->compile('{link p param}'), -); -Assert::contains( - '$this->global->uiControl->link("p", [\'param\' => 123])', - $latte->compile('{link p param => 123}'), -); -Assert::contains( - '$this->global->uiControl->link("p", [\'param\' => 123])', - $latte->compile('{link p, param => 123}'), -); diff --git a/tests/Bridges.Latte2/UIMacros.renderSnippets.phpt b/tests/Bridges.Latte2/UIMacros.renderSnippets.phpt deleted file mode 100644 index 71c354140..000000000 --- a/tests/Bridges.Latte2/UIMacros.renderSnippets.phpt +++ /dev/null @@ -1,97 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class InnerControl extends Nette\Application\UI\Control -{ - public function render() - { - $latte = new Latte\Engine; - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiPresenter', $this->getPresenter()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new Nette\Bridges\ApplicationLatte\SnippetBridge($this)); - $params['say'] = 'Hello'; - $latte->render(__DIR__ . '/templates/snippet-included.latte', $params); - } -} - -class TestPresenter extends Nette\Application\UI\Presenter -{ - public function createComponentMulti() - { - return new Nette\Application\UI\Multiplier(function () { - $control = new InnerControl; - $control->redrawControl(); - return $control; - }); - } - - - public function render() - { - $latte = new Latte\Engine; - UIMacros::install($latte->getCompiler()); - $latte->addProvider('snippetBridge', new Nette\Bridges\ApplicationLatte\SnippetBridge($this)); - $latte->render(__DIR__ . '/templates/snippet-include.latte'); - } -} - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl(); -$presenter['multi-1']->redrawControl(); -$presenter->render(); -Assert::same([ - 'snippets' => [ - 'snippet--hello' => 'Hello', - 'snippet--include' => "

Included file #3 (A, B)

\n", - 'snippet--array-1' => 'Value 1', - 'snippet--array-2' => 'Value 2', - 'snippet--array-3' => 'Value 3', - 'snippet--array2-1' => 'Value 1', - 'snippet--array2-2' => 'Value 2', - 'snippet--array2-3' => 'Value 3', - 'snippet--includeSay' => 'Hello include snippet', - 'snippet--nested1' => "\t
Foo
\n", - 'snippet-multi-1-includeSay' => 'Hello', - ], -], (array) $presenter->payload); - - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl('hello'); -$presenter->redrawControl('array'); -$presenter->render(); - -Assert::same([ - 'snippets' => [ - 'snippet--hello' => 'Hello', - 'snippet--array-1' => 'Value 1', - 'snippet--array-2' => 'Value 2', - 'snippet--array-3' => 'Value 3', - ], -], (array) $presenter->payload); - -$presenter = new TestPresenter; -ob_start(); -$presenter->render(); -$content = ob_get_clean(); -Assert::matchFile(__DIR__ . '/expected/UIMacros.renderSnippets.html', $content); diff --git a/tests/Bridges.Latte2/UIMacros.renderSnippets2.phpt b/tests/Bridges.Latte2/UIMacros.renderSnippets2.phpt deleted file mode 100644 index 58a72d170..000000000 --- a/tests/Bridges.Latte2/UIMacros.renderSnippets2.phpt +++ /dev/null @@ -1,84 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class InnerControl extends Nette\Application\UI\Control -{ - public function render() - { - $this->renderA(); - $this->renderB(); - } - - - public function renderA() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiPresenter', $this->getPresenter()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new SnippetBridge($this)); - $params['say'] = 'Hello'; - $latte->render('{snippet testA}{$say}{/snippet}', $params); - } - - - public function renderB() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiPresenter', $this->getPresenter()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new SnippetBridge($this)); - $params['say'] = 'world'; - $latte->render('{snippet testB}{$say}{/snippet}', $params); - } -} - -class TestPresenter extends Nette\Application\UI\Presenter -{ - public function createComponentMulti() - { - return new Nette\Application\UI\Multiplier(fn() => new InnerControl); - } - - - public function render() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new SnippetBridge($this)); - $latte->render(''); - } -} - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter['multi-1']->redrawControl(); -$presenter->render(); -Assert::same([ - 'snippets' => [ - 'snippet-multi-1-testA' => 'Hello', - 'snippet-multi-1-testB' => 'world', - ], -], (array) $presenter->payload); diff --git a/tests/Bridges.Latte2/UIMacros.renderSnippets3.phpt b/tests/Bridges.Latte2/UIMacros.renderSnippets3.phpt deleted file mode 100644 index 3dc72672b..000000000 --- a/tests/Bridges.Latte2/UIMacros.renderSnippets3.phpt +++ /dev/null @@ -1,73 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class TestControl extends Nette\Application\UI\Control -{ - public function render() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiPresenter', $this->getPresenter()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new Nette\Bridges\ApplicationLatte\SnippetBridge($this)); - $latte->render('{snippet foo}hello{/snippet}'); - } -} - -class TestPresenter extends Nette\Application\UI\Presenter -{ - public function createComponentTest() - { - return new TestControl; - } - - - public function render() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new Nette\Bridges\ApplicationLatte\SnippetBridge($this)); - $latte->render('{snippet foo}{control test}{/snippet}'); - } -} - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl('foo'); -$presenter['test']->redrawControl('foo'); -$presenter->render(); -Assert::same([ - 'snippets' => [ - 'snippet--foo' => '
hello
', - ], -], (array) $presenter->payload); - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter['test']->redrawControl('foo'); -$presenter->render(); -Assert::same([ - 'snippets' => [ - 'snippet-test-foo' => 'hello', - ], -], (array) $presenter->payload); diff --git a/tests/Bridges.Latte2/UIMacros.renderSnippets4.phpt b/tests/Bridges.Latte2/UIMacros.renderSnippets4.phpt deleted file mode 100644 index 917404369..000000000 --- a/tests/Bridges.Latte2/UIMacros.renderSnippets4.phpt +++ /dev/null @@ -1,54 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - - -class TestPresenter extends Nette\Application\UI\Presenter -{ - public function render() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new SnippetBridge($this)); - $latte->render('{snippet foo}{php $presenter->renderFoo()}{/snippet}', ['presenter' => $this]); - } - - - public function renderFoo() - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new SnippetBridge($this)); - $latte->render('Hello'); - } -} - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl('foo'); -$presenter->render(); -Assert::same([ - 'snippets' => [ - 'snippet--foo' => 'Hello', - ], -], (array) $presenter->payload); diff --git a/tests/Bridges.Latte2/UIMacros.renderSnippets5.phpt b/tests/Bridges.Latte2/UIMacros.renderSnippets5.phpt deleted file mode 100644 index a915657fe..000000000 --- a/tests/Bridges.Latte2/UIMacros.renderSnippets5.phpt +++ /dev/null @@ -1,59 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - - -class TestPresenter extends Nette\Application\UI\Presenter -{ - public function render(string $template) - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('uiControl', $this); - $latte->addProvider('snippetBridge', new SnippetBridge($this)); - $latte->render($template, ['presenter' => $this]); - } -} - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl('foo'); -$presenter->render('
Hello
'); -Assert::same([ - 'snippets' => [ - 'snippet--foo' => 'Hello', - ], -], (array) $presenter->payload); - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl('foo'); -Assert::exception(function () use ($presenter) { - $presenter->render('
Hello
'); -}, Latte\CompileException::class, 'Cannot combine HTML attribute id with n:snippet.'); - - -$presenter = new TestPresenter; -$presenter->snippetMode = true; -$presenter->redrawControl('foo'); -Assert::exception(function () use ($presenter) { - $presenter->render('
Hello
'); -}, Latte\CompileException::class, 'Cannot combine HTML attribute id with n:snippet.'); diff --git a/tests/Bridges.Latte2/UIMacros.renderSnippets6.phpt b/tests/Bridges.Latte2/UIMacros.renderSnippets6.phpt deleted file mode 100644 index dc4e32a25..000000000 --- a/tests/Bridges.Latte2/UIMacros.renderSnippets6.phpt +++ /dev/null @@ -1,45 +0,0 @@ -')) { - Tester\Environment::skip('Test for Latte 2'); -} - - -class TestPresenter extends Nette\Application\UI\Presenter -{ - public function render(string $template) - { - $latte = new Latte\Engine; - $latte->setLoader(new Latte\Loaders\StringLoader); - UIMacros::install($latte->getCompiler()); - $latte->addProvider('snippetBridge', new Nette\Bridges\ApplicationLatte\SnippetBridge($this)); - $latte->onCompile[] = function ($latte) { - $latte->getCompiler()->getMacros()['snippet'][0]->snippetAttribute = 'data-snippet'; - }; - $latte->render($template); - } -} - - -$presenter = new TestPresenter; -ob_start(); -$presenter->render('
hello
'); -$content = ob_get_clean(); -Assert::same('
hello
', $content); - - -$presenter = new TestPresenter; -Assert::exception(function () use ($presenter) { - $presenter->render('
hello
'); -}, Latte\CompileException::class, 'Cannot combine HTML attribute data-snippet with n:snippet.'); diff --git a/tests/Bridges.Latte2/expected/UIMacros.isLinkCurrent.php b/tests/Bridges.Latte2/expected/UIMacros.isLinkCurrent.php deleted file mode 100644 index 15ef390af..000000000 --- a/tests/Bridges.Latte2/expected/UIMacros.isLinkCurrent.php +++ /dev/null @@ -1,22 +0,0 @@ -%A%n:href before n:class - -n:href after n:class - -href before n:class - -href after n:class - -'; - if ($this->global->uiPresenter->getLastCreatedRequestFlag("current")) { - echo 'empty'; - } - echo ' - -'; - if ($this->global->uiPresenter->isLinkCurrent("default")) { - echo 'default'; - } - echo ' - -global->fn->isLinkCurrent)('default') ? 'current' : null%A%>custom function -%A% diff --git a/tests/Bridges.Latte2/expected/UIMacros.renderSnippets.html b/tests/Bridges.Latte2/expected/UIMacros.renderSnippets.html deleted file mode 100644 index 3ff3683ed..000000000 --- a/tests/Bridges.Latte2/expected/UIMacros.renderSnippets.html +++ /dev/null @@ -1,20 +0,0 @@ -
Hello
world! - -

Included file #3 (A, B)

-
- -
Value 1
-
Value 2
-
Value 3
-
- -
Value 1
-
Value 2
-
Value 3
- - -
Hello include snippet
- - -
Foo
-
diff --git a/tests/Bridges.Latte2/templates/include3.latte b/tests/Bridges.Latte2/templates/include3.latte deleted file mode 100644 index 14caf4cb4..000000000 --- a/tests/Bridges.Latte2/templates/include3.latte +++ /dev/null @@ -1 +0,0 @@ -

Included file #3 ({$localvar}, {$hello})

diff --git a/tests/Bridges.Latte2/templates/snippet-include.latte b/tests/Bridges.Latte2/templates/snippet-include.latte deleted file mode 100644 index 8a1ec964d..000000000 --- a/tests/Bridges.Latte2/templates/snippet-include.latte +++ /dev/null @@ -1,25 +0,0 @@ -{snippet hello}Hello{/snippet} world! - -{snippet include} - {include include3.latte localvar => 'A', hello => 'B'} -{/snippet} - -{snippet array} - {foreach [1, 2, 3] as $id} - {snippet "array-$id"}Value {$id}{/snippet} - {/foreach} -{/snippet} - -{snippetArea array2} - {foreach [1, 2, 3] as $id} - {snippet "array2-$id"}Value {$id}{/snippet} - {/foreach} -{/snippetArea} - -{snippetArea foo} - {include snippet-included.latte say => 'Hello include snippet'} -{/snippetArea} - -{snippet nested1} - {snippet nested2}Foo{/snippet} -{/snippet} diff --git a/tests/Bridges.Latte2/templates/snippet-included.latte b/tests/Bridges.Latte2/templates/snippet-included.latte deleted file mode 100644 index a392b6227..000000000 --- a/tests/Bridges.Latte2/templates/snippet-included.latte +++ /dev/null @@ -1 +0,0 @@ -{snippet includeSay}{$say}{/snippet} diff --git a/tests/Bridges.Latte3/Template.getParentName().phpt b/tests/Bridges.Latte3/Template.getParentName().phpt index b354ad1ee..e63f523eb 100644 --- a/tests/Bridges.Latte3/Template.getParentName().phpt +++ b/tests/Bridges.Latte3/Template.getParentName().phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - Tester\Environment::bypassFinals(); $presenter = Mockery::mock(Nette\Application\UI\Presenter::class) diff --git a/tests/Bridges.Latte3/TemplateFactory.customTemplate.phpt b/tests/Bridges.Latte3/TemplateFactory.customTemplate.phpt index 976f99b78..a76c9d50e 100644 --- a/tests/Bridges.Latte3/TemplateFactory.customTemplate.phpt +++ b/tests/Bridges.Latte3/TemplateFactory.customTemplate.phpt @@ -14,10 +14,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - Tester\Environment::bypassFinals(); diff --git a/tests/Bridges.Latte3/TemplateFactory.onCreate.phpt b/tests/Bridges.Latte3/TemplateFactory.onCreate.phpt index ed6e9b61c..987e86aea 100644 --- a/tests/Bridges.Latte3/TemplateFactory.onCreate.phpt +++ b/tests/Bridges.Latte3/TemplateFactory.onCreate.phpt @@ -14,10 +14,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - test('', function () { $engine = new Latte\Engine; diff --git a/tests/Bridges.Latte3/UIExtension.filters.phpt b/tests/Bridges.Latte3/UIExtension.filters.phpt index 952f5a760..0dc89f8cd 100644 --- a/tests/Bridges.Latte3/UIExtension.filters.phpt +++ b/tests/Bridges.Latte3/UIExtension.filters.phpt @@ -10,10 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(null)); diff --git a/tests/Bridges.Latte3/UIExtension.nonce.control.phpt b/tests/Bridges.Latte3/UIExtension.nonce.control.phpt index 9248da8af..cf822c0ab 100644 --- a/tests/Bridges.Latte3/UIExtension.nonce.control.phpt +++ b/tests/Bridges.Latte3/UIExtension.nonce.control.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $response = Mockery::mock(Nette\Http\IResponse::class); $response->shouldReceive('getHeader')->with('Content-Security-Policy')->andReturn("hello 'nonce-abcd123==' world"); diff --git a/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt b/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt index 2f2a8d254..15f0d212d 100644 --- a/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt +++ b/tests/Bridges.Latte3/UIExtension.nonce.presenter.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - Tester\Environment::bypassFinals(); $response = Mockery::mock(Nette\Http\IResponse::class); diff --git a/tests/Bridges.Latte3/isLinkCurrent().phpt b/tests/Bridges.Latte3/isLinkCurrent().phpt index 1ca37dcb3..277027dc9 100644 --- a/tests/Bridges.Latte3/isLinkCurrent().phpt +++ b/tests/Bridges.Latte3/isLinkCurrent().phpt @@ -10,10 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - Tester\Environment::bypassFinals(); $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); diff --git a/tests/Bridges.Latte3/n-snippet.2.phpt b/tests/Bridges.Latte3/n-snippet.2.phpt index 983c46ce5..a5cfc2a20 100644 --- a/tests/Bridges.Latte3/n-snippet.2.phpt +++ b/tests/Bridges.Latte3/n-snippet.2.phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); $latte->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(null)); diff --git a/tests/Bridges.Latte3/n-snippet.block.phpt b/tests/Bridges.Latte3/n-snippet.block.phpt index 107dd6ebc..27a83c2f7 100644 --- a/tests/Bridges.Latte3/n-snippet.block.phpt +++ b/tests/Bridges.Latte3/n-snippet.block.phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); diff --git a/tests/Bridges.Latte3/n-snippet.dynamic.phpt b/tests/Bridges.Latte3/n-snippet.dynamic.phpt index ab2827bca..a794e2d0c 100644 --- a/tests/Bridges.Latte3/n-snippet.dynamic.phpt +++ b/tests/Bridges.Latte3/n-snippet.dynamic.phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); diff --git a/tests/Bridges.Latte3/n-snippet.phpt b/tests/Bridges.Latte3/n-snippet.phpt index c9ff1b893..ac2247eec 100644 --- a/tests/Bridges.Latte3/n-snippet.phpt +++ b/tests/Bridges.Latte3/n-snippet.phpt @@ -6,9 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} class Test { diff --git a/tests/Bridges.Latte3/renderSnippets.phpt b/tests/Bridges.Latte3/renderSnippets.phpt index 675995784..4d113171f 100644 --- a/tests/Bridges.Latte3/renderSnippets.phpt +++ b/tests/Bridges.Latte3/renderSnippets.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class InnerControl extends Nette\Application\UI\Control { diff --git a/tests/Bridges.Latte3/renderSnippets2.phpt b/tests/Bridges.Latte3/renderSnippets2.phpt index 31522dbee..1a092d470 100644 --- a/tests/Bridges.Latte3/renderSnippets2.phpt +++ b/tests/Bridges.Latte3/renderSnippets2.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class InnerControl extends Nette\Application\UI\Control { diff --git a/tests/Bridges.Latte3/renderSnippets3.phpt b/tests/Bridges.Latte3/renderSnippets3.phpt index dd11322d4..65a621014 100644 --- a/tests/Bridges.Latte3/renderSnippets3.phpt +++ b/tests/Bridges.Latte3/renderSnippets3.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class TestControl extends Nette\Application\UI\Control { diff --git a/tests/Bridges.Latte3/renderSnippets4.phpt b/tests/Bridges.Latte3/renderSnippets4.phpt index 3bf12a6e5..c209301c6 100644 --- a/tests/Bridges.Latte3/renderSnippets4.phpt +++ b/tests/Bridges.Latte3/renderSnippets4.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class TestPresenter extends Nette\Application\UI\Presenter { diff --git a/tests/Bridges.Latte3/renderSnippets5.phpt b/tests/Bridges.Latte3/renderSnippets5.phpt index fdbd86159..340e36cf6 100644 --- a/tests/Bridges.Latte3/renderSnippets5.phpt +++ b/tests/Bridges.Latte3/renderSnippets5.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class TestPresenter extends Nette\Application\UI\Presenter { diff --git a/tests/Bridges.Latte3/renderSnippets6.phpt b/tests/Bridges.Latte3/renderSnippets6.phpt index f264135e7..a9cda7417 100644 --- a/tests/Bridges.Latte3/renderSnippets6.phpt +++ b/tests/Bridges.Latte3/renderSnippets6.phpt @@ -11,10 +11,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class TestPresenter extends Nette\Application\UI\Presenter { diff --git a/tests/Bridges.Latte3/renderSnippets7.phpt b/tests/Bridges.Latte3/renderSnippets7.phpt index 63f3cb635..a7689c434 100644 --- a/tests/Bridges.Latte3/renderSnippets7.phpt +++ b/tests/Bridges.Latte3/renderSnippets7.phpt @@ -9,10 +9,6 @@ Tester\Environment::bypassFinals(); require __DIR__ . '/ControlMock.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $dataSets = [ diff --git a/tests/Bridges.Latte3/{control}.2.phpt b/tests/Bridges.Latte3/{control}.2.phpt index bb2cb9171..7086c7fd1 100644 --- a/tests/Bridges.Latte3/{control}.2.phpt +++ b/tests/Bridges.Latte3/{control}.2.phpt @@ -10,10 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class MockComponent { diff --git a/tests/Bridges.Latte3/{control}.3.phpt b/tests/Bridges.Latte3/{control}.3.phpt index 7a270383f..d9317b057 100644 --- a/tests/Bridges.Latte3/{control}.3.phpt +++ b/tests/Bridges.Latte3/{control}.3.phpt @@ -10,9 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} $control = new class { public function render() diff --git a/tests/Bridges.Latte3/{control}.phpt b/tests/Bridges.Latte3/{control}.phpt index a1ba85e15..8d78e3546 100644 --- a/tests/Bridges.Latte3/{control}.phpt +++ b/tests/Bridges.Latte3/{control}.phpt @@ -10,10 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); diff --git a/tests/Bridges.Latte3/{ifCurrent}.phpt b/tests/Bridges.Latte3/{ifCurrent}.phpt index 3c9ee133e..0be5f05e2 100644 --- a/tests/Bridges.Latte3/{ifCurrent}.phpt +++ b/tests/Bridges.Latte3/{ifCurrent}.phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - Tester\Environment::bypassFinals(); $latte = new Latte\Engine; diff --git a/tests/Bridges.Latte3/{link}.2.phpt b/tests/Bridges.Latte3/{link}.2.phpt index 816283b42..7fc270038 100644 --- a/tests/Bridges.Latte3/{link}.2.phpt +++ b/tests/Bridges.Latte3/{link}.2.phpt @@ -10,10 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - class MockControl { diff --git a/tests/Bridges.Latte3/{link}.phpt b/tests/Bridges.Latte3/{link}.phpt index e2457c9a7..9d8e296e6 100644 --- a/tests/Bridges.Latte3/{link}.phpt +++ b/tests/Bridges.Latte3/{link}.phpt @@ -10,10 +10,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); diff --git a/tests/Bridges.Latte3/{snippet}.dynamic.phpt b/tests/Bridges.Latte3/{snippet}.dynamic.phpt index 3b2068ed0..1eb5aacdd 100644 --- a/tests/Bridges.Latte3/{snippet}.dynamic.phpt +++ b/tests/Bridges.Latte3/{snippet}.dynamic.phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); diff --git a/tests/Bridges.Latte3/{snippet}.phpt b/tests/Bridges.Latte3/{snippet}.phpt index bf9022dce..5afa062ef 100644 --- a/tests/Bridges.Latte3/{snippet}.phpt +++ b/tests/Bridges.Latte3/{snippet}.phpt @@ -6,10 +6,6 @@ use Tester\Assert; require __DIR__ . '/../bootstrap.php'; -if (version_compare(Latte\Engine::VERSION, '3', '<')) { - Tester\Environment::skip('Test for Latte 3'); -} - $latte = new Latte\Engine; $latte->setLoader(new Latte\Loaders\StringLoader); From 9fc5371ff8e3b4cc79fc6942081d9eeaa5344cab Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 15 Oct 2021 18:14:52 +0200 Subject: [PATCH 10/23] removed compatibility for old class names - inteface Nette\Application\IRouter replaced by Nette\Routing\Router --- src/Application/Routers/Route.php | 3 --- src/Application/Routers/RouteList.php | 3 --- src/Application/Routers/SimpleRouter.php | 3 --- src/Application/UI/Component.php | 3 --- src/Application/UI/ComponentReflection.php | 3 --- src/compatibility-intf.php | 11 --------- src/compatibility.php | 28 ---------------------- 7 files changed, 54 deletions(-) delete mode 100644 src/compatibility.php diff --git a/src/Application/Routers/Route.php b/src/Application/Routers/Route.php index ba611da0e..2e22d9679 100644 --- a/src/Application/Routers/Route.php +++ b/src/Application/Routers/Route.php @@ -187,6 +187,3 @@ public static function path2presenter(string $s): string return $s; } } - - -interface_exists(Nette\Application\IRouter::class); diff --git a/src/Application/Routers/RouteList.php b/src/Application/Routers/RouteList.php index 99e2a6d17..126c0d053 100644 --- a/src/Application/Routers/RouteList.php +++ b/src/Application/Routers/RouteList.php @@ -139,6 +139,3 @@ public function offsetUnset($index): void $this->modify($index, null); } } - - -interface_exists(Nette\Application\IRouter::class); diff --git a/src/Application/Routers/SimpleRouter.php b/src/Application/Routers/SimpleRouter.php index 35d2c8ad9..2f99c51ba 100644 --- a/src/Application/Routers/SimpleRouter.php +++ b/src/Application/Routers/SimpleRouter.php @@ -38,6 +38,3 @@ public function __construct(array|string $defaults = []) parent::__construct($defaults); } } - - -interface_exists(Nette\Application\IRouter::class); diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index 73111c884..e261443ad 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -342,6 +342,3 @@ public function error(string $message = '', int $httpCode = Nette\Http\IResponse throw new Nette\Application\BadRequestException($message, $httpCode); } } - - -class_exists(PresenterComponent::class); diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 0c7d8b004..481c9bc8d 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -341,6 +341,3 @@ public static function getClassesAndTraits(string $class): array return $res; } } - - -class_exists(PresenterComponentReflection::class); diff --git a/src/compatibility-intf.php b/src/compatibility-intf.php index 5bee25bb1..0d5b2f8ff 100644 --- a/src/compatibility-intf.php +++ b/src/compatibility-intf.php @@ -9,17 +9,6 @@ namespace Nette\Application; -use Nette; - -if (false) { - /** @deprecated use Nette\Routing\Router */ - interface IRouter extends Nette\Routing\Router - { - } -} elseif (!interface_exists(IRouter::class)) { - class_alias(Nette\Routing\Router::class, IRouter::class); -} - if (false) { /** @deprecated use Nette\Application\Response */ interface IResponse extends Response diff --git a/src/compatibility.php b/src/compatibility.php deleted file mode 100644 index cf55aa4bc..000000000 --- a/src/compatibility.php +++ /dev/null @@ -1,28 +0,0 @@ - Date: Thu, 8 Feb 2024 21:39:57 +0100 Subject: [PATCH 11/23] added type hints (BC break) --- src/Bridges/ApplicationLatte/TemplateFactory.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index 5ae96343d..31acb518c 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -37,8 +37,7 @@ public function __construct( } - /** @return Template */ - public function createTemplate(?UI\Control $control = null, ?string $class = null): UI\Template + public function createTemplate(?UI\Control $control = null, ?string $class = null): Template { $class ??= $this->templateClass; if (!is_a($class, Template::class, allow_string: true)) { From 7787aff678adf886458dbc7bbd4051a25ccf722f Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 15 Oct 2021 18:19:42 +0200 Subject: [PATCH 12/23] RouteList: array access is deprecated --- src/Application/Routers/RouteList.php | 10 ++++++++++ tests/Bridges.DI/RoutingExtension.basic.phpt | 7 ++++--- tests/Routers/RouteList.basic.phpt | 3 +-- tests/Routers/RouteList.modules.phpt | 5 ++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Application/Routers/RouteList.php b/src/Application/Routers/RouteList.php index 126c0d053..1305cc64e 100644 --- a/src/Application/Routers/RouteList.php +++ b/src/Application/Routers/RouteList.php @@ -95,6 +95,13 @@ public function getModule(): ?string */ public function offsetSet($index, $router): void { + if ($router instanceof Route) { + trigger_error('Usage `$router[] = new Route(...)` is deprecated, use `$router->addRoute(...)`.', E_USER_DEPRECATED); + } else { + $class = getclass($router); + trigger_error("Usage `\$router[] = new $class` is deprecated, use `\$router->add(new $class)`.", E_USER_DEPRECATED); + } + if ($index === null) { $this->add($router); } else { @@ -109,6 +116,7 @@ public function offsetSet($index, $router): void */ public function offsetGet($index): Nette\Routing\Router { + trigger_error('Usage `$route = $router[...]` is deprecated, use `$router->getRouters()`.', E_USER_DEPRECATED); if (!$this->offsetExists($index)) { throw new Nette\OutOfRangeException('Offset invalid or out of range'); } @@ -122,6 +130,7 @@ public function offsetGet($index): Nette\Routing\Router */ public function offsetExists($index): bool { + trigger_error('Usage `isset($router[...])` is deprecated.', E_USER_DEPRECATED); return is_int($index) && $index >= 0 && $index < count($this->getRouters()); } @@ -132,6 +141,7 @@ public function offsetExists($index): bool */ public function offsetUnset($index): void { + trigger_error('Usage `unset($router[$index])` is deprecated, use `$router->modify($index, null)`.', E_USER_DEPRECATED); if (!$this->offsetExists($index)) { throw new Nette\OutOfRangeException('Offset invalid or out of range'); } diff --git a/tests/Bridges.DI/RoutingExtension.basic.phpt b/tests/Bridges.DI/RoutingExtension.basic.phpt index a8e13d1a6..0b6f57a72 100644 --- a/tests/Bridges.DI/RoutingExtension.basic.phpt +++ b/tests/Bridges.DI/RoutingExtension.basic.phpt @@ -31,9 +31,10 @@ test('', function () { $container = new Container1; $router = $container->getService('router'); Assert::type(Nette\Application\Routers\RouteList::class, $router); - Assert::same('index.php', $router[0]->getMask()); - Assert::same('item/', $router[1]->getMask()); + $routes = $router->getRouters(); + Assert::same('index.php', $routes[0]->getMask()); + Assert::same('item/', $routes[1]->getMask()); Assert::type(Nette\Application\Routers\RouteList::class, $router); - Assert::type(Nette\Application\Routers\Route::class, $router[0]); + Assert::type(Nette\Application\Routers\Route::class, $routes[0]); }); diff --git a/tests/Routers/RouteList.basic.phpt b/tests/Routers/RouteList.basic.phpt index 22afeda6c..b4783db95 100644 --- a/tests/Routers/RouteList.basic.phpt +++ b/tests/Routers/RouteList.basic.phpt @@ -6,7 +6,6 @@ declare(strict_types=1); -use Nette\Application\Routers\Route; use Nette\Application\Routers\RouteList; use Tester\Assert; @@ -17,7 +16,7 @@ require __DIR__ . '/Route.php'; $list = new RouteList; -$list[] = new Route('//'); +$list->addRoute('//'); Assert::same('http://example.com/front.homepage/', testRouteOut($list, ['presenter' => 'Front:Homepage'])); diff --git a/tests/Routers/RouteList.modules.phpt b/tests/Routers/RouteList.modules.phpt index db2aff0d2..ff1e15193 100644 --- a/tests/Routers/RouteList.modules.phpt +++ b/tests/Routers/RouteList.modules.phpt @@ -6,7 +6,6 @@ declare(strict_types=1); -use Nette\Application\Routers\Route; use Nette\Application\Routers\RouteList; @@ -16,12 +15,12 @@ require __DIR__ . '/Route.php'; $list = new RouteList; -$list[] = new Route('auth/[/]', [ +$list->addRoute('auth/[/]', [ 'module' => 'Auth', 'presenter' => 'Homepage', 'action' => 'default', ]); -$list[] = new Route('[/]', [ +$list->addRoute('[/]', [ 'module' => 'Default', 'presenter' => 'Homepage', 'action' => 'default', From 8a01270f0b56870a546eb46d7230995cd2c22738 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 24 Oct 2022 19:12:55 +0200 Subject: [PATCH 13/23] Revert "UI\PresenterComponent: removed references created by loadState() for persistent parameters. [Closes nette/nette#703][Closes nette/nette#703][Closes #69]" (possible BC break) This reverts commit cda17f460d020b0f042364d4e140742022a7e94d. See https://forum.nette.org/cs/35528-stejne-pojmenovany-parametr-akce-presenteru-a-persistentni-odlisne-chovani-v-nette-2-0-oproti-aktualnimu#p221742 BC break: Property must be nullable, ie: #[Persistent] public ?int $foo --- src/Application/UI/Component.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index e261443ad..9d31d6681 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -165,9 +165,9 @@ public function loadState(array $params): void )); } - $this->$name = $params[$name]; + $this->$name = &$params[$name]; } else { - $params[$name] = $this->$name ?? null; + $params[$name] = &$this->$name; } } @@ -201,7 +201,7 @@ final public function getParameter(string $name): mixed */ final public function getParameters(): array { - return $this->params; + return array_map(fn($item) => $item, $this->params); } From 9f9e96ad655f479fa3d7a3dff10cceec5985d194 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sun, 12 Sep 2021 23:44:04 +0200 Subject: [PATCH 14/23] Component: only UI components can be added to presenter/component (BC break) WIP --- src/Application/UI/Component.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index 9d31d6681..ec65162ca 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -71,15 +71,17 @@ public function getUniqueId(): string } - protected function createComponent(string $name): ?Nette\ComponentModel\IComponent + public function addComponent( + Nette\ComponentModel\IComponent $component, + ?string $name, + ?string $insertBefore = null, + ): static { - $res = parent::createComponent($name); - if ($res && !$res instanceof SignalReceiver && !$res instanceof StatePersistent) { - $type = $res::class; - trigger_error("It seems that component '$name' of type $type is not intended to be used in the Presenter."); + if (!$component instanceof SignalReceiver && !$component instanceof StatePersistent) { + throw new Nette\InvalidStateException("Component '$name' of type " . get_debug_type($component) . ' is not intended to be used in the Presenter.'); } - return $res; + return parent::addComponent($component, $name, $insertBefore = null); } From d0b663e6974051a7adfa988d1b977236dc97ddb1 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Fri, 24 Sep 2021 14:06:27 +0200 Subject: [PATCH 15/23] deprecated magic properties except for $template & $payload (BC break) --- src/Application/Request.php | 10 +++++----- src/Application/UI/Component.php | 4 ++-- src/Application/UI/ComponentReflection.php | 4 ++-- src/Application/UI/Presenter.php | 12 ++++++------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Application/Request.php b/src/Application/Request.php index 5c9985ce3..10b5f2782 100644 --- a/src/Application/Request.php +++ b/src/Application/Request.php @@ -15,11 +15,11 @@ /** * Presenter request. * - * @property string $presenterName - * @property array $parameters - * @property array $post - * @property array $files - * @property string|null $method + * @property-deprecated string $presenterName + * @property-deprecated array $parameters + * @property-deprecated array $post + * @property-deprecated array $files + * @property-deprecated string|null $method */ final class Request { diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index ec65162ca..e86cdd8c3 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -19,8 +19,8 @@ * other child components, and interact with user. Components have properties * for storing their status, and responds to user command. * - * @property-read Presenter $presenter - * @property-read bool $linkCurrent + * @property-deprecated Presenter $presenter + * @property-deprecated bool $linkCurrent */ abstract class Component extends Nette\ComponentModel\Container implements SignalReceiver, StatePersistent, \ArrayAccess { diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 481c9bc8d..0fc0f98c0 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -14,8 +14,8 @@ /** * Helpers for Presenter & Component. - * @property-read string $name - * @property-read string $fileName + * @property-deprecated string $name + * @property-deprecated string $fileName * @internal */ final class ComponentReflection extends \ReflectionClass diff --git a/src/Application/UI/Presenter.php b/src/Application/UI/Presenter.php index 23f57f178..72edadfd5 100644 --- a/src/Application/UI/Presenter.php +++ b/src/Application/UI/Presenter.php @@ -20,13 +20,13 @@ /** * Presenter component represents a webpage instance. It converts Request to Response. * - * @property-read Nette\Application\Request $request - * @property-read string $action - * @property string $view - * @property string|bool $layout + * @property-deprecated Nette\Application\Request $request + * @property-deprecated string $action + * @property-deprecated string $view + * @property-deprecated string|bool $layout * @property-read \stdClass $payload - * @property-read Nette\Http\Session $session - * @property-read Nette\Security\User $user + * @property-deprecated Nette\Http\Session $session + * @property-deprecated Nette\Security\User $user */ abstract class Presenter extends Control implements Application\IPresenter { From 663815624809ef4f2490eb345272746b89272c8f Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 20 Oct 2021 01:53:14 +0200 Subject: [PATCH 16/23] Component::link() & etc uses variadic parameter --- src/Application/UI/Component.php | 50 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index e86cdd8c3..5654674b3 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -248,15 +248,15 @@ public static function formatSignalMethod(string $signal): string /** * Generates URL to presenter, action or signal. * @param string $destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" - * @param array|mixed $args + * @param mixed ...$args * @throws InvalidLinkException */ - public function link(string $destination, $args = []): string + public function link(string $destination, ...$args): string { try { - $args = func_num_args() < 3 && is_array($args) - ? $args - : array_slice(func_get_args(), 1); + $args = count($args) === 1 && is_array($args[0] ?? null) + ? $args[0] + : $args; return $this->getPresenter()->createRequest($this, $destination, $args, 'link'); } catch (InvalidLinkException $e) { @@ -268,13 +268,13 @@ public function link(string $destination, $args = []): string /** * Returns destination as Link object. * @param string $destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" - * @param array|mixed $args + * @param mixed ...$args */ - public function lazyLink(string $destination, $args = []): Link + public function lazyLink(string $destination, ...$args): Link { - $args = func_num_args() < 3 && is_array($args) - ? $args - : array_slice(func_get_args(), 1); + $args = count($args) === 1 && is_array($args[0] ?? null) + ? $args[0] + : $args; return new Link($this, $destination, $args); } @@ -282,15 +282,15 @@ public function lazyLink(string $destination, $args = []): Link /** * Determines whether it links to the current page. * @param string $destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" - * @param array|mixed $args + * @param mixed ...$args * @throws InvalidLinkException */ - public function isLinkCurrent(?string $destination = null, $args = []): bool + public function isLinkCurrent(?string $destination = null, ...$args): bool { if ($destination !== null) { - $args = func_num_args() < 3 && is_array($args) - ? $args - : array_slice(func_get_args(), 1); + $args = count($args) === 1 && is_array($args[0] ?? null) + ? $args[0] + : $args; $this->getPresenter()->createRequest($this, $destination, $args, 'test'); } @@ -301,15 +301,15 @@ public function isLinkCurrent(?string $destination = null, $args = []): bool /** * Redirect to another presenter, action or signal. * @param string $destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" - * @param array|mixed $args + * @param mixed ...$args * @return never * @throws Nette\Application\AbortException */ - public function redirect(string $destination, $args = []): void + public function redirect(string $destination, ...$args): void { - $args = func_num_args() < 3 && is_array($args) - ? $args - : array_slice(func_get_args(), 1); + $args = count($args) === 1 && is_array($args[0] ?? null) + ? $args[0] + : $args; $presenter = $this->getPresenter(); $presenter->redirectUrl($presenter->createRequest($this, $destination, $args, 'redirect')); } @@ -318,15 +318,15 @@ public function redirect(string $destination, $args = []): void /** * Permanently redirects to presenter, action or signal. * @param string $destination in format "[//] [[[module:]presenter:]action | signal! | this] [#fragment]" - * @param array|mixed $args + * @param mixed ...$args * @return never * @throws Nette\Application\AbortException */ - public function redirectPermanent(string $destination, $args = []): void + public function redirectPermanent(string $destination, ...$args): void { - $args = func_num_args() < 3 && is_array($args) - ? $args - : array_slice(func_get_args(), 1); + $args = count($args) === 1 && is_array($args[0] ?? null) + ? $args[0] + : $args; $presenter = $this->getPresenter(); $presenter->redirectUrl( $presenter->createRequest($this, $destination, $args, 'redirect'), From 050427f4802d81d40bc84c49601359adf2b104f8 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 21 Jun 2022 15:27:13 +0200 Subject: [PATCH 17/23] Component::getParameter() $default is deprecated --- src/Application/UI/Component.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Application/UI/Component.php b/src/Application/UI/Component.php index 5654674b3..eb1242cca 100644 --- a/src/Application/UI/Component.php +++ b/src/Application/UI/Component.php @@ -192,6 +192,7 @@ public function saveState(array &$params): void final public function getParameter(string $name): mixed { if (func_num_args() > 1) { + trigger_error(__METHOD__ . '() parameter $default is deprecated, use operator ??', E_USER_DEPRECATED); $default = func_get_arg(1); } return $this->params[$name] ?? $default ?? null; From 0ee3273cecf930ae652a5741ba1ee5be21f702e6 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 12 Dec 2023 00:11:10 +0100 Subject: [PATCH 18/23] Presenter: removed constructor (BC break!) --- src/Application/UI/Presenter.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Application/UI/Presenter.php b/src/Application/UI/Presenter.php index 72edadfd5..7f383f419 100644 --- a/src/Application/UI/Presenter.php +++ b/src/Application/UI/Presenter.php @@ -114,11 +114,6 @@ abstract class Presenter extends Control implements Application\IPresenter private Nette\Http\UrlScript $refUrlCache; - public function __construct() - { - } - - final public function getRequest(): ?Application\Request { return $this->request; From f2026a807f016eba85a2fe0a47b0567e313c443e Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 6 Apr 2024 20:49:11 +0200 Subject: [PATCH 19/23] @annotations are deprecated (BC break) --- src/Application/UI/ComponentReflection.php | 13 +++++- src/Application/UI/MethodReflection.php | 4 ++ src/Application/UI/Presenter.php | 2 +- .../ComponentReflection.parseAnnotation.phpt | 44 ------------------- tests/UI/Presenter.getParameters.phpt | 2 +- .../UI/Presenter.getPersistentComponents.phpt | 12 +---- tests/UI/Presenter.link().persistent.phpt | 17 +++---- tests/UI/Presenter.link().phpt | 23 +++++----- tests/UI/fixtures/ParamPresenter.php | 2 +- 9 files changed, 40 insertions(+), 79 deletions(-) delete mode 100644 tests/UI/ComponentReflection.parseAnnotation.phpt diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 0fc0f98c0..1dda9d57a 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -26,7 +26,7 @@ final class ComponentReflection extends \ReflectionClass /** - * Returns array of class properties that are public and have attribute #[Persistent] or #[Parameter] or annotation @persistent. + * Returns array of class properties that are public and have attribute #[Persistent] or #[Parameter]. */ public function getParameters(): array { @@ -72,7 +72,7 @@ public function getParameters(): array /** - * Returns array of persistent properties. They are public and have attribute #[Persistent] or annotation @persistent. + * Returns array of persistent properties. They are public and have attribute #[Persistent]. */ public function getPersistentParams(): array { @@ -251,6 +251,7 @@ private static function castScalar(mixed &$val, string $type): bool /** * Returns an annotation value. + * @deprecated */ public static function parseAnnotation(\Reflector $ref, string $name): ?array { @@ -268,6 +269,12 @@ public static function parseAnnotation(\Reflector $ref, string $name): ?array } } + $attr = match ($name) { + 'persistent' => '#[Nette\Application\Attributes\Persistent]', + 'deprecated' => '#[Nette\Application\Attributes\Deprecated]', + 'crossOrigin' => '#[Nette\Application\Attributes\Request(sameOrigin: false)]', + }; + trigger_error("Annotation @$name is deprecated, use $attr (used in " . Nette\Utils\Reflection::toString($ref) . ')', E_USER_DEPRECATED); return $res; } @@ -286,6 +293,7 @@ public static function getType(\ReflectionParameter|\ReflectionProperty $item): /** * Has class specified annotation? + * @deprecated */ public function hasAnnotation(string $name): bool { @@ -295,6 +303,7 @@ public function hasAnnotation(string $name): bool /** * Returns an annotation value. + * @deprecated */ public function getAnnotation(string $name): mixed { diff --git a/src/Application/UI/MethodReflection.php b/src/Application/UI/MethodReflection.php index f576deeaf..f84687356 100644 --- a/src/Application/UI/MethodReflection.php +++ b/src/Application/UI/MethodReflection.php @@ -17,18 +17,22 @@ final class MethodReflection extends \ReflectionMethod { /** * Has method specified annotation? + * @deprecated */ public function hasAnnotation(string $name): bool { + trigger_error(__METHOD__ . '() is deprecated', E_USER_DEPRECATED); return (bool) ComponentReflection::parseAnnotation($this, $name); } /** * Returns an annotation value. + * @deprecated */ public function getAnnotation(string $name): mixed { + trigger_error(__METHOD__ . '() is deprecated', E_USER_DEPRECATED); $res = ComponentReflection::parseAnnotation($this, $name); return $res ? end($res) : null; } diff --git a/src/Application/UI/Presenter.php b/src/Application/UI/Presenter.php index 7f383f419..1adca3b9b 100644 --- a/src/Application/UI/Presenter.php +++ b/src/Application/UI/Presenter.php @@ -1140,7 +1140,7 @@ public function restoreRequest(string $key): void /** * Returns array of persistent components. - * This default implementation detects components by class-level annotation @persistent(cmp1, cmp2). + * This default implementation detects components by class-level attribute #[Persistent(cmp1, cmp2)]. */ public static function getPersistentComponents(): array { diff --git a/tests/UI/ComponentReflection.parseAnnotation.phpt b/tests/UI/ComponentReflection.parseAnnotation.phpt deleted file mode 100644 index 278b5e7d1..000000000 --- a/tests/UI/ComponentReflection.parseAnnotation.phpt +++ /dev/null @@ -1,44 +0,0 @@ - Date: Sat, 6 Apr 2024 18:44:44 +0200 Subject: [PATCH 20/23] LatteFactory: $control is passed to create() (BC break) --- src/Bridges/ApplicationDI/LatteExtension.php | 5 +++-- src/Bridges/ApplicationLatte/LatteFactory.php | 3 ++- src/Bridges/ApplicationLatte/TemplateFactory.php | 4 ---- tests/Bridges.DI/LatteExtension.basic.phpt | 14 -------------- 4 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/Bridges/ApplicationDI/LatteExtension.php b/src/Bridges/ApplicationDI/LatteExtension.php index 18d1362ee..82673aa13 100644 --- a/src/Bridges/ApplicationDI/LatteExtension.php +++ b/src/Bridges/ApplicationDI/LatteExtension.php @@ -59,8 +59,9 @@ public function loadConfiguration(): void ->addSetup('setAutoRefresh', [$this->debugMode]) ->addSetup('setStrictTypes', [$config->strictTypes]) ->addSetup('setStrictParsing', [$config->strictParsing]) - ->addSetup('enablePhpLinter', [$config->phpLinter]) - ->addSetup('?', [$builder::literal('func_num_args() && $service->addExtension(new Nette\Bridges\ApplicationLatte\UIExtension(func_get_arg(0)))')]); + ->addSetup('enablePhpLinter', [$config->phpLinter]); + + $this->addExtension(new Statement(ApplicationLatte\UIExtension::class, [$builder::literal('$control')])); if ($cache = $builder->getByType(Nette\Caching\Storage::class)) { $this->addExtension(new Statement(Nette\Bridges\CacheLatte\CacheExtension::class, [$builder->getDefinition($cache)])); diff --git a/src/Bridges/ApplicationLatte/LatteFactory.php b/src/Bridges/ApplicationLatte/LatteFactory.php index e6d2c8842..71e1ced0c 100644 --- a/src/Bridges/ApplicationLatte/LatteFactory.php +++ b/src/Bridges/ApplicationLatte/LatteFactory.php @@ -10,11 +10,12 @@ namespace Nette\Bridges\ApplicationLatte; use Latte; +use Nette\Application\UI\Control; interface LatteFactory { - function create(/*?Control $control = null*/): Latte\Engine; + function create(?Control $control = null): Latte\Engine; } diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index 31acb518c..1f2cbb764 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -48,10 +48,6 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul $template = new $class($latte); $presenter = $control?->getPresenterIfExists(); - if (!Nette\Utils\Arrays::some($latte->getExtensions(), fn($e) => $e instanceof UIExtension)) { - $latte->addExtension(new UIExtension($control)); - } - // default parameters $baseUrl = $this->httpRequest ? rtrim($this->httpRequest->getUrl()->withoutUserInfo()->getBaseUrl(), '/') diff --git a/tests/Bridges.DI/LatteExtension.basic.phpt b/tests/Bridges.DI/LatteExtension.basic.phpt index 34ea641d5..a3a13d48f 100644 --- a/tests/Bridges.DI/LatteExtension.basic.phpt +++ b/tests/Bridges.DI/LatteExtension.basic.phpt @@ -59,20 +59,6 @@ Assert::type(Nette\Bridges\ApplicationLatte\LatteFactory::class, $container->get $latte = $container->getService('nette.latteFactory')->create(); $extensions = Assert::with($latte, fn() => $this->extensions); -Assert::equal([ - new Latte\Essential\CoreExtension, - new Latte\Sandbox\SandboxExtension, - new Nette\Bridges\FormsLatte\FormsExtension, - new MyExtension, - new MyExtension(1), - new MyExtension(2), - new MyExtension, -], $extensions); - -// UIExtension is added -$latte = $container->getService('nette.latteFactory')->create(null); -$extensions = Assert::with($latte, fn() => $this->extensions); - Assert::equal([ new Latte\Essential\CoreExtension, new Latte\Sandbox\SandboxExtension, From 2dddce74a4e1e13f90a7091a748d1367d0cb7621 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 22 Jan 2024 00:20:18 +0100 Subject: [PATCH 21/23] uses nette/routing 4.0 --- src/Application/Routers/RouteList.php | 4 ++-- src/Bridges/ApplicationTracy/RoutingPanel.php | 2 +- tests/Routers/RouteList.addRoute.phpt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Application/Routers/RouteList.php b/src/Application/Routers/RouteList.php index 1305cc64e..6ed3d079c 100644 --- a/src/Application/Routers/RouteList.php +++ b/src/Application/Routers/RouteList.php @@ -65,10 +65,10 @@ public function addRoute( #[Language('TEXT')] string $mask, array|string|\Closure $metadata = [], - int|bool $oneWay = 0, + bool $oneWay = false, ): static { - $this->add(new Route($mask, $metadata), (int) $oneWay); + $this->add(new Route($mask, $metadata), $oneWay); return $this; } diff --git a/src/Bridges/ApplicationTracy/RoutingPanel.php b/src/Bridges/ApplicationTracy/RoutingPanel.php index fa0209b46..39e4fee73 100644 --- a/src/Bridges/ApplicationTracy/RoutingPanel.php +++ b/src/Bridges/ApplicationTracy/RoutingPanel.php @@ -85,7 +85,7 @@ private function analyse(Routing\RouteList $router, ?Nette\Http\IRequest $httpRe continue; } - $matched = $flags[$i] & $router::ONE_WAY ? 'oneway' : 'no'; + $matched = empty($flags[$i]['oneWay']) ? 'no' : 'oneway'; $params = $e = null; try { if ( diff --git a/tests/Routers/RouteList.addRoute.phpt b/tests/Routers/RouteList.addRoute.phpt index fd6ab423a..068f66805 100644 --- a/tests/Routers/RouteList.addRoute.phpt +++ b/tests/Routers/RouteList.addRoute.phpt @@ -12,7 +12,7 @@ require __DIR__ . '/Route.php'; $list = new RouteList; $list->addRoute('foo', ['presenter' => 'foo'], RouteList::ONE_WAY); -$list->addRoute('bar', ['presenter' => 'bar'], RouteList::ONE_WAY); +$list->addRoute('bar', ['presenter' => 'bar'], oneWay: true); $list->addRoute('hello', ['presenter' => 'hello']); From 488ccc6ff9dc8e4acdc4c932a1580aa91f878611 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Mon, 9 Jan 2023 14:07:48 +0100 Subject: [PATCH 22/23] LatteExtension: added option 'variables' --- src/Bridges/ApplicationDI/LatteExtension.php | 7 +- .../ApplicationLatte/DefaultTemplate.php | 1 + .../ApplicationLatte/TemplateFactory.php | 2 + .../Bridges.DI/LatteExtension.variables.phpt | 74 +++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/Bridges.DI/LatteExtension.variables.phpt diff --git a/src/Bridges/ApplicationDI/LatteExtension.php b/src/Bridges/ApplicationDI/LatteExtension.php index 82673aa13..7751b8904 100644 --- a/src/Bridges/ApplicationDI/LatteExtension.php +++ b/src/Bridges/ApplicationDI/LatteExtension.php @@ -38,6 +38,7 @@ public function getConfigSchema(): Nette\Schema\Schema 'strictTypes' => Expect::bool(false), 'strictParsing' => Expect::bool(false), 'phpLinter' => Expect::string(), + 'variables' => Expect::array([]), ]); } @@ -75,8 +76,10 @@ public function loadConfiguration(): void } $builder->addDefinition($this->prefix('templateFactory')) - ->setFactory(ApplicationLatte\TemplateFactory::class) - ->setArguments(['templateClass' => $config->templateClass]); + ->setFactory(ApplicationLatte\TemplateFactory::class, [ + 'templateClass' => $config->templateClass, + 'configVars' => $config->variables, + ]); if ($this->name === 'latte') { $builder->addAlias('nette.latteFactory', $this->prefix('latteFactory')); diff --git a/src/Bridges/ApplicationLatte/DefaultTemplate.php b/src/Bridges/ApplicationLatte/DefaultTemplate.php index 29d761663..85eae9c6d 100644 --- a/src/Bridges/ApplicationLatte/DefaultTemplate.php +++ b/src/Bridges/ApplicationLatte/DefaultTemplate.php @@ -29,6 +29,7 @@ final class DefaultTemplate extends Template /** @var \stdClass[] */ public array $flashes = []; + public \stdClass $config; /** diff --git a/src/Bridges/ApplicationLatte/TemplateFactory.php b/src/Bridges/ApplicationLatte/TemplateFactory.php index 1f2cbb764..5dc9cf50f 100644 --- a/src/Bridges/ApplicationLatte/TemplateFactory.php +++ b/src/Bridges/ApplicationLatte/TemplateFactory.php @@ -28,6 +28,7 @@ public function __construct( private readonly ?Nette\Http\IRequest $httpRequest = null, private readonly ?Nette\Security\User $user = null, $templateClass = null, + private array $configVars = [], ) { if ($templateClass && (!class_exists($templateClass) || !is_a($templateClass, Template::class, true))) { throw new Nette\InvalidArgumentException("Class $templateClass does not implement " . Template::class . ' or it does not exist.'); @@ -63,6 +64,7 @@ public function createTemplate(?UI\Control $control = null, ?string $class = nul 'flashes' => $flashes, 'control' => $control, 'presenter' => $presenter, + 'config' => $control instanceof UI\Presenter && $this->configVars ? (object) $this->configVars : null, ]; foreach ($params as $key => $value) { diff --git a/tests/Bridges.DI/LatteExtension.variables.phpt b/tests/Bridges.DI/LatteExtension.variables.phpt new file mode 100644 index 000000000..c7051e5d8 --- /dev/null +++ b/tests/Bridges.DI/LatteExtension.variables.phpt @@ -0,0 +1,74 @@ +load(Tester\FileMock::create(' + latte: + variables: + ', 'neon')); + + $compiler = new DI\Compiler; + $compiler->addExtension('latte', new Nette\Bridges\ApplicationDI\LatteExtension('', false)); + $code = $compiler + ->addConfig($config) + ->setClassName('Container1') + ->compile(); + eval($code); + + $container = new Container1; + $latteFactory = $container->getService('latte.templateFactory'); + $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); + $presenter->shouldReceive('getHttpResponse')->andReturn(Mockery::mock(Nette\Http\IResponse::class)->shouldIgnoreMissing()); + $presenter->shouldIgnoreMissing(); + + $template = $latteFactory->createTemplate($presenter); + Assert::notContains('config', $template->getParameters()); +}); + + +test('presenter presence', function () { + $loader = new DI\Config\Loader; + $config = $loader->load(Tester\FileMock::create(' + latte: + variables: + foo: bar + ', 'neon')); + + $compiler = new DI\Compiler; + $compiler->addExtension('latte', new Nette\Bridges\ApplicationDI\LatteExtension('', false)); + $code = $compiler + ->addConfig($config) + ->setClassName('Container2') + ->compile(); + eval($code); + + $container = new Container2; + $latteFactory = $container->getService('latte.templateFactory'); + $template = $latteFactory->createTemplate(); + Assert::notContains('config', $template->getParameters()); + + + $presenter = Mockery::mock(Nette\Application\UI\Presenter::class); + $presenter->shouldReceive('getHttpResponse')->andReturn(Mockery::mock(Nette\Http\IResponse::class)->shouldIgnoreMissing()); + $presenter->shouldIgnoreMissing(); + + $template = $latteFactory->createTemplate($presenter); + Assert::equal( + (object) ['foo' => 'bar'], + $template->getParameters()['config'], + ); +}); From e0ef23e536921754a239544a24c8afc30038def3 Mon Sep 17 00:00:00 2001 From: Jan Vejvar Date: Sun, 7 Apr 2024 03:20:19 +0200 Subject: [PATCH 23/23] Latte bridge: add block rendering support --- src/Bridges/ApplicationLatte/Template.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Bridges/ApplicationLatte/Template.php b/src/Bridges/ApplicationLatte/Template.php index b9850a6f5..abdd41d89 100644 --- a/src/Bridges/ApplicationLatte/Template.php +++ b/src/Bridges/ApplicationLatte/Template.php @@ -36,20 +36,20 @@ final public function getLatte(): Latte\Engine /** * Renders template to output. */ - public function render(?string $file = null, array $params = []): void + public function render(?string $file = null, array $params = [], ?string $block = null): void { Nette\Utils\Arrays::toObject($params, $this); - $this->latte->render($file ?: $this->file, $this); + $this->latte->render($file ?: $this->file, $this, $block); } /** * Renders template to output. */ - public function renderToString(?string $file = null, array $params = []): string + public function renderToString(?string $file = null, array $params = [], ?string $block = null): string { Nette\Utils\Arrays::toObject($params, $this); - return $this->latte->renderToString($file ?: $this->file, $this); + return $this->latte->renderToString($file ?: $this->file, $this, $block); }