Construire un formulaire de souscription pour Acymailing avec Fabrik
Pour plusieurs raisons, on souhaite parfois personnaliser au maximum le formulaire de souscription d'un outil newsletter. Ici un exemple simplifié avec l'extension Acymailing.
À noter qu'une documentation Acymailing existe permettant d'utiliser des liens de souscription à intégrer dans Fabrik (ICI). Mais ce n'est pas ainsi que nous procéderons ci-dessous, où nous préfèrererons créer nos propres checkboxs pour gérer les souscriptions.
Avant toute chose, appelez votre table #_acymailing_subscriber dans Fabrik, et interdisez la modification des types de champs (dans les paramètres de la liste, Advanced).
Commencez ensuite la construction de votre formulaire classiquement. Enfin, adaptez les codes suivants :
Concaténation du champ name
Parfois vous souhaitez afficher des champs de type lastname et firstname. Mais c'est le champ name d'Acymailing qui sera utilisé dans les newsletters. Gérez-le comme voulu (concaténation, casse...).
Faîtes en un champ calc, caché, puis par exemple :
return '{#_acymailing_subscriber___firstname}'.' '.'{#_acymailing_subscriber___lastname}' ;
Gestion des champs date en timestamp Unix
En effet Acymailing utilise le format de date Unix timestamp. Or Fabrik n'implémente pas nativement ce format. Il faudra donc le gérer en PHP et SQL.
Dans la table #_acymailing_subscriber, dans le champ created, caché, en Default value et Eval mode :
return time() ;
Le champ date de la table #_acymailing_listsub sera rempli dans le plugin de formulaire suivant, via la fonction UNIX_TIMESTAMP()
.
Inscription à des listes liées à un bouton checkbox
Ici un exemple où nous ne permettons le choix qu'entre 2 listes, facilement adaptable à vos besoins.
Il va falloir créer un champ Fabrik de type checkbox, qui va prendre en compte le choix de l'utilisateur. Ici ce champ est appelé lists, et pour une meilleure compéhension, nous utiliserons ses labels dans le code ci-dessous, et nous ajoutons les id respectifs dans les labels (My list ID 3, etc...).
Ce champ lists sera nécessaire uniquement pour la 1ère souscription de l'abonné. En effet pendant la soumission du formulaire, le code va répercuter les choix de l'utilisateur dans la table #_acymailing_listsub (et là par contre, ce sont les id des listes concernées qui sont utilisés dans le code, vous devez donc les connaitre et les adapter dans les requêtes SQL du code).
Ce code est fait pour un champ lists placé dans la table #_acymailing_subscriber (plus simple à faire et à expliquer), mais des commentaires permettent de l'adapter pour utiliser une table jointe (ce qui sera bien plus orienté base de données relationnelles, conseillé !).
Les 2 premières conditions elseif
gèrent les cas où l'utilisateur a choisi une seule des listes disponibles à la saisie. Le dernier elseif
celui où l'utilisateur choisit les 2 listes.
Dans un formulaire pointant en table principale sur #_acymailing_subscriber, avec un champ subid en tant qu'internal id, dans un plugin de formulaire donc, en mode End of form submission :
// Recover subid created $My_Subid = $formModel->formData['#_acymailing_subscriber___subid'] ; // Recover lists choosen in chekbox field $My_List = $data['#_acymailing_subscriber___lists'] ; // Implode if data comes from an array (joined table), comment/uncomment if necessary // $My_List = implode(',', $My_List); if ($My_List === "My list ID 3") { //Query 1 defined('_JEXEC') or die('Restricted access'); $db = FabrikWorker::getDBO(false, 1); $query = " INSERT INTO #_acymailing_listsub (subid, listid, status, subdate) VALUES ('$My_Subid', '3', '1', UNIX_TIMESTAMP()) " ; $db->setQuery($query); $db->query(); } elseif ($My_List === "My list ID 6") { //Query 2 defined('_JEXEC') or die('Restricted access'); $db = FabrikWorker::getDBO(false, 1); $query = " INSERT INTO #_acymailing_listsub (subid, listid, status, subdate) VALUES ('$My_Subid', '6', '1', UNIX_TIMESTAMP()) " ; $db->setQuery($query); $db->query(); } // Last elseif if data does not come from an array elseif ($My_List === "<ul><li>My list ID 3</li><li>My list ID 6</li></ul>") // Or if data comes from an array // elseif ($My_List === "My list ID 3,My list ID 6") { //Query 3 defined('_JEXEC') or die('Restricted access'); $db = FabrikWorker::getDBO(false, 1); $query = " INSERT INTO #_acymailing_listsub (subid, listid, status, subdate) VALUES ('$My_Subid', '3', '1', UNIX_TIMESTAMP()), ('$My_Subid', '6', '1', UNIX_TIMESTAMP()) " ; $db->setQuery($query); $db->query(); }; // var_dump($My_List); // exit;
Champ key
Attention : le 12/10/2018 le support Acymailing me confirme que la gestion de ce champ est inutile au moment de la création d'un nouvel abonné. En effet ce champ sera automatiquement généré au moment de l'envoi d'un 1er email. Je laisse toutefois le code ci-dessous en cas de changement ou si besoin.
Le champ key est indispensable pour le bon fonctionnement d'Acymailing (les désinscriptions et views on line notamment, les balises, etc...), il doit contenir une chaîne randomisée unique de 14 caractères (du moins unique pour tout humain unique, de ce que je comprends, car j'ai observé des mises-à-jour étonnantes sur ce champ, où Acy reliait des adresses emails à la même personne, et correctement ! Bref).
Dans un champ classique, caché bien sûr, en Default value et Eval mode. Modifiez uniquement le nom de la table :
$myDb = FabrikWorker::getDbo(false, 1); $myQuery = $myDb->getQuery(true); $oops = 0; do { // these 3 lines are just here to prevent locking up your web server in an infinite loop doing database lookups // if I made a mistake in the code, you can remove them once it's working if ($oops++ > 10) { return "Something went wrong!"; } $myString = substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,14))),1,14); // replace 'yourfield' with this element's name, and 'yourtable' with this form's table name $myQuery->select('COUNT(*) AS foo') ->from('#_acymailing_subscriber') ->where('#_acymailing_subscriber.key = ' . $myDb->quote($myString)); $myDb->setQuery($myQuery); //var_dump((string)$myQuery);exit; try { $myResult = $myDb->loadResult(); } catch (Exception $e) { //$this->app->enqueueMessage($e->getMessage()); return 'Something went wrong!'; } } while (!empty($myResult)); return $myString;