Merge branch 'master' of github.com:thelia/thelia

This commit is contained in:
Manuel Raynaud
2013-09-06 16:15:04 +02:00
42 changed files with 1518 additions and 700 deletions

View File

@@ -185,6 +185,7 @@
<service id="smarty.plugin.dataAccess" class="Thelia\Core\Template\Smarty\Plugins\DataAccessFunctions" scope="request">
<tag name="thelia.parser.register_plugin"/>
<argument type="service" id="request" />
<argument type="service" id="thelia.securityContext" />
<argument type="service" id="thelia.parser.context"/>
</service>

View File

@@ -113,10 +113,19 @@
<default key="_controller">Thelia\Controller\Admin\CurrencyController::deleteAction</default>
</route>
<route id="admin.configuration.currencies.update-position" path="/admin/configuration/currencies/update-position">
<route id="admin.configuration.attribute" path="/admin/configuration/product_attributes">
<default key="_controller">Thelia\Controller\Admin\AttributeController::defaultAction</default>
</route>
<!-- attribute and feature routes management -->
<route id="admin.configuration.currencies.update-position" path="/admin/configuration/product_attributes">
<default key="_controller">Thelia\Controller\Admin\CurrencyController::updatePositionAction</default>
</route>
<!-- end attribute and feature routes management -->
<!-- The default route, to display a template -->
<route id="admin.processTemplate" path="/admin/{template}">

View File

@@ -0,0 +1,57 @@
<?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\Controller\Admin;
use Thelia\Core\Event\MessageDeleteEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Tools\URL;
use Thelia\Core\Event\MessageUpdateEvent;
use Thelia\Core\Event\MessageCreateEvent;
use Thelia\Log\Tlog;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Core\Security\Exception\AuthorizationException;
use Thelia\Model\MessageQuery;
use Thelia\Form\MessageModificationForm;
use Thelia\Form\MessageCreationForm;
/**
* Manages messages sent by mail
*
* @author Franck Allimant <franck@cqfdev.fr>
*/
class AttributeController extends BaseAdminController
{
/**
* The default action is displaying the messages list.
*
* @return Symfony\Component\HttpFoundation\Response the response
*/
public function defaultAction() {
if (null !== $response = $this->checkAuth("admin.configuration.attributes.view")) return $response;
return $this->render('product_attributes');
}
}

View File

@@ -241,7 +241,7 @@ class ConfigController extends BaseAdminController
if ($this->getRequest()->get('save_mode') == 'stay') {
$this->redirectToRoute(
"admin.configuration.variables.change",
"admin.configuration.variables.update",
array('variable_id' => $variable_id)
);
}

View File

@@ -226,7 +226,7 @@ class BaseController extends ContainerAware
$route = $this->container->get($routerName)->getRouteCollection()->get($routeId);
if ($route == null) {
throw new InvalidArgumentException(sprintf("Route ID '%s' does not exists.", $routeId));
throw new \InvalidArgumentException(sprintf("Route ID '%s' does not exists.", $routeId));
}
return $route->getPath();

View File

@@ -162,7 +162,8 @@ class Attribute extends BaseI18nLoop
->set("TITLE",$attribute->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $attribute->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $attribute->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $attribute->getVirtualColumn('i18n_POSTSCRIPTUM'));
->set("POSTSCRIPTUM", $attribute->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $attribute->getPosition());
$loopResult->addRow($loopResultRow);
}

View File

@@ -131,7 +131,8 @@ class AttributeAvailability extends BaseI18nLoop
->set("TITLE",$attributeAv->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $attributeAv->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $attributeAv->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $attributeAv->getVirtualColumn('i18n_POSTSCRIPTUM'));
->set("POSTSCRIPTUM", $attributeAv->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $attributeAv->getPosition());
$loopResult->addRow($loopResultRow);
}

View File

@@ -113,10 +113,10 @@ class Country extends BaseI18nLoop
->set("TITLE",$country->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $country->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $country->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $country->getVirtualColumn('i18n_POSTSCRIPTUM'));
$loopResultRow->set("ISOCODE", $country->getIsocode());
$loopResultRow->set("ISOALPHA2", $country->getIsoalpha2());
$loopResultRow->set("ISOALPHA3", $country->getIsoalpha3());
->set("POSTSCRIPTUM", $country->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("ISOCODE", $country->getIsocode())
->set("ISOALPHA2", $country->getIsoalpha2())
->set("ISOALPHA3", $country->getIsoalpha3());
$loopResult->addRow($loopResultRow);
}

View File

@@ -154,7 +154,8 @@ class Feature extends BaseI18nLoop
->set("TITLE",$feature->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $feature->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $feature->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $feature->getVirtualColumn('i18n_POSTSCRIPTUM'));
->set("POSTSCRIPTUM", $feature->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $feature->getPosition());
$loopResult->addRow($loopResultRow);
}

