Logo de Béjean Développement

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();
    }
}