source: spip-zone/_plugins_/newsletters/action/generer_newsletter.php @ 68158

Last change on this file since 68158 was 68158, checked in by cedric@…, 8 years ago

v0.1-dev du plugin Newsletters

Gestion d'un objet editorial d'infolettre
Une infolettre se compose d'un titre, chapo, texte, d'une selection d'article, et se base sur un modele

Les modeles sont les squelettes disponibles dans les dossiers newsletters/ du path
Le squelette produit la version html_email. Le titre du modele (pour l'interface) est deduit par extraction du commentaire <!-- tire=... --> du squelette (comme faisait cfg, mais sans evaluation)
Si une version .texte.html du squelette existe, elle est utilisee pour generer la version texte_email. Sinon on produit automatiquement une version texte par nettoyage (mix de ce que fait spip-listes, de regles de nettoyage pour le balisage de mise en page, et utilisation de markdownify pour produire du texte au format MarkDown? pour l'editorial)
Si une version .page.html du squelette existe, elle est utilisee pour generer la version html_page affichee dans la version en ligne. Sinon c'est la version html_email qui est utilisee. Dans tous les cas les css supplementaires css/newsletter_inline.css sont ajoutees a la page visualisee dans la navigateur.

Le plugin est fourni avec un gabarit "basic.html" en une colonne, responsive, qui s'adapte sur les smartphones et se degrade bien en texte automatiquement.

Dans le workflow par defaut on edite jamais manuellement les versions html&texte finales mais uniquement le contenu editorial (titre, chapo, texte, selection, modeles)
Les version html&texte sont alors generees a chaque modif editoriale et lors de la previsu.
En previsu on peut voir les 3 versions (html_email, texte_email et html_page).
On peut editer aux crayons le contenu editorial dans la version html_email (mais il faut repasser sur la lettre et la preview pour re-generer, a ameliorer)

A tout moment, il est possible de passer en edition avancee de la Newsletter. On a alors acces uniquement aux champs html_email, texte_email et html_page qui permettent de controler le rendu precis final.
Ce mode edition avancee est reserve aux utilisateurs avertis. Il rend possible la creation d'une Newsletter par simple copie/colle d'un gabarit html prepare dans un autre outil.
Une fois passe en edition avancee, la Newsletter n'est jamais regeneree, et on n'a plus acces aux contenus edito (sauf le titre)
Il est possible de repasser en edition normale, mais les modifs manuelles seront alors ecrasee par re-generation du contenu a partir du squelettes.

Une fois publiee, la newsletter n'est plus editable qu'en mode avance, par les admins (permet de corriger les coquilles pour envoi ulterieurs ou pour la version en ligne)

(a noter : le plugin s'appelle Newsletters par convention, mais toutes les chaines de langue utilisent le terme infolettre dans la version fr)

TODO :
definir l'API pour la textification du html (fonction interne pour le moment)
definir l'API de remplacement de contenu dans la lettre generee (nom, email, url_desincription)
importer automatiquementa l'installation les infolettres generees avec les plugins spip-listes, spip-lettres, clevermail (et ma_lettre ?)
brancher sur l'api d'envoi (test, en masse) d'un plugin a venir

File size: 4.9 KB
Line 
1<?php
2/**
3 * Plugin Newsletters
4 * (c) 2012 Cedric Morin
5 * Licence GNU/GPL
6 */
7
8if (!defined('_ECRIRE_INC_VERSION')) return;
9
10function action_generer_newsletter_dist($id_newsletter = null, $force = false){
11        if (is_null($id_newsletter)){
12                $securiser_action = charger_fonction('securiser_action', 'inc');
13                $id_newsletter = $securiser_action();
14        }
15
16        include_spip('inc/autoriser');
17        if (autoriser('generer', 'newsletter', $id_newsletter)){
18                $row = sql_fetsel('*', 'spip_newsletters', 'id_newsletter=' . intval($id_newsletter));
19
20                // si cuite on ne genere pas, sauf si force
21                if (!$row['baked'] OR $force){
22                        $patron = $row['patron'];
23                        $date = intval($row['date_redac'])?$row['date_redac']:$row['date'];
24
25                        $set = array();
26                        $set['html_email'] = newsletters_recuperer_fond($id_newsletter, $patron, $date);
27                        if (trouver_fond("$patron.texte","newsletters"))
28                                $set['texte_email'] = newsletters_recuperer_fond($id_newsletter, "$patron.texte", $date);
29                        else
30                                $set['texte_email'] = newsletters_html2text($set['html_email']);
31
32                        $set['html_page'] = '';
33                        if (trouver_fond("$patron.page","newsletters"))
34                                $set['html_page'] = newsletters_recuperer_fond($id_newsletter, "$patron.page", $date);
35
36                        #header('Content-Type: text/plain; charset=utf-8');
37                        #echo($set['texte_email']);
38                        #die();
39
40                        include_spip("action/editer_objet");
41                        objet_modifier("newsletter",$id_newsletter,$set);
42
43                }
44        }
45}
46
47function newsletters_recuperer_fond($id_newsletter, $patron, $date = null){
48
49        if (is_null($date))
50                $date = date('Y-m-d 00:00:00');
51
52        // on passe la globale lien_implicite_cible_public en true
53        // pour avoir les liens internes en public (en non prive d'apres le contexte)
54        // credit de l'astuce: denisb & rastapopoulos
55        $GLOBALS['lien_implicite_cible_public'] = true;
56
57        $texte = recuperer_fond(
58                "newsletters/$patron",
59                array(
60                        'date' => $date,
61                        'id_newsletter' => $id_newsletter,
62                )
63        );
64
65        // on revient a la config initiale
66        unset($GLOBALS['lien_implicite_cible_public']);
67
68        return $texte;
69}
70
71function newsletters_html2text($html){
72        // nettoyer les balises de mise en page html
73        $html = preg_replace(",</(td|th)>,Uims","<br/>",$html);
74        $html = preg_replace(",</(table)>,Uims","@@@hr@@@",$html);
75        $html = preg_replace(",</?(html|body|table|td|th|tbody|thead|center|article|section|span)[^>]*>,Uims","\n\n",$html);
76        $html = preg_replace(",<!--.*-->,Uims","\n",$html);
77        $html = preg_replace(",<(/?)(div|tr|caption)([^>]*>),Uims","<\\1p>",$html);
78        $html = preg_replace(",(<p>\s*)+,ims","<p>",$html);
79        $html = preg_replace(",<br/?>\s*</p>,ims","</p>",$html);
80        $html = preg_replace(",</p>\s*<br/?>,ims","</p>",$html);
81        $html = preg_replace(",(</p>\s*(@@@hr@@@)?\s*)+,ims","</p>\\2",$html);
82        $html = preg_replace(",(<p>\s*</p>),ims","",$html);
83        #return $html;
84
85        $html = preg_replace(",<textarea[^>]*spip_cadre[^>]*>(.*)</textarea>,Uims","<code>\n\\1\n</code>",$html);
86
87        // vider le contenu de qqunes :
88        $html = preg_replace(",<head[^>]*>.*</head>,Uims","\n",$html);
89
90        // Liens :
91        // Nettoyage des liens des notes de bas de page
92        $html = preg_replace("@<a href=\"#n(b|h)[0-9]+-[0-9]+\" name=\"n(b|h)[0-9]+-[0-9]+\" class=\"spip_note\">([0-9]+)</a>@", "\\3", $html);
93        // Supprimer tous les liens internes
94        $html = preg_replace("/\<a href=['\"]#(.*?)['\"][^>]*>(.*?)<\/a>/ims","\\2", $html);
95        // Remplace tous les liens
96        preg_match_all("/\<a href=['\"](.*?)['\"][^>]*>(.*?)<\/a>/ims", $html,$matches,PREG_SET_ORDER);
97        $prelinks = $postlinks = array();
98        foreach ($matches as $k => $match){
99                $link = "@@@link$k@@@";
100                $prelinks[$match[0]] = $match[2]." ($link)";
101                $postlinks[$link] = $match[1];
102        }
103        $html = str_replace(array_keys($prelinks), array_values($prelinks),$html);
104
105        // les images par leur alt ?
106        // au moins les puces
107        $html = preg_replace(',<img\s[^>]*alt="-"[^>]*>,Uims','-',$html);
108        // les autres
109        $html = preg_replace(',<img\s[^>]*alt=[\'"]([^\'"]*)[\'"][^>]*>,Uims',"\\1",$html);
110        // on vire celles sans alt
111        $html = preg_replace(",</?(img)[^>]*>,Uims","\n",$html);
112
113        // espaces
114        $html = str_replace("&nbsp;"," ",$html);
115        $html = preg_replace(",<p>\s+,ims","<p>",$html);
116
117        #return $html;
118        include_spip("lib/markdownify/markdownify");
119        $parser = new Markdownify(false,false,false);
120        $texte = $parser->parseString($html);
121
122        $texte = str_replace(array_keys($postlinks), array_values($postlinks),$texte);
123
124
125        // trim et sauts de ligne en trop ou pas assez
126        $texte = trim($texte);
127        $texte = str_replace("<br />\n","\n",$texte);
128        $texte = preg_replace(",(@@@hr@@@\s*)+\Z,ims","",$texte);
129        $texte = preg_replace(",(@@@hr@@@\s*)+,ims","\n\n\n".str_pad("-",75,"-")."\n\n\n",$texte);
130        $texte = preg_replace(",(\n#+\s),ims","\n\n\\1",$texte);
131        $texte = preg_replace(",(\n\s*)(\n\s*)(\n\s*)+,ims","\n\n\n",$texte);
132
133        // entites restantes ? (dans du code...)
134        include_spip('inc/charsets');
135        $texte = unicode2charset($texte);
136        $texte = str_replace(array('&#039;', '&#034;'),array("'",'"'), $texte);
137
138
139        // Faire des lignes de 75 caracteres maximum
140        return trim(wordwrap($texte));
141
142}
143
Note: See TracBrowser for help on using the repository browser.