Envoyer des données clients vers une API externe
Objectif
Envoyer à une API externe des données géographiques d'un client
Pré-requis
Pour mettre en place le test, vous devez disposer d'une installation de Magento
Tutoriel
Le projet Git de cet article est disponible sur Froggit, lien vers le dépôt.
Création du module
Je vous invite à télécharger le modèle de base pour la création du module, dans le but de gagner du temps, Pensez à bien renommer Master
en Customer
.
Dans le fichier etc/module.xml
, il faut indiquer que notre module doit s'initialiser après le module Magento_Customer
. Voici le contenu du fichier etc/module.xml
:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="NicolasBejean_Customer" setup_version="1.2.0">
<sequence>
<module name="Magento_Customer"/>
</sequence>
</module>
</config>
Création du plugin
Un plugin est une classe qui modifie le comportement des fonctions publiques d'une classe. Il est possible d'exécuter des instructions avant, après ou autour d'une fonction.
Pour nous permettre d'envoyer les données clients à une API externe, nous allons exécuter une instruction après l'enregistrement de l'adresse dans la base de données.
Pour créer notre plugin, il est nécessaire de le déclarer dans le fichier etc/di.xml
du module. Le fichier doit contenir ceci :
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Customer\Model\Address">
<plugin name="NicolasBejeanModelAddress" type="NicolasBejean\Customer\Plugin\ModelAddress" sortOrder="1" disabled="false" />
</type>
</config>
Ci-dessus, nous définissons la classe PHP Magento\Customer\Model\Address
. Cette dernière se verra associer notre plugin NicolasBejeanModelAddress
qui correspond à la classe PHP où se trouvera notre instruction nous permettant d'instancier l'Helper NicolasBejean\Customer\Helper\SendGeoLocation.php
qui lui transmettra les données souhaitées à l'API.
Voici le contenu de notre fichier ModelAddress.php
:
<?php
namespace NicolasBejean\Customer\Plugin;
use NicolasBejean\Customer\Helper\SendGeoLocation;
/**
* Class ModelAddress
*
* @category PHP
* @package NicolasBejean\Customer\Plugin
* @author Nicolas Béjean <[email protected]>
* @license https://lab.frogg.it/bejean-developpement/magento-2/modules/customer/-/blob/master/LICENCE GPL3 Licence
* @link https://www.bejean.eu
*/
class ModelAddress
{
/**
* @var SendGeoLocation
*/
private SendGeoLocation $helper;
/**
* ModelAddress constructor.
*
* @param SendGeoLocation $helper
*/
public function __construct(
SendGeoLocation $helper
) {
$this->helper = $helper;
}
/**
* @param \Magento\Customer\Model\Address $subject
*/
public function afterSave(\Magento\Customer\Model\Address $subject)
{
$customer = $subject->getCustomer();
$this->helper->sendDataToApi($customer, $subject);
}
}
Je vous invite à lancer les commandes bin/magento setup:upgrade && bin/magento setup:di:compile
pour installer le module et déclarer notre plugin.
Si vous n'avez pas d'erreur, vous pouvez passer à la suite.
Création de l'Helper
Pour terminer, nous allons créer un Helper qui transmettra les données souhaitées. Dans l'exemple ci-dessous, nous récupérons, dans la fonction sendDataToApi
, plusieurs données, j'ai choisi les identifiants du client, du site, du pays ainsi que la ville et le code postal.
Pour faciliter la lecture des données, j'ai créé 2 fonctions qui permettent de récupérer le nom du site et du pays en fonction de leurs identifiants.
Une fois les données rassemblées, je peux transmettre le tableau de données à l'API.
<?php
namespace NicolasBejean\Customer\Helper;
use Magento\Customer\Model\Address;
use Magento\Customer\Model\Customer;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Api\WebsiteRepositoryInterface;
use Magento\Directory\Api\CountryInformationAcquirerInterface;
/**
* Class SendGeoLocation
*
* @category PHP
* @package NicolasBejean\Customer\Helper
* @author Nicolas Béjean <[email protected]>
* @license https://lab.frogg.it/bejean-developpement/magento-2/modules/customer/-/blob/master/LICENCE GPL3 Licence
* @link https://www.bejean.eu
*/
class SendGeoLocation extends AbstractHelper
{
/**
* @var WebsiteRepositoryInterface
*/
private WebsiteRepositoryInterface $websiteRepositoryInterface;
/**
* @var CountryInformationAcquirerInterface
*/
private CountryInformationAcquirerInterface $countryInformationAcquirerInterface;
/**
* SendGeoLocation constructor.
* @param Context $context
* @param WebsiteRepositoryInterface $websiteRepositoryInterface
* @param CountryInformationAcquirerInterface $countryInformationAcquirerInterface
*/
public function __construct(
Context $context,
WebsiteRepositoryInterface $websiteRepositoryInterface,
CountryInformationAcquirerInterface $countryInformationAcquirerInterface
) {
$this->websiteRepositoryInterface = $websiteRepositoryInterface;
$this->countryInformationAcquirerInterface = $countryInformationAcquirerInterface;
parent::__construct($context);
}
public function sendDataToApi(Customer $customer, Address $address)
{
$customerId = $customer->getId();
$websiteId = $customer->getWebsiteId();
$countryId = $address->getCountryId();
$city = $address->getCity();
$postCode = $address->getPostcode();
$websiteName = $this->getWebsiteNameFromId($websiteId);
$countryName = $this->getCountryNameFromId($countryId);
$data = array(
'customerId' => $customerId,
'websiteName' => $websiteName,
'countryName' => $countryName,
'postCode' => $postCode,
'city' => $city
);
/* Instructions */
}
/**
* @param int $websiteId
* @return string
*/
private function getWebsiteNameFromId (int $websiteId): string
{
try {
$website = $this->websiteRepositoryInterface->getById($websiteId);
} catch (NoSuchEntityException $e) {
return '';
}
return $website->getName();
}
/**
* @param string $countryId
* @return string
*/
private function getCountryNameFromId (string $countryId): string
{
try {
$country = $this->countryInformationAcquirerInterface->getCountryInfo($countryId);
} catch (NoSuchEntityException $e) {
return '';
}
return $country->getFullNameLocale();
}
}