Merge branch 'cleanmaster' into modules

This commit is contained in:
Etienne Roudeix
2013-12-10 15:57:37 +01:00
31 changed files with 1238 additions and 350 deletions

View File

@@ -58,6 +58,11 @@ $ php Thelia thelia:install
You just have to follow all instructions.
Contribute
----------
see the documentation : http://doc.thelia.net/en/documentation/contribute.html
Usage
-----

View File

@@ -25,6 +25,8 @@ namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Exception\UrlRewritingException;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\CategoryQuery;
use Thelia\Model\Category as CategoryModel;
@@ -90,6 +92,13 @@ class Category extends BaseAction implements EventSubscriberInterface
->save();
// Update the rewritten URL, if required
try {
$category->setRewrittenUrl($event->getLocale(), $event->getUrl());
} catch(UrlRewritingException $e) {
throw new FormValidationException($e->getMessage(), $e->getCode());
}
$event->setCategory($category);
}
}

View File

@@ -32,6 +32,8 @@ use Thelia\Core\Event\Content\ContentToggleVisibilityEvent;
use Thelia\Core\Event\Content\ContentUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Exception\UrlRewritingException;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\ContentFolder;
use Thelia\Model\ContentFolderQuery;
use Thelia\Model\ContentQuery;
@@ -79,6 +81,13 @@ class Content extends BaseAction implements EventSubscriberInterface
->save()
;
// Update the rewritten URL, if required
try {
$content->setRewrittenUrl($event->getLocale(), $event->getUrl());
} catch(UrlRewritingException $e) {
throw new FormValidationException($e->getMessage(), $e->getCode());
}
$content->updateDefaultFolder($event->getDefaultFolder());
$event->setContent($content);

View File

@@ -29,6 +29,8 @@ use Thelia\Core\Event\Folder\FolderToggleVisibilityEvent;
use Thelia\Core\Event\Folder\FolderUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Exception\UrlRewritingException;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\FolderQuery;
use Thelia\Model\Folder as FolderModel;
@@ -56,6 +58,13 @@ class Folder extends BaseAction implements EventSubscriberInterface
->save();
;
// Update the rewritten URL, if required
try {
$folder->setRewrittenUrl($event->getLocale(), $event->getUrl());
} catch(UrlRewritingException $e) {
throw new FormValidationException($e->getMessage(), $e->getCode());
}
$event->setFolder($folder);
}
}

View File

@@ -25,6 +25,8 @@ namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Exception\UrlRewritingException;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\ProductQuery;
use Thelia\Model\Product as ProductModel;
@@ -114,7 +116,11 @@ class Product extends BaseAction implements EventSubscriberInterface
;
// Update the rewritten URL, if required
$product->setRewrittenUrl($event->getLocale(), $event->getUrl());
try {
$product->setRewrittenUrl($event->getLocale(), $event->getUrl());
} catch(UrlRewritingException $e) {
throw new FormValidationException($e->getMessage(), $e->getCode());
}
// Update default category (ifd required)
$product->updateDefaultCategory($event->getDefaultCategory());

View File

@@ -58,7 +58,9 @@
<argument type="service" id="thelia.translator" />
</service>
<service id="smarty.plugin.module" class="Thelia\Core\Template\Smarty\Plugins\Module" >
<service id="smarty.plugin.module" class="Thelia\Core\Template\Smarty\Plugins\Module" scope="request">
<argument>%kernel.debug%</argument>
<argument type="service" id="request"/>
<tag name="thelia.parser.register_plugin"/>
</service>

View File

@@ -107,7 +107,7 @@ final class TheliaEvents
/**
* sent just before customer removal
*/
const BEFORE_DELETECUSTOMER = "action.before_updateCustomer";
const BEFORE_DELETECUSTOMER = "action.before_deleteCustomer";
/**
* sent just after customer removal
@@ -121,7 +121,7 @@ final class TheliaEvents
const ADDRESS_CREATE = "action.createAddress";
/**
* sent for address creation
* sent for address modification
*/
const ADDRESS_UPDATE = "action.updateAddress";
@@ -135,7 +135,14 @@ final class TheliaEvents
*/
const ADDRESS_DEFAULT = "action.defaultAddress";
/**
* sent once the address creation form has been successfully validated, and before address insertion in the database.
*/
const BEFORE_CREATEADDRESS = "action.before_createAddress";
/**
* Sent just after a successful insert of a new address in the database.
*/
const AFTER_CREATEADDRESS = "action.after_createAddress";
const BEFORE_UPDATEADDRESS = "action.before_updateAddress";

