Skip to content

Commit

Permalink
Add ViewTemplateRenderer::class. (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
terabytesoftw committed Jun 5, 2023
1 parent 8f043a7 commit d9aa65e
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 6 deletions.
15 changes: 11 additions & 4 deletions composer.json
Expand Up @@ -19,18 +19,21 @@
"yiisoft/aliases": "^3.0",
"yiisoft/arrays": "^3.0",
"yiisoft/data-response": "^2.0",
"yiisoft/mailer": "^5.0",
"yiisoft/mailer-symfony": "^3.0",
"yiisoft/mailer": "^5.0",
"yiisoft/router-fastroute": "^3.0",
"yiisoft/router": "^3.0",
"yiisoft/session": "^2.0",
"yiisoft/translator": "^3.0"
"yiisoft/translator-message-php": "^1.1",
"yiisoft/translator": "^3.0",
"yiisoft/view": "^8.0"
},
"require-dev": {
"httpsoft/http-message": "^1.0",
"infection/infection": "^0.27",
"maglnet/composer-require-checker": "^4.3",
"phpunit/phpunit": "^10.0",
"roave/infection-static-analysis-plugin": "^1.28",
"phpunit/phpunit": "^10.1",
"roave/infection-static-analysis-plugin": "^1.31",
"vimeo/psalm": "^5.4",
"yii-tools/support": "^1.0@dev",
"yiisoft/config": "^1.3",
Expand Down Expand Up @@ -66,6 +69,10 @@
"common/*.php",
"../tests/data/config/common/*.php"
],
"di-web": [
"$di",
"web/*.php"
],
"application-params": "../tests/data/config/application-params.php",
"params": "../tests/data/config/params.php"
}
Expand Down
73 changes: 73 additions & 0 deletions src/ViewTemplateRenderer.php
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

namespace Yii\Service;

use Psr\Http\Message\ResponseInterface;
use Yiisoft\Aliases\Aliases;
use Yiisoft\DataResponse\DataResponseFactoryInterface;
use Yiisoft\View\ViewContextInterface;
use Yiisoft\View\WebView;

final class ViewTemplateRenderer implements ViewContextInterface
{
private string $layout = '@layout/main.php';
private array $layoutParameters = [];
private string $viewPath = '@views';

public function __construct(
private readonly Aliases $aliases,
private readonly DataResponseFactoryInterface $dataResponse,
private readonly WebView $webView,
) {
}

public function getViewPath(): string
{
return $this->findAliases($this->viewPath);
}

public function render(string $view, array $viewParameters = [], array $layoutParameters = []): ResponseInterface
{
$content = $this->renderView($view, $viewParameters);

$parameters = ['content' => $content, ...$layoutParameters, ...$this->layoutParameters];

$layout = $this->findAliases($this->layout);

$content = $this->webView->renderFile($layout, $parameters);

return $this->dataResponse->createResponse($content);
}

public function withLayoutParameters(array $parameters): self
{
$new = clone $this;
$new->layoutParameters = $parameters;

return $new;
}

public function withViewPath(string $path): self
{
$new = clone $this;
$new->viewPath = $path;

return $new;
}

private function findAliases(string $aliases): string
{
if (substr($aliases, 0, 1) === '@') {
return $this->aliases->get($aliases);
}

return $aliases;
}

private function renderView(string $view, array $viewParameters): string
{
return $this->webView->withContext($this)->render($view, $viewParameters);
}
}
14 changes: 12 additions & 2 deletions tests/Support/TestTrait.php
Expand Up @@ -8,6 +8,7 @@
use Yii\Service\Mailer;
use Yii\Service\ParameterInterface;
use Yii\Service\Redirect;
use Yii\Service\ViewTemplateRenderer;
use Yiisoft\Aliases\Aliases;
use Yiisoft\Config\Config;
use Yiisoft\Config\ConfigPaths;
Expand All @@ -24,6 +25,7 @@ trait TestTrait
private Mailer $mailer;
private ParameterInterface $parameter;
private Redirect $redirect;
private ViewTemplateRenderer $viewTemplateRenderer;
protected bool $writeToFiles = true;

public function setup(): void
Expand All @@ -33,7 +35,14 @@ public function setup(): void

public function tearDown(): void
{
unset($this->aliases, $this->logger, $this->mailer, $this->parameter, $this->redirect);
unset(
$this->aliases,
$this->logger,
$this->mailer,
$this->parameter,
$this->redirect,
$this->viewTemplateRenderer,
);
}

