0012f46229b9823096c1cfb569635641fcc6e57d
[lhc/web/www.git] / www / ecrire / inc / notifications.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2017 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 /**
14 * Gestion des notifications
15 *
16 * @package SPIP\Core\Notifications
17 **/
18 if (!defined('_ECRIRE_INC_VERSION')) {
19 return;
20 }
21
22
23 /**
24 * La fonction de notification de base, qui dispatche le travail
25 *
26 * @api
27 * @param string $quoi
28 * Événement de notification
29 * @param int $id
30 * id de l'objet en relation avec l'événement
31 * @param array $options
32 * Options de notification, interprétées en fonction de la notification
33 */
34 function inc_notifications_dist($quoi, $id = 0, $options = array()) {
35
36 // charger les fichiers qui veulent ajouter des definitions
37 // ou faire des trucs aussi dans le pipeline, ca fait deux api pour le prix d'une ...
38 pipeline('notifications', array('args' => array('quoi' => $quoi, 'id' => $id, 'options' => $options)));
39
40 if ($notification = charger_fonction($quoi, 'notifications', true)) {
41 spip_log("$notification($quoi,$id"
42 . ($options ? "," . serialize($options) : "")
43 . ")", 'notifications');
44 $notification($quoi, $id, $options);
45 }
46 }
47
48 /**
49 * Néttoyage des emails avant un envoi
50 *
51 * On passe par référence pour la perf
52 *
53 * les emails liste par $exclure seront exclus de la liste
54 *
55 * @param array $emails
56 * @param array $exclure
57 */
58 function notifications_nettoyer_emails(&$emails, $exclure = array()) {
59 // filtrer et unifier
60 $emails = array_unique(array_filter(array_map('email_valide', array_map('trim', $emails))));
61 if ($exclure and count($exclure)) {
62 // nettoyer les exclusions d'abord
63 notifications_nettoyer_emails($exclure);
64 // faire un diff
65 $emails = array_diff($emails, $exclure);
66 }
67 }
68
69 /**
70 * Envoyer un email de notification
71 *
72 * Le sujet peut être vide, dans ce cas il reprendra la première ligne non vide du texte
73 *
74 * @param array|string $emails
75 * @param string $texte
76 * @param string $sujet
77 * @param string $from
78 * @param string $headers
79 */
80 function notifications_envoyer_mails($emails, $texte, $sujet = "", $from = "", $headers = "") {
81 // rien a faire si pas de texte !
82 if (!strlen($texte)) {
83 return;
84 }
85
86 // si on ne specifie qu'un email, le mettre dans un tableau
87 if (!is_array($emails)) {
88 $emails = explode(',', $emails);
89 }
90
91 notifications_nettoyer_emails($emails);
92
93 // tester si le mail est deja en html
94 if (strpos($texte, "<") !== false // eviter les tests suivants si possible
95 and $ttrim = trim($texte)
96 and substr($ttrim, 0, 1) == "<"
97 and substr($ttrim, -1, 1) == ">"
98 and stripos($ttrim, "</html>") !== false
99 ) {
100
101 if (!strlen($sujet)) {
102 // dans ce cas on ruse un peu : extraire le sujet du title
103 if (preg_match(",<title>(.*)</title>,Uims", $texte, $m)) {
104 $sujet = $m[1];
105 } else {
106 // fallback, on prend le body si on le trouve
107 if (preg_match(",<body[^>]*>(.*)</body>,Uims", $texte, $m)) {
108 $ttrim = $m[1];
109 }
110
111 // et on extrait la premiere ligne de vrai texte...
112 // nettoyer le html et les retours chariots
113 $ttrim = textebrut($ttrim);
114 $ttrim = str_replace("\r\n", "\r", $ttrim);
115 $ttrim = str_replace("\r", "\n", $ttrim);
116 // decouper
117 $ttrim = explode("\n", trim($ttrim));
118 // extraire la premiere ligne de texte brut
119 $sujet = array_shift($ttrim);
120 }
121 }
122
123 // si besoin on ajoute le content-type dans les headers
124 if (stripos($headers, "Content-Type") === false) {
125 $headers .= "Content-Type: text/html\n";
126 }
127 }
128
129 // si le sujet est vide, extraire la premiere ligne du corps
130 // du mail qui est donc du texte
131 if (!strlen($sujet)) {
132 // nettoyer un peu les retours chariots
133 $texte = str_replace("\r\n", "\r", $texte);
134 $texte = str_replace("\r", "\n", $texte);
135 // decouper
136 $texte = explode("\n", trim($texte));
137 // extraire la premiere ligne
138 $sujet = array_shift($texte);
139 $texte = trim(implode("\n", $texte));
140 }
141
142 $envoyer_mail = charger_fonction('envoyer_mail', 'inc');
143 foreach ($emails as $email) {
144 // passer dans un pipeline qui permet un ajout eventuel
145 // (url de suivi des notifications par exemple)
146 $envoi = pipeline('notifications_envoyer_mails', array('email' => $email, 'sujet' => $sujet, 'texte' => $texte));
147 $email = $envoi['email'];
148
149 job_queue_add('envoyer_mail', ">$email : " . $envoi['sujet'],
150 array($email, $envoi['sujet'], $envoi['texte'], $from, $headers), 'inc/');
151 }
152
153 }
154
155 /**
156 * Notifier un événement sur un objet
157 *
158 * Récupère le fond désigné dans $modele,
159 * prend la première ligne comme sujet
160 * et l'interprète pour envoyer l'email
161 *
162 * @param int $id_objet
163 * @param string $type_objet
164 * @param string $modele
165 * @return string
166 */
167 function email_notification_objet($id_objet, $type_objet, $modele) {
168 $envoyer_mail = charger_fonction('envoyer_mail', 'inc'); // pour nettoyer_titre_email
169 $id_type = id_table_objet($type_objet);
170
171 return recuperer_fond($modele, array($id_type => $id_objet, "id" => $id_objet));
172 }
173
174 /**
175 * Notifier un événement sur un article
176 *
177 * Récupère le fond désigné dans $modele,
178 * prend la première ligne comme sujet
179 * et l'interprète pour envoyer l'email
180 *
181 * @param int $id_article
182 * @param string $modele
183 * @return string
184 */
185 function email_notification_article($id_article, $modele) {
186 $envoyer_mail = charger_fonction('envoyer_mail', 'inc'); // pour nettoyer_titre_email
187
188 return recuperer_fond($modele, array('id_article' => $id_article));
189 }
190
191 /**
192 * Notifier la publication d'un article
193 *
194 * @deprecated Ne plus utiliser
195 * @param int $id_article
196 **/
197 function notifier_publication_article($id_article) {
198 if ($GLOBALS['meta']["suivi_edito"] == "oui") {
199 $adresse_suivi = $GLOBALS['meta']["adresse_suivi"];
200 $texte = email_notification_article($id_article, "notifications/article_publie");
201 notifications_envoyer_mails($adresse_suivi, $texte);
202 }
203 }
204
205 /**
206 * Notifier la proposition d'un article
207 *
208 * @deprecated Ne plus utiliser
209 * @param int $id_article
210 **/
211 function notifier_proposition_article($id_article) {
212 if ($GLOBALS['meta']["suivi_edito"] == "oui") {
213 $adresse_suivi = $GLOBALS['meta']["adresse_suivi"];
214 $texte = email_notification_article($id_article, "notifications/article_propose");
215 notifications_envoyer_mails($adresse_suivi, $texte);
216 }
217 }