[SPIP] v3.2.1-->v3.2.2
[lhc/web/www.git] / www / ecrire / inc / drapeau_edition.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
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 drapeaux d'édition
15 *
16 * Drapeau d'edition : on regarde qui a ouvert quel objet éditorial en
17 * édition, et on le signale aux autres redacteurs pour éviter de se marcher
18 * sur les pieds
19 *
20 * Le format est une meta drapeau_edition qui contient un tableau sérialisé
21 * `type_objet => (id_objet => (id_auteur => (nom_auteur => (date_modif))))`
22 *
23 * À chaque mise à jour de ce tableau on oublie les enregistrements datant
24 * de plus d'une heure
25 *
26 * Attention ce n'est pas un verrou "bloquant", juste un drapeau qui signale
27 * que l'on bosse sur cet objet editorial ; les autres peuvent passer outre
28 * (en cas de communication orale c'est plus pratique)
29 *
30 * @package SPIP\Core\Drapeaux\Edition
31 **/
32 if (!defined('_ECRIRE_INC_VERSION')) {
33 return;
34 }
35
36
37 /**
38 * Retourne le tableau des éléments édités en cours après avoir supprimé
39 * les éléments trop vieux (de plus d'une heure) du tableau.
40 *
41 * @uses ecrire_tableau_edition()
42 *
43 * @return array
44 * Tableau des éléments édités actuellement, par objet et auteur, du type :
45 * `[ type d'objet ][id_objet][id_auteur][nom de l'auteur] = time()`
46 **/
47 function lire_tableau_edition() {
48 $edition = @unserialize($GLOBALS['meta']['drapeau_edition']);
49 if (!$edition) {
50 return array();
51 }
52 $changed = false;
53
54 $bon_pour_le_service = time() - 3600;
55 // parcourir le tableau et virer les vieux
56 foreach ($edition as $objet => $data) {
57 if (!is_array($data)) {
58 unset($edition[$objet]);
59 } // vieille version
60 else {
61 foreach ($data as $id => $tab) {
62 if (!is_array($tab)) {
63 unset($edition[$objet][$tab]);
64 } // vieille version
65 else {
66 foreach ($tab as $n => $duo) {
67 if (current($duo) < $bon_pour_le_service) {
68 unset($edition[$objet][$id][$n]);
69 $changed = true;
70 }
71 }
72 }
73 if (!$edition[$objet][$id]) {
74 unset($edition[$objet][$id]);
75 }
76 }
77 }
78 if (!$edition[$objet]) {
79 unset($edition[$objet]);
80 }
81 }
82
83 if ($changed) {
84 ecrire_tableau_edition($edition);
85 }
86
87 return $edition;
88 }
89
90 /**
91 * Enregistre la liste des éléments édités
92 *
93 * @uses ecrire_meta()
94 *
95 * @param array $edition
96 * Tableau des éléments édités actuellement, par objet et auteur, du type :
97 * `[ type d'objet ][id_objet][id_auteur][nom de l'auteur] = time()`
98 **/
99 function ecrire_tableau_edition($edition) {
100 ecrire_meta('drapeau_edition', serialize($edition));
101 }
102
103 /**
104 * Signale qu'un auteur édite tel objet
105 *
106 * Si l'objet est non éditable dans l'espace privé, ne pas retenir le signalement
107 * qui correspond à un process unique.
108 *
109 * @see lire_tableau_edition()
110 * @see ecrire_tableau_edition()
111 *
112 * @param int $id
113 * Identifiant de l'objet
114 * @param array $auteur
115 * Session de l'auteur
116 * @param string $type
117 * Type d'objet édité
118 */
119 function signale_edition($id, $auteur, $type = 'article') {
120 include_spip('base/objets');
121 include_spip('inc/filtres');
122 if (objet_info($type, 'editable') !== 'oui') {
123 return;
124 }
125
126 $edition = lire_tableau_edition();
127 if (isset($auteur['id_auteur']) and $id_a = $auteur['id_auteur']) {
128 $nom = $auteur['nom'];
129 } else {
130 $nom = $id_a = $GLOBALS['ip'];
131 }
132
133 if (!isset($edition[$type][$id]) or !is_array($edition[$type][$id])) {
134 $edition[$type][$id] = array();
135 }
136 $edition[$type][$id][$id_a][$nom] = time();
137 ecrire_tableau_edition($edition);
138 }
139
140 /**
141 * Qui édite mon objet ?
142 *
143 * @see lire_tableau_edition()
144 *
145 * @param integer $id
146 * Identifiant de l'objet
147 * @param string $type
148 * Type de l'objet
149 * @return array
150 * Tableau sous la forme `["id_auteur"]["nom de l'auteur"] = time()`
151 */
152 function qui_edite($id, $type = 'article') {
153
154 $edition = lire_tableau_edition();
155
156 return empty($edition[$type][$id]) ? array() : $edition[$type][$id];
157 }
158
159 /**
160 * Afficher les auteurs ayant édités récemment l'objet.
161 *
162 * @param integer $id
163 * Identifiant de l'objet
164 * @param string $type
165 * Type de l'objet
166 * @return array
167 * Liste de tableaux `['nom_auteur_modif' => x|y|z, 'date_diff' => n]`
168 */
169 function mention_qui_edite($id, $type = 'article') {
170 $modif = qui_edite($id, $type);
171 unset($modif[$GLOBALS['visiteur_session']['id_auteur']]);
172
173 if ($modif) {
174 $quand = 0;
175 foreach ($modif as $duo) {
176 $auteurs[] = typo(key($duo));
177 $quand = max($quand, current($duo));
178 }
179
180 // format lie a la chaine de langue 'avis_article_modifie'
181 return array(
182 'nom_auteur_modif' => join(' | ', $auteurs),
183 'date_diff' => ceil((time() - $quand) / 60)
184 );
185 }
186 }
187
188 /**
189 * Quels sont les objets en cours d'édition par `$id_auteur` ?
190 *
191 * @uses lire_tableau_edition()
192 *
193 * @param int $id_auteur
194 * Identifiant de l'auteur
195 * @return array
196 * Liste de tableaux `['objet' => x, 'id_objet' => n]`
197 */
198 function liste_drapeau_edition($id_auteur) {
199 $edition = lire_tableau_edition();
200 $objets_ouverts = array();
201
202 foreach ($edition as $objet => $data) {
203 foreach ($data as $id => $auteurs) {
204 if (isset($auteurs[$id_auteur])
205 and is_array($auteurs[$id_auteur]) // precaution
206 and (array_pop($auteurs[$id_auteur]) > time() - 3600)
207 ) {
208 $objets_ouverts[] = array(
209 'objet' => $objet,
210 'id_objet' => $id,
211 );
212 }
213 }
214 }
215
216 return $objets_ouverts;
217 }
218
219 /**
220 * Quand l'auteur veut libérer tous ses objets (tous types)
221 *
222 * @uses lire_tableau_edition()
223 * @uses ecrire_tableau_edition()
224 *
225 * @param integer $id_auteur
226 * @return void
227 */
228 function debloquer_tous($id_auteur) {
229 $edition = lire_tableau_edition();
230 foreach ($edition as $objet => $data) {
231 foreach ($data as $id => $auteurs) {
232 if (isset($auteurs[$id_auteur])) {
233 unset($edition[$objet][$id][$id_auteur]);
234 ecrire_tableau_edition($edition);
235 }
236 }
237 }
238 }
239
240 /**
241 * Quand l'auteur libère un objet précis
242 *
243 * @uses lire_tableau_edition()
244 * @uses ecrire_tableau_edition()
245 *
246 * @param integer $id_auteur
247 * Identifiant de l'auteur
248 * @param integer $id_objet
249 * Identifiant de l'objet édité
250 * @param string $type
251 * Type de l'objet
252 * @return void
253 */
254 function debloquer_edition($id_auteur, $id_objet, $type = 'article') {
255 $edition = lire_tableau_edition();
256
257 foreach ($edition as $objet => $data) {
258 if ($objet == $type) {
259 foreach ($data as $id => $auteurs) {
260 if ($id == $id_objet
261 and isset($auteurs[$id_auteur])
262 ) {
263 unset($edition[$objet][$id][$id_auteur]);
264 ecrire_tableau_edition($edition);
265 }
266 }
267 }
268 }
269 }