Merge branch 'master' of https://github.com/thelia/thelia into coupon

* 'master' of https://github.com/thelia/thelia: (121 commits)
  set cartItem in cart add and update events
  need to unescape breadcrumb strings after been in array
  update readme file
  update insert.sql with new release version
  change changelog file format
  Prevent product and content création at catalog root
  dynamic delivery modules on delivery front template
  complete changelog
  Finished merging modules with master
  Revert "Merge branch 'cleanmaster' into modules"
  use TaxEngine::getDeliveryCountry in delivery loop
  refacto getTaxCountry which is actually getDeliveryCountry
  make it magic last stand
  change loop in shipping zone template using module insteadof delivery
  Fixed template loop
  Refactored templates processing
  complete readme file
  change email address of core contributors
  fix getPosition folder test
  add coupon tests
  ...

Conflicts:
	core/lib/Thelia/Controller/Admin/ProductController.php
This commit is contained in:
gmorel
2013-12-25 14:14:20 +01:00
199 changed files with 7036 additions and 2625 deletions

View File

@@ -33,7 +33,6 @@ class CategoryUpdateEvent extends CategoryCreateEvent
protected $description;
protected $postscriptum;
protected $url;
protected $parent;
public function __construct($category_id)
@@ -89,18 +88,6 @@ class CategoryUpdateEvent extends CategoryCreateEvent
return $this;
}
public function getUrl()
{
return $this->url;
}
public function setUrl($url)
{
$this->url = $url;
return $this;
}
public function getParent()
{
return $this->parent;

View File

@@ -36,8 +36,6 @@ class ContentUpdateEvent extends ContentCreateEvent
protected $description;
protected $postscriptum;
protected $url;
public function __construct($content_id)
{
$this->content_id = $content_id;
@@ -123,24 +121,4 @@ class ContentUpdateEvent extends ContentCreateEvent
return $this->postscriptum;
}
/**
* @param mixed $url
*
* @return $this
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @return mixed
*/
public function getUrl()
{
return $this->url;
}
}

View File

@@ -37,8 +37,6 @@ class FolderUpdateEvent extends FolderCreateEvent
protected $description;
protected $postscriptum;
protected $url;
public function __construct($folder_id)
{
$this->folder_id = $folder_id;
@@ -116,22 +114,4 @@ class FolderUpdateEvent extends FolderCreateEvent
return $this->postscriptum;
}
/**
* @param mixed $url
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @return mixed
*/
public function getUrl()
{
return $this->url;
}
}

View File

