PluginProbe
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts / trunk
Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts vtrunk
2.7.6 2.7.5 2.7.4 trunk 1.3 2.0.4 2.0.6 2.1.91 2.2.4 2.2.7 2.2.9 2.3.1 2.3.10 2.4.10 2.4.2 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.6.0 2.6.1 2.7.0 2.7.1 All 27 releases
insert-php / admin / includes / class.snippets.viewtable.php

class.snippets.viewtable.php in Woody Code Snippets – Insert PHP, CSS, JS, and Header/Footer Scripts trunk, at admin/includes/class.snippets.viewtable.php

427 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Snippets View Table
4 *
5 * @package Woody_Code_Snippets
6 */
7
8 // Exit if accessed directly
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class WINP_SnippetsViewTable
15 *
16 * Handles the custom columns and display for snippets list table.
17 */
18 class WINP_SnippetsViewTable {
19
20 /**
21 * Custom columns.
22 *
23 * @var array<string, string>
24 */
25 private $columns = [];
26
27 /**
28 * Constructor.
29 */
30 public function __construct() {
31 $this->setup_hooks();
32 }
33
34 /**
35 * Setup WordPress hooks.
36 *
37 * @return void
38 */
39 private function setup_hooks() {
40 // Define columns.
41 $this->columns = [
42 'winp_actions' => __( 'Status', 'insert-php' ),
43 'title' => __( 'Snippet title', 'insert-php' ),
44 'winp_description' => __( 'Description', 'insert-php' ),
45 'winp_where_use' => __( 'Location', 'insert-php' ),
46 'winp_taxonomy' => __( 'Tags', 'insert-php' ),
47 'winp_priority' => __( 'Priority', 'insert-php' ),
48 'winp_snippet_type' => '',
49 ];
50
51 // Columns.
52 add_filter( 'manage_edit-' . WINP_SNIPPETS_POST_TYPE . '_columns', [ $this, 'setup_columns' ] );
53 add_action( 'manage_' . WINP_SNIPPETS_POST_TYPE . '_posts_custom_column', [ $this, 'render_column' ], 10, 2 );
54 add_filter( 'manage_edit-' . WINP_SNIPPETS_POST_TYPE . '_sortable_columns', [ $this, 'sortable_columns' ] );
55
56 // Scripts and styles.
57 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
58
59 // Row actions.
60 add_filter( 'post_row_actions', [ $this, 'modify_row_actions' ], 10, 2 );
61 add_filter( 'bulk_actions-edit-' . WINP_SNIPPETS_POST_TYPE, [ $this, 'modify_bulk_actions' ] );
62
63 // AJAX actions.
64 add_action( 'wp_ajax_change_priority', [ $this, 'change_priority' ] );
65 add_action( 'wp_ajax_change_snippet_status', [ $this, 'change_snippet_status' ] );
66
67 // Run actions on admin_init to ensure proper loading order.
68 add_action( 'admin_init', [ $this, 'run_actions' ] );
69 }
70
71 /**
72 * Setup custom columns.
73 *
74 * @param array<string, string> $columns Existing columns.
75 * @return array<string, string> Modified columns.
76 */
77 public function setup_columns( $columns ) {
78 unset( $columns ); // Unused, we define our own columns.
79 $new_columns = [];
80 $new_columns['cb'] = '<input type="checkbox" />';
81
82 foreach ( $this->columns as $id => $title ) {
83 $new_columns[ $id ] = $title;
84 }
85
86 return $new_columns;
87 }
88
89 /**
90 * Render custom column content.
91 *
92 * @param string $column Column name.
93 * @param int $post_id Post ID.
94 * @return void
95 */
96 public function render_column( $column, $post_id ) {
97 $post = get_post( $post_id );
98 $method_name = 'column_' . $column;
99
100 if ( method_exists( $this, $method_name ) && is_callable( [ $this, $method_name ] ) ) {
101 $this->{$method_name}( $post );
102 }
103 }
104
105 /**
106 * Enqueue scripts and styles.
107 *
108 * @param string $hook Current admin page hook.
109 * @return void
110 */
111 public function enqueue_assets( $hook ) {
112 if ( 'edit.php' !== $hook ) {
113 return;
114 }
115
116 $screen = get_current_screen();
117 if ( ! $screen || WINP_SNIPPETS_POST_TYPE !== $screen->post_type ) {
118 return;
119 }
120
121 wp_enqueue_style( 'winp-list-table', WINP_PLUGIN_URL . '/admin/assets/css/list-table.css', [], WINP_PLUGIN_VERSION );
122 wp_enqueue_script( 'winp-snippet-list', WINP_PLUGIN_URL . '/admin/assets/js/snippet-list.js', [ 'jquery' ], WINP_PLUGIN_VERSION, true );
123 wp_localize_script( 'winp-snippet-list', 'winp_ajax', [ 'nonce' => wp_create_nonce( 'winp_ajax' ) ] );
124 }
125
126 /**
127 * Modify row actions.
128 *
129 * @param array<string, string> $actions Existing actions.
130 * @param WP_Post $post Post object.
131 * @return array<string, string> Modified actions.
132 */
133 public function modify_row_actions( $actions, $post ) {
134 if ( WINP_SNIPPETS_POST_TYPE !== $post->post_type ) {
135 return $actions;
136 }
137
138 // Remove quick edit for non-public types.
139 unset( $actions['inline hide-if-no-js'] );
140
141 return $actions;
142 }
143
144 /**
145 * Modify bulk actions.
146 *
147 * @param array<string, string> $actions Existing actions.
148 * @return array<string, string> Modified actions.
149 */
150 public function modify_bulk_actions( $actions ) {
151 // Remove bulk edit.
152 unset( $actions['edit'] );
153
154 return $actions;
155 }
156
157 /**
158 * Column 'Type'
159 *
160 * @param WP_Post $post Post object.
161 * @return void
162 */
163 public function column_winp_snippet_type( $post ) {
164 $type = WINP_Helper::getMetaOption( $post->ID, 'snippet_type', WINP_SNIPPET_TYPE_PHP );
165 $class = 'wbcr-inp-type-' . esc_attr( $type );
166 $type = $type == 'universal' ? 'uni' : $type;
167 $type = $type == 'advert' ? 'ad' : $type;
168
169 echo '<div class="wbcr-inp-snippet-type-label ' . esc_attr( $class ) . '">' . esc_html( $type ) . '</div>';
170 }
171
172 /**
173 * Column 'Description'
174 *
175 * @param WP_Post $post Post object.
176 * @return void
177 */
178 public function column_winp_description( $post ) {
179 echo esc_html( WINP_Helper::getMetaOption( $post->ID, 'snippet_description' ) );
180 }
181
182 /**
183 * Column 'Where_use'
184 *
185 * @param WP_Post $post Post object.
186 * @return void
187 */
188 public function column_winp_where_use( $post ) {
189 $value = WINP_Helper::get_where_use_text( $post );
190
191 $is_shortcode = ( strpos( $value, '[' ) === 0 && strrpos( $value, ']' ) === strlen( $value ) - 1 );
192
193 if ( $is_shortcode ) {
194 echo "<div style='position: relative; display: inline-flex; align-items: center; width: 100%;'>";
195 echo "<span class='dashicons dashicons-clipboard' style='position: absolute; left: 8px; pointer-events: none; color: #2271b1;'></span>";
196 echo "<input type='text' name='wbcr_inp_shortcode_input' class='wbcr_inp_shortcode_input' value='" . esc_attr( $value ) . "' readonly='readonly' style='cursor: pointer; padding-left: 35px; width: 100%;'>";
197 echo '</div>';
198 } else {
199 echo esc_html( $value );
200 }
201 }
202
203 /**
204 * Column 'Taxonomy'
205 *
206 * @param WP_Post $post Post object.
207 * @return void
208 */
209 public function column_winp_taxonomy( $post ) {
210 $post_cat = get_the_terms( $post->ID, WINP_SNIPPETS_TAXONOMY );
211 $result = [];
212 if ( is_array( $post_cat ) ) {
213 foreach ( $post_cat as $item ) {
214 $href = admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE . "&winp_filter_tag={$item->slug}" );
215 $result[] = "<a href='{$href}' class='winp-taxonomy-href'>{$item->name}</a>";
216 }
217 }
218 echo implode( ', ', $result );
219 }
220
221 /**
222 * Column 'Priority'
223 *
224 * @param WP_Post $post Post object.
225 * @return void
226 */
227 public function column_winp_priority( $post ) {
228 $snippet_priority = WINP_Helper::getMetaOption( $post->ID, 'snippet_priority' );
229 echo "<input type='number' name='wbcr_inp_input_priority' class='wbcr_inp_input_priority'
230 data-snippet-id='{$post->ID}' value='{$snippet_priority}'>";
231 }
232
233 /**
234 * Column 'Actions'
235 *
236 * @param WP_Post $post Post object.
237 * @return void
238 */
239 public function column_winp_actions( $post ) {
240 $post_id = (int) $post->ID;
241 $is_activate = (int) WINP_Helper::getMetaOption( $post_id, 'snippet_activate', 0 );
242 $css_class = 'winp-inactive';
243
244 if ( $is_activate ) {
245 $css_class = '';
246 }
247
248 $url = wp_nonce_url(
249 admin_url( 'edit.php?post_type=' . WINP_SNIPPETS_POST_TYPE . '&amp;post=' . $post_id . '&amp;action=wbcr_inp_activate_snippet' ),
250 'wbcr_inp_snippert_' . $post_id . '_action_nonce'
251 );
252
253 echo '<a class="winp-snippet-active-switch ' . esc_attr( $css_class ) . '" id="winp-snippet-status-switch" data-snippet-id="' . esc_attr( (string) $post_id ) . '" href="' . esc_url( $url ) . '">&nbsp;</a>';
254 }
255
256 /**
257 * Activate/Deactivate snippet
258 *
259 * @return void
260 */
261 public function run_actions() {
262 if ( WINP_HTTP::get( 'post_type', '', true ) == WINP_SNIPPETS_POST_TYPE ) {
263 $post = WINP_HTTP::get( 'post', 0 );
264 $action = WINP_HTTP::get( 'action', '', 'sanitize_key' );
265
266 if ( ! empty( $action ) && ! empty( $post ) && 'wbcr_inp_activate_snippet' == $action ) {
267 $post_id = (int) $post;
268 $wpnonce = WINP_HTTP::get( '_wpnonce', '' );
269
270 if ( ! wp_verify_nonce( $wpnonce, 'wbcr_inp_snippert_' . $post_id . '_action_nonce' ) || ! WINP_Plugin::app()->current_user_car() ) {
271 wp_die( 'Permission error. You can not edit this page.' );
272 }
273
274 $is_activate = (int) WINP_Helper::getMetaOption( $post_id, 'snippet_activate', 0 );
275 $snippet_scope = WINP_Helper::getMetaOption( $post_id, 'snippet_scope' );
276 $snippet_type = WINP_Helper::get_snippet_type( $post_id );
277
278 /**
279 * Prevent activation of the snippet if it contains an error. This will not allow the user to break his site.
280 *
281 * @since 2.0.5
282 */
283 if ( ( 'evrywhere' == $snippet_scope || 'auto' == $snippet_scope ) && $snippet_type != WINP_SNIPPET_TYPE_TEXT && $snippet_type != WINP_SNIPPET_TYPE_AD && $snippet_type != WINP_SNIPPET_TYPE_CSS && $snippet_type != WINP_SNIPPET_TYPE_JS && ! $is_activate ) {
284 if ( WINP_Plugin::app()->get_execute_object()->getSnippetError( $post_id ) ) {
285 wp_safe_redirect(
286 add_query_arg(
287 [
288 'action' => 'edit',
289 'post' => $post_id,
290 'wbcr_inp_save_snippet_result' => 'code-error',
291 ],
292 admin_url( 'post.php' )
293 )
294 );
295 exit;
296 }
297 }
298
299 $status = ! $is_activate;
300
301 update_post_meta( $post_id, 'wbcr_inp_snippet_activate', $status );
302
303 $redirect_url = add_query_arg(
304 [
305 'post_type' => WINP_SNIPPETS_POST_TYPE,
306 'wbcr_inp_snippet_updated' => 1,
307 ],
308 admin_url( 'edit.php' )
309 );
310
311 wp_safe_redirect( $redirect_url );
312 exit;
313 }
314 }
315 }
316
317 /**
318 * Make columns sortable.
319 *
320 * @param array<string, string> $sortable_columns Existing sortable columns.
321 * @return array<string, string> Modified sortable columns.
322 */
323 public function sortable_columns( $sortable_columns ) {
324 $sortable_columns['winp_priority'] = 'winp_priority';
325
326 return $sortable_columns;
327 }
328
329 /**
330 * AJAX action for change priority.
331 *
332 * @return void
333 */
334 public function change_priority() {
335 check_ajax_referer( 'winp_ajax' );
336
337 if ( ! current_user_can( 'manage_options' ) ) {
338 wp_send_json( [ 'error_message' => __( "You don't have permission to edit this.", 'insert-php' ) ] );
339 }
340
341 if ( isset( $_POST['snippet_id'] ) && isset( $_POST['priority'] ) ) {
342 if ( is_numeric( $_POST['priority'] ) ) {
343 WINP_Helper::updateMetaOption( $_POST['snippet_id'], 'snippet_priority', $_POST['priority'] );
344
345 wp_send_json(
346 [
347 'message' => __( 'Priority successfully changed', 'insert-php' ),
348 ]
349 );
350 } else {
351 wp_send_json(
352 [
353 'error_message' => __( 'Priority was not changed. It must be a number.', 'insert-php' ),
354 ]
355 );
356 }
357 } else {
358 wp_send_json(
359 [
360 'error_message' => __( 'Priority is not changed!', 'insert-php' ),
361 ]
362 );
363 }
364 }
365
366 /**
367 * AJAX action for change snippet status.
368 *
369 * @return void
370 */
371 public function change_snippet_status() {
372 check_ajax_referer( 'winp_ajax' );
373
374 if ( ! current_user_can( 'manage_options' ) ) {
375 wp_send_json( [ 'error_message' => __( "You don't have permission to edit this.", 'insert-php' ) ] );
376 }
377
378 if ( isset( $_POST['snippet_id'] ) ) {
379 $snippet_id = $_POST['snippet_id'];
380 $is_activate = (int) WINP_Helper::getMetaOption( $snippet_id, 'snippet_activate', 0 );
381 $snippet_scope = WINP_Helper::getMetaOption( $snippet_id, 'snippet_scope' );
382 $snippet_type = WINP_Helper::get_snippet_type( $snippet_id );
383
384 /**
385 * Prevent activation of the snippet if it contains an error. This will not allow the user to break his site.
386 *
387 * @since 2.0.5
388 */
389 if ( ( 'evrywhere' == $snippet_scope || 'auto' == $snippet_scope ) && $snippet_type != WINP_SNIPPET_TYPE_TEXT && $snippet_type != WINP_SNIPPET_TYPE_AD && $snippet_type != WINP_SNIPPET_TYPE_CSS && $snippet_type != WINP_SNIPPET_TYPE_JS && ! $is_activate ) {
390 if ( WINP_Plugin::app()->get_execute_object()->getSnippetError( $snippet_id ) ) {
391 wp_send_json(
392 [
393 'alert' => true,
394 'error_message' => __( 'This snippet was not activated due to code errors. Please fix the errors and try again.', 'insert-php' ),
395 ]
396 );
397 }
398 }
399
400 $status = ! $is_activate;
401
402 $ok = update_post_meta( $snippet_id, 'wbcr_inp_snippet_activate', $status );
403
404 if ( $ok ) {
405 wp_send_json(
406 [
407 'message' => __( 'Snippet status changed', 'insert-php' ),
408 ]
409 );
410 } else {
411 wp_send_json(
412 [
413 'error_message' => __( 'Snippet status could not be changed. Please try again or check your permissions.', 'insert-php' ),
414 ]
415 );
416
417 }
418 } else {
419 wp_send_json(
420 [
421 'error_message' => __( 'Could not update snippet status. Please refresh and try again.', 'insert-php' ),
422 ]
423 );
424 }
425 }
426 }
427