Skip to content

Commit 843d6ae

Browse files
author
Marco Bunge
committed
Add Presentation service for better usage of view engine.
1 parent 80c2dca commit 843d6ae

File tree

8 files changed

+272
-49
lines changed

8 files changed

+272
-49
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Hawkbit Presentation Changelog
22

3+
## 1.1.0
4+
5+
### Added
6+
7+
- Add Hawkbit controller constructor injection support for presentation
8+
- Add presentation service for extensible engine configuration and encapsulated view logic
9+
310
## 1.0.1
411

512
### Added

README.md

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![Coverage Status][ico-coveralls]][link-coveralls]
88

99
Presentation layer for Hawkbit PSR-7 Micro PHP framework.
10-
Hawkbit Persitence uses factories of `dasprid/container-interop-doctrine` and wraps them with in a PresentationService
10+
Hawkbit Presentation uses [`league/plates`](http://platesphp.com/) as view engine and wraps it with in a PresentationService
1111

1212
## Install
1313

@@ -70,23 +70,13 @@ $app->register(new PresentationServiceProvider([
7070
]));
7171
```
7272

73-
### Full configuration
74-
75-
A full configuration is available on [DASPRiD/container-interop-doctrine/example/full-config.php](https://github.com/DASPRiD/container-interop-doctrine/blob/master/example/full-config.php).
76-
Refer to [container-interop-doctrine Documentation](https://github.com/DASPRiD/container-interop-doctrine) for further instructions on factories.
77-
7873
### Presentation from Hawbit Application
7974

8075
```php
8176
<?php
8277

83-
/** @var \Hawkbit\Presentation\PresentationServiceInterface $Presentation */
84-
$Presentation = $app[\Hawkbit\Presentation\PresentationServiceInterface::class];
85-
86-
$em = $Presentation->getEntityManager();
87-
88-
// or with from specific connection
89-
$em = $Presentation->getEntityManager('connectionname');
78+
/** @var \Hawkbit\Presentation\PresentationService $Presentation */
79+
$service = $app[\Hawkbit\Presentation\PresentationService::class];
9080

9181
```
9282

@@ -97,28 +87,58 @@ Access Presentation service in controller. Hawbit is inject classes to controlle
9787
```php
9888
<?php
9989

100-
use \Hawkbit\Presentation\PresentationServiceInterface;
90+
use \Hawkbit\Presentation\PresentationService;
91+
use Psr\Http\Message\ServerRequestInterface;
92+
use Psr\Http\Message\ResponseInterface;
10193

102-
class MyController{
103-
94+
class MyController
95+
{
10496
/**
105-
* @var \Hawkbit\Presentation\PresentationServiceInterface
97+
* @var PresentationService
10698
*/
107-
private $Presentation = null;
108-
109-
public function __construct(PresentationServiceInterface $Presentation){
110-
$this->Presentation = $Presentation;
99+
private $presentationService;
100+
101+
/**
102+
* TestInjectableController constructor.
103+
* @param PresentationService $presentation
104+
*/
105+
public function __construct(PresentationService $presentation)
106+
{
107+
$this->presentationService = $presentation;
111108
}
112-
113-
public function index(){
114-
$em = $this->Presentation->getEntityManager();
115-
116-
// or with from specific connection
117-
$em = $this->Presentation->getEntityManager('connectionname');
109+
110+
public function getIndex(ServerRequestInterface $request, ResponseInterface $response, array $args = [])
111+
{
112+
$response->getBody()->write($this->presentationService->render('index', ['world' => 'World']));
113+
return $response;
118114
}
119115
}
120116
```
121117

118+
### Access and extend engine
119+
120+
In most cases you would like to extend or access plates. We recommend to extend plates
121+
in a central point of your application like bootstrap or even better in your project service provider.
122+
123+
```php
124+
<?php
125+
126+
use Hawkbit\Presentation\PresentationService;
127+
128+
/** @var PresentationService $service */
129+
$service = $app->getContainer()->get(PresentationService::class);
130+
$service->getEngine()
131+
->addFolder('acme', __DIR__ . '/templates/acme')
132+
->registerFunction('uppercase', function ($string) {
133+
return strtoupper($string);
134+
});
135+
136+
```
137+
138+
### Plates
139+
140+
Please refer to [plates documentation](http://platesphp.com) for more details.
141+
122142
## Change log
123143

124144
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
@@ -140,6 +160,7 @@ If you discover any security related issues, please email <[email protected]> instead
140160
## Credits
141161

142162
- [Marco Bunge](https://github.com/mbunge)
163+
- [Jonathan Reinik (Plates)](https://github.com/reinink)
143164
- [All contributors](https://github.com/hawkbit/Presentation/graphs/contributors)
144165

145166
## License

src/PresentationService.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: marco.bunge
5+
* Date: 02.01.2017
6+
* Time: 11:16
7+
*/
8+
9+
namespace Hawkbit\Presentation;
10+
11+
12+
use Hawkbit\Configuration;
13+
use League\Plates\Engine;
14+
use League\Plates\Template\Template;
15+
16+
class PresentationService
17+
{
18+
19+
/** @var Engine */
20+
private $engine;
21+
22+
/**
23+
* EngineFactory constructor.
24+
* @param array|Configuration $templates
25+
*/
26+
public function __construct($templates)
27+
{
28+
// normalize template config to array
29+
if($templates instanceof Configuration){
30+
$templates = $templates->toArray();
31+
}
32+
33+
// determine default
34+
if(isset($templates['default'])){
35+
$default = $templates['default'];
36+
unset($templates['default']);
37+
}else{
38+
$default = array_shift($templates);
39+
}
40+
41+
// build engine
42+
$engine = new Engine($default);
43+
foreach ($templates as $name => $template) {
44+
$engine->addFolder($name, $template, false);
45+
}
46+
47+
$this->engine = $engine;
48+
}
49+
50+
public function getEngine(){
51+
return $this->engine;
52+
}
53+
54+
/**
55+
* Add preassigned template data.
56+
* @param array $data;
57+
* @param null|string|array $templates;
58+
* @return $this
59+
*/
60+
public function addData(array $data, $templates = null){
61+
$this->engine->addData($data, $templates);
62+
return $this;
63+
}
64+
65+
/**
66+
* Get all preassigned template data.
67+
* @param null|string $template;
68+
* @return array
69+
*/
70+
public function getData($template){
71+
return $this->engine->getData($template);
72+
}
73+
74+
/**
75+
* Check if a template exists.
76+
* @param string $name
77+
* @return boolean
78+
*/
79+
public function exists($name)
80+
{
81+
return $this->engine->exists($name);
82+
}
83+
84+
/**
85+
* Create a new template.
86+
* @param string $name
87+
* @return Template
88+
*/
89+
public function make($name)
90+
{
91+
return $this->engine->make($name);
92+
}
93+
94+
/**
95+
* Create a new template and render it.
96+
* @param string $name
97+
* @param array $data
98+
* @return string
99+
*/
100+
public function render($name, array $data = array())
101+
{
102+
return $this->engine->render($name, $data);
103+
}
104+
}

src/PresentationServiceProvider.php

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,22 @@
99
namespace Hawkbit\Presentation;
1010

1111

12+
use Hawkbit\Configuration;
1213
use League\Container\ServiceProvider\AbstractServiceProvider;
14+
use League\Container\ServiceProvider\BootableServiceProviderInterface;
1315
use League\Plates\Engine;
1416

15-
class PresentationServiceProvider extends AbstractServiceProvider
17+
class PresentationServiceProvider extends AbstractServiceProvider implements BootableServiceProviderInterface
1618
{
1719

18-
protected $provides = [
19-
Engine::class
20-
];
2120
/**
22-
* @var array
21+
* @var
2322
*/
2423
private $templates;
2524

2625
/**
2726
* PresentationServiceProvider constructor.
28-
* @param array $templates
27+
* @param $templates
2928
*/
3029
public function __construct($templates)
3130
{
@@ -41,26 +40,19 @@ public function __construct($templates)
4140
*/
4241
public function register()
4342
{
44-
$this->registerTemplateEngine();
43+
4544
}
4645

4746
/**
48-
* Register template engine
47+
* Method will be invoked on registration of a service provider implementing
48+
* this interface. Provides ability for eager loading of Service Providers.
4949
*
50-
* @return $this
50+
* @return void
5151
*/
52-
protected function registerTemplateEngine()
52+
public function boot()
5353
{
5454
$container = $this->getContainer();
55-
$this->getContainer()->add(Engine::class, function () use ($container) {
56-
$templates = $this->templates;
57-
$default = isset($templates['default']) ? $templates['default'] : reset($templates);
58-
$engine = new Engine($default);
59-
foreach ($templates as $name => $template) {
60-
$engine->addFolder($name, $template, false);
61-
}
62-
return $engine;
63-
});
64-
return $this;
55+
$container->share(PresentationService::class)
56+
->withArgument($this->templates);
6557
}
6658
}

tests/IntegrationTest.php

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
use ContainerInteropDoctrine\EntityManagerFactory;
1313
use Doctrine\ORM\EntityManagerInterface;
1414
use Hawkbit\Application;
15+
use Hawkbit\Presentation\Presentation;
1516
use Hawkbit\Presentation\PresentationService;
1617
use Hawkbit\Presentation\PresentationServiceInterface;
1718
use Hawkbit\Presentation\PresentationServiceProvider;
19+
use Hawkbit\Presentation\Tests\Mocks\InjectableController;
1820
use League\Plates\Engine;
1921
use org\bovigo\vfs\vfsStream;
22+
use Zend\Diactoros\ServerRequestFactory;
2023

2124
class IntegrationTest extends \PHPUnit_Framework_TestCase
2225
{
@@ -26,10 +29,42 @@ public function testIntegration()
2629
$app = new Application(require __DIR__ . '/assets/config.php');
2730
$app->register(new PresentationServiceProvider($app->getConfig('templates')));
2831

29-
$engine = $app[Engine::class];
32+
$engine = $app[PresentationService::class];
3033
$result = $engine->render('index', ['world' => 'World']);
3134

32-
$this->assertInstanceOf(Engine::class, $engine);
35+
$this->assertInstanceOf(PresentationService::class, $engine);
3336
$this->assertEquals('Hello World', $result);
3437
}
38+
39+
public function testInjectableIntegration()
40+
{
41+
$app = new Application(require __DIR__ . '/assets/config.php');
42+
$app->register(new PresentationServiceProvider($app->getConfig('templates')));
43+
44+
$app->get('/', [InjectableController::class, 'getIndex']);
45+
46+
$response = $app->handle(ServerRequestFactory::fromGlobals());
47+
48+
$this->assertEquals('Hello World', $response->getBody()->__toString());
49+
}
50+
51+
public function testExtendEngine()
52+
{
53+
$app = new Application(require __DIR__ . '/assets/config.php');
54+
$app->register(new PresentationServiceProvider($app->getConfig('templates')));
55+
56+
/** @var PresentationService $service */
57+
$service = $app[PresentationService::class];
58+
$service->getEngine()
59+
->addFolder('acme', __DIR__ . '/templates/acme')
60+
->registerFunction('uppercase', function ($string) {
61+
return strtoupper($string);
62+
});
63+
64+
$app->get('/', [InjectableController::class, 'getAcme']);
65+
$response = $app->handle(ServerRequestFactory::fromGlobals());
66+
$this->assertEquals('FOO BAR', $response->getBody()->__toString());
67+
}
68+
69+
3570
}

0 commit comments

Comments
 (0)