View File

@@ -23,12 +23,28 @@
namespace Thelia\Core\Template\Smarty\Plugins;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
use Thelia\Core\Template\Smarty\AbstractSmartyPlugin;
use Thelia\Model\ModuleQuery;
class Module extends AbstractSmartyPlugin
{
/**
* @var bool application debug mode
*/
protected $debug;
/**
* @var Request $request
*/
protected $request;
public function __construct($debug, Request $request)
{
$this->debug = $debug;
$this->request = $request;
}
/**
* Process theliaModule template inclusion function
*
@@ -44,6 +60,10 @@ class Module extends AbstractSmartyPlugin
if (false !== $location = $this->getParam($params, 'location', false)) {
if($this->debug === true && $this->request->get('SHOW_INCLUDE')) {
echo sprintf('<div style="background-color: #C82D26; border-color: #000000; border: solid;">%s</div>', $location);
}
$moduleLimit = $this->getParam($params, 'module', null);
$modules = ModuleQuery::getActivated();

View File

@@ -240,20 +240,18 @@ class TemplateHelper
fwrite($fp, '<' . "?php\n\n");
fwrite($fp, "return array(\n");
$idx = 0;
// Sort keys alphabetically while keeping index
asort($texts);
foreach($texts as $text)
{
foreach ($texts as $key => $text) {
// Write only defined (not empty) translations
if (! empty($translations[$idx])) {
if (! empty($translations[$key])) {
$text = str_replace("'", "\'", $text);
$translation = str_replace("'", "\'", $translations[$idx]);
$translation = str_replace("'", "\'", $translations[$key]);
fwrite($fp, sprintf("\t'%s' => '%s',\n", $text, $translation));
fwrite($fp, sprintf(" '%s' => '%s',\n", $text, $translation));
}
$idx++;
}
fwrite($fp, ");\n");

View File

@@ -27,6 +27,8 @@ class UrlRewritingException extends \Exception
{
const UNKNOWN_EXCEPTION = 0;
const URL_ALREADY_EXISTS = 100;
const URL_NOT_FOUND = 404;
const RESOLVER_NULL_SEARCH = 800;

View File

@@ -26,8 +26,10 @@ namespace Thelia\Model\Tools;
use Thelia\Core\Event\GenerateRewrittenUrlEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Exception\UrlRewritingException;
use Thelia\Model\RewritingArgumentQuery;
use Thelia\Model\RewritingUrlQuery;
use Thelia\Model\RewritingUrl;
use Thelia\Rewriting\RewritingResolver;
use Thelia\Tools\URL;
use Thelia\Model\ConfigQuery;
/**
@@ -153,12 +155,78 @@ trait UrlRewritingTrait {
* Set the rewritten URL for the given locale
*
* @param string $locale a valid locale (e.g. en_US)
* @param $url the wanted url
* @param $url
* @return $this
* @throws UrlRewritingException
* @throws \Thelia\Exception\UrlRewritingException
*/
public function setRewrittenUrl($locale, $url)
{
// TODO - code me !
$currentUrl = $this->getRewrittenUrl($locale);
if($currentUrl == $url) {
/* no url update */
return $this;
}
try {
$resolver = new RewritingResolver($url);
/* we can reassign old url */
if(null === $resolver->redirectedToUrl) {
/* else ... */
if($resolver->view == $this->getRewrittenUrlViewName() && $resolver->viewId == $this->getId()) {
/* it's an url related to the current object */
if($resolver->locale != $locale) {
/* it is an url related to this product for another locale */
throw new UrlRewritingException('URL_ALREADY_EXISTS', UrlRewritingException::URL_ALREADY_EXISTS);
}
if (count($resolver->otherParameters) > 0) {
/* it is an url related to this product but with more arguments */
throw new UrlRewritingException('URL_ALREADY_EXISTS', UrlRewritingException::URL_ALREADY_EXISTS);
}
/* here it must be a deprecated url */
} else {
/* already related to another object */
throw new UrlRewritingException('URL_ALREADY_EXISTS', UrlRewritingException::URL_ALREADY_EXISTS);
}
}
} catch(UrlRewritingException $e) {
/* It's all good if URL is not found */
if($e->getCode() !== UrlRewritingException::URL_NOT_FOUND) {
throw $e;
}
}
/* set the new URL */
if(isset($resolver)) {
/* erase the old one */
$rewritingUrl = RewritingUrlQuery::create()->findOneByUrl($url);
$rewritingUrl->setView($this->getRewrittenUrlViewName())
->setViewId($this->getId())
->setViewLocale($locale)
->setRedirected(null)
->save()
;
/* erase additional arguments if any : only happens in case it erases a deprecated url */
RewritingArgumentQuery::create()->filterByRewritingUrl($rewritingUrl)->deleteAll();
} else {
/* just create it */
$rewritingUrl = new RewritingUrl();
$rewritingUrl->setUrl($url)
->setView($this->getRewrittenUrlViewName())
->setViewId($this->getId())
->setViewLocale($locale)
->save()
;
}
/* deprecate the old one if needed */
$oldRewritingUrl = RewritingUrlQuery::create()->findOneByUrl($currentUrl);
$oldRewritingUrl->setRedirected($rewritingUrl->getId())->save();
return $this;
}

View File

@@ -71,7 +71,9 @@ class RewritingRetriever
$this->rewrittenUrl = null;
$this->url = URL::getInstance()->viewUrl($view, $allParametersWithoutView);
if($this->search !== null) {
$this->rewrittenUrl = $this->search->getUrl();
$this->rewrittenUrl = URL::getInstance()->absoluteUrl(
$this->search->getUrl()
);
}
}

