Completed
Push — master ( 634397...9bf31e )
by cam
01:24
created
ecrire/src/Texte/Collecteur/Multis.php 1 patch
Indentation   +204 added lines, -204 removed lines patch added patch discarded remove patch
@@ -29,209 +29,209 @@
 block discarded – undo
29 29
  */
30 30
 class Multis extends AbstractCollecteur {
31 31
 
32
-	protected static string $markPrefix = 'MULTI';
33
-
34
-	/**
35
-	 * La preg pour découper et collecter les modèles
36
-	 * @var string
37
-	 */
38
-	protected string $preg_multi;
39
-
40
-	public function __construct(?string $preg = null) {
41
-
42
-		$this->preg_multi = ($preg ?: '@<multi>(.*?)</multi>@sS');
43
-	}
44
-
45
-	/**
46
-	 * Sanitizer une collection d'occurences de multi : on sanitize chaque texte de langue séparemment
47
-	 *
48
-	 * @param array $collection
49
-	 * @param string $sanitize_callback
50
-	 * @return array
51
-	 */
52
-	protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
53
-
54
-		foreach ($collection as &$multi) {
55
-			$changed = false;
56
-			foreach ($multi['trads'] as $lang => $trad) {
57
-				$t = $sanitize_callback($trad);
58
-				if ($t !== $trad) {
59
-					$changed = true;
60
-					$multi['trads'][$lang] = $t;
61
-				}
62
-			}
63
-			if ($changed) {
64
-				$texte = $this->agglomerer_trads($multi['trads']);
65
-				$multi['raw'] = str_replace($multi['texte'], $texte, $multi['raw']);
66
-				$multi['texte'] = $texte;
67
-			}
68
-		}
69
-		return $collection;
70
-	}
71
-
72
-
73
-	/**
74
-	 * Convertit le contenu d'une balise `<multi>` en un tableau
75
-	 *
76
-	 * Exemple de blocs.
77
-	 * - `texte par défaut [fr] en français [en] en anglais`
78
-	 * - `[fr] en français [en] en anglais`
79
-	 *
80
-	 * @param string $bloc
81
-	 *     Le contenu intérieur d'un bloc multi
82
-	 * @return array [code de langue => texte]
83
-	 *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
84
-	 **/
85
-	protected function extraire_trads($bloc) {
86
-		$trads = [];
87
-
88
-		$langs = $this->collecteur($bloc, ']', '[', '@[\[]([a-z]{2,3}(_[a-z]{2,3})?(_[a-z]{2,3})?)[\]]@siS');
89
-		$lang = '';
90
-		$pos_prev = 0;
91
-		foreach ($langs as $l) {
92
-			$pos = $l['pos'];
93
-			if ($lang or $pos > $pos_prev) {
94
-				$trads[$lang] = substr($bloc, $pos_prev, $pos - $pos_prev);
95
-			}
96
-			$lang = $l['match'][1];
97
-			$pos_prev = $pos + $l['length'];
98
-		}
99
-		$trads[$lang] = substr($bloc, $pos_prev);
100
-
101
-		return $trads;
102
-	}
103
-
104
-	/**
105
-	 * Recoller ensemble les trads pour reconstituer le texte dans la balise <multi>...</multi>
106
-	 * @param $trads
107
-	 * @return string
108
-	 */
109
-	protected function agglomerer_trads($trads) {
110
-		$texte = '';
111
-		foreach ($trads as $lang => $trad) {
112
-			if ($texte or $lang) {
113
-				$texte .= "[$lang]";
114
-			}
115
-			$texte .= $trad;
116
-		}
117
-		return $texte;
118
-	}
119
-
120
-	/**
121
-	 * @param string $texte
122
-	 * @param array $options
123
-	 *   bool $collecter_liens
124
-	 * @return array
125
-	 */
126
-	public function collecter(string $texte, array $options = []): array {
127
-		if (!$texte) {
128
-			return [];
129
-		}
130
-
131
-		// collecter les matchs de la preg
132
-		$multis = $this->collecteur($texte, '', '<multi', $this->preg_multi, empty($options['detecter_presence']) ? 0 : 1);
133
-
134
-		// si on veut seulement detecter la présence, on peut retourner tel quel
135
-		if (empty($options['detecter_presence'])) {
136
-
137
-			$pos_prev = 0;
138
-			foreach ($multis as $k => &$multi) {
139
-
140
-				$multi['texte'] = $multi['match'][1];
141
-				// extraire les trads du texte
142
-				$trads = $this->extraire_trads($multi['match'][1]);
143
-				$multi['trads'] = $trads;
144
-			}
145
-		}
146
-
147
-		return $multis;
148
-	}
149
-
150
-	/**
151
-	 * Traiter les multis d'un texte
152
-	 *
153
-	 * @uses approcher_langue()
154
-	 * @uses lang_typo()
155
-	 * @uses code_echappement()
156
-	 * @uses echappe_retour()
157
-	 *
158
-	 * @param string $texte
159
-	 * @param array $options
160
-	 *   ?string $lang
161
-	 *   ?string $lang_defaut
162
-	 *   ?bool echappe_span
163
-	 *   ?bool appliquer_typo
164
-	 * @return string
165
-	 */
166
-	public function traiter(string $texte, array $options) {
167
-		if ($texte) {
168
-
169
-			$multis = $this->collecter($texte);
170
-			if (!empty($multis)) {
171
-				$lang = $options['lang'] ?? $GLOBALS['spip_lang'];
172
-				$lang_defaut = $options['lang_defaut'] ?? _LANGUE_PAR_DEFAUT;
173
-				$echappe_span = $options['echappe_span'] ?? false;
174
-				$appliquer_typo = $options['appliquer_typo'] ?? true;
175
-
176
-				if (!function_exists('approcher_langue')) {
177
-					include_spip('inc/lang');
178
-				}
179
-				if (!function_exists('code_echappement')) {
180
-					include_spip('inc/texte_mini');
181
-				}
182
-
183
-				$offset_pos = 0;
184
-				foreach ($multis as $m) {
185
-
186
-					// chercher la version de la langue courante
187
-					$trads = $m['trads'];
188
-					if ($l = approcher_langue($trads, $lang)) {
189
-						$trad = $trads[$l];
190
-					} else {
191
-						if ($lang_defaut == 'aucune') {
192
-							$trad = '';
193
-						} else {
194
-							// langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
195
-							// ou la premiere dispo
196
-							if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
197
-								$l = array_keys($trads);
198
-								$l = reset($l);
199
-							}
200
-
201
-							// mais typographier le texte selon les regles de celle-ci
202
-							// Attention aux blocs multi sur plusieurs lignes
203
-							if ($appliquer_typo) {
204
-								$trad = $trads[$l];
205
-								$typographie = charger_fonction(lang_typo($l), 'typographie');
206
-								$trad = $typographie($trad);
207
-
208
-								// Tester si on echappe en span ou en div
209
-								// il ne faut pas echapper en div si propre produit un seul paragraphe
210
-								include_spip('inc/texte');
211
-								$trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
212
-								$mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
213
-								if ($mode === 'div') {
214
-									$trad = rtrim($trad) . "\n\n";
215
-								}
216
-								$trad = code_echappement($trad, 'multi', false, $mode);
217
-								$trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
218
-								if (lang_dir($l) !== lang_dir($lang)) {
219
-									$trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
220
-								}
221
-								if (!$echappe_span) {
222
-									$trad = echappe_retour($trad, 'multi');
223
-								}
224
-							}
225
-						}
226
-					}
227
-
228
-					$texte = substr_replace($texte, $trad, $m['pos'] + $offset_pos, $m['length']);
229
-					$offset_pos += strlen($trad) - $m['length'];
230
-				}
231
-			}
232
-		}
233
-
234
-		return $texte;
235
-	}
32
+    protected static string $markPrefix = 'MULTI';
33
+
34
+    /**
35
+     * La preg pour découper et collecter les modèles
36
+     * @var string
37
+     */
38
+    protected string $preg_multi;
39
+
40
+    public function __construct(?string $preg = null) {
41
+
42
+        $this->preg_multi = ($preg ?: '@<multi>(.*?)</multi>@sS');
43
+    }
44
+
45
+    /**
46
+     * Sanitizer une collection d'occurences de multi : on sanitize chaque texte de langue séparemment
47
+     *
48
+     * @param array $collection
49
+     * @param string $sanitize_callback
50
+     * @return array
51
+     */
52
+    protected function sanitizer_collection(array $collection, string $sanitize_callback): array {
53
+
54
+        foreach ($collection as &$multi) {
55
+            $changed = false;
56
+            foreach ($multi['trads'] as $lang => $trad) {
57
+                $t = $sanitize_callback($trad);
58
+                if ($t !== $trad) {
59
+                    $changed = true;
60
+                    $multi['trads'][$lang] = $t;
61
+                }
62
+            }
63
+            if ($changed) {
64
+                $texte = $this->agglomerer_trads($multi['trads']);
65
+                $multi['raw'] = str_replace($multi['texte'], $texte, $multi['raw']);
66
+                $multi['texte'] = $texte;
67
+            }
68
+        }
69
+        return $collection;
70
+    }
71
+
72
+
73
+    /**
74
+     * Convertit le contenu d'une balise `<multi>` en un tableau
75
+     *
76
+     * Exemple de blocs.
77
+     * - `texte par défaut [fr] en français [en] en anglais`
78
+     * - `[fr] en français [en] en anglais`
79
+     *
80
+     * @param string $bloc
81
+     *     Le contenu intérieur d'un bloc multi
82
+     * @return array [code de langue => texte]
83
+     *     Peut retourner un code de langue vide, lorsqu'un texte par défaut est indiqué.
84
+     **/
85
+    protected function extraire_trads($bloc) {
86
+        $trads = [];
87
+
88
+        $langs = $this->collecteur($bloc, ']', '[', '@[\[]([a-z]{2,3}(_[a-z]{2,3})?(_[a-z]{2,3})?)[\]]@siS');
89
+        $lang = '';
90
+        $pos_prev = 0;
91
+        foreach ($langs as $l) {
92
+            $pos = $l['pos'];
93
+            if ($lang or $pos > $pos_prev) {
94
+                $trads[$lang] = substr($bloc, $pos_prev, $pos - $pos_prev);
95
+            }
96
+            $lang = $l['match'][1];
97
+            $pos_prev = $pos + $l['length'];
98
+        }
99
+        $trads[$lang] = substr($bloc, $pos_prev);
100
+
101
+        return $trads;
102
+    }
103
+
104
+    /**
105
+     * Recoller ensemble les trads pour reconstituer le texte dans la balise <multi>...</multi>
106
+     * @param $trads
107
+     * @return string
108
+     */
109
+    protected function agglomerer_trads($trads) {
110
+        $texte = '';
111
+        foreach ($trads as $lang => $trad) {
112
+            if ($texte or $lang) {
113
+                $texte .= "[$lang]";
114
+            }
115
+            $texte .= $trad;
116
+        }
117
+        return $texte;
118
+    }
119
+
120
+    /**
121
+     * @param string $texte
122
+     * @param array $options
123
+     *   bool $collecter_liens
124
+     * @return array
125
+     */
126
+    public function collecter(string $texte, array $options = []): array {
127
+        if (!$texte) {
128
+            return [];
129
+        }
130
+
131
+        // collecter les matchs de la preg
132
+        $multis = $this->collecteur($texte, '', '<multi', $this->preg_multi, empty($options['detecter_presence']) ? 0 : 1);
133
+
134
+        // si on veut seulement detecter la présence, on peut retourner tel quel
135
+        if (empty($options['detecter_presence'])) {
136
+
137
+            $pos_prev = 0;
138
+            foreach ($multis as $k => &$multi) {
139
+
140
+                $multi['texte'] = $multi['match'][1];
141
+                // extraire les trads du texte
142
+                $trads = $this->extraire_trads($multi['match'][1]);
143
+                $multi['trads'] = $trads;
144
+            }
145
+        }
146
+
147
+        return $multis;
148
+    }
149
+
150
+    /**
151
+     * Traiter les multis d'un texte
152
+     *
153
+     * @uses approcher_langue()
154
+     * @uses lang_typo()
155
+     * @uses code_echappement()
156
+     * @uses echappe_retour()
157
+     *
158
+     * @param string $texte
159
+     * @param array $options
160
+     *   ?string $lang
161
+     *   ?string $lang_defaut
162
+     *   ?bool echappe_span
163
+     *   ?bool appliquer_typo
164
+     * @return string
165
+     */
166
+    public function traiter(string $texte, array $options) {
167
+        if ($texte) {
168
+
169
+            $multis = $this->collecter($texte);
170
+            if (!empty($multis)) {
171
+                $lang = $options['lang'] ?? $GLOBALS['spip_lang'];
172
+                $lang_defaut = $options['lang_defaut'] ?? _LANGUE_PAR_DEFAUT;
173
+                $echappe_span = $options['echappe_span'] ?? false;
174
+                $appliquer_typo = $options['appliquer_typo'] ?? true;
175
+
176
+                if (!function_exists('approcher_langue')) {
177
+                    include_spip('inc/lang');
178
+                }
179
+                if (!function_exists('code_echappement')) {
180
+                    include_spip('inc/texte_mini');
181
+                }
182
+
183
+                $offset_pos = 0;
184
+                foreach ($multis as $m) {
185
+
186
+                    // chercher la version de la langue courante
187
+                    $trads = $m['trads'];
188
+                    if ($l = approcher_langue($trads, $lang)) {
189
+                        $trad = $trads[$l];
190
+                    } else {
191
+                        if ($lang_defaut == 'aucune') {
192
+                            $trad = '';
193
+                        } else {
194
+                            // langue absente, prendre le fr ou une langue précisée (meme comportement que inc/traduire.php)
195
+                            // ou la premiere dispo
196
+                            if (!$l = approcher_langue($trads, $options['lang_defaut'])) {
197
+                                $l = array_keys($trads);
198
+                                $l = reset($l);
199
+                            }
200
+
201
+                            // mais typographier le texte selon les regles de celle-ci
202
+                            // Attention aux blocs multi sur plusieurs lignes
203
+                            if ($appliquer_typo) {
204
+                                $trad = $trads[$l];
205
+                                $typographie = charger_fonction(lang_typo($l), 'typographie');
206
+                                $trad = $typographie($trad);
207
+
208
+                                // Tester si on echappe en span ou en div
209
+                                // il ne faut pas echapper en div si propre produit un seul paragraphe
210
+                                include_spip('inc/texte');
211
+                                $trad_propre = preg_replace(',(^<p[^>]*>|</p>$),Uims', '', propre($trad));
212
+                                $mode = preg_match(',</?(' . _BALISES_BLOCS . ')[>[:space:]],iS', $trad_propre) ? 'div' : 'span';
213
+                                if ($mode === 'div') {
214
+                                    $trad = rtrim($trad) . "\n\n";
215
+                                }
216
+                                $trad = code_echappement($trad, 'multi', false, $mode);
217
+                                $trad = str_replace("'", '"', inserer_attribut($trad, 'lang', $l));
218
+                                if (lang_dir($l) !== lang_dir($lang)) {
219
+                                    $trad = str_replace("'", '"', inserer_attribut($trad, 'dir', lang_dir($l)));
220
+                                }
221
+                                if (!$echappe_span) {
222
+                                    $trad = echappe_retour($trad, 'multi');
223
+                                }
224
+                            }
225
+                        }
226
+                    }
227
+
228
+                    $texte = substr_replace($texte, $trad, $m['pos'] + $offset_pos, $m['length']);
229
+                    $offset_pos += strlen($trad) - $m['length'];
230
+                }
231
+            }
232
+        }
233
+
234
+        return $texte;
235
+    }
236 236
 
237 237
 }
Please login to merge, or discard this patch.