private function createContainer(): void
Expand All @@ -47,7 +56,7 @@ private function createContainer(): void
MailerInterface::class => $this->writeToFiles ? FileMailer::class : SymfonyMailer::class,
];

$definitions = array_merge($config->get('di'), $mailerInterfaceOverride);
$definitions = array_merge($config->get('di-web'), $mailerInterfaceOverride);
$containerConfig = ContainerConfig::create()->withDefinitions(array_merge($definitions));
$container = new Container($containerConfig);

Expand All @@ -56,5 +65,6 @@ private function createContainer(): void
$this->mailer = $container->get(Mailer::class);
$this->parameter = $container->get(ParameterInterface::class);
$this->redirect = $container->get(Redirect::class);
$this->viewTemplateRenderer = $container->get(ViewTemplateRenderer::class);
}
}
21 changes: 21 additions & 0 deletions tests/ViewTemplateRenderer/ImmutabilityTest.php
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Yii\Service\Tests\ViewTemplateRenderer;

use PHPUnit\Framework\TestCase;
use Yii\Service\Tests\Support\TestTrait;

final class ImmutabilityTest extends TestCase
{
use TestTrait;

public function testImmutability(): void
{
$viewTemplateRenderer = $this->viewTemplateRenderer;

$this->assertNotSame($viewTemplateRenderer, $viewTemplateRenderer->withLayoutParameters([]));
$this->assertNotSame($viewTemplateRenderer, $viewTemplateRenderer->withViewPath(''));
}
}
73 changes: 73 additions & 0 deletions tests/ViewTemplateRenderer/Test.php
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

namespace Yii\Service\Tests\ViewTemplateRenderer;

use PHPUnit\Framework\TestCase;
use Yii\Service\Tests\Support\TestTrait;
use Yii\Support\Assert;
use Yiisoft\DataResponse\DataResponse;

final class Test extends TestCase
{
use TestTrait;

public function testRender(): void
{
$this->aliases->set('@layout', dirname(__DIR__) . '/data/resources/view');

/** @var DataResponse $dataResponse */
$dataResponse = $this->viewTemplateRenderer
->withViewPath(dirname(__DIR__) . '/data/resources/view')
->render('view', ['title' => 'View'], ['title' => 'Layout']);

Assert::equalsWithoutLE(
<<<HTML
<!DOCTYPE html>
<html>
<head>
<title>Layout</title>
</head>
<body>
<h1>View</h1>
</body>
</html>
HTML,
$dataResponse->getData(),
);
}

public function testWithLayoutParameters(): void
{
$this->aliases->set('@layout', dirname(__DIR__) . '/data/resources/view');

/** @var DataResponse $dataResponse */
$dataResponse = $this->viewTemplateRenderer
->withViewPath(dirname(__DIR__) . '/data/resources/view')
->withLayoutParameters(['csrfToken' => 'test'])
->render('view', ['title' => 'View'], ['title' => 'Layout']);

Assert::equalsWithoutLE(
<<<HTML
<!DOCTYPE html>
<html>
<head>
<meta name="csrf-token" content="test">
<title>Layout</title>
</head>
<body>
<h1>View</h1>
</body>
</html>
HTML,
$dataResponse->getData(),
);
}
}
10 changes: 10 additions & 0 deletions tests/data/config/common/stream-factory.php
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

use HttpSoft\Message\StreamFactory;
use Psr\Http\Message\StreamFactoryInterface;

return [
StreamFactoryInterface::class => StreamFactory::class,
];
26 changes: 26 additions & 0 deletions tests/data/resources/view/main.php
@@ -0,0 +1,26 @@
<?php
/**
* @var $this \Yiisoft\View\WebView
* @var $content string
* @var string|null $csrfToken
*/
$csrfToken = $csrfToken ?? null;
?>
<?php $this->beginPage(); ?>
<!DOCTYPE html>
<html>
<head>
<?php if ($csrfToken !== null): ?>
<meta name="csrf-token" content="<?= $csrfToken ?>">
<?php endif ?>
<title><?= $title ?></title>
</head>
<body>
<?php $this->beginBody(); ?>

<?= $content ?>

<?php $this->endBody(); ?>
</body>
</html>
<?php $this->endPage();
5 changes: 5 additions & 0 deletions tests/data/resources/view/view.php
@@ -0,0 +1,5 @@
<?php

/** @var string $title */
?>
<h1><?= $title ?></h1>

0 comments on commit d9aa65e

Please sign in to comment.