View File

@@ -35,14 +35,45 @@ use Thelia\Model\ContentFolder;
use Thelia\Model\ContentFolderQuery;
use Thelia\Model\ContentQuery;
use Thelia\Model\FolderQuery;
use Thelia\Tests\TestCaseWithURLToolSetup;
/**
* Class ContentTest
* @package Thelia\Tests\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ContentTest extends BaseAction
class ContentTest extends TestCaseWithURLToolSetup
{
use RewrittenUrlTestTrait;
public function getUpdateEvent(&$content)
{
if(!$content instanceof \Thelia\Model\Content) {
$content = $this->getRandomContent();
}
$event = new ContentUpdateEvent($content->getId());
$event
->setVisible(1)
->setLocale($content->getLocale())
->setTitle($content->getTitle())
->setChapo($content->getChapo())
->setDescription($content->getDescription())
->setPostscriptum($content->getPostscriptum())
->setDefaultFolder($content->getDefaultFolderId())
;
return $event;
}
public function processUpdateAction($event)
{
$contentAction = new Content($this->getContainer());
$contentAction->update($event);
return $event->getContent();
}
public function testCreateContent()
{
$folder = $this->getRandomFolder();
@@ -80,6 +111,7 @@ class ContentTest extends BaseAction
->setChapo('test update content short description')
->setDescription('test update content description')
->setPostscriptum('test update content postscriptum')
->setUrl($content->getRewrittenUrl('en_US'))
->setDefaultFolder($folder->getId())
;

View File

@@ -30,14 +30,45 @@ use Thelia\Core\Event\Folder\FolderToggleVisibilityEvent;
use Thelia\Core\Event\Folder\FolderUpdateEvent;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Model\FolderQuery;
use Thelia\Tests\TestCaseWithURLToolSetup;
/**
* Class FolderTest
* @package Thelia\Tests\Action\ImageTest
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class FolderTest extends BaseAction
class FolderTest extends TestCaseWithURLToolSetup
{
use RewrittenUrlTestTrait;
public function getUpdateEvent(&$folder)
{
if(!$folder instanceof \Thelia\Model\Folder) {
$folder = $this->getRandomFolder();
}
$event = new FolderUpdateEvent($folder->getId());
$event
->setVisible(1)
->setLocale($folder->getLocale())
->setTitle($folder->getTitle())
->setChapo($folder->getChapo())
->setDescription($folder->getDescription())
->setPostscriptum($folder->getPostscriptum())
->setParent($folder->getParent())
;
return $event;
}
public function processUpdateAction($event)
{
$contentAction = new Folder($this->getContainer());
$contentAction->update($event);
return $event->getFolder();
}
/**
* test folder creation
* @covers Thelia\Action\Folder::create
@@ -82,6 +113,7 @@ class FolderTest extends BaseAction
->setChapo('test folder update chapo')
->setDescription('update folder description')
->setPostscriptum('update folder postscriptum')
->setUrl($folder->getRewrittenUrl('en_US'))
->setParent(0)
;

View File

@@ -0,0 +1,86 @@
<?php
namespace Thelia\Tests\Action;
use Propel\Runtime\ActiveQuery\Criteria;
use Thelia\Exception\UrlRewritingException;
use Thelia\Model\Base\RewritingUrlQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Rewriting\RewritingResolver;
use Thelia\Tools\URL;
/**
* Class RewrittenUrlTestTrait
* @package Thelia\Tests\Action
* @author Etienne Roudeix <eroudeix@openstudio.fr>
*/
trait RewrittenUrlTestTrait
{
abstract public function getUpdateEvent(&$object);
abstract public function processUpdateAction($event);
/**
* @expectedException \Thelia\Form\Exception\FormValidationException
* @expectedExceptionCode 100
*/
public function testUpdateExistingUrl()
{
$object = null;
$event = $this->getUpdateEvent($object);
/* get an existing url */
$existingUrl = RewritingUrlQuery::create()
->filterByViewId($object->getId(), Criteria::NOT_EQUAL)
->filterByRedirected(null)
->filterByView(ConfigQuery::getObsoleteRewrittenUrlView(), Criteria::NOT_EQUAL)
->findOne();
if(null === $existingUrl) {
$this->fail('use fixtures before launching test, there is not enough rewritten url');
}
$event->setUrl($existingUrl->getUrl());
$this->processUpdateAction($event);
}
public function testUpdateUrl()
{
$object = null;
$event = $this->getUpdateEvent($object);
$currentUrl = $object->getRewrittenUrl($object->getLocale());
/* get a brand new URL */
$exist = true;
while(true === $exist) {
$newUrl = md5(rand(1, 999999)) . ".html";
try {
new RewritingResolver($newUrl);
} catch(UrlRewritingException $e) {
if($e->getCode() === UrlRewritingException::URL_NOT_FOUND) {
/* It's all good if URL is not found */
$exist = false;
} else {
throw $e;
}
}
}
$event->setUrl($newUrl);
$updatedObject = $this->processUpdateAction($event);
/* new URL is updated */
$this->assertEquals($newUrl, $updatedObject->getRewrittenUrl($object->getLocale()));
/* old url must be redirected to the new one */
$newUrlEntry = RewritingUrlQuery::create()->findOneByUrl($newUrl);
$oldUrlEntry = RewritingUrlQuery::create()->findOneByUrl($currentUrl);
$this->assertEquals($oldUrlEntry->getRedirected(), $newUrlEntry->getId());
/* we can reassign old Url to another object */
//@todo
}
}

