Test du sparty parser

This commit is contained in:
franck
2013-06-18 15:36:22 +02:00
parent 0719c8b740
commit 7351edeb46
19 changed files with 10282 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\Template\Assets;
use Assetic\AssetManager;
use Assetic\FilterManager;
use Assetic\Filter;
use Assetic\Factory\AssetFactory;
use Assetic\Factory\Worker\CacheBustingWorker;
use Assetic\AssetWriter;
use Assetic\Asset\AssetCache;
use Assetic\Cache\FilesystemCache;
class AsseticManager {
protected $options;
public function __construct($_options = array()) {
$this->options = $_options;
}
/**
* Generates assets from $asset_path in $output_path, using $filters.
*
* @param string $asset_path the full path to the asset file (or file collection)
* @param unknown $output_path the full disk path to the output directory (shoud be visible to web server)
* @param unknown $output_url the URL to the generated asset directory
* @param unknown $asset_type the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension.
* @param unknown $filters a list of filters, as defined below (see switch($filter_name) ...)
* @param unknown $debug true / false
* @throws \Exception
* @return string The URL to the generated asset file.
*/
public function asseticize($asset_path, $output_path, $output_url, $asset_type, $filters, $debug) {
$asset_name = basename($asset_path);
$asset_dir = dirname($asset_path);
$am = new AssetManager();
$fm = new FilterManager();
if (! empty($filters)) {
$filter_list = explode(',', $filters);
foreach($filter_list as $filter_name) {
$filter_name = trim($filter_name);
switch($filter_name) {
case 'less' :
$fm->set('less', new Filter\LessphpFilter());
break;
case 'sass' :
$fm->set('less', new Filter\Sass\SassFilter());
break;
case 'cssembed' :
$fm->set('cssembed', new Filter\PhpCssEmbedFilter());
break;
case 'cssrewrite':
$fm->set('cssrewrite', new Filter\CssRewriteFilter());
break;
case 'cssimport':
$fm->set('cssimport', new Filter\CssImportFilter());
break;
default :
throw new \Exception("Unsupported Assetic filter: '$filter_name'");
break;
}
}
}
else {
$filter_list = array();
}
// Factory setup
$factory = new AssetFactory($asset_dir);
$factory->setAssetManager($am);
$factory->setFilterManager($fm);
$factory->setDefaultOutput('*'.(! empty($asset_type) ? '.' : '').$asset_type);
$factory->setDebug($debug);
$factory->addWorker(new CacheBustingWorker());
// Prepare the assets writer
$writer = new AssetWriter($output_path);
$asset = $factory->createAsset($asset_name, $filter_list);
$cache = new AssetCache($asset, new FilesystemCache($output_path));
$writer->writeAsset($cache);
return rtrim($output_url, '/').'/'.$asset->getTargetPath();
}
}

View File

