Init du projet

This commit is contained in:
2018-06-25 22:39:00 +02:00
commit f9229a6025
122 changed files with 23329 additions and 0 deletions

7
module/Smarty/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.idea
vendor
composer.lock
composer.phar
phpunit.xml
phpmd.xml
phpdox.xml

21
module/Smarty/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 skillfish
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

88
module/Smarty/README.md Normal file
View File

@@ -0,0 +1,88 @@
# zf3-smarty-module
Based on https://github.com/randlem/zf2-smarty-module and modified for use with ZF3
# Installation
Although you could just clone this repository, it is highly recommended to install the module via composer.
- run `php composer.phar require skillfish/zf3-smarty-module`
- add Smarty to your ZF3 modules Configuration e.g /config/modules.config.php
- change the View Manager Strategy to Smarty in your module or apllication config like:
```php
<?php
return [
'view_manager' => [
'strategies' => [
'Smarty\View\Strategy'
],
],
];
```
you might also want to change your View Manager's Template Map to actually use .tpl files instead of the default .phtml
```php
<?php
return [
'view_manager' => [
'template_map' => [
'layout/layout' => '/module/Application/view/layout/layout.tpl',
'application/index/index' => '/module/Application/view/application/index/index.tpl',
'error/404' => '/module/Application/view/error/404.tpl',
'error/index' => '/module/Applicationview/error/index.tpl',
],
],
];
```
# Template Inheritance
In order for template inheritance to work, you must terminate your ViewModel inside your Controller with `$viewModel->setTerminal(true);` and make use of the smarty `{extends}` tag. Otherwise the ViewModel will render the default layout template and inheritance won't work.
### Example
layout.tpl
```html
<html>
<head>
<title>{block 'title'}Page name{/block}</title>
</head>
<body>
{block 'content'}{/block}
</body>
</html>
```
index.tpl
```html
{extends 'layout.tpl'}
{block 'title' append} - Index{/block}
{block 'content'}This is the index template{/block}
```
Controller
```php
public function indexAction()
{
$viewModel = new ViewModel();
$viewModel->setTerminal(true);
return $viewModel;
}
```
will result in
```html
<html>
<head>
<title>Page name - Index</title>
</head>
<body>
This is the index template
</body>
</html>
```
# Requirements
The composer module currently requires:
```json
"require": {
"php": ">5.4",
"smarty/smarty": "~3.1.29",
"zendframework/zend-stdlib": "~3.0.1",
"zendframework/zend-mvc": "~3.0.1",
"zendframework/zend-servicemanager": "~3.1",
"zendframework/zend-modulemanager": "~2.7.1"
},
```

View File