View File

@@ -101,7 +101,7 @@ class RewritingRetrieverTest extends \PHPUnit_Framework_TestCase
$retriever->loadViewUrl('view', 'fr_FR', 1);
$this->assertEquals('foo.html', $retriever->rewrittenUrl);
$this->assertEquals(URL::getInstance()->absoluteUrl('foo.html'), $retriever->rewrittenUrl);
$this->assertEquals(URL::getInstance()->viewUrl('view', array('locale' => 'fr_FR', 'view_id' => 1)), $retriever->url);
}

View File

@@ -30,15 +30,21 @@ namespace Thelia\Tests;
*/
class TestCaseWithURLToolSetup extends \PHPUnit_Framework_TestCase
{
private $container = null;
public function __construct()
{
$this->container = new \Symfony\Component\DependencyInjection\ContainerBuilder();
$dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface");
$this->container->set("event_dispatcher", $dispatcher);
$this->setupURLTool();
}
protected function setupURLTool()
{
$container = new \Symfony\Component\DependencyInjection\ContainerBuilder();
$context = new \Symfony\Component\Routing\RequestContext(
'/thelia/index.php',
'GET',
@@ -57,8 +63,13 @@ class TestCaseWithURLToolSetup extends \PHPUnit_Framework_TestCase
->method('getContext')
->will($this->returnValue($context));
$container->set("router.admin", $router);
$this->container->set("router.admin", $router);
new \Thelia\Tools\URL($container);
new \Thelia\Tools\URL($this->container);
}
public function getContainer()
{
return $this->container;
}
}

View File

@@ -199,7 +199,7 @@ class URL
public function retrieve($view, $viewId, $viewLocale)
{
if (ConfigQuery::isRewritingEnable()) {
URL::getInstance()->absoluteUrl($this->retriever->loadViewUrl($view, $viewLocale, $viewId));
$this->retriever->loadViewUrl($view, $viewLocale, $viewId);
} else {
$allParametersWithoutView = array();
$allParametersWithoutView['locale'] = $viewLocale;

File diff suppressed because it is too large Load Diff

View File

@@ -161,16 +161,6 @@
width: 100%;
}
.btn-group {
white-space: nowrap; // prevent buttons from wrapping when in tight spaces (e.g., the table on the tests page)
> .btn {
float: inherit;
}
> .btn + .btn {
margin-left: -4px;
}
}
// -- Login form --------------------------------------------------------------
.form-signin {
@@ -423,4 +413,19 @@
.dropzone {
border: 1px dashed #ddd;
padding: 20px;
}
// No button wrap in button groups in td.action cells
table {
td.actions {
.btn-group {
white-space: nowrap; // prevent buttons from wrapping when in tight spaces (e.g., the table on the tests page)
> .btn {
float: inherit;
}
> .btn + .btn {
margin-left: -4px;
}
}
}
}

View File

@@ -155,6 +155,7 @@
</div>
<div class="tab-pane fade" id="modules">
{module_include location='content-edit'}
</div>
</div>
</div>

View File

@@ -27,7 +27,7 @@
{if !$IS_ENABLED}
<div class="alert alert-info">
<span class="glyphicon glyphicon-question-sign"></span>
{intl l='This coupon is disabled, you can enable to the bottom of this form.'}
{intl l='This coupon is disabled, you can enable at the bottom of this form.'}
</div>
{/if}

View File

@@ -131,7 +131,7 @@
<div class="control-group">
<lablel>&nbsp;</lablel>
<div class="controls">
<p>{intl l='Colder created on %date_create. Last modification: %date_change' date_create="{format_date date=$CREATE_DATE}" date_change="{format_date date=$UPDATE_DATE}"}</p>
<p>{intl l='Folder created on %date_create. Last modification: %date_change' date_create="{format_date date=$CREATE_DATE}" date_change="{format_date date=$UPDATE_DATE}"}</p>
</div>
</div>
</div>
@@ -255,6 +255,7 @@
</div>
<div class="tab-pane fade" id="modules">
{module_include location='folder-edit'}
</div>
</div>
</div>

View File

@@ -46,7 +46,7 @@
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
<p class="title title-without-tabs">{intl l="Image informations"}</p>
<p class="title title-without-tabs">{intl l="Image information"}</p>
<div class="row">
<div class="col-md-6">

View File

@@ -7,7 +7,7 @@
<form method="POST" action="{url path='/admin/content/folder/add'}" id="related_content_form">
<p class="title title-without-tabs">{intl l='Additional Folders'}</p>
<p>{intl l='A content could be attached to more than one folder. Select here the additional fodlers for this content.'}
<p>{intl l='A content could be attached to more than one folder. Select here the additional folders for this content.'}
{loop name="default_folder" type="folder" id=$DEFAULT_FOLDER}
{intl l='You can change the default folder (%title) in the "General" tab.' title=$TITLE}
{/loop}

View File

@@ -25,7 +25,7 @@
<div class="alert alert-info">
<p>{intl l="In order to manges your shop taxes you can manage"} <strong>{intl l="taxes"}</strong> {intl l="and"} <strong>{intl l="tax rules"}</strong>.</p>
<p>{intl l="Taxes define the amount of money which is add to a bought product."}</p>
<p>{intl l="Taxes define the amount of money which is added to a bought product."}</p>
<p>
{intl l="Example :"}
<ul>

0
templates/email/default/I18n/en_US.php Normal file → Executable file
View File

0
templates/email/default/I18n/es_ES.php Normal file → Executable file
View File

0
templates/email/default/I18n/fr_FR.php Normal file → Executable file
View File

0
templates/email/default/I18n/it_IT.php Normal file → Executable file
View File

View File

@@ -197,18 +197,20 @@
{strip}
{capture "additional"}
{ifloop rel="feature_info"}
{ifloop rel="feature_value_info"}
<ul>
{loop name="feature_info" type="feature" product="{$ID}"}
{ifloop rel="feature_value_info"}
<li>
<strong>{$TITLE}</strong> :
{loop name="feature_value_info" type="feature_value" feature="{$ID}" product="{product attr="id"}"}
{$TITLE}
{/loop}
</li>
{/ifloop}
{/loop}
</ul>
{/ifloop}
{/ifloop}
{/capture}
{/strip}
@@ -221,7 +223,7 @@
</ul>
<div class="tab-content">
<div class="tab-pane active in" id="description" itemprop="description" role="tabpanel" aria-labelledby="tab1">
<p>{$DESCRIPTION|default:'N/A'}</p>
<p>{$DESCRIPTION|default:'N/A' nofilter}</p>
</div>
{if $smarty.capture.additional ne ""}
<div class="tab-pane" id="additional" role="tabpanel" aria-labelledby="tab2">