From cd73dc47b2fc153c44dd98385dcfb46297ef2904 Mon Sep 17 00:00:00 2001 From: XiangMin Liu <635750556@qq.com> Date: Sat, 5 Dec 2020 01:32:59 +0800 Subject: [PATCH] refactor: Remove \Leevel\Router\View and optimize view code --- src/Leevel/Router/Provider/Register.php | 15 +- src/Leevel/Router/Response.php | 18 +- src/Leevel/Router/View.php | 86 --------- src/Leevel/Router/composer.json | 1 + src/Leevel/View/Console/Cache.php | 2 +- src/Leevel/View/Manager.php | 4 +- src/Leevel/View/Provider/Register.php | 56 ++---- src/Leevel/{Router => View}/Proxy/View.php | 19 +- tests/Router/Provider/RegisterTest.php | 17 +- tests/Router/Proxy/ResponseTest.php | 74 +++++++- tests/Router/Proxy/ViewTest.php | 83 --------- tests/Router/ResponseTest.php | 75 +++++++- tests/Router/ViewTest.php | 195 --------------------- tests/View/Console/CacheTest.php | 2 +- tests/View/ManagerTest.php | 165 +++++++++++++++-- tests/View/Provider/RegisterTest.php | 21 +-- tests/View/Proxy/ViewTest.php | 139 +++++++++++++++ tests/{Router => View}/assert/hello.php | 0 18 files changed, 461 insertions(+), 511 deletions(-) delete mode 100644 src/Leevel/Router/View.php rename src/Leevel/{Router => View}/Proxy/View.php (59%) delete mode 100644 tests/Router/Proxy/ViewTest.php delete mode 100644 tests/Router/ViewTest.php create mode 100644 tests/View/Proxy/ViewTest.php rename tests/{Router => View}/assert/hello.php (100%) diff --git a/src/Leevel/Router/Provider/Register.php b/src/Leevel/Router/Provider/Register.php index e2d4649a8..166a1cda0 100644 --- a/src/Leevel/Router/Provider/Register.php +++ b/src/Leevel/Router/Provider/Register.php @@ -46,7 +46,6 @@ public function register(): void $this->url(); $this->redirect(); $this->response(); - $this->view(); } /** @@ -133,25 +132,13 @@ protected function response(): void function (IContainer $container): Response { $option = $container['option']; - return (new Response($container['view'], $container['redirect'])) + return (new Response($container['views'], $container['redirect'])) ->setViewSuccessTemplate($option->get('view\\success')) ->setViewFailTemplate($option->get('view\\fail')); }, ); } - /** - * 注册 view 服务 - */ - protected function view(): void - { - $this->container - ->singleton( - 'view', - fn (IContainer $container): View => new View($container['view.view']), - ); - } - /** * 设置 COOKIE 助手配置. */ diff --git a/src/Leevel/Router/Response.php b/src/Leevel/Router/Response.php index 7eef55fc8..2259fa41f 100644 --- a/src/Leevel/Router/Response.php +++ b/src/Leevel/Router/Response.php @@ -27,22 +27,13 @@ use Symfony\Component\HttpFoundation\ResponseHeaderBag; use SplFileInfo; use SplFileObject; +use Leevel\View\Manager; /** * 响应. */ class Response { - /** - * 视图. - */ - protected IView $view; - - /** - * 跳转实例. - */ - protected Redirect $redirect; - /** * 视图正确模板. */ @@ -56,10 +47,11 @@ class Response /** * 构造函数. */ - public function __construct(IView $view, Redirect $redirect) + public function __construct( + protected Manager $view, + protected Redirect $redirect, + ) { - $this->view = $view; - $this->redirect = $redirect; } /** diff --git a/src/Leevel/Router/View.php b/src/Leevel/Router/View.php deleted file mode 100644 index cda59a5e1..000000000 --- a/src/Leevel/Router/View.php +++ /dev/null @@ -1,86 +0,0 @@ - - * (c) 2010-2020 http://queryphp.com All rights reserved. - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Leevel\Router; - -use Leevel\View\IView as IViews; - -/** - * 视图. - */ -class View implements IView -{ - /** - * 构造函数. - */ - public function __construct(protected IViews $view) - { - } - - /** - * {@inheritDoc} - */ - public function switchView(IViews $view): void - { - $var = $this->getVar(); - $this->view = $view; - $this->setVar($var); - } - - /** - * {@inheritDoc} - */ - public function setVar(array|string $name, mixed $value = null): void - { - $this->view->setVar($name, $value); - } - - /** - * {@inheritDoc} - */ - public function getVar(?string $name = null): mixed - { - return $this->view->getVar($name); - } - - /** - * {@inheritDoc} - */ - public function deleteVar(array $name): void - { - $this->view->deleteVar($name); - } - - /** - * {@inheritDoc} - */ - public function clearVar(): void - { - $this->view->clearVar(); - } - - /** - * {@inheritDoc} - */ - public function display(string $file, array $vars = [], ?string $ext = null): string - { - return $this->view->display($file, $vars, $ext); - } -} diff --git a/src/Leevel/Router/composer.json b/src/Leevel/Router/composer.json index bb58a54b1..3a3ff7efa 100644 --- a/src/Leevel/Router/composer.json +++ b/src/Leevel/Router/composer.json @@ -18,6 +18,7 @@ "leevel/pipeline": "1.1.*", "leevel/di": "1.1.*", "leevel/filesystem": "1.1.*", + "leevel/view": "1.1.*", "symfony/http-foundation": "~5.1", "symfony/finder": "~5.1" }, diff --git a/src/Leevel/View/Console/Cache.php b/src/Leevel/View/Console/Cache.php index 48b43688d..571b9ef83 100644 --- a/src/Leevel/View/Console/Cache.php +++ b/src/Leevel/View/Console/Cache.php @@ -185,7 +185,7 @@ protected function getHtmlView(): Html { return $this->app ->container() - ->make('view.views') + ->make('views') ->connect('html'); } } diff --git a/src/Leevel/View/Manager.php b/src/Leevel/View/Manager.php index d0b75fdd2..ec41c13d4 100644 --- a/src/Leevel/View/Manager.php +++ b/src/Leevel/View/Manager.php @@ -62,7 +62,9 @@ protected function makeConnectHtml(string $connect): Html { $html = new Html($this->normalizeConnectOption($connect)); $html->setParseResolver(function (): Parser { - return $this->container['view.parser']; + return (new Parser( new Compiler())) + ->registerCompilers() + ->registerParsers(); }); return $html; diff --git a/src/Leevel/View/Provider/Register.php b/src/Leevel/View/Provider/Register.php index 4808fe1a9..7e6fedaf6 100644 --- a/src/Leevel/View/Provider/Register.php +++ b/src/Leevel/View/Provider/Register.php @@ -22,10 +22,8 @@ use Leevel\Di\IContainer; use Leevel\Di\Provider; -use Leevel\View\Compiler; use Leevel\View\IView; use Leevel\View\Manager; -use Leevel\View\Parser; use Leevel\View\View; /** @@ -38,10 +36,8 @@ class Register extends Provider */ public function register(): void { - $this->viewViews(); - $this->viewView(); - $this->viewCompiler(); - $this->viewParser(); + $this->views(); + $this->view(); } /** @@ -50,10 +46,8 @@ public function register(): void public static function providers(): array { return [ - 'view.views' => Manager::class, - 'view.view' => [IView::class, View::class], - 'view.compiler' => Compiler::class, - 'view.parser' => Parser::class, + 'views' => Manager::class, + 'view' => [IView::class, View::class], ]; } @@ -66,54 +60,26 @@ public static function isDeferred(): bool } /** - * 注册 view.views 服务. + * 注册 views 服务. */ - protected function viewViews(): void + protected function views(): void { $this->container ->singleton( - 'view.views', + 'views', fn (IContainer $container): Manager => new Manager($container), ); } /** - * 注册 view.view 服务. + * 注册 view 服务. */ - protected function viewView(): void + protected function view(): void { $this->container ->singleton( - 'view.view', - fn (IContainer $container): IView => $container['view.views']->connect(), - ); - } - - /** - * 注册 view.compiler 服务. - */ - protected function viewCompiler(): void - { - $this->container - ->singleton( - 'view.compiler', - fn (): Compiler => new Compiler(), - ); - } - - /** - * 注册 view.parser 服务. - */ - protected function viewParser(): void - { - $this->container - ->singleton( - 'view.parser', - function (IContainer $container): Parser { - return (new Parser($container['view.compiler'])) - ->registerCompilers() - ->registerParsers(); - }, + 'view', + fn (IContainer $container): IView => $container['views']->connect(), ); } } diff --git a/src/Leevel/Router/Proxy/View.php b/src/Leevel/View/Proxy/View.php similarity index 59% rename from src/Leevel/Router/Proxy/View.php rename to src/Leevel/View/Proxy/View.php index 8c9e883d2..5216bb28e 100644 --- a/src/Leevel/Router/Proxy/View.php +++ b/src/Leevel/View/Proxy/View.php @@ -18,20 +18,19 @@ * file that was distributed with this source code. */ -namespace Leevel\Router\Proxy; +namespace Leevel\View\Proxy; use Leevel\Di\Container; -use Leevel\Router\View as BaseView; +use Leevel\View\Manager; /** * 代理 view. * - * @method static void switchView(\Leevel\View\IView $view) 切换视图. - * @method static void setVar($name, $value = null) 变量赋值. - * @method static mixed getVar(?string $name = null) 获取变量赋值. - * @method static void deleteVar(array $name) 删除变量值. - * @method static void clearVar() 清空变量值. - * @method static string display(string $file, array $vars = [], ?string $ext = null) 加载视图文件. + * @method static string display(string $file, array $vars = [], ?string $ext = null) 加载视图文件. + * @method static void setVar(array|string $name, mixed $value = null) 设置模板变量. + * @method static mixed getVar(?string $name = null) 获取变量值. + * @method static void deleteVar(array $name) 删除变量值. + * @method static void clearVar() 清空变量值. */ class View { @@ -46,8 +45,8 @@ public static function __callStatic(string $method, array $args): mixed /** * 代理服务. */ - public static function proxy(): BaseView + public static function proxy(): Manager { - return Container::singletons()->make('view'); + return Container::singletons()->make('views'); } } diff --git a/tests/Router/Provider/RegisterTest.php b/tests/Router/Provider/RegisterTest.php index 842fee249..da3d8643f 100644 --- a/tests/Router/Provider/RegisterTest.php +++ b/tests/Router/Provider/RegisterTest.php @@ -25,15 +25,13 @@ use Leevel\Option\Option; use Leevel\Router\IRouter; use Leevel\Router\IUrl; -use Leevel\Router\IView; use Leevel\Router\Provider\Register; use Leevel\Router\Redirect; use Leevel\Router\Response; use Leevel\Router\Router; use Leevel\Router\Url; -use Leevel\Router\View; use Leevel\Session\ISession; -use Leevel\View\IView as IViews; +use Leevel\View\Manager; use Tests\TestCase; class RegisterTest extends TestCase @@ -53,8 +51,7 @@ public function testBaseUse(): void $this->assertInstanceof(Redirect::class, $container->make('redirect')); $this->assertInstanceof(Response::class, $container->make('response')); $this->assertInstanceof(Response::class, $container->make('response')); - $this->assertInstanceof(IView::class, $container->make('view')); - $this->assertInstanceof(View::class, $container->make('view')); + $this->assertInstanceof(Manager::class, $container->make('views')); $this->assertSame('http://www.queryphp.cn/foo/bar?hello=world', $url->make('foo/bar', ['hello' => 'world'])); } @@ -82,25 +79,19 @@ protected function createContainer(): Container 'fail' => 'fail', ], ]); - $container->singleton('option', $option); $request = $this->createMock(Request::class); - $request->method('getEnter')->willReturn(''); $this->assertSame('', $request->getEnter()); - $request->method('isSecure')->willReturn(false); $this->assertFalse($request->isSecure()); - $container->singleton('request', $request); - $view = $this->createMock(IViews::class); - - $container->singleton('view.view', $view); + $view = $this->createMock(Manager::class); + $container->singleton('views', $view); $session = $this->createMock(ISession::class); - $container->singleton('session', $session); return $container; diff --git a/tests/Router/Proxy/ResponseTest.php b/tests/Router/Proxy/ResponseTest.php index f6758201e..73e4f6914 100644 --- a/tests/Router/Proxy/ResponseTest.php +++ b/tests/Router/Proxy/ResponseTest.php @@ -21,14 +21,16 @@ namespace Tests\Router\Proxy; use Leevel\Di\Container; +use Leevel\Di\IContainer; use Leevel\Http\JsonResponse; use Leevel\Http\Request; +use Leevel\Kernel\App; +use Leevel\Option\Option; use Leevel\Router\Proxy\Response as ProxyResponse; use Leevel\Router\Redirect; use Leevel\Router\Response as RouterResponse; use Leevel\Router\Url; -use Leevel\Router\View; -use Leevel\View\Phpui; +use Leevel\View\Manager; use Symfony\Component\HttpFoundation\Response; use Tests\TestCase; @@ -116,13 +118,9 @@ protected function getFilterHeaders(array $headers): array return $headers; } - protected function makeView(): View + protected function makeView(): Manager { - return new View( - new Phpui([ - 'theme_path' => __DIR__.'/assert', - ]) - ); + return $this->createViewManager('phpui'); } protected function makeRedirect(bool $isSecure = false): Redirect @@ -158,4 +156,64 @@ protected function createContainer(): Container return $container; } + + protected function createViewManager(string $connect = 'html'): Manager + { + $app = new ExtendAppForResponse($container = new Container(), ''); + $container->instance('app', $app); + + $manager = new Manager($container); + + $this->assertInstanceof(IContainer::class, $manager->container()); + $this->assertInstanceof(Container::class, $manager->container()); + + $this->assertSame(__DIR__.'/assert', $app->themesPath()); + $this->assertSame(__DIR__.'/cache_theme', $app->runtimePath('theme')); + + $option = new Option([ + 'view' => [ + 'default' => $connect, + 'action_fail' => 'public/fail', + 'action_success' => 'public/success', + 'connect' => [ + 'html' => [ + 'driver' => 'html', + 'suffix' => '.html', + ], + 'phpui' => [ + 'driver' => 'phpui', + 'suffix' => '.php', + ], + ], + ], + ]); + $container->singleton('option', $option); + + $request = new ExtendRequestForResponse(); + $container->singleton('request', $request); + + return $manager; + } +} + +class ExtendAppForResponse extends App +{ + public function development(): bool + { + return true; + } + + public function themesPath(string $path = ''): string + { + return __DIR__.'/assert'; + } + + public function runtimePath(string $path = ''): string + { + return __DIR__.'/cache_'.$path; + } +} + +class ExtendRequestForResponse +{ } diff --git a/tests/Router/Proxy/ViewTest.php b/tests/Router/Proxy/ViewTest.php deleted file mode 100644 index 5a2f4257b..000000000 --- a/tests/Router/Proxy/ViewTest.php +++ /dev/null @@ -1,83 +0,0 @@ - - * (c) 2010-2020 http://queryphp.com All rights reserved. - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Tests\Router\Proxy; - -use Leevel\Di\Container; -use Leevel\Router\IView; -use Leevel\Router\Proxy\View as ProxyView; -use Leevel\Router\View; -use Leevel\View\Html; -use Tests\TestCase; - -class ViewTest extends TestCase -{ - protected function setUp(): void - { - $this->tearDown(); - } - - protected function tearDown(): void - { - Container::singletons()->clear(); - } - - public function testBaseUse(): void - { - $view = new View( - $html = new Html() - ); - $this->assertInstanceof(IView::class, $view); - - $container = $this->createContainer(); - $container->singleton('view', function () use ($view): View { - return $view; - }); - - $view->setVar('hello', 'world'); - $this->assertSame('world', $view->getVar('hello')); - $this->assertSame('world', $html->getVar('hello')); - } - - public function testProxy(): void - { - $view = new View( - $html = new Html() - ); - $this->assertInstanceof(IView::class, $view); - - $container = $this->createContainer(); - $container->singleton('view', function () use ($view): View { - return $view; - }); - - ProxyView::setVar('hello', 'world'); - $this->assertSame('world', ProxyView::getVar('hello')); - $this->assertSame('world', $html->getVar('hello')); - } - - protected function createContainer(): Container - { - $container = Container::singletons(); - $container->clear(); - - return $container; - } -} diff --git a/tests/Router/ResponseTest.php b/tests/Router/ResponseTest.php index 2eca11b87..1db5929ea 100644 --- a/tests/Router/ResponseTest.php +++ b/tests/Router/ResponseTest.php @@ -20,14 +20,17 @@ namespace Tests\Router; +use Leevel\Di\Container; +use Leevel\Di\IContainer; use Leevel\Http\JsonResponse; use Leevel\Http\RedirectResponse; use Leevel\Http\Request; +use Leevel\Kernel\App; +use Leevel\Option\Option; use Leevel\Router\Redirect; use Leevel\Router\Response as RouterResponse; use Leevel\Router\Url; -use Leevel\Router\View; -use Leevel\View\Phpui; +use Leevel\View\Manager; use SplFileInfo; use SplFileObject; use Symfony\Component\HttpFoundation\BinaryFileResponse; @@ -849,13 +852,9 @@ protected function getFilterHeaders(array $headers): array return $headers; } - protected function makeView(): View + protected function makeView(): Manager { - return new View( - new Phpui([ - 'theme_path' => __DIR__.'/assert', - ]) - ); + return $this->createViewManager('phpui'); } protected function makeRedirect(bool $isSecure = false): Redirect @@ -883,4 +882,64 @@ protected function makeRequest(bool $isSecure = false): Request return $request; } + + protected function createViewManager(string $connect = 'html'): Manager + { + $app = new ExtendAppForResponse($container = new Container(), ''); + $container->instance('app', $app); + + $manager = new Manager($container); + + $this->assertInstanceof(IContainer::class, $manager->container()); + $this->assertInstanceof(Container::class, $manager->container()); + + $this->assertSame(__DIR__.'/assert', $app->themesPath()); + $this->assertSame(__DIR__.'/cache_theme', $app->runtimePath('theme')); + + $option = new Option([ + 'view' => [ + 'default' => $connect, + 'action_fail' => 'public/fail', + 'action_success' => 'public/success', + 'connect' => [ + 'html' => [ + 'driver' => 'html', + 'suffix' => '.html', + ], + 'phpui' => [ + 'driver' => 'phpui', + 'suffix' => '.php', + ], + ], + ], + ]); + $container->singleton('option', $option); + + $request = new ExtendRequestForResponse(); + $container->singleton('request', $request); + + return $manager; + } +} + +class ExtendAppForResponse extends App +{ + public function development(): bool + { + return true; + } + + public function themesPath(string $path = ''): string + { + return __DIR__.'/assert'; + } + + public function runtimePath(string $path = ''): string + { + return __DIR__.'/cache_'.$path; + } +} + +class ExtendRequestForResponse +{ } diff --git a/tests/Router/ViewTest.php b/tests/Router/ViewTest.php deleted file mode 100644 index 9b4e9e427..000000000 --- a/tests/Router/ViewTest.php +++ /dev/null @@ -1,195 +0,0 @@ - - * (c) 2010-2020 http://queryphp.com All rights reserved. - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Tests\Router; - -use Leevel\Router\IView; -use Leevel\Router\View; -use Leevel\View\Html; -use Leevel\View\Phpui; -use Tests\TestCase; - -/** - * @api( - * zh-CN:title="View", - * path="component/view", - * zh-CN:description=" - * 视图统一由视图组件完成,通常我们使用代理 `\Leevel\Router\Proxy\View` 类进行静态调用。 - * - * 内置支持的视图驱动类型包括 html、phpui,未来可能增加其他驱动。 - * - * ## 使用方式 - * - * 使用容器 view 服务 - * - * ``` php - * \App::make('view')->setVar($name, $value = null): void; - * ``` - * - * 依赖注入 - * - * ``` php - * class Demo - * { - * private \Leevel\Router\IView $view; - * - * public function __construct(\Leevel\Router\IView $view) - * { - * $this->view = $view; - * } - * } - * ``` - * - * 使用静态代理 - * - * ``` php - * \Leevel\Router\Proxy\View::setVar($name, $value = null): void; - * ``` - * - * ## view 配置 - * - * 系统的 view 配置位于应用下面的 `option/view.php` 文件。 - * - * 可以定义多个视图连接,并且支持切换,每一个连接支持驱动设置。 - * - * ``` php - * {[file_get_contents('option/view.php')]} - * ``` - * - * mail 参数根据不同的连接会有所区别,通用的 view 参数如下: - * - * |配置项|配置描述| - * |:-|:-| - * |fail|错误模板| - * |success|成功模板| - * ", - * note="值得注意的是,系统的视图组件是经过了路由的视图层做了一层封装。", - * ) - */ -class ViewTest extends TestCase -{ - /** - * @api( - * zh-CN:title="视图基本使用", - * zh-CN:description="", - * zh-CN:note="", - * ) - */ - public function testBaseUse(): void - { - $view = new View( - $html = new Html() - ); - $this->assertInstanceof(IView::class, $view); - - $view->setVar('hello', 'world'); - $this->assertSame('world', $view->getVar('hello')); - $this->assertSame('world', $html->getVar('hello')); - } - - /** - * @api( - * zh-CN:title="deleteVar 删除变量值", - * zh-CN:description="", - * zh-CN:note="", - * ) - */ - public function testDeleteVar(): void - { - $view = new View( - $html = new Html() - ); - - $view->setVar('hello', 'world'); - $this->assertSame('world', $view->getVar('hello')); - $this->assertSame('world', $html->getVar('hello')); - - $view->deleteVar(['hello']); - $this->assertNull($view->getVar('hello')); - $this->assertNull($html->getVar('hello')); - } - - /** - * @api( - * zh-CN:title="clearVar 清空变量值", - * zh-CN:description="", - * zh-CN:note="", - * ) - */ - public function testClearVar(): void - { - $view = new View( - $html = new Html() - ); - - $view->setVar('foo', 'bar'); - $this->assertSame('bar', $view->getVar('foo')); - $this->assertSame('bar', $html->getVar('foo')); - - $view->clearVar(); - $this->assertNull($view->getVar('foo')); - $this->assertNull($html->getVar('foo')); - } - - /** - * @api( - * zh-CN:title="display 加载视图文件", - * zh-CN:description="", - * zh-CN:note="", - * ) - */ - public function testDisplay(): void - { - $view = new View( - new Phpui([ - 'theme_path' => __DIR__, - ]) - ); - - $view->setVar('foo', 'bar'); - - $this->assertSame( - 'Hi here! bar', - $view->display(__DIR__.'/assert/hello.php') - ); - } - - /** - * @api( - * zh-CN:title="switchView 切换视图", - * zh-CN:description="", - * zh-CN:note="", - * ) - */ - public function testSwitchView(): void - { - $view = new View( - $phpui = new Phpui() - ); - - $view->setVar('foo', 'bar'); - $this->assertSame('bar', $view->getVar('foo')); - $this->assertSame('bar', $phpui->getVar('foo')); - - $view->switchView($html = new Html()); - $this->assertSame('bar', $view->getVar('foo')); - $this->assertSame('bar', $html->getVar('foo')); - } -} diff --git a/tests/View/Console/CacheTest.php b/tests/View/Console/CacheTest.php index adf89b0f5..ac41f84a5 100644 --- a/tests/View/Console/CacheTest.php +++ b/tests/View/Console/CacheTest.php @@ -105,7 +105,7 @@ protected function makeViewViews(IContainer $container): void $container ->singleton( - 'view.views', + 'views', fn (IContainer $container): Manager => new Manager($container), ); } diff --git a/tests/View/ManagerTest.php b/tests/View/ManagerTest.php index cae6be626..3f0bb24da 100644 --- a/tests/View/ManagerTest.php +++ b/tests/View/ManagerTest.php @@ -25,11 +25,66 @@ use Leevel\Filesystem\Helper; use Leevel\Kernel\App; use Leevel\Option\Option; -use Leevel\View\Compiler; use Leevel\View\Manager; -use Leevel\View\Parser; use Tests\TestCase; +/** + * @api( + * zh-CN:title="View", + * path="component/view", + * zh-CN:description=" + * 视图统一由视图组件完成,通常我们使用代理 `\Leevel\View\Proxy\View` 类进行静态调用。 + * + * 内置支持的视图驱动类型包括 html、phpui,未来可能增加其他驱动。 + * + * ## 使用方式 + * + * 使用容器 view 服务 + * + * ``` php + * \App::make('views')->setVar(array|string $name, mixed $value = null): void; + * ``` + * + * 依赖注入 + * + * ``` php + * class Demo + * { + * private \Leevel\View\Manager $view; + * + * public function __construct(\Leevel\View\Manager $view) + * { + * $this->view = $view; + * } + * } + * ``` + * + * 使用静态代理 + * + * ``` php + * \Leevel\Router\Proxy\View::setVar(array|string $name, mixed $value = null): void; + * ``` + * + * ## view 配置 + * + * 系统的 view 配置位于应用下面的 `option/view.php` 文件。 + * + * 可以定义多个视图连接,并且支持切换,每一个连接支持驱动设置。 + * + * ``` php + * {[file_get_contents('option/view.php')]} + * ``` + * + * 视图参数根据不同的连接会有所区别,通用的 view 参数如下: + * + * |配置项|配置描述| + * |:-|:-| + * |fail|错误模板| + * |success|成功模板| + * ", + * note="", + * ) + */ class ManagerTest extends TestCase { protected function tearDown(): void @@ -39,6 +94,13 @@ protected function tearDown(): void } } + /** + * @api( + * zh-CN:title="视图基本使用", + * zh-CN:description="", + * zh-CN:note="", + * ) + */ public function testBaseUse(): void { $manager = $this->createManager(); @@ -47,12 +109,94 @@ public function testBaseUse(): void $this->assertSame('hello html,bar.', $result); } - public function testPhpui(): void + /** + * @api( + * zh-CN:title="PHP 自身作为模板", + * zh-CN:description="", + * zh-CN:note="", + * ) + */ + public function testPhpUi(): void + { + $manager = $this->createManager('phpui'); + + $manager->setVar('hello', 'world'); + $this->assertSame('world', $manager->getVar('hello')); + $this->assertSame('world', $manager->connect('phpui')->getVar('hello')); + } + + /** + * @api( + * zh-CN:title="getVar 获取变量值", + * zh-CN:description="", + * zh-CN:note="", + * ) + */ + public function testGetVar(): void + { + $manager = $this->createManager(); + + $manager->setVar('hello', 'world'); + $this->assertSame('world', $manager->getVar('hello')); + $this->assertSame(null, $manager->getVar('hello2')); + } + + /** + * @api( + * zh-CN:title="deleteVar 删除变量值", + * zh-CN:description="", + * zh-CN:note="", + * ) + */ + public function testDeleteVar(): void { $manager = $this->createManager('phpui'); + + $manager->setVar('hello', 'world'); + $this->assertSame('world', $manager->getVar('hello')); + $this->assertSame('world', $manager->connect('phpui')->getVar('hello')); + + $manager->deleteVar(['hello']); + $this->assertNull($manager->getVar('hello')); + $this->assertNull($manager->connect('phpui')->getVar('hello')); + } + + /** + * @api( + * zh-CN:title="clearVar 清空变量值", + * zh-CN:description="", + * zh-CN:note="", + * ) + */ + public function testClearVar(): void + { + $manager = $this->createManager(); + $manager->setVar('foo', 'bar'); - $result = $manager->display('html_test'); - $this->assertSame('hello html,bar.', $result); + $this->assertSame('bar', $manager->getVar('foo')); + $this->assertSame('bar', $manager->connect('html')->getVar('foo')); + + $manager->clearVar(); + $this->assertNull($manager->getVar('foo')); + $this->assertNull($manager->connect('html')->getVar('foo')); + } + + /** + * @api( + * zh-CN:title="display 加载视图文件", + * zh-CN:description="", + * zh-CN:note="", + * ) + */ + public function testDisplay(): void + { + $manager = $this->createManager('phpui'); + + $manager->setVar('foo', 'bar'); + $this->assertSame( + 'Hi here! bar', + $manager->display(__DIR__.'/assert/hello.php') + ); } protected function createManager(string $connect = 'html'): Manager @@ -90,19 +234,8 @@ protected function createManager(string $connect = 'html'): Manager $request = new ExtendRequest(); $container->singleton('request', $request); - $container->singleton('view.parser', function () { - return $this->makeHtml(); - }); - return $manager; } - - protected function makeHtml(): Parser - { - return (new Parser(new Compiler())) - ->registerCompilers() - ->registerParsers(); - } } class ExtendApp extends App diff --git a/tests/View/Provider/RegisterTest.php b/tests/View/Provider/RegisterTest.php index cb6a4a97a..5519ae983 100644 --- a/tests/View/Provider/RegisterTest.php +++ b/tests/View/Provider/RegisterTest.php @@ -24,9 +24,7 @@ use Leevel\Filesystem\Helper; use Leevel\Kernel\App; use Leevel\Option\Option; -use Leevel\View\Compiler; use Leevel\View\Manager; -use Leevel\View\Parser; use Leevel\View\Provider\Register; use Tests\TestCase; @@ -43,8 +41,8 @@ public function testBaseUse(): void $test->register(); $container->alias($test->providers()); - // view.views - $manager = $container->make('view.views'); + // views + $manager = $container->make('views'); $manager->setVar('foo', 'bar'); $result = $manager->display('html_test'); $this->assertSame('hello html,bar.', $result); @@ -55,8 +53,8 @@ public function testBaseUse(): void $result = $manager->display('html_test'); $this->assertSame('hello html,newbar.', $result); - // view.view - $view = $container->make('view.view'); + // view + $view = $container->make('view'); $view->setVar('foo', 'newbarview'); $result = $view->display('html_test'); $this->assertSame('hello html,newbarview.', $result); @@ -90,19 +88,8 @@ protected function createContainer(): Container $container->singleton('request', $request); - $container->singleton('view.parser', function () { - return $this->makeHtml(); - }); - return $container; } - - protected function makeHtml(): Parser - { - return (new Parser(new Compiler())) - ->registerCompilers() - ->registerParsers(); - } } class ExtendApp extends App diff --git a/tests/View/Proxy/ViewTest.php b/tests/View/Proxy/ViewTest.php new file mode 100644 index 000000000..6f22a59f9 --- /dev/null +++ b/tests/View/Proxy/ViewTest.php @@ -0,0 +1,139 @@ + + * (c) 2010-2020 http://queryphp.com All rights reserved. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Tests\View\Proxy; + +use Leevel\Di\Container; +use Leevel\Di\IContainer; +use Leevel\Kernel\App; +use Leevel\Option\Option; +use Leevel\View\Proxy\View as ProxyView; +use Leevel\View\Manager; +use Tests\TestCase; + +class ViewTest extends TestCase +{ + protected function setUp(): void + { + $this->tearDown(); + } + + protected function tearDown(): void + { + Container::singletons()->clear(); + } + + public function testBaseUse(): void + { + $manager = $this->createManager(); + $this->assertInstanceof(Manager::class, $manager); + + $container = $this->createContainer(); + $container->singleton('views', function () use ($manager): Manager { + return $manager; + }); + + $manager->setVar('hello', 'world'); + $this->assertSame('world', $manager->getVar('hello')); + } + + public function testProxy(): void + { + $manager = $this->createManager(); + $this->assertInstanceof(Manager::class, $manager); + + $container = $this->createContainer(); + $container->singleton('views', function () use ($manager): Manager { + return $manager; + }); + + ProxyView::setVar('hello', 'world'); + $this->assertSame('world', ProxyView::getVar('hello')); + $this->assertSame('world', $manager->getVar('hello')); + } + + protected function createContainer(): Container + { + $container = Container::singletons(); + $container->clear(); + + return $container; + } + + protected function createManager(string $connect = 'html'): Manager + { + $app = new ExtendApp($container = new Container(), ''); + $container->instance('app', $app); + + $manager = new Manager($container); + + $this->assertInstanceof(IContainer::class, $manager->container()); + $this->assertInstanceof(Container::class, $manager->container()); + + $this->assertSame(__DIR__.'/assert', $app->themesPath()); + $this->assertSame(__DIR__.'/cache_theme', $app->runtimePath('theme')); + + $option = new Option([ + 'view' => [ + 'default' => $connect, + 'action_fail' => 'public/fail', + 'action_success' => 'public/success', + 'connect' => [ + 'html' => [ + 'driver' => 'html', + 'suffix' => '.html', + ], + 'phpui' => [ + 'driver' => 'phpui', + 'suffix' => '.php', + ], + ], + ], + ]); + $container->singleton('option', $option); + + $request = new ExtendRequest(); + $container->singleton('request', $request); + + return $manager; + } +} + +class ExtendApp extends App +{ + public function development(): bool + { + return true; + } + + public function themesPath(string $path = ''): string + { + return __DIR__.'/assert'; + } + + public function runtimePath(string $path = ''): string + { + return __DIR__.'/cache_'.$path; + } +} + +class ExtendRequest +{ +} diff --git a/tests/Router/assert/hello.php b/tests/View/assert/hello.php similarity index 100% rename from tests/Router/assert/hello.php rename to tests/View/assert/hello.php