Skip to content

Commit 74bc6f6

Browse files
committed
Presenter: added parseDestination(), taken out from createRequest()
1 parent 1c58150 commit 74bc6f6

File tree

2 files changed

+90
-10
lines changed

2 files changed

+90
-10
lines changed

src/Application/UI/Presenter.php

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -725,17 +725,11 @@ protected function createRequest(Component $component, string $destination, arra
725725

726726
$this->lastCreatedRequest = $this->lastCreatedRequestFlag = NULL;
727727

728-
// PARSE DESTINATION
729-
if (!preg_match('~^ (?<absolute>//)?+ (?<path>[^!?#]++) (?<signal>!)?+ (?<query>\?[^#]*)?+ (?<fragment>\#.*)?+ $~x', $destination, $parts)) {
730-
throw new InvalidLinkException("Invalid destination '$destination'.");
731-
}
732-
728+
$parts = $this->parseDestination($destination);
733729
$path = $parts['path'];
734-
if (!empty($parts['query'])) {
735-
parse_str(substr($parts['query'], 1), $args);
736-
}
730+
$args = $parts['args'] ?? $args;
737731

738-
if (!$component instanceof self || !empty($parts['signal'])) {
732+
if (!$component instanceof self || $parts['signal']) {
739733
[$cname, $signal] = Helpers::splitName($path);
740734
if ($cname !== '') {
741735
$component = $component->getComponent(strtr($cname, ':', '-'));
@@ -881,7 +875,30 @@ protected function createRequest(Component $component, string $destination, arra
881875

882876
return $mode === 'forward' || $mode === 'test'
883877
? NULL
884-
: $this->requestToUrl($this->lastCreatedRequest, $mode === 'link' && !$parts['absolute']) . ($parts['fragment'] ?? '');
878+
: $this->requestToUrl($this->lastCreatedRequest, $mode === 'link' && !$parts['absolute']) . $parts['fragment'];
879+
}
880+
881+
882+
/**
883+
* Parse destination in format "[//] [[[module:]presenter:]action | signal! | this] [?query] [#fragment]"
884+
* @throws InvalidLinkException
885+
* @internal
886+
*/
887+
public static function parseDestination(string $destination): array
888+
{
889+
if (!preg_match('~^ (?<absolute>//)?+ (?<path>[^!?#]++) (?<signal>!)?+ (?<query>\?[^#]*)?+ (?<fragment>\#.*)?+ $~x', $destination, $matches)) {
890+
throw new InvalidLinkException("Invalid destination '$destination'.");
891+
}
892+
if (!empty($matches['query'])) {
893+
parse_str(substr($matches['query'], 1), $args);
894+
}
895+
return [
896+
'absolute' => (bool) $matches['absolute'],
897+
'path' => $matches['path'],
898+
'signal' => !empty($matches['signal']),
899+
'args' => $args ?? NULL,
900+
'fragment' => $matches['fragment'] ?? '',
901+
];
885902
}
886903

887904

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Application\UI\Presenter;
6+
use Nette\Application\UI\InvalidLinkException;
7+
use Tester\Assert;
8+
9+
10+
require __DIR__ . '/../bootstrap.php';
11+
12+
13+
Assert::same([
14+
'absolute' => FALSE,
15+
'path' => 'a:b',
16+
'signal' => FALSE,
17+
'args' => NULL,
18+
'fragment' => '',
19+
], Presenter::parseDestination('a:b'));
20+
21+
Assert::same([
22+
'absolute' => FALSE,
23+
'path' => 'a:b',
24+
'signal' => TRUE,
25+
'args' => NULL,
26+
'fragment' => '',
27+
], Presenter::parseDestination('a:b!'));
28+
29+
Assert::same([
30+
'absolute' => TRUE,
31+
'path' => 'a:b',
32+
'signal' => FALSE,
33+
'args' => NULL,
34+
'fragment' => '',
35+
], Presenter::parseDestination('//a:b'));
36+
37+
Assert::same([
38+
'absolute' => FALSE,
39+
'path' => 'a:b',
40+
'signal' => FALSE,
41+
'args' => NULL,
42+
'fragment' => '#fragment',
43+
], Presenter::parseDestination('a:b#fragment'));
44+
45+
Assert::same([
46+
'absolute' => FALSE,
47+
'path' => 'a:b',
48+
'signal' => FALSE,
49+
'args' => [],
50+
'fragment' => '#fragment',
51+
], Presenter::parseDestination('a:b?#fragment'));
52+
53+
Assert::same([
54+
'absolute' => FALSE,
55+
'path' => 'a:b',
56+
'signal' => FALSE,
57+
'args' => ['a' => 'b', 'c' => 'd'],
58+
'fragment' => '#fragment',
59+
], Presenter::parseDestination('a:b?a=b&c=d#fragment'));
60+
61+
Assert::exception(function () {
62+
Presenter::parseDestination('');
63+
}, InvalidLinkException::class);

0 commit comments

Comments
 (0)