PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / assets / php / admin-dashboard.php

admin-dashboard.php in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at assets/php/admin-dashboard.php

361 lines 16.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Blockenberg — Block Manager Dashboard
4 *
5 * WordPress.com-inspired admin page that lets users enable / disable
6 * individual blocks. Disabled blocks are stored in the
7 * 'blockenberg_disabled_blocks' option as a flat array of block names
8 * (e.g. "blockenberg/accordion").
9 *
10 * @package Blockenberg
11 */
12
13 defined( 'ABSPATH' ) || exit;
14
15 /* ──────────────────────────────────────────────
16 * 1. Register admin menu
17 * ────────────────────────────────────────────── */
18 add_action( 'admin_menu', function () {
19 add_menu_page(
20 __( 'Blockenberg', 'blockenberg' ),
21 __( 'Blockenberg', 'blockenberg' ),
22 'manage_options',
23 'blockenberg',
24 'bkbg_render_dashboard',
25 'dashicons-screenoptions',
26 59
27 );
28 } );
29
30 /* ──────────────────────────────────────────────
31 * 2. Enqueue dashboard assets (only on our page)
32 * ────────────────────────────────────────────── */
33 add_action( 'admin_enqueue_scripts', function ( $hook ) {
34 if ( 'toplevel_page_blockenberg' !== $hook ) {
35 return;
36 }
37
38 $plugin_dir = dirname( __DIR__, 2 );
39 $plugin_url = plugins_url( '', $plugin_dir . '/blockenberg.php' );
40
41 wp_enqueue_style(
42 'bkbg-admin-dashboard',
43 $plugin_url . '/assets/css/admin-dashboard.css',
44 array(),
45 filemtime( $plugin_dir . '/assets/css/admin-dashboard.css' )
46 );
47
48 wp_enqueue_script(
49 'bkbg-admin-dashboard',
50 $plugin_url . '/assets/js/admin-dashboard.js',
51 array( 'jquery' ),
52 filemtime( $plugin_dir . '/assets/js/admin-dashboard.js' ),
53 true
54 );
55
56 wp_localize_script( 'bkbg-admin-dashboard', 'bkbgDashboard', array(
57 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
58 'nonce' => wp_create_nonce( 'bkbg_save_blocks' ),
59 'i18n' => array(
60 'saved' => __( 'Settings saved.', 'blockenberg' ),
61 'saving' => __( 'Saving…', 'blockenberg' ),
62 'error' => __( 'Save failed. Please try again.', 'blockenberg' ),
63 'enableAll' => __( 'Enable All', 'blockenberg' ),
64 'disableAll' => __( 'Disable All', 'blockenberg' ),
65 ),
66 ) );
67 } );
68
69 /* ──────────────────────────────────────────────
70 * 3. AJAX handler — save disabled blocks
71 * ────────────────────────────────────────────── */
72 add_action( 'wp_ajax_bkbg_save_disabled_blocks', function () {
73 check_ajax_referer( 'bkbg_save_blocks', 'nonce' );
74
75 if ( ! current_user_can( 'manage_options' ) ) {
76 wp_send_json_error( 'Unauthorized', 403 );
77 }
78
79 $raw = isset( $_POST['disabled'] ) ? $_POST['disabled'] : array();
80
81 if ( is_string( $raw ) ) {
82 $raw = json_decode( stripslashes( $raw ), true );
83 }
84
85 if ( ! is_array( $raw ) ) {
86 $raw = array();
87 }
88
89 $sanitized = array();
90 foreach ( $raw as $block_name ) {
91 $clean = sanitize_text_field( $block_name );
92 if ( '' !== $clean && strpos( $clean, 'blockenberg/' ) === 0 ) {
93 $sanitized[] = $clean;
94 }
95 }
96
97 update_option( 'blockenberg_disabled_blocks', $sanitized, false );
98
99 wp_send_json_success( array(
100 'disabled' => $sanitized,
101 'count' => count( $sanitized ),
102 ) );
103 } );
104
105 /* ──────────────────────────────────────────────
106 * 4. Helper — collect blocks metadata
107 * ────────────────────────────────────────────── */
108 function bkbg_get_all_blocks_meta() {
109 $blocks_dir = dirname( __DIR__, 2 ) . '/blocks';
110 $blocks = array();
111
112 foreach ( glob( $blocks_dir . '/*/block.json' ) as $json_path ) {
113 $raw = file_get_contents( $json_path );
114 if ( ! $raw ) {
115 continue;
116 }
117
118 // WordPress block.json can have trailing commas — strip them.
119 $raw = preg_replace( '/,\s*([\]}])/', '$1', $raw );
120 $data = json_decode( $raw, true );
121 if ( ! is_array( $data ) || empty( $data['name'] ) ) {
122 continue;
123 }
124
125 $blocks[] = array(
126 'name' => $data['name'],
127 'title' => isset( $data['title'] ) ? $data['title'] : basename( dirname( $json_path ) ),
128 'category' => isset( $data['category'] ) ? $data['category'] : 'blockenberg',
129 'icon' => isset( $data['icon'] ) ? $data['icon'] : 'block-default',
130 'keywords' => isset( $data['keywords'] ) ? $data['keywords'] : array(),
131 );
132 }
133
134 // Sort by title.
135 usort( $blocks, function ( $a, $b ) {
136 return strcasecmp( $a['title'], $b['title'] );
137 } );
138
139 return $blocks;
140 }
141
142 /* ──────────────────────────────────────────────
143 * 5. Category labels (mirrors block_categories_all).
144 * ────────────────────────────────────────────── */
145 function bkbg_get_category_labels() {
146 return array(
147 'bkbg-layout' => __( 'Layout & Structure', 'blockenberg' ),
148 'bkbg-content' => __( 'Content & Typography', 'blockenberg' ),
149 'bkbg-media' => __( 'Media & Images', 'blockenberg' ),
150 'bkbg-marketing' => __( 'Marketing & Conversion', 'blockenberg' ),
151 'bkbg-business' => __( 'Business & Services', 'blockenberg' ),
152 'bkbg-blog' => __( 'Blog & Editorial', 'blockenberg' ),
153 'bkbg-interactive' => __( 'Interactive & Games', 'blockenberg' ),
154 'bkbg-charts' => __( 'Charts & Data', 'blockenberg' ),
155 'bkbg-calculators' => __( 'Calculators & Tools', 'blockenberg' ),
156 'bkbg-effects' => __( 'Effects & Animation', 'blockenberg' ),
157 'bkbg-dev' => __( 'Developer Tools', 'blockenberg' ),
158 'blockenberg' => __( 'General', 'blockenberg' ),
159 );
160 }
161
162 /* Category dashicons */
163 function bkbg_get_category_icons() {
164 return array(
165 'bkbg-layout' => 'dashicons-layout',
166 'bkbg-content' => 'dashicons-editor-paragraph',
167 'bkbg-media' => 'dashicons-format-image',
168 'bkbg-marketing' => 'dashicons-megaphone',
169 'bkbg-business' => 'dashicons-building',
170 'bkbg-blog' => 'dashicons-welcome-write-blog',
171 'bkbg-interactive' => 'dashicons-games',
172 'bkbg-charts' => 'dashicons-chart-bar',
173 'bkbg-calculators' => 'dashicons-calculator',
174 'bkbg-effects' => 'dashicons-art',
175 'bkbg-dev' => 'dashicons-code-standards',
176 'blockenberg' => 'dashicons-screenoptions',
177 );
178 }
179
180 /* ──────────────────────────────────────────────
181 * 6. Render the dashboard page
182 * ────────────────────────────────────────────── */
183 function bkbg_render_dashboard() {
184 $blocks = bkbg_get_all_blocks_meta();
185 $disabled = get_option( 'blockenberg_disabled_blocks', array() );
186 $category_labels = bkbg_get_category_labels();
187 $category_icons = bkbg_get_category_icons();
188
189 if ( ! is_array( $disabled ) ) {
190 $disabled = array();
191 }
192
193 // Group blocks by category.
194 $by_category = array();
195 foreach ( $blocks as $block ) {
196 $cat = $block['category'];
197 if ( ! isset( $by_category[ $cat ] ) ) {
198 $by_category[ $cat ] = array();
199 }
200 $by_category[ $cat ][] = $block;
201 }
202
203 // Sort categories in the same order as $category_labels.
204 $ordered = array();
205 foreach ( array_keys( $category_labels ) as $cat_slug ) {
206 if ( isset( $by_category[ $cat_slug ] ) ) {
207 $ordered[ $cat_slug ] = $by_category[ $cat_slug ];
208 }
209 }
210 // Append any unknown categories.
211 foreach ( $by_category as $cat_slug => $cat_blocks ) {
212 if ( ! isset( $ordered[ $cat_slug ] ) ) {
213 $ordered[ $cat_slug ] = $cat_blocks;
214 }
215 }
216
217 $total_blocks = count( $blocks );
218 $enabled_blocks = $total_blocks - count( $disabled );
219 ?>
220 <div id="bkbg-dashboard" class="bkbg-dashboard">
221
222 <!-- Header -->
223 <header class="bkbg-header">
224 <div class="bkbg-header__left">
225 <div class="bkbg-header__logo">
226 <span class="dashicons dashicons-screenoptions"></span>
227 </div>
228 <div class="bkbg-header__text">
229 <h1><?php esc_html_e( 'Blockenberg', 'blockenberg' ); ?></h1>
230 <p class="bkbg-header__subtitle">
231 <?php
232 printf(
233 /* translators: 1: enabled count 2: total count */
234 esc_html__( '%1$s of %2$s blocks enabled', 'blockenberg' ),
235 '<span id="bkbg-enabled-count">' . intval( $enabled_blocks ) . '</span>',
236 '<span id="bkbg-total-count">' . intval( $total_blocks ) . '</span>'
237 );
238 ?>
239 </p>
240 </div>
241 </div>
242 <div class="bkbg-header__right">
243 <div class="bkbg-search-wrap">
244 <input type="text" id="bkbg-search" class="bkbg-search"
245 placeholder="<?php esc_attr_e( 'Search blocks…', 'blockenberg' ); ?>"
246 autocomplete="off" />
247 </div>
248 <button type="button" id="bkbg-save" class="bkbg-btn bkbg-btn--primary">
249 <span class="dashicons dashicons-cloud-saved"></span>
250 <?php esc_html_e( 'Save Changes', 'blockenberg' ); ?>
251 </button>
252 </div>
253 </header>
254
255 <!-- Toolbar -->
256 <div class="bkbg-toolbar">
257 <div class="bkbg-toolbar__tabs" id="bkbg-category-tabs">
258 <button type="button" class="bkbg-tab bkbg-tab--active" data-category="all">
259 <?php esc_html_e( 'All Blocks', 'blockenberg' ); ?>
260 <span class="bkbg-tab__count"><?php echo intval( $total_blocks ); ?></span>
261 </button>
262 <?php foreach ( $ordered as $cat_slug => $cat_blocks ) :
263 $label = isset( $category_labels[ $cat_slug ] ) ? $category_labels[ $cat_slug ] : $cat_slug;
264 $icon = isset( $category_icons[ $cat_slug ] ) ? $category_icons[ $cat_slug ] : 'dashicons-block-default';
265 ?>
266 <button type="button" class="bkbg-tab" data-category="<?php echo esc_attr( $cat_slug ); ?>">
267 <span class="dashicons <?php echo esc_attr( $icon ); ?>"></span>
268 <?php echo esc_html( $label ); ?>
269 <span class="bkbg-tab__count"><?php echo count( $cat_blocks ); ?></span>
270 </button>
271 <?php endforeach; ?>
272 </div>
273 <div class="bkbg-toolbar__actions">
274 <button type="button" id="bkbg-enable-all" class="bkbg-btn bkbg-btn--ghost">
275 <?php esc_html_e( 'Enable All', 'blockenberg' ); ?>
276 </button>
277 <button type="button" id="bkbg-disable-all" class="bkbg-btn bkbg-btn--ghost bkbg-btn--danger">
278 <?php esc_html_e( 'Disable All', 'blockenberg' ); ?>
279 </button>
280 </div>
281 </div>
282
283 <!-- Toast notification -->
284 <div id="bkbg-toast" class="bkbg-toast" aria-live="polite"></div>
285
286 <!-- Block grid -->
287 <div class="bkbg-grid" id="bkbg-grid">
288 <?php foreach ( $ordered as $cat_slug => $cat_blocks ) :
289 $label = isset( $category_labels[ $cat_slug ] ) ? $category_labels[ $cat_slug ] : $cat_slug;
290 ?>
291 <div class="bkbg-category-section" data-category="<?php echo esc_attr( $cat_slug ); ?>">
292 <div class="bkbg-category-header">
293 <h2 class="bkbg-category-title">
294 <?php
295 $icon = isset( $category_icons[ $cat_slug ] ) ? $category_icons[ $cat_slug ] : 'dashicons-block-default';
296 ?>
297 <span class="dashicons <?php echo esc_attr( $icon ); ?>"></span>
298 <?php echo esc_html( $label ); ?>
299 <span class="bkbg-category-count"><?php echo count( $cat_blocks ); ?></span>
300 </h2>
301 <div class="bkbg-category-actions">
302 <button type="button" class="bkbg-cat-toggle" data-action="enable" data-cat="<?php echo esc_attr( $cat_slug ); ?>">
303 <?php esc_html_e( 'Enable All', 'blockenberg' ); ?>
304 </button>
305 <span class="bkbg-cat-sep">|</span>
306 <button type="button" class="bkbg-cat-toggle" data-action="disable" data-cat="<?php echo esc_attr( $cat_slug ); ?>">
307 <?php esc_html_e( 'Disable All', 'blockenberg' ); ?>
308 </button>
309 </div>
310 </div>
311 <div class="bkbg-cards">
312 <?php foreach ( $cat_blocks as $block ) :
313 $is_disabled = in_array( $block['name'], $disabled, true );
314 $slug = str_replace( 'blockenberg/', '', $block['name'] );
315 $dashicon = $block['icon'];
316
317 // Ensure icon is a simple dashicon string (not an object).
318 if ( is_array( $dashicon ) ) {
319 $dashicon = isset( $dashicon['src'] ) ? $dashicon['src'] : 'block-default';
320 }
321
322 // Normalise icon class.
323 if ( strpos( $dashicon, 'dashicons-' ) !== 0 ) {
324 $dashicon = 'dashicons-' . $dashicon;
325 }
326 ?>
327 <div class="bkbg-card <?php echo $is_disabled ? 'bkbg-card--disabled' : ''; ?>"
328 data-block="<?php echo esc_attr( $block['name'] ); ?>"
329 data-title="<?php echo esc_attr( strtolower( $block['title'] ) ); ?>"
330 data-slug="<?php echo esc_attr( $slug ); ?>"
331 data-keywords="<?php echo esc_attr( strtolower( implode( ' ', $block['keywords'] ) ) ); ?>">
332 <div class="bkbg-card__icon">
333 <span class="dashicons <?php echo esc_attr( $dashicon ); ?>"></span>
334 </div>
335 <div class="bkbg-card__info">
336 <span class="bkbg-card__title"><?php echo esc_html( $block['title'] ); ?></span>
337 </div>
338 <label class="bkbg-toggle">
339 <input type="checkbox"
340 class="bkbg-toggle__input"
341 data-block="<?php echo esc_attr( $block['name'] ); ?>"
342 <?php checked( ! $is_disabled ); ?> />
343 <span class="bkbg-toggle__slider"></span>
344 </label>
345 </div>
346 <?php endforeach; ?>
347 </div>
348 </div>
349 <?php endforeach; ?>
350 </div>
351
352 <!-- Empty state for search -->
353 <div id="bkbg-empty" class="bkbg-empty" style="display:none;">
354 <span class="dashicons dashicons-search"></span>
355 <p><?php esc_html_e( 'No blocks match your search.', 'blockenberg' ); ?></p>
356 </div>
357
358 </div>
359 <?php
360 }
361