Skip to content

Commit 6c73406

Browse files
authored
Merge pull request #34 from kalibora/support-redirect
Support redirect
2 parents a525cc7 + 20cae91 commit 6c73406

File tree

8 files changed

+138
-2
lines changed

8 files changed

+138
-2
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
/**
3+
* This file is part of the Madapaja.TwigModule package.
4+
*
5+
* @license http://opensource.org/licenses/MIT MIT
6+
*/
7+
namespace Madapaja\TwigModule\Annotation;
8+
9+
use Ray\Di\Di\Qualifier;
10+
11+
/**
12+
* @Annotation
13+
* @Target("METHOD")
14+
* @Qualifier
15+
*/
16+
final class TwigRedirectPath
17+
{
18+
public $value;
19+
}

src/TwigModule.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Madapaja\TwigModule\Annotation\TwigLoader;
1111
use Madapaja\TwigModule\Annotation\TwigOptions;
1212
use Madapaja\TwigModule\Annotation\TwigPaths;
13+
use Madapaja\TwigModule\Annotation\TwigRedirectPath;
1314
use Ray\Di\AbstractModule;
1415
use Ray\Di\Scope;
1516
use Twig\Environment;
@@ -52,6 +53,7 @@ protected function configure()
5253
$this->bindTwigEnvironment();
5354
$this->bindTwigPaths();
5455
$this->bindTwigOptions();
56+
$this->bindTwigRedirectPath();
5557
}
5658

5759
private function bindRender()
@@ -116,6 +118,11 @@ private function bindTwigOptions()
116118
$this->bind()->annotatedWith(TwigOptions::class)->toProvider(OptionProvider::class);
117119
}
118120

121+
private function bindTwigRedirectPath()
122+
{
123+
$this->bind()->annotatedWith(TwigRedirectPath::class)->toInstance('/redirect/redirect.html.twig');
124+
}
125+
119126
private function isNotEmpty($var)
120127
{
121128
return \is_array($var) && ! empty($var);

src/TwigRenderer.php

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use BEAR\Resource\Code;
1010
use BEAR\Resource\RenderInterface;
1111
use BEAR\Resource\ResourceObject;
12+
use Madapaja\TwigModule\Annotation\TwigRedirectPath;
1213
use Ray\Aop\WeavedInterface;
1314
use Twig\Environment;
1415
use Twig\Error\LoaderError;
@@ -29,14 +30,23 @@ class TwigRenderer implements RenderInterface
2930
*/
3031
public $twig;
3132

33+
/**
34+
* @var string
35+
*/
36+
private $redirectPage;
37+
3238
/**
3339
* @var TemplateFinderInterface
3440
*/
3541
private $templateFinder;
3642

37-
public function __construct(Environment $twig, TemplateFinderInterface $templateFinder = null)
43+
/**
44+
* @TwigRedirectPath("redirectPage")
45+
*/
46+
public function __construct(Environment $twig, string $redirectPage, TemplateFinderInterface $templateFinder = null)
3847
{
3948
$this->twig = $twig;
49+
$this->redirectPage = $redirectPage;
4050
$this->templateFinder = $templateFinder ?: new TemplateFinder;
4151
}
4252

@@ -46,7 +56,14 @@ public function __construct(Environment $twig, TemplateFinderInterface $template
4656
public function render(ResourceObject $ro)
4757
{
4858
$this->setContentType($ro);
49-
$ro->view = $this->isNoContent($ro) ? '' : $this->renderView($ro);
59+
60+
if ($this->isNoContent($ro)) {
61+
$ro->view = '';
62+
} elseif ($this->isRedirect($ro)) {
63+
$ro->view = $this->renderRedirectView($ro);
64+
} else {
65+
$ro->view = $this->renderView($ro);
66+
}
5067

5168
return $ro->view;
5269
}
@@ -65,6 +82,13 @@ private function renderView(ResourceObject $ro)
6582
return $template ? $template->render($this->buildBody($ro)) : '';
6683
}
6784

85+
private function renderRedirectView(ResourceObject $ro)
86+
{
87+
$url = $ro->headers['Location'];
88+
89+
return $this->twig->render($this->redirectPage, ['url' => $url]);
90+
}
91+
6892
/**
6993
* @return null|\Twig\TemplateWrapper
7094
*/
@@ -84,6 +108,17 @@ private function isNoContent(ResourceObject $ro) : bool
84108
return $ro->code === Code::NO_CONTENT || $ro->view === '';
85109
}
86110