@@ -0,0 +1,302 @@
<?php
namespace Thelia\Core\Template;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Thelia\Core\Template\ParserInterface;
use \Smarty;
use Thelia\Core\Template\Loop\Category;
class SmartyParser extends Smarty implements ParserInterface {
/**
* @var Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
protected $template = "smarty-sample";
protected $status = 200;
protected $loopDefinition = array();
public function __construct(ContainerInterface $container)
{
parent::__construct();
$this->container = $container;
$compile_dir = THELIA_ROOT . 'cache/smarty/compile';
if (! is_dir($compile_dir)) @mkdir($compile_dir, 0777, true);
$cache_dir = THELIA_ROOT . 'cache/smarty/cache';
if (! is_dir($cache_dir)) @mkdir($cache_dir, 0777, true);
$this->setTemplateDir(THELIA_TEMPLATE_DIR.$this->template);
$this->setCompileDir($compile_dir);
$this->setCacheDir($cache_dir);
$this->registerPlugin('block', 'loop', array($this, 'theliaLoop'));
$this->registerPlugin('block', 'empty', array($this, 'theliaEmpty'));
$this->registerPlugin('block', 'notempty', array($this, 'theliaNotEmpty'));
// Prevent ErrorException: Notice: Undefined index
$this->error_reporting = E_ALL ^ E_NOTICE;
$this->status = 200;
}
/**
*
* associative array containing information for loop execution
*
* key is loop name
* value is the class implementing/extending base loop classes
*
* ex :
*
* $loop = array(
* "product" => "Thelia\Loop\Product",
* "category" => "Thelia\Loop\Category",
* "myLoop" => "My\Own\Loop"
* );
*
* @param array $loops
* @throws \InvalidArgumentException if loop name already exists
*/
public function setLoopList(array $loopDefinition)
{
foreach ($loopDefinition as $name => $className) {
if (array_key_exists($name, $this->loopDefinition)) {
throw new \InvalidArgumentException(sprintf("%s loop name already exists for %s class name", $name, $className));
}
$this->loopDefinition[$name] = $className;
}
}
private function extractParam($loop, $smartyParam)
{
$defaultItemsParams = array('required' => true);
$shortcutItemParams = array(
'optional' => array('required' => false)
);
$errorCode = 0;
$faultActor = array();
$faultDetails = array();
foreach($loop->defineArgs() as $name => $param){
if(is_integer($name)){
$name = $param;
$param = $defaultItemsParams;
}
if(is_string($param) && array_key_exists($param, $shortcutItemParams)){
$param = $shortcutItemParams[$param];
}
if(!is_array($param)){
$param = array('default' => $param);
}
$value = isset($smartyParam[$name]) ? $smartyParam[$name] : null;
if($value == null){
if(isset($param['default'])){
$value = $param['default'];
}
else if($param['required'] === true){
$faultActor[] = $name;
$faultDetails[] = sprintf('"%s" parameter is missing', $name);
continue;
}
}
$loop->{$name} = $value;
}
if(!empty($faultActor)){
$complement = sprintf('[%s]', implode(', ', $faultDetails));
throw new \InvalidArgumentException($complement);
}
}
public function theliaEmpty($params, $content, $template, &$repeat) {
// When encoutering close tag, check if loop has results.
if ($repeat === false) {
return $this->checkEmptyLoop($params, $template) ? $content : '';
}
}
public function theliaNotEmpty($params, $content, $template, &$repeat) {
// When encoutering close tag, check if loop has results.
if ($repeat === false) {
return $this->checkEmptyLoop($params, $template) ? '' : $content;
}
}
private function checkEmptyLoop($params, $template) {
if (empty($params['name']))
throw new \InvalidArgumentException("Missing 'name' parameter in conditional loop arguments");
$loopName = $params['name'];
// Find loop results in the current template vars
$loopResults = $template->getTemplateVars($loopName);
if (empty($loopResults)) {
throw new \InvalidArgumentException("Loop $loopName is not dfined.");
}
return $loopResults->isEmpty();
}
public function theliaLoop($params, $content, $template, &$repeat) {
if (empty($params['name']))
throw new \InvalidArgumentException("Missing 'name' parameter in loop arguments");
if (empty($params['type']))
throw new \InvalidArgumentException("Missing 'type' parameter in loop arguments");
$name = $params['name'];
if ($content === null) {
$loop = $this->createLoopInstance(strtolower($params['type']));
$this->extractParam($loop, $params);
$loopResults = $loop->exec();
$template->assignByRef($name, $loopResults);
}
else {
$loopResults = $template->getTemplateVars($name);
$loopResults->next();
}
if ($loopResults->valid()) {
$loopResultRow = $loopResults->current();
foreach($loopResultRow->getVarVal() as $var => $val) {
$template->assign(substr($var, 1), $val);
$template->assign('__COUNT__', 1 + $loopResults->key());
$template->assign('__TOTAL__', $loopResults->getCount());
}
$repeat = $loopResults->valid();
}
if ($content !== null) {
if ($loopResults->isEmpty()) $content = "";
return $content;
}
}
/**
*
* find the loop class with his name and construct an instance of this class
*
* @param string $name
* @return \Thelia\Tpex\Element\Loop\BaseLoop
* @throws \Thelia\Tpex\Exception\InvalidElementException
* @throws \Thelia\Tpex\Exception\ElementNotFoundException
*/
protected function createLoopInstance($name)
{
if (! isset($this->loopDefinition[$name])) {
throw new ElementNotFoundException(sprintf("%s loop does not exists", $name));
}
$class = new \ReflectionClass($this->loopDefinition[$name]);
if ($class->isSubclassOf("Thelia\Tpex\Element\Loop\BaseLoop") === false) {
throw new InvalidElementException(sprintf("%s Loop class have to extends Thelia\Tpex\Element\Loop\BaseLoop",
$name));
}
return $class->newInstance(
$this->container->get('request'),
$this->container->get('event_dispatcher')
);
}
/**
*
* This method must return a Symfony\Component\HttpFoudation\Response instance or the content of the response
*
*/
public function getContent()
{
return $this->fetch($this->getTemplateFilePath());
}
/**
*
* set $content with the body of the response or the Response object directly
*
* @param string|Symfony\Component\HttpFoundation\Response $content
*/
public function setContent($content)
{
$this->content = $content;
}
/**
*
* @return type the status of the response
*/
public function getStatus()
{
return $this->status;
}
/**
*
* status HTTP of the response
*
* @param int $status
*/
public function setStatus($status)
{
$this->status = $status;
}
/**
* Main parser function, load the parser
*/
public function loadParser()
{
$file = $this->getTemplateFilePath();
echo "f=$file";
}
protected function getTemplateFilePath()
{
$request = $this->container->get('request');
$file = $request->attributes->get('_view');
$fileName = THELIA_TEMPLATE_DIR . rtrim($this->template, "/") . "/" . $file . ".html";
if (file_exists($fileName)) return $fileName;
throw new ResourceNotFoundException(sprintf("%s file not found in %s template", $file, $this->template));
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,135 @@
// -- Tools --------------------------------------------------------------------
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
.box-shadow(@shadow: 0 1px 2px rgba(0,0,0,.05)) {
-webkit-box-shadow: @shadow;
-moz-box-shadow: @shadow;
box-shadow: @shadow;
}
// -- Base styling ------------------------------------------------------------
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
background: url("img/bg.jpg") repeat;
font-size: 13px;
}
h3, h4 {
color: #5a6876;
background: -webkit-gradient(linear, left top, left bottom, from(#42505d), to(#72808e));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
h3 {
padding: 0px;
margin: 0px 0px 20px 0px;
text-align: left;
font-size : 18px;
}
h4 {
padding: 0px 0px 20px 0px;
margin: 0px;
text-align: left;
}
#wrapper {
padding-top: 20px;
}
a {
color: #e9720f;
font-weight: bold;
}
// -- Brandbar ----------------------------------------------------------------
/* --- BRAND BAR ---*/
.brandbar {
background: url("images/header.jpg") repeat-x;
height: 90px;
a.brand {
text-indent: -133337px;
display: block;
float: left;
margin-right: 20px;
background: url("images/logo.png") 0px 12px no-repeat;
width: 124px;
height: 63px;
}
.breadcrumb {
border-radius: 0px;
padding: 25px 0px 25px 30px;
background: url("images/logo-light.png") left center no-repeat;
float: left;
margin: 12px 0px 0px 0px;
a {
color: #949aa1;
text-shadow: 0px 1px 0px rgba(0,0,0,0.8);
}
.active {
color: #FFF;
text-shadow: 0px 1px 0px rgba(0,0,0,0.8);
border-bottom: 1px dotted white;
}
}
.Blocmoncompte {
float: right;
margin: 0px;
padding: 0px;
margin-top: 35px;
color: white;
font-size: 13px;
text-shadow: 0px 1px 0px rgba(0,0,0,0.8);
}
dt {
float: left;
margin-right: 15px;
}
.deconnexion {
float: right;
margin: 0px;
a {
text-indent: -13337px;
display: block;
background: url("images/deconnexion.png") no-repeat;
width: 23px;
height: 24px;
}
}
}
// -- Login form --------------------------------------------------------------
.form-signin {
max-width: 400px;
padding: 19px 29px 29px;
margin: 0 auto 20px;
background-color: #fff;
border: 1px solid #e5e5e5;
.border-radius;
.box-shadow;
}

File diff suppressed because one or more lines are too long

View File

View File

@@ -0,0 +1,13 @@
{* Include required JS files *}
{javascripts file='../assets/js/jquery.min.js'}
<link rel="stylesheet" href="{$asset_url}" target="screen">
{/javascripts}
{javascripts file='../assets/bootstrap/js/bootstrap.min.js'}
<link rel="stylesheet" href="{$asset_url}" target="screen">
{/javascripts}
{* TODO allow modules to include JS here *}
</body>
</html>

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="{$lang}">
<head>
<title>{intl l='Thelia Back Office'}{if ! empty($page_title)} - {$page_title}{/if}</title>
{images file='../assets/img/favicon.ico'}<link rel="shortcut icon" href="{$asset_url}" />{/images}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{stylesheets file='../assets/css/*' filters='less,cssrewrite'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{stylesheets file='../assets/bootstrap/css/bootstrap.min.css' filters='cssrewrite'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{stylesheets file='../assets/bootstrap/css/bootstrap-responsive.min.css' filters='cssrewrite'}
<link rel="stylesheet" href="{$asset_url}">
{/stylesheets}
{* TODO allow modules to include CSS here *}
</head>
<body>

View File

@@ -0,0 +1,35 @@
{$page_title={intl l='Thelia'}}
{include file='includes/header.inc.tpl'}
<div class="loginpage">
<div class="brandbar container">
<a class="brand" href="index.php">{images file='assets/img/logo-thelia-34px.png'}<img src="{$asset_url}" alt="{intl l='Thelia, solution e-commerce libre'}" />{/images}</a>
</div>
<div id="wrapper" class="container">
{thelia_module action='index_top'}
<div class="hero-unit">
<h1>{intl l='Thelia Back Office'}</h1>
<form action="/admin/login" method="post" class="well form-inline">
<input type="text" class="input" placeholder="{intl l='E-mail address'}" name="username" />
<input type="password" class="input" placeholder="{intl l='Password'}" name="password" />
<label class="checkbox"> <input type="checkbox" name="remember" value="yes"> {intl l='Remember me'}</label>
<button type="submit" class="btn btn-primary">{intl l='Login'} <i class="icon-play"></i></button>
</form>
</div>
<div class="row-fluid">
</div>
</div>
{thelia_module action='index_bottom'}
</div>
{include file='includes/footer.inc.tpl'}

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?>

View File

@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<p>Category loop example</p>
{loop type="category" name="catloop1"}
{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE} <br />
nb child : {$NB_CHILD} <br /><br />
{/loop}
</div>
<div>
<p>Conditional example #1</p>
{notempty name="catloop2"}
Loop catloop2 is not empty: <ul>
{loop type="category" name="catloop2" parent="12"}
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
{/loop}
</ul>
{/notempty}
{empty name="catloop2"}
<p>Loop catloop2 is empty</p>
{/empty}
</div>
<div>
<p>Conditional example #2</p>
{notempty name="catloop3"}
Loop catloop3 is not empty: <ul>
{loop type="category" name="catloop3" parent="0"}
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
{/loop}
</ul>
{/notempty}
{empty name="catloop3"}
<p>Loop catloop3 is empty</p>
{/empty}
{empty name="catloop2"}
<p>... but catloop2 is still empty :-)</p>
{/empty}
</div>
<div>
<p>Traditional for loop</p>
{for $index=5 to 12 step 1}
Compteur = {$index}<br />
{/for}
</div>
</body>
</html>