PluginProbe
Blocks – Reusable Content, Shortcodes & Site Variables / trunk
Blocks – Reusable Content, Shortcodes & Site Variables vtrunk
26.09.03.15 26.08.31.21 26.08.22.20 26.08.22.22 26.08.22.17 26.08.22.13 26.08.21.19 26.08.07.23 26.07.19.14 26.07.13.21 26.07.13.17 26.07.12.13 026.07.07.21 026.07.05.18 026.06.26.20 026.06.26.21 026.06.08.20 026.05.13.14 026.04.29.10 trunk 026.02.22.22 026.03.16.23 026.04.23.13
blocks / includes / admin / blocks-admin.php

blocks-admin.php in Blocks – Reusable Content, Shortcodes & Site Variables trunk, at includes/admin/blocks-admin.php

316 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Blocks
4 * @license GPL-2.0-or-later
5 */
6
7 defined( 'ABSPATH' ) || exit;
8
9 add_action( 'admin_menu', 'blocks_admin_menu', 8 );
10
11 function blocks_admin_menu() {
12 add_menu_page(
13 __( 'Block', 'blocks' ),
14 __( 'Blocks', 'blocks' ),
15 'blocks_read_cms_blocks',
16 'block',
17 'blocks_admin_management_page',
18 'dashicons-screenoptions'
19 );
20
21 // First submenu replaces the auto-generated duplicate.
22 $edit = add_submenu_page(
23 'block',
24 __( 'Edit Block', 'blocks' ),
25 __( 'All Blocks', 'blocks' ),
26 'blocks_read_cms_blocks',
27 'block',
28 'blocks_admin_management_page'
29 );
30 add_action( 'load-' . $edit, 'blocks_load_admin' );
31
32 $addnew = add_submenu_page(
33 'block',
34 __( 'Add New Block', 'blocks' ),
35 __( 'Add New Block', 'blocks' ),
36 'blocks_edit_cms_blocks',
37 'block-new',
38 'blocks_admin_add_new_page'
39 );
40 add_action( 'load-' . $addnew, 'blocks_load_admin' );
41
42 add_submenu_page(
43 'block',
44 __( 'Categories', 'blocks' ),
45 __( 'Categories', 'blocks' ),
46 'manage_categories',
47 'edit-tags.php?taxonomy=blocks_category&post_type=wpcmsb_cms_block'
48 );
49
50 add_submenu_page(
51 'block',
52 __( 'Tags', 'blocks' ),
53 __( 'Tags', 'blocks' ),
54 'manage_categories',
55 'edit-tags.php?taxonomy=blocks_tag&post_type=wpcmsb_cms_block'
56 );
57 }
58
59 // Pin admin-menu highlight to the Block parent on blocks_category / blocks_tag
60 // screens: wpcmsb_cms_block has show_ui=false, so WordPress cannot infer the
61 // parent menu and falls back to highlighting "Posts".
62 add_filter( 'parent_file', 'blocks_pin_taxonomy_parent_file' );
63 add_filter( 'submenu_file', 'blocks_pin_taxonomy_submenu_file', 10, 2 );
64
65 function blocks_pin_taxonomy_parent_file( $parent_file ) {
66 $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
67 if ( $screen && in_array( $screen->taxonomy, array( 'blocks_category', 'blocks_tag' ), true ) ) {
68 return 'block';
69 }
70 return $parent_file;
71 }
72
73 function blocks_pin_taxonomy_submenu_file( $submenu_file, $parent_file ) {
74 $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
75 if ( $screen && in_array( $screen->taxonomy, array( 'blocks_category', 'blocks_tag' ), true ) ) {
76 return 'edit-tags.php?taxonomy=' . $screen->taxonomy . '&post_type=wpcmsb_cms_block';
77 }
78 return $submenu_file;
79 }
80
81 // Add update badge late, after WordPress populates update transient.
82 add_action( 'admin_menu', 'blocks_admin_menu_update_badge', 999 );
83
84 /**
85 * Add update badge to Blocks menu (runs late to ensure transient is populated).
86 */
87 function blocks_admin_menu_update_badge() {
88 global $menu, $submenu;
89
90 if ( ! blocks_get_update_count() ) {
91 return;
92 }
93
94 $update_badge = ' <span class="awaiting-mod count-1"><span class="pending-count">1</span></span>';
95
96 // Add badge to main menu.
97 foreach ( $menu as $key => $item ) {
98 if ( isset( $item[2] ) && 'block' === $item[2] ) {
99 $menu[ $key ][0] .= $update_badge; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Admin menu badge requires direct $menu mutation.
100 break;
101 }
102 }
103
104 // Add "Update Available" submenu after "All Blocks".
105 if ( isset( $submenu['block'] ) && current_user_can( 'update_plugins' ) ) {
106 // Insert after position 0 (All Blocks).
107 $update_item = array(
108 __( 'Update Available', 'blocks' ) . $update_badge,
109 'update_plugins',
110 'plugins.php?plugin_status=upgrade',
111 __( 'Update Available', 'blocks' ),
112 );
113
114 // Find position after "All Blocks" (index 0).
115 array_splice( $submenu['block'], 1, 0, array( $update_item ) );
116 }
117 }
118
119 add_filter( 'set-screen-option', 'blocks_set_screen_options', 10, 3 );
120
121 function blocks_set_screen_options( $result, $option, $value ) {
122 if ( 'blocks_per_page' === $option ) {
123 return $value;
124 }
125 return $result;
126 }
127
128 function blocks_setup_screen_options() {
129 global $plugin_page;
130
131 if ( 'block' !== $plugin_page ) {
132 return;
133 }
134
135 $current_screen = get_current_screen();
136
137 if ( ! $current_screen ) {
138 return;
139 }
140
141 if ( ! class_exists( 'Blocks_List_Table' ) ) {
142 require_once BLOCKS_PLUGIN_DIR . '/includes/core/class-blocks-list-table.php';
143 }
144
145 add_filter(
146 'manage_' . $current_screen->id . '_columns',
147 array( 'Blocks_List_Table', 'define_columns' )
148 );
149
150 add_screen_option(
151 'per_page',
152 array(
153 'label' => __( 'Block', 'blocks' ),
154 'default' => 20,
155 'option' => 'blocks_per_page',
156 )
157 );
158 }
159
160 function blocks_load_admin() {
161 $action = blocks_current_action();
162
163 if ( 'save' === $action ) {
164 blocks_handle_save_action();
165 return;
166 }
167
168 if ( 'copy' === $action ) {
169 blocks_handle_copy_action();
170 return;
171 }
172
173 if ( 'delete' === $action ) {
174 blocks_handle_delete_action();
175 return;
176 }
177
178 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display check, no data modification.
179 if ( ! empty( $_GET['post'] ) ) {
180 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
181 $post_id = absint( $_GET['post'] );
182
183 if ( ! current_user_can( 'blocks_read_cms_blocks' ) ) {
184 wp_die( esc_html__( 'You are not allowed to access this page.', 'blocks' ) );
185 }
186
187 Blocks::get_instance( $post_id );
188 }
189
190 blocks_setup_screen_options();
191 }
192
193 add_action( 'admin_enqueue_scripts', 'blocks_admin_enqueue_scripts' );
194
195 function blocks_admin_enqueue_scripts( $hook_suffix ) {
196 if ( 'blocks_page_blocks-specials' === $hook_suffix ) {
197 wp_enqueue_style(
198 'blocks-specials',
199 blocks_plugin_url( 'assets/css/specials.css' ),
200 array(),
201 BLOCKS_VERSION,
202 'all'
203 );
204
205 wp_enqueue_script(
206 'blocks-specials',
207 blocks_plugin_url( 'assets/js/specials.js' ),
208 array(),
209 BLOCKS_VERSION,
210 true
211 );
212
213 return;
214 }
215
216 if ( ! in_array( $hook_suffix, array( 'toplevel_page_block', 'blocks_page_block-new' ), true ) ) {
217 return;
218 }
219
220 wp_enqueue_style(
221 'blocks-admin',
222 blocks_plugin_url( 'assets/css/admin.css' ),
223 array(),
224 BLOCKS_VERSION,
225 'all'
226 );
227
228 // The custom editor reuses WordPress's publish and postbox interactions.
229 // The list screen only needs Blocks' shortcode-copy behavior.
230 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing.
231 $is_editor = 'blocks_page_block-new' === $hook_suffix || isset( $_GET['post'] );
232 if ( $is_editor ) {
233 wp_enqueue_script( 'post' );
234 }
235
236 wp_enqueue_script(
237 'blocks-admin',
238 blocks_plugin_url( 'assets/js/admin.js' ),
239 array(),
240 BLOCKS_VERSION,
241 true
242 );
243
244 }
245
246 add_action( 'blocks_admin_notices', 'blocks_admin_updated_message' );
247
248 function blocks_admin_updated_message() {
249 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only, shows success message after redirect.
250 if ( empty( $_REQUEST['message'] ) ) {
251 return;
252 }
253
254 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
255 $message_key = sanitize_key( $_REQUEST['message'] );
256
257 $messages = array(
258 'created' => __( 'Block created.', 'blocks' ),
259 'saved' => __( 'Block saved.', 'blocks' ),
260 'deleted' => __( 'Block deleted.', 'blocks' ),
261 );
262
263 $message = $messages[ $message_key ] ?? '';
264
265 if ( $message ) {
266 echo '<div id="message" class="updated"><p>' . esc_html( $message ) . '</p></div>';
267 }
268 }
269
270 add_action( 'blocks_admin_notices', 'blocks_admin_not_allowed_notice' );
271
272 function blocks_admin_not_allowed_notice() {
273 $cms_block = blocks_get_current();
274 if ( ! $cms_block ) {
275 return;
276 }
277
278 if ( current_user_can( 'blocks_edit_cms_block', $cms_block->id() ) ) {
279 return;
280 }
281
282 printf(
283 '<div class="notice notice-warning"><p>%s</p></div>',
284 esc_html( __( 'You are not allowed to edit this Block.', 'blocks' ) )
285 );
286 }
287
288 add_filter( 'plugin_action_links', 'blocks_plugin_action_links', 10, 2 );
289
290 function blocks_plugin_action_links( $links, $file ) {
291 if ( BLOCKS_PLUGIN_BASENAME !== $file ) {
292 return $links;
293 }
294
295 $settings_link = '<a href="' . menu_page_url( 'block', false ) . '">' . esc_html( __( 'Settings', 'blocks' ) ) . '</a>';
296 array_unshift( $links, $settings_link );
297
298 return $links;
299 }
300
301 /**
302 * Check if the Blocks plugin has an update available.
303 *
304 * @return int 1 if update available, 0 otherwise.
305 */
306 function blocks_get_update_count() {
307 $update_data = get_site_transient( 'update_plugins' );
308
309 if ( ! is_object( $update_data ) || ! isset( $update_data->response ) ) {
310 return 0;
311 }
312
313 // Only check for Blocks plugin updates, not all plugins.
314 return isset( $update_data->response[ BLOCKS_PLUGIN_BASENAME ] ) ? 1 : 0;
315 }
316