View File

@@ -129,7 +129,8 @@ class FeatureAvailability extends BaseI18nLoop
->set("TITLE",$featureAv->getVirtualColumn('i18n_TITLE'))
->set("CHAPO", $featureAv->getVirtualColumn('i18n_CHAPO'))
->set("DESCRIPTION", $featureAv->getVirtualColumn('i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $featureAv->getVirtualColumn('i18n_POSTSCRIPTUM'));
->set("POSTSCRIPTUM", $featureAv->getVirtualColumn('i18n_POSTSCRIPTUM'))
->set("POSITION", $featureAv->getPosition());
$loopResult->addRow($loopResultRow);
}

View File

@@ -149,7 +149,8 @@ class FeatureValue extends BaseI18nLoop
->set("TITLE",$featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_TITLE'))
->set("CHAPO", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_CHAPO'))
->set("DESCRIPTION", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_DESCRIPTION'))
->set("POSTSCRIPTUM", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM'));
->set("POSTSCRIPTUM", $featureValue->getVirtualColumn(FeatureAvTableMap::TABLE_NAME . '_i18n_POSTSCRIPTUM'))
->set("POSITION", $featureValue->getPosition());
$loopResult->addRow($loopResultRow);
}

View File

@@ -89,7 +89,8 @@ class Title extends BaseI18nLoop
->set("LOCALE",$locale)
->set("DEFAULT", $title->getByDefault())
->set("SHORT", $title->getVirtualColumn('i18n_SHORT'))
->set("LONG", $title->getVirtualColumn('i18n_LONG'));
->set("LONG", $title->getVirtualColumn('i18n_LONG'))
->set("POSITION", $title->getPosition());
$loopResult->addRow($loopResultRow);
}

View File

@@ -121,7 +121,7 @@ class AdminUtilities extends AbstractSmartyPlugin
}
if (! empty($icon))
$output = sprintf('<i class="icon icon-chevron-%s"></i> ', $icon);
$output = sprintf('<i class="glyphicon glyphicon-chevron-%s"></i> ', $icon);
else
$output = '';

View File

@@ -23,10 +23,20 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Propel\Runtime\ActiveQuery\ModelCriteria;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Template\ParserContext;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Model\CategoryQuery;
use Thelia\Model\ContentQuery;
use Thelia\Model\FolderQuery;
use Thelia\Model\Product;
use Thelia\Model\ProductQuery;
use Thelia\Model\Tools\ModelCriteriaTools;
use Thelia\Tools\DateTimeFormat;
/**
* Implementation of data access to main Thelia objects (users, cart, etc.)
*
@@ -37,10 +47,13 @@ class DataAccessFunctions extends AbstractSmartyPlugin
{
private $securityContext;
protected $parserContext;
protected $request;
public function __construct(SecurityContext $securityContext, ParserContext $parserContext)
public function __construct(Request $request, SecurityContext $securityContext, ParserContext $parserContext)
{
$this->securityContext = $securityContext;
$this->parserContext = $parserContext;
$this->request = $request;
}
/**
@@ -52,7 +65,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*/
public function adminDataAccess($params, &$smarty)
{
return $this->userDataAccess("Admin User", $this->securityContext->getAdminUser(), $params);
return $this->dataAccess("Admin User", $params, $this->securityContext->getAdminUser());
}
/**
@@ -64,37 +77,146 @@ class DataAccessFunctions extends AbstractSmartyPlugin
*/
public function customerDataAccess($params, &$smarty)
{
return $this->userDataAccess("Customer User", $this->securityContext->getCustomerUser(), $params);
return $this->dataAccess("Customer User", $params, $this->securityContext->getCustomerUser());
}
public function productDataAccess($params, &$smarty)
{
$productId = $this->request->get('product_id');
if($productId !== null) {
$search = ProductQuery::create()
->filterById($productId);
return $this->dataAccessWithI18n("Product", $params, $search);
}
}
public function categoryDataAccess($params, &$smarty)
{
$categoryId = $this->request->get('category_id');
if($categoryId !== null) {
$search = CategoryQuery::create()
->filterById($categoryId);
return $this->dataAccessWithI18n("Category", $params, $search);
}
}
public function contentDataAccess($params, &$smarty)
{
$contentId = $this->request->get('content_id');
if($contentId !== null) {
$search = ContentQuery::create()
->filterById($contentId);
return $this->dataAccessWithI18n("Content", $params, $search);
}
}
public function folderDataAccess($params, &$smarty)
{
$folderId = $this->request->get('folder_id');
if($folderId !== null) {
$search = FolderQuery::create()
->filterById($folderId);
return $this->dataAccessWithI18n("Folder", $params, $search);
}
}
/**
* @param $objectLabel
* @param $user
* @param $params
* @param $objectLabel
* @param $params
* @param ModelCriteria $search
* @param array $columns
* @param null $foreignTable
* @param string $foreignKey
*
* @return string
*/
protected function dataAccessWithI18n($objectLabel, $params, ModelCriteria $search, $columns = array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM'), $foreignTable = null, $foreignKey = 'ID')
{
$lang = $this->getNormalizedParam($params, array('lang'));
if($lang === null) {
$lang = $this->request->getSession()->getLang()->getId();
}
ModelCriteriaTools::getI18n(
false,
$lang,
$search,
$this->request->getSession()->getLang()->getLocale(),
$columns,
$foreignTable,
$foreignKey,
true
);
$data = $search->findOne();
$noGetterData = array();
foreach($columns as $column) {
$noGetterData[$column] = $data->getVirtualColumn('i18n_' . $column);
}
return $this->dataAccess($objectLabel, $params, $data, $noGetterData);
}
/**
* @param $objectLabel
* @param $params
* @param $data
* @param array $noGetterData
*
* @return string
* @throws \InvalidArgumentException
*/
protected function userDataAccess($objectLabel, $user, $params)
{
$attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr'));
protected function dataAccess($objectLabel, $params, $data, $noGetterData = array())
{
$attribute = $this->getNormalizedParam($params, array('attribute', 'attrib', 'attr'));
if (! empty($attribute)) {
if (! empty($attribute)) {
if (null != $user) {
$getter = sprintf("get%s", ucfirst($attribute));
if (null != $data) {
if (method_exists($user, $getter)) {
return $user->$getter();
}
$keyAttribute = strtoupper($attribute);
if(array_key_exists($keyAttribute, $noGetterData)) {
return $noGetterData[$keyAttribute];
}
throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", $objectLabel, $attribute));
$getter = sprintf("get%s", ucfirst($attribute));
if (method_exists($data, $getter)) {
$return = $data->$getter();
}
}
if($return instanceof \DateTime) {
if (array_key_exists("format", $params)) {
$format = $params["format"];
} else {
$format = DateTimeFormat::getInstance($this->request)->getFormat(array_key_exists("output", $params) ? $params["output"] : null);
}
$return = $return->format($format);
}
return $return;
}
throw new \InvalidArgumentException(sprintf("%s has no '%s' attribute", $objectLabel, $attribute));
}
}
return '';
}
return '';
}
/**
* Define the various smarty plugins hendled by this class
*
@@ -104,7 +226,11 @@ class DataAccessFunctions extends AbstractSmartyPlugin
{
return array(
new SmartyPluginDescriptor('function', 'admin', $this, 'adminDataAccess'),
new SmartyPluginDescriptor('function', 'customer', $this, 'customerDataAccess')
new SmartyPluginDescriptor('function', 'customer', $this, 'customerDataAccess'),
new SmartyPluginDescriptor('function', 'product', $this, 'productDataAccess'),
new SmartyPluginDescriptor('function', 'category', $this, 'categoryDataAccess'),
new SmartyPluginDescriptor('function', 'content', $this, 'contentDataAccess'),
new SmartyPluginDescriptor('function', 'folder', $this, 'folderDataAccess'),
);
}
}

View File

@@ -27,6 +27,7 @@ use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Core\Template\Smarty\Exception\SmartyPluginException;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Tools\DateTimeFormat;
/**
*
@@ -79,29 +80,10 @@ class Format extends AbstractSmartyPlugin
return "";
}
$format = null;
$output = array_key_exists("output", $params) ? $params["output"] : null;
if (array_key_exists("format", $params)) {
$format = $params["format"];
} else {
$session = $this->request->getSession();
$lang = $session->getLang();
if($lang) {
switch ($output) {
case "date" :
$format = $lang->getDateFormat();
break;
case "time" :
$format = $lang->getTimeFormat();
break;
default:
case "datetime" :
$format = $lang->getDateTimeFormat();
break;
}
}
$format = DateTimeFormat::getInstance($this->request)->getFormat(array_key_exists("output", $params) ? $params["output"] : null);
}
return $date->format($format);

View File

@@ -43,12 +43,31 @@ abstract class BaseDescForm extends BaseForm
->add("title", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => "Title",
"label_attr" => array(
"for" => "title"
)
)
)
->add("chapo", "text", array())
->add("description", "text", array())
->add("postscriptum", "text", array())
->add("chapo", "text", array(
"label" => "Summary",
"label_attr" => array(
"for" => "summary"
)
))
->add("description", "text", array(
"label" => "Detailed description",
"label_attr" => array(
"for" => "detailed_description"
)
))
->add("postscriptum", "text", array(
"label" => "Conclusion",
"label_attr" => array(
"for" => "conclusion"
)
))
;
}
}

View File

@@ -32,6 +32,10 @@ class CategoryCreationForm extends BaseForm
->add("title", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => "Category title *",
"label_attr" => array(
"for" => "title"
)
))
->add("parent", "integer", array(

View File

@@ -40,11 +40,19 @@ class ConfigCreationForm extends BaseForm
$this->formBuilder
->add("name", "text", array(
"constraints" => $name_constraints
"constraints" => $name_constraints,
"label" => "Name *",
"label_attr" => array(
"for" => "name"
)
))
->add("title", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => "Purpose *",
"label_attr" => array(
"for" => "purpose"
)
))
->add("locale", "hidden", array(
@@ -52,9 +60,16 @@ class ConfigCreationForm extends BaseForm
new Constraints\NotBlank()
)
))
->add("value", "text", array())
->add("value", "text", array(
"label" => "Value *",
"label_attr" => array(
"for" => "value"
)
))
->add("hidden", "hidden", array())
->add("secured", "hidden", array())
->add("secured", "hidden", array(
"label" => "Prevent variable modification or deletion, except for super-admin"
))
;
}

View File

@@ -44,11 +44,22 @@ class ConfigModificationForm extends BaseDescForm
->add("name", "text", array(
"constraints" => array(
new NotBlank()
),
"label" => "Name",
"label_attr" => array(
"for" => "name"
)
))
->add("value", "text", array(
"label" => "Value",
"label_attr" => array(
"for" => "value"
)
))
->add("value", "text", array())
->add("hidden", "hidden", array())
->add("secured", "hidden", array())
->add("secured", "hidden", array(
"label" => "Prevent variable modification or deletion, except for super-admin"
))
;
}

View File

@@ -40,11 +40,19 @@ class MessageCreationForm extends BaseForm
$this->formBuilder
->add("name", "text", array(
"constraints" => $name_constraints
"constraints" => $name_constraints,
"label" => "Name *",
"label_attr" => array(
"for" => "name"
)
))
->add("title", "text", array(
"constraints" => array(
new Constraints\NotBlank()
),
"label" => "Purpose *",
"label_attr" => array(
"for" => "purpose"
)
))
->add("locale", "hidden", array(

View File

@@ -33,13 +33,43 @@ class MessageModificationForm extends BaseForm
{
$this->formBuilder
->add("id" , "hidden", array("constraints" => array(new GreaterThan(array('value' => 0)))))
->add("name" , "text" , array("constraints" => array(new NotBlank())))
->add("secured" , "text" , array())
->add("name" , "text" , array(
"constraints" => array(new NotBlank()),
"label" => "Name *",
"label_attr" => array(
"for" => "name"
)
))
->add("secured" , "text" , array(
"label" => "Prevent mailing template modification or deletion, except for super-admin"
))
->add("locale" , "text" , array())
->add("title" , "text" , array("constraints" => array(new NotBlank())))
->add("subject" , "text" , array("constraints" => array(new NotBlank())))
->add("html_message" , "text" , array())
->add("text_message" , "text" , array())
->add("title" , "text" , array(
"constraints" => array(new NotBlank()),
"label" => "Title *",
"label_attr" => array(
"for" => "title"
)
))
->add("subject" , "text" , array(
"constraints" => array(new NotBlank()),
"label" => "Message subject *",
"label_attr" => array(
"for" => "subject"
)
))
->add("html_message" , "text" , array(
"label" => "HTML Message",
"label_attr" => array(
"for" => "html_message"
)
))
->add("text_message" , "text" , array(
"label" => "Text Message",
"label_attr" => array(
"for" => "text_message"
)
))
;
}

View File

@@ -113,7 +113,7 @@ class ModelCriteriaTools
$localeSearch = LangQuery::create()->findOneById($requestedLangId);
if ($localeSearch === null) {
throw new \InvalidArgumentException(sprintf('Incorrect lang argument given in attribute loop: lang ID %d not found', $requestedLangId));
throw new \InvalidArgumentException(sprintf('Incorrect lang argument given : lang ID %d not found', $requestedLangId));
}
$locale = $localeSearch->getLocale();

View File

@@ -0,0 +1,66 @@
<?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\Tools;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerInterface;
class DateTimeFormat
{
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
}
public static function getInstance(Request $request)
{
return new DateTimeFormat($request);
}
public function getFormat($output = null)
{
$lang = $this->request->getSession()->getLang();
$format = null;
if($lang) {
switch ($output) {
case "date" :
$format = $lang->getDateFormat();
break;
case "time" :
$format = $lang->getTimeFormat();
break;
default:
case "datetime" :
$format = $lang->getDateTimeFormat();
break;
}
}
return $format;
}
}