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