@@ -189,6 +189,7 @@ public function getTemplateProcessor()
189189 *
190190 * @param string $value
191191 * @return string
192+ *
192193 * @throws \Exception
193194 */
194195 public function filter ($ value )
@@ -203,19 +204,21 @@ public function filter($value)
203204 $ this ->filteringDepthMeter ->descend ();
204205
205206 // Processing of template directives.
206- $ templateDirectivesResults = $ this ->processDirectives ($ value );
207+ $ templateDirectivesResults = array_unique (
208+ $ this ->processDirectives ($ value ),
209+ SORT_REGULAR
210+ );
207211
208- foreach ($ templateDirectivesResults as $ result ) {
209- $ value = str_replace ($ result ['directive ' ], $ result ['output ' ], $ value );
210- }
212+ $ value = $ this ->applyDirectivesResults ($ value , $ templateDirectivesResults );
211213
212214 // Processing of deferred directives received from child templates
213215 // or nested directives.
214- $ deferredDirectivesResults = $ this ->processDirectives ($ value , true );
216+ $ deferredDirectivesResults = array_unique (
217+ $ this ->processDirectives ($ value , true ),
218+ SORT_REGULAR
219+ );
215220
216- foreach ($ deferredDirectivesResults as $ result ) {
217- $ value = str_replace ($ result ['directive ' ], $ result ['output ' ], $ value );
218- }
221+ $ value = $ this ->applyDirectivesResults ($ value , $ deferredDirectivesResults );
219222
220223 if ($ this ->filteringDepthMeter ->showMark () > 1 ) {
221224 // Signing own deferred directives (if any).
@@ -271,17 +274,60 @@ private function processDirectives($value, $isSigned = false): array
271274 foreach ($ constructions as $ construction ) {
272275 $ replacedValue = $ directiveProcessor ->process ($ construction , $ this , $ this ->templateVars );
273276
274- $ results [] = [
277+ $ result = [
275278 'directive ' => $ construction [0 ],
276279 'output ' => $ replacedValue
277280 ];
281+
282+ if (count ($ this ->afterFilterCallbacks ) > 0 ) {
283+ $ result ['callbacks ' ] = $ this ->afterFilterCallbacks ;
284+
285+ $ this ->resetAfterFilterCallbacks ();
286+ }
287+
288+ $ results [] = $ result ;
278289 }
279290 }
280291 }
281292
282293 return $ results ;
283294 }
284295
296+ /**
297+ * Applies results produced by directives.
298+ *
299+ * @param string $value
300+ * @param array $results
301+ *
302+ * @return string
303+ */
304+ private function applyDirectivesResults (string $ value , array $ results ): string
305+ {
306+ $ processedResults = [];
307+
308+ foreach ($ results as $ result ) {
309+ foreach ($ processedResults as $ processedResult ) {
310+ $ result ['directive ' ] = str_replace (
311+ $ processedResult ['directive ' ],
312+ $ processedResult ['output ' ],
313+ $ result ['directive ' ]
314+ );
315+ }
316+
317+ $ value = str_replace ($ result ['directive ' ], $ result ['output ' ], $ value );
318+
319+ if (isset ($ result ['callbacks ' ])) {
320+ foreach ($ result ['callbacks ' ] as $ callback ) {
321+ $ this ->addAfterFilterCallback ($ callback );
322+ }
323+ }
324+
325+ $ processedResults [] = $ result ;
326+ }
327+
328+ return $ value ;
329+ }
330+
285331 /**
286332 * Modifies given regular expression pattern to be able to recognize signed directives.
287333 *
0 commit comments