Initial Commit
This commit is contained in:
27
local/modules/TheliaMigrateCountry/Config/config.xml
Normal file
27
local/modules/TheliaMigrateCountry/Config/config.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<config xmlns="http://thelia.net/schema/dic/config"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
|
||||
|
||||
<forms>
|
||||
<form name="thelia.admin.country.state.migration" class="TheliaMigrateCountry\Form\CountryStateMigrationForm"/>
|
||||
</forms>
|
||||
|
||||
<services>
|
||||
<service id="theliamigratecountry.action" class="TheliaMigrateCountry\EventListeners\MigrateCountryListener" >
|
||||
<tag name="kernel.event_subscriber"/>
|
||||
</service>
|
||||
|
||||
<service id="thelia.form.type.country.state.migrate" class="TheliaMigrateCountry\Form\Type\CountryStateMigrationType">
|
||||
<tag name="thelia.form.type" />
|
||||
</service>
|
||||
</services>
|
||||
|
||||
<hooks>
|
||||
<hook id="theliamigratecountry.hook">
|
||||
<tag name="hook.event_listener" event="configuration.shipping-bottom" type="back" templates="configuration-shipping-bottom.html" />
|
||||
</hook>
|
||||
</hooks>
|
||||
|
||||
</config>
|
||||
26
local/modules/TheliaMigrateCountry/Config/module.xml
Normal file
26
local/modules/TheliaMigrateCountry/Config/module.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module xmlns="http://thelia.net/schema/dic/module"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://thelia.net/schema/dic/module http://thelia.net/schema/dic/module/module-2_2.xsd">
|
||||
<fullnamespace>TheliaMigrateCountry\TheliaMigrateCountry</fullnamespace>
|
||||
<descriptive locale="en_US">
|
||||
<title>Countries/states migration tool</title>
|
||||
</descriptive>
|
||||
<descriptive locale="fr_FR">
|
||||
<title>Utilitaire de migration des pays/états</title>
|
||||
</descriptive>
|
||||
<languages>
|
||||
<language>en_US</language>
|
||||
<language>fr_FR</language>
|
||||
</languages>
|
||||
<version>2.3.1</version>
|
||||
<authors>
|
||||
<author>
|
||||
<name>Julien Chanséaume</name>
|
||||
<email>julien@thelia.net</email>
|
||||
</author>
|
||||
</authors>
|
||||
<type>classic</type>
|
||||
<thelia>2.3.0</thelia>
|
||||
<stability>alpha</stability>
|
||||
</module>
|
||||
15
local/modules/TheliaMigrateCountry/Config/routing.xml
Normal file
15
local/modules/TheliaMigrateCountry/Config/routing.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<routes xmlns="http://symfony.com/schema/routing"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
|
||||
|
||||
<route id="admin.configuration.countries.migrate" path="/admin/configuration/countries/migrate">
|
||||
<default key="_controller">TheliaMigrateCountry\Controller\MigrateController::migrateSystemAction</default>
|
||||
</route>
|
||||
|
||||
<route id="admin.configuration.countries.do-migrate" path="/admin/configuration/countries/do-migrate" methods="post">
|
||||
<default key="_controller">TheliaMigrateCountry\Controller\MigrateController::doMigrateSystemAction</default>
|
||||
</route>
|
||||
|
||||
</routes>
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace TheliaMigrateCountry\Controller;
|
||||
|
||||
use Thelia\Controller\Admin\BaseAdminController;
|
||||
use Thelia\Core\Security\AccessManager;
|
||||
use Thelia\Core\Security\Resource\AdminResources;
|
||||
use Thelia\Form\Exception\FormValidationException;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Model\Country;
|
||||
use Thelia\Model\CountryQuery;
|
||||
use Thelia\Model\Map\AddressTableMap;
|
||||
use Thelia\Model\Map\CountryAreaTableMap;
|
||||
use Thelia\Model\Map\TaxRuleCountryTableMap;
|
||||
use TheliaMigrateCountry\Events\MigrateCountryEvent;
|
||||
use TheliaMigrateCountry\Events\MigrateCountryEvents;
|
||||
|
||||
|
||||
/**
|
||||
* Class MigrateController
|
||||
* @package TheliaMigrateCountry\Controller
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class MigrateController extends BaseAdminController
|
||||
{
|
||||
protected $useFallbackTemplate = true;
|
||||
|
||||
public function migrateSystemAction()
|
||||
{
|
||||
$response = $this->checkAuth(AdminResources::COUNTRY, array(), AccessManager::UPDATE);
|
||||
if (null !== $response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// load country not migrated
|
||||
$dataForm = [];
|
||||
|
||||
$migratedCountries = json_decode(ConfigQuery::read('thelia_country_state_migration', '[]'), true);
|
||||
|
||||
$countries = CountryQuery::create()
|
||||
->filterByHasStates(1)
|
||||
;
|
||||
|
||||
/** @var Country $country */
|
||||
foreach ($countries as $country) {
|
||||
$oldCountries = CountryQuery::create()
|
||||
->filterByHasStates(0)
|
||||
->filterByIsocode($country->getIsoCode())
|
||||
->find()
|
||||
;
|
||||
/** @var Country $oldCountry */
|
||||
foreach ($oldCountries as $oldCountry) {
|
||||
if (!isset($migratedCountries[$oldCountry->getId()])) {
|
||||
$dataForm[] = [
|
||||
'migrate' => false,
|
||||
'country' => $oldCountry->getId(),
|
||||
'new_country' => $country->getId(),
|
||||
'new_state' => null
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prepare form
|
||||
$form = $this->createForm('thelia.admin.country.state.migration', 'form', ['migrations' => $dataForm]);
|
||||
$this->getParserContext()->addForm($form);
|
||||
|
||||
return $this->render(
|
||||
'countries-migrate',
|
||||
[
|
||||
'countriesMigrated' => $migratedCountries,
|
||||
'showForm' => count($dataForm) != 0
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function doMigrateSystemAction()
|
||||
{
|
||||
$response = $this->checkAuth(AdminResources::COUNTRY, array(), AccessManager::UPDATE);
|
||||
if (null !== $response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$changeForm = $this->createForm('thelia.admin.country.state.migration', 'form');
|
||||
|
||||
try {
|
||||
// Check the form against constraints violations
|
||||
$form = $this->validateForm($changeForm, "POST");
|
||||
|
||||
// Get the form field values
|
||||
$data = $form->getData();
|
||||
|
||||
foreach ($data['migrations'] as $migration) {
|
||||
|
||||
if (!$migration['migrate']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$changeEvent = new MigrateCountryEvent(
|
||||
$migration['country'],
|
||||
$migration['new_country'],
|
||||
$migration['new_state']
|
||||
);
|
||||
|
||||
$this->dispatch(MigrateCountryEvents::MIGRATE_COUNTRY, $changeEvent);
|
||||
|
||||
// memorize the migration
|
||||
$migratedCountries = json_decode(ConfigQuery::read('thelia_country_state_migration', '[]'), true);
|
||||
$migratedCountries[$changeEvent->getCountry()] = [
|
||||
'country' => $changeEvent->getNewCountry(),
|
||||
'state' => $changeEvent->getNewState(),
|
||||
'counter' => $changeEvent->getCounter()
|
||||
];
|
||||
ConfigQuery::write('thelia_country_state_migration', json_encode($migratedCountries));
|
||||
|
||||
// message
|
||||
$message = $this->getTranslator()->trans(
|
||||
'Country %id migrated to country (ID %country) and state (ID %state) (address: %address, tax rules: %tax, shipping zones: %zone)',
|
||||
[
|
||||
'%id' => $changeEvent->getCountry(),
|
||||
'%country' => $changeEvent->getNewCountry(),
|
||||
'%state' => $changeEvent->getNewState(),
|
||||
'%address' => $changeEvent->getCounter()[AddressTableMap::TABLE_NAME],
|
||||
'%tax' => $changeEvent->getCounter()[TaxRuleCountryTableMap::TABLE_NAME],
|
||||
'%zone' => $changeEvent->getCounter()[CountryAreaTableMap::TABLE_NAME]
|
||||
]
|
||||
);
|
||||
|
||||
// add flash message
|
||||
$this->getSession()->getFlashBag()->add('migrate', $message);
|
||||
|
||||
// Log migration
|
||||
$this->adminLogAppend(
|
||||
AdminResources::COUNTRY,
|
||||
AccessManager::UPDATE,
|
||||
$message,
|
||||
$changeEvent->getCountry()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $this->generateSuccessRedirect($changeForm);
|
||||
} catch (FormValidationException $ex) {
|
||||
// Form cannot be validated
|
||||
$error_msg = $this->createStandardFormValidationErrorMessage($ex);
|
||||
}
|
||||
|
||||
if (false !== $error_msg) {
|
||||
$this->setupFormErrorContext(
|
||||
$this->getTranslator()->trans("Country migration"),
|
||||
$error_msg,
|
||||
$changeForm,
|
||||
$ex
|
||||
);
|
||||
|
||||
return $this->render(
|
||||
'countries-migrate',
|
||||
[
|
||||
'countriesMigrated' => $migratedCountries,
|
||||
'showForm' => true
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace TheliaMigrateCountry\EventListeners;
|
||||
|
||||
use Propel\Runtime\Exception\PropelException;
|
||||
use Propel\Runtime\Propel;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Thelia\Model\AddressQuery;
|
||||
use Thelia\Model\Base\CountryQuery;
|
||||
use Thelia\Model\CountryAreaQuery;
|
||||
use Thelia\Model\Map\AddressTableMap;
|
||||
use Thelia\Model\Map\CountryAreaTableMap;
|
||||
use Thelia\Model\Map\TaxRuleCountryTableMap;
|
||||
use Thelia\Model\TaxRuleCountryQuery;
|
||||
use TheliaMigrateCountry\Events\MigrateCountryEvent;
|
||||
use TheliaMigrateCountry\Events\MigrateCountryEvents;
|
||||
|
||||
/**
|
||||
* Class MigrateCountryListener
|
||||
* @package TheliaMigrateCountry\EventListeners
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class MigrateCountryListener implements EventSubscriberInterface
|
||||
{
|
||||
|
||||
public function migrateCountry(MigrateCountryEvent $event)
|
||||
{
|
||||
$counter = [];
|
||||
|
||||
// update address
|
||||
$counter[AddressTableMap::TABLE_NAME] = $this->migrateAddress($event);
|
||||
|
||||
// tax rules
|
||||
$counter[TaxRuleCountryTableMap::TABLE_NAME] = $this->migrateAddress($event);
|
||||
|
||||
// shipping zone
|
||||
$counter[CountryAreaTableMap::TABLE_NAME] = $this->migrateAddress($event);
|
||||
|
||||
// if it succeeds we toggle the visibility of old country and new
|
||||
$this->setCountriesVisibility($event);
|
||||
|
||||
$event->setCounter($counter);
|
||||
|
||||
}
|
||||
|
||||
protected function migrateAddress(MigrateCountryEvent $event)
|
||||
{
|
||||
$con = Propel::getWriteConnection(AddressTableMap::DATABASE_NAME);
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
$updatedRows = AddressQuery::create()
|
||||
->filterByCountryId($event->getCountry())
|
||||
->update(
|
||||
[
|
||||
'CountryId' => $event->getNewCountry(),
|
||||
'StateId' => $event->getNewState(),
|
||||
]
|
||||
);
|
||||
|
||||
$con->commit();
|
||||
|
||||
return $updatedRows;
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
protected function migrateTaxRules(MigrateCountryEvent $event)
|
||||
{
|
||||
$con = Propel::getWriteConnection(TaxRuleCountryTableMap::DATABASE_NAME);
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
$updatedRows = TaxRuleCountryQuery::create()
|
||||
->filterByCountryId($event->getCountry())
|
||||
->update(
|
||||
[
|
||||
'CountryId' => $event->getNewCountry(),
|
||||
'StateId' => $event->getNewState(),
|
||||
]
|
||||
);
|
||||
|
||||
$con->commit();
|
||||
|
||||
return $updatedRows;
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
protected function migrateShippingZones(MigrateCountryEvent $event)
|
||||
{
|
||||
$con = Propel::getWriteConnection(CountryAreaTableMap::DATABASE_NAME);
|
||||
$con->beginTransaction();
|
||||
try {
|
||||
$updatedRows = CountryAreaQuery::create()
|
||||
->filterByCountryId($event->getCountry())
|
||||
->update(
|
||||
[
|
||||
'CountryId' => $event->getNewCountry(),
|
||||
'StateId' => $event->getNewState(),
|
||||
]
|
||||
);
|
||||
|
||||
$con->commit();
|
||||
|
||||
return $updatedRows;
|
||||
} catch (PropelException $e) {
|
||||
$con->rollback();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function setCountriesVisibility(MigrateCountryEvent $event)
|
||||
{
|
||||
$oldCountry = CountryQuery::create()->findPk($event->getCountry());
|
||||
|
||||
if (null !== $oldCountry) {
|
||||
$oldCountry
|
||||
->setVisible(0)
|
||||
->save()
|
||||
;
|
||||
}
|
||||
|
||||
$newCountry = CountryQuery::create()->findPk($event->getNewCountry());
|
||||
if (null !== $newCountry) {
|
||||
$newCountry
|
||||
->setVisible(1)
|
||||
->save()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
MigrateCountryEvents::MIGRATE_COUNTRY => 'migrateCountry'
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace TheliaMigrateCountry\Events;
|
||||
|
||||
use Thelia\Core\Event\ActionEvent;
|
||||
|
||||
/**
|
||||
* Class MigrateCountryEvent
|
||||
* @package TheliaMigrateCountry\Events
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class MigrateCountryEvent extends ActionEvent
|
||||
{
|
||||
/** @var int Old country Id */
|
||||
protected $country;
|
||||
|
||||
/** @var int New country Id */
|
||||
protected $newCountry;
|
||||
|
||||
/** @var int New state Id */
|
||||
protected $newState;
|
||||
|
||||
/** @var array counter */
|
||||
protected $counter = [];
|
||||
|
||||
/**
|
||||
* MigrateCountryEvent constructor.
|
||||
* @param $country
|
||||
* @param int $newCountry
|
||||
* @param int $newState
|
||||
*/
|
||||
public function __construct($country, $newCountry, $newState)
|
||||
{
|
||||
$this->country = $country;
|
||||
$this->newCountry = $newCountry;
|
||||
$this->newState = $newState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCountry()
|
||||
{
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $country
|
||||
*/
|
||||
public function setCountry($country)
|
||||
{
|
||||
$this->country = $country;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getNewCountry()
|
||||
{
|
||||
return $this->newCountry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $newCountry
|
||||
*/
|
||||
public function setNewCountry($newCountry)
|
||||
{
|
||||
$this->newCountry = $newCountry;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getNewState()
|
||||
{
|
||||
return $this->newState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $newState
|
||||
*/
|
||||
public function setNewState($newState)
|
||||
{
|
||||
$this->newState = $newState;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCounter()
|
||||
{
|
||||
return $this->counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $counter
|
||||
*/
|
||||
public function setCounter($counter)
|
||||
{
|
||||
$this->counter = $counter;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace TheliaMigrateCountry\Events;
|
||||
|
||||
/**
|
||||
* Class MigrateCountryEvents
|
||||
* @package TheliaMigrateCountry\Events
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class MigrateCountryEvents
|
||||
{
|
||||
const MIGRATE_COUNTRY = 'action.migrate-country.migrate';
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace TheliaMigrateCountry\Form;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\Count;
|
||||
use Thelia\Form\BaseForm;
|
||||
|
||||
/**
|
||||
* Class CountryStateMigrationForm
|
||||
* @package TheliaMigrateCountry\Form
|
||||
*
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class CountryStateMigrationForm extends BaseForm
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdocs
|
||||
*/
|
||||
protected function buildForm()
|
||||
{
|
||||
$this->formBuilder
|
||||
->add(
|
||||
'migrations',
|
||||
'collection',
|
||||
[
|
||||
"type" => "country_state_migration",
|
||||
"allow_add" => true,
|
||||
"required" => true,
|
||||
"cascade_validation" => true,
|
||||
"constraints" => array(
|
||||
new Count(["min" => 1]),
|
||||
),
|
||||
]
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return "thelia_country_state_migration";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace TheliaMigrateCountry\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Thelia\Core\Form\Type\AbstractTheliaType;
|
||||
use Thelia\Core\Translation\Translator;
|
||||
use Thelia\Model\StateQuery;
|
||||
|
||||
/**
|
||||
* Class CountryStateMigrationType
|
||||
* @package TheliaMigrateCountry\Form\Type
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class CountryStateMigrationType extends AbstractTheliaType
|
||||
{
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults(
|
||||
[
|
||||
"cascade_validation" => true,
|
||||
"constraints" => array(
|
||||
new Callback([
|
||||
"methods" => array(
|
||||
[$this, "checkStateId"],
|
||||
),
|
||||
]),
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add("migrate", "checkbox")
|
||||
->add(
|
||||
"country",
|
||||
"country_id"
|
||||
)
|
||||
->add(
|
||||
"new_country",
|
||||
"country_id"
|
||||
)
|
||||
->add(
|
||||
"new_state",
|
||||
"state_id",
|
||||
[
|
||||
"constraints" => [],
|
||||
]
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
public function checkStateId($value, ExecutionContextInterface $context)
|
||||
{
|
||||
|
||||
if ($value['migrate']) {
|
||||
if (null !== $state = StateQuery::create()->findPk($value['new_state'])) {
|
||||
if ($state->getCountryId() !== $value['new_country']) {
|
||||
$context->addViolation(
|
||||
Translator::getInstance()->trans(
|
||||
"The state id '%id' does not belong to country id '%id_country'",
|
||||
[
|
||||
'%id' => $value['new_state'],
|
||||
'%id_country' => $value['new_country']
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$context->addViolation(
|
||||
Translator::getInstance()->trans(
|
||||
"The state id '%id' doesn't exist",
|
||||
['%id' => $value['new_state']]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function getRowData(ExecutionContextInterface $context)
|
||||
{
|
||||
$propertyPath = $context->getPropertyPath();
|
||||
$data = $this->getRowData($context);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this type.
|
||||
*
|
||||
* @return string The name of this type
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'country_state_migration';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
' country ' => ' country ',
|
||||
' migrated to ' => ' migrated to ',
|
||||
' state ' => ' state ',
|
||||
'After the migration the old country will be hide and the new one shown' => 'After the migration the old country will be hide and the new one shown',
|
||||
'All States' => 'All States',
|
||||
'All countries have been migrated' => 'All countries have been migrated',
|
||||
'Configuration' => 'Configuration',
|
||||
'Countries' => 'Countries',
|
||||
'Countries migrated' => 'Countries migrated',
|
||||
'Countries to migrate' => 'Countries to migrate',
|
||||
'Country ' => 'Country ',
|
||||
'Country migration' => 'Country migration',
|
||||
'For USA and Canada the states already exists as countries, so you have to select the right state.' => 'For USA and Canada the states already exists as countries, so you have to select the right state.',
|
||||
'For other countries, you should decide to use state or not. ' => 'For other countries, you should decide to use state or not. ',
|
||||
'Home' => 'Home',
|
||||
'If you want to use the new country with its states, you have to check the migrate checkbox and select a state.' => 'If you want to use the new country with its states, you have to check the migrate checkbox and select a state.',
|
||||
'In version 2.3 of Thelia, the system of country has changed.' => 'In version 2.3 of Thelia, the system of country has changed.',
|
||||
'Migrate ?' => 'Migrate ?',
|
||||
'Migrate countries' => 'Migrate countries',
|
||||
'New country' => 'New country',
|
||||
'Now, countries has been splited in countries and states.' => 'Now, countries has been splited in countries and states.',
|
||||
'Old country' => 'Old country',
|
||||
'State' => 'State',
|
||||
'The migration proccess is tricky and couldn\'t be automated.' => 'The migration proccess is tricky and couldn\'t be automated.',
|
||||
'The migration will change the address, tax rules and shipping zones to match with the new system.' => 'The migration will change the address, tax rules and shipping zones to match with the new system.',
|
||||
'The update proccess has created new countries (even if it exists) and associated states.' => 'The update proccess has created new countries (even if it exists) and associated states.',
|
||||
'We added a \'default\' state with a blank name as a fallback. Customer will have the possibility to change it later.' => 'We added a \'default\' state with a blank name as a fallback. Customer will have the possibility to change it later.',
|
||||
);
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
' country ' => ' le pays',
|
||||
' migrated to ' => 'migré vers',
|
||||
' state ' => ' état ',
|
||||
'After the migration the old country will be hide and the new one shown' => 'Après la migration l\'ancien pays sera caché et le nouveau sera activé.',
|
||||
'All States' => 'Tous les états',
|
||||
'All countries have been migrated' => 'Tous les pays ont été migré',
|
||||
'Configuration' => 'Configuration',
|
||||
'Countries' => 'Pays',
|
||||
'Countries migrated' => 'Pays migrés',
|
||||
'Countries to migrate' => 'Pays à migrer.',
|
||||
'Country ' => 'Le pays',
|
||||
'Country migration' => 'Migration pays',
|
||||
'For USA and Canada the states already exists as countries, so you have to select the right state.' => 'Pour les USA et le Canada les états étaient déjà présents mais en tant que pays. Vous devrez donc choisir l\'état correspondant.',
|
||||
'For other countries, you should decide to use state or not. ' => 'Pour les autres pays, vous devrez choisir d\'utiliser ou pas les états.',
|
||||
'Home' => 'Accueil',
|
||||
'If you want to use the new country with its states, you have to check the migrate checkbox and select a state.' => 'Si vous voulez utiliser les nouveaux pays avec les états, vous devrez cocher la boîte à cocher \'migrer\' et sélectionner un état.',
|
||||
'In version 2.3 of Thelia, the system of country has changed.' => 'En version 2.3 de Thelia, le sysème des pays a changé.',
|
||||
'Migrate ?' => 'Migrer ?',
|
||||
'Migrate countries' => 'Migrer les pays',
|
||||
'New country' => 'Nouveau pays',
|
||||
'Now, countries has been splited in countries and states.' => 'Les pays ont été séparé en pays et états.',
|
||||
'Old country' => 'Ancien pays',
|
||||
'State' => 'État/région',
|
||||
'The migration proccess is tricky and couldn\'t be automated.' => 'Le processus de migration est compliqué et ne peux pas être automatisé',
|
||||
'The migration will change the address, tax rules and shipping zones to match with the new system.' => 'La migration changera les adresses, les règles de taxe et les zones de livraisons pour fonctionner avec le nouveau système.',
|
||||
'The update proccess has created new countries (even if it exists) and associated states.' => 'Le processus de mise à jour a créé de nouveaux pays (même si il existait) et associé des états.',
|
||||
'We added a \'default\' state with a blank name as a fallback. Customer will have the possibility to change it later.' => 'Nous avons ajouté un état par \'défaut\' avec un nom vide. Par la suite, le client pourra le changer.',
|
||||
];
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
' country ' => 'paese',
|
||||
' migrated to ' => ' migrato a ',
|
||||
' state ' => ' stato ',
|
||||
'All States' => 'Tutti gli Stati',
|
||||
'Configuration' => 'Impostazione',
|
||||
'Countries' => 'Paesi',
|
||||
'Country ' => 'Paese',
|
||||
'Country migration' => 'Migrazione del paese',
|
||||
'Home' => 'Home',
|
||||
'Migrate countries' => 'Migrazione dei paesi',
|
||||
'New country' => 'Nuovo paese',
|
||||
'Now, countries has been splited in countries and states.' => 'Ora, i paesi sono stati divisi in paesi e stati.',
|
||||
'State' => 'Stato',
|
||||
'The update proccess has created new countries (even if it exists) and associated states.' => 'Il processo di aggiornamento ha creato nuovi paesi (anche esistenti) e stati associati.',
|
||||
'We added a \'default\' state with a blank name as a fallback. Customer will have the possibility to change it later.' => 'Abbiamo aggiunto uno stato di \'default\' con un nome vuoto come fallback. Il cliente avrà la possibilità di modificarlo in seguito.',
|
||||
];
|
||||
8
local/modules/TheliaMigrateCountry/I18n/en_US.php
Normal file
8
local/modules/TheliaMigrateCountry/I18n/en_US.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'Country %id migrated to country (ID %country) and state (ID %state) (address: %address, tax rules: %tax, shipping zones: %zone)' => 'Country %id migrated to country (ID %country) and state (ID %state) (address: %address, tax rules: %tax, shipping zones: %zone)',
|
||||
'Country migration' => 'Country migration',
|
||||
'The state id \'%id\' does not belong to country id \'%id_country\'' => 'The state id \'%id\' does not belong to country id \'%id_country\'',
|
||||
'The state id \'%id\' doesn\'t exist' => 'The state id \'%id\' doesn\'t exist',
|
||||
);
|
||||
8
local/modules/TheliaMigrateCountry/I18n/fr_FR.php
Normal file
8
local/modules/TheliaMigrateCountry/I18n/fr_FR.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'Country %id migrated to country (ID %country) and state (ID %state) (address: %address, tax rules: %tax, shipping zones: %zone)' => 'Le pays %id migré vers le pays (ID %country) et état (ID %state) (adresses: %address, règles de taxe: %tax, zones de livraison: %zone)',
|
||||
'Country migration' => 'Migration pays',
|
||||
'The state id \'%id\' does not belong to country id \'%id_country\'' => 'L\'état id \'%id\' n\'appartient pas au pays id \'%id_country\'',
|
||||
'The state id \'%id\' doesn\'t exist' => 'L\'état id \'%id\' n\'existe pas',
|
||||
];
|
||||
8
local/modules/TheliaMigrateCountry/I18n/it_IT.php
Normal file
8
local/modules/TheliaMigrateCountry/I18n/it_IT.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'Country %id migrated to country (ID %country) and state (ID %state) (address: %address, tax rules: %tax, shipping zones: %zone)' => 'Paese %id migrato a paese (ID %country) e stato (ID %state) (Indirizzo: %address, norme fiscali: %tax, zone di spedizione: %zone)',
|
||||
'Country migration' => 'Migrazione del paese',
|
||||
'The state id \'%id\' does not belong to country id \'%id_country\'' => 'L\'id dello stato \'%id\' non appartiene a id paese \'%id_country\'',
|
||||
'The state id \'%id\' doesn\'t exist' => 'L\'id dello stato \'%id\' non esiste',
|
||||
];
|
||||
165
local/modules/TheliaMigrateCountry/LICENSE.txt
Normal file
165
local/modules/TheliaMigrateCountry/LICENSE.txt
Normal file
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
18
local/modules/TheliaMigrateCountry/Readme.md
Normal file
18
local/modules/TheliaMigrateCountry/Readme.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Thelia Migrate Country
|
||||
|
||||
This module allow you to migrate the system of country from Thelia version <= 2.2.* to version >= 2.3.0-alpha1.
|
||||
|
||||
## Installation
|
||||
|
||||
### Manually
|
||||
|
||||
* Copy the module into ```<thelia_root>/local/modules/``` directory and be sure that the name of the module is TheliaMigrateCountry.
|
||||
* Activate it in your thelia administration panel
|
||||
|
||||
### Composer
|
||||
|
||||
Add it in your main thelia composer.json file
|
||||
|
||||
```
|
||||
composer require your-vendor/thelia-migrate-country-module:~1.0
|
||||
```
|
||||
28
local/modules/TheliaMigrateCountry/TheliaMigrateCountry.php
Normal file
28
local/modules/TheliaMigrateCountry/TheliaMigrateCountry.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace TheliaMigrateCountry;
|
||||
|
||||
use Thelia\Module\BaseModule;
|
||||
|
||||
class TheliaMigrateCountry extends BaseModule
|
||||
{
|
||||
/** @var string */
|
||||
const DOMAIN_NAME = 'theliamigratecountry';
|
||||
|
||||
/*
|
||||
* You may now override BaseModuleInterface methods, such as:
|
||||
* install, destroy, preActivation, postActivation, preDeactivation, postDeactivation
|
||||
*
|
||||
* Have fun !
|
||||
*/
|
||||
}
|
||||
11
local/modules/TheliaMigrateCountry/composer.json
Normal file
11
local/modules/TheliaMigrateCountry/composer.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "thelia/thelia-migrate-country-module",
|
||||
"license": "LGPL-3.0+",
|
||||
"type": "thelia-module",
|
||||
"require": {
|
||||
"thelia/installer": "~1.1"
|
||||
},
|
||||
"extra": {
|
||||
"installer-name": "TheliaMigrateCountry"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{loop type="auth" name="pcc1" role="ADMIN" resource="admin.configuration.contry" access="VIEW"}
|
||||
<tr>
|
||||
<td><a href="{url path='/admin/configuration/countries/migrate'}">{intl l='Migrate countries'}</a></td>
|
||||
<td><a class="btn btn-default btn-xs" href="{url path='/admin/configuration/countries/migrate'}"><i class="glyphicon glyphicon-edit"></i></a></td>
|
||||
</tr>
|
||||
{/loop}
|
||||
@@ -0,0 +1,299 @@
|
||||
{extends file="admin-layout.tpl"}
|
||||
|
||||
{block name="no-return-functions"}
|
||||
{$admin_current_location = 'configuration'}
|
||||
{/block}
|
||||
|
||||
{block name="page-title"}{intl l='Country migration'}{/block}
|
||||
|
||||
{block name="check-resource"}admin.configuration.country{/block}
|
||||
{block name="check-access"}update{/block}
|
||||
|
||||
{block name="main-content"}
|
||||
<div class="countries migrate-country">
|
||||
|
||||
<div id="wrapper" class="container">
|
||||
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="{url path='/admin/home'}">{intl l="Home"}</a></li>
|
||||
<li><a href="{url path='/admin/configuration'}">{intl l="Configuration"}</a></li>
|
||||
<li><a href="{url path='/admin/configuration/countries'}">{intl l="Countries"}</a></li>
|
||||
<li>{intl l='Migrate countries'}</li>
|
||||
</ul>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 general-block-decorator">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12 title title-without-tabs">
|
||||
{intl l='Migrate countries'}
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="alert alert-info">
|
||||
{intl l='In version 2.3 of Thelia, the system of country has changed.'}
|
||||
{intl l='Now, countries has been split in countries and states.'}<br>
|
||||
{intl l="The migration process is tricky and couldn't be automated."}<br><br>
|
||||
{intl l="The update process has created new countries (even if it exists) and associated states."}<br>
|
||||
{intl l="The migration will change the address, tax rules and shipping zones to match with the new system."}<br>
|
||||
{intl l="After the migration the old country will be hide and the new one shown"}<br><br>
|
||||
{intl l="For USA and Canada the states already exists as countries, so you have to select the right state."}<br>
|
||||
{intl l="For other countries, you should decide to use state or not. "}
|
||||
{intl l="If you want to use the new country with its states, you have to check the migrate checkbox and select a state."}
|
||||
{intl l="We added a 'default' state with a blank name as a fallback. Customer will have the possibility to change it later."}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if $showForm}
|
||||
<div class="form-container">
|
||||
<div class="col-md-12">
|
||||
|
||||
{form name="thelia.admin.country.state.migration"}
|
||||
<form method="POST" action="{url path="/admin/configuration/countries/do-migrate"}" {form_enctype} class="clearfix">
|
||||
{include
|
||||
file = "includes/inner-form-toolbar.html"
|
||||
hide_submit_buttons = false
|
||||
|
||||
page_url = {url path="/admin/configuration/countries/migrate"}
|
||||
close_url = {url path="/admin/configuration/countries"}
|
||||
}
|
||||
|
||||
{form_hidden_fields exclude="locale"}
|
||||
|
||||
{render_form_field field='success_url' value={url path="/admin/configuration/countries/migrate"}}
|
||||
|
||||
{if $form_error}<div class="alert alert-danger">{$form_error_message}</div>{/if}
|
||||
|
||||
{if {hasflash type="migrate"}}
|
||||
<div class="alert alert-success">
|
||||
{flash type="migrate"}
|
||||
<div>{$MESSAGE}</div>
|
||||
{/flash}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="table-responsive table-migration">
|
||||
<table class="table table-striped table-condensed">
|
||||
<caption class="clearfix">
|
||||
{intl l='Countries to migrate'}
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><a href="#" id="toggle-migrate">{intl l="Migrate ?"}</a></th>
|
||||
<th>{intl l="Old country"}</th>
|
||||
<th>{intl l="New country"}</th>
|
||||
<th>{intl l="State"}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{form_collection form=$form collection="migrations"}
|
||||
{$newCountryId=0}
|
||||
{$countryId=0}
|
||||
<tr>
|
||||
<td>
|
||||
{form_collection_field form=$form row=$row field="migrate"}
|
||||
<input type="checkbox" name="{$name}" id="migrate_{$collection_current}" value="{$value}" />
|
||||
{/form_collection_field}
|
||||
</td>
|
||||
<td>
|
||||
{form_collection_field form=$form row=$row field="country"}
|
||||
{$countryId={$value}}
|
||||
<input type="hidden" name="{$name}" id="country_{$collection_current}" value="{$value}" />
|
||||
<span data-country="{$value}"></span>
|
||||
{/form_collection_field}
|
||||
</td>
|
||||
<td>
|
||||
{form_collection_field form=$form row=$row field="new_country"}
|
||||
{$newCountryId={$value}}
|
||||
<input type="hidden" name="{$name}" id="new_country_{$collection_current}" value="{$value}" />
|
||||
<span data-country="{$value}"></span>
|
||||
{/form_collection_field}
|
||||
</td>
|
||||
<td>
|
||||
{form_collection_field form=$form row=$row field="new_state"}
|
||||
{$ref[]={$label_attr.for}}
|
||||
<input type="hidden" name="{$name}" id="new_state_{$collection_current}" value="{$value}" />
|
||||
<select class="form-control states-select" data-new-country="{$newCountryId}" data-country="{$countryId}" data-rel="#new_state_{$collection_current}"></select>
|
||||
{/form_collection_field}
|
||||
</td>
|
||||
</tr>
|
||||
{/form_collection}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
{/form}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{else}
|
||||
<div class="col-md-12">
|
||||
{intl l="All countries have been migrated"}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{if count($countriesMigrated) > 0 }
|
||||
<div class="col-md-12 general-block-decorator countries-migrated">
|
||||
<div class="row">
|
||||
<div class="col-md-12 title title-without-tabs">
|
||||
{intl l='Countries migrated'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{foreach $countriesMigrated as $country => $new}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
{intl l='Country '} <strong><span class="text-info" data-country="{$country}"></span></strong>
|
||||
{intl l=' migrated to '}
|
||||
{intl l=' country '}
|
||||
<strong><span class="text-success" data-country="{$new.country}"></span></strong>
|
||||
{intl l=' state '}
|
||||
<strong><span class="text-success" data-state="{$new.state}"></span></strong>
|
||||
</div>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
{block name="javascript-initialization"}
|
||||
{javascripts file='assets/js/bootstrap-select/bootstrap-select.js'}
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
{javascripts file='assets/js/libs/underscore-min.js'}
|
||||
<script src="{$asset_url}"></script>
|
||||
{/javascripts}
|
||||
|
||||
<script id="tpl-select-states" type="text/html">
|
||||
<option value=""> </option>
|
||||
<% _.each(items, function(item) { %>
|
||||
<option value="<%= item.id %>" <% if (selected == item.id) { %>selected<% } %>><%- item.title %></option>
|
||||
<% }) %>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
|
||||
var countries = {render action='Thelia\Controller\Admin\CountryController::getDataAction' visible=0 lang='en_US'};
|
||||
var countriesById = {};
|
||||
var statesById = {};
|
||||
var migrate = false;
|
||||
|
||||
var i18n = {
|
||||
'configuration': '{intl l="Configuration"}'
|
||||
, 'states_all': '{intl l='All States'}'
|
||||
, 'countries': '{intl l="Countries"}'
|
||||
};
|
||||
|
||||
{literal}
|
||||
var tpl = {
|
||||
'select-states': _.template($("#tpl-select-states").html())
|
||||
};
|
||||
|
||||
|
||||
var initialize = function initialize() {
|
||||
var addList = [],
|
||||
addedList = [];
|
||||
|
||||
countriesById = _.indexBy(countries, 'id');
|
||||
_.each(
|
||||
countries,
|
||||
function (country) {
|
||||
if (country.hasStates) {
|
||||
_.extend(statesById, _.indexBy(country.states, 'id'));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Display countries title
|
||||
$('span[data-country]').each(function(){
|
||||
$(this).html(countriesById[$(this).data('country')].title);
|
||||
});
|
||||
|
||||
$('span[data-state]').each(function(){
|
||||
$(this).html(statesById[$(this).data('state')].title);
|
||||
});
|
||||
|
||||
// Build state select
|
||||
$('.states-select').each(function(){
|
||||
var $select = $(this),
|
||||
$rel = $($select.data("rel")),
|
||||
country,
|
||||
newCountry,
|
||||
stateId;
|
||||
|
||||
country = countriesById[$select.data('country')];
|
||||
newCountry = countriesById[$select.data('new-country')];
|
||||
|
||||
// fill the select
|
||||
stateId = $rel.val();
|
||||
if (!stateId) {
|
||||
stateId = findState(newCountry.states, country.title);
|
||||
if (stateId != null) {
|
||||
$rel.val(stateId);
|
||||
}
|
||||
}
|
||||
|
||||
$select.html(render('select-states', {'selected': stateId, 'items': newCountry.states}));
|
||||
$select.on("change", function() {
|
||||
$($select.data("rel")).val($select.val());
|
||||
});
|
||||
});
|
||||
|
||||
$('#toggle-migrate').on('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
migrate = !migrate;
|
||||
$('.table-migration').find('input[type=checkbox]').prop("checked", migrate);
|
||||
});
|
||||
};
|
||||
|
||||
var sanitize = function sanitize(value) {
|
||||
return ('' + value).toLowerCase().replace(/[a-z0-9]/, '');
|
||||
};
|
||||
|
||||
var findState = function findState(states, countryTitle) {
|
||||
var state;
|
||||
|
||||
countryTitle = sanitize(countryTitle);
|
||||
|
||||
state = _.find(states, function(item) {
|
||||
return (sanitize(countryTitle).indexOf(sanitize(item.title)) !== -1);
|
||||
});
|
||||
|
||||
if (state === undefined) {
|
||||
state = _.find(states, function(item) {
|
||||
return ('default'.indexOf(sanitize(item.title)) !== -1);
|
||||
});
|
||||
}
|
||||
|
||||
return (state === undefined) ? 0 : state.id;
|
||||
};
|
||||
|
||||
// Utils
|
||||
var render = function render(tplName, obj) {
|
||||
var data = $.extend({}, obj, {'i18n': i18n});
|
||||
return tpl[tplName](data);
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
initialize();
|
||||
});
|
||||
|
||||
{/literal}
|
||||
})(jQuery);
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
{block name="javascript-last-call"}
|
||||
{hook name="wysiwyg.js" location="wysiwyg-country-edit-js" }
|
||||
{/block}
|
||||
Reference in New Issue
Block a user