feat: selecteur : pour / cc / cci / repondre_a => on utilise maintenant

select2 ce qui permet de gérer une fichier pour l'autocomplete
This commit is contained in:
Christophe 2025-04-07 22:43:24 +02:00
parent 8415578c22
commit ffc6d5d849
6 changed files with 125 additions and 236 deletions

View file

@ -61,6 +61,17 @@ On peut ajouter des documents via un fichier du type : **gamumail/SLUG_fichier.h
- gamumail/SLUG_soustexte.html -> sous le contenu du mail, avant les pièces jointes
- gamumail/SLUG_fichiers.html -> à la fin du formulaire
On peut ajouter un fichier pour l'autocomplete des emails
- gamumail/SLUG_autocomplete_emails.html
- gamumail/autocomplete_emails.html
```html
<BOUCLE_allStagiaires(DATA){source table, #ENV{options/id_gf_session}|getStagiairesSession}>
<BOUCLE(CONDITION){si #VALEUR{email}|in_array{#ENV{t}}|non}>
<option value="#VALEUR{email}"> #VALEUR{nom} &nbsp; [(#VALEUR{prenom})&nbsp;] [&#60;(#VALEUR{email})&#62;] </option>
</BOUCLE>
</BOUCLE_allStagiaires>
```
### aide à la rédaction du contenu:
- le fichier **gamumail/remplacement_slugs.html** s'affiche en bas de la page de configuration des modèles **inclure/gamumail_config.html**
@ -327,15 +338,15 @@ $fonction(lire_config('souscriptions/slug_souscription_validation'), $Tdest, $op
```
## Slugs et @@ fournis pour surcharges facultatives de SPIP pour permettre l'envoi des mails en Gamumail plutôt que via notification
### slug `valider_inscription` :
- message pour la validation de l'adresse mail lors de la création d'un compte avec le form `inscription`
- à activer via une surcharge de `action_inscrire_auteur_dist()` : cf plugin **sq_collecte/sq_collecte_fonctions.php**
### slug `valider_inscription` :
- message pour la validation de l'adresse mail lors de la création d'un compte avec le form `inscription`
- à activer via une surcharge de `action_inscrire_auteur_dist()` : cf plugin **sq_collecte/sq_collecte_fonctions.php**
- pour intégrer la définition du mot de passe dès l'inscription (sans le plugin inscription_motdepasse) + d'autres contrôles de l'inscription :
- pour la saisie surcharge du HTML du form d'inscription : cf plugin **sq_collecte/formulaires/inscription.html**
- pour les contrôles il faut surcharger `formulaires_inscription_verifier_dist()` : cf plugin **sq_collecte/sq_collecte_fonctions.php**
### slug `pass_oubli`
- message pour le reset du mot de passe
- message pour le reset du mot de passe
- à activer via une surcharge de `formulaires_oubli_traiter_dist()`: cf plugin **rocb/rocb_options.php**

View file

@ -1,171 +1,14 @@
/* les styles de tag-editor */
.tag-editor {
list-style-type: none;
padding: 0 5px 0 0;
margin: 0;
overflow: hidden;
border: 1px solid #eee;
cursor: text;
font: normal 14px sans-serif;
color: #555;
background: #fff;
line-height: 20px;
width: 100%;
.select2-selection__choice__remove {
color: red!important;
font-weight: bold!important;
}
/* core styles usually need no change */
.tag-editor li {
display: block;
float: left;
overflow: hidden;
margin: 3px 0;
}
.select2-selection__choice {
font-size: 1.5rem;
.tag-editor div {
float: left;
padding: 0 4px;
}
.tag-editor .placeholder {
padding: 0 8px;
color: #bbb;
}
.tag-editor .tag-editor-spacer {
padding: 0;
width: 8px;
overflow: hidden;
color: transparent;
background: none;
}
.tag-editor input {
vertical-align: inherit;
border: 0;
outline: none;
padding: 0;
margin: 0;
cursor: text;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
font-style: inherit;
box-shadow: none;
background: none;
color: #444;
}
/* hide original input field or textarea visually to allow tab navigation */
.tag-editor-hidden-src {
position: absolute !important;
left: -99999px;
}
/* hide IE10 "clear field" X */
.tag-editor ::-ms-clear {
display: none;
}
/* tag style */
.tag-editor .tag-editor-tag {
/*padding-left: 5px; color: #46799b; background: #e0eaf1; white-space: nowrap;*/
/*overflow: hidden; cursor: pointer; border-radius: 2px 0 0 2px;*/
padding-left: 5px;
color: rgb(43, 43, 43);
background: rgb(210, 211, 211);
white-space: nowrap;
overflow: hidden;
cursor: pointer;
border-radius: 4px 0 0 4px;
}
/* delete icon */
/*.tag-editor .tag-editor-delete { background: #e0eaf1; cursor: pointer; border-radius: 0 2px 2px 0; padding-left: 3px; padding-right: 4px; }*/
.tag-editor .tag-editor-delete {
background: rgb(210, 211, 211);
cursor: pointer;
border-radius: 0 4px 4px 0;
padding-left: 3px;
padding-right: 4px;
}
.tag-editor .tag-editor-delete i {
line-height: 18px;
display: inline-block;
}
/*.tag-editor .tag-editor-delete i:before { font-size: 16px; color: #8ba7ba; content: "×"; font-style: normal; }*/
.tag-editor .tag-editor-delete i:before {
font-size: 16px;
color: rgba(200, 37, 37, 1);
content: '×';
font-style: normal;
}
.tag-editor .tag-editor-delete:hover i:before {
color: #d65454;
}
.tag-editor .tag-editor-tag.active+.tag-editor-delete,
.tag-editor .tag-editor-tag.active+.tag-editor-delete i {
visibility: hidden;
cursor: text;
}
.tag-editor .tag-editor-tag.active {
background: none !important;
}
/* jQuery UI autocomplete - code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css */
.ui-autocomplete {
position: absolute;
top: 0;
left: 0;
cursor: default;
font-size: 14px;
}
.ui-front {
z-index: 9999;
}
.ui-menu {
list-style: none;
padding: 1px;
margin: 0;
display: block;
outline: none;
}
.ui-menu .ui-menu-item a {
text-decoration: none;
display: block;
padding: 2px 0.4em;
line-height: 1.4;
min-height: 0;
/* support: IE7 */
}
.ui-widget-content {
border: 1px solid #bbb;
background: #fff;
color: #555;
}
.ui-widget-content a {
color: #46799b;
}
.ui-widget-content .ui-state-hover,
.ui-widget-header .ui-state-hover,
.ui-state-focus,
.ui-widget-content .ui-state-focus,
.ui-widget-header .ui-state-focus {
background: #e0eaf1;
}
.ui-helper-hidden-accessible {
display: none;
.select2-container--default .select2-results > .select2-results__options {
max-height: initial;
}
/* les styles de gamumails */

View file

@ -1,4 +1,19 @@
#CACHE{0}
#SET{fichier_autocomplete_email, ''}
[(#CHEMIN{gamumail/autocomplete_email.html}|oui)
#SET{fichier_autocomplete_email,autocomplete_email}
]
#SET{f,#SLUG|concat{_autocomplete_email}}
[(#CHEMIN{gamumail/#GET{f}.html}|oui)
#SET{fichier_autocomplete_email,#GET{f}}
]
<style>
.select2-container--default .select2-results__option[aria-selected="true"] {
display: none;
}
</style>
<link rel="stylesheet" href="[(#CHEMIN{css/gamumail.css}|timestamp)]" type="text/css" media="screen" charset="utf-8" />
@ -24,15 +39,20 @@
<INCLURE{fond=gamumail/#GET{fichier},env,lang=#GET{lang_dest}}>
]
<div class="editer_groupe">
#SET{name,pour}
#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
#SET{obli,"obligatoire"}
<div class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
#SET{erreurs,#ENV**{erreurs}|table_valeur{pour}}
[(#SET{mailsOk,#ENV{pour}|gamumailExtraireMails})]
[<span class="erreur_message">(#GET{erreurs})</span>]
<div class="editer_pour">
<label for="#GET{name}">Pour</label>
[<span class="erreur_message">(#GET{erreurs})</span>]
<input required type="text" class="text tagEditor" name="#GET{name}" id="#GET{name}" value="#ENV{#GET{name}}" >
<select id="pour" class="select2" name="pour[]" multiple data-sort-alpha="true" data-tags="true" >
#INCLURE{fond=formulaires/inc_charger_mails,champ=pour,t=#ENV{pour}}
[(#GET{fichier_autocomplete_email}|oui)
[(#INCLURE{fond=gamumail/#GET{fichier_autocomplete_email},env,champ=pour,t=#GET{mailsOk}})]
]
</select>
</div>
</div>
<BOUCLE_testEnvoiSepare(CONDITION){si #ENV{envoi_separe}|oui}>
<div class="editer_groupe">
#SET{name,envoi_separe}
@ -52,39 +72,46 @@
</div>
</BOUCLE_testEnvoiSepare>
<div class="editer_groupe">
#SET{name,cc}
#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
#SET{obli,"obligatoire"}
<div class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
#SET{erreurs,#ENV**{erreurs}|table_valeur{cc}}
[(#SET{mailsOk,#ENV{cc}|gamumailExtraireMails})]
[<span class="erreur_message">(#GET{erreurs})</span>]
<div class="editer_cc">
<label for="#GET{name}">Cc</label>
[<span class="erreur_message">(#GET{erreurs})</span>]
<input type="text" class="text mail_cc tagEditor" name="#GET{name}" id="#GET{name}" value="#ENV{#GET{name}}" >
<select id="cc" class="select2" name="cc[]" multiple data-sort-alpha="true" data-tags="true" >
#INCLURE{fond=formulaires/inc_charger_mails,champ=cc,t=#ENV{cc}}
[(#GET{fichier_autocomplete_email}|oui)
[(#INCLURE{fond=gamumail/#GET{fichier_autocomplete_email},env,champ=cc,t=#GET{mailsOk}})]
]
</select>
</div>
</div>
<div class="editer_groupe">
#SET{name,cci}
#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
#SET{obli,"obligatoire"}
<div class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
#SET{erreurs,#ENV**{erreurs}|table_valeur{cci}}
[(#SET{mailsOk,#ENV{cci}|gamumailExtraireMails})]
[<span class="erreur_message">(#GET{erreurs})</span>]
<div class="editer_cci">
<label for="#GET{name}">Cci</label>
[<span class="erreur_message">(#GET{erreurs})</span>]
<input type="text" class="text mail_cci tagEditor" name="#GET{name}" id="#GET{name}" value="#ENV{#GET{name}}" >
<select id="cci" class="select2" name="cci[]" multiple data-sort-alpha="true" data-tags="true" >
#INCLURE{fond=formulaires/inc_charger_mails,champ=cci,t=#ENV{cci}}
[(#GET{fichier_autocomplete_email}|oui)
[(#INCLURE{fond=gamumail/#GET{fichier_autocomplete_email},env,champ=cci,t=#GET{mailsOk}})]
]
</select>
</div>
</div>
<BOUCLE_testRepondreA(CONDITION){si #ENV{repondre_a}}>
<div class="editer_groupe">
#SET{name,repondre_a}
#SET{erreurs,#ENV**{erreurs}|table_valeur{#GET{name}}}
#SET{obli,"obligatoire"}
<div class="editer editer_[(#GET{name})][ (#GET{obli})][ (#GET{erreurs}|oui)erreur]">
<label for="#GET{name}">Répondre à</label>
[<span class="erreur_message">(#GET{erreurs})</span>]
<input type="text" class="text mail_repondre_a tagEditor" name="#GET{name}" id="#GET{name}" value="#ENV{#GET{name}}" >
</div>
[(#SET{erreurs,#ENV**{erreurs}|table_valeur{repondre_a}})]
[<span class="erreur_message">(#GET{erreurs})</span>]
<div class="editer_repondre_a">
<label for="#GET{name}">Répondre à</label>
<select id="repondre_a" class="select2" name="repondre_a[]" multiple data-sort-alpha="true" data-tags="true" >
#INCLURE{fond=formulaires/inc_charger_mails,champ=repondre_a,t=#ENV{repondre_a}}
</select>
</div>
</div>
</BOUCLE_testRepondreA>
@ -167,23 +194,8 @@
<div class="boutons text-center">
<button type="submit" class="btn"><:gamumail:envoyer:></button>
</div>
</div></form>
</div>
<script src="[(#CHEMIN{js/jquery.tag-editor.min.js}|timestamp)]" type="text/javascript"></script>
<script src="[(#CHEMIN{js/jquery.caret.min.js}|timestamp)]" type="text/javascript"></script>
<script type="text/javascript">
jQuery(function() {
gamumail();
//onAjaxLoad(gamumail);
function gamumail(){
var navigateur = navigator.platform.toUpperCase().slice(0, 3);
if (navigateur !== "MAC") {
$(".tagEditor").tagEditor({
delimiter: ',; '
});
}
}
});
</script>

View file

@ -25,10 +25,14 @@ include_spip('inc/filtres');
function formulaires_gamumail_charger_dist($slug, $destinataires = 0, $Tclient = [], $Tpdf = [], $redirect = '', $options = []){
$Tmails = [];
$Tcc = lire_config('gamumail/mail_cc') !== '' ? explode(',', lire_config('gamumail/mail_cc', '')) : [];
$Tcci = lire_config('gamumail/mail_cci') !== '' ? explode(',', lire_config('gamumail/mail_cci', '')) : [];
$Tcc = !empty(lire_config('gamumail/mail_cc')) ? explode(',', lire_config('gamumail/mail_cc', '')) : [];
$Tcc = count($Tcc) ? array_map('arrayMails', $Tcc) : [];
$Trepondre_a = lire_config('gamumail/mail_repondre_a') !== '' ? explode(',', lire_config('gamumail/mail_repondre_a', '')) : [];
$Tcci = !empty(lire_config('gamumail/mail_cci')) ? explode(',', lire_config('gamumail/mail_cci', '')) : [];
$Tcci = count($Tcci) ? array_map('arrayMails', $Tcci) : [];
$Trepondre_a = !empty(lire_config('gamumail/mail_repondre_a')) ? explode(',', lire_config('gamumail/mail_repondre_a', '')) : [];
$Trepondre_a = count($Trepondre_a) ? array_map('arrayMails', $Trepondre_a) : [];
if (!empty($destinataires) and !is_array($destinataires)) {
$destinataires = explode(',', $destinataires);
@ -38,12 +42,14 @@ function formulaires_gamumail_charger_dist($slug, $destinataires = 0, $Tclient =
foreach ($destinataires as $dest) {
if (is_numeric($dest)) {
if ($mail = sql_getfetsel('email', 'spip_auteurs', 'id_auteur='.$dest)) {
$Tmails[] = $mail;
if ($tM = sql_fetsel('*', 'spip_auteurs', 'id_auteur='.$dest)) {
$Tmails[] = [
'email' => $tM['email'],
'texte' => $tM['nom'] . ' ' . ($tM['prenom'] ?? '') . ' ' . '&#60;' . $tM['email'] . '&#62;',
];
}
}
elseif (email_valide($dest)) {
$Tmails[] = $dest;
} elseif (email_valide($dest)) {
$Tmails[] = ['email' => $dest];
}
}
@ -58,9 +64,9 @@ function formulaires_gamumail_charger_dist($slug, $destinataires = 0, $Tclient =
$copie = (isset($o['copie']) and in_array($o['copie'], ['cc', 'cci'])) ? $o['copie'] : false;
if (email_valide($mail)) {
if (!$copie) {
$Tmails[] = $mail;
$Tmails[] = ['email' => $mail];
} else {
$copie == 'cc' ? $Tcc[] = $mail : $Tcci[] = $mail;
$copie == 'cc' ? $Tcc[] = ['email' => $mail] : $Tcci[] = ['email' => $mail];
}
}
}
@ -101,10 +107,10 @@ function formulaires_gamumail_charger_dist($slug, $destinataires = 0, $Tclient =
"slug" => $slug,
'sujet' => $sujet,
'texte' => $texte,
'pour' => implode(',', $Tmails),
'cc' => implode(',', $Tcc),
'cci' => implode(',', $Tcci),
'repondre_a' => implode(',', $Trepondre_a),
'pour' => $Tmails,
'cc' => $Tcc,
'cci' => $Tcci,
'repondre_a' => $Trepondre_a,
'TFichierpdfs' => $TFichierPdf,
'Tpdfs_ok' => [],
'docs_spip' => $gamuMail['id_docs'] ?? '',
@ -130,8 +136,13 @@ function formulaires_gamumail_charger_dist($slug, $destinataires = 0, $Tclient =
function formulaires_gamumail_verifier_dist($slug, $destinataires = 0, $Tclient = [], $Tpdf = [], $redirect = '', $options = []) :Array{
$erreurs = array();
//champs obligatoire
foreach (array('pour', 'sujet', 'texte') as $obligatoire) {
$pour = _request("pour") ?? [];
if (!count($pour)) {
$erreurs['pour'] = 'Ce champs est obligatoire';
}
foreach (array('sujet', 'texte') as $obligatoire) {
if (!_request($obligatoire)) $erreurs[$obligatoire] = 'Ce champs est obligatoire';
}
@ -150,7 +161,6 @@ function formulaires_gamumail_verifier_dist($slug, $destinataires = 0, $Tclient
// vérif des destinataires
$Tid_erreur = $Tmails_erreur = [];
$pour = explode(',', _request('pour'));
foreach ($pour as $dest) {
if (is_numeric($dest)) {
if (!$mail = sql_getfetsel('email', 'spip_auteurs', 'id_auteur='.$dest)) {
@ -165,7 +175,7 @@ function formulaires_gamumail_verifier_dist($slug, $destinataires = 0, $Tclient
$erreurs['pour'] = _T("gamumail:id_destinataires_sans_mails", ['ids_erreur' => join(', ', $Tid_erreur)]).' ';
}
if (count($Tmails_erreur)) {
$erreurs['pour'] .= _T("gamumail:mails_destinataires_en_erreur", ['mails_erreur' => join(', ', $Tmails_erreur)]);
$erreurs['pour'] = $erreurs['pour'] ?? '' . _T("gamumail:mails_destinataires_en_erreur", ['mails_erreur' => join(', ', $Tmails_erreur)]);
}
// les id_document attachés sont-ils OK ?
@ -247,8 +257,7 @@ function formulaires_gamumail_traiter_dist($slug, $destinataires = 0, $Tclient =
$envoi_separe = _request('envoi_separe') ?? '';
$options['envoi_separe'] = $envoi_separe;
$pour = _request('pour');
$pour = explode(',', $pour);
$pour = _request('pour') ?? [];
$destinataires = [];
foreach ($pour as $dest) {
@ -303,15 +312,15 @@ function formulaires_gamumail_traiter_dist($slug, $destinataires = 0, $Tclient =
function gamuSend($slug, $options, $destinataires, $Tclient, $Tpdf, $Tfiles, $redirect, &$retour = []) {
$cc = _request('cc') ?? '';
$cci = _request('cci') ?? '';
$repondre_a = _request('repondre_a') ?? '';
$cc = _request('cc') ?? [];
$cci = _request('cci') ?? [];
$repondre_a = _request('repondre_a') ?? [];
$cc = explode(',', $cc);
$cci = explode(',', $cci);
// $cc = explode(',', $cc);
// $cci = explode(',', $cci);
$Tcci_gamuza = $GLOBALS['gamuza_mail_cci'] ?? [];
$cci = array_merge($cci, $Tcci_gamuza);
$repondre_a = explode(',', $repondre_a);
// $repondre_a = explode(',', $repondre_a);
$sujet = _request('sujet');
$html = propre(_request('texte'));
@ -576,3 +585,7 @@ function gamuSend($slug, $options, $destinataires, $Tclient, $Tpdf, $Tfiles, $re
return $ok;
}
function arrayMails(string $t):array {
return ['email' => trim($t)];
}

View file

@ -0,0 +1,3 @@
<BOUCLE(DATA){source tableau, #ENV{t}}>
<option value="[(#VALEUR{email}|sinon{#VALEUR})]" selected>[(#VALEUR{texte}|sinon{#VALEUR{email}}|sinon{#VALEUR})]</option>
</BOUCLE>

View file

@ -113,3 +113,10 @@ function gamumail_remplacer_modele($modele, $val, $texte){
function afficher_remplacements() {
return $GLOBALS['remplacements_gamumail'];
}
function gamumailExtraireMails($t):array {
if (empty($t)) {
return [];
}
return array_map(fn($d) => $d['email'] ?? $d, $t);
}