[04/09/2024] Installation du module ForcePhone pour rendre le téléphone obligatoire à la création du compte.

This commit is contained in:
2024-09-04 21:46:00 +02:00
parent 38fbe0533e
commit 5a79db3015
22 changed files with 1063 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
# 1.2.1
- check if phones are not empty before formatting
- save cell phones on international format too
- remove forget log warning
# 1.2
- fix missing form '.thelia_customer_update'
- add check phones format (enable/disable it in config)
- save phones on international format

View File

@@ -0,0 +1,70 @@
<?php
namespace ForcePhone\Command;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Thelia\Command\ContainerAwareCommand;
use Thelia\Log\Tlog;
use Thelia\Model\Base\AddressQuery;
use Thelia\Model\Customer;
class UpdatePhoneNumberCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName("module:ForcePhone:update")
->setDescription("Update phone number of all addresses");
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->initRequest();
$addresses = AddressQuery::create()->find();
foreach ($addresses as $address){
if ($phone = $address->getPhone()){
$phone = $this->updatePhone($phone, $address->getCountry()->getIsoalpha2(), $address->getCustomer(), $output);
if ($phone !== null){
$address
->setPhone($phone)
->save();
}
}
if ($cellphone = $address->getCellphone()){
$cellphone = $this->updatePhone($cellphone, $address->getCountry()->getIsoalpha2(), $address->getCustomer(), $output);
if ($cellphone !== null) {
$address
->setCellphone($cellphone)
->save();
}
}
}
$output->writeln('Success');
}
protected function updatePhone($phoneNumber, $isoalpha2, Customer $customer, OutputInterface $output)
{
$phoneUtil = PhoneNumberUtil::getInstance();
try {
$phoneNumberProto = $phoneUtil->parse($phoneNumber, $isoalpha2);
}catch (\Exception $e){
Tlog::getInstance()->error('Phone number '.$phoneNumber.' for customer '.$customer->getRef().' is invalid');
$output->writeln('Error : Phone number '.$phoneNumber.' for customer '.$customer->getRef().' is invalid');
return null;
}
if ($phoneUtil->isValidNumber($phoneNumberProto)) {
return $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
}
return $phoneNumber;
}
}

View File

@@ -0,0 +1,28 @@
<?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="forcephone_configuration" class="ForcePhone\Form\ConfigForm" />
</forms>
<commands>
<command class="ForcePhone\Command\UpdatePhoneNumberCommand" />
</commands>
<hooks>
<hook id="forcephone.configuration.hook" class="ForcePhone\Hook\HookManager" scope="request">
<tag name="hook.event_listener" event="module.configuration" type="back" method="onModuleConfigure" />
</hook>
</hooks>
<services>
<service id="forcephone.services" class="ForcePhone\EventListeners\ForcePhoneEventListener" scope="request">
<argument id="request" type="service"/>
<tag name="kernel.event_subscriber"/>
</service>
</services>
</config>

View File

@@ -0,0 +1,32 @@
<?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>ForcePhone\ForcePhone</fullnamespace>
<descriptive locale="en_US">
<title>Require the customer to enter its home phone number, mobile phone number or both</title>
</descriptive>
<descriptive locale="fr_FR">
<title>Oblige le client à laisser un numéro de téléphone fixe, mobile ou les deux</title>
</descriptive>
<languages>
<language>en_US</language>
<language>fr_FR</language>
</languages>
<version>1.2.5</version>
<authors>
<author>
<name>Etienne Perriere</name>
<email>eperriere@openstudio.fr</email>
</author>
<author>
<name>Franck Allimant</name>
<company>CQFDev</company>
<email>franck@cqfdev.fr</email>
<website>www.cqfdev.fr</website>
</author>
</authors>
<type>classic</type>
<thelia>2.1.0</thelia>
<stability>beta</stability>
</module>

View File

@@ -0,0 +1,18 @@
<?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="forcephone.config" path="/admin/module/forcephone/configure" methods="post">
<default key="_controller">ForcePhone\Controller\ConfigureController::configure</default>
</route>
<route id="forcephone.check_order_phone" path="/forcephone/check/order-phone/{orderId}" methods="get">
<default key="_controller">ForcePhone\Controller\ApiController::checkPhoneOrder</default>
</route>
<route id="forcephone.reformat_phone" path="/forcephone/format-phone/{phone}/{countryId}" methods="get">
<default key="_controller">ForcePhone\Controller\ApiController::reformatPhoneNumber</default>
</route>
</routes>