@@ -33,7 +33,6 @@ class ProductUpdateEvent extends ProductCreateEvent
protected $description;
protected $postscriptum;
protected $url;
protected $parent;
public function __construct($product_id)
@@ -89,18 +88,6 @@ class ProductUpdateEvent extends ProductCreateEvent
return $this;
}
public function getUrl()
{
return $this->url;
}
public function setUrl($url)
{
$this->url = $url;
return $this;
}
public function getParent()
{
return $this->parent;

View File

@@ -160,6 +160,7 @@ final class TheliaEvents
const CATEGORY_DELETE = "action.deleteCategory";
const CATEGORY_TOGGLE_VISIBILITY = "action.toggleCategoryVisibility";
const CATEGORY_UPDATE_POSITION = "action.updateCategoryPosition";
const CATEGORY_UPDATE_SEO = "action.updateCategorySeo";
const CATEGORY_ADD_CONTENT = "action.categoryAddContent";
const CATEGORY_REMOVE_CONTENT = "action.categoryRemoveContent";
@@ -180,6 +181,7 @@ final class TheliaEvents
const FOLDER_DELETE = "action.deleteFolder";
const FOLDER_TOGGLE_VISIBILITY = "action.toggleFolderVisibility";
const FOLDER_UPDATE_POSITION = "action.updateFolderPosition";
const FOLDER_UPDATE_SEO = "action.updateFolderSeo";
const BEFORE_CREATEFOLDER = "action.before_createFolder";
const AFTER_CREATEFOLDER = "action.after_createFolder";
@@ -197,6 +199,7 @@ final class TheliaEvents
const CONTENT_DELETE = "action.deleteContent";
const CONTENT_TOGGLE_VISIBILITY = "action.toggleContentVisibility";
const CONTENT_UPDATE_POSITION = "action.updateContentPosition";
const CONTENT_UPDATE_SEO = "action.updateContentSeo";
const CONTENT_ADD_FOLDER = "action.contentAddFolder";
const CONTENT_REMOVE_FOLDER = "action.contentRemoveFolder";
@@ -269,6 +272,7 @@ final class TheliaEvents
const PRODUCT_DELETE = "action.deleteProduct";
const PRODUCT_TOGGLE_VISIBILITY = "action.toggleProductVisibility";
const PRODUCT_UPDATE_POSITION = "action.updateProductPosition";
const PRODUCT_UPDATE_SEO = "action.updateProductSeo";
const PRODUCT_ADD_CONTENT = "action.productAddContent";
const PRODUCT_REMOVE_CONTENT = "action.productRemoveContent";
@@ -404,6 +408,7 @@ final class TheliaEvents
* Save given documents
*/
const DOCUMENT_UPDATE = "action.updateDocument";
const DOCUMENT_UPDATE_POSITION = "action.updateDocumentPosition";
/**
* Delete given document
@@ -424,6 +429,7 @@ final class TheliaEvents
* Save given images
*/
const IMAGE_UPDATE = "action.updateImages";
const IMAGE_UPDATE_POSITION = "action.updateImagePosition";
/**
* Delete given image
@@ -685,9 +691,15 @@ final class TheliaEvents
*/
const MODULE_TOGGLE_ACTIVATION = 'thelia.module.toggleActivation';
/**
* sent when module position is changed
*/
const MODULE_UPDATE_POSITION = 'thelia.module.action.updatePosition';
/**
* module
*/
const MODULE_CREATE = 'thelia.module.create';
const MODULE_UPDATE = 'thelia.module.update';
const MODULE_DELETE = 'thelia.module.delete';

View File

@@ -0,0 +1,60 @@
<?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\Event;
use Propel\Runtime\ActiveQuery\ModelCriteria;
class UpdateFilePositionEvent extends UpdatePositionEvent
{
protected $query;
/**
* @param ModelCriteria $query
* @param $object_id
* @param null $mode
* @param null $position
*/
public function __construct(ModelCriteria $query, $object_id, $mode, $position = null)
{
parent::__construct($object_id, $mode, $position);
$this->setQuery($query);
}
/**
* @param ModelCriteria $query
*/
public function setQuery(ModelCriteria $query)
{
$this->query = $query;
}
/**
* @return ModelCriteria|null
*/
public function getQuery()
{
return $this->query;
}
}

View File

@@ -0,0 +1,188 @@
<?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\Event;
class UpdateSeoEvent extends ActionEvent
{
protected $object_id;
protected $locale;
protected $url;
protected $meta_title;
protected $meta_description;
protected $meta_keywords;
protected $object;
/**
* @param $object_id
* @param null $locale
* @param null $url
* @param null $meta_title
* @param null $meta_description
* @param null $meta_keywords
*/
public function __construct($object_id, $locale = null, $url = null, $meta_title = null, $meta_description = null, $meta_keywords = null)
{
$this->object_id = $object_id;
$this->locale = $locale;
$this->url = $url;
$this->meta_title = $meta_title;
$this->meta_description = $meta_description;
$this->meta_keywords = $meta_keywords;
}
/**
* @return mixed
*/
public function getObjectId()
{
return $this->object_id;
}
/**
* @param $object_id
* @return $this
*/
public function setObjectId($object_id)
{
$this->object_id = $object_id;
return $this;
}
/**
* @return null
*/
public function getLocale()
{
return $this->locale;
}
/**
* @param $locale
* @return $this
*/
public function setLocale($locale)
{
$this->locale = $locale;
return $this;
}
/**
* @return null
*/
public function getUrl()
{
return $this->url;
}
/**
* @param $url
* @return $this
*/
public function setUrl($url)
{
$this->url = $url;
return $this;
}
/**
* @return null
*/
public function getMetaTitle()
{
return $this->meta_title;
}
/**
* @param $meta_title
* @return $this
*/
public function setMetaTitle($meta_title)
{
$this->meta_title = $meta_title;
return $this;
}
/**
* @return null
*/
public function getMetaDescription()
{
return $this->meta_description;
}
/**
* @param $meta_description
* @return $this
*/
public function setMetaDescription($meta_description)
{
$this->meta_description = $meta_description;
return $this;
}
/**
* @return null
*/
public function getMetaKeywords()
{
return $this->meta_keywords;
}
/**
* @param $meta_keywords
* @return $this
*/
public function setMetaKeywords($meta_keywords)
{
$this->meta_keywords = $meta_keywords;
return $this;
}
/**
* @param mixed $object
*/
public function setObject($object)
{
$this->object = $object;
return $this;
}
/**
* @return mixed
*/
public function getObject()
{
return $this->object;
}
}

View File

@@ -78,7 +78,7 @@ class ViewListener implements EventSubscriberInterface
{
$parser = $this->container->get('thelia.parser');
$parser->setTemplate(TemplateHelper::getInstance()->getActiveFrontTemplate());
$parser->setTemplateDefinition(TemplateHelper::getInstance()->getActiveFrontTemplate());
$request = $this->container->get('request');
try {

View File

@@ -34,6 +34,11 @@ use Symfony\Component\HttpFoundation\Request as BaseRequest;
class Request extends BaseRequest
{
private $excludeContent = array(
'username',
'password'
);
public function getProductId()
{
return $this->get("product_id");
@@ -66,4 +71,17 @@ class Request extends BaseRequest
{
return parent::getSession();
}
public function toString($withContent = true)
{
$string =
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
$this->headers."\r\n";
if (true === $withContent) {
$string .= $this->getContent();
}
return $string;
}
}

View File

@@ -23,7 +23,7 @@
namespace Thelia\Core\Security\Exception;
class RessourceException extends \RuntimeException
class ResourceException extends \RuntimeException
{
const UNKNOWN_EXCEPTION = 0;

View File

@@ -25,29 +25,43 @@ namespace Thelia\Core\Template\Assets;
interface AssetManagerInterface {
/**
* Prepare an asset directory.
* Prepare an asset directory by checking that no changes occured in
* the source directory. If any change is detected, the whole asset directory
* is copied in the web space.
*
* @param string $sourceAssetsDirectory the full path to the source asstes directory
* @param string $webAssetsDirectoryBase the base directory of the web based asset directory
* @param $webAssetsTemplate
* @param string $webAssetsKey the assets key : module name or 0 for base template
*
* @param string $source_assets_directory the full path to the source asstes directory
* @param string $web_assets_directory_base the base directory of the web based asset directory
* @throws \RuntimeException if something goes wrong.
*
* @internal param string $source_assets_directory the full path to the source asstes directory
* @internal param string $web_assets_directory_base the base directory of the web based asset directory
* @internal param string $key the assets key : module name or 0 for base template
*/
public function prepareAssets($source_assets_directory, $web_assets_directory_base);
public function prepareAssets($sourceAssetsDirectory, $webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey);
/**
* Generates assets from $asset_path in $output_path, using $filters.
*
* @param string $asset_path the full path to the asset file (or file collection, e.g. *.less)
* @param $assetSource
* @param $assetDirectoryBase
* @param string $webAssetsDirectoryBase the full path to the asset file (or file collection, e.g. *.less)
*
* @param string $web_assets_directory_base the full disk path to the base assets output directory in the web space
* @param string $output_url the URL to the base assets output directory in the web space
* @param string $webAssetsTemplate the full disk path to the base assets output directory in the web space
* @param $webAssetsKey
* @param string $outputUrl the URL to the base assets output directory in the web space
*
* @param string $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 array $filters a list of filters, as defined below (see switch($filter_name) ...)
* @param string $assetType the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension.
* @param array $filters a list of filters, as defined below (see switch($filter_name) ...)
*
* @param boolean $debug the debug mode, true or false
* @param boolean $debug true / false
*
* @throws \InvalidArgumentException if an invalid filter name is found
* @return string The URL to the generated asset file.
* @internal param string $web_assets_directory_base the full disk path to the base assets output directory in the web space
* @internal param string $output_url the URL to the base assets output directory in the web space
*
* @return string The URL to the generated asset file.
*/
public function processAsset($asset_path, $web_assets_directory_base, $output_url, $asset_type, $filters, $debug);
public function processAsset($assetSource, $assetDirectoryBase, $webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey, $outputUrl, $assetType, $filters, $debug);
}

View File

@@ -31,7 +31,6 @@ use Assetic\AssetWriter;
use Thelia\Model\ConfigQuery;
use Thelia\Log\Tlog;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOException;
/**
* This class is a simple helper for generating assets using Assetic.
@@ -73,7 +72,9 @@ class AsseticAssetManager implements AssetManagerInterface
/**
* Check if a file is a source asset file
*
* @param \DirectoryIterator $fileInfo
* @param \SplFileInfo $fileInfo
*
* @return bool
*/
protected function isSourceFile(\SplFileInfo $fileInfo) {
return in_array($fileInfo->getExtension(), $this->source_file_extensions);
@@ -81,8 +82,9 @@ class AsseticAssetManager implements AssetManagerInterface
/**
* Recursively copy assets from the source directory to the destination
* directory in the web space, ommiting source files.
* directory in the web space, omitting source files.
*
* @param Filesystem $fs
* @param string $from_directory the source
* @param string $to_directory the destination
* @throws \RuntimeException if a problem occurs.
@@ -121,38 +123,21 @@ class AsseticAssetManager implements AssetManagerInterface
}
}
/**
* Compite the assets path relative to the base template directory
*
* @param string $source_assets_directory the source directory
* @param string $web_assets_directory_base base directory of the web assets
* @return the full path of the destination directory
*/
protected function getRelativeDirectoryPath($source_assets_directory, $web_assets_directory_base)
{
$source_assets_directory = realpath($source_assets_directory);
// Remove base path from asset source path to get a path relative to the template base
// and use it to create the destination path.
return str_replace(
realpath(THELIA_ROOT),
'',
$source_assets_directory
);
}
/**
* Compute the destination directory path, from the source directory and the
* base directory of the web assets
*
* @param string $source_assets_directory the source directory
* @param string $web_assets_directory_base base directory of the web assets
* @param string $webAssetsDirectoryBase base directory of the web assets
* @param $webAssetsTemplate
* @param string $webAssetsKey the assests key : module name or 0 for base template
*
* @internal param string $source_assets_directory the source directory
* @return the full path of the destination directory
*/
protected function getDestinationDirectory($source_assets_directory, $web_assets_directory_base)
protected function getDestinationDirectory($webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey)
{
// Compute the absolute path of the output directory
return $web_assets_directory_base . $this->getRelativeDirectoryPath($source_assets_directory, $web_assets_directory_base);
return $webAssetsDirectoryBase . DS . $webAssetsTemplate . DS . $webAssetsKey;
}
/**
@@ -160,14 +145,17 @@ class AsseticAssetManager implements AssetManagerInterface
* the source directory. If any change is detected, the whole asset directory
* is copied in the web space.
*
* @param string $source_assets_directory the full path to the source asstes directory
* @param string $web_assets_directory_base the base directory of the web based asset directory
* @param string $sourceAssetsDirectory the full path to the source asstes directory
* @param string $webAssetsDirectoryBase the base directory of the web based asset directory
* @param $webAssetsTemplate
* @param string $webAssetsKey the assets key : module name or 0 for base template
*
* @throws \RuntimeException if something goes wrong.
*/
public function prepareAssets($source_assets_directory, $web_assets_directory_base) {
public function prepareAssets($sourceAssetsDirectory, $webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey)
{
// Compute the absolute path of the output directory
$to_directory = $this->getDestinationDirectory($source_assets_directory, $web_assets_directory_base);
$to_directory = $this->getDestinationDirectory($webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey);
// Get a path to the stamp file
$stamp_file_path = $to_directory . DS . '.source-stamp';
@@ -176,7 +164,7 @@ class AsseticAssetManager implements AssetManagerInterface
$prev_stamp = @file_get_contents($stamp_file_path);
// Get the current stamp of the source directory
$curr_stamp = $this->getStamp($source_assets_directory);
$curr_stamp = $this->getStamp($sourceAssetsDirectory);
if ($prev_stamp !== $curr_stamp) {
@@ -197,7 +185,7 @@ class AsseticAssetManager implements AssetManagerInterface
$fs->remove($tmp_dir);
// Copy the whole source dir in a temp directory
$this->copyAssets($fs, $source_assets_directory, $tmp_dir);
$this->copyAssets($fs, $sourceAssetsDirectory, $tmp_dir);
// Remove existing directory
if ($fs->exists($to_directory)) $fs->remove($to_directory);
@@ -284,67 +272,73 @@ class AsseticAssetManager implements AssetManagerInterface
/**
* Generates assets from $asset_path in $output_path, using $filters.
*
* @param string $asset_path the full path to the asset file (or file collection, e.g. *.less)
* @param $assetSource
* @param $assetDirectoryBase
* @param string $webAssetsDirectoryBase the full path to the asset file (or file collection, e.g. *.less)
*
* @param string $web_assets_directory_base the full disk path to the base assets output directory in the web space
* @param string $output_url the URL to the base assets output directory in the web space
* @param string $webAssetsTemplate the full disk path to the base assets output directory in the web space
* @param $webAssetsKey
* @param string $outputUrl the URL to the base assets output directory in the web space
*
* @param string $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 array $filters a list of filters, as defined below (see switch($filter_name) ...)
* @param string $assetType the asset type: css, js, ... The generated files will have this extension. Pass an empty string to use the asset source extension.
* @param array $filters a list of filters, as defined below (see switch($filter_name) ...)
*
* @param boolean $debug true / false
* @throws \InvalidArgumentException if an invalid filter name is found
* @return string The URL to the generated asset file.
* @param boolean $debug true / false
*
* @return string The URL to the generated asset file.
*/
public function processAsset($asset_path, $web_assets_directory_base, $output_url, $asset_type, $filters, $debug)
public function processAsset($assetSource, $assetDirectoryBase, $webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey, $outputUrl, $assetType, $filters, $debug)
{
$asset_name = basename($asset_path);
$input_directory = realpath(dirname($asset_path));
$assetName = basename($assetSource);
$inputDirectory = realpath(dirname($assetSource));
$assetFileDirectoryInAssetDirectory = trim(str_replace(array($assetDirectoryBase, $assetName), '', $assetSource), DS);
$am = new AssetManager();
$fm = new FilterManager();
// Get the filter list
$filter_list = $this->decodeAsseticFilters($fm, $filters);
$filterList = $this->decodeAsseticFilters($fm, $filters);
// Factory setup
$factory = new AssetFactory($input_directory);
$factory = new AssetFactory($inputDirectory);
$factory->setAssetManager($am);
$factory->setFilterManager($fm);
$factory->setDefaultOutput('*' . (!empty($asset_type) ? '.' : '') . $asset_type);
$factory->setDefaultOutput('*' . (!empty($assetType) ? '.' : '') . $assetType);
$factory->setDebug($debug);
$asset = $factory->createAsset($asset_name, $filter_list);
$asset = $factory->createAsset($assetName, $filterList);
$input_directory = realpath(dirname($asset_path));
$output_directory = $this->getDestinationDirectory($input_directory, $web_assets_directory_base);
$outputDirectory = $this->getDestinationDirectory($webAssetsDirectoryBase, $webAssetsTemplate, $webAssetsKey);
// Get the URL part from the relative path
$output_relative_path = $this->getRelativeDirectoryPath($input_directory, $web_assets_directory_base);
$outputRelativePath = $webAssetsTemplate . DS . $webAssetsKey;
$output_relative_web_path = rtrim(str_replace('\\', '/', $output_relative_path), '/') . '/';
$outputRelativeWebPath = rtrim(str_replace('\\', '/', $outputRelativePath), '/') . '/';
$asset_target_filename = $asset->getTargetPath();
$assetTargetFilename = $asset->getTargetPath();
// This is the final name of the generated asset
$asset_destination_path = $output_directory . DS . $asset_target_filename;
/*
* This is the final name of the generated asset
* We preserve file structure intending to keep - for example - relative css links working
*/
$assetDestinationPath = $outputDirectory . DS . $assetFileDirectoryInAssetDirectory . DS . $assetTargetFilename;
Tlog::getInstance()->addDebug("Asset destination full path: $asset_destination_path");
Tlog::getInstance()->addDebug("Asset destination full path: $assetDestinationPath");
// We generate an asset only if it does not exists, or if the asset processing is forced in development mode
if (! file_exists($asset_destination_path) || ($this->debugMode && ConfigQuery::read('process_assets', true)) ) {
if (! file_exists($assetDestinationPath) || ($this->debugMode && ConfigQuery::read('process_assets', true)) ) {
$writer = new AssetWriter($output_directory);
$writer = new AssetWriter($outputDirectory . DS . $assetFileDirectoryInAssetDirectory);
Tlog::getInstance()->addDebug("Writing asset to $output_directory");
Tlog::getInstance()->addDebug("Writing asset to $outputDirectory . DS . $assetFileDirectoryInAssetDirectory");
$writer->writeAsset($asset);
}
return rtrim($output_url, '/') . '/' . ltrim($output_relative_web_path, '/') . $asset_target_filename;
return rtrim($outputUrl, '/') . '/' . trim($outputRelativeWebPath, '/') . '/' . trim($assetFileDirectoryInAssetDirectory, '/') . '/' . ltrim($assetTargetFilename, '/');
}
}
}

View File

@@ -16,6 +16,7 @@ use Thelia\Core\Template\Element\LoopResultRow;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Model\CountryQuery;
use Thelia\TaxEngine\TaxEngine;
use Thelia\Type;
class Cart extends BaseLoop implements ArraySearchLoopInterface
@@ -78,7 +79,7 @@ class Cart extends BaseLoop implements ArraySearchLoopInterface
public function parseResults(LoopResult $loopResult)
{
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic;
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
foreach($loopResult->getResultDataCollection() as $cartItem) {
$product = $cartItem->getProduct();

View File

@@ -96,7 +96,7 @@ class Category extends BaseI18nLoop implements PropelSearchLoopInterface
$search = CategoryQuery::create();
/* manage translations */
$this->configureI18nProcessing($search);
$this->configureI18nProcessing($search, array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS'));
$id = $this->getId();
@@ -213,25 +213,28 @@ class Category extends BaseI18nLoop implements PropelSearchLoopInterface
$loopResultRow = new LoopResultRow($category);
$loopResultRow
->set("ID", $category->getId())
->set("IS_TRANSLATED",$category->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$this->locale)
->set("TITLE", $category->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $category->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT", $category->getParent())
->set("URL", $category->getUrl($this->locale))
->set("PRODUCT_COUNT", $category->countAllProducts())
->set("CHILD_COUNT", $category->countChild())
->set("VISIBLE", $category->getVisible() ? "1" : "0")
->set("POSITION", $category->getPosition())
->set("ID" , $category->getId())
->set("IS_TRANSLATED" ,$category->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" ,$this->locale)
->set("TITLE" , $category->getVirtualColumn('i18n_TITLE'))
->set("CHAPO" , $category->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION" , $category->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $category->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT" , $category->getParent())
->set("URL" , $category->getUrl($this->locale))
->set("META_TITLE" , $category->getVirtualColumn('i18n_META_TITLE'))
->set("META_DESCRIPTION" , $category->getVirtualColumn('i18n_META_DESCRIPTION'))
->set("META_KEYWORDS" , $category->getVirtualColumn('i18n_META_KEYWORDS'))
->set("PRODUCT_COUNT" , $category->countAllProducts())
->set("CHILD_COUNT" , $category->countChild())
->set("VISIBLE" , $category->getVisible() ? "1" : "0")
->set("POSITION" , $category->getPosition())
->set("HAS_PREVIOUS", $previous != null ? 1 : 0)
->set("HAS_NEXT" , $next != null ? 1 : 0)
->set("HAS_PREVIOUS" , $previous != null ? 1 : 0)
->set("HAS_NEXT" , $next != null ? 1 : 0)
->set("PREVIOUS", $previous != null ? $previous->getId() : -1)
->set("NEXT" , $next != null ? $next->getId() : -1)
->set("PREVIOUS" , $previous != null ? $previous->getId() : -1)
->set("NEXT" , $next != null ? $next->getId() : -1)
;
$loopResult->addRow($loopResultRow);

View File

@@ -85,7 +85,7 @@ class Content extends BaseI18nLoop implements PropelSearchLoopInterface
$search = ContentQuery::create();
/* manage translations */
$this->configureI18nProcessing($search);
$this->configureI18nProcessing($search, array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS'));
$id = $this->getId();
@@ -215,17 +215,21 @@ class Content extends BaseI18nLoop implements PropelSearchLoopInterface
foreach ($loopResult->getResultDataCollection() as $content) {
$loopResultRow = new LoopResultRow($content);
$loopResultRow->set("ID", $content->getId())
->set("IS_TRANSLATED",$content->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$this->locale)
->set("TITLE",$content->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $content->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $content->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $content->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $content->getPosition())
->set("DEFAULT_FOLDER", $content->getDefaultFolderId())
->set("URL", $content->getUrl($this->locale))
->set("VISIBLE", $content->getVisible())
$loopResultRow->set("ID" , $content->getId())
->set("IS_TRANSLATED" , $content->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" , $this->locale)
->set("TITLE" , $content->getVirtualColumn('i18n_TITLE'))
->set("CHAPO" , $content->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION" , $content->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $content->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("URL" , $content->getUrl($this->locale))
->set("META_TITLE" , $content->getVirtualColumn('i18n_META_TITLE'))
->set("META_DESCRIPTION" , $content->getVirtualColumn('i18n_META_DESCRIPTION'))
->set("META_KEYWORDS" , $content->getVirtualColumn('i18n_META_KEYWORDS'))
->set("POSITION" , $content->getPosition())
->set("DEFAULT_FOLDER" , $content->getDefaultFolderId())
->set("VISIBLE" , $content->getVisible())
;
$loopResult->addRow($loopResultRow);

View File

@@ -29,6 +29,7 @@ use Thelia\Exception\OrderException;
use Thelia\Model\CountryQuery;
use Thelia\Module\BaseModule;
use Thelia\Module\DeliveryModuleInterface;
use Thelia\TaxEngine\TaxEngine;
/**
* Class Delivery
@@ -59,7 +60,7 @@ class Delivery extends BaseSpecificModule
throw new \InvalidArgumentException('Cannot found country id: `' . $countryId . '` in delivery loop');
}
} else {
$country = CountryQuery::create()->findOneByByDefault(1);
$country = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
}
foreach ($loopResult->getResultDataCollection() as $deliveryModule) {

View File

@@ -78,7 +78,7 @@ class Folder extends BaseI18nLoop implements PropelSearchLoopInterface
$search = FolderQuery::create();
/* manage translations */
$this->configureI18nProcessing($search);
$this->configureI18nProcessing($search, array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS'));
$id = $this->getId();
@@ -164,19 +164,22 @@ class Folder extends BaseI18nLoop implements PropelSearchLoopInterface
$loopResultRow = new LoopResultRow($folder);
$loopResultRow
->set("ID", $folder->getId())
->set("IS_TRANSLATED",$folder->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE",$this->locale)
->set("TITLE",$folder->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $folder->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $folder->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $folder->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT", $folder->getParent())
->set("URL", $folder->getUrl($this->locale))
->set("CHILD_COUNT", $folder->countChild())
->set("CONTENT_COUNT", $folder->countAllContents())
->set("VISIBLE", $folder->getVisible() ? "1" : "0")
->set("POSITION", $folder->getPosition())
->set("ID" , $folder->getId())
->set("IS_TRANSLATED" , $folder->getVirtualColumn('IS_TRANSLATED'))
->set("LOCALE" , $this->locale)
->set("TITLE" , $folder->getVirtualColumn('i18n_TITLE'))
->set("CHAPO" , $folder->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION" , $folder->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $folder->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("PARENT" , $folder->getParent())
->set("URL" , $folder->getUrl($this->locale))
->set("META_TITLE" , $folder->getVirtualColumn('i18n_META_TITLE'))
->set("META_DESCRIPTION" , $folder->getVirtualColumn('i18n_META_DESCRIPTION'))
->set("META_KEYWORDS" , $folder->getVirtualColumn('i18n_META_KEYWORDS'))
->set("CHILD_COUNT" , $folder->countChild())
->set("CONTENT_COUNT" , $folder->countAllContents())
->set("VISIBLE" , $folder->getVisible() ? "1" : "0")
->set("POSITION" , $folder->getPosition())
;
$loopResult->addRow($loopResultRow);

View File

@@ -38,6 +38,7 @@ use Thelia\Model\ModuleQuery;
use Thelia\Module\BaseModule;
use Thelia\Type;
use Thelia\Type\TypeCollection;
/**
*
@@ -76,6 +77,13 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
))
)
),
new Argument(
'order',
new TypeCollection(
new Type\EnumListType(array('id', 'id_reverse', 'code', 'code_reverse', 'alpha', 'alpha_reverse', 'manual', 'manual_reverse', 'enabled', 'enabled_reverse'))
),
'manual'
),
Argument::createIntListTypeArgument('exclude'),
Argument::createBooleanOrBothTypeArgument('active', Type\BooleanOrBothType::ANY)
);
@@ -126,7 +134,42 @@ class Module extends BaseI18nLoop implements PropelSearchLoopInterface
$search->filterByActivate($active ? 1 : 0, Criteria::EQUAL);
}
$search->orderByPosition();
$orders = $this->getOrder();
foreach ($orders as $order) {
switch ($order) {
case "id":
$search->orderById(Criteria::ASC);
break;
case "id_reverse":
$search->orderById(Criteria::DESC);
break;
case "alpha":
$search->addAscendingOrderByColumn('i18n_TITLE');
break;
case "alpha_reverse":
$search->addDescendingOrderByColumn('i18n_TITLE');
break;
case "code":
$search->orderByCode(Criteria::ASC);
break;
case "code_reverse":
$search->orderByCode(Criteria::DESC);
break;
case "manual":
$search->orderByPosition(Criteria::ASC);
break;
case "manual_reverse":
$search->orderByPosition(Criteria::DESC);
break;
case "enabled":
$search->orderByActivate(Criteria::ASC);
break;
case "enabled_reverse":
$search->orderByActivate(Criteria::DESC);
break;
}
}
return $search;

View File

@@ -42,6 +42,7 @@ use Thelia\Model\Map\ProductPriceTableMap;
use Thelia\Model\Map\ProductSaleElementsTableMap;
use Thelia\Model\Map\ProductTableMap;
use Thelia\Model\ProductQuery;
use Thelia\TaxEngine\TaxEngine;
use Thelia\Type\TypeCollection;
use Thelia\Type;
@@ -222,7 +223,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
}
/* manage translations */
$this->configureI18nProcessing($search);
$this->configureI18nProcessing($search, array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS'));
$id = $this->getId();
@@ -464,7 +465,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
return $this->parseComplex($loopResult);
}
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
foreach ($loopResult->getResultDataCollection() as $product) {
@@ -518,6 +519,9 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
->set("DESCRIPTION" , $product->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("URL" , $product->getUrl($this->locale))
->set("META_TITLE" , $product->getVirtualColumn('i18n_META_TITLE'))
->set("META_DESCRIPTION" , $product->getVirtualColumn('i18n_META_DESCRIPTION'))
->set("META_KEYWORDS" , $product->getVirtualColumn('i18n_META_KEYWORDS'))
->set("BEST_PRICE" , $product->getVirtualColumn('is_promo') ? $promoPrice : $price)
->set("BEST_PRICE_TAX" , $taxedPrice - $product->getVirtualColumn('is_promo') ? $taxedPromoPrice - $promoPrice : $taxedPrice - $price)
->set("BEST_TAXED_PRICE" , $product->getVirtualColumn('is_promo') ? $taxedPromoPrice : $taxedPrice)
@@ -569,7 +573,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
$search = ProductQuery::create();
/* manage translations */
$this->configureI18nProcessing($search);
$this->configureI18nProcessing($search, array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS'));
$attributeNonStrictMatch = $this->getAttribute_non_strict_match();
$isPSELeftJoinList = array();
@@ -979,7 +983,7 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
{
$loopResult = new LoopResult($results);
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
foreach ($loopResult->getResultDataCollection() as $product) {
@@ -1025,6 +1029,9 @@ class Product extends BaseI18nLoop implements PropelSearchLoopInterface, SearchL
->set("DESCRIPTION" , $product->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM" , $product->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("URL" , $product->getUrl($this->locale))
->set("META_TITLE" , $product->getVirtualColumn('i18n_META_TITLE'))
->set("META_DESCRIPTION" , $product->getVirtualColumn('i18n_META_DESCRIPTION'))
->set("META_KEYWORDS" , $product->getVirtualColumn('i18n_META_KEYWORDS'))
->set("BEST_PRICE" , $price)
->set("BEST_PRICE_TAX" , $taxedPrice - $price)
->set("BEST_TAXED_PRICE" , $taxedPrice)

View File

@@ -37,6 +37,7 @@ use Thelia\Model\Base\ProductSaleElementsQuery;
use Thelia\Model\CountryQuery;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Map\ProductSaleElementsTableMap;
use Thelia\TaxEngine\TaxEngine;
use Thelia\Type\TypeCollection;
use Thelia\Type;
@@ -145,7 +146,7 @@ class ProductSaleElements extends BaseLoop implements PropelSearchLoopInterface
public function parseResults(LoopResult $loopResult)
{
$taxCountry = CountryQuery::create()->findPk(64); // @TODO : make it magic
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
foreach ($loopResult->getResultDataCollection() as $PSEValue) {
$loopResultRow = new LoopResultRow($PSEValue);

View File

@@ -59,9 +59,9 @@ class Template extends BaseLoop implements ArraySearchLoopInterface
{
return new ArgumentCollection(
new Argument(
'template_type',
'template-type',
new Type\TypeCollection(
new Type\EnumListType(array(
new Type\EnumType(array(
'front-office',
'back-office',
'pdf',
@@ -73,7 +73,7 @@ class Template extends BaseLoop implements ArraySearchLoopInterface
}
public function buildArray() {
$type = $this->getArg(template_type);
$type = $this->getArg('template-type')->getValue();
if ($type == 'front-office')
$templateType = TemplateDefinition::FRONT_OFFICE;
@@ -104,4 +104,4 @@ class Template extends BaseLoop implements ArraySearchLoopInterface
return $loopResult;
}
}
}

View File

@@ -30,9 +30,6 @@ namespace Thelia\Core\Template;
interface ParserInterface
{
/**
*
*/
public function render($realTemplateName, array $parameters = array());
public function setContent($content);
@@ -40,4 +37,26 @@ interface ParserInterface
public function getStatus();
public function setStatus($status);
}
/**
* Add a template directory to the current template list
*
* @param unknown $templateType the template type (
*
* @param string $templateName the template name
* @param string $templateDirectory path to the template dirtectory
* @param unknown $key ???
* @param string $unshift ??? Etienne ?
*/
public function addTemplateDirectory($templateType, $templateName, $templateDirectory, $key, $unshift = false);
/**
* Return the registeted template directories for a givent template type
*
* @param unknown $templateType
* @throws InvalidArgumentException if the tempmateType is not defined
* @return array: an array of defined templates directories for the given template type
*/
public function getTemplateDirectories($templateType);
}

View File

@@ -24,6 +24,7 @@
namespace Thelia\Core\Template\Smarty\Assets;
use Thelia\Core\Template\Assets\AsseticHelper;
use Thelia\Core\Template\TemplateDefinition;
use Thelia\Tools\URL;
use Thelia\Core\Template\Assets\AssetManagerInterface;
@@ -36,6 +37,8 @@ class SmartyAssetsManager
private $web_root;
private $path_relative_to_web_root;
static private $assetsDirectory = null;
/**
* Creates a new SmartyAssetsManager instance
*
@@ -51,48 +54,75 @@ class SmartyAssetsManager
$this->assetsManager = $assetsManager;
}
public function prepareAssets($assets_directory, \Smarty_Internal_Template $template) {
public function prepareAssets($assets_directory, \Smarty_Internal_Template $template)
{
self::$assetsDirectory = $assets_directory;
$tpl_dir = dirname($template->source->filepath);
$smartyParser = $template->smarty;
$templateDefinition = $smartyParser->getTemplateDefinition();
$asset_dir_absolute_path = realpath($tpl_dir . DS . $assets_directory);
// Get the registered template directories for the current template path
$templateDirectories = $smartyParser->getTemplateDirectories($templateDefinition->getType());
if ($asset_dir_absolute_path === false) throw new \Exception("Failed to get real path of '".$tpl_dir . DS . $assets_directory."'");
if (isset($templateDirectories[$templateDefinition->getName()])) {
$this->assetsManager->prepareAssets(
$asset_dir_absolute_path,
$this->web_root . $this->path_relative_to_web_root
);
/* create assets foreach registered directory : main @ modules */
foreach($templateDirectories[$templateDefinition->getName()] as $key => $directory) {
$tpl_path = $directory . DS . self::$assetsDirectory;
$asset_dir_absolute_path = realpath($tpl_path);
if (false !== $asset_dir_absolute_path) {
$this->assetsManager->prepareAssets(
$asset_dir_absolute_path,
$this->web_root . $this->path_relative_to_web_root,
$templateDefinition->getPath(),
$key
);
}
}
}
}
public function computeAssetUrl($assetType, $params, \Smarty_Internal_Template $template)
{
$file = $params['file'];
$filters = isset($params['filters']) ? $params['filters'] : '';
$debug = isset($params['debug']) ? trim(strtolower($params['debug'])) == 'true' : false;
$file = $params['file'];
$assetOrigin = isset($params['source']) ? $params['source'] : "0";
$filters = isset($params['filters']) ? $params['filters'] : '';
$debug = isset($params['debug']) ? trim(strtolower($params['debug'])) == 'true' : false;
// Get template base path
$tpl_path = $template->source->filepath;
/* we trick here relative thinking for file attribute */
$file = ltrim($file, '/');
while(substr($file, 0, 3) == '../') {
$file = substr($file, 3);
}
// Get basedir
$tpl_dir = dirname($tpl_path);
$smartyParser = $template->smarty;
$templateDefinition = $smartyParser->getTemplateDefinition();
// Create absolute dir path
$asset_dir = realpath($tpl_dir) . DS . dirname($file);
$asset_file = basename($file);
$templateDirectories = $smartyParser->getTemplateDirectories($templateDefinition->getType());
if ($asset_dir === false) throw new \Exception("Failed to get real path of '".$tpl_dir.'/'.dirname($file)."'");
if (! isset($templateDirectories[$templateDefinition->getName()][$assetOrigin])) {
throw new \Exception("Failed to get real path of '/".dirname($file)."'");
}
$url = $this->assetsManager->processAsset(
$asset_dir . DS . $asset_file,
$this->web_root . $this->path_relative_to_web_root,
URL::getInstance()->absoluteUrl($this->path_relative_to_web_root, null, URL::PATH_TO_FILE /* path only */),
$assetType,
$filters,
$debug
);
$assetSource = $templateDirectories[$templateDefinition->getName()][$assetOrigin];
return $url;
$url = $this->assetsManager->processAsset(
$assetSource . DS . $file,
$assetSource . DS . self::$assetsDirectory,
$this->web_root . $this->path_relative_to_web_root,
$templateDefinition->getPath(),
$assetOrigin,
URL::getInstance()->absoluteUrl($this->path_relative_to_web_root, null, URL::PATH_TO_FILE /* path only */),
$assetType,
$filters,
$debug
);
return $url;
}
public function processSmartyPluginCall($assetType, $params, $content, \Smarty_Internal_Template $template, &$repeat)

View File

@@ -40,6 +40,7 @@ use Thelia\Model\OrderQuery;
use Thelia\Model\Product;
use Thelia\Model\ProductQuery;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\TaxEngine\TaxEngine;
use Thelia\Tools\DateTimeFormat;
use Thelia\Cart\CartTrait;
@@ -181,10 +182,10 @@ class DataAccessFunctions extends AbstractSmartyPlugin
public function cartDataAccess($params, $smarty)
{
if (array_key_exists('currentCountry', self::$dataAccessCache)) {
$currentCountry = self::$dataAccessCache['currentCountry'];
$taxCountry = self::$dataAccessCache['currentCountry'];
} else {
$currentCountry = CountryQuery::create()->findOneById(64); // @TODO : make it magic
self::$dataAccessCache['currentCountry'] = $currentCountry;
$taxCountry = TaxEngine::getInstance($this->request->getSession())->getDeliveryCountry();
self::$dataAccessCache['currentCountry'] = $taxCountry;
}
$cart = $this->getCart($this->request);
@@ -197,7 +198,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
$result = $cart->getTotalAmount();
break;
case "total_taxed_price":
$result = $cart->getTaxedAmount($currentCountry);
$result = $cart->getTaxedAmount($taxCountry);
break;
}

View File

@@ -16,6 +16,7 @@ use Thelia\Core\Template\ParserContext;
use Thelia\Core\Template\TemplateDefinition;
use Thelia\Model\ConfigQuery;
use Thelia\Core\Template\TemplateHelper;
use Imagine\Exception\InvalidArgumentException;
use Thelia\Core\Translation\Translator;
/**
@@ -34,7 +35,12 @@ class SmartyParser extends Smarty implements ParserInterface
protected $backOfficeTemplateDirectories = array();
protected $frontOfficeTemplateDirectories = array();
protected $template = "";
protected $templateDirectories = array();
/**
* @var TemplateDefinition
*/
protected $templateDefinition = "";
protected $status = 200;
@@ -91,6 +97,46 @@ class SmartyParser extends Smarty implements ParserInterface
$this->registerFilter('variable', array(__CLASS__, "theliaEscape"));
}
/**
* Add a template directory to the current template list
*
* @param unknown $templateType the template type (a TemplateDefinition type constant)
* @param string $templateName the template name
* @param string $templateDirectory path to the template dirtectory
* @param unknown $key ???
* @param string $unshift ??? Etienne ?
*/
public function addTemplateDirectory($templateType, $templateName, $templateDirectory, $key, $unshift = false) {
if(true === $unshift && isset($this->templateDirectories[$templateType][$templateName])) {
$this->templateDirectories[$templateType][$templateName] = array_merge(
array(
$key => $templateDirectory,
),
$this->templateDirectories[$templateType][$templateName]
);
} else {
$this->templateDirectories[$templateType][$templateName][$key] = $templateDirectory;
}
}
/**
* Return the registeted template directories for a givent template type
*
* @param unknown $templateType
* @throws InvalidArgumentException
* @return multitype:
*/
public function getTemplateDirectories($templateType)
{
if (! isset($this->templateDirectories[$templateType])) {
throw new InvalidArgumentException("Failed to get template type %", $templateType);
}
return $this->templateDirectories[$templateType];
}
public function removeBlankLines($tpl_source, \Smarty_Internal_Template $template)
{
return preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $tpl_source);
@@ -105,72 +151,52 @@ class SmartyParser extends Smarty implements ParserInterface
}
}
public function addBackOfficeTemplateDirectory($templateName, $templateDirectory, $key)
{
$this->backOfficeTemplateDirectories[$templateName][$key] = $templateDirectory;
}
public function addFrontOfficeTemplateDirectory($templateName, $templateDirectory, $key)
{
$this->frontOfficeTemplateDirectories[$templateName][$key] = $templateDirectory;
}
/**
* @param TemplateDefinition $templateDefinition
*/
public function setTemplate(TemplateDefinition $templateDefinition)
public function setTemplateDefinition(TemplateDefinition $templateDefinition)
{
$this->template = $templateDefinition->getPath();
$this->templateDefinition = $templateDefinition;
/* init template directories */
$this->setTemplateDir(array());
/* add main template directory */
$this->addTemplateDir($templateDefinition->getAbsolutePath(), 0);
/* define config directory */
$configDirectory = $templateDefinition->getAbsoluteConfigPath();
$configDirectory = THELIA_TEMPLATE_DIR . $this->getTemplate() . '/configs';
$this->setConfigDir($configDirectory);
/* add modules template directories */
switch($templateDefinition->getType()) {
case TemplateDefinition::FRONT_OFFICE:
/* do not pass array directly to addTemplateDir since we cant control on keys */
if(isset($this->frontOfficeTemplateDirectories[$templateDefinition->getName()])) {
foreach($this->frontOfficeTemplateDirectories[$templateDefinition->getName()] as $key => $directory) {
$this->addTemplateDir($directory, $key);
}
}
break;
$this->addTemplateDirectory(
$templateDefinition->getType(),
$templateDefinition->getName(),
THELIA_TEMPLATE_DIR . $this->getTemplate(),
'0',
true
);
case TemplateDefinition::BACK_OFFICE:
/* do not pass array directly to addTemplateDir since we cant control on keys */
if(isset($this->backOfficeTemplateDirectories[$templateDefinition->getName()])) {
foreach($this->backOfficeTemplateDirectories[$templateDefinition->getName()] as $key => $directory) {
$this->addTemplateDir($directory, $key);
}
}
break;
case TemplateDefinition::PDF:
break;
default:
break;
/* do not pass array directly to addTemplateDir since we cant control on keys */
if (isset($this->templateDirectories[$templateDefinition->getType()][$templateDefinition->getName()])) {
foreach($this->templateDirectories[$templateDefinition->getType()][$templateDefinition->getName()] as $key => $directory) {
$this->addTemplateDir($directory, $key);
}
}
}
public function getTemplateDefinition()
{
return $this->templateDefinition;
}
public function getTemplate()
{
return $this->template;
return $this->templateDefinition->getPath();
}
/**
* Return a rendered template, either from file or ftom a string
*
* @param string $resourceType either 'string' (rendering from a string) or 'file' (rendering a file)
* @param string $resourceContent the resource content (a text, or a template file name)
* @param array $parameters an associative array of names / value pairs
* @param string $resourceType either 'string' (rendering from a string) or 'file' (rendering a file)
* @param string $resourceContent the resource content (a text, or a template file name)
* @param array $parameters an associative array of names / value pairs
*
* @return string the rendered template text
*/
@@ -186,17 +212,16 @@ class SmartyParser extends Smarty implements ParserInterface
return $this->fetch(sprintf("%s:%s", $resourceType, $resourceContent));
}
/**
* Return a rendered template file
*
* @param string $realTemplateName the template name (from the template directory)
* @param array $parameters an associative array of names / value pairs
* @param string $realTemplateName the template name (from the template directory)
* @param array $parameters an associative array of names / value pairs
* @return string the rendered template text
*/
public function render($realTemplateName, array $parameters = array()) {
if(false === $this->templateExists($realTemplateName)) {
public function render($realTemplateName, array $parameters = array())
{
if (false === $this->templateExists($realTemplateName)) {
throw new ResourceNotFoundException(Translator::getInstance()->trans("Template file %file cannot be found.", array('%file', $realTemplateName)));
}
@@ -206,11 +231,12 @@ class SmartyParser extends Smarty implements ParserInterface
/**
* Return a rendered template text
*
* @param string $templateText the template text
* @param array $parameters an associative array of names / value pairs
* @param string $templateText the template text
* @param array $parameters an associative array of names / value pairs
* @return string the rendered template text
*/
public function renderString($templateText, array $parameters = array()) {
public function renderString($templateText, array $parameters = array())
{
return $this->internalRenderer('string', $templateText, $parameters);
}

View File

@@ -35,6 +35,13 @@ class TemplateDefinition
const PDF_SUBDIR = 'pdf/';
const EMAIL_SUBDIR = 'email/';
protected static $standardTemplatesSubdirs = array(
self::FRONT_OFFICE => self::FRONT_OFFICE_SUBDIR,
self::BACK_OFFICE => self::BACK_OFFICE_SUBDIR,
self::PDF => self::PDF_SUBDIR,
self::EMAIL => self::EMAIL_SUBDIR,
);
/**
* @var the template directory name (e.g. 'default')
*/
@@ -128,4 +135,11 @@ class TemplateDefinition
$this->type = $type;
return $this;
}
}
/**
* Returns an iterator on the standard templates subdir names
*/
public static function getStandardTemplatesSubdirsIterator() {
return new \ArrayIterator(self::$standardTemplatesSubdirs);
}
}

View File

@@ -86,36 +86,52 @@ class TemplateHelper
);
}
/**
* Returns an array which contains all standard template definitions
*/
public function getStandardTemplateDefinitions() {
return array(
$this->getActiveFrontTemplate(),
$this->getActiveAdminTemplate(),
$this->getActivePdfTemplate(),
$this->getActiveMailTemplate(),
);
}
/**
* Return a list of existing templates for a given template type
*
* @param int $templateType the template type
* @return An array of \Thelia\Core\Template\TemplateDefinition
*/
public function getList($templateType) {
$list = $exclude = array();
if ($templateType == TemplateDefinition::BACK_OFFICE) {
$baseDir = THELIA_TEMPLATE_DIR.TemplateDefinition::BACK_OFFICE_SUBDIR;
$tplIterator = TemplateDefinition::getStandardTemplatesSubdirsIterator();
foreach($tplIterator as $type => $subdir) {
if ($templateType == $type) {
$baseDir = THELIA_TEMPLATE_DIR.$subdir;
// Every subdir of the basedir is supposed to be a template.
$di = new \DirectoryIterator($baseDir);
foreach ($di as $file) {
// Ignore 'dot' elements
if ($file->isDot() || ! $file->isDir()) continue;
// Ignore reserved directory names
if (in_array($file->getFilename()."/", $exclude)) continue;
$list[] = new TemplateDefinition($file->getFilename(), $templateType);
}
return $list;
}
}
else if ($templateType == TemplateDefinition::PDF) {
$baseDir = THELIA_TEMPLATE_DIR.TemplateDefinition::PDF_SUBDIR;
}
else {
$baseDir = THELIA_TEMPLATE_DIR.TemplateDefinition::FRONT_OFFICE_SUBDIR;
$exclude = array(TemplateDefinition::BACK_OFFICE_SUBDIR, TemplateDefinition::PDF_SUBDIR);
}
// Every subdir of the basedir is supposed to be a template.
$di = new \DirectoryIterator($baseDir);
foreach ($di as $file) {
// Ignore 'dot' elements
if ($file->isDot() || ! $file->isDir()) continue;
// Ignore reserved directory names
if (in_array($file->getFilename()."/", $exclude)) continue;
$list[] = new TemplateDefinition($file->getFilename(), $templateType);
}
return $list;
}

View File

@@ -55,11 +55,12 @@ use Symfony\Component\Config\FileLocator;
use Propel\Runtime\Propel;
use Propel\Runtime\Connection\ConnectionManagerSingle;
use Thelia\Core\Template\TemplateHelper;
use Thelia\Log\Tlog;
class Thelia extends Kernel
{
const THELIA_VERSION = '2.0.0-beta1';
const THELIA_VERSION = '2.0.0-beta2';
public function init()
{
@@ -105,6 +106,61 @@ class Thelia extends Kernel
}
/**
* Add all module's standard templates to the parser environment
*
* @param TheliaParser $parser the parser
* @param Module $module the Module.
*/
protected function addStandardModuleTemplatesToParserEnvironment($parser, $module) {
$stdTpls = TemplateDefinition::getStandardTemplatesSubdirsIterator();
foreach($stdTpls as $templateType => $templateSubdirName) {
$this->addModuleTemplateToParserEnvironment($parser, $module, $templateType, $templateSubdirName);
}
}
/**
* Add a module template directory to the parser environment
*
* @param TheliaParser $parser the parser
* @param Module $module the Module.
* @param string $templateType the template type (one of the TemplateDefinition type constants)
* @param string $templateSubdirName the template subdirectory name (one of the TemplateDefinition::XXX_SUBDIR constants)
*/
protected function addModuleTemplateToParserEnvironment($parser, $module, $templateType, $templateSubdirName) {
// Get template path
$templateDirectory = $module->getAbsoluteTemplateDirectoryPath($templateSubdirName);
try {
$templateDirBrowser = new \DirectoryIterator($templateDirectory);
$code = ucfirst($module->getCode());
/* browse the directory */
foreach ($templateDirBrowser as $templateDirContent) {
/* is it a directory which is not . or .. ? */
if ($templateDirContent->isDir() && ! $templateDirContent->isDot()) {
$parser->addMethodCall(
'addTemplateDirectory',
array(
$templateType,
$templateDirContent->getFilename(),
$templateDirContent->getPathName(),
$code
)
);
}
}
}
catch (\UnexpectedValueException $ex) {
// The directory does not exists, ignore it.
}
}
/**
*
* Load some configuration
@@ -129,22 +185,19 @@ class Thelia extends Kernel
$translationDirs = array();
$parser = $container->getDefinition('thelia.parser');
foreach ($modules as $module) {
try {
$defintion = new Definition();
$defintion->setClass($module->getFullNamespace());
$defintion->addMethodCall("setContainer", array(new Reference('service_container')));
$definition = new Definition();
$definition->setClass($module->getFullNamespace());
$definition->addMethodCall("setContainer", array(new Reference('service_container')));
$container->setDefinition(
"module.".$module->getCode(),
$defintion
$definition
);
$code = ucfirst($module->getCode());
$loader = new XmlFileLoader($container, new FileLocator($module->getAbsoluteConfigPath()));
$loader->load("config.xml");
@@ -152,79 +205,24 @@ class Thelia extends Kernel
$translationDirs[] = $dir;
}
/* is there a front-office template directory ? */
$frontOfficeModuleTemplateDirectory = sprintf("%s%stemplates%s%s", $module->getAbsoluteBaseDir(), DS, DS, TemplateDefinition::FRONT_OFFICE_SUBDIR);
if (is_dir($frontOfficeModuleTemplateDirectory)) {
try {
$moduleFrontOfficeTemplateBrowser = new \DirectoryIterator($frontOfficeModuleTemplateDirectory);
} catch (\UnexpectedValueException $e) {
throw $e;
}
$this->addStandardModuleTemplatesToParserEnvironment($parser, $module);
/* browse the directory */
foreach ($moduleFrontOfficeTemplateBrowser as $moduleFrontOfficeTemplateContent) {
/* is it a directory which is not . or .. ? */
if ($moduleFrontOfficeTemplateContent->isDir() && !$moduleFrontOfficeTemplateContent->isDot()) {
$parser->addMethodCall(
'addFrontOfficeTemplateDirectory',
array(
$moduleFrontOfficeTemplateContent->getFilename(),
$moduleFrontOfficeTemplateContent->getPathName(),
$code,
)
);
}
}
}
/* is there a back-office template directory ? */
$backOfficeModuleTemplateDirectory = sprintf("%s%stemplates%s%s", $module->getAbsoluteBaseDir(), DS, DS, TemplateDefinition::BACK_OFFICE_SUBDIR);
if (is_dir($backOfficeModuleTemplateDirectory)) {
try {
$moduleBackOfficeTemplateBrowser = new \DirectoryIterator($backOfficeModuleTemplateDirectory);
} catch (\UnexpectedValueException $e) {
throw $e;
}
/* browse the directory */
foreach ($moduleBackOfficeTemplateBrowser as $moduleBackOfficeTemplateContent) {
/* is it a directory which is not . or .. ? */
if ($moduleBackOfficeTemplateContent->isDir() && !$moduleBackOfficeTemplateContent->isDot()) {
$parser->addMethodCall(
'addBackOfficeTemplateDirectory',
array(
$moduleBackOfficeTemplateContent->getFilename(),
$moduleBackOfficeTemplateContent->getPathName(),
$code,
)
);
}
}
}
} catch (\InvalidArgumentException $e) {
// TODO: process module configuration exception
Tlog::getInstance()->addError(sprintf("Failed to load module %s: %s", $module->getCode(), $e->getMessage()), $e);
}
}
// Load translation from templates
//core translation
// core translation
$translationDirs[] = THELIA_ROOT . "core/lib/Thelia/Config/I18n";
// Standard templates (front, back, pdf, mail)
$th = TemplateHelper::getInstance();
// admin template
if (is_dir($dir = $th->getActiveAdminTemplate()->getAbsoluteI18nPath())) {
$translationDirs[] = $dir;
}
// front template
if (is_dir($dir = $th->getActiveFrontTemplate()->getAbsoluteI18nPath())) {
$translationDirs[] = $dir;
}
// PDF template
if (is_dir($dir = $th->getActivePdfTemplate()->getAbsoluteI18nPath())) {
$translationDirs[] = $dir;
foreach($th->getStandardTemplateDefinitions() as $templateDefinition) {
if (is_dir($dir = $templateDefinition->getAbsoluteI18nPath())) {
$translationDirs[] = $dir;
}
}
if ($translationDirs) {
@@ -372,5 +370,4 @@ class Thelia extends Kernel
//Nothing is load here but it's possible to load container configuration here.
//exemple in sf2 : $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
}
}