PluginProbe
Extendify / 3.0.6
Extendify v3.0.6
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / app / Agent / TagBlocks.php

TagBlocks.php in Extendify 3.0.6, at app/Agent/TagBlocks.php

139 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Extendify\Agent;
4
5 defined('ABSPATH') || die('No direct access.');
6
7 class TagBlocks
8 {
9 // Iterating blocks: their inner template renders once per item, so tagging
10 // children would assign N rendered ids to one parsed block. Skip the subtree.
11 // Public so WPController::getBlockCode walks the same list.
12 public static $ignored = [
13 'core/query',
14 'core/post-template',
15 'core/post-content',
16 'core/comments',
17 'core/comment-template',
18 'woocommerce/product-collection',
19 'woocommerce/product-template',
20 ];
21
22 public static function init()
23 {
24 \add_filter('the_content', [self::class, 'enterScope'], 0);
25 \add_filter('the_content', [self::class, 'leaveScope'], PHP_INT_MAX);
26
27 \add_filter('pre_render_block', [self::class, 'pre'], 10, 2);
28 \add_filter('render_block', [self::class, 'post'], 10, 2);
29 }
30
31 public static function enterScope($content)
32 {
33 if (is_admin()) {
34 return $content;
35 }
36
37 if (empty($GLOBALS['extendify_agent_scope'])) {
38 $GLOBALS['extendify_agent_scope'] = [
39 'depth' => 0,
40 'frames' => [],
41 ];
42 }
43 $GLOBALS['extendify_agent_scope']['depth']++;
44 // Each scope has: seq, id_stack, pushed_stack, skip_depth
45 $GLOBALS['extendify_agent_scope']['frames'][] = [
46 'seq' => 0,
47 'id_stack' => [],
48 'pushed_stack' => [],
49 'skip_depth' => 0, // >0 while inside an ignored subtree
50 ];
51 return $content;
52 }
53
54 public static function leaveScope($content)
55 {
56 if (is_admin()) {
57 return $content;
58 }
59 $S =& $GLOBALS['extendify_agent_scope'];
60 if (!empty($S['depth'])) {
61 $S['depth']--;
62 array_pop($S['frames']);
63 }
64 return $content;
65 }
66
67 public static function pre($pre, $parsed_block)
68 {
69 if (is_admin() || !is_array($parsed_block) || empty($parsed_block['blockName'])) {
70 return $pre;
71 }
72
73 $S = $GLOBALS['extendify_agent_scope'] ?? null;
74 if (!$S || ($S['depth'] ?? 0) !== 1 || empty($S['frames'])) {
75 return $pre;
76 } // only outer the_content
77
78 $i = count($S['frames']) - 1;
79 $frame = $S['frames'][$i];
80
81 $name = $parsed_block['blockName'];
82
83 // If this block starts an ignored subtree, enter skip mode
84 if (in_array($name, self::$ignored, true)) {
85 $frame['skip_depth']++;
86 $frame['pushed_stack'][] = false; // we didn't assign an id to this block
87 } elseif ($frame['skip_depth'] > 0) {
88 // Already skipping? (we're inside an ignored subtree)
89 $frame['pushed_stack'][] = false; // no id for anything under ignored
90 } else {
91 // Normal counting
92 $frame['seq']++;
93 $id = $frame['seq'];
94 $frame['id_stack'][] = $id;
95 $frame['pushed_stack'][] = true;
96 }
97
98 $GLOBALS['extendify_agent_scope']['frames'][$i] = $frame;
99 return $pre;
100 }
101
102 public static function post($content, $parsed_block)
103 {
104 $S = $GLOBALS['extendify_agent_scope'] ?? null;
105 if (!$S || empty($S['frames'])) {
106 return $content;
107 }
108
109 $i = count($S['frames']) - 1;
110 $frame = $S['frames'][$i];
111
112 $name = is_array($parsed_block) ? ($parsed_block['blockName'] ?? null) : null;
113
114 // Pop pushed flag & optional id (ALWAYS pop to stay balanced)
115 $pushed = !empty($frame['pushed_stack']) ? array_pop($frame['pushed_stack']) : false;
116 $id = ($pushed && !empty($frame['id_stack'])) ? array_pop($frame['id_stack']) : null;
117
118 // Inject only when: outer scope, we counted this block, html present, not admin
119 if (!is_admin() && ($S['depth'] ?? 0) === 1 && $pushed && $id && $content && $name) {
120 $tp = new \WP_HTML_Tag_Processor($content);
121 $value = (string) (int) $id;
122
123 // Move cursor to the first start tag in the fragment
124 if ($tp->next_tag()) {
125 $tp->set_attribute('data-extendify-agent-block-id', $value);
126 $content = $tp->get_updated_html();
127 }
128 }
129
130 // If this block ends an ignored subtree, exit skip mode
131 if ($name && in_array($name, self::$ignored, true) && $frame['skip_depth'] > 0) {
132 $frame['skip_depth']--;
133 }
134
135 $GLOBALS['extendify_agent_scope']['frames'][$i] = $frame;
136 return $content;
137 }
138 }
139