Merge branch 'master' into tax

Conflicts:
	core/lib/Thelia/Config/Resources/action.xml
	core/lib/Thelia/Controller/Admin/AddressController.php
	core/lib/Thelia/Controller/Admin/CustomerController.php
	core/lib/Thelia/Controller/Admin/ModuleController.php
This commit is contained in:
Etienne Roudeix
2013-10-21 17:48:13 +02:00
100 changed files with 1333 additions and 491 deletions

View File

@@ -39,7 +39,8 @@
"symfony/icu": "1.0",
"swiftmailer/swiftmailer": "5.0.*",
"symfony/serializer": "2.3.*",
"ensepar/html2pdf": "1.0.1"
"ensepar/html2pdf": "1.0.1",
"symfony/finder": "~2.2"
},
"require-dev" : {
"phpunit/phpunit": "3.7.*",

4
composer.lock generated
View File

@@ -3,7 +3,7 @@
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
],
"hash": "852879ecc2e39e5cf283a3b1c5051a8e",
"hash": "4f3fabbb795a71df45ae9f6ccb6df355",
"packages": [
{
"name": "ensepar/html2pdf",
@@ -949,7 +949,7 @@
},
{
"name": "symfony/finder",
"version": "v2.3.5",
"version": "v2.3.6",
"target-dir": "Symfony/Component/Finder",
"source": {
"type": "git",

View File

@@ -34,7 +34,6 @@ use Thelia\Model\CountryQuery;
use Thelia\Action\BaseAction;
use Thelia\Model\Area as AreaModel;
/**
* Class Area
* @package Thelia\Action
@@ -97,7 +96,6 @@ class Area extends BaseAction implements EventSubscriberInterface
$event->setArea($area);
}
/**
* Returns an array of event names this subscriber wants to listen to.
*

View File

@@ -0,0 +1,75 @@
<?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\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Thelia\Core\Event\Cache\CacheEvent;
use Thelia\Core\Event\TheliaEvents;
/**
* Class Cache
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Cache extends BaseAction implements EventSubscriberInterface
{
public function cacheClear(CacheEvent $event)
{
$dir = $event->getDir();
$directoryBrowser = new \DirectoryIterator($dir);
$fs = new Filesystem();
$fs->remove($dir);
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::CACHE_CLEAR => array('cacheClear', 128)
);
}
}

View File

@@ -160,7 +160,7 @@ class Content extends BaseAction implements EventSubscriberInterface
->filterByFolderId($event->getFolderId())
->findOne();
if(null !== $contentFolder) {
if (null !== $contentFolder) {
$contentFolder->delete();
}
}

View File

@@ -32,7 +32,6 @@ use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Country as CountryModel;
use Thelia\Model\CountryQuery;
/**
* Class Country
* @package Thelia\Action
@@ -85,15 +84,13 @@ class Country extends BaseAction implements EventSubscriberInterface
public function toggleDefault(CountryToggleDefaultEvent $event)
{
if( null !== $country = CountryQuery::create()->findPk($event->getCountryId()))
{
if ( null !== $country = CountryQuery::create()->findPk($event->getCountryId())) {
$country->toggleDefault();
$event->setCountry($country);
}
}
/**
* Returns an array of event names this subscriber wants to listen to.
*

View File

@@ -25,7 +25,6 @@ namespace Thelia\Action;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\ActionEvent;
use Thelia\Core\Event\Customer\CustomerAddressEvent;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\TheliaEvents;

View File

@@ -0,0 +1,136 @@
<?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\Action;
use Propel\Runtime\Propel;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Filesystem;
use Thelia\Core\Event\Cache\CacheEvent;
use Thelia\Core\Event\Module\ModuleDeleteEvent;
use Thelia\Core\Event\Module\ModuleToggleActivationEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\Map\ModuleTableMap;
use Thelia\Model\ModuleQuery;
use Thelia\Module\BaseModule;
/**
* Class Module
* @package Thelia\Action
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class Module extends BaseAction implements EventSubscriberInterface
{
public function toggleActivation(ModuleToggleActivationEvent $event)
{
if (null !== $module = ModuleQuery::create()->findPk($event->getModuleId())) {
$moduleClass = new \ReflectionClass($module->getFullNamespace());
$moduleInstance = $moduleClass->newInstance();
if ( method_exists($moduleInstance, 'setContainer')) {
$moduleInstance->setContainer($this->container);
if ($module->getActivate() == BaseModule::IS_ACTIVATED) {
$moduleInstance->deActivate($module);
} else {
$moduleInstance->activate($module);
}
}
$event->setModule($module);
$this->cacheClear();
}
}
public function delete(ModuleDeleteEvent $event)
{
if (null !== $module = ModuleQuery::create()->findPk($event->getModuleId())) {
$con = Propel::getWriteConnection(ModuleTableMap::DATABASE_NAME);
$con->beginTransaction();
try {
if(null === $module->getFullNamespace()) {
throw new \LogicException('can not instanciante this module if namespace is null. Maybe the model is not loaded ?');
}
$reflected = new \ReflectionClass($module->getFullNamespace());
$instance = $reflected->newInstance();
$instance->setContainer($this->container);
$path = dirname($reflected->getFileName());
$instance->destroy($con);
$fs = new Filesystem();
$fs->remove($path);
$module->delete($con);
$con->commit();
$event->setModule($module);
$this->cacheClear();
} catch (\Exception $e) {
$con->rollBack();
throw $e;
}
}
}
protected function cacheClear()
{
$cacheEvent = new CacheEvent($this->container->getParameter('kernel.cache_dir'));
$this->getDispatcher()->dispatch(TheliaEvents::CACHE_CLEAR, $cacheEvent);
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * array('eventName' => 'methodName')
* * array('eventName' => array('methodName', $priority))
* * array('eventName' => array(array('methodName1', $priority), array('methodName2'))
*
* @return array The event names to listen to
*
* @api
*/
public static function getSubscribedEvents()
{
return array(
TheliaEvents::MODULE_TOGGLE_ACTIVATION => array('toggleActivation', 128),
TheliaEvents::MODULE_DELETE => array('delete', 128)
);
}
}

View File

@@ -26,7 +26,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Thelia\Core\Event\PdfEvent;
use Thelia\Core\Event\TheliaEvents;
/**
* Class Pdf
* @package Thelia\Action

View File

@@ -29,7 +29,6 @@ use Thelia\Core\Event\TheliaEvents;
use Thelia\Model\AreaDeliveryModule;
use Thelia\Model\AreaDeliveryModuleQuery;
/**
* Class ShippingZone
* @package Thelia\Action
@@ -55,7 +54,7 @@ class ShippingZone extends BaseAction implements EventSubscriberInterface
->filterByDeliveryModuleId($event->getShoppingZoneId())
->findOne();
if($areaDelivery) {
if ($areaDelivery) {
$areaDelivery->delete();
} else {
throw new \RuntimeException(sprintf('areaDeliveryModule not found with area_id = %d and delivery_module_id = %d', $event->getAreaId(), $event->getShoppingZoneId()));

View File

@@ -69,8 +69,6 @@ class TaxRule extends BaseAction implements EventSubscriberInterface
->save()
;
$event->setTaxRule($taxRule);
}
}
@@ -91,12 +89,12 @@ class TaxRule extends BaseAction implements EventSubscriberInterface
->delete();
/* for each country */
foreach($event->getCountryList() as $country) {
foreach ($event->getCountryList() as $country) {
$position = 1;
/* on applique les nouvelles regles */
foreach($taxList as $tax) {
if(is_array($tax)) {
foreach($tax as $samePositionTax) {
foreach ($taxList as $tax) {
if (is_array($tax)) {
foreach ($tax as $samePositionTax) {
$taxModel = new TaxRuleCountry();
$taxModel->setTaxRule($taxRule)
->setCountryId($country)

View File

@@ -30,6 +30,8 @@ use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOException;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Core\Event\Cache\CacheEvent;
use Thelia\Core\Event\TheliaEvents;
/**
* clear the cache
@@ -72,7 +74,11 @@ class CacheClear extends ContainerAwareCommand
$output->writeln(sprintf("Clearing cache in <info>%s</info> directory", $dir));
try {
$directoryBrowser = new \DirectoryIterator($dir);
$cacheEvent = new CacheEvent($dir);
$this->
getContainer()
->get('event_dispatcher')
->dispatch(TheliaEvents::CACHE_CLEAR, $cacheEvent);
} catch (\UnexpectedValueException $e) {
// throws same exception code for does not exist and permission denied ...
if (!file_exists($dir)) {
@@ -82,15 +88,11 @@ class CacheClear extends ContainerAwareCommand
}
throw $e;
}
$fs = new Filesystem();
try {
$fs->remove($dir);
$output->writeln(sprintf("<info>%s cache dir cleared successfully</info>", $dir));
} catch (IOException $e) {
$output->writeln(sprintf("Error during clearing cache : %s", $e->getMessage()));
}
$output->writeln(sprintf("<info>%s cache dir cleared successfully</info>", $dir));
}
}

View File

@@ -143,8 +143,8 @@ class Install extends ContainerAwareCommand
$permissions = new CheckPermission(false, $this->getContainer()->get('thelia.translator'));
$isValid = $permissions->exec();
foreach($permissions->getValidationMessages() as $item => $data) {
if($data['status']) {
foreach ($permissions->getValidationMessages() as $item => $data) {
if ($data['status']) {
$output->writeln(array(
sprintf("<info>%s ...</info> %s",
$data['text'],
@@ -162,7 +162,7 @@ class Install extends ContainerAwareCommand
}
if(false === $isValid) {
if (false === $isValid) {
$output->writeln(array(
"",
"<error>Please put correct permissions and reload install process</error>"

View File

@@ -26,7 +26,6 @@ namespace Thelia\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Thelia\Model\ModuleQuery;

View File

@@ -62,7 +62,7 @@ class ModuleGenerateCommand extends BaseModuleGenerate
$output->renderBlock(array(
'',
sprintf("module %s create with success", $this->module),
"You can now configure your module and complete plugin.xml file",
"You can now configure your module and complete module.xml file",
''
), "bg=green;fg=black");
}
@@ -86,7 +86,7 @@ class ModuleGenerateCommand extends BaseModuleGenerate
$fs = new Filesystem();
$skeletonDir = str_replace("/", DIRECTORY_SEPARATOR, THELIA_ROOT . "/core/lib/Thelia/Command/Skeleton/Module/");
$fs->copy($skeletonDir . "config.xml", $this->moduleDirectory . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "config.xml");
$fs->copy($skeletonDir . "plugin.xml", $this->moduleDirectory . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "plugin.xml");
$fs->copy($skeletonDir . "module.xml", $this->moduleDirectory . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "module.xml");
$classContent = file_get_contents($skeletonDir . "Class.php");

View File

@@ -25,7 +25,7 @@ namespace %%NAMESPACE%%;
use Thelia\Module\BaseModule;
class %%CLASSNAME%% extends BaseModule
class Class extends BaseModule
{
/**
* YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<fullnamespace></fullnamespace>
<descriptive locale="en_US">
<title></title>
</descriptive>
<descriptive locale="fr_FR">
<title></title>
</descriptive>
<version></version>
<author>
<name></name>
<email></email>
</author>
<type></type>
<thelia></thelia>
<stability></stability>
</module>

View File

@@ -141,6 +141,16 @@
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.module" class="Thelia\Action\Module">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.cache" class="Thelia\Action\Cache">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>
</service>
<service id="thelia.action.profile" class="Thelia\Action\Profile">
<argument type="service" id="service_container"/>
<tag name="kernel.event_subscriber"/>

View File

@@ -842,10 +842,19 @@
<!-- Modules rule management -->
<route id="admin.module" path="/admin/modules">
<route id="admin.module" path="/admin/configuration/modules">
<default key="_controller">Thelia\Controller\Admin\ModuleController::indexAction</default>
</route>
<route id="admin.module.toggle-activation" path="/admin/configuration/modules/toggle-activation/{module_id}">
<default key="_controller">Thelia\Controller\Admin\ModuleController::toggleActivationAction</default>
<requirement key="module_id">\d+</requirement>
</route>
<route id="admin.module.delete" path="/admin/configuration/modules/delete">
<default key="_controller">Thelia\Controller\Admin\ModuleController::deleteAction</default>
</route>
<!-- end Modules rule management -->
<!-- tax management -->

View File

@@ -25,14 +25,12 @@ namespace Thelia\Controller\Admin;
use Thelia\Core\Event\Address\AddressCreateOrUpdateEvent;
use Thelia\Core\Event\Address\AddressEvent;
use Thelia\Core\Event\AdminResources;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\AddressCreateForm;
use Thelia\Form\AddressUpdateForm;
use Thelia\Model\AddressQuery;
use Thelia\Model\CustomerQuery;
/**
* Class AddressController
* @package Thelia\Controller\Admin
@@ -79,7 +77,7 @@ class AddressController extends AbstractCrudController
$this->dispatch(TheliaEvents::ADDRESS_DEFAULT, $addressEvent);
$this->adminLogAppend(sprintf("address %d for customer %d removal", $address_id, $address->getCustomerId()));
} catch(\Exception $e) {
} catch (\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during address removal with message %s", $e->getMessage()));
}
@@ -177,8 +175,6 @@ class AddressController extends AbstractCrudController
$formData["is_default"]
);
return $event;
}

View File

@@ -244,7 +244,7 @@ class CountryController extends AbstractCrudController
try {
$this->dispatch(TheliaEvents::COUNTRY_TOGGLE_DEFAULT, $toogleDefaultEvent);
if($toogleDefaultEvent->hasCountry()) {
if ($toogleDefaultEvent->hasCountry()) {
return $this->nullResponse();
}
} catch (\Exception $ex) {

View File

@@ -24,8 +24,6 @@
namespace Thelia\Controller\Admin;
use Propel\Runtime\Exception\PropelException;
use Symfony\Component\Form\Form;
use Thelia\Core\Event\Address\AddressEvent;
use Thelia\Core\Event\AdminResources;
use Thelia\Core\Event\Customer\CustomerAddressEvent;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
@@ -33,7 +31,6 @@ use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\CustomerModification;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Model\AddressQuery;
use Thelia\Model\CustomerQuery;
use Thelia\Core\Translation\Translator;
@@ -58,8 +55,6 @@ class CustomerController extends BaseAdminController
));
}
/**
* update customer action
*

View File

@@ -25,6 +25,11 @@ namespace Thelia\Controller\Admin;
use Thelia\Core\Event\AdminResources;
use Thelia\Core\Event\Module\ModuleDeleteEvent;
use Thelia\Core\Event\Module\ModuleToggleActivationEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Module\ModuleManagement;
/**
* Class ModuleController
* @package Thelia\Controller\Admin
@@ -35,7 +40,11 @@ class ModuleController extends BaseAdminController
public function indexAction()
{
if (null !== $response = $this->checkAuth(AdminResources::MODULE_VIEW)) return $response;
return $this->render("modules", array("display_module" => 20));
$modulemanagement = new ModuleManagement();
$modulemanagement->updateModules();
return $this->render("modules");
}
public function updateAction($module_id)
@@ -44,4 +53,68 @@ class ModuleController extends BaseAdminController
"module_id" => $module_id
));
}
public function toggleActivationAction($module_id)
{
if (null !== $response = $this->checkAuth("admin.module.update")) return $response;
$message = null;
try {
$event = new ModuleToggleActivationEvent($module_id);
$this->dispatch(TheliaEvents::MODULE_TOGGLE_ACTIVATION, $event);
if (null === $event->getModule()) {
throw new \LogicException(
$this->getTranslator()->trans("No %obj was updated.", array('%obj' => 'Module')));
}
} catch (\Exception $e) {
$message = $e->getMessage();
}
if ($this->getRequest()->isXmlHttpRequest()) {
if ($message) {
$response = $this->jsonResponse(json_encode(array(
"error" => $message
)), 500);
} else {
$response = $this->nullResponse();
}
} else {
$this->redirectToRoute('admin.module');
}
return $response;
}
public function deleteAction()
{
if (null !== $response = $this->checkAuth("admin.module.delete")) return $response;
$message = null;
try {
$module_id = $this->getRequest()->get('module_id');
$deleteEvent = new ModuleDeleteEvent($module_id);
$this->dispatch(TheliaEvents::MODULE_DELETE, $deleteEvent);
if($deleteEvent->hasModule() === false) {
throw new \LogicException(
$this->getTranslator()->trans("No %obj was updated.", array('%obj' => 'Module')));
}
} catch (\Exception $e) {
\Thelia\Log\Tlog::getInstance()->error(sprintf("error during module removal : %s", $message));
$message = $e->getMessage();
}
if($message) {
return $this->render("modules", array(
"error_message" => $message
));
} else {
$this->redirectToRoute('admin.module');
}
}
}

View File

@@ -212,7 +212,6 @@ class OrderController extends BaseAdminController
{
if (null !== $response = $this->checkAuth(AdminResources::ORDER_UPDATE)) return $response;
$html = $this->renderRaw(
$fileName,
array(
@@ -228,7 +227,7 @@ class OrderController extends BaseAdminController
$this->dispatch(TheliaEvents::GENERATE_PDF, $pdfEvent);
if($pdfEvent->hasPdf()) {
if ($pdfEvent->hasPdf()) {
return Response::create($pdfEvent->getPdf(), 200,
array(
'Content-type' => "application/pdf",

View File

@@ -141,5 +141,4 @@ class ShippingZoneController extends BaseAdminController
return $this->getRequest()->get('shipping_zone_id', 0);
}
}

View File

@@ -58,7 +58,7 @@ class BaseController extends ContainerAware
/**
* Return an empty response (after an ajax request, for example)
*/
protected function nullResponse($status = 200)
protected function nullResponse($content = null, $status = 200)
{
return new Response(null, $status);
}
@@ -66,9 +66,9 @@ class BaseController extends ContainerAware
/**
* Return a JSON response
*/
protected function jsonResponse($json_data)
protected function jsonResponse($json_data, $status = 200)
{
return new Response($json_data, 200, array('content-type' => 'application/json'));
return new Response($json_data, $status, array('content-type' => 'application/json'));
}
/**

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Area;
/**
* Class AreaAddCountryEvent
* @package Thelia\Core\Event\Area
@@ -34,7 +33,7 @@ class AreaAddCountryEvent extends AreaEvent
protected $area_id;
protected $country_id;
function __construct($area_id, $country_id)
public function __construct($area_id, $country_id)
{
$this->area_id = $area_id;
$this->country_id = $country_id;
@@ -80,7 +79,4 @@ class AreaAddCountryEvent extends AreaEvent
return $this->country_id;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Area;
/**
* Class AreaCreateEvent
* @package Thelia\Core\Event\Area
@@ -49,5 +48,4 @@ class AreaCreateEvent extends AreaEvent
return $this->name;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Area;
/**
* Class AreaDeleteEvent
* @package Thelia\Core\Event\Area
@@ -61,5 +60,4 @@ class AreaDeleteEvent extends AreaEvent
return $this->area_id;
}
}

View File

@@ -24,7 +24,6 @@
namespace Thelia\Core\Event\Area;
use Thelia\Core\Event\ActionEvent;
/**
* Class AreaEvent
* @package Thelia\Core\Event\Shipping

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Area;
/**
* Class AreaRemoveCountryEvent
* @package Thelia\Core\Event\Area

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Area;
/**
* Class AreaUpdateEvent
* @package Thelia\Core\Event\Area

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Area;
/**
* Class AreaUpdatePostageEvent
* @package Thelia\Core\Event\Area
@@ -34,7 +33,7 @@ class AreaUpdatePostageEvent extends AreaEvent
protected $area_id;
protected $postage;
function __construct($area_id)
public function __construct($area_id)
{
$this->area_id = $area_id;
}
@@ -79,7 +78,4 @@ class AreaUpdatePostageEvent extends AreaEvent
return $this->postage;
}
}

View File

@@ -0,0 +1,65 @@
<?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\Cache;
use Thelia\Core\Event\ActionEvent;
/**
* Class CacheEvent
* @package Thelia\Core\Event\Cache
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class CacheEvent extends ActionEvent
{
/**
* @var string cache directory
*/
protected $dir;
public function __construct($dir)
{
$this->dir = $dir;
}
/**
* @param mixed $dir
*
* @return $this
*/
public function setDir($dir)
{
$this->dir = $dir;
return $this;
}
/**
* @return mixed
*/
public function getDir()
{
return $this->dir;
}
}

View File

@@ -24,7 +24,6 @@
namespace Thelia\Core\Event\Content;
use Thelia\Model\Content;
/**
* Class ContentAddFolderEvent
* @package Thelia\Core\Event\Content
@@ -61,6 +60,4 @@ class ContentAddFolderEvent extends ContentEvent
return $this->folderId;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Content;
/**
* Class ContentRemoveFolderEvent
* @package Thelia\Core\Event\Content

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Country;
/**
* Class CountryCreateEvent
* @package Thelia\Core\Event\Country
@@ -150,5 +149,4 @@ class CountryCreateEvent extends CountryEvent
return $this->area;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Country;
/**
* Class CountryDeleteEvent
* @package Thelia\Core\Event\Country
@@ -36,7 +35,7 @@ class CountryDeleteEvent extends CountryEvent
*/
protected $country_id;
function __construct($country_id)
public function __construct($country_id)
{
$this->country_id = $country_id;
}

View File

@@ -25,7 +25,6 @@ namespace Thelia\Core\Event\Country;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Country;
/**
* Class CountryEvent
* @package Thelia\Core\Event\Country
@@ -38,7 +37,7 @@ class CountryEvent extends ActionEvent
*/
protected $country;
function __construct(Country $country = null)
public function __construct(Country $country = null)
{
$this->country = $country;
}
@@ -69,5 +68,4 @@ class CountryEvent extends ActionEvent
return null !== $this->country;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Country;
/**
* Class CountryToggleDefaultEvent
* @package Thelia\Core\Event\Country
@@ -33,7 +32,7 @@ class CountryToggleDefaultEvent extends CountryEvent
{
protected $country_id;
function __construct($country_id)
public function __construct($country_id)
{
$this->country_id = $country_id;
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Country;
/**
* Class CountryUpdateEvent
* @package Thelia\Core\Event\Country
@@ -37,7 +36,7 @@ class CountryUpdateEvent extends CountryCreateEvent
protected $description;
protected $postscriptum;
function __construct($country_id)
public function __construct($country_id)
{
$this->country_id = $country_id;
}
@@ -114,7 +113,4 @@ class CountryUpdateEvent extends CountryCreateEvent
return $this->country_id;
}
}

View File

@@ -0,0 +1,61 @@
<?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\Module;
/**
* Class ModuleDeleteEvent
* @package Thelia\Core\Event\Module
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleDeleteEvent extends ModuleEvent
{
/**
* @var int module id
*/
protected $module_id;
function __construct($module_id)
{
$this->module_id = $module_id;
}
/**
* @param int $module_id
*/
public function setModuleId($module_id)
{
$this->module_id = $module_id;
}
/**
* @return int
*/
public function getModuleId()
{
return $this->module_id;
}
}

View File

@@ -0,0 +1,70 @@
<?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\Module;
use Thelia\Core\Event\ActionEvent;
use Thelia\Model\Module;
/**
* Class ModuleEvent
* @package Thelia\Core\Event\Module
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleEvent extends ActionEvent
{
/**
* @var \Thelia\Model\Module
*/
protected $module;
public function __construct(Module $module = null)
{
$this->module = $module;
}
/**
* @param \Thelia\Model\Module $module
*
* @return $this
*/
public function setModule(Module $module)
{
$this->module = $module;
return $this;
}
/**
* @return \Thelia\Model\Module
*/
public function getModule()
{
return $this->module;
}
public function hasModule()
{
return null !== $this->module;
}
}

View File

@@ -0,0 +1,63 @@
<?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\Module;
/**
* Class ModuleToggleActivationEvent
* @package Thelia\Core\Event\Module
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleToggleActivationEvent extends ModuleEvent
{
/**
* @var int
*/
protected $module_id;
public function __construct($module_id)
{
$this->module_id = $module_id;
}
/**
* @param int $module_id
*
* @return $this
*/
public function setModuleId($module_id)
{
$this->module_id = $module_id;
return $this;
}
/**
* @return int
*/
public function getModuleId()
{
return $this->module_id;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event;
/**
* Class PdfEvent
* @package Thelia\Core\Event
@@ -189,5 +188,4 @@ class PdfEvent extends ActionEvent
return $this->unicode;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Product;
class ProductCreateEvent extends ProductEvent
{
protected $ref;

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\Product;
class ProductDeleteEvent extends ProductEvent
{
public function __construct($product_id)

View File

@@ -24,7 +24,6 @@
namespace Thelia\Core\Event\ShippingZone;
use Thelia\Core\Event\ActionEvent;
/**
* Class ShippingZoneAddAreaEvent
* @package Thelia\Core\Event\ShippingZone
@@ -35,7 +34,7 @@ class ShippingZoneAddAreaEvent extends ActionEvent
protected $area_id;
protected $shopping_zone_id;
function __construct($area_id, $shopping_zone_id)
public function __construct($area_id, $shopping_zone_id)
{
$this->area_id = $area_id;
$this->shopping_zone_id = $shopping_zone_id;
@@ -81,7 +80,4 @@ class ShippingZoneAddAreaEvent extends ActionEvent
return $this->shopping_zone_id;
}
}

View File

@@ -23,7 +23,6 @@
namespace Thelia\Core\Event\ShippingZone;
/**
* Class ShippingZoneRemoveAreaEvent
* @package Thelia\Core\Event\ShippingZone

View File

@@ -118,5 +118,4 @@ class TaxRuleEvent extends ActionEvent
return $this->taxList;
}
}

View File

@@ -183,7 +183,6 @@ final class TheliaEvents
const FOLDER_TOGGLE_VISIBILITY = "action.toggleFolderVisibility";
const FOLDER_UPDATE_POSITION = "action.updateFolderPosition";
const BEFORE_CREATEFOLDER = "action.before_createFolder";
const AFTER_CREATEFOLDER = "action.after_createFolder";
@@ -204,7 +203,6 @@ final class TheliaEvents
const CONTENT_ADD_FOLDER = "action.contentAddFolder";
const CONTENT_REMOVE_FOLDER = "action.contentRemoveFolder";
const BEFORE_CREATECONTENT = "action.before_createContent";
const AFTER_CREATECONTENT = "action.after_createContent";
@@ -222,7 +220,6 @@ final class TheliaEvents
const COUNTRY_TOGGLE_DEFAULT = "action.toggleCountryDefault";
//const COUNTRY_UPDATE_POSITION = "action.updateFolderPosition";
const BEFORE_CREATECOUNTRY = "action.before_createCountry";
const AFTER_CREATECOUNTRY = "action.after_createCountry";
@@ -670,4 +667,18 @@ final class TheliaEvents
const GENERATE_PDF = 'thelia.generatePdf';
/**
* sent when a module is activated or deactivated
*/
const MODULE_TOGGLE_ACTIVATION = 'thelia.module.toggleActivation';
/**
* sent when a module is deleted
*/
const MODULE_DELETE = 'thelia.module.delete';
/**
* sent for clearing cache
*/
const CACHE_CLEAR = 'thelia.cache.clear';
}

View File

@@ -30,7 +30,6 @@ use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Model\AreaQuery;
/**
* Class Area
* @package Thelia\Core\Template\Loop
@@ -112,8 +111,7 @@ class Area extends BaseLoop
$withoutZone = $this->getWithout_zone();
if($withoutZone)
{
if ($withoutZone) {
$search->joinAreaDeliveryModule('without_zone', Criteria::LEFT_JOIN)
->addJoinCondition('without_zone', 'delivery_module_id '.Criteria::EQUAL.' ?', $withoutZone, null, \PDO::PARAM_INT)
->where('`without_zone`.delivery_module_id '.Criteria::ISNULL);
@@ -140,5 +138,4 @@ class Area extends BaseLoop
return $loopResult;
}
}

View File

@@ -114,7 +114,7 @@ class Folder extends BaseI18nLoop
if (null !== $content) {
$obj = ContentQuery::create()->findPk($content);
if($obj) {
if ($obj) {
$search->filterByContent($obj, Criteria::IN);
}
}

View File

@@ -30,7 +30,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Model\FolderQuery;
use Thelia\Type\BooleanOrBothType;
/**
* Class FolderPath
* @package Thelia\Core\Template\Loop
@@ -156,5 +155,4 @@ class FolderPath extends BaseI18nLoop
return $loopResult;
}
}

View File

@@ -97,7 +97,7 @@ class Tax extends BaseI18nLoop
$country = $this->getCountry();
$taxRule = $this->getTax_rule();
if(null !== $taxRule && null !== $country) {
if (null !== $taxRule && null !== $country) {
$search->filterByTaxRuleCountry(
TaxRuleCountryQuery::create()
->filterByCountryId($country, Criteria::EQUAL)
@@ -108,7 +108,7 @@ class Tax extends BaseI18nLoop
}
$excludeTaxRule = $this->getExclude_tax_rule();
if(null !== $excludeTaxRule && null !== $country) {
if (null !== $excludeTaxRule && null !== $country) {
$excludedTaxes = TaxRuleCountryQuery::create()
->filterByCountryId($country, Criteria::EQUAL)
->filterByTaxRuleId($excludeTaxRule, Criteria::IN)
@@ -118,7 +118,7 @@ class Tax extends BaseI18nLoop
$excludedTaxes,
Criteria::NOT_IN
);*/
foreach($excludedTaxes as $excludedTax) {
foreach ($excludedTaxes as $excludedTax) {
$search->filterByTaxRuleCountry($excludedTax, Criteria::NOT_EQUAL);
}
}

View File

@@ -32,7 +32,6 @@ use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
use Thelia\Core\Template\Loop\Argument\Argument;
use Thelia\Model\Base\TemplateQuery;
use Thelia\Type;
/**
*

View File

@@ -172,6 +172,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
self::$dataAccessCache['defaultCountry'] = $defaultCountry;
}*/
$defaultCountry = CountryQuery::create()->filterByByDefault(1)->limit(1);
return $this->dataAccessWithI18n("defaultCountry", $params, $defaultCountry);
}
}
@@ -237,7 +238,7 @@ class DataAccessFunctions extends AbstractSmartyPlugin
public function ConfigDataAccess($params, $smarty)
{
if(false === array_key_exists("key", $params)) {
if (false === array_key_exists("key", $params)) {
return null;
}

View File

@@ -167,9 +167,13 @@ class Form extends AbstractSmartyPlugin
if( true === $formFieldConfig->getOption('prototype') ) {
} else {
/* access to choices */
if (isset($formFieldView->vars['choices'])) {
$template->assign("choices", $formFieldView->vars['choices']);
}
}
}
/* access to thelia type */
if($formFieldType instanceof TheliaType) {
@@ -275,8 +279,8 @@ $this->assignFieldValues($template, $formFieldView->vars["full_name"], $fieldVar
foreach ($formView->getIterator() as $row) {
if ($this->isHidden($row) && $row->isRendered() === false) {
$attributeList = array();
if(isset($row->vars["attr"])) {
foreach($row->vars["attr"] as $attrKey => $attrValue) {
if (isset($row->vars["attr"])) {
foreach ($row->vars["attr"] as $attrKey => $attrValue) {
$attributeList[] = sprintf($attrFormat, $attrKey, $attrValue);
}
}

View File

@@ -28,7 +28,6 @@ use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Form\BaseForm;
/**
* Class AreaCountryForm
* @package Thelia\Form\Area

View File

@@ -26,7 +26,6 @@ use Thelia\Core\Translation\Translator;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Form\BaseForm;
/**
* Class AreaCreateForm
* @package Thelia\Form\Shipping

View File

@@ -25,7 +25,6 @@ namespace Thelia\Form\Area;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Thelia\Form\Area\AreaCreateForm;
/**
* Class AreaModificationForm
* @package Thelia\Form\Shipping

View File

@@ -29,7 +29,6 @@ use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Form\BaseForm;
use Thelia\Core\Translation\Translator;
/**
* Class AreaPostageForm
* @package Thelia\Form\Area

View File

@@ -23,8 +23,6 @@
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
class CountryModificationForm extends CountryCreationForm
{

View File

@@ -28,7 +28,6 @@ use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Form\BaseForm;
/**
* Class ShippingZoneAddArea
* @package Thelia\Form\ShippingZone

View File

@@ -23,7 +23,6 @@
namespace Thelia\Form\ShippingZone;
/**
* Class ShippingZoneRemoveArea
* @package Thelia\Form\ShippingZone

View File

@@ -24,8 +24,6 @@ namespace Thelia\Form;
use Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Translation\Translator;
use Thelia\Model\CountryQuery;
class TaxRuleCreationForm extends BaseForm
{

View File

@@ -34,7 +34,7 @@ class TaxRuleTaxListUpdateForm extends BaseForm
protected function buildForm()
{
$countryList = array();
foreach(CountryQuery::create()->find() as $country) {
foreach (CountryQuery::create()->find() as $country) {
$countryList[$country->getId()] = $country->getId();
}
@@ -96,7 +96,7 @@ class TaxRuleTaxListUpdateForm extends BaseForm
public function verifyTaxList($value, ExecutionContextInterface $context)
{
$jsonType = new JsonType();
if(!$jsonType->isValid($value)) {
if (!$jsonType->isValid($value)) {
$context->addViolation("Tax list is not valid JSON");
}
@@ -104,10 +104,10 @@ class TaxRuleTaxListUpdateForm extends BaseForm
/* check we have 2 level max */
foreach($taxList as $taxLevel1) {
if(is_array($taxLevel1)) {
foreach($taxLevel1 as $taxLevel2) {
if(is_array($taxLevel2)) {
foreach ($taxList as $taxLevel1) {
if (is_array($taxLevel1)) {
foreach ($taxLevel1 as $taxLevel2) {
if (is_array($taxLevel2)) {
$context->addViolation("Bad tax list JSON");
} else {
$taxModel = TaxQuery::create()->findPk($taxLevel2);

View File

@@ -60,7 +60,14 @@ class CartItem extends BaseCartItem
}
}
$this->setQuantity($value);
$this->addQuantity($value);
return $this;
}
public function addQuantity($quantity)
{
$this->setQuantity($this->getQuantity() + $quantity);
return $this;
}

View File

@@ -56,7 +56,7 @@ class ConfigQuery extends BaseConfigQuery {
public static function getPageNotFoundView()
{
return self::read("page_not_found_view", '404');
return self::read("page_not_found_view", '404.html');
}
public static function getPassedUrlView()

View File

@@ -13,6 +13,9 @@ class Country extends BaseCountry
public function toggleDefault()
{
if($this->getId() === null) {
throw new \RuntimeException("impossible to just uncheck default country, choose a new one");
}
CountryQuery::create()
->filterByByDefault(1)
->update(array('ByDefault' => 0));
@@ -47,6 +50,10 @@ class Country extends BaseCountry
public function preDelete(ConnectionInterface $con = null)
{
if($this->getByDefault()) {
return false;
}
$this->dispatchEvent(TheliaEvents::BEFORE_DELETECOUNTRY, new CountryEvent($this));
return true;

View File

@@ -24,7 +24,10 @@
namespace Thelia\Module;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Propel;
use Symfony\Component\DependencyInjection\ContainerAware;
use Thelia\Model\Map\ModuleTableMap;
use Thelia\Model\ModuleI18nQuery;
use Thelia\Model\Map\ModuleImageTableMap;
use Thelia\Model\ModuleI18n;
@@ -43,27 +46,60 @@ abstract class BaseModule extends ContainerAware
const IS_ACTIVATED = 1;
const IS_NOT_ACTIVATED = 0;
protected $reflected;
public function __construct()
{
}
public function activate()
public function activate($moduleModel = null)
{
if (null === $moduleModel) {
$moduleModel = $this->getModuleModel();
}
if ($moduleModel->getActivate() == self::IS_NOT_ACTIVATED) {
$moduleModel->setActivate(self::IS_ACTIVATED);
$moduleModel->save();
$con = Propel::getWriteConnection(ModuleTableMap::DATABASE_NAME);
$con->beginTransaction();
try {
$this->afterActivation();
if ($this->preActivation($con)) {
$moduleModel->setActivate(self::IS_ACTIVATED);
$moduleModel->save($con);
$this->postActivation($con);
$con->commit();
}
} catch (\Exception $e) {
$moduleModel->setActivate(self::IS_NOT_ACTIVATED);
$moduleModel->save();
$con->rollBack();
throw $e;
}
}
}
public function deActivate($moduleModel = null)
{
if (null === $moduleModel) {
$moduleModel = $this->getModuleModel();
}
if ($moduleModel->getActivate() == self::IS_ACTIVATED) {
$con = Propel::getWriteConnection(ModuleTableMap::DATABASE_NAME);
$con->beginTransaction();
try {
if ($this->preDeactivation($con)) {
$moduleModel->setActivate(self::IS_NOT_ACTIVATED);
$moduleModel->save($con);
$this->postDeactivation($con);
$con->commit();
}
} catch (\Exception $e) {
$con->rollBack();
throw $e;
}
}
}
public function hasContainer()
{
return null === $this->container;
@@ -72,7 +108,7 @@ abstract class BaseModule extends ContainerAware
public function getContainer()
{
if ($this->hasContainer() === false) {
throw new \RuntimeException("Sorry, container his not available in this context");
throw new \RuntimeException("Sorry, container is not available in this context");
}
return $this->container;
@@ -99,17 +135,19 @@ abstract class BaseModule extends ContainerAware
}
}
public function deployImageFolder(Module $module, $folderPath)
public function deployImageFolder(Module $module, $folderPath, ConnectionInterface $con = null)
{
try {
$directoryBrowser = new \DirectoryIterator($folderPath);
} catch (\UnexpectedValueException $e) {
throw $e;
}
if(null === $con) {
$con = \Propel\Runtime\Propel::getConnection(
ModuleImageTableMap::DATABASE_NAME
);
}
/* browse the directory */
$imagePosition = 1;
@@ -178,9 +216,42 @@ abstract class BaseModule extends ContainerAware
return $moduleModel;
}
abstract public function getCode();
abstract public function install();
abstract public function afterActivation();
abstract public function destroy();
public function getCode()
{
if (null === $this->reflected) {
$this->reflected = new \ReflectionObject($this);
}
return basename(dirname($this->reflected->getFileName()));
}
public function install(ConnectionInterface $con = null)
{
}
public function preActivation(ConnectionInterface $con = null)
{
return true;
}
public function postActivation(ConnectionInterface $con = null)
{
}
public function preDeactivation(ConnectionInterface $con = null)
{
return true;
}
public function postDeactivation(ConnectionInterface $con = null)
{
}
public function destroy(ConnectionInterface $con = null)
{
}
}

View File

@@ -0,0 +1,34 @@
<?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\Module\Exception;
/**
* Class InvalidXmlDocumentException
* @package Thelia\Module\Exception
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class InvalidXmlDocumentException extends \RuntimeException
{
}

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\Module;
use Thelia\Module\Exception\InvalidXmlDocumentException;
/**
* Class ModuleDescriptorValidator
* @package Thelia\Module
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleDescriptorValidator
{
private $xsd_file;
public function __construct()
{
$this->xsd_file = __DIR__ . '/schema/module/module.xsd';
}
public function validate($xml_file)
{
$dom = new \DOMDocument();
if ($dom->load($xml_file)) {
if ($dom->schemaValidate($this->xsd_file)) {
return true;
}
}
throw new InvalidXmlDocumentException(sprintf("%s file is not a valid file", $xml_file));
}
public function getDescriptor($xml_file)
{
$this->validate($xml_file);
return @simplexml_load_file($xml_file);
}
}

View File

@@ -0,0 +1,118 @@
<?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\Module;
use Propel\Runtime\Connection\ConnectionInterface;
use Propel\Runtime\Exception\PropelException;
use Propel\Runtime\Propel;
use Symfony\Component\Finder\Finder;
use Thelia\Model\Map\ModuleTableMap;
use Thelia\Model\Module;
use Thelia\Model\ModuleI18n;
use Thelia\Model\ModuleQuery;
/**
* Class ModuleManagement
* @package Thelia\Module
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class ModuleManagement
{
protected $baseModuleDir;
protected $reflected;
public function __construct()
{
$this->baseModuleDir = THELIA_MODULE_DIR;
}
public function updateModules()
{
$finder = new Finder();
$finder
->name('module.xml')
->in($this->baseModuleDir . '/*/Config');
$descriptorValidator = new ModuleDescriptorValidator();
foreach ($finder as $file) {
$content = $descriptorValidator->getDescriptor($file->getRealPath());
$reflected = new \ReflectionClass((string) $content->fullnamespace);
$code = basename(dirname($reflected->getFileName()));
if (null === ModuleQuery::create()->filterByCode($code)->findOne()) {
$module = new Module();
$con = Propel::getWriteConnection(ModuleTableMap::DATABASE_NAME);
$con->beginTransaction();
try {
$module
->setCode($code)
->setFullNamespace((string) $content->fullnamespace)
->setType($this->getModuleType($reflected))
->setActivate(0)
->save($con);
$this->saveDescription($module, $content, $con);
$con->commit();
} catch (PropelException $e) {
$con->rollBack();
throw $e;
}
}
}
}
private function saveDescription(Module $module,\SimpleXMLElement $content, ConnectionInterface $con)
{
foreach ($content->descriptive as $description) {
$locale = $description->attributes()->locale;
$moduleI18n = new ModuleI18n();
$moduleI18n
->setLocale($locale)
->setModule($module)
->setTitle($description->title)
->setDescription(isset($description->description)?$description->description:null)
->setPostscriptum(isset($description->postscriptum)?$description->postscriptum:null)
->setChapo(isset($description->subtitle)?$description->subtitle:null)
->save($con);
}
}
private function getModuleType(\ReflectionClass $reflected)
{
if ($reflected->implementsInterface('Thelia\Module\DeliveryModuleInterface')) {
return BaseModule::DELIVERY_MODULE_TYPE;
} elseif ($reflected->implementsInterface('Thelia\Module\PaymentModuleInterface')) {
return BaseModule::PAYMENT_MODULE_TYPE;
} else {
return BaseModule::CLASSIC_MODULE_TYPE;
}
}
}

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding='UTF-8'?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="module">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" minOccurs="1" name="fullnamespace">
<xs:annotation>
<xs:documentation>The full namespace for the main class module (for example MyModule\MyModule)</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="descriptive" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>complete description, each description must be identify by ISO CODE 639</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="title" minOccurs="1" maxOccurs="1"/>
<xs:element type="xs:string" name="subtitle" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:string" name="description" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:string" name="postscriptum" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute type="xs:string" name="locale"/>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="version">
<xs:annotation>
<xs:documentation>Module version</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="author">
<xs:annotation>
<xs:documentation>Module author</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="company" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:string" name="email"/>
<xs:element type="xs:anyURI" name="website" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="type">
<xs:annotation>
<xs:documentation>module type : classic, delivery, payment</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="classic"/>
<xs:enumeration value="delivery"/>
<xs:enumeration value="payment"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="prerequis" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Les plugins qui doivent déjà être présents</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="plugin" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="version" use="optional"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="thelia">
<xs:annotation>
<xs:documentation>minimum required version of Thelia in 'dot' format (for example 1.2.3.4)</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[0-9.]+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="stability">
<xs:annotation>
<xs:documentation>current module stability: alpha, beta, rc, prod</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="alpha"/>
<xs:enumeration value="beta"/>
<xs:enumeration value="rc"/>
<xs:enumeration value="prod"/>
<xs:enumeration value="other"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element type="xs:string" name="documentation" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Le nom du fichier contenant la documentation. Ce fichier doit se trouver dans le répertoire du plugin.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element type="xs:anyURI" name="urlmiseajour" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>L'URL a interroger pour vérifier la présence d'une nouvelle version, appellé avec le nom du plugin et sa version</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -23,7 +23,6 @@
namespace Thelia\Tests\Action;
/**
* Class BaseAction
* @package Thelia\Tests\Action\ImageTest

View File

@@ -36,7 +36,6 @@ use Thelia\Model\ContentFolderQuery;
use Thelia\Model\ContentQuery;
use Thelia\Model\FolderQuery;
/**
* Class ContentTest
* @package Thelia\Tests\Action
@@ -205,7 +204,7 @@ class ContentTest extends BaseAction
$test = ContentFolderQuery::create()
->filterByContent($content)
->filterByFolder($folder);
} while($test->count() > 0);
} while ($test->count() > 0);
$event = new ContentAddFolderEvent($content, $folder->getId());
@@ -267,7 +266,7 @@ class ContentTest extends BaseAction
->addAscendingOrderByColumn('RAND()')
->findOne();
if(null === $folder) {
if (null === $folder) {
$this->fail('use fixtures before launching test, there is no folder in database');
}

View File

@@ -31,7 +31,6 @@ use Thelia\Core\Event\Folder\FolderUpdateEvent;
use Thelia\Core\Event\UpdatePositionEvent;
use Thelia\Model\FolderQuery;
/**
* Class FolderTest
* @package Thelia\Tests\Action\ImageTest
@@ -73,8 +72,6 @@ class FolderTest extends BaseAction
{
$folder = $this->getRandomFolder();
$visible = !$folder->getVisible();
$event = new FolderUpdateEvent($folder->getId());
@@ -147,7 +144,7 @@ class FolderTest extends BaseAction
->filterByPosition(1, Criteria::GREATER_THAN)
->findOne();
if(null === $folder) {
if (null === $folder) {
$this->fail('use fixtures before launching test, there is no folder in database');
}
@@ -169,7 +166,7 @@ class FolderTest extends BaseAction
->filterByPosition(1)
->findOne();
if(null === $folder) {
if (null === $folder) {
$this->fail('use fixtures before launching test, there is no folder in database');
}
@@ -191,7 +188,7 @@ class FolderTest extends BaseAction
->filterByPosition(1, Criteria::GREATER_THAN)
->findOne();
if(null === $folder) {
if (null === $folder) {
$this->fail('use fixtures before launching test, there is no folder in database');
}
@@ -215,7 +212,7 @@ class FolderTest extends BaseAction
->addAscendingOrderByColumn('RAND()')
->findOne();
if(null === $folder) {
if (null === $folder) {
$this->fail('use fixtures before launching test, there is no folder in database');
}

View File

@@ -115,6 +115,10 @@ class CacheClearTest extends \PHPUnit_Framework_TestCase
$container->setParameter("kernel.cache_dir", $this->cache_dir);
$dispatcher = $this->getMock("Symfony\Component\EventDispatcher\EventDispatcherInterface");
$container->set("event_dispatcher", $dispatcher);
return $container;
}

View File

@@ -127,7 +127,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$taxRulesCollection = new ObjectCollection();
$aProduct = ProductQuery::create()->findOne();
if(null === $aProduct) {
if (null === $aProduct) {
return;
}
@@ -169,7 +169,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$taxRulesCollection->setModel('\Thelia\Model\Tax');
$aProduct = ProductQuery::create()->findOne();
if(null === $aProduct) {
if (null === $aProduct) {
return;
}
@@ -214,7 +214,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$taxRulesCollection->append($tax);
$aProduct = ProductQuery::create()->findOne();
if(null === $aProduct) {
if (null === $aProduct) {
return;
}
@@ -270,7 +270,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
$taxRulesCollection->append($tax);
$aProduct = ProductQuery::create()->findOne();
if(null === $aProduct) {
if (null === $aProduct) {
return;
}

View File

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

View File

@@ -19,7 +19,7 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat
('image_cache_dir_from_web_root', 'cache/images', 0, 0, NOW(), NOW()),
('document_cache_dir_from_web_root', 'cache/documents', 0, 0, NOW(), NOW()),
('currency_rate_update_url', 'http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml', 0, 0, NOW(), NOW()),
('page_not_found_view', '404', 0, 0, NOW(), NOW()),
('page_not_found_view', '404.html', 0, 0, NOW(), NOW()),
('passed_url_view', 'passed-url', 0, 0, NOW(), NOW()),
('use_tax_free_amounts', 0, 0, 0, NOW(), NOW()),
('process_assets', '1', 0, 0, NOW(), NOW()),
@@ -39,6 +39,8 @@ INSERT INTO `module` (`id`, `code`, `type`, `activate`, `position`, `full_namesp
(4, 'FakeCB', 3, 0, 2, 'FakeCB\\FakeCB', NOW(), NOW());
INSERT INTO `module_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES
('1', 'en_US', 'Debug bar', NULL, NULL, NULL),
('1', 'fr_FR', 'Debug bar', NULL, NULL, NULL),
('2', 'en_US', '72h delivery', NULL, NULL, NULL),
('2', 'fr_FR', 'Livraison par colissimo en 72h', NULL, NULL, NULL);
@@ -275,7 +277,6 @@ INSERT INTO `country` (`id`, `area_id`, `isocode`, `isoalpha2`, `isoalpha3`, `by
(187, NULL, '862', 'VE', 'VEN', 0, NOW(), NOW()),
(188, NULL, '704', 'VN', 'VNM', 0, NOW(), NOW()),
(189, NULL, '887', 'YE', 'YEM', 0, NOW(), NOW()),
(190, NULL, '807', 'MK', 'MKD', 0, NOW(), NOW()),
(191, NULL, '180', 'CD', 'COD', 0, NOW(), NOW()),
(192, NULL, '894', 'ZM', 'ZMB', 0, NOW(), NOW()),
(193, NULL, '716', 'ZW', 'ZWE', 0, NOW(), NOW()),
@@ -915,9 +916,6 @@ INSERT INTO `country_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `po
(189, 'en_US', 'Yemen', '', '', ''),
(189, 'es_ES', 'Yemen', '', '', ''),
(189, 'fr_FR', 'Yémen', '', '', ''),
(190, 'en_US', 'Yougoslavia', '', '', ''),
(190, 'es_ES', 'Yugoslavia', '', '', ''),
(190, 'fr_FR', 'Yougoslavie', '', '', ''),
(191, 'en_US', 'Zaire', '', '', ''),
(191, 'es_ES', 'Zaire', '', '', ''),
(191, 'fr_FR', 'Zaïre', '', '', ''),

View File

@@ -23,6 +23,7 @@
namespace Cheque;
use Propel\Runtime\Connection\ConnectionInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Model\ModuleImageQuery;
@@ -59,17 +60,13 @@ class Cheque extends BaseModule implements PaymentModuleInterface
// no special process, waiting for the cheque.
}
public function install()
{
}
public function afterActivation()
public function postActivation(ConnectionInterface $con = null)
{
/* insert the images from image folder if first module activation */
$module = $this->getModuleModel();
if(ModuleImageQuery::create()->filterByModule($module)->count() == 0) {
$this->deployImageFolder($module, sprintf('%s/images', __DIR__));
$this->deployImageFolder($module, sprintf('%s/images', __DIR__), $con);
}
/* set module title */
@@ -82,10 +79,6 @@ class Cheque extends BaseModule implements PaymentModuleInterface
);
}
public function destroy()
{
// TODO: Implement destroy() method.
}
public function getCode()
{

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<fullnamespace>Cheque\Cheque</fullnamespace>
<descriptive locale="en_US">
<title>Cheque</title>
</descriptive>
<descriptive locale="fr_FR">
<title>Cheque</title>
</descriptive>
<version>1.1</version>
<author>
<name>Manuel Raynaud</name>
<email>mraynaud@openstudio.fr</email>
</author>
<type>payment</type>
<thelia>2.0.0</thelia>
<stability>alpha</stability>
</module>

View File

@@ -67,25 +67,6 @@ class Colissimo extends BaseModule implements DeliveryModuleInterface
return 2;
}
public function afterActivation()
{
}
/**
* YOU HAVE TO IMPLEMENT HERE ABSTRACT METHODD FROM BaseModule Class
* Like install and destroy
*/
public function install()
{
// TODO: Implement install() method.
}
public function destroy()
{
// TODO: Implement destroy() method.
}
public function getCode()
{
return 'Colissimo';

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<fullnamespace>Colissimo\Colissimo</fullnamespace>
<descriptive locale="en_US">
<title>colisimo</title>
</descriptive>
<descriptive locale="fr_FR">
<title>colisimo</title>
</descriptive>
<version>1.0</version>
<author>
<name>Manuel Raynaud</name>
<email>mraynaud@openstudio.fr</email>
</author>
<type>delivery</type>
<thelia>2.0.0</thelia>
<stability>alpha</stability>
</module>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<fullnamespace>FakeCB\FakeCB</fullnamespace>
<descriptive locale="en_US">
<title>fake cb</title>
</descriptive>
<descriptive locale="fr_FR">
<title>simulation cb</title>
</descriptive>
<version>1.0</version>
<author>
<name>Manuel Raynaud</name>
<email>mraynaud@openstudio.fr</email>
</author>
<type>payment</type>
<thelia>2.0.0</thelia>
<stability>alpha</stability>
</module>

View File

@@ -23,6 +23,7 @@
namespace FakeCB;
use Propel\Runtime\Connection\ConnectionInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Thelia\Model\Base\ModuleImageQuery;
@@ -59,12 +60,8 @@ class FakeCB extends BaseModule implements PaymentModuleInterface
// TODO: Implement pay() method.
}
public function install()
{
}
public function afterActivation()
public function postActivation(ConnectionInterface $con = null)
{
/* insert the images from image folder if first module activation */
$module = $this->getModuleModel();
@@ -82,10 +79,6 @@ class FakeCB extends BaseModule implements PaymentModuleInterface
);
}
public function destroy()
{
// TODO: Implement destroy() method.
}
public function getCode()
{

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<module>
<fullnamespace>TheliaDebugBar\TheliaDebugBar</fullnamespace>
<descriptive locale="en_US">
<title>debugbar for thelia</title>
</descriptive>
<descriptive locale="fr_FR">
<title>debugbar pour thelia</title>
</descriptive>
<version>1.0</version>
<author>
<name>Manuel Raynaud</name>
<email>mraynaud@openstudio.fr</email>
</author>
<type>classic</type>
<thelia>2.0.0</thelia>
<stability>alpha</stability>
</module>

View File

@@ -32,21 +32,6 @@ class TheliaDebugBar extends BaseModule
* Like install and destroy
*/
public function afterActivation()
{
}
public function install()
{
// TODO: Implement install() method.
}
public function destroy()
{
// TODO: Implement destroy() method.
}
public function getCode()
{
return 'TheliaDebugBar';

View File

@@ -0,0 +1,60 @@
<div class="general-block-decorator">
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<caption class="clearfix">
{$caption_title|default:{intl l='classic modules'}}
</caption>
<thead>
<tr>
<th>{intl l="Name"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Enable/Disable"}</th>
{module_include location='modules_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
{loop type="module" name="module.{$module_type}" module_type={$module_type|default:1} backend_context=1}
<tr>
<td><a href="#">{$TITLE}</a></td>
<td>{$CHAPO}</td>
<td>
<div class="make-switch switch-small module-activation" data-id="{$ID}" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox" {if $ACTIVE}checked{/if}>
</div>
<noscript>
{if $ACTIVE}
<a title="{intl l="Deactivate %title module" title=$TITLE}" href="{url path="/admin/configuration/modules/toggle-activation/{$ID}"}">{intl l="deactivation"}</a>
{else}
<a title="{intl l="activate %title module" title=$TITLE}" href="{url path="/admin/configuration/modules/toggle-activation/{$ID}"}">{intl l="activation"}</a>
{/if}
</noscript>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs module-delete-action" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
{/loop}
</tbody>
</table>
</div>
</div>

View File

@@ -25,221 +25,11 @@
<div class="row">
<div class="col-md-12">
<div class="general-block-decorator">
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<caption class="clearfix">
{intl l='Transport modules'}
</caption>
<thead>
<tr>
<th>{intl l="Name"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Enable/Disable"}</th>
{if $error_message}<div class="alert alert-danger">{$error_message}</div>{/if}
{include file="includes/module-block.html" module_type="1" caption_title={intl l='Classic modules'}}
{include file="includes/module-block.html" module_type="2" caption_title={intl l='Delivery modules'}}
{include file="includes/module-block.html" module_type="3" caption_title={intl l='Payment modules'}}
{module_include location='modules_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="">Tinymce</a></td>
<td>Eos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid! Eius, pariatur accusantium odit quidem laboriosam.</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox" checked>
</div>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
<tr>
<td><a href="">So colissimo</a></td>
<td>Eos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox">
</div>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
<tr>
<td><a href="">Title meta</a></td>
<td>Eos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox">
</div>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="general-block-decorator">
<div class="table-responsive">
<table class="table table-striped table-condensed table-left-aligned">
<caption class="clearfix">
{intl l='Delivery modules'}
</caption>
<thead>
<tr>
<th>{intl l="Name"}</th>
<th>{intl l="Description"}</th>
<th>{intl l="Enable/Disable"}</th>
{module_include location='modules_table_header'}
<th class="actions">{intl l="Actions"}</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="">Tinymce</a></td>
<td>Eos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid! Eius, pariatur accusantium odit quidem laboriosam.</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox" checked>
</div>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
<tr>
<td><a href="">So colissimo</a></td>
<td>Eos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox">
</div>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
<tr>
<td><a href="">Title meta</a></td>
<td>Eos minima maiores doloribus mollitia perspiciatis esse iusto odit error delectus aliquid</td>
<td>
<div class="make-switch switch-small" data-on="success" data-off="danger" data-on-label="<i class='glyphicon glyphicon-ok-circle'></i>" data-off-label="<i class='glyphicon glyphicon-remove-circle'></i>">
<input type="checkbox">
</div>
</td>
{module_include location='modules_table_row'}
<td>
<div class="btn-group">
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.documentation"}
<a class="btn btn-default btn-xs" title="{intl l='Read the documentation of this module'}" href="{url path="/admin/module/documentation/$ID"}"><span class="glyphicon glyphicon-book"></span></a>
{/loop}
{loop type="auth" name="can_change" roles="ADMIN" permissions="admin.modules.edit"}
<a class="btn btn-default btn-xs" title="{intl l='Edit this module'}" href="{url path="/admin/module/update/$ID"}"><span class="glyphicon glyphicon-edit"></span></a>
{/loop}
{loop type="auth" name="can_delete" roles="ADMIN" permissions="admin.modules.delete"}
<a class="btn btn-default btn-xs" title="{intl l='Delete this module'}" href="#delete_module_dialog" data-id="{$ID}" data-toggle="modal"><span class="glyphicon glyphicon-trash"></span></a>
{/loop}
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
@@ -251,8 +41,7 @@
{* Delete module confirmation dialog *}
{capture "delete_module_dialog"}
<input type="hidden" name="current_module_id" value="{$current_module_id}" />
<input type="hidden" name="module_id" id="delete_module_id" value"" />
<input type="hidden" name="module_id" id="delete_module_id" value="" />
{/capture}
{include
@@ -262,10 +51,25 @@
dialog_title = {intl l="Delete a module"}
dialog_message = {intl l="Do you really want to delete this module ?"}
form_action = {url path='/admin/modules/delete'}
form_action = {url path='/admin/configuration/modules/delete'}
form_content = {$smarty.capture.delete_module_dialog nofilter}
}
<div class="modal fade" id="module-failed" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>{intl l="An error occured"}</h3>
</div>
<div class="modal-body" id="module-failed-body">
</div>
</div>
</div>
</div>
{/block}
{block name="javascript-initialization"}
@@ -273,4 +77,28 @@
{javascripts file='assets/js/bootstrap-switch/bootstrap-switch.js'}
<script src="{$asset_url}"></script>
{/javascripts}
<script>
$(document).ready(function(){
var url_management = "{url path="/admin/configuration/modules/toggle-activation/"}";
$(".module-activation").on("switch-change", function(e, data){
$('body').append('<div class="modal-backdrop fade in" id="loading-event"><div class="loading"></div></div>');
$.ajax({
url: url_management+$(this).data('id')
}).done(function(){
$("#loading-event").remove();
})
.fail(function(jqXHR, textStatus, errorThrown){
$("#loading-event").remove();
$('#module-failed-body').html(jqXHR.responseJSON.error);
$("#module-failed").modal("show");
});
});
$(".module-delete-action").click(function(){
$("#delete_module_id").val($(this).data("id"));
});
});
</script>
{/block}

View File

@@ -5,7 +5,7 @@
{* Breadcrumb *}
{block name='no-return-functions' append}
{$sBreadcrumb = []}
{$breadcrumbs = []}
{loop type="product" name="product_breadcrumb" id="{product attr="id"}"}
{loop name="category_path" type="category-path" category="{$DEFAULT_CATEGORY}"}
{$breadcrumbs[] = ['title' => {$TITLE}, 'url'=> {$URL}]}
@@ -138,6 +138,10 @@
{form_hidden_fields form=$form}
<input type="hidden" name="view" value="product">
<input type="hidden" name="product_id" value="{$ID}">
{form_field form=$form field="append"}
<input type="hidden" name="{$name}" value="1">
{/form_field}
{if $form_error}<div class="alert alert-error">{$form_error_message}</div>{/if}