111+
private function isRedirect(ResourceObject $ro) : bool
112+
{
113+
return \in_array($ro->code, [
114+
Code::MOVED_PERMANENTLY,
115+
Code::FOUND,
116+
Code::SEE_OTHER,
117+
Code::TEMPORARY_REDIRECT,
118+
Code::PERMANENT_REDIRECT,
119+
], true) && isset($ro->headers['Location']);
120+
}
121+
87122
private function loadTemplate(ResourceObject $ro) : TemplateWrapper
88123
{
89124
$loader = $this->twig->getLoader();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo is {{ foo }}.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* This file is part of the Madapaja.TwigModule package.
4+
*
5+
* @license http://opensource.org/licenses/MIT MIT
6+
*/
7+
namespace Madapaja\TwigModule\Resource\Page;
8+
9+
use BEAR\Resource\Code;
10+
use BEAR\Resource\ResourceObject;
11+
12+
class Redirect extends ResourceObject
13+
{
14+
public function onGet()
15+
{
16+
$this->body = [
17+
'foo' => 'bar',
18+
];
19+
20+
return $this;
21+
}
22+
23+
public function onPost()
24+
{
25+
$this->code = Code::FOUND;
26+
$this->headers['Location'] = '/path/to/baz';
27+
28+
return $this;
29+
}
30+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="refresh" content="0;url={{ url }}" />
6+
<title>Redirecting to {{ url }}</title>
7+
</head>
8+
<body>
9+
Redirecting to <a href="{{ url }}">{{ url }}</a>.
10+
</body>
11+
</html>

tests/FileLoaderTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Madapaja\TwigModule\Resource\Page\Index;
1111
use Madapaja\TwigModule\Resource\Page\NoTemplate;
1212
use Madapaja\TwigModule\Resource\Page\Page;
13+
use Madapaja\TwigModule\Resource\Page\Redirect;
1314
use PHPUnit_Framework_TestCase;
1415
use Ray\Di\Injector;
1516

@@ -122,4 +123,25 @@ public function testIndexTemplateWithoutPaths()
122123
$ro->onGet();
123124
$this->assertSame('Hello, BEAR.Sunday!', \trim((string) $ro));
124125
}
126+
127+
public function testNoRedirectOnGet()
128+
{
129+
$injector = $this->getInjector();
130+
$ro = $injector->getInstance(Redirect::class);
131+
$ro->onGet();
132+
133+
$this->assertSame(Code::OK, $ro->code);
134+
$this->assertSame('foo is bar.', \trim((string) $ro));
135+
}
136+
137+
public function testRedirectOnPost()
138+
{
139+
$injector = $this->getInjector();
140+
$ro = $injector->getInstance(Redirect::class);
141+
$ro->onPost();
142+
143+
$this->assertSame(Code::FOUND, $ro->code);
144+
$this->assertSame('/path/to/baz', $ro->headers['Location']);
145+
$this->assertRegexp('#^.*Redirecting to /path/to/baz.*$#s', \trim((string) $ro));
146+
}
125147
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="refresh" content="0;url={{ url }}" />
6+
<title>Redirecting to {{ url }}</title>
7+
</head>
8+
<body>
9+
Redirecting to <a href="{{ url }}">{{ url }}</a>.
10+
</body>
11+
</html>

0 commit comments

Comments
 (0)