PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / trunk
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO vtrunk
2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 1.11.0 All 47 releases
thinkrank / includes / editor / class-bricks-elements-manager.php

class-bricks-elements-manager.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO trunk, at includes/editor/class-bricks-elements-manager.php

183 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Bricks Elements Integration Manager
5 *
6 * Registers ThinkRank's Bricks elements (FAQ, HowTo, Table of Contents) so a
7 * Bricks-built page can emit FAQPage, HowTo and SiteNavigationElement schema
8 * the same way a Gutenberg or Elementor page already can (#626).
9 *
10 * The Elementor widgets do not port. They are written against Elementor's
11 * widget API — `Widget_Base`, `Controls_Manager`, `Repeater` — and Bricks has
12 * its own: elements extend `Bricks\Element`, declare controls as a plain array
13 * in `set_controls()`, and are registered through
14 * `Bricks\Elements::register_element()`. What is shared is the rendered markup
15 * and the stylesheets, so the two builders' output is identical on the page.
16 *
17 * Registration runs on `init` at priority 11. Bricks loads its own element base
18 * class in `Elements::init_elements()` on `init` at the default priority, so
19 * anything earlier would extend a class that does not exist yet.
20 *
21 * All hooks are Bricks-gated: without the theme, none of this runs and no
22 * Bricks class is referenced.
23 *
24 * @package ThinkRank
25 * @subpackage Editor
26 * @since 2.3.1
27 */
28
29 declare(strict_types=1);
30
31 namespace ThinkRank\Editor;
32
33 // Prevent direct access
34 if (!defined('ABSPATH')) {
35 exit;
36 }
37
38 /**
39 * Bricks Elements Manager.
40 *
41 * @since 2.3.1
42 */
43 class Bricks_Elements_Manager {
44
45 /**
46 * Builder category the elements are filed under.
47 *
48 * @var string
49 */
50 private const CATEGORY = 'thinkrank';
51
52 /**
53 * Element name => file basename, in panel order.
54 *
55 * @var array<string,string>
56 */
57 private const ELEMENTS = [
58 'thinkrank-faq' => 'class-faq-element',
59 'thinkrank-howto' => 'class-howto-element',
60 'thinkrank-toc' => 'class-toc-element',
61 ];
62
63 /**
64 * Element name => the shared block stylesheet it renders against.
65 *
66 * The Bricks elements reuse the Gutenberg blocks' compiled CSS rather than
67 * shipping a second copy, so a page built either way looks the same.
68 *
69 * @var array<string,string>
70 */
71 private const STYLES = [
72 'thinkrank-faq' => 'faq-block',
73 'thinkrank-howto' => 'howto-block',
74 'thinkrank-toc' => 'toc-block',
75 ];
76
77 /**
78 * Wire up hooks. Safe without Bricks — every one of them checks for it.
79 *
80 * @return void
81 */
82 public function init(): void {
83 add_action('init', [$this, 'register_elements'], 11);
84 add_filter('bricks/builder/i18n', [$this, 'register_category']);
85 add_action('wp_enqueue_scripts', [$this, 'register_styles']);
86 }
87
88 /**
89 * Hand the element files to Bricks.
90 *
91 * @return void
92 */
93 public function register_elements(): void {
94 if (!class_exists('\\Bricks\\Elements') || !class_exists('\\Bricks\\Element')) {
95 return;
96 }
97
98 foreach (self::ELEMENTS as $name => $basename) {
99 $file = THINKRANK_PLUGIN_DIR . "includes/editor/bricks/{$basename}.php";
100 if (!is_readable($file)) {
101 continue;
102 }
103
104 \Bricks\Elements::register_element($file, $name, self::class_for($name));
105 }
106 }
107
108 /**
109 * Name the ThinkRank category in the builder's element panel.
110 *
111 * Bricks reads category labels from this map, keyed by the `$category`
112 * an element declares. Without an entry the panel falls back to the raw
113 * key, which would read "thinkrank" rather than "ThinkRank".
114 *
115 * @param mixed $i18n Builder strings.
116 * @return mixed
117 */
118 public function register_category($i18n) {
119 // Another filter may have handed on something that is not a map;
120 // passing it through unchanged is better than replacing it.
121 if (!is_array($i18n)) {
122 return $i18n;
123 }
124
125 $i18n[self::CATEGORY] = __('ThinkRank', 'thinkrank');
126
127 return $i18n;
128 }
129
130 /**
131 * Register (not enqueue) the shared block stylesheets.
132 *
133 * Each element enqueues its own handle from `enqueue_scripts()`, which
134 * Bricks calls only for elements actually on the page — so a page with no
135 * ThinkRank element loads none of this CSS.
136 *
137 * Registration is skipped for a handle another integration already
138 * registered: the Elementor manager registers the same three on the same
139 * hook, and a site running both builders would otherwise register twice.
140 *
141 * @return void
142 */
143 public function register_styles(): void {
144 foreach (self::STYLES as $handle) {
145 $style_handle = "thinkrank-{$handle}";
146 if (wp_style_is($style_handle, 'registered')) {
147 continue;
148 }
149
150 $css = THINKRANK_PLUGIN_DIR . "assets/{$handle}.css";
151 if (!file_exists($css)) {
152 continue;
153 }
154
155 $asset_path = THINKRANK_PLUGIN_DIR . "assets/{$handle}.asset.php";
156 $asset = file_exists($asset_path) ? include $asset_path : [];
157
158 wp_register_style(
159 $style_handle,
160 THINKRANK_PLUGIN_URL . "assets/{$handle}.css",
161 [],
162 $asset['version'] ?? THINKRANK_VERSION
163 );
164 }
165 }
166
167 /**
168 * The class implementing one element.
169 *
170 * @param string $name Bricks element name.
171 * @return string Fully qualified class name.
172 */
173 private static function class_for(string $name): string {
174 $map = [
175 'thinkrank-faq' => Bricks\FAQ_Element::class,
176 'thinkrank-howto' => Bricks\Howto_Element::class,
177 'thinkrank-toc' => Bricks\TOC_Element::class,
178 ];
179
180 return $map[$name] ?? '';
181 }
182 }
183