PluginProbe ʕ •ᴥ•ʔ
Code Manager / 1.0.7
Code Manager v1.0.7
1.0.47 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.3 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.4 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
code-manager / Code_Manager / Code_Manager_List.php
code-manager / Code_Manager Last commit date
Code_Manager.php 5 years ago Code_Manager_Export.php 5 years ago Code_Manager_Form.php 5 years ago Code_Manager_Import.php 5 years ago Code_Manager_Import_File.php 5 years ago Code_Manager_List.php 5 years ago Code_Manager_List_View.php 5 years ago Code_Manager_Model.php 5 years ago Code_Manager_Preview.php 5 years ago Code_Manager_Settings.php 5 years ago Code_Manager_Tabs.php 5 years ago Message_Box.php 5 years ago WP_List_Table.php 5 years ago
Code_Manager_List.php
1058 lines
1 <?php
2
3 namespace Code_Manager {
4
5 /**
6 * Class Code_Manager
7 *
8 * Implements list mode view for Code Manager. Extends WordPress class WP_List_Table.
9 *
10 * @author Peter Schulz
11 * @since 1.0.0
12 */
13 class Code_Manager_List extends WP_List_Table {
14
15 /**
16 * Row number in the list
17 *
18 * @var int
19 */
20 protected static $list_number = 0;
21
22 protected $code_types = [];
23
24 /**
25 * WP nonce to (de)activate preview mode for a specific code id
26 *
27 * @var string
28 */
29 protected $wpnonce;
30
31 public function __construct( $args = array() ) {
32 parent::__construct( $args );
33
34 $this->wpnonce = wp_create_nonce( 'code-manager-' . Code_manager::get_current_user_login() );
35 $code_manager_tabs_class = CODE_MANAGER_TAB_CLASS;
36 $code_manager_tabs = new $code_manager_tabs_class();
37 $code_type_groups = $code_manager_tabs->get_code_types();
38 $code_types = [''];
39 foreach ( $code_type_groups as $code_type_group ) {
40 foreach ( $code_type_group as $key => $value ) {
41 $this->code_types[ $key ] = $value;
42 }
43 }
44 }
45
46 /**
47 * Show list table
48 *
49 * @since 1.0.0
50 */
51 public function show() {
52 ?>
53 <div class="wrap">
54 <?php
55 $this->show_title();
56 $this->show_body();
57 ?>
58 </div>
59 <script type="text/javascript">
60 var wpnonce = '<?php echo $this->wpnonce; ?>';
61 jQuery(function () {
62 jQuery('#cb-select-all-1').on('click', function (event) {
63 if (jQuery('#cb-select-all-1').is(':checked')) {
64 jQuery('[name="bulk-selected[]"]').prop('checked', true);
65 jQuery('#cb-select-all-2').prop('checked', true);
66 } else {
67 jQuery('[name="bulk-selected[]"]').prop('checked', false);
68 jQuery('#cb-select-all-2').prop('checked', false);
69 }
70 });
71 jQuery('#cb-select-all-2').on('click', function (event) {
72 if (jQuery('#cb-select-all-2').is(':checked')) {
73 jQuery('[name="bulk-selected[]"]').prop('checked', true);
74 jQuery('#cb-select-all-1').prop('checked', true);
75 } else {
76 jQuery('[name="bulk-selected[]"]').prop('checked', false);
77 jQuery('#cb-select-all-1').prop('checked', false);
78 }
79 });
80 });
81 </script>
82 <?php
83 }
84
85 /**
86 * Add title to page
87 *
88 * @since 1.0.0
89 */
90 protected function show_title() {
91 ?>
92 <h1 class="wp-heading-inline">
93 <span>
94 <span class="cm_page_title">
95 <?php echo CODE_MANAGER_H1_TITLE; ?>
96 </span>
97 <a href="?page=<?php echo CODE_MANAGER_MENU_SLUG; ?>&tabmode=on"
98 title="Switch to tab mode to work open multiple code editors simultaneously">
99 <span class="material-icons cm_menu_title">tab</span></a>
100 <a href="?page=<?php echo CODE_MANAGER_MENU_SLUG; ?>&action=new"
101 title="Add new code"
102 id="header_new">
103 <span class="material-icons cm_menu_title">add_circle_outline</span></a>
104 <a href="javascript:void(0)" title="Import code"
105 onclick="jQuery('#upload_file_container').toggle()">
106 <span class="material-icons cm_menu_title">arrow_circle_up</span></a>
107 <a href="<?php echo CODE_MANAGER_HELP_URL; ?>" target="_blank"
108 title="Plugin help - opens in a new tab or window">
109 <span class="material-icons cm_menu_title">help_outline</span></a>
110 </span>
111 </h1>
112 <?php
113 }
114
115 /**
116 * Add page body
117 *
118 * JavaScript depending on server variables not available in the browser are added here. Generic JavaScript
119 * code is added as a script file.
120 *
121 * @since 1.0.0
122 */
123 protected function show_body() {
124 $code_manager_selected_code_type = '';
125 if ( isset( $_REQUEST['selected_code_type'] ) ) {
126 $code_manager_selected_code_type = sanitize_text_field( wp_unslash( $_REQUEST['selected_code_type'] ) );
127 } elseif ( isset( $_COOKIE[CODE_MANAGER_COOKIES_LIST] ) ) {
128 $code_manager_selected_code_type = $_COOKIE[CODE_MANAGER_COOKIES_LIST];
129 }
130
131 $this->add_import_container();
132 ?>
133 <iframe id="cm_stealth_mode" style="display:none;"></iframe>
134 <div id="cm_invisible_container" style="display:none;"></div>
135 <div>
136 <form id="cm_list_table" method="post" action="?page=<?php echo CODE_MANAGER_MENU_SLUG; ?>">
137 <?php
138 $this->show_form();
139 ?>
140 </form>
141 </div>
142 <script type="text/javascript">
143 var code_manager_code_groups = [];
144 <?php
145 $code_manager_tab_class = CODE_MANAGER_TAB_CLASS;
146 $code_manager_tab = new $code_manager_tab_class();
147 $code_types = $code_manager_tab->get_code_types();
148 foreach ( $code_types as $code_type_group => $value ) {
149 echo 'code_manager_code_group = [];';
150 foreach ( $value as $code_type => $code_type_label ) {
151 echo "code_manager_code_group['{$code_type}'] = '{$code_type_label}';";
152 }
153 echo "code_manager_code_groups['{$code_type_group}'] = code_manager_code_group;";
154 }
155 ?>
156 var code_manager_selected_code_type = '<?php echo $code_manager_selected_code_type; ?>';
157 </script>
158 <?php
159 }
160
161 /**
162 * Add form to page (including search box)
163 *
164 * @since 1.0.0
165 */
166 protected function show_form() {
167 $this->prepare_items();
168 $this->search_box( 'search', 'search_id' );
169 $this->display();
170 wp_nonce_field( 'code-manager-export' . Code_manager::get_current_user_login(), '_expnonce', false );
171 wp_nonce_field( 'code-manager-delete' . Code_manager::get_current_user_login(), '_delnonce', false );
172 }
173
174 /**
175 * Add import container to list table
176 *
177 * @since 1.0.0
178 */
179 public function add_import_container() {
180 $file_uploads_enabled = @ini_get( 'file_uploads' );
181 ?>
182 <script type='text/javascript'>
183 function before_submit_upload() {
184 if (jQuery('#filename').val() == '') {
185 alert('<?php echo __( 'No file to import!', 'code-manager' ); ?>');
186 return false;
187 }
188 if (!(jQuery('#filename')[0].files[0].size < <?php echo Code_Manager_Export::convert_memory_to_decimal( @ini_get( 'upload_max_filesize' ) ); ?>)) {
189 alert("<?php echo __( 'File exceeds maximum size of', 'code-manager' ); ?> <?php echo @ini_get( 'upload_max_filesize' ); ?>!");
190 return false;
191 }
192 }
193 </script>
194 <style>
195 .cm_upload {
196 background: #fff;
197 border-top: 1px solid #ccc;
198 border-bottom: 1px solid #ccc;
199 padding-left: 20px;
200 padding-bottom: 10px;
201 }
202 </style>
203 <div id="upload_file_container" style="display: none">
204 <br/>
205 <div class="cm_upload">
206 <?php if ( $file_uploads_enabled ) { ?>
207 <p>
208 <strong><?php echo __( 'IMPORTS CODE MANAGER DATA ONLY', 'code-manager' ); ?></strong>
209 </p>
210 <p>
211 <?php
212 echo __( 'Supports only file type', 'code-manager' ) .
213 ' <strong>sql</strong>. ' .
214 __( 'Maximum supported file size is', 'code-manager' ) .
215 ' <strong>' . @ini_get( 'upload_max_filesize' ) . '</strong>.';
216 ?>
217 </p>
218 <form id="form_import_table" method="post" enctype="multipart/form-data">
219 <input type="file" name="filename" id="filename" accept=".sql">
220 <input type="submit" value="<?php echo __( 'Import file', 'code-manager' ); ?>"
221 class="button button-secondary"
222 onclick="return before_submit_upload()">
223 <input type="button"
224 onclick="jQuery('#upload_file_container').hide()"
225 class="button button-secondary"
226 value="<?php echo __( 'Cancel', 'code-manager' ); ?>">
227 <input type="hidden" name="action" value="import">
228 <?php wp_nonce_field( 'code-manager-import' . Code_manager::get_current_user_login(), '_impnonce', false ); ?>
229 </form>
230 <?php } else { ?>
231 <p>
232 <strong><?php echo __( 'ERROR', 'code-manager' ); ?></strong>
233 </p>
234 <p>
235 <?php
236 echo __( 'Your configuration does not allow file uploads!', 'code-manager' );
237 echo ' ';
238 echo __( 'Set', 'code-manager' );
239 echo ' <strong>';
240 echo __( 'file_uploads', 'code-manager' );
241 echo '</strong> ';
242 echo __( 'to', 'code-manager' );
243 echo ' <strong>';
244 echo __( 'On', 'code-manager' );
245 echo '.';
246 echo '</strong>';
247 ?>
248 </p>
249 <?php } ?>
250 </div>
251 <div>&nbsp;</div>
252 </div>
253 <?php
254 }
255
256 /**
257 * Perform database query
258 *
259 * Called from method prepare_items().
260 *
261 * @since 1.0.0
262 *
263 * @param int $per_page Items shown per page
264 * @param int $page_number Current page number
265 *
266 * @return array Contains rows found
267 */
268 public static function get_codes( $per_page = 10, $page_number = 1 ) {
269 global $wpdb;
270
271 $where = '';
272
273 $selected_code_type = '';
274 if ( isset( $_REQUEST['selected_code_type'] ) && '' !== $_REQUEST['selected_code_type'] ) {
275 if ( '*' === $_REQUEST['selected_code_type'] ) {
276 $selected_code_type = '';
277 } else {
278 $selected_code_type = sanitize_text_field( wp_unslash( $_REQUEST['selected_code_type'] ) ); // input var okay.
279 }
280 } elseif ( isset( $_COOKIE[CODE_MANAGER_COOKIES_LIST] ) ) {
281 if ( '*' === $_COOKIE[CODE_MANAGER_COOKIES_LIST] ) {
282 $selected_code_type = '';
283 } else {
284 $selected_code_type = $_COOKIE[CODE_MANAGER_COOKIES_LIST];
285 }
286 }
287 if ( '' !== $selected_code_type ) {
288 $where .= $wpdb->prepare(
289 " where `code_type` = %s",
290 [
291 $selected_code_type,
292 ]
293 ); // WPCS: unprepared SQL OK.
294 }
295
296 $search_value = '';
297 if ( isset( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) ) {
298 $search_value = sanitize_text_field( wp_unslash( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) ); // input var okay.
299 } elseif ( isset( $_COOKIE[ CODE_MANAGER_COOKIES_SEARCH ] ) ) {
300 $search_value = $_COOKIE[ CODE_MANAGER_COOKIES_SEARCH ];
301 }
302 if ( '' !== $search_value ) {
303 $where_or_and = ''===$where ? 'where' : 'and';
304 $where .= $wpdb->prepare(
305 " {$where_or_and} (`code_name` like '%s' " .
306 " or `code_type` like '%s'" .
307 " or `code` like '%s')",
308 [
309 '%' . esc_sql( $search_value ) . '%',
310 '%' . esc_sql( $search_value ) . '%',
311 '%' . esc_sql( $search_value ) . '%',
312 ]
313 ); // WPCS: unprepared SQL OK.
314 }
315
316 $code_manager_model_class = CODE_MANAGER_MODEL_CLASS;
317 $code_manager_model = new $code_manager_model_class();
318 $sql = "select * from " . $code_manager_model::get_base_table_name();
319 if ( '' !== $where ) {
320 $sql .= $where;
321 }
322 if ( ! empty( $_REQUEST['orderby'] ) ) {
323 $sql .= ' ORDER BY ' . esc_sql( $_REQUEST['orderby'] );
324 $sql .= ! empty( $_REQUEST['order'] ) ? ' ' . esc_sql( $_REQUEST['order'] ) : ' ASC';
325 }
326 $sql .= " LIMIT $per_page";
327 $sql .= ' OFFSET ' . ( $page_number - 1 ) * $per_page;
328
329 $result = $wpdb->get_results( $sql, 'ARRAY_A' );
330 return $result;
331 }
332
333 /**
334 * Return number of records found
335 *
336 * @since 1.0.0
337 *
338 * @param int $per_page Items shown per page
339 * @param int $page_number Current page number
340 *
341 * @return array Contains rows found
342 */
343 public static function record_count() {
344 global $wpdb;
345
346 $where = '';
347
348 $selected_code_type = '';
349 if ( isset( $_REQUEST['selected_code_type'] ) && '' !== $_REQUEST['selected_code_type'] ) {
350 if ( '*' === $_REQUEST['selected_code_type'] ) {
351 $selected_code_type = '';
352 } else {
353 $selected_code_type = sanitize_text_field( wp_unslash( $_REQUEST['selected_code_type'] ) ); // input var okay.
354 }
355 } elseif ( isset( $_COOKIE[CODE_MANAGER_COOKIES_LIST] ) ) {
356 if ( '*' === $_COOKIE[CODE_MANAGER_COOKIES_LIST] ) {
357 $selected_code_type = '';
358 } else {
359 $selected_code_type = $_COOKIE[CODE_MANAGER_COOKIES_LIST];
360 }
361 }
362 if ( '' !== $selected_code_type ) {
363 $where .= $wpdb->prepare(
364 " where `code_type` = %s",
365 [
366 $selected_code_type,
367 ]
368 ); // WPCS: unprepared SQL OK.
369 }
370
371 $search_value = '';
372 if ( isset( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) ) {
373 $search_value = sanitize_text_field( wp_unslash( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) ); // input var okay.
374 } elseif ( isset( $_COOKIE[ CODE_MANAGER_COOKIES_SEARCH ] ) ) {
375 $search_value = $_COOKIE[ CODE_MANAGER_COOKIES_SEARCH ];
376 }
377 if ( '' !== $search_value ) {
378 $where_or_and = ''==$where ? 'where' : 'and';
379 $where .= $wpdb->prepare(
380 " {$where_or_and} (`code_name` like '%s' " .
381 " or `code_type` like '%s'" .
382 " or `code` like '%s')",
383 [
384 '%' . esc_attr( $search_value ) . '%',
385 '%' . esc_attr( $search_value ) . '%',
386 '%' . esc_attr( $search_value ) . '%',
387 ]
388 ); // WPCS: unprepared SQL OK.
389 }
390
391 $code_manager_model_class = CODE_MANAGER_MODEL_CLASS;
392 $code_manager_model = new $code_manager_model_class();
393 $sql = 'select count(*) from ' . $code_manager_model::get_base_table_name();
394 if ( '' !== $where ) {
395 $sql .= $where;
396 }
397
398 return $wpdb->get_var( $sql );
399 }
400
401 /**
402 * Overwrite method (WP_List_Table.)search_box to handle cookies in search
403 *
404 * @since 1.0.0
405 *
406 * @param string $text
407 * @param string $input_id
408 */
409 public function search_box( $text, $input_id ) {
410 // Always show search box!!!
411 // This plugin uses cookies. If the search box is disabled when nothing is found, it is not possible to
412 // remove the search criterion.
413
414 // if ( empty( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) && ! $this->has_items() ) {
415 // return;
416 // }
417
418 $input_id = $input_id . '-search-input';
419
420 $search_value = '';
421 if ( isset( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) ) {
422 $search_value = sanitize_text_field( wp_unslash( $_REQUEST[ CODE_MANAGER_SEARCH_ITEM_NAME ] ) ); // input var okay.
423 } elseif ( isset( $_COOKIE[ CODE_MANAGER_COOKIES_SEARCH ] ) ) {
424 $search_value = $_COOKIE[ CODE_MANAGER_COOKIES_SEARCH ];
425 }
426
427 if ( ! empty( $_REQUEST['orderby'] ) ) {
428 echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
429 }
430 if ( ! empty( $_REQUEST['order'] ) ) {
431 echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
432 }
433 if ( ! empty( $_REQUEST['post_mime_type'] ) ) {
434 echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
435 }
436 if ( ! empty( $_REQUEST['detached'] ) ) {
437 echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
438 }
439 ?>
440 <p class="search-box">
441 <label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php echo $text; ?>:</label>
442 <input type="search" id="<?php echo esc_attr( $input_id ); ?>" name="<?php echo CODE_MANAGER_SEARCH_ITEM_NAME; ?>" value="<?php echo $search_value; ?>" />
443 <?php submit_button( $text, '', '', false, array( 'id' => 'search-submit' ) ); ?>
444 </p>
445 <?php
446 }
447
448 /**
449 * Overwrite method (WP_List_Table.)display_tablenav to handle cookies
450 *
451 * If bulk actions are hidden when nothing is found, the user cannot change the code type selection.
452 *
453 * @since 1.0.0
454 *
455 * @param string $which
456 */
457 protected function display_tablenav( $which ) {
458 // Always show bulk actions
459 if ( 'top' === $which ) {
460 wp_nonce_field( 'bulk-' . $this->_args['plural'] );
461 }
462 ?>
463 <div class="tablenav <?php echo esc_attr( $which ); ?>">
464 <div class="alignleft actions bulkactions">
465 <?php $this->bulk_actions( $which ); ?>
466 </div>
467 <?php
468 $this->extra_tablenav( $which );
469 $this->pagination( $which );
470 ?>
471 <br class="clear" />
472 </div>
473 <?php
474 }
475
476 /**
477 * Overwrite method (WP_List_Table.)column_default to:
478 * (1) Add edit code link (@see Code_Manager_List::column_default_add_action_edit())
479 * (2) Add delete code link (@see Code_Manager_List::column_default_add_action_delete())
480 * (3) Add copy shortcode link (for shortcodes only)
481 * (4) Add code enable/disable checkbox/listbox
482 *
483 * @since 1.0.0
484 *
485 * @param object $item
486 * @param string $column_name
487 *
488 * @return mixed|string|void
489 */
490 public function column_default( $item, $column_name ) {
491 if ( 'code_id' === $column_name ) {
492 if ( ! isset( $this->code_types[ $item[ 'code_type' ] ] ) ) {
493 $actions['noactions'] = 'No actions';
494 } else {
495 $actions['edit'] = $this->column_default_add_action_edit( $item, $column_name );
496 $actions['delete'] = $this->column_default_add_action_delete( $item, $column_name );
497 }
498
499 return sprintf( '%1$s %2$s', $item[ $column_name ], $this->row_actions( $actions ) );
500 }
501
502 if ( 'code_type' === $column_name ) {
503 if ( strpos( $item[ $column_name ], 'shortcode' ) !== false ) {
504 $shortcode_id = '[' . CODE_MANAGER_SHORT_CODE . " id=\"{$item['code_id']}\"]";
505 $shortcode_name = '[' . CODE_MANAGER_SHORT_CODE . " name=\"{$item['code_name']}\"]";
506 $title = __( 'Copy shortcode to clipboard', 'code-manager' );
507 $message = __( 'Shortcode copied to clipboard', 'code-manager' );
508 if ( isset( $this->code_types[ $item[ $column_name ] ] ) ) {
509 $output = $this->code_types[ $item[ $column_name ] ] . '<div style="height:10px"></div>';
510 }
511 $output .= '<a href="javascript:void(0)" class="dashicons dashicons-image-rotate" ' .
512 'onclick="jQuery(\'#cm_copy_id_' . self::$list_number . '\').toggle(); ' .
513 'jQuery(\'#cm_copy_name_' . self::$list_number . '\').toggle();"' .
514 '></a>&nbsp;' .
515 '<span id="cm_copy_id_' . self::$list_number . '" style="display:none">' .
516 $shortcode_id . ' ' .
517 '<a href="javascript:void(0)" class="dashicons dashicons-clipboard c2c" ' .
518 "onclick='jQuery.notify(\"{$message}\", \"info\")' " .
519 "data-clipboard-text='{$shortcode_id}' title='{$title}'" .
520 '></a></span>' .
521 '<span id="cm_copy_name_' . self::$list_number . '">' .
522 $shortcode_name . ' ' .
523 '<a href="javascript:void(0)" class="dashicons dashicons-clipboard c2c" ' .
524 "onclick='jQuery.notify(\"{$message}\", \"info\")' " .
525 "data-clipboard-text='{$shortcode_name}' title='{$title}'" .
526 '></a></span>';
527 return $output;
528 } else {
529 if ( isset( $this->code_types[ $item[ $column_name ] ] ) ) {
530 return $this->code_types[ $item[ $column_name ] ];
531 }
532 }
533 return __( 'Unknown code type', 'code-manager' ) . ': ' . $item[ $column_name ];
534 }
535
536 if ( 'code_enabled' === $column_name ) {
537 $id = $item[ 'code_id' ];
538 $wp_nonce = wp_create_nonce( 'code-manager-' . Code_manager::get_current_user_login() );
539 $checked = 1 == $item['code_enabled'] ? 'checked' : '';
540 return
541 "<label style='white-space:nowrap' title='Enable code' class='cm_tooltip'>
542 <input type='checkbox'
543 id='code_enabled_{$id}'
544 $checked
545 onclick='activate_code($id,\"$wp_nonce\")'
546 >Enable
547 </label><br/>" .
548 $this->add_preview_switch( $id );
549 }
550
551 if ( 'code' === $column_name ) {
552 $code = '<pre>' . esc_html( str_replace( '&', '&amp;', $item[ $column_name ] ) ) . '</pre>';
553 $title = "({$item['code_id']}) {$item['code_name']} ({$item['code_type']})";
554
555 $function = 'show_code_' . self::$list_number;
556 $dialog = 'dialog_' . self::$list_number;
557
558 return
559 "<script type='text/javascript'>
560 function {$function}() {
561 html = `<div>{$code}</div>`;
562 height = jQuery(window).height() * 0.6;
563 var {$dialog} = jQuery(html).dialog({
564 dialogClass: 'no-close',
565 title: '{$title}',
566 modal: true,
567 width: '60%',
568 height: height,
569 buttons: {
570 'OK': function() {
571 {$dialog}.dialog('destroy');
572 }
573 }
574 });
575 }
576 </script>
577 <a href='javascript:void(0)' onclick='{$function}()'>
578 <span class='dashicons dashicons-editor-code cm_menu_title'
579 title='Click to view code'
580 ></span>
581 </a>";
582 }
583
584 return esc_html( str_replace( '&', '&amp;', $item[ $column_name ] ) );
585 }
586
587 protected function add_preview_switch( $id ) {
588 if ( Code_Manager_Preview::is_code_id_preview_enabled( $id ) ) {
589 $checked = 'checked';
590 } else {
591 $checked = '';
592 }
593 return "<label style='white-space:nowrap' title='Enable preview mode for this code' class='cm_tooltip'>
594 <input type='checkbox'
595 id='code_enabled_{$id}'
596 $checked
597 onclick='set_code_preview($id,\"{$this->wpnonce}\",jQuery(this).is(\":checked\"))'
598 >Preview
599 </label>";
600 }
601
602 /**
603 * Override method (WP_List_Table.)column_cb
604 *
605 * @since 1.0.0
606 *
607 * @param object $item
608 *
609 * @return string|void
610 */
611 public function column_cb( $item ) {
612 return "<input type='checkbox' name='bulk-selected[]' value='" . $item['code_id'] . "' />";
613 }
614
615 /**
616 * Adds edit code link to a given row
617 *
618 * @since 1.0.0
619 *
620 * @param $item
621 * @param $column_name
622 *
623 * @return string
624 */
625 protected function column_default_add_action_edit( $item, $column_name ) {
626 return '<a href="?page=' . CODE_MANAGER_MENU_SLUG .
627 '&action=edit&code_id=' . $item[ $column_name ] .
628 '" class="edit">Edit</a>';
629 }
630
631 /**
632 * Adds delete code link to a given row
633 *
634 * @since 1.0.0
635 *
636 * @param $item
637 * @param $column_name
638 *
639 * @return string
640 */
641 protected function column_default_add_action_delete( $item, $column_name ) {
642 $page = isset( $_REQUEST['paged'] ) ? $_REQUEST['paged'] : 1;
643
644 $wp_nonce = wp_create_nonce( 'code-manager-delete' . Code_manager::get_current_user_login() );
645 $form_id = '_' . ( self::$list_number++ );
646 $delete_form =
647 "<form" .
648 " id='delete_form$form_id'" .
649 " action='?page=" . CODE_MANAGER_MENU_SLUG . "'" .
650 " method='post'>" .
651 "<input type='hidden' name='code_id' value='{$item[ $column_name ]}'>" .
652 "<input type='hidden' name='action' value='delete' />" .
653 "<input type='hidden' name='paged' value='{$page}' />" .
654 "<input type='hidden' name='_wpnonce' value='{$wp_nonce}'>" .
655 "</form>";
656 ?>
657
658 <script type='text/javascript'>
659 jQuery("#cm_invisible_container").append("<?php echo $delete_form; ?>");
660 function delete_code<?php echo $form_id; ?>() {
661 html = "<div>You are about to permanently delete this code from your site. This action cannot be undone. 'No' to stop, 'Yes' to delete.</div>";
662 var dialog = jQuery(html).dialog({
663 dialogClass: 'no-close',
664 title: 'Delete code?',
665 buttons: {
666 'Yes': function() {
667 dialog.dialog('destroy');
668 jQuery('#delete_form<?php echo $form_id; ?>').submit();
669 },
670 'No': function() {
671 dialog.dialog('destroy');
672 },
673 'Cancel': function() {
674 dialog.dialog('destroy');
675 }
676 }
677 });
678 }
679 </script>
680
681 <?php
682 return sprintf(
683 '<a href="javascript:void(0)" class="delete" onclick="delete_code%s()">Delete</a>',
684 $form_id
685 );
686 }
687
688 /**
689 * Overwrite method to remove class fixed (prevents wrapping shortcode)
690 *
691 * @since 1.0.0
692 *
693 * @return array|string[]
694 */
695 protected function get_table_classes() {
696 return array( 'widefat', 'striped', $this->_args['plural'] );
697 }
698
699 /**
700 * Overrides method (WP_List_Table.)prepare_items
701 *
702 * @since 1.0.0
703 */
704 public function prepare_items() {
705 $columns = $this->get_columns();
706 $hidden = $this->get_hidden_columns();
707 $sortable = $this->get_sortable_columns();
708 $primary = $this->get_primary_column();
709 $this->_column_headers = [ $columns, $hidden, $sortable, $primary ];
710
711 $this->process_bulk_action();
712
713 $per_page = $this->get_items_per_page( 'code_manager_rows_per_page', 10 );
714 $current_page = $this->get_pagenum();
715 $total_items = static::record_count();
716
717 $this->set_pagination_args( [
718 'total_items' => $total_items,
719 'per_page' => $per_page
720 ] );
721
722 $this->items = static::get_codes( $per_page, $current_page );
723 }
724
725 /**
726 * Overrides method (WP_List_Table.)get_bulk_actions
727 *
728 * @since 1.0.0
729 *
730 * @return array|string[]
731 */
732 public function get_bulk_actions() {
733 $actions = [
734 'bulk-delete' => 'Delete Permanently',
735 'export' => 'Export',
736 ];
737
738 return $actions;
739 }
740
741 /**
742 * Implements bulk actions recognition
743 *
744 * @since 1.0.0
745 */
746 public function process_bulk_action() {
747 if ( 'delete' === $this->current_action() ) {
748 $this->code_delete();
749 } else if ( 'bulk-delete' === $this->current_action() ) {
750 $this->code_bulk_delete();
751 } elseif ( 'export' === $this->current_action() ) {
752 $this->code_export();
753 } elseif ( 'import' === $this->current_action() ) {
754 $this->code_import();
755 }
756 }
757
758 /**
759 * Implement code delete action
760 *
761 * @since 1.0.0
762 */
763 protected function code_delete() {
764 $wp_nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : ''; // input var okay.
765 if ( ! wp_verify_nonce( $wp_nonce, 'code-manager-delete' . Code_manager::get_current_user_login() ) ) {
766 $msg = new Message_Box(
767 [
768 'message_text' => __( 'Not authorized', 'code-manager' ),
769 'message_type' => 'error',
770 'message_is_dismissible' => false,
771 ]
772 );
773 $msg->box();
774
775 return;
776 }
777
778 if ( isset( $_REQUEST['code_id'] ) ) {
779 $code_id = sanitize_text_field( wp_unslash( $_REQUEST['code_id'] ) ); // input var okay.
780 $code_manager_model_class = CODE_MANAGER_MODEL_CLASS;
781 $code_manager_model = new $code_manager_model_class();
782 $delete_failed = 1 !== $code_manager_model::dml_delete( $code_id );
783 } else {
784 $delete_failed = true;
785 }
786
787 if ( $delete_failed ) {
788 $msg = new Message_Box(
789 [
790 'message_text' => __( 'Delete action failed', 'code-manager' ),
791 'message_type' => 'error',
792 'message_is_dismissible' => false,
793 ]
794 );
795 $msg->box();
796 } else {
797 $msg = new Message_Box(
798 [
799 'message_text' => __( 'Succesfully deleted code', 'code-manager' ),
800 ]
801 );
802 $msg->box();
803 }
804 }
805
806 /**
807 * Implement code delete bulk action
808 *
809 * @since 1.0.0
810 */
811 protected function code_bulk_delete() {
812 if ( isset( $_REQUEST['bulk-selected'] ) ) {
813 $wp_nonce = isset( $_REQUEST['_delnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_delnonce'] ) ) : ''; // input var okay.
814 if ( ! wp_verify_nonce( $wp_nonce, 'code-manager-delete' . Code_manager::get_current_user_login() ) ) {
815 $msg = new Message_Box(
816 [
817 'message_text' => __( 'Not authorized', 'code-manager' ),
818 'message_type' => 'error',
819 'message_is_dismissible' => false,
820 ]
821 );
822 $msg->box();
823
824 return;
825 }
826
827 $bulk_rows = $_REQUEST['bulk-selected'];
828 $delete_failed = 0;
829 for ( $i = 0; $i < count( $bulk_rows ); $i ++ ) {
830 $code_id = sanitize_text_field( wp_unslash( $_REQUEST['bulk-selected'][ $i ] ) ); // input var okay.
831 $code_manager_model_class = CODE_MANAGER_MODEL_CLASS;
832 $code_manager_model = new $code_manager_model_class();
833
834 if ( 1 !== $code_manager_model::dml_delete( $code_id ) ) {
835 $delete_failed ++;
836 }
837 }
838
839 if ( $delete_failed > 0 ) {
840 if ( $delete_failed === count( $bulk_rows ) ) {
841 $msg = new Message_Box(
842 [
843 'message_text' => __( 'Some delete actions failed', 'code-manager' ),
844 'message_type' => 'error',
845 'message_is_dismissible' => false,
846 ]
847 );
848 $msg->box();
849 } else {
850 $msg = new Message_Box(
851 [
852 'message_text' => __( 'Could not delete code', 'code-manager' ),
853 'message_type' => 'error',
854 'message_is_dismissible' => false,
855 ]
856 );
857 $msg->box();
858 }
859 } else {
860 $msg = new Message_Box(
861 [
862 'message_text' => __( 'Succesfully deleted code', 'code-manager' ),
863 ]
864 );
865 $msg->box();
866 }
867 } else {
868 $msg = new Message_Box(
869 [
870 'message_text' => __( 'Nothing to delete', 'code-manager' ),
871 ]
872 );
873 $msg->box();
874 }
875 }
876
877 /**
878 * Export code.
879 */
880 protected function code_export() {
881 if ( isset( $_REQUEST['bulk-selected'] ) ) {
882 $wp_nonce = isset( $_REQUEST['_expnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_expnonce'] ) ) : ''; // input var okay.
883 if ( ! wp_verify_nonce( $wp_nonce, 'code-manager-export' . Code_manager::get_current_user_login() ) ) {
884 $msg = new Message_Box(
885 [
886 'message_text' => __( 'Not authorized', 'code-manager' ),
887 'message_type' => 'error',
888 'message_is_dismissible' => false,
889 ]
890 );
891 $msg->box();
892
893 return;
894 }
895
896 $bulk_rows = $_REQUEST['bulk-selected'];
897 $code_ids = '';
898 $rows = 0;
899 for ( $i = 0; $i < count( $bulk_rows ); $i ++ ) {
900 $code_id = sanitize_text_field( wp_unslash( $_REQUEST['bulk-selected'][ $i ] ) ); // input var okay.
901 if ( is_numeric( $code_id ) ) {
902 $code_ids .= "&cid[{$rows}]={$code_id}";
903 $rows++;
904 }
905 }
906
907 // Prepare URL
908 $querystring = admin_url() . "admin.php?action=code_manager_export&wpnonce={$wp_nonce}{$code_ids}";
909
910 // Start export
911 echo '
912 <script type="text/javascript">
913 jQuery(function() {
914 jQuery("#cm_stealth_mode").attr("src","' . $querystring . '");
915 });
916 </script>
917 ';
918 } else {
919 $msg = new Message_Box(
920 [
921 'message_text' => __( 'Nothing to export', 'code-manager' ),
922 ]
923 );
924 $msg->box();
925 }
926 }
927
928 /**
929 * Import code.
930 */
931 protected function code_import() {
932 $wp_nonce = isset( $_REQUEST['_impnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_impnonce'] ) ) : ''; // input var okay.
933 if ( ! wp_verify_nonce( $wp_nonce, 'code-manager-import' . Code_manager::get_current_user_login() ) ) {
934 $msg = new Message_Box(
935 [
936 'message_text' => __( 'Not authorized', 'code-manager' ),
937 'message_type' => 'error',
938 'message_is_dismissible' => false,
939 ]
940 );
941 $msg->box();
942
943 return;
944 }
945
946 Code_Manager_Import::import();
947 }
948
949 /**
950 * Overrides method (WP_List_Table.)get_columns
951 *
952 * @since 1.0.0
953 *
954 * @return array
955 */
956 public function get_columns() {
957 return static::get_column_labels_default();
958 }
959
960 /**
961 * Returns all column labels
962 *
963 * Defined as static method to be used in multiple situations and maintained in one location.
964 *
965 * @since 1.0.0
966 *
967 * @return array
968 */
969 public static function get_column_labels_default() {
970 return [
971 'cb' => '<input type="checkbox" />',
972 'code_id' => __( 'ID', 'code-manager' ),
973 'code_name' => __( 'Name', 'code-manager' ),
974 'code_type' => __( 'Shortcode', 'code-manager' ),
975 'code_enabled' => __( 'Status', 'code-manager' ),
976 'code' => __( 'Code', 'code-manager' ),
977 'code_author' => __( 'Author', 'code-manager' ),
978 'code_description' => __( 'Description', 'code-manager' ),
979 ];
980 }
981
982 /**
983 * Returns hidden columns (taken from usermeta)
984 *
985 * @since 1.0.0
986 *
987 * @return string[]
988 */
989 public function get_hidden_columns() {
990 $hidden = get_user_meta(
991 get_current_user_id(),
992 'manage' . get_current_screen()->id . 'columnshidden'
993 );
994
995 return 0 === sizeof( $hidden ) ? self::get_hidden_columns_default() : $hidden[0];
996 }
997
998 /**
999 * Returns default hidden columns
1000 *
1001 * Can be changed by the user in screen options.
1002 *
1003 * @since 1.0.0
1004 *
1005 * @return string[]
1006 */
1007 public static function get_hidden_columns_default() {
1008 return [
1009 'code_url',
1010 'code',
1011 ];
1012 }
1013
1014 /**
1015 * Overrides method (WP_List_Table.)get_sortable_columns
1016 *
1017 * @since 1.0.0
1018 *
1019 * @return array|array[]
1020 */
1021 public function get_sortable_columns() {
1022 return self::_get_sortable_columns();
1023 }
1024
1025 /**
1026 * Get sortable columns
1027 *
1028 * Defined as static method to be used in multiple situations and maintained in one location.
1029 *
1030 * @since 1.0.0
1031 *
1032 * @return array[]
1033 */
1034 public static function _get_sortable_columns() {
1035 return [
1036 'code_id' => ['code_id', false],
1037 'code_name' => ['code_name', false],
1038 'code_type' => ['code_type', false],
1039 'code_enabled' => ['code_type', false],
1040 'code_author' => ['code_author', false],
1041 'code_description' => ['code_description', false],
1042 ];
1043 }
1044
1045 /**
1046 * Overrides method (WP_List_Table.)get_primary_column
1047 *
1048 * @since 1.0.0
1049 *
1050 * @return int|string
1051 */
1052 public function get_primary_column() {
1053 return 'code_id';
1054 }
1055
1056 }
1057
1058 }