@@ -0,0 +1,30 @@
{
"name": "skillfish/zf3-smarty-module",
"description": "Zend Framework 3 Module for integrating Smarty 3 as View Manager",
"type": "library",
"license": "MIT",
"keywords": [
"smarty",
"module",
"zf3"
],
"authors": [
{
"name": "Heiko Baumgärtner",
"email": "skillfish@gmail.com"
}
],
"require": {
"php": ">5.4",
"smarty/smarty": "^3.1",
"zendframework/zend-stdlib": "^3.0",
"zendframework/zend-mvc": "^3.0",
"zendframework/zend-servicemanager": "^3.1",
"zendframework/zend-modulemanager": "^2.7"
},
"autoload": {
"psr-4": {
"Smarty\\": "src/"
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Smarty2;
use Smarty\View\Strategy;
use Smarty\Service\StrategyFactory;
use Smarty\View\Renderer;
use Smarty\Service\RendererFactory;
use Smarty\Service\PluginManager;
use Smarty\Service\PluginManagerFactory;
use Smarty\Service\PluginDelegator;
return [
'view_manager' => [
'strategies' => [
Strategy::class,
],
],
'service_manager' => [
'factories' => [
Strategy::class => StrategyFactory::class,
Renderer::class => RendererFactory::class,
PluginManager::class => PluginManagerFactory::class,
],
'delegators' => [
Renderer::class => [
PluginDelegator::class,
],
],
],
'smarty' => [
'suffix' => 'tpl',
'compile_dir' => getcwd() . '/data/smarty/templates_c',
'config_file' => getcwd() . '/config/autoload/smarty.conf',
'escape_html' => true,
'caching' => false,
'cache_dir' => getcwd() . '/data/smarty/cache',
'plugins_dir' => getcwd() . '/data/smarty/plugins',
'plugins' => [
// Plugin manager configuration.
'manager' => [
],
// Plugins.
// For example (MyFuncPlugin should be added in Plugin manager):
// 'functions' => [
// 'my_func' => MyFuncPlugin::class,
// ]
// This config register MyFuncPlugin with "my_func" name in Smarty.
'functions' => [
],
'modifiers' => [
],
'blocks' => [
],
'if_blocks' => [
],
'cycle_blocks' => [
],
],
],
];

View File

@@ -0,0 +1,8 @@
<?php
namespace Smarty\Exception;
use Zend\ServiceManager\Exception\InvalidServiceException as ZendInvalidServiceException;
class InvalidServiceException extends ZendInvalidServiceException
{
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Smarty;
class Module
{
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Smarty\Plugin;
use Smarty;
/**
* Interface to detect if a class is Smarty Block plugin.
*/
interface BlockPluginInterface extends PluginInterface
{
/**
* @param array $params
* @param string $content
* @param Smarty $smarty
* @param bool $repeat
*
* @return string
*/
public function prepare(array $params, $content, $smarty, &$repeat);
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Smarty\Plugin;
use Smarty;
/**
* Interface to detect if a class is Smarty CycleBlock plugin.
*/
interface CycleBlockPluginInterface extends PluginInterface
{
/**
* Call before cycle.
*
* @param array $params
* @param Smarty $smarty
*
* @return string|null
*/
public function init(array $params, $smarty);
/**
* Call before iteration.
*
* @param array $params
* @param Smarty $smarty
*
* @return bool true - if the current iteration is valid.
*/
public function isValid(array $params, $smarty);
/**
* Attention: move the pointer to this method.
*
* @param array $params
* @param string $content
* @param Smarty $smarty
*
* @return string Content of the current iteration.
*/
public function prepareIteration(array $params, $content, $smarty);
/**
* Call after cycle.
*
* @param array $params
* @param Smarty $smarty
*
* @return string|null
*/
public function end(array $params, $smarty);
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Smarty\Plugin;
use Smarty;
/**
* Interface to detect if a class is Smarty Function plugin.
*/
interface FunctionPluginInterface extends PluginInterface
{
/**
* @param array $params
* @param Smarty $smarty
*
* @return mixed
*/
public function run(array $params, $smarty);
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Smarty\Plugin;
use Smarty;
/**
* Interface to detect if a class is Smarty IfBlock plugin.
*/
interface IfBlockPluginInterface extends PluginInterface
{
/**
* @param array $params
* @param Smarty $smarty
*
* @return bool
*/
public function checkCondition(array $params, $smarty);
/**
* @param array $params
* @param string $content
* @param Smarty $smarty
*
* @return string Content, if the condition is true.
*/
public function prepareTrue(array $params, $content, $smarty);
/**
* @param array $params
* @param string $content
* @param Smarty $smarty
*
* @return string Content, if the condition is false.
*/
public function prepareFalse(array $params, $content, $smarty);
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Smarty\Plugin;
/**
* Interface to detect if a class is Smarty Modifier plugin.
*/
interface ModifierPluginInterface extends PluginInterface
{
/**
* @param mixed $value
* @param mixed ...
*
* @return mixed
*/
public function modify($value);
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Smarty\Plugin;
/**
* Interface to detect if a class is Smarty plugin.
*
* Abstract base interface that cannot be implemented alone. Instead it must be
* implemented by either FunctionPluginInterface, ModifierPluginInterface,
* BlockPluginInterface or IfBlockPluginInterface.
*/
interface PluginInterface
{
}

View File

@@ -0,0 +1,117 @@
<?php
namespace Smarty\Service;
use Zend\ServiceManager\Factory\DelegatorFactoryInterface;
use Zend\ServiceManager\PluginManagerInterface;
use Interop\Container\ContainerInterface;
use Smarty;
use Smarty\Service\PluginManager;
use Smarty\Service\PluginProxy\IfBlockProxy;
use Smarty\Service\PluginProxy\CycleBlockProxy;
use Smarty\Exception\InvalidServiceException;
use Smarty\Plugin\FunctionPluginInterface;
use Smarty\Plugin\ModifierPluginInterface;
use Smarty\Plugin\BlockPluginInterface;
use Smarty\Plugin\IfBlockPluginInterface;
use Smarty\Plugin\CycleBlockPluginInterface;
/**
* This delegator used for registration Object-plugins in Smarty.
*/
class PluginDelegator implements DelegatorFactoryInterface
{
/**
* @var Smarty
*/
private $smarty;
/**
* @var PluginManagerInterface
*/
private $pluginManager;
/**
* {@inheritdoc}
*/
public function __invoke(ContainerInterface $container, $name, callable $callback, array $options = null)
{
$config = $container->get('Configuration');
$pluginsConfig = $config['smarty']['plugins'];
$renderer = call_user_func($callback);
$this->smarty = $renderer->getEngine();
$this->pluginManager = $container->get(PluginManager::class);
$this->registerFunctionPlugins($pluginsConfig['functions']);
$this->registerModifierPlugins($pluginsConfig['modifiers']);
$this->registerBlockPlugins($pluginsConfig['blocks']);
$this->registerIfBlockPlugins($pluginsConfig['if_blocks']);
$this->registerCycleBlockPlugins($pluginsConfig['cycle_blocks']);
return $renderer;
}
/**
* @param array $pluginsConfig
* @param string $expectedInstance
*
* @throws InvalidServiceException
*
* @return PluginInterface[]
*/
protected function getPlugins(array $pluginsConfig, $expectedInstance)
{
$plugins = [];
foreach ($pluginsConfig as $name => $pluginClass) {
$plugin = $this->pluginManager->build($pluginClass, ['name' => $name]);
if (!$plugin instanceOf $expectedInstance) {
throw new InvalidServiceException(sprintf(
'Plugin delegator "%s" expected an instance of type "%s", but "%s" was received',
__CLASS__,
$expectedInstance,
is_object($plugin) ? get_class($plugin) : gettype($plugin)
));
}
$plugins[$name] = $plugin;
}
return $plugins;
}
public function registerFunctionPlugins(array $plugins)
{
foreach ($this->getPlugins($plugins, FunctionPluginInterface::class) as $name => $plugin) {
$this->smarty->registerPlugin('function', $name, [$plugin, 'run']);
}
}
public function registerModifierPlugins(array $plugins)
{
foreach ($this->getPlugins($plugins, ModifierPluginInterface::class) as $name => $plugin) {
$this->smarty->registerPlugin('modifier', $name, [$plugin, 'modify']);
}
}
public function registerBlockPlugins(array $plugins)
{
foreach ($this->getPlugins($plugins, BlockPluginInterface::class) as $name => $plugin) {
$this->smarty->registerPlugin('block', $name, [$plugin, 'prepare']);
}
}
public function registerIfBlockPlugins(array $plugins)
{
foreach ($this->getPlugins($plugins, IfBlockPluginInterface::class) as $name => $plugin) {
$proxy = new IfBlockProxy($plugin, $name);
$this->smarty->registerPlugin('block', $name, [$proxy, '__invoke']);
$this->smarty->registerPlugin('function', $name . '_else', [$proxy, 'elseFunction']);
}
}
public function registerCycleBlockPlugins(array $plugins)
{
foreach ($this->getPlugins($plugins, CycleBlockPluginInterface::class) as $name => $plugin) {
$proxy = new CycleBlockProxy($plugin);
$this->smarty->registerPlugin('block', $name, [$proxy, '__invoke']);
}
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace Smarty\Service;
use Zend\ServiceManager\AbstractPluginManager;
use Smarty\Plugin\PluginInterface;
class PluginManager extends AbstractPluginManager
{
protected $instanceOf = PluginInterface::class;
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Smarty\Service;
use Zend\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceManager;
class PluginManagerFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = $container->get('Configuration');
$config = $config['smarty']['plugins'];
return new PluginManager($container, $config['manager']);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Smarty\Service\PluginProxy;
use Smarty\Plugin\CycleBlockPluginInterface;
class CycleBlockProxy
{
/**
* @var IfBlockPluginInterface
*/
private $plugin;
/**
* @param IfBlockPluginInterface $plugin
*/
public function __construct(CycleBlockPluginInterface $plugin)
{
$this->plugin = $plugin;
}
public function __invoke(array $params, $content, $smarty, &$repeat)
{
if (is_null($content)) {
return $this->plugin->init($params, $smarty);
}
if (!$this->plugin->isValid($params, $smarty)) {
$repeat = false;
return $this->plugin->end($params, $smarty);
}
$repeat = true;
return $this->plugin->prepareIteration($params, $content, $smarty);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Smarty\Service\PluginProxy;
use Smarty\Plugin\IfBlockPluginInterface;
class IfBlockProxy
{
/**
* @var IfBlockPluginInterface
*/
private $plugin;
/**
* @var string
*/
private $name;
/**
* @param IfBlockPluginInterface $plugin
* @param string $name
*/
public function __construct(IfBlockPluginInterface $plugin, $name)
{
$this->plugin = $plugin;
$this->name = $name;
}
public function __invoke(array $params, $content, $smarty, &$repeat)
{
$trueFalseBlockContents = explode(sprintf('{%s_else}', $this->name), $content);
if (!isset($trueFalseBlockContents[1])) {
$trueFalseBlockContents[1] = '';
}
if (!$this->plugin->checkCondition($params, $smarty)) {
return $this->plugin->prepareFalse($params, $trueFalseBlockContents[1], $smarty);
}
return $this->plugin->prepareTrue($params, $trueFalseBlockContents[0], $smarty);
}
public function elseFunction(array $params, $smarty)
{
return $smarty->left_delimiter . $this->name . '_else' . $smarty->right_delimiter;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Smarty\Service;
use Zend\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
use Smarty\View\Renderer;
use Smarty;
class RendererFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = $container->get('Configuration');
$config = $config['smarty'];
/** @var $pathResolver \Zend\View\Resolver\TemplatePathStack */
$pathResolver = clone $container->get('ViewTemplatePathStack');
$pathResolver->setDefaultSuffix($config['suffix']);
/** @var $resolver \Zend\View\Resolver\AggregateResolver */
$resolver = $container->get('ViewResolver');
$resolver->attach($pathResolver);
$engine = new Smarty();
$engine->setCompileDir($config['compile_dir']);
$engine->setEscapeHtml($config['escape_html']);
$engine->setTemplateDir($pathResolver->getPaths()->toArray());
$engine->setCaching($config['caching']);
$engine->setCacheDir($config['cache_dir']);
$engine->addPluginsDir($config['plugins_dir']);
if (file_exists($config['config_file'])) {
$engine->configLoad($config['config_file']);
}
$renderer = new Renderer();
$renderer->setEngine($engine);
$renderer->setSuffix($config['suffix']);
$renderer->setResolver($resolver);
return $renderer;
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Smarty\Service;
use Zend\ServiceManager\Factory\FactoryInterface;
use Interop\Container\ContainerInterface;
use Smarty\View\Renderer;
use Smarty\View\Strategy;
class StrategyFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$renderer = $container->get(Renderer::class);
$strategy = new Strategy($renderer);
return $strategy;
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace Smarty\View;
use Zend\View\Renderer\RendererInterface;
use Zend\View\Resolver\ResolverInterface;
use Zend\View\Model\ModelInterface;
use Zend\View\Exception\DomainException;
use Smarty;
use ArrayObject;
class Renderer implements RendererInterface
{
/**
* @var Smarty
*/
protected $engine;
/**
* @var ResolverInterface
*/
protected $resolver;
/**
* Template suffix for this renderer
* @var string
*/
protected $suffix;
public function setEngine(Smarty $engine)
{
$this->engine = $engine;
$this->engine->assign('this', $this);
}
public function getEngine()
{
return $this->engine;
}
public function setResolver(ResolverInterface $resolver)
{
$this->resolver = $resolver;
}
public function render($nameOrModel, $values = null)
{
if ($nameOrModel instanceof ModelInterface) {
$model = $nameOrModel;
$nameOrModel = $nameOrModel->getTemplate();
if (empty($nameOrModel)) {
throw new DomainException(sprintf(
'%s: recieved View Model argument, but template is empty.',
__METHOD__
));
}
$values = $model->getVariables();
unset($model);
}
if (!($file = $this->resolver->resolve($nameOrModel))) {
throw new DomainException(sprintf(
'Unable to find template "%s"',
$nameOrModel
));
}
if ($values instanceof ArrayObject) {
$values = $values->getArrayCopy();
}
$smarty = $this->getEngine();
$smarty->clearAllAssign();
$smarty->assign($values);
$content = $smarty->fetch($file);
return $content;
}
public function canRender($nameOrModel)
{
if ($nameOrModel instanceof ModelInterface) {
$nameOrModel = $nameOrModel->getTemplate();
}
$tpl = $this->resolver->resolve($nameOrModel);
$ext = pathinfo($tpl, PATHINFO_EXTENSION);
if ($tpl && $ext == $this->getSuffix()) {
return true;
}
return false;
}
public function setSuffix($suffix)
{
$this->suffix = $suffix;
}
public function getSuffix()
{
return $this->suffix;
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Smarty\View;
use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\View\ViewEvent;
use Smarty\View\Renderer;
class Strategy implements ListenerAggregateInterface
{
/**
* @var callable
*/
protected $listeners = [];
/**
* @var Renderer
*/
protected $renderer;
public function __construct(Renderer $renderer)
{
$this->renderer = $renderer;
}
public function attach(EventManagerInterface $events, $priority = 100)
{
$this->listeners[] = $events->attach(ViewEvent::EVENT_RENDERER, [$this, 'selectRenderer'], $priority);
$this->listeners[] = $events->attach(ViewEvent::EVENT_RESPONSE, [$this, 'injectResponse'], $priority);
}
public function detach(EventManagerInterface $events)
{
foreach ($this->listeners as $index => $listener) {
$events->detach($listener);
unset($this->listeners[$index]);
}
}
public function selectRenderer(ViewEvent $e)
{
if (!$this->renderer->canRender($e->getModel())) {
return false;
}
return $this->renderer;
}
public function injectResponse(ViewEvent $e)
{
$renderer = $e->getRenderer();
if ($renderer !== $this->renderer) {
return false;
}
$result = $e->getResult();
$response = $e->getResponse();
$response->setContent($result);
}
}