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:
@@ -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
4
composer.lock
generated
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
75
core/lib/Thelia/Action/Cache.php
Normal file
75
core/lib/Thelia/Action/Cache.php
Normal 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -160,7 +160,7 @@ class Content extends BaseAction implements EventSubscriberInterface
|
||||
->filterByFolderId($event->getFolderId())
|
||||
->findOne();
|
||||
|
||||
if(null !== $contentFolder) {
|
||||
if (null !== $contentFolder) {
|
||||
$contentFolder->delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
|
||||
136
core/lib/Thelia/Action/Module.php
Normal file
136
core/lib/Thelia/Action/Module.php
Normal 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Core\Event\PdfEvent;
|
||||
use Thelia\Core\Event\TheliaEvents;
|
||||
|
||||
|
||||
/**
|
||||
* Class Pdf
|
||||
* @package Thelia\Action
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
18
core/lib/Thelia/Command/Skeleton/Module/module.xml
Executable file
18
core/lib/Thelia/Command/Skeleton/Module/module.xml
Executable 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>
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -141,5 +141,4 @@ class ShippingZoneController extends BaseAdminController
|
||||
return $this->getRequest()->get('shipping_zone_id', 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
namespace Thelia\Core\Event\Area;
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Class AreaEvent
|
||||
* @package Thelia\Core\Event\Shipping
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Core\Event\Area;
|
||||
|
||||
|
||||
/**
|
||||
* Class AreaRemoveCountryEvent
|
||||
* @package Thelia\Core\Event\Area
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Core\Event\Area;
|
||||
|
||||
|
||||
/**
|
||||
* Class AreaUpdateEvent
|
||||
* @package Thelia\Core\Event\Area
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
65
core/lib/Thelia/Core/Event/Cache/CacheEvent.php
Normal file
65
core/lib/Thelia/Core/Event/Cache/CacheEvent.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Core\Event\Content;
|
||||
|
||||
|
||||
/**
|
||||
* Class ContentRemoveFolderEvent
|
||||
* @package Thelia\Core\Event\Content
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
61
core/lib/Thelia/Core/Event/Module/ModuleDeleteEvent.php
Normal file
61
core/lib/Thelia/Core/Event/Module/ModuleDeleteEvent.php
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
70
core/lib/Thelia/Core/Event/Module/ModuleEvent.php
Normal file
70
core/lib/Thelia/Core/Event/Module/ModuleEvent.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Core\Event\Product;
|
||||
|
||||
|
||||
class ProductCreateEvent extends ProductEvent
|
||||
{
|
||||
protected $ref;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Core\Event\Product;
|
||||
|
||||
|
||||
class ProductDeleteEvent extends ProductEvent
|
||||
{
|
||||
public function __construct($product_id)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Core\Event\ShippingZone;
|
||||
|
||||
|
||||
/**
|
||||
* Class ShippingZoneRemoveAreaEvent
|
||||
* @package Thelia\Core\Event\ShippingZone
|
||||
|
||||
@@ -118,5 +118,4 @@ class TaxRuleEvent extends ActionEvent
|
||||
return $this->taxList;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Form\ShippingZone;
|
||||
|
||||
|
||||
/**
|
||||
* Class ShippingZoneRemoveArea
|
||||
* @package Thelia\Form\ShippingZone
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
60
core/lib/Thelia/Module/ModuleDescriptorValidator.php
Normal file
60
core/lib/Thelia/Module/ModuleDescriptorValidator.php
Normal 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);
|
||||
}
|
||||
}
|
||||
118
core/lib/Thelia/Module/ModuleManagement.php
Normal file
118
core/lib/Thelia/Module/ModuleManagement.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
110
core/lib/Thelia/Module/schema/module/module.xsd
Normal file
110
core/lib/Thelia/Module/schema/module/module.xsd
Normal 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>
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
namespace Thelia\Tests\Action;
|
||||
|
||||
|
||||
/**
|
||||
* Class BaseAction
|
||||
* @package Thelia\Tests\Action\ImageTest
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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', '', '', ''),
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
18
local/modules/Cheque/Config/module.xml
Executable file
18
local/modules/Cheque/Config/module.xml
Executable 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>
|
||||
@@ -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';
|
||||
|
||||
18
local/modules/Colissimo/Config/module.xml
Normal file
18
local/modules/Colissimo/Config/module.xml
Normal 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>
|
||||
18
local/modules/FakeCB/Config/module.xml
Normal file
18
local/modules/FakeCB/Config/module.xml
Normal 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>
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
18
local/modules/TheliaDebugBar/Config/module.xml
Normal file
18
local/modules/TheliaDebugBar/Config/module.xml
Normal 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>
|
||||
@@ -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';
|
||||
|
||||
60
templates/admin/default/includes/module-block.html
Normal file
60
templates/admin/default/includes/module-block.html
Normal 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>
|
||||
@@ -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">×</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}
|
||||
@@ -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}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user