Malheureusement, les observateurs ne sont utiles que dans les fonctions php. Cela signifie que pour qu'un événement soit déclenché, il doit être initialement distribué dispatch()
par un répartiteur d'événements natif ou personnalisé. Dans ce cas particulier, l'action entreprise est un clic sur un bouton de mode de paiement. Ce clic ne déclenche aucune exécution de code php, seul le code Javascript est exécuté.
Comme le processus de paiement dans Magento 2 est principalement construit autour de Knockout JS, la plupart des actions se produisent sur le frontend en utilisant Javascript au lieu du php côté serveur.
Knockout JS est très flexible et il est possible de lier des événements et d'observer des variables. De l'autre côté, cela peut nécessiter une courbe d'apprentissage abrupte.
Un bon angle à considérer pour votre projet serait d'utiliser un contrôleur au lieu d'un observateur:
1. Commençons par créer un module ...
2. Créez un contrôleur qui fait votre logique lorsqu'il est déclenché
Structure du contrôleur: http://www.example.com/route/controller_folder/action
2.1 Créez la Action
classe de contrôleur :
app / code / NameSpace / Module / Controller / Test / Action.php
namespace NameSpace\Module\Controller\Test;
class Action extends \Magento\Framework\App\Action\Action
{
public function execute()
{
$request = $this->getRequest();
//EXECUTE YOUR LOGIC HERE
}
}
2.2 Enregistrer un itinéraire pour vos contrôleurs
app / code / NameSpace / Module / etc / adminhtml / routes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="route" frontName="route">
<module name="NameSpace_Module" />
</route>
</router>
</config>
2.3 Comme cela sera utilisé lors du paiement, ajoutez votre itinéraire à la liste des URL sécurisées [MODIFIER]
app / code / NameSpace / Module / etc / di.xml
<?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\Framework\Url\SecurityInfo">
<arguments>
<argument name="secureUrlList" xsi:type="array">
<item name="route" xsi:type="string">/route/</item>
</argument>
</arguments>
</type>
</config>
3. Ajoutez un fichier javascript sur la page de paiement à l'aide du fichier de mise en page suivant:
app / code / NameSpace / Module / view / frontend / layout / checkout_index_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<head>
<link src="NameSpace_Module::js/payment-method-trigger.js"/>
</head>
</page>
4. Dans ce script, vous pouvez simplement ajouter une fonction pour envoyer une demande de publication ajax chaque fois qu'un onglet de mode de paiement est cliqué.
Meilleure méthode - Knockout: abonnement à observable
La meilleure façon de déclencher l'événement de clic sans étendre / remplacer le fichier de base ou sans impact sur la fonction de clic d'origine consisterait à souscrire un observable à l'aide de Knockout.
Méthode 2 - Étendre la classe JS [EDIT]
Il devrait également y avoir un moyen d'étendre la classe JS initiale
define([
'NameSpace_Module/path/to/original/file', //JS FILE TO EXTEND
], function (originalFile) { //PASS AS A PARAMETER
'use strict';
return originalFile.extend({ //EXTEND
//FUNCTIONS ADDED HERE WILL OVERRIDE FUNCTIONS
//FROM ORIGINAL CLASS IF ALREADY EXISTS
someFunction: {
someLogic();
},
});
});
Méthode 3 - Remplacer select-payment-method.js
Jouer avec Knockout JS peut parfois être délicat et dans le cadre de cette réponse, nous remplacerons simplement la fonction responsable de l'enregistrement du mode de paiement dans le devis qui est déclenché par la fonction selectPaymentMethod. Ce n'est peut-être pas la solution la plus élégante par rapport à l'utilisation de 100% Knockout JS, mais cela devrait fonctionner comme prévu sans affecter aucune fonctionnalité, à moins qu'une future mise à jour de Magento n'interfère en modifiant la fonction d'origine.
Pour mieux comprendre, vous pouvez trouver la fonction selectPaymentMethod
à la ligne 139 de ce fichier:
Magento_Checkout / js / view / payment / default.js
1. Maintenant, nous devons déclarer le remplacement de notre fonction:
app / code / NameSpace / Module / view / frontend / requirejs-config.js
var config = {
map: {
'*': {
'Magento_Checkout/js/action/select-payment-method':
'NameSpace_Module/js/action/payment/select-payment-method'
}
}
};
2. Enfin, nous réutilisons la fonction de sélection du mode de paiement avec un petit plus pour effectuer notre appel ajax!
app / code / NameSpace / Module / view / frontend / web / js / action / payment / select-payment-method.js
define(
[
'jquery',
'uiComponent',
'ko',
'Magento_Checkout/js/model/quote',
], function ($, uiComponent, ko, quote) {
'use strict';
function () {
$.ajax({
showLoader: true,
url: 'http://www.example.com/route/controller_folder/action',
data: { action : 1, param : 2},
type: "POST",
dataType: 'json'
}).done(function (data) {
alert('Request Sent');
});
};
return function (paymentMethod) {
quote.paymentMethod(paymentMethod);
}
});
Chaque fois qu'un client cliquera sur un onglet de méthode de paiement, votre méthode Javascript enverra une requête post ajax à votre contrôleur qui exécutera le code php avec votre logique.
Cela touche plusieurs aspects différents de Magento 2. Bien que j'aimerais fournir une solution rapide et facile à votre question, c'est juste la façon dont Magento 2 a été construit. Désormais, une grande partie de la logique est implémentée côté client et encore plus à l'approche du système de caisse.
N'oubliez pas de toujours être prudent lorsque vous traitez avec le système de paiement, un bogue sur une page de paiement peut faire très mal à un magasin.
REMARQUE: tout le code ci-dessus n'est pas testé