View File

@@ -0,0 +1,19 @@
<?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 ForcePhone\Constraints;
use Symfony\Component\Validator\Constraint;
class AtLeastOnePhone extends Constraint
{
}

View File

@@ -0,0 +1,41 @@
<?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 ForcePhone\Constraints;
use ForcePhone\ForcePhone;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Thelia\Core\Translation\Translator;
class AtLeastOnePhoneValidator extends ConstraintValidator
{
/**
* Checks if at least one phone number is provided
*
* @param mixed $value The value that should be validated
* @param Constraint $constraint The constraint for the validation
*
* @api
*/
public function validate($value, Constraint $constraint)
{
$data = $this->context->getRoot()->getData();
if (empty($data["phone"]) && empty($data["cellphone"])) {
$this->context->addViolationAt(
"phone",
Translator::getInstance()->trans("Please enter at least one phone number.", [], ForcePhone::DOMAIN_NAME)
);
}
}
}

View File

@@ -0,0 +1,19 @@
<?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 ForcePhone\Constraints;
use Symfony\Component\Validator\Constraint;
class CheckPhoneFormat extends Constraint
{
}

View File

@@ -0,0 +1,71 @@
<?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 ForcePhone\Constraints;
use ForcePhone\ForcePhone;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Thelia\Core\Translation\Translator;
use Thelia\Log\Tlog;
use Thelia\Model\CountryQuery;
class CheckPhoneFormatValidator extends ConstraintValidator
{
/**
* Checks if phone format correspond on country
*
* @param mixed $value The value that should be validated
* @param Constraint $constraint The constraint for the validation
*
* @api
*/
public function validate($value, Constraint $constraint)
{
$data = $this->context->getRoot()->getData();
if (!empty($value)) {
try {
if (!isset($data['country']) || empty($data['country'])) {
throw new \Exception('No country ID for checking phone format');
}
$country = CountryQuery::create()->findOneById($data['country']);
if (!$country) {
throw new \Exception('Country not found for checking phone format');
}
$phoneUtil = PhoneNumberUtil::getInstance();
$phoneNumberProto = $phoneUtil->parse($value, $country->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
} catch (\Exception $exception) {
$isValid = false;
Tlog::getInstance()->warning($exception->getMessage());
}
if (!$isValid) {
$this->context->addViolation(
Translator::getInstance()->trans(
'Please enter a valid phone number',
[],
ForcePhone::DOMAIN_NAME
)
);
}
}
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace ForcePhone\Controller;
use ForcePhone\ForcePhone;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\HttpFoundation\JsonResponse;
use Thelia\Model\CountryQuery;
use Thelia\Model\OrderQuery;
class ApiController extends BaseFrontController
{
public function checkPhoneOrder($orderId)
{
$order = OrderQuery::create()->filterById($orderId)->findOne();
if (null === $order) {
return new JsonResponse('Order not found', 400);
}
$phoneUtil = PhoneNumberUtil::getInstance();
$address = $order->getOrderAddressRelatedByDeliveryOrderAddressId();
if (!empty($address->getPhone())) {
$phoneNumberProto = $phoneUtil->parse($address->getPhone(), $address->getCountry()->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if (!$isValid) {
return new JsonResponse('Wrong phone number', 400);
}
}
if (!empty($address->getCellphone())) {
$phoneNumberProto = $phoneUtil->parse($address->getCellphone(), $address->getCountry()->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if (!$isValid) {
return new JsonResponse('Wrong cellphone number', 400);
}
}
if (
ForcePhone::getConfigValue('force_one', false) &&
empty($address->getCellphone()) && empty($address->getPhone())
) {
return new JsonResponse('No phone number found', 400);
}
return new JsonResponse('Success', 200);
}
public function reformatPhoneNumber($phone, $countryId)
{
$phoneUtil = PhoneNumberUtil::getInstance();
$country = CountryQuery::create()->filterById($countryId)->findOne();
if (!$country){
return new JsonResponse('Invalid country id', 400);
}
$phoneNumberProto = $phoneUtil->parse($phone, $country->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if (!$isValid) {
return new JsonResponse('Invalid phone number', 400);
}
$phone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
return new JsonResponse($phone, 200);
}
}

View File

@@ -0,0 +1,87 @@
<?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 ForcePhone\Controller;
use ForcePhone\ForcePhone;
use Thelia\Controller\Admin\BaseAdminController;
use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Core\Thelia;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Tools\URL;
use Thelia\Tools\Version\Version;
class ConfigureController extends BaseAdminController
{
public function configure()
{
if (null !== $response = $this->checkAuth(AdminResources::MODULE, 'forcephone', AccessManager::UPDATE)) {
return $response;
}
$configurationForm = $this->createForm('forcephone_configuration');
$message = null;
try {
$form = $this->validateForm($configurationForm);
// Get the form field values
$data = $form->getData();
foreach ($data as $name => $value) {
if (is_array($value)) {
$value = implode(';', $value);
}
ForcePhone::setConfigValue($name, $value);
}
// Log configuration modification
$this->adminLogAppend(
"forcephone.configuration.message",
AccessManager::UPDATE,
"ForcePhone configuration updated"
);
// Redirect to the success URL,
if ($this->getRequest()->get('save_mode') == 'stay') {
// If we have to stay on the same page, redisplay the configuration page/
$url = '/admin/module/ForcePhone';
} else {
// If we have to close the page, go back to the module back-office page.
$url = '/admin/modules';
}
return $this->generateRedirect(URL::getInstance()->absoluteUrl($url));
} catch (FormValidationException $ex) {
$message = $this->createStandardFormValidationErrorMessage($ex);
} catch (\Exception $ex) {
$message = $ex->getMessage();
}
$this->setupFormErrorContext(
$this->getTranslator()->trans("ForcePhone configuration", [], ForcePhone::DOMAIN_NAME),
$message,
$configurationForm,
$ex
);
// Before 2.2, the errored form is not stored in session
if (Version::test(Thelia::THELIA_VERSION, '2.2', false, "<")) {
return $this->render('module-configure', [ 'module_code' => 'ForcePhone' ]);
} else {
return $this->generateRedirect(URL::getInstance()->absoluteUrl('/admin/module/ForcePhone'));
}
}
}

View File

@@ -0,0 +1,271 @@
<?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 ForcePhone\EventListeners;
use ForcePhone\Constraints\AtLeastOnePhone;
use ForcePhone\Constraints\CheckPhoneFormat;
use ForcePhone\ForcePhone;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use OpenApi\Events\ModelValidationEvent;
use OpenApi\Model\Api\Address;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Core\Event\Address\AddressEvent;
use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Event\TheliaFormEvent;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Translation\Translator;
use Thelia\Log\Tlog;
use Thelia\Model\CountryQuery;
use function Complex\add;
/**
* Class ForcePhoneEventListener
* @package ForcePhone\EventListeners
* @author Etienne Perriere <eperriere@openstudio.fr>
*/
class ForcePhoneEventListener implements EventSubscriberInterface
{
protected $request;
/**
* ForcePhoneEventListener constructor.
* @param Request $request
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
TheliaEvents::FORM_AFTER_BUILD . '.thelia_customer_create' => ['forcePhoneInput', 128],
TheliaEvents::FORM_AFTER_BUILD . '.thelia_customer_update' => ['forcePhoneInput', 128],
TheliaEvents::FORM_AFTER_BUILD . '.thelia_address_update' => ['forcePhoneInput', 128],
TheliaEvents::FORM_AFTER_BUILD . '.thelia_address_creation' => ['forcePhoneInput', 128],
TheliaEvents::AFTER_CREATECUSTOMER => ['customerPhoneUpdate', 125],
TheliaEvents::AFTER_UPDATECUSTOMER => ['customerPhoneUpdate', 125],
TheliaEvents::BEFORE_UPDATEADDRESS => ['addressPhoneUpdate', 125],
TheliaEvents::BEFORE_CREATEADDRESS => ['addressPhoneUpdate', 125],
'open_api_model_validation_address' => ['validateOpenApiAddress', 125]
];
}
/**
* @param TheliaFormEvent $event
*/
public function forcePhoneInput(TheliaFormEvent $event)
{
if ($this->request->fromApi() === false) {
$constraints = [];
if (ForcePhone::getConfigValue('force_one', false)) {
$constraints[] = new AtLeastOnePhone();
}
$validateFormat = ForcePhone::getConfigValue('validate_format', false);
if ($validateFormat) {
$constraints[] = new CheckPhoneFormat();
}
$forcePhone = ForcePhone::getConfigValue('force_phone', false);
if (!empty($constraints) || $forcePhone) {
$event->getForm()->getFormBuilder()
->remove('phone')
->add(
'phone',
'text',
[
'constraints' => $forcePhone ? array_merge([new NotBlank()], $constraints) : $constraints,
'label' => Translator::getInstance()->trans('Phone'),
'label_attr' => ['for' => 'phone'],
'required' => $forcePhone,
]
);
}
$forceCellPhone = ForcePhone::getConfigValue('force_cellphone', false);
if (!empty($constraints) || $forceCellPhone) {
$event->getForm()->getFormBuilder()
->remove('cellphone')
->add(
'cellphone',
'text',
[
'constraints' => $forceCellPhone ? array_merge([new NotBlank()], $constraints) : $constraints,
'label' => Translator::getInstance()->trans('Cellphone'),
'label_attr' => ['for' => 'cellphone'],
'required' => $forceCellPhone,
]
);
}
}
}
/**
* @param AddressEvent $addressEvent
*/
public function addressPhoneUpdate(AddressEvent $addressEvent)
{
$validateFormat = ForcePhone::getConfigValue('validate_format', false);
if ($this->request->fromApi() === false && $validateFormat) {
$address = $addressEvent->getAddress();
try {
$phoneUtil = PhoneNumberUtil::getInstance();
if (!empty($address->getPhone())) {
$phoneNumberProto = $phoneUtil->parse($address->getPhone(), $address->getCountry()->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if ($isValid) {
$phone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
$address->setPhone($phone);
}
}
if (!empty($address->getCellphone())) {
$phoneNumberProto = $phoneUtil->parse($address->getCellphone(), $address->getCountry()->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if ($isValid) {
$phone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
$address->setCellphone($phone);
}
}
} catch (\Exception $exception) {
Tlog::getInstance()->warning('Error on update phone format');
}
}
}
/**
* @param CustomerEvent $customerEvent
*/
public function customerPhoneUpdate(CustomerEvent $customerEvent)
{
$validateFormat = ForcePhone::getConfigValue('validate_format', false);
if ($this->request->fromApi() === false && $validateFormat) {
$address = $customerEvent->getCustomer()->getDefaultAddress();
try {
$phoneUtil = PhoneNumberUtil::getInstance();
if (!empty($address->getPhone())) {
$phoneNumberProto = $phoneUtil->parse($address->getPhone(), $address->getCountry()->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if ($isValid) {
$phone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
$address->setPhone($phone)->save();
}
}
if (!empty($address->getCellphone())) {
$phoneNumberProto = $phoneUtil->parse($address->getCellphone(), $address->getCountry()->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if ($isValid) {
$phone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
$address->setCellphone($phone)->save();
}
}
} catch (\Exception $exception) {
Tlog::getInstance()->warning('Error on update phone format');
}
}
}
public function validateOpenApiAddress(ModelValidationEvent $event)
{
if ($event->getGroups() === 'read' ) {
return;
}
/** @var Address $address */
$address = $event->getModel();
$country = CountryQuery::create()->filterById($address->getCountryId())->findOne();
$violations = $event->getViolations();
$phoneUtil = PhoneNumberUtil::getInstance();
if (!empty($address->getPhone())) {
try {
$phoneNumberProto = $phoneUtil->parse($address->getPhone(), $country->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if (!$isValid) {
throw new \Exception('Invalid phone number');
}
$phone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
$address->setPhone($phone);
}catch (\Exception $exception){
$message = Translator::getInstance()->trans(
'Please enter a valid phone number',
[],
ForcePhone::DOMAIN_NAME
);
$violations['phoneNumber'] = $event->getModelFactory()->buildModel('SchemaViolation', ['message' => $message]);
}
}
if (!empty($address->getCellphone())) {
try {
$phoneNumberProto = $phoneUtil->parse($address->getCellphone(), $country->getIsoalpha2());
$isValid = $phoneUtil->isValidNumber($phoneNumberProto);
if (!$isValid) {
throw new \Exception('Invalid cellphone number');
}
$cellphone = $phoneUtil->format($phoneNumberProto, PhoneNumberFormat::INTERNATIONAL);
$address->setCellphone($cellphone);
}catch (\Exception $exception){
$message = Translator::getInstance()->trans(
'Please enter a valid phone number',
[],
ForcePhone::DOMAIN_NAME
);
$violations['cellphoneNumber'] = $event->getModelFactory()->buildModel('SchemaViolation', ['message' => $message]);
}
}
$event->setModel($address);
$event->setViolations($violations);
}
}

View File

@@ -0,0 +1,36 @@
<?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 ForcePhone;
use Propel\Runtime\Connection\ConnectionInterface;
use Thelia\Module\BaseModule;
/**
* Class ForcePhone
* @package ForcePhone
* @author Etienne Perriere <eperriere@openstudio.fr>
*/
class ForcePhone extends BaseModule
{
/** @var string */
const DOMAIN_NAME = 'forcephone';
public function postActivation(ConnectionInterface $con = null)
{
// Define default values
if (null === self::getConfigValue('force_phone', null)) {
self::setConfigValue('force_phone', 1);
}
}
}

View File

@@ -0,0 +1,78 @@
<?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 ForcePhone\Form;
use ForcePhone\ForcePhone;
use Symfony\Component\Validator\Constraints\NotBlank;
use Thelia\Form\BaseForm;
class ConfigForm extends BaseForm
{
protected function buildForm()
{
$this->formBuilder
->add(
'force_phone',
'checkbox',
[
'required' => false,
'label' => $this->translator->trans('Home phone number', [], ForcePhone::DOMAIN_NAME),
'label_attr' => [
'for' => 'force_phone',
]
]
)
->add(
'force_cellphone',
'checkbox',
[
'required' => false,
'label' => $this->translator->trans('Mobile phone number', [], ForcePhone::DOMAIN_NAME),
'label_attr' => [
'for' => 'force_cellphone',
]
]
)
->add(
'force_one',
'checkbox',
[
'required' => false,
'label' => $this->translator->trans('At least one phone number', [], ForcePhone::DOMAIN_NAME),
'label_attr' => [
'for' => 'force_one',
]
]
)
->add(
'validate_format',
'checkbox',
[
'required' => false,
'label' => $this->translator->trans('Check phone numbers format', [], ForcePhone::DOMAIN_NAME),
'label_attr' => [
'for' => 'validate_format',
]
]
)
;
}
/**
* @return string the name of you form. This name must be unique
*/
public function getName()
{
return 'forcephone_config';
}
}

View File

@@ -0,0 +1,49 @@
<?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 ForcePhone\Hook;
use ForcePhone\ForcePhone;
use Thelia\Core\Event\Hook\HookRenderEvent;
use Thelia\Core\Hook\BaseHook;
use Thelia\Model\ModuleConfig;
use Thelia\Model\ModuleConfigQuery;
class HookManager extends BaseHook
{
public function onModuleConfigure(HookRenderEvent $event)
{
$vars = [];
if (null !== $params = ModuleConfigQuery::create()->findByModuleId(ForcePhone::getModuleId())) {
/** @var ModuleConfig $param */
foreach ($params as $param) {
$vars[ $param->getName() ] = $param->getValue();
}
}
$event->add(
$this->render('force-phone/module-configuration.html', $vars)
);
}
}

View File

@@ -0,0 +1,6 @@
<?php
return array(
'Force Phone Configuration' => 'Force Phone Configuration',
'Please check below the phone numbers that must be mandatory in the customer and addresses forms' => 'Please check below the phone numbers that will be required in the customer and address forms',
);

View File

@@ -0,0 +1,6 @@
<?php
return array(
'Force Phone Configuration' => 'Configuration de Force Phone',
'Please check below the phone numbers that must be mandatory in the customer and addresses forms' => 'Merci de cocher ci-dessous les numéros de téléphones qui doivent être obligatoirement saisis dans les formulaires client et addresse',
);

View File

@@ -0,0 +1,14 @@
<?php
return array(
'At least one phone number' => 'At least one phone number',
'Cellphone' => 'Cellphone',
'ForcePhone configuration' => 'ForcePhone configuration',
'Home phone number' => 'Home phone number',
'Mobile phone number' => 'Mobile phone number',
'Phone' => 'Phone',
'Please enter a home or mobile phone number' => 'Please enter a home or mobile phone number',
'Please enter at least one phone number.' => 'Please enter at least one phone number.',
'Check phone numbers format' => 'Check phone numbers format',
'Please enter a valid phone number' => 'Please enter a valid phone number',
);

View File

@@ -0,0 +1,14 @@
<?php
return array(
'At least one phone number' => 'Au moins un des deux',
'Cellphone' => 'Téléphone mobile',
'ForcePhone configuration' => 'Configuration de Force Phone',
'Home phone number' => 'Numéro de téléphone fixe',
'Mobile phone number' => 'Numéro de téléphone mobile',
'Phone' => 'Téléphone fixe',
'Please enter a home or mobile phone number' => 'Merci d\'indiquer un numéro de téléphone fixe ou mobile',
'Please enter at least one phone number.' => 'Merci d\'indiquer au moins un numéro de téléphone',
'Check phone numbers format' => 'Vérifier le format de la saisie du téléphone',
'Please enter a valid phone number' => 'Merci d\'indiquer un numéro de téléphone valide',
);

View File

@@ -0,0 +1,40 @@
# Force Phone
This module sets the mobile phone number, the home phone number, both or one of them as required in the customer and address forms.
## Installation
**Since 1.2 need to be installed by Composer**
### Composer
Add it in your main Thelia composer.json file
```
composer require thelia/force-phone-module:~1.2
```
### Manually (only for version < 1.2)
* Copy the module into ```<thelia_root>/local/modules/``` directory and be sure that the name of the module is ForcePhone.
* Activate it in your Thelia administration panel
## Usage
Activate the module and the home phone number becomes required in the customer and address forms.
Go to module configuration to select which phone numbers (home, mobile, both or one of them) should be required.
Affected pages :
- register
- create address
- update address
## Other
Be sure to set proper translations for phone inputs' labels.
You can find translation for the mandatory input in your administration panel:
` Configuration --> Translation --> Modules --> Set the phone input mandatory for the customer --> Core files `
Translation for the second phone input is in:
` Configuration --> Translation --> Thelia core `

View File

@@ -0,0 +1,12 @@
{
"name": "thelia/force-phone-module",
"license": "LGPL-3.0+",
"type": "thelia-module",
"require": {
"thelia/installer": "~1.1",
"giggsey/libphonenumber-for-php": "^8.10"
},
"extra": {
"installer-name": "ForcePhone"
}
}

View File

@@ -0,0 +1,60 @@
<div class="row">
<div class="col-md-12 general-block-decorator">
<div class="row">
<div class="col-md-12 title title-without-tabs">
{intl d='forcephone.bo.default' l="Force Phone Configuration"}
</div>
</div>
<div class="form-container">
<div class="row">
<div class="col-md-12">
{form name="forcephone_configuration"}
<form action="{url path="/admin/module/forcephone/configure"}" method="post">
{form_hidden_fields form=$form}
{include file = "includes/inner-form-toolbar.html"
hide_flags = true
page_url = "{url path='/admin/module/ForcePhone'}"
close_url = "{url path='/admin/modules'}"
}
{if $form_error}
<div class="row">
<div class="col-md-12">
<div class="alert alert-danger">{$form_error_message}</div>
</div>
</div>
{/if}
<div class="row">
<div class="col-md-12">
<p>{intl d='forcephone.bo.default' l='Please check below the phone numbers that must be mandatory in the customer and addresses forms'}</p>
{custom_render_form_field form=$form field="force_phone"}
<input type="checkbox" {form_field_attributes form=$form field="force_phone"} {if $force_phone}checked{/if}>
{$label}
{/custom_render_form_field}
{custom_render_form_field form=$form field="force_cellphone"}
<input type="checkbox" {form_field_attributes form=$form field="force_cellphone"} {if $force_cellphone}checked{/if}>
{$label}
{/custom_render_form_field}
{custom_render_form_field form=$form field="force_one"}
<input type="checkbox" {form_field_attributes form=$form field="force_one"} {if $force_one}checked{/if}>
{$label}
{/custom_render_form_field}
{custom_render_form_field form=$form field="validate_format"}
<input type="checkbox" {form_field_attributes form=$form field="validate_format"} {if $validate_format}checked{/if}>
{$label}
{/custom_render_form_field}
</div>
</div>
</form>
{/form}
</div>
</div>
</div>
</div>
</div>