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