PluginProbe
Admin Columns / 1.4.3
Admin Columns v1.4.3
7.1.4 7.0.19 2.3.5 2.4 2.4.1 2.4.10 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.6.1 2.5.6.2 2.5.6.3 2.5.6.4 3.0 3.0.1 All 113 releases
codepress-admin-columns / codepress-admin-columns.php
codepress-admin-columns.php
3,329 lines 88.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Codepress Admin Columns
4 Version: 1.4.3
5 Description: Customise columns on the administration screens for post(types), pages, media, comments, links and users with an easy to use drag-and-drop interface.
6 Author: Codepress
7 Author URI: http://www.codepress.nl
8 Plugin URI: http://www.codepress.nl/plugins/codepress-admin-columns/
9 Text Domain: codepress-admin-columns
10 Domain Path: /languages
11 License: GPLv2
12
13 Copyright 2011 Codepress info@codepress.nl
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License version 2 as published by
17 the Free Software Foundation.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29 define( 'CPAC_VERSION', '1.4.3' );
30
31 // only run plugin in the admin interface
32 if ( !is_admin() )
33 return false;
34
35 /**
36 * Dependencies
37 *
38 * @since 1.3
39 */
40 require_once dirname( __FILE__ ) . '/classes/sortable.php';
41
42 /**
43 * Codepress Admin Columns Class
44 *
45 * @since 1.0
46 *
47 */
48 class Codepress_Admin_Columns
49 {
50 private $post_types,
51 $slug,
52 $textdomain,
53 $codepress_url,
54 $wordpress_url,
55 $excerpt_length,
56 $admin_page,
57 $notice_message,
58 $notice_type,
59 $api_url;
60
61 /**
62 * Constructor
63 *
64 * @since 1.0
65 */
66 function __construct()
67 {
68 $this->api_url = 'http://www.codepress.nl/';
69
70 // wp is loaded
71 add_action( 'wp_loaded', array( $this, 'init') );
72 }
73
74 /**
75 * Initialize plugin.
76 *
77 * Loading sequence is determined and intialized.
78 *
79 * @since 1.0
80 */
81 public function init()
82 {
83 // vars
84 $this->post_types = $this->get_post_types();
85
86 // set
87 $this->slug = 'codepress-admin-columns';
88 $this->textdomain = 'codepress-admin-columns';
89 $this->codepress_url = 'http://www.codepress.nl/plugins/codepress-admin-columns';
90 $this->wordpress_url = 'http://wordpress.org/tags/codepress-admin-columns';
91
92 // number of words
93 $this->excerpt_length = 20;
94
95 // translations
96 load_plugin_textdomain( $this->textdomain, false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
97
98 // register settings
99 add_action( 'admin_menu', array( $this, 'settings_menu') );
100 add_action( 'admin_init', array( $this, 'register_settings') );
101
102 // styling & scripts
103 add_action( 'admin_enqueue_scripts' , array( $this, 'column_styles') );
104 add_filter( 'admin_body_class', array( $this, 'admin_class' ) );
105 add_action( 'admin_head', array( $this, 'admin_css') );
106
107 // register column headers
108 add_action( 'admin_init', array( $this, 'register_columns' ) );
109
110 // actions columns
111 add_action( 'manage_pages_custom_column', array( $this, 'manage_posts_column_value'), 10, 2 );
112 add_action( 'manage_posts_custom_column', array( $this, 'manage_posts_column_value'), 10, 2 );
113 add_filter( 'manage_users_custom_column', array( $this, 'manage_users_column_value'), 10, 3 );
114 add_action( 'manage_media_custom_column', array( $this, 'manage_media_column_value'), 10, 2 );
115 add_action( 'manage_link_custom_column', array( $this, 'manage_link_column_value'), 10, 2 );
116 add_action( 'manage_comments_custom_column', array( $this, 'manage_comments_column_value'), 10, 2 );
117
118 // action ajax
119 add_action( 'wp_ajax_cpac_addon_activation', array( $this, 'ajax_activation'));
120
121 // handle requests gets a low priority so it will trigger when all other plugins have loaded their columns
122 add_action( 'admin_init', array( $this, 'handle_requests' ), 1000 );
123
124 // filters
125 add_filter( 'plugin_action_links', array( $this, 'add_settings_link'), 1, 2);
126 }
127
128 /**
129 * Admin Menu.
130 *
131 * Create the admin menu link for the settings page.
132 *
133 * @since 1.0
134 */
135 public function settings_menu()
136 {
137 $page = add_options_page(
138 // Page title
139 esc_html__( 'Admin Columns Settings', $this->textdomain ),
140 // Menu Title
141 esc_html__( 'Admin Columns', $this->textdomain ),
142 // Capability
143 'manage_options',
144 // Menu slug
145 $this->slug,
146 // Callback
147 array( $this, 'plugin_settings_page')
148 );
149
150 // set admin page
151 $this->admin_page = $page;
152
153 // settings page specific styles and scripts
154 add_action( "admin_print_styles-$page", array( $this, 'admin_styles') );
155 add_action( "admin_print_scripts-$page", array( $this, 'admin_scripts') );
156
157 // add help tabs
158 add_action("load-$page", array( $this, 'help_tabs'));
159 }
160
161 /**
162 * Add Settings link to plugin page
163 *
164 * @since 1.0
165 */
166 function add_settings_link( $links, $file )
167 {
168 if ( $file != plugin_basename( __FILE__ ))
169 return $links;
170
171 array_unshift($links, '<a href="' . admin_url("admin.php") . '?page=' . $this->slug . '">' . __( 'Settings' ) . '</a>');
172 return $links;
173 }
174
175 /**
176 * Register Columns
177 *
178 * apply_filters location in includes/screen.php
179 *
180 * @since 1.0
181 */
182 public function register_columns()
183 {
184 /** Posts */
185 foreach ( $this->post_types as $post_type ) {
186
187 // register column per post type
188 add_filter("manage_edit-{$post_type}_columns", array($this, 'callback_add_posts_column_headings'));
189 }
190
191 /** Users */
192 add_filter( "manage_users_columns", array($this, 'callback_add_users_column_headings'), 9);
193 // give higher priority, so it will load just before other plugins to prevent conflicts
194
195 /** Media */
196 add_filter( "manage_upload_columns", array($this, 'callback_add_media_column_headings'));
197
198 /** Links */
199 add_filter( "manage_link-manager_columns", array($this, 'callback_add_links_column_headings'));
200
201 /** Comments */
202 add_filter( "manage_edit-comments_columns", array($this, 'callback_add_comments_column_headings'));
203 }
204
205 /**
206 * Callback add Posts Column
207 *
208 * @since 1.0
209 */
210 public function callback_add_posts_column_headings($columns)
211 {
212 global $post;
213
214 return $this->add_columns_headings($post->post_type, $columns);
215 }
216
217 /**
218 * Callback add Users column
219 *
220 * @since 1.1
221 */
222 public function callback_add_users_column_headings($columns)
223 {
224 return $this->add_columns_headings('wp-users', $columns);
225 }
226
227 /**
228 * Callback add Media column
229 *
230 * @since 1.3
231 */
232 public function callback_add_media_column_headings($columns)
233 {
234 return $this->add_columns_headings('wp-media', $columns);
235 }
236
237 /**
238 * Callback add Links column
239 *
240 * @since 1.3.1
241 */
242 public function callback_add_links_column_headings($columns)
243 {
244 return $this->add_columns_headings('wp-links', $columns);
245 }
246
247 /**
248 * Callback add Comments column
249 *
250 * @since 1.3.1
251 */
252 public function callback_add_comments_column_headings($columns)
253 {
254 return $this->add_columns_headings('wp-comments', $columns);
255 }
256
257 /**
258 * Add managed columns by Type
259 *
260 * @since 1.1
261 */
262 private function add_columns_headings( $type, $columns )
263 {
264 // only get stored columns.. the rest we don't need
265 $db_columns = $this->get_stored_columns($type);
266
267 if ( !$db_columns )
268 return $columns;
269
270 // filter already loaded columns by plugins
271 $set_columns = $this->filter_preset_columns( $type, $columns );
272
273 // loop through columns
274 foreach ( $db_columns as $id => $values ) {
275 // is active
276 if ( isset($values['state']) && $values['state'] == 'on' ){
277
278 // register format
279 $set_columns[$id] = $values['label'];
280 }
281 }
282
283 return $set_columns;
284 }
285
286 /**
287 * Set columns. These columns apply either for every post or set by a plugin.
288 *
289 * @since 1.0
290 */
291 private function filter_preset_columns( $type, $columns )
292 {
293 $options = get_option('cpac_options_default');
294
295 if ( !$options )
296 return $columns;
297
298 // we use the wp default columns for filtering...
299 $stored_wp_default_columns = $options[$type];
300
301 // ... the ones that are set by plugins, theme functions and such.
302 $dif_columns = array_diff(array_keys($columns), array_keys($stored_wp_default_columns));
303
304 // we add those to the columns
305 $pre_columns = array();
306 if ( $dif_columns ) {
307 foreach ( $dif_columns as $column ) {
308 $pre_columns[$column] = $columns[$column];
309 }
310 }
311
312 return $pre_columns;
313 }
314
315 /**
316 * Add managed sortable columns by Type
317 *
318 * @since 1.1
319 */
320 private function add_managed_sortable_columns( $type, $columns )
321 {
322 $display_columns = $this->get_merged_columns($type);
323
324 if ( ! $display_columns )
325 return $columns;
326
327 foreach ( $display_columns as $id => $vars ) {
328 if ( isset($vars['options']['sortorder']) && $vars['options']['sortorder'] == 'on' ){
329
330 // register format
331 $columns[$id] = $this->sanitize_string($vars['label']);
332 }
333 }
334 return $columns;
335 }
336
337 /**
338 * Get a list of Column options per post type
339 *
340 * @since 1.0
341 */
342 private function get_column_boxes($type)
343 {
344 // merge all columns
345 $display_columns = $this->get_merged_columns($type);
346
347 // define
348 $list = '';
349
350 // loop throught the active columns
351 if ( $display_columns ) {
352 foreach ( $display_columns as $id => $values ) {
353
354 // add items to the list
355 $list .= $this->get_box($type, $id, $values);
356
357 }
358 }
359
360 // custom field button
361 $button_add_column = '';
362 if ( $this->get_meta_by_type($type) )
363 $button_add_column = "<a href='javacript:;' class='cpac-add-customfield-column button'>+ " . __('Add Custom Field Column', $this->textdomain) . "</a>";
364
365 return "
366 <div class='cpac-box'>
367 <ul class='cpac-option-list'>
368 {$list}
369 </ul>
370 {$button_add_column}
371 <div class='cpac-reorder-msg'>" . __('drag and drop to reorder', $this->textdomain) . "</div>
372 </div>
373 ";
374 }
375
376 /**
377 * Get merged columns
378 *
379 * @since 1.0
380 */
381 protected function get_merged_columns( $type )
382 {
383 /** Comments */
384 if ( $type == 'wp-comments' ) {
385 $wp_default_columns = $this->get_wp_default_comments_columns();
386 $wp_custom_columns = $this->get_custom_comments_columns();
387 }
388
389 /** Links */
390 elseif ( $type == 'wp-links' ) {
391 $wp_default_columns = $this->get_wp_default_links_columns();
392 $wp_custom_columns = $this->get_custom_links_columns();
393 }
394
395 /** Users */
396 elseif ( $type == 'wp-users' ) {
397 $wp_default_columns = $this->get_wp_default_users_columns();
398 $wp_custom_columns = $this->get_custom_users_columns();
399 }
400
401 /** Media */
402 elseif ( $type == 'wp-media' ) {
403 $wp_default_columns = $this->get_wp_default_media_columns();
404 $wp_custom_columns = $this->get_custom_media_columns();
405 }
406
407 /** Posts */
408 else {
409 $wp_default_columns = $this->get_wp_default_posts_columns($type);
410 $wp_custom_columns = $this->get_custom_posts_columns($type);
411 }
412
413 // merge columns
414 $display_columns = $this->parse_columns($wp_custom_columns, $wp_default_columns, $type);
415
416 return $display_columns;
417 }
418
419 /**
420 * Merge the default columns (set by WordPress) and the added custom columns (set by plugins, theme etc.)
421 *
422 * @since 1.3.3
423 */
424 function parse_columns($wp_custom_columns, $wp_default_columns, $type) {
425 // merge columns
426 $default_columns = wp_parse_args($wp_custom_columns, $wp_default_columns);
427
428 //get saved database columns
429 $db_columns = $this->get_stored_columns($type);
430 if ( $db_columns ) {
431
432 // let's remove any unavailable columns.. such as disabled plugins
433 $db_columns = $this->remove_unavailable_columns($db_columns, $default_columns);
434
435 // loop throught the active columns
436 foreach ( $db_columns as $id => $values ) {
437
438 // get column meta options from custom columns
439 if ( $this->is_column_meta($id) )
440 $db_columns[$id]['options'] = $wp_custom_columns['column-meta-1']['options'];
441
442 // add static options
443 elseif ( isset($default_columns[$id]['options']) )
444 $db_columns[$id]['options'] = $default_columns[$id]['options'];
445
446 unset($default_columns[$id]);
447 }
448 }
449
450 // merge all
451 return wp_parse_args($db_columns, $default_columns);
452 }
453
454 /**
455 * Remove deactivated (plugin) columns
456 *
457 * This will remove any columns that have been stored, but are no longer available. This happends
458 * when plugins are deactivated or when they are removed from the theme functions.
459 *
460 * @since 1.2
461 */
462 private function remove_unavailable_columns( array $db_columns, array $default_columns)
463 {
464 // check or differences
465 $diff = array_diff( array_keys($db_columns), array_keys($default_columns) );
466
467 if ( ! empty($diff) && is_array($diff) ) {
468 foreach ( $diff as $column_name ){
469 // make an exception for column-meta-xxx
470 if ( ! $this->is_column_meta($column_name) ) {
471 unset($db_columns[$column_name]);
472 }
473 }
474 }
475
476 return $db_columns;
477 }
478
479 /**
480 * Get checkbox
481 *
482 * @since 1.0
483 */
484 private function get_box($type, $id, $values)
485 {
486 $classes = array();
487
488 // set state
489 $state = isset($values['state']) ? $values['state'] : '';
490
491 // class
492 $classes[] = "cpac-box-{$id}";
493 if ( $state )
494 $classes[] = 'active';
495 if ( ! empty($values['options']['class']) )
496 $classes[] = $values['options']['class'];
497 $class = implode(' ', $classes);
498
499 // more box options
500 $more_options = $this->get_additional_box_options($type, $id, $values);
501 $action = "<a class='cpac-action' href='#open'>open</a>";
502
503 // type label
504 $type_label = isset($values['options']['type_label']) ? $values['options']['type_label'] : '';
505
506 // label
507 $label = isset($values['label']) ? str_replace("'", '"', $values['label']) : '';
508
509 // width
510 $width = isset($values['width']) ? $values['width'] : 0;
511 $width_descr = isset($values['width']) && $values['width'] > 0 ? $values['width'] . '%' : __('default', $this->textdomain);
512
513 // hide box options
514 $label_hidden = '';
515 if ( ! empty($values['options']['hide_options']) || strpos($label, '<img') !== false ) {
516 $label_hidden = ' style="display:none"';
517 }
518
519 $list = "
520 <li class='{$class}'>
521 <div class='cpac-sort-handle'></div>
522 <div class='cpac-type-options'>
523 <div class='cpac-checkbox'></div>
524 <input type='hidden' class='cpac-state' name='cpac_options[columns][{$type}][{$id}][state]' value='{$state}'/>
525 <label class='main-label'>{$values['label']}</label>
526 </div>
527 <div class='cpac-meta-title'>
528 {$action}
529 <span>{$type_label}</span>
530 </div>
531 <div class='cpac-type-inside'>
532 <label for='cpac_options-{$type}-{$id}-label'{$label_hidden}>Label: </label>
533 <input type='text' name='cpac_options[columns][{$type}][{$id}][label]' id='cpac_options-{$type}-{$id}-label' value='{$label}' class='text'{$label_hidden}/>
534 <label for='cpac_options-{$type}-{$id}-width'>".__('Width', $this->textdomain).":</label>
535 <input type='hidden' maxlength='4' class='input-width' name='cpac_options[columns][{$type}][{$id}][width]' id='cpac_options-{$type}-{$id}-width' value='{$width}' />
536 <div class='description width-decription' title='".__('default', $this->textdomain)."'>{$width_descr}</div>
537 <div class='input-width-range'></div>
538 <br/>
539 {$more_options}
540 </div>
541 </li>
542 ";
543
544 return $list;
545 }
546
547 /**
548 * Get additional box option fields
549 *
550 * @since 1.0
551 */
552 private function get_additional_box_options($type, $id, $values)
553 {
554 $fields = '';
555
556 // Custom Fields
557 if ( $this->is_column_meta($id) )
558 $fields = $this->get_box_options_customfields($type, $id, $values);
559
560 return $fields;
561 }
562
563 /**
564 * Box Options: Custom Fields
565 *
566 * @since 1.0
567 */
568 private function get_box_options_customfields($type, $id, $values)
569 {
570 // get post meta fields
571 $fields = $this->get_meta_by_type($type);
572
573 if ( empty($fields) )
574 return false;
575
576 // set meta field options
577 $current = ! empty($values['field']) ? $values['field'] : '' ;
578 $field_options = '';
579 foreach ($fields as $field) {
580 $field_options .= sprintf
581 (
582 '<option value="%s"%s>%s</option>',
583 $field,
584 $field == $current? ' selected="selected"':'',
585 $field
586 );
587 }
588
589 // set meta fieldtype options
590 $currenttype = ! empty($values['field_type']) ? $values['field_type'] : '' ;
591 $fieldtype_options = '';
592 $fieldtypes = array(
593 '' => __('Default'),
594 'image' => __('Image'),
595 'library_id' => __('Media Library Icon', $this->textdomain),
596 'excerpt' => __('Excerpt'),
597 'array' => __('Multiple Values', $this->textdomain),
598 'numeric' => __('Numeric', $this->textdomain),
599 'date' => __('Date', $this->textdomain),
600 'title_by_id' => __('Post Title (Post ID\'s)', $this->textdomain),
601 );
602
603 // add filter
604 $fieldtypes = apply_filters('cpac-field-types', $fieldtypes );
605
606 // set select options
607 foreach ( $fieldtypes as $fkey => $fieldtype ) {
608 $fieldtype_options .= sprintf
609 (
610 '<option value="%s"%s>%s</option>',
611 $fkey,
612 $fkey == $currenttype? ' selected="selected"':'',
613 $fieldtype
614 );
615 }
616
617 // before and after string
618 $before = ! empty($values['before']) ? $values['before'] : '' ;
619 $after = ! empty($values['after']) ? $values['after'] : '' ;
620
621 if ( empty($field_options) )
622 return false;
623
624 // add remove button
625 $remove = '<p class="remove-description description">'.__('This field can not be removed', $this->textdomain).'</p>';
626 if ( $id != 'column-meta-1') {
627 $remove = "
628 <p>
629 <a href='javascript:;' class='cpac-delete-custom-field-box'>".__('Remove')."</a>
630 </p>
631 ";
632 }
633
634 $inside = "
635 <label for='cpac-{$type}-{$id}-field'>Custom Field: </label>
636 <select name='cpac_options[columns][{$type}][{$id}][field]' id='cpac-{$type}-{$id}-field'>{$field_options}</select>
637 <br/>
638 <label for='cpac-{$type}-{$id}-field_type'>Field Type: </label>
639 <select name='cpac_options[columns][{$type}][{$id}][field_type]' id='cpac-{$type}-{$id}-field_type'>{$fieldtype_options}</select>
640 <br/>
641 <label for='cpac-{$type}-{$id}-before'>Before: </label>
642 <input type='text' class='cpac-before' name='cpac_options[columns][{$type}][{$id}][before]' id='cpac-{$type}-{$id}-before' value='{$before}'/>
643 <br/>
644 <label for='cpac-{$type}-{$id}-after'>After: </label>
645 <input type='text' class='cpac-after' name='cpac_options[columns][{$type}][{$id}][after]' id='cpac-{$type}-{$id}-after' value='{$after}'/>
646 <br/>
647 {$remove}
648 ";
649
650 return $inside;
651 }
652
653 /**
654 * Get post meta fields by type; post(types) or users.
655 *
656 * @since 1.0
657 */
658 private function get_meta_by_type($type = 'post')
659 {
660 global $wpdb;
661
662 /** Comments */
663 if ( $type == 'wp-comments') {
664 $sql = "SELECT DISTINCT meta_key FROM {$wpdb->commentmeta} ORDER BY 1";
665 }
666
667 /** Users */
668 elseif ( $type == 'wp-users') {
669 $sql = "SELECT DISTINCT meta_key FROM {$wpdb->usermeta} ORDER BY 1";
670 }
671
672 /** Posts */
673 else {
674 $sql = $wpdb->prepare( "SELECT DISTINCT meta_key FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON pm.post_id = p.ID WHERE p.post_type = %s ORDER BY 1", $type);
675 }
676
677 // run sql
678 $fields = $wpdb->get_results($sql, ARRAY_N);
679
680 // postmeta
681 if ( $fields ) {
682 $meta_fields = array();
683 foreach ($fields as $field) {
684 // filter out hidden meta fields
685 if (substr($field[0],0,1) != "_") {
686 $meta_fields[] = $field[0];
687 }
688 }
689 return $meta_fields;
690 }
691
692 return false;
693 }
694
695 /**
696 * Register admin scripts
697 *
698 * @since 1.0
699 */
700 public function admin_scripts()
701 {
702 wp_enqueue_script( 'jquery-ui-slider' );
703 wp_enqueue_script( 'cpac-qtip2', $this->plugin_url('/assets/js/jquery.qtip.js'), array('jquery'), CPAC_VERSION );
704 wp_enqueue_script( 'cpac-admin', $this->plugin_url('/assets/js/admin-column.js'), array('jquery', 'dashboard', 'jquery-ui-sortable'), CPAC_VERSION );
705 }
706
707 /**
708 * Get column types
709 *
710 * @since 1.1
711 */
712 private function get_types()
713 {
714 $types = $this->post_types;
715 $types['wp-users'] = 'wp-users';
716 $types['wp-media'] = 'wp-media';
717 $types['wp-links'] = 'wp-links';
718 $types['wp-comments'] = 'wp-comments';
719
720 return $types;
721 }
722
723 /**
724 * Get post types
725 *
726 * @since 1.0
727 */
728 protected function get_post_types()
729 {
730 $post_types = get_post_types(array(
731 '_builtin' => false
732 ));
733 $post_types['post'] = 'post';
734 $post_types['page'] = 'page';
735
736 return apply_filters('cpac-get-post-types', $post_types);
737 }
738
739 /**
740 * Register admin css
741 *
742 * @since 1.0
743 */
744 public function admin_styles()
745 {
746 wp_enqueue_style( 'jquery-ui-lightness', $this->plugin_url('/assets/ui-theme/jquery-ui-1.8.18.custom.css'), array(), CPAC_VERSION, 'all' );
747 wp_enqueue_style( 'cpac-admin', $this->plugin_url('/assets/css/admin-column.css'), array(), CPAC_VERSION, 'all' );
748 }
749
750 /**
751 * Register column css
752 *
753 * @since 1.0
754 */
755 public function column_styles()
756 {
757 wp_enqueue_style( 'cpac-columns', $this->plugin_url('/assets/css/column.css'), array(), CPAC_VERSION, 'all' );
758 }
759
760 /**
761 * Register plugin options
762 *
763 * @since 1.0
764 */
765 public function register_settings()
766 {
767 // If we have no options in the database, let's add them now.
768 if ( false === get_option('cpac_options') )
769 add_option( 'cpac_options', array($this, 'get_default_plugin_options') );
770
771 register_setting( 'cpac-settings-group', 'cpac_options', array($this, 'options_callback') );
772 }
773
774 /**
775 * Returns the default plugin options.
776 *
777 * @since 1.0
778 */
779 public function get_default_plugin_options()
780 {
781 $default_plugin_options = array(
782 'post' => '',
783 'page' => ''
784 );
785 return apply_filters( 'cpac_default_plugin_options', $default_plugin_options );
786 }
787
788 /**
789 * Optional callback.
790 *
791 * @since 1.0
792 */
793 public function options_callback($options)
794 {
795 return $options;
796 }
797
798 /**
799 * Handle requests.
800 *
801 * @since 1.0
802 */
803 public function handle_requests()
804 {
805 // settings updated
806 if ( ! empty($_REQUEST['settings-updated']) )
807 $this->store_wp_default_columns();
808
809 // restore defaults
810 if ( ! empty($_REQUEST['cpac-restore-defaults']) )
811 $this->restore_defaults();
812
813 }
814
815 /**
816 * Stores WP default columns
817 *
818 * This will store columns that are set by WordPress core or
819 * set by the theme for page, post(types) and user columns
820 *
821 * @since 1.2
822 */
823 private function store_wp_default_columns()
824 {
825 // stores the default columns that are set by WP or set in the theme.
826 $wp_default_columns = array();
827
828 // Posts
829 foreach ( $this->post_types as $post_type ) {
830 $wp_default_columns[$post_type] = $this->get_wp_default_posts_columns($post_type);
831 }
832
833 // Users
834 $wp_default_columns['wp-users'] = $this->get_wp_default_users_columns();
835
836 // Media
837 $wp_default_columns['wp-media'] = $this->get_wp_default_media_columns();
838
839 // Links
840 $wp_default_columns['wp-links'] = $this->get_wp_default_links_columns();
841
842 // Comments
843 $wp_default_columns['wp-comments'] = $this->get_wp_default_comments_columns();
844
845 update_option( 'cpac_options_default', $wp_default_columns );
846 }
847
848 /**
849 * Restore defaults
850 *
851 * @since 1.0
852 */
853 private function restore_defaults()
854 {
855 delete_option( 'cpac_options' );
856 delete_option( 'cpac_options_default' );
857 }
858
859 /**
860 * Returns excerpt
861 *
862 * @since 1.0
863 */
864 private function get_post_excerpt($post_id)
865 {
866 global $post;
867
868 $save_post = $post;
869 $post = get_post($post_id);
870 $excerpt = get_the_excerpt();
871 $post = $save_post;
872
873 $output = $this->get_shortened_string($excerpt, $this->excerpt_length );
874
875 return $output;
876 }
877
878 /**
879 * Returns shortened string
880 *
881 * @since 1.0
882 */
883 private function get_shortened_string($string = '', $num_words = 55, $more = null)
884 {
885 if (!$string)
886 return false;
887
888 return wp_trim_words( $string, $num_words, $more );
889 }
890
891 /**
892 * Manage custom column for Post Types.
893 *
894 * @since 1.0
895 */
896 public function manage_posts_column_value($column_name, $post_id)
897 {
898 $type = $column_name;
899
900 // Check for taxonomies, such as column-taxonomy-[taxname]
901 if ( strpos($type, 'column-taxonomy-') !== false )
902 $type = 'column-taxonomy';
903
904 // Check for custom fields, such as column-meta-[customfieldname]
905 if ( $this->is_column_meta($type) )
906 $type = 'column-post-meta';
907
908 // Hook
909 do_action('cpac-manage-posts-column', $type, $column_name, $post_id);
910
911 // Switch Types
912 $result = '';
913 switch ($type) :
914
915 // Post ID
916 case "column-postid" :
917 $result = $post_id;
918 break;
919
920 // Excerpt
921 case "column-excerpt" :
922 $result = $this->get_post_excerpt($post_id);
923 break;
924
925 // Featured Image
926 case "column-featured_image" :
927 if ( has_post_thumbnail($post_id) )
928 $result = get_the_post_thumbnail($post_id, array(80,80));
929 break;
930
931 // Sticky Post
932 case "column-sticky" :
933 if ( is_sticky($post_id) )
934 $result = $this->get_asset_image('checkmark.png');
935 break;
936
937 // Order
938 case "column-order" :
939 $result = get_post_field('menu_order', $post_id);
940 break;
941
942 // Post Formats
943 case "column-post_formats" :
944 $result = get_post_format($post_id);
945 break;
946
947 // Page template
948 case "column-page-template" :
949 // file name
950 $page_template = get_post_meta($post_id, '_wp_page_template', true);
951
952 // get template nice name
953 $result = array_search($page_template, get_page_templates());
954 break;
955
956 // Slug
957 case "column-page-slug" :
958 $result = get_post($post_id)->post_name;
959 break;
960
961 // Slug
962 case "column-word-count" :
963 $result = str_word_count( $this->strip_trim( get_post($post_id)->post_content ) );
964 break;
965
966 // Taxonomy
967 case "column-taxonomy" :
968 $tax = str_replace('column-taxonomy-', '', $column_name);
969 $tags = get_the_terms($post_id, $tax);
970 $tarr = array();
971
972 // for post formats we will display standard instead of empty
973 if ( $tax == 'post_format' && empty($tags) ) {
974 $result = __('Standard');
975 }
976
977 // add name with link
978 elseif ( !empty($tags) ) {
979 $post_type = get_post_type($post_id);
980 foreach($tags as $tag) {
981 // sanatize title
982 if ( isset($tag->term_id) ) {
983 $tax_title = esc_html(sanitize_term_field('name', $tag->name, $tag->term_id, $tag->taxonomy, 'edit'));
984 $tarr[] = "<a href='edit.php?post_type={$post_type}&{$tag->taxonomy}={$tag->slug}'>{$tax_title}</a>";
985 }
986 }
987 $result = implode(', ', $tarr);
988 }
989 break;
990
991 // Custom Field
992 case "column-post-meta" :
993 $result = $this->get_column_value_custom_field($post_id, $column_name, 'post');
994 break;
995
996 // Attachment
997 case "column-attachment" :
998 $result = $this->get_column_value_attachments($post_id);
999 break;
1000
1001 // Attachment count
1002 case "column-attachment-count" :
1003 $result = count($this->get_attachment_ids($post_id));
1004 break;
1005
1006 // Roles
1007 case "column-roles" :
1008 $user_id = get_post($post_id)->post_author;
1009 $userdata = get_userdata( $user_id );
1010 if ( !empty($userdata->roles[0]) )
1011 echo implode(', ',$userdata->roles);
1012 break;
1013
1014 // Post status
1015 case "column-status" :
1016 $p = get_post($post_id);
1017 $result = $p->post_status;
1018 if ( $result == 'future')
1019 $result = $result . " <p class='description'>" . date_i18n( get_option('date_format') . ' ' . get_option('time_format') , strtotime($p->post_date) ) . "</p>";
1020 break;
1021
1022 // Post comment status
1023 case "column-comment-status" :
1024 $p = get_post($post_id);
1025 $result = $this->get_asset_image('no.png', $p->comment_status);
1026 if ( $p->comment_status == 'open' )
1027 $result = $this->get_asset_image('checkmark.png', $p->comment_status);
1028 break;
1029
1030 // Post ping status
1031 case "column-ping-status" :
1032 $p = get_post($post_id);
1033 $result = $this->get_asset_image('no.png', $p->ping_status);
1034 if ( $p->ping_status == 'open' )
1035 $result = $this->get_asset_image('checkmark.png', $p->ping_status);
1036 break;
1037
1038 // Post actions ( delete, edit etc. )
1039 case "column-actions" :
1040 $result = $this->get_column_value_actions($post_id, 'posts');
1041 break;
1042
1043 default :
1044 $result = '';
1045
1046 endswitch;
1047
1048 echo $result;
1049 }
1050
1051 /**
1052 * Manage custom column for Users.
1053 *
1054 * @since 1.1
1055 */
1056 public function manage_users_column_value( $value, $column_name, $user_id )
1057 {
1058 $type = $column_name;
1059
1060 $userdata = get_userdata( $user_id );
1061
1062 if ( ! $userdata )
1063 return false;
1064
1065 // Check for user custom fields: column-meta-[customfieldname]
1066 if ( $this->is_column_meta($type) )
1067 $type = 'column-user-meta';
1068
1069 // Check for post count: column-user_postcount-[posttype]
1070 if ( $this->get_posttype_by_postcount_column($type) )
1071 $type = 'column-user_postcount';
1072
1073 // Hook
1074 do_action('cpac-manage-users-column', $type, $column_name, $user_id);
1075
1076 $result = '';
1077 switch ($type) :
1078
1079 // user id
1080 case "column-user_id" :
1081 $result = $user_id;
1082 break;
1083
1084 // first name
1085 case "column-nickname" :
1086 $result = $userdata->nickname;
1087 break;
1088
1089 // first name
1090 case "column-first_name" :
1091 $result = $userdata->first_name;
1092 break;
1093
1094 // last name
1095 case "column-last_name" :
1096 $result = $userdata->last_name;
1097 break;
1098
1099 // user url
1100 case "column-user_url" :
1101 $result = $userdata->user_url;
1102 break;
1103
1104 // user registration date
1105 case "column-user_registered" :
1106 $result = $userdata->user_registered;
1107 break;
1108
1109 // user description
1110 case "column-user_description" :
1111 $result = $this->get_shortened_string( get_the_author_meta('user_description', $user_id), $this->excerpt_length );
1112 break;
1113
1114 // user description
1115 case "column-user_postcount" :
1116 $post_type = $this->get_posttype_by_postcount_column($column_name);
1117
1118 // get post count
1119 $count = $this->get_post_count( $post_type, $user_id );
1120
1121 // set result
1122 $result = $count > 0 ? "<a href='edit.php?post_type={$post_type}&author={$user_id}'>{$count}</a>" : (string) $count;
1123 break;
1124
1125 // user actions
1126 case "column-actions" :
1127 $result = $this->get_column_value_actions($user_id, 'users');
1128 break;
1129
1130 // user meta data ( custom field )
1131 case "column-user-meta" :
1132 $result = $this->get_column_value_custom_field($user_id, $column_name, 'user');
1133 break;
1134
1135 default :
1136 $result = '';
1137
1138 endswitch;
1139
1140 return $result;
1141 }
1142
1143 /**
1144 * Manage custom column for Media.
1145 *
1146 * @since 1.3
1147 */
1148 public function manage_media_column_value( $column_name, $media_id )
1149 {
1150 $type = $column_name;
1151
1152 $meta = wp_get_attachment_metadata($media_id);
1153 $p = get_post($media_id);
1154
1155 // Hook
1156 do_action('cpac-manage-media-column', $type, $column_name, $media_id);
1157
1158 $result = '';
1159 switch ($type) :
1160
1161 // media id
1162 case "column-mediaid" :
1163 $result = $media_id;
1164 break;
1165
1166 // dimensions
1167 case "column-dimensions" :
1168 if ( !empty($meta['width']) && !empty($meta['height']) )
1169 $result = "{$meta['width']} x {$meta['height']}";
1170 break;
1171
1172 // width
1173 case "column-width" :
1174 $result = !empty($meta['width']) ? $meta['width'] : '';
1175 break;
1176
1177 // height
1178 case "column-height" :
1179 $result = !empty($meta['height']) ? $meta['height'] : '';
1180 break;
1181
1182 // description
1183 case "column-description" :
1184 $result = $p->post_content;
1185 break;
1186
1187 // caption
1188 case "column-caption" :
1189 $result = $p->post_excerpt;
1190 break;
1191
1192 // alternate text
1193 case "column-alternate_text" :
1194 $alt = get_post_meta($media_id, '_wp_attachment_image_alt', true);
1195 $result = $this->strip_trim($alt);
1196 break;
1197
1198 // mime type
1199 case "column-mime_type" :
1200 $result = $p->post_mime_type;
1201 break;
1202
1203 // file name
1204 case "column-file_name" :
1205 $file = wp_get_attachment_url($p->ID);
1206 $filename = basename($file);
1207 $result = "<a title='{$filename}' href='{$file}'>{$filename}</a>";
1208 break;
1209
1210 // file paths
1211 case "column-file_paths" :
1212 $sizes = get_intermediate_image_sizes();
1213 $url = wp_get_attachment_url($p->ID);
1214 $filename = basename($url);
1215 $paths[] = "<a title='{$filename}' href='{$url}'>" . __('original', $this->textdomain) . "</a>";
1216 if ( $sizes ) {
1217 foreach ( $sizes as $size ) {
1218 $src = wp_get_attachment_image_src( $media_id, $size );
1219 if (!empty($src[0])) {
1220 $filename = basename($src[0]);
1221 $paths[] = "<a title='{$filename}' href='{$src[0]}'>{$size}</a>";
1222 }
1223 }
1224 }
1225 $result = implode('<span class="cpac-divider"></span>', $paths);
1226 break;
1227
1228 default :
1229 $result = '';
1230
1231 endswitch;
1232
1233 echo $result;
1234 }
1235
1236 /**
1237 * Manage custom column for Links
1238 *
1239 * @since 1.3.1
1240 */
1241 public function manage_link_column_value( $column_name, $link_id )
1242 {
1243 $type = $column_name;
1244
1245 // links object... called bookmark
1246 $bookmark = get_bookmark($link_id);
1247
1248 // Hook
1249 do_action('cpac-manage-link-column', $type, $column_name, $link_id);
1250
1251 $result = '';
1252 switch ($type) :
1253
1254 // link id
1255 case "column-link_id" :
1256 $result = $link_id;
1257 break;
1258
1259 // description
1260 case "column-description" :
1261 $result = $bookmark->link_description;
1262 break;
1263
1264 // target
1265 case "column-target" :
1266 $result = $bookmark->link_target;
1267 break;
1268
1269 // notes
1270 case "column-notes" :
1271 $result = $this->get_shortened_string($bookmark->link_notes, $this->excerpt_length);
1272 break;
1273
1274 // rss
1275 case "column-rss" :
1276 $result = $this->get_shorten_url($bookmark->link_rss);
1277 break;
1278
1279 // image
1280 case "column-image" :
1281 $result = $this->get_thumbnail($bookmark->link_image);
1282 break;
1283
1284 // name length
1285 case "column-length" :
1286 $result = strlen($bookmark->link_name);
1287 break;
1288
1289 // owner
1290 case "column-owner" :
1291 $result = $bookmark->link_owner;
1292
1293 // add user link
1294 $userdata = get_userdata( $bookmark->link_owner );
1295 if (!empty($userdata->data)) {
1296 $result = $userdata->data->user_nicename;
1297 //$result = "<a href='user-edit.php?user_id={$bookmark->link_owner}'>{$result}</a>";
1298 }
1299 break;
1300
1301 default :
1302 $result = '';
1303
1304 endswitch;
1305
1306 echo $result;
1307 }
1308
1309 /**
1310 * Manage custom column for Comments
1311 *
1312 * @since 1.3.1
1313 */
1314 public function manage_comments_column_value( $column_name, $comment_id )
1315 {
1316 $type = $column_name;
1317
1318 // comments object
1319 $comment = get_comment($comment_id);
1320
1321 // Check for custom fields, such as column-meta-[customfieldname]
1322 if ( $this->is_column_meta($type) )
1323 $type = 'column-comment-meta';
1324
1325 // Hook
1326 do_action('cpac-manage-comments-column', $type, $column_name, $comment_id);
1327
1328 $result = '';
1329 switch ($type) :
1330
1331 // comment id
1332 case "column-comment_id" :
1333 $result = $comment_id;
1334 break;
1335
1336 // author
1337 case "column-author_author" :
1338 $result = $comment->comment_author;
1339 break;
1340
1341 // avatar
1342 case "column-author_avatar" :
1343 $result = get_avatar( $comment, 80 );
1344 break;
1345
1346 // url
1347 case "column-author_url" :
1348 $result = $this->get_shorten_url($comment->comment_author_url);
1349 break;
1350
1351 // ip
1352 case "column-author_ip" :
1353 $result = $comment->comment_author_IP;
1354 break;
1355
1356 // email
1357 case "column-author_email" :
1358 $result = $comment->comment_author_email;
1359 break;
1360
1361 // parent
1362 case "column-reply_to" :
1363 if ( $comment->comment_approved ) {
1364 $parent = get_comment( $comment->comment_parent );
1365 $parent_link = esc_url( get_comment_link( $comment->comment_parent ) );
1366 $name = get_comment_author( $parent->comment_ID );
1367 $result = sprintf( '<a href="%1$s">%2$s</a>', $parent_link, $name );
1368 }
1369 break;
1370
1371 // approved
1372 case "column-approved" :
1373 $result = $this->get_asset_image('no.png');
1374 if ( $comment->comment_approved )
1375 $result = $this->get_asset_image('checkmark.png');
1376 break;
1377
1378 // date
1379 case "column-date" :
1380 $comment_url = esc_url( get_comment_link( $comment_id ) );
1381 $result = sprintf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>' ),
1382 $comment_url,
1383 $this->get_date($comment->comment_date),
1384 $this->get_time($comment->comment_date)
1385 );
1386 $result = "<div class='submitted-on'>{$result}</div>";
1387 break;
1388
1389 // date GMT
1390 case "column-date_gmt" :
1391 $comment_url = esc_url( get_comment_link( $comment_id ) );
1392 $result = sprintf( __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>' ),
1393 $comment_url,
1394 $this->get_date($comment->comment_date_gmt),
1395 $this->get_time($comment->comment_date_gmt)
1396 );
1397 $result = "<div class='submitted-on'>{$result}</div>";
1398 break;
1399
1400 // custom field
1401 case "column-comment-meta" :
1402 $result = $this->get_column_value_custom_field($comment_id, $column_name, 'comment');
1403 break;
1404
1405 // agent
1406 case "column-agent" :
1407 $result = $comment->comment_agent;
1408 break;
1409
1410 // excerpt
1411 case "column-excerpt" :
1412 $comment = get_comment($comment_id);
1413 $result = $this->get_shortened_string($comment->comment_content, $this->excerpt_length);
1414 break;
1415
1416 default :
1417 $result = '';
1418
1419 endswitch;
1420
1421 echo $result;
1422 }
1423
1424 /**
1425 * Get column value of post attachments
1426 *
1427 * @since 1.0
1428 */
1429 private function get_column_value_attachments( $post_id )
1430 {
1431 $result = '';
1432 $attachment_ids = $this->get_attachment_ids($post_id);
1433 if ( $attachment_ids ) {
1434 foreach ( $attachment_ids as $attach_id ) {
1435 if ( wp_get_attachment_image($attach_id) )
1436 $result .= wp_get_attachment_image( $attach_id, array(80,80), true );
1437 }
1438 }
1439 return $result;
1440 }
1441
1442 /**
1443 * Get column value of post actions
1444 *
1445 * This part has been taken from the following classes
1446 * Posts List Table
1447 *
1448 *
1449 * @since 1.4.2
1450 */
1451 private function get_column_value_actions( $id, $type = 'posts' )
1452 {
1453 $actions = array();
1454
1455 /** Posts */
1456 if ( $type == 'posts') {
1457 $post_id = $id;
1458 $post = get_post($post_id);
1459 $title = _draft_or_post_title();
1460 $post_type_object = get_post_type_object( $post->post_type );
1461 $can_edit_post = current_user_can( $post_type_object->cap->edit_post, $post->ID );
1462
1463 if ( $can_edit_post && 'trash' != $post->post_status ) {
1464 $actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr( __( 'Edit this item' ) ) . '">' . __( 'Edit' ) . '</a>';
1465 $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr( __( 'Edit this item inline' ) ) . '">' . __( 'Quick&nbsp;Edit' ) . '</a>';
1466 }
1467 if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
1468 if ( 'trash' == $post->post_status )
1469 $actions['untrash'] = "<a title='" . esc_attr( __( 'Restore this item from the Trash' ) ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-' . $post->post_type . '_' . $post->ID ) . "'>" . __( 'Restore' ) . "</a>";
1470 elseif ( EMPTY_TRASH_DAYS )
1471 $actions['trash'] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash' ) . "</a>";
1472 if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS )
1473 $actions['delete'] = "<a class='submitdelete' title='" . esc_attr( __( 'Delete this item permanently' ) ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently' ) . "</a>";
1474 }
1475 if ( $post_type_object->public ) {
1476 if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) {
1477 if ( $can_edit_post )
1478 $actions['view'] = '<a href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) . '" title="' . esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'Preview' ) . '</a>';
1479 } elseif ( 'trash' != $post->post_status ) {
1480 $actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'View' ) . '</a>';
1481 }
1482 }
1483 }
1484
1485 /** Users */
1486 elseif ( $type == 'users' ) {
1487
1488 $user_object = new WP_User( $id );
1489 $screen = get_current_screen();
1490
1491 if ( 'site-users-network' == $screen->id )
1492 $url = "site-users.php?id={$this->site_id}&amp;";
1493 else
1494 $url = 'users.php?';
1495
1496 if ( get_current_user_id() == $user_object->ID ) {
1497 $edit_link = 'profile.php';
1498 } else {
1499 $edit_link = esc_url( add_query_arg( 'wp_http_referer', urlencode( stripslashes( $_SERVER['REQUEST_URI'] ) ), "user-edit.php?user_id=$user_object->ID" ) );
1500 }
1501
1502 if ( current_user_can( 'edit_user', $user_object->ID ) ) {
1503 $edit = "<strong><a href=\"$edit_link\">$user_object->user_login</a></strong><br />";
1504 $actions['edit'] = '<a href="' . $edit_link . '">' . __( 'Edit' ) . '</a>';
1505 } else {
1506 $edit = "<strong>$user_object->user_login</strong><br />";
1507 }
1508
1509 if ( !is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'delete_user', $user_object->ID ) )
1510 $actions['delete'] = "<a class='submitdelete' href='" . wp_nonce_url( "users.php?action=delete&amp;user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Delete' ) . "</a>";
1511 if ( is_multisite() && get_current_user_id() != $user_object->ID && current_user_can( 'remove_user', $user_object->ID ) )
1512 $actions['remove'] = "<a class='submitdelete' href='" . wp_nonce_url( $url."action=remove&amp;user=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Remove' ) . "</a>";
1513 }
1514
1515 return implode(' | ', $actions);
1516 }
1517
1518 /**
1519 * Get column value of post attachments
1520 *
1521 * @since 1.2.1
1522 */
1523 protected function get_attachment_ids( $post_id )
1524 {
1525 return get_posts(array(
1526 'post_type' => 'attachment',
1527 'numberposts' => -1,
1528 'post_status' => null,
1529 'post_parent' => $post_id,
1530 'fields' => 'ids'
1531 ));
1532 }
1533
1534 /**
1535 * Get post count
1536 *
1537 * @since 1.3.1
1538 */
1539 protected function get_post_count( $post_type, $user_id )
1540 {
1541 if ( ! post_type_exists($post_type) || ! get_userdata($user_id) )
1542 return false;
1543
1544 $user_posts = get_posts(array(
1545 'post_type' => $post_type,
1546 'numberposts' => -1,
1547 'author' => $user_id,
1548 'post_status' => 'publish'
1549 ));
1550 return count($user_posts);
1551 }
1552
1553 /**
1554 * Get image from assets folder
1555 *
1556 * @since 1.3.1
1557 */
1558 protected function get_asset_image($name = '', $title = '')
1559 {
1560 if ( $name )
1561 return sprintf("<img alt='' src='%s' title='%s'/>", $this->plugin_url("assets/images/{$name}"), $title);
1562 }
1563
1564 /**
1565 * Shorten URL
1566 *
1567 * @since 1.3.1
1568 */
1569 protected function get_shorten_url($url = '')
1570 {
1571 if ( !$url )
1572 return false;
1573
1574 // shorten url
1575 $short_url = url_shorten( $url );
1576
1577 return "<a title='{$url}' href='{$url}'>{$short_url}</a>";
1578 }
1579 /**
1580 * Get column value of Custom Field
1581 *
1582 * @since 1.0
1583 */
1584 protected function get_column_value_custom_field($object_id, $column_name, $meta_type = 'post')
1585 {
1586 /** Users */
1587 if ( $meta_type == 'user' ) {
1588 $type = 'wp-users';
1589 }
1590
1591 /** Posts */
1592 else {
1593 $type = get_post_type($object_id);
1594 }
1595
1596 // get column
1597 $columns = $this->get_stored_columns($type);
1598
1599 // inputs
1600 $field = isset($columns[$column_name]['field']) ? $columns[$column_name]['field'] : '';
1601 $fieldtype = isset($columns[$column_name]['field_type']) ? $columns[$column_name]['field_type'] : '';
1602 $before = isset($columns[$column_name]['before']) ? $columns[$column_name]['before'] : '';
1603 $after = isset($columns[$column_name]['after']) ? $columns[$column_name]['after'] : '';
1604
1605 // Get meta field value
1606 $meta = get_metadata($meta_type, $object_id, $field, true);
1607
1608 // multiple meta values
1609 if ( ( $fieldtype == 'array' && is_array($meta) ) || is_array($meta) ) {
1610 $meta = get_metadata($meta_type, $object_id, $field, true);
1611 $meta = $this->recursive_implode(', ', $meta);
1612 }
1613
1614 // make sure there are no serialized arrays or empty meta data
1615 if ( empty($meta) || !is_string($meta) )
1616 return false;
1617
1618 // handles each field type differently..
1619 switch ($fieldtype) :
1620
1621 // Image
1622 case "image" :
1623 $meta = $this->get_thumbnail($meta);
1624 break;
1625
1626 // Media Library ID
1627 case "library_id" :
1628 $meta = $this->get_media_thumbnails($meta);
1629 break;
1630
1631 // Excerpt
1632 case "excerpt" :
1633 $meta = $this->get_shortened_string($meta, $this->excerpt_length);
1634 break;
1635
1636 // Date
1637 case "date" :
1638 $meta = $this->get_date($meta);
1639 break;
1640
1641 // Title
1642 case "title_by_id" :
1643 $titles = $this->get_custom_field_value_title($meta);
1644 if ( $titles )
1645 $meta = $titles;
1646 break;
1647
1648 endswitch;
1649
1650 // add before and after string
1651 $meta = "{$before}{$meta}{$after}";
1652
1653 return $meta;
1654 }
1655
1656 /**
1657 * Get custom field value 'Title by ID'
1658 *
1659 * @since 1.3
1660 */
1661 private function get_custom_field_value_title($meta)
1662 {
1663 //remove white spaces and strip tags
1664 $meta = $this->strip_trim( str_replace(' ','', $meta) );
1665
1666 // var
1667 $ids = $titles = array();
1668
1669 // check for multiple id's
1670 if ( strpos($meta, ',') !== false )
1671 $ids = explode(',',$meta);
1672 elseif ( is_numeric($meta) )
1673 $ids[] = $meta;
1674
1675 // display title with link
1676 if ( $ids && is_array($ids) ) {
1677 foreach ( $ids as $id ) {
1678 $title = is_numeric($id) ? get_the_title($id) : '';
1679 $link = get_edit_post_link($id);
1680 if ( $title )
1681 $titles[] = $link ? "<a href='{$link}'>{$title}</a>" : $title;
1682 }
1683 }
1684
1685 return implode('<span class="cpac-divider"></span>', $titles);
1686 }
1687
1688 /**
1689 * Get column value of Custom Field
1690 *
1691 * @since 1.2
1692 */
1693 private function get_user_column_value_custom_field($user_id, $id)
1694 {
1695 $columns = $this->get_stored_columns('wp-users');
1696
1697 // inputs
1698 $field = isset($columns[$id]['field']) ? $columns[$id]['field'] : '';
1699 $fieldtype = isset($columns[$id]['field_type']) ? $columns[$id]['field_type'] : '';
1700 $before = isset($columns[$id]['before']) ? $columns[$id]['before'] : '';
1701 $after = isset($columns[$id]['after']) ? $columns[$id]['after'] : '';
1702
1703 // Get meta field value
1704 $meta = get_user_meta($user_id, $field, true);
1705
1706 // multiple meta values
1707 if ( ( $fieldtype == 'array' && is_array($meta) ) || is_array($meta) ) {
1708 $meta = get_user_meta($user_id, $field);
1709 $meta = $this->recursive_implode(', ', $meta);
1710 }
1711
1712 // make sure there are no serialized arrays or empty meta data
1713 if ( empty($meta) || !is_string($meta) )
1714 return false;
1715
1716 // handles each field type differently..
1717 switch ($fieldtype) :
1718
1719 // Image
1720 case "image" :
1721 $meta = $this->get_thumbnail($meta);
1722 break;
1723
1724 // Media Library ID
1725 case "library_id" :
1726 $meta = $this->get_media_thumbnails($meta);
1727 break;
1728
1729 // Excerpt
1730 case "excerpt" :
1731 $meta = $this->get_shortened_string($meta, $this->excerpt_length);
1732 break;
1733
1734 endswitch;
1735
1736 // add before and after string
1737 $meta = "{$before}{$meta}{$after}";
1738
1739 return $meta;
1740 }
1741
1742 /**
1743 * Implode for multi dimensional array
1744 *
1745 * @since 1.0
1746 */
1747 private function recursive_implode( $glue, $pieces )
1748 {
1749 foreach( $pieces as $r_pieces ) {
1750 if( is_array( $r_pieces ) ) {
1751 $retVal[] = $this->recursive_implode( $glue, $r_pieces );
1752 }
1753 else {
1754 $retVal[] = $r_pieces;
1755 }
1756 }
1757 if ( isset($retVal) && is_array($retVal) )
1758 return implode( $glue, $retVal );
1759
1760 return false;
1761 }
1762
1763 /**
1764 * Get WP default supported admin columns per post type.
1765 *
1766 * @since 1.0
1767 */
1768 private function get_wp_default_posts_columns($post_type = 'post')
1769 {
1770 // load dependencies
1771
1772 // deprecated as of wp3.3
1773 if ( file_exists(ABSPATH . 'wp-admin/includes/template.php') )
1774 require_once(ABSPATH . 'wp-admin/includes/template.php');
1775
1776 // introduced since wp3.3
1777 if ( file_exists(ABSPATH . 'wp-admin/includes/screen.php') )
1778 require_once(ABSPATH . 'wp-admin/includes/screen.php');
1779
1780 // used for getting columns
1781 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1782 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1783 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php') )
1784 require_once(ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php');
1785
1786 // some plugins depend on settings the $_GET['post_type'] variable such as ALL in One SEO
1787 $_GET['post_type'] = $post_type;
1788
1789 // for 3rd party plugin support we will call load-edit.php so all the
1790 // additional columns that are set by them will be avaible for us
1791 do_action('load-edit.php');
1792
1793 // we need to change the current screen
1794 global $current_screen;
1795 $org_current_screen = $current_screen;
1796
1797 // overwrite current_screen global with our post type of choose...
1798 $current_screen->post_type = $post_type;
1799
1800 // ...so we can get its columns
1801 $columns = WP_Posts_List_Table::get_columns();
1802
1803 if ( empty ( $columns ) )
1804 return false;
1805
1806 // change to uniform format
1807 $posts_columns = $this->get_uniform_format($columns);
1808
1809 // reset current screen
1810 $current_screen = $org_current_screen;
1811
1812 return $posts_columns;
1813 }
1814
1815 /**
1816 * Get WP default users columns per post type.
1817 *
1818 * @since 1.1
1819 */
1820 private function get_wp_default_users_columns()
1821 {
1822 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1823 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1824 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php') )
1825 require_once(ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php');
1826
1827 // turn off site users
1828 $this->is_site_users = false;
1829
1830 // get users columns
1831 $columns = WP_Users_List_Table::get_columns();
1832
1833 // change to uniform format
1834 $columns = $this->get_uniform_format($columns);
1835
1836 // add sorting to some of the default links columns
1837 $columns = $this->set_sorting_to_default_users_columns($columns);
1838
1839 return apply_filters('cpac-default-users-columns', $columns);
1840 }
1841
1842 /**
1843 * Add Sorting to WP default Users columns
1844 *
1845 * @since 1.4
1846 */
1847 private function set_sorting_to_default_users_columns($columns)
1848 {
1849 // Comment
1850 if ( !empty($columns['role']) ) {
1851 $columns['role']['options']['sortorder'] = 'on';
1852 }
1853 return $columns;
1854 }
1855
1856 /**
1857 * Get WP default media columns.
1858 *
1859 * @since 1.2.1
1860 */
1861 private function get_wp_default_media_columns()
1862 {
1863 // could use _get_list_table('WP_Media_List_Table') ?
1864 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1865 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1866 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-media-list-table.php') )
1867 require_once(ABSPATH . 'wp-admin/includes/class-wp-media-list-table.php');
1868
1869 global $current_screen;
1870 $org_current_screen = $current_screen;
1871
1872 // overwrite current_screen global with our media id...
1873 $current_screen->id = 'upload';
1874
1875 // init media class
1876 $wp_media = new WP_Media_List_Table;
1877
1878 // get media columns
1879 $columns = $wp_media->get_columns();
1880
1881 // reset current screen
1882 $current_screen = $org_current_screen;
1883
1884 // change to uniform format
1885 return $this->get_uniform_format($columns);
1886 }
1887
1888 /**
1889 * Get WP default links columns.
1890 *
1891 * @since 1.3.1
1892 */
1893 private function get_wp_default_links_columns()
1894 {
1895 // dependencies
1896 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1897 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1898 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-links-list-table.php') )
1899 require_once(ABSPATH . 'wp-admin/includes/class-wp-links-list-table.php');
1900
1901 // get links columns
1902 $columns = WP_Links_List_Table::get_columns();
1903
1904 // change to uniform format
1905 $columns = $this->get_uniform_format($columns);
1906
1907 // add sorting to some of the default links columns
1908 $columns = $this->set_sorting_to_default_links_columns($columns);
1909
1910 return apply_filters('cpac-default-links-columns', $columns);
1911 }
1912
1913 /**
1914 * Add Sorting to WP default links columns
1915 *
1916 * @since 1.4
1917 */
1918 private function set_sorting_to_default_links_columns($columns)
1919 {
1920 // Relationship
1921 if ( !empty($columns['rel']) ) {
1922 $columns['rel']['options']['sortorder'] = 'on';
1923 }
1924 return $columns;
1925 }
1926
1927 /**
1928 * Get WP default links columns.
1929 *
1930 * @since 1.3.1
1931 */
1932 private function get_wp_default_comments_columns()
1933 {
1934 // dependencies
1935 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1936 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1937 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-comments-list-table.php') )
1938 require_once(ABSPATH . 'wp-admin/includes/class-wp-comments-list-table.php');
1939
1940 global $current_screen;
1941 $org_current_screen = $current_screen;
1942
1943 // overwrite current_screen global with our media id...
1944 $current_screen->id = 'edit-comments';
1945
1946 // init table object
1947 $wp_comment = new WP_Comments_List_Table;
1948
1949 // get comments
1950 $columns = $wp_comment->get_columns();
1951
1952 // reset current screen
1953 $current_screen = $org_current_screen;
1954
1955 // change to uniform format
1956 $columns = $this->get_uniform_format($columns);
1957
1958 // add sorting to some of the default links columns
1959 $columns = $this->set_sorting_to_default_comments_columns($columns);
1960
1961 return apply_filters('cpac-default-comments-columns', $columns);
1962 }
1963
1964 /**
1965 * Add Sorting to WP default comments columns
1966 *
1967 * @since 1.4
1968 */
1969 private function set_sorting_to_default_comments_columns($columns)
1970 {
1971 // Comment
1972 if ( !empty($columns['comment']) ) {
1973 $columns['comment']['options']['sortorder'] = 'on';
1974 }
1975 return $columns;
1976 }
1977
1978 /**
1979 * Build uniform format for all columns
1980 *
1981 * @since 1.0
1982 */
1983 private function get_uniform_format($columns)
1984 {
1985 // we remove the checkbox column as an option...
1986 if ( isset($columns['cb']) )
1987 unset($columns['cb']);
1988
1989 // change to uniform format
1990 $uniform_columns = array();
1991 foreach ( (array) $columns as $id => $label ) {
1992 $hide_options = false;
1993 $type_label = $label;
1994
1995 // comment exception
1996 if ( strpos( $label, 'comment-grey-bubble.png') ) {
1997 $type_label = __('Comments', $this->textdomain);
1998 $hide_options = true;
1999 }
2000
2001 // user icon excerption
2002 if ( $id == 'icon' ) {
2003 $type_label = __('Icon', $this->textdomain);
2004 }
2005
2006 $uniform_colums[$id] = array(
2007 'label' => $label,
2008 'state' => 'on',
2009 'options' => array(
2010 'type_label' => $type_label,
2011 'hide_options' => $hide_options,
2012 'class' => 'cpac-box-wp-native',
2013 )
2014 );
2015 }
2016 return $uniform_colums;
2017 }
2018
2019 /**
2020 * Custom posts columns
2021 *
2022 * @since 1.0
2023 */
2024 private function get_custom_posts_columns($post_type)
2025 {
2026 $custom_columns = array(
2027 'column-featured_image' => array(
2028 'label' => __('Featured Image', $this->textdomain)
2029 ),
2030 'column-excerpt' => array(
2031 'label' => __('Excerpt', $this->textdomain)
2032 ),
2033 'column-order' => array(
2034 'label' => __('Page Order', $this->textdomain)
2035 ),
2036 'column-post_formats' => array(
2037 'label' => __('Post Format', $this->textdomain)
2038 ),
2039 'column-postid' => array(
2040 'label' => __('ID', $this->textdomain)
2041 ),
2042 'column-page-slug' => array(
2043 'label' => __('Slug', $this->textdomain)
2044 ),
2045 'column-attachment' => array(
2046 'label' => __('Attachment', $this->textdomain)
2047 ),
2048 'column-attachment-count' => array(
2049 'label' => __('No. of Attachments', $this->textdomain)
2050 ),
2051 'column-roles' => array(
2052 'label' => __('Roles', $this->textdomain)
2053 ),
2054 'column-status' => array(
2055 'label' => __('Status', $this->textdomain)
2056 ),
2057 'column-comment-status' => array(
2058 'label' => __('Comment status', $this->textdomain)
2059 ),
2060 'column-ping-status' => array(
2061 'label' => __('Ping status', $this->textdomain)
2062 ),
2063 'column-actions' => array(
2064 'label' => __('Actions', $this->textdomain),
2065 'options' => array(
2066 'sortorder' => false
2067 )
2068 )
2069 );
2070
2071 // Word count support
2072 if ( post_type_supports($post_type, 'editor') ) {
2073 $custom_columns['column-word-count'] = array(
2074 'label' => __('Word count', $this->textdomain)
2075 );
2076 }
2077
2078 // Sticky support
2079 if ( $post_type == 'post' ) {
2080 $custom_columns['column-sticky'] = array(
2081 'label' => __('Sticky', $this->textdomain)
2082 );
2083 }
2084
2085 // Order support
2086 if ( post_type_supports($post_type, 'page-attributes') ) {
2087 $custom_columns['column-order'] = array(
2088 'label' => __('Page Order', $this->textdomain),
2089 'options' => array(
2090 'type_label' => __('Order', $this->textdomain)
2091 )
2092 );
2093 }
2094
2095 // Page Template
2096 if ( $post_type == 'page' ) {
2097 $custom_columns['column-page-template'] = array(
2098 'label' => __('Page Template', $this->textdomain)
2099 );
2100 }
2101
2102 // Post Formats
2103 if ( post_type_supports($post_type, 'post-formats') ) {
2104 $custom_columns['column-post_formats'] = array(
2105 'label' => __('Post Format', $this->textdomain)
2106 );
2107 }
2108
2109 // Taxonomy support
2110 $taxonomies = get_object_taxonomies($post_type, 'objects');
2111 if ( $taxonomies ) {
2112 foreach ( $taxonomies as $tax_slug => $tax ) {
2113 if ( $tax_slug != 'post_tag' && $tax_slug != 'category' && $tax_slug != 'post_format' ) {
2114 $custom_columns['column-taxonomy-'.$tax->name] = array(
2115 'label' => $tax->label,
2116 'show_filter' => true,
2117 'options' => array(
2118 'type_label' => __('Taxonomy', $this->textdomain)
2119 )
2120 );
2121 }
2122 }
2123 }
2124
2125 // Custom Field support
2126 if ( $this->get_meta_by_type($post_type) ) {
2127 $custom_columns['column-meta-1'] = array(
2128 'label' => __('Custom Field', $this->textdomain),
2129 'field' => '',
2130 'field_type' => '',
2131 'before' => '',
2132 'after' => '',
2133 'options' => array(
2134 'type_label' => __('Field', $this->textdomain),
2135 'class' => 'cpac-box-metafield'
2136 )
2137 );
2138 }
2139
2140 // merge with defaults
2141 $custom_columns = $this->parse_defaults($custom_columns);
2142
2143 return apply_filters('cpac-custom-posts-columns', $custom_columns);
2144 }
2145
2146 /**
2147 * Custom users columns
2148 *
2149 * @since 1.1
2150 */
2151 private function get_custom_users_columns()
2152 {
2153 $custom_columns = array(
2154 'column-user_id' => array(
2155 'label' => __('User ID', $this->textdomain)
2156 ),
2157 'column-nickname' => array(
2158 'label' => __('Nickname', $this->textdomain)
2159 ),
2160 'column-first_name' => array(
2161 'label' => __('First name', $this->textdomain)
2162 ),
2163 'column-last_name' => array(
2164 'label' => __('Last name', $this->textdomain)
2165 ),
2166 'column-user_url' => array(
2167 'label' => __('Url', $this->textdomain)
2168 ),
2169 'column-user_registered' => array(
2170 'label' => __('Registered', $this->textdomain)
2171 ),
2172 'column-user_description' => array(
2173 'label' => __('Description', $this->textdomain)
2174 ),
2175 'column-actions' => array(
2176 'label' => __('Actions', $this->textdomain),
2177 'options' => array(
2178 'sortorder' => false
2179 )
2180 ),
2181 );
2182
2183 // User total number of posts
2184 if ($this->get_post_types()) {
2185 foreach ( $this->get_post_types() as $post_type ) {
2186 $label = $this->get_plural_name($post_type);
2187 $custom_columns['column-user_postcount-'.$post_type] = array(
2188 'label' => __( sprintf('No. of %s',$label), $this->textdomain),
2189 'options' => array(
2190 'type_label' => __('Postcount', $this->textdomain)
2191 )
2192 );
2193 }
2194 }
2195
2196 // Custom Field support
2197 $custom_columns['column-meta-1'] = array(
2198 'label' => __('Custom Field', $this->textdomain),
2199 'field' => '',
2200 'field_type' => '',
2201 'before' => '',
2202 'after' => '',
2203 'options' => array(
2204 'type_label' => __('Field', $this->textdomain),
2205 'class' => 'cpac-box-metafield'
2206 )
2207 );
2208
2209 // merge with defaults
2210 $custom_columns = $this->parse_defaults($custom_columns);
2211
2212 return apply_filters('cpac-custom-users-columns', $custom_columns);
2213 }
2214
2215 /**
2216 * Custom media columns
2217 *
2218 * @since 1.3
2219 */
2220 private function get_custom_media_columns()
2221 {
2222 $custom_columns = array(
2223 'column-mediaid' => array(
2224 'label' => __('ID', $this->textdomain)
2225 ),
2226 'column-mime_type' => array(
2227 'label' => __('Mime type', $this->textdomain)
2228 ),
2229 'column-file_name' => array(
2230 'label' => __('File name', $this->textdomain)
2231 ),
2232 'column-dimensions' => array(
2233 'label' => __('Dimensions', $this->textdomain)
2234 ),
2235 'column-height' => array(
2236 'label' => __('Height', $this->textdomain)
2237 ),
2238 'column-width' => array(
2239 'label' => __('Width', $this->textdomain)
2240 ),
2241 'column-caption' => array(
2242 'label' => __('Caption', $this->textdomain)
2243 ),
2244 'column-description' => array(
2245 'label' => __('Description', $this->textdomain)
2246 ),
2247 'column-alternate_text' => array(
2248 'label' => __('Alt', $this->textdomain)
2249 ),
2250 'column-file_paths' => array(
2251 'label' => __('Upload paths', $this->textdomain),
2252 'options' => array(
2253 'sortorder' => false
2254 )
2255 ),
2256 );
2257
2258 // merge with defaults
2259 $custom_columns = $this->parse_defaults($custom_columns);
2260
2261 return apply_filters('cpac-custom-media-columns', $custom_columns);
2262 }
2263
2264 /**
2265 * Custom links columns
2266 *
2267 * @since 1.3.1
2268 */
2269 private function get_custom_links_columns()
2270 {
2271 $custom_columns = array(
2272 'column-link_id' => array (
2273 'label' => __('ID', $this->textdomain)
2274 ),
2275 'column-description' => array (
2276 'label' => __('Description', $this->textdomain)
2277 ),
2278 'column-image' => array(
2279 'label' => __('Image', $this->textdomain)
2280 ),
2281 'column-target' => array(
2282 'label' => __('Target', $this->textdomain)
2283 ),
2284 'column-owner' => array(
2285 'label' => __('Owner', $this->textdomain)
2286 ),
2287 'column-notes' => array(
2288 'label' => __('Notes', $this->textdomain)
2289 ),
2290 'column-rss' => array(
2291 'label' => __('Rss', $this->textdomain)
2292 ),
2293 'column-length' => array(
2294 'label' => __('Length', $this->textdomain)
2295 )
2296 );
2297
2298 // merge with defaults
2299 $custom_columns = $this->parse_defaults($custom_columns);
2300
2301 return apply_filters('cpac-custom-links-columns', $custom_columns);
2302 }
2303
2304 /**
2305 * Custom comments columns
2306 *
2307 * @since 1.3.1
2308 */
2309 private function get_custom_comments_columns()
2310 {
2311 $custom_columns = array(
2312 'column-comment_id' => array(
2313 'label' => __('ID', $this->textdomain)
2314 ),
2315 'column-author_author' => array(
2316 'label' => __('Author Name', $this->textdomain)
2317 ),
2318 'column-author_avatar' => array(
2319 'label' => __('Avatar', $this->textdomain)
2320 ),
2321 'column-author_url' => array(
2322 'label' => __('Author url', $this->textdomain)
2323 ),
2324 'column-author_ip' => array(
2325 'label' => __('Author IP', $this->textdomain)
2326 ),
2327 'column-author_email' => array(
2328 'label' => __('Author email', $this->textdomain)
2329 ),
2330 'column-reply_to' => array(
2331 'label' => __('In Reply To', $this->textdomain),
2332
2333 // options
2334 'options' => array(
2335 'sortorder' => false
2336 )
2337 ),
2338 'column-approved' => array(
2339 'label' => __('Approved', $this->textdomain)
2340 ),
2341 'column-date' => array(
2342 'label' => __('Date', $this->textdomain)
2343 ),
2344 'column-date_gmt' => array(
2345 'label' => __('Date GMT', $this->textdomain)
2346 ),
2347 'column-agent' => array(
2348 'label' => __('Agent', $this->textdomain)
2349 ),
2350 'column-excerpt' => array(
2351 'label' => __('Excerpt', $this->textdomain)
2352 )
2353 );
2354
2355 // Custom Field support
2356 if ( $this->get_meta_by_type('wp-comments') ) {
2357 $custom_columns['column-meta-1'] = array(
2358 'label' => __('Custom Field', $this->textdomain),
2359 'field' => '',
2360 'field_type' => '',
2361 'before' => '',
2362 'after' => '',
2363 'options' => array(
2364 'type_label' => __('Field', $this->textdomain),
2365 'class' => 'cpac-box-metafield',
2366 'sortorder' => false,
2367 )
2368 );
2369 }
2370
2371 // merge with defaults
2372 $custom_columns = $this->parse_defaults($custom_columns);
2373
2374 return apply_filters('cpac-custom-comments-columns', $custom_columns);
2375 }
2376
2377 /**
2378 * Parse defaults
2379 *
2380 * @since 1.1
2381 */
2382 private function parse_defaults($columns)
2383 {
2384 // default arguments
2385 $defaults = array(
2386
2387 // stored values
2388 'label' => '',
2389 'state' => '',
2390 'width' => '',
2391
2392 // static values
2393 'options' => array(
2394 'type_label' => __('Custom', $this->textdomain),
2395 'hide_options' => false,
2396 'class' => 'cpac-box-custom',
2397 'sortorder' => 'on',
2398 )
2399 );
2400
2401 // parse args
2402 foreach ( $columns as $k => $column ) {
2403 $c[$k] = wp_parse_args( $column, $defaults);
2404
2405 // parse options args
2406 if ( isset($column['options']) )
2407 $c[$k]['options'] = wp_parse_args( $column['options'], $defaults['options']);
2408
2409 // set type label
2410 if ( empty($column['options']['type_label']) && !empty($column['label']) )
2411 $c[$k]['options']['type_label'] = $column['label'];
2412 }
2413
2414 return $c;
2415 }
2416
2417 /**
2418 * Admin requests for orderby column
2419 *
2420 * @since 1.0
2421 */
2422 protected function get_stored_columns($type)
2423 {
2424 // get plugin options
2425 $options = get_option('cpac_options');
2426
2427 // get saved columns
2428 if ( isset($options['columns'][$type]) )
2429 return $options['columns'][$type];
2430
2431 return false;
2432 }
2433
2434 /**
2435 * Post Type Menu
2436 *
2437 * @since 1.0
2438 */
2439 private function get_menu()
2440 {
2441 // set
2442 $menu = '';
2443 $count = 1;
2444
2445 // referer
2446 $referer = ! empty($_REQUEST['cpac_type']) ? $_REQUEST['cpac_type'] : '';
2447
2448 // loop
2449 foreach ( $this->get_types() as $type ) {
2450 $label = $this->get_singular_name($type);
2451 $clean_label = $this->sanitize_string($type);
2452
2453 // divider
2454 $divider = $count++ == 1 ? '' : ' | ';
2455
2456 // current
2457 $current = '';
2458 if ( $this->is_menu_type_current($type) )
2459 $current = ' class="current"';
2460
2461 // menu list
2462 $menu .= "
2463 <li>{$divider}<a{$current} href='#cpac-box-{$clean_label}'>{$label}</a></li>
2464 ";
2465 }
2466
2467 // settings url
2468 $class_current_settings = $this->is_menu_type_current('plugin_settings') ? ' current': '';
2469
2470 // options button
2471 $options_btn = "<a href='#cpac-box-plugin_settings' class='cpac-settings-link{$class_current_settings}'>".__('Addons')."</a>";
2472 //$options_btn = '';
2473
2474 return "
2475 <div class='cpac-menu'>
2476 <ul class='subsubsub'>
2477 {$menu}
2478 </ul>
2479 {$options_btn}
2480 </div>
2481 ";
2482 }
2483
2484 /**
2485 * Checks if menu type is currently viewed
2486 *
2487 * @since 1.0
2488 */
2489 private function is_menu_type_current( $type )
2490 {
2491 // referer
2492 $referer = ! empty($_REQUEST['cpac_type']) ? $_REQUEST['cpac_type'] : '';
2493
2494 // get label
2495 $clean_label = $this->sanitize_string($type);
2496
2497 // get first element from post-types
2498 $first = array_shift( array_values($this->post_types) );
2499
2500 // display the page that was being viewed before saving
2501 if ( $referer ) {
2502 if ( $referer == 'cpac-box-'.$clean_label ) {
2503 return true;
2504 }
2505
2506 // settings page has not yet been saved
2507 } elseif ( $first == $type ) {
2508 return true;
2509 }
2510
2511 return false;
2512 }
2513
2514 /**
2515 * Get singular name of post type
2516 *
2517 * @since 1.0
2518 */
2519 private function get_singular_name( $type )
2520 {
2521 // Links
2522 if ( $type == 'wp-links' )
2523 $label = 'Links';
2524
2525 // Comments
2526 elseif ( $type == 'wp-comments' )
2527 $label = 'Comments';
2528
2529 // Users
2530 elseif ( $type == 'wp-users' )
2531 $label = 'Users';
2532
2533 // Media
2534 elseif ( $type == 'wp-media' )
2535 $label = 'Media Library';
2536
2537 // Posts
2538 else {
2539 $posttype_obj = get_post_type_object($type);
2540 $label = $posttype_obj->labels->singular_name;
2541 }
2542
2543 return $label;
2544 }
2545
2546 /**
2547 * Get plural name of post type
2548 *
2549 * @since 1.3.1
2550 */
2551 private function get_plural_name( $type )
2552 {
2553 $posttype_obj = get_post_type_object($type);
2554 if ( $posttype_obj )
2555 return $posttype_obj->labels->name;
2556
2557 return false;
2558 }
2559
2560 /**
2561 * Get screen link to overview screen
2562 *
2563 * @since 1.3.1
2564 */
2565 private function get_type_screen_link( $type )
2566 {
2567 // Links
2568 if ( $type == 'wp-comments' )
2569 $link = get_admin_url() . 'edit-comments.php';
2570
2571 // Links
2572 if ( $type == 'wp-links' )
2573 $link = get_admin_url() . 'link-manager.php';
2574
2575 // Users
2576 if ( $type == 'wp-users' )
2577 $link = get_admin_url() . 'users.php';
2578
2579 // Media
2580 elseif ( $type == 'wp-media' )
2581 $link = get_admin_url() . 'upload.php';
2582
2583 // Posts
2584 else
2585 $link = get_admin_url() . "edit.php?post_type={$type}";
2586
2587 return $link;
2588 }
2589
2590 /**
2591 * Sanitize label
2592 *
2593 * Uses intern wordpress function esc_url so it matches the label sorting url.
2594 *
2595 * @since 1.0
2596 */
2597 protected function sanitize_string($string)
2598 {
2599 $string = esc_url($string);
2600 $string = str_replace('http://','', $string);
2601 $string = str_replace('https://','', $string);
2602
2603 return $string;
2604 }
2605
2606 /**
2607 * Get plugin url.
2608 *
2609 * @since 1.0
2610 */
2611 private function plugin_url( $file = '' )
2612 {
2613 return plugins_url($file, __FILE__);
2614 }
2615
2616 /**
2617 * Checks if column-meta key exists
2618 *
2619 * @since 1.0
2620 */
2621 protected function is_column_meta( $id = '' )
2622 {
2623 if ( strpos($id, 'column-meta-') !== false )
2624 return true;
2625
2626 return false;
2627 }
2628
2629 /**
2630 * Get the posttype from columnname
2631 *
2632 * @since 1.3.1
2633 */
2634 protected function get_posttype_by_postcount_column( $id = '' )
2635 {
2636 if ( strpos($id, 'column-user_postcount-') !== false )
2637 return str_replace('column-user_postcount-', '', $id);
2638
2639 return false;
2640 }
2641
2642 /**
2643 * Get a thumbnail
2644 *
2645 * @since 1.0
2646 */
2647 private function get_thumbnail( $image = '' )
2648 {
2649 if ( empty($image) )
2650 return false;
2651
2652 // get correct image path
2653 $image_path = str_replace( WP_CONTENT_URL, WP_CONTENT_DIR, $image);
2654
2655 // resize image
2656 if ( file_exists($image_path) && $this->is_image($image_path) ) {
2657 $resized = image_resize( $image_path, 80, 80, true);
2658
2659 if ( ! is_wp_error( $resized ) ) {
2660 $image = str_replace( WP_CONTENT_DIR, WP_CONTENT_URL, $resized);
2661
2662 return "<img src='{$image}' alt='' width='80' height='80' />";
2663 }
2664
2665 return $resized->get_error_message();
2666 }
2667
2668 return false;
2669 }
2670
2671 /**
2672 * Get a thumbnail
2673 *
2674 * @since 1.3.1
2675 */
2676 private function get_media_thumbnails($meta)
2677 {
2678 $meta = $this->strip_trim( str_replace(' ','', $meta) );
2679
2680 // split media ids
2681 $media_ids = array($meta);
2682 if ( strpos($meta, ',') !== false )
2683 $media_ids = explode(',', $meta);
2684
2685 // check if media exists
2686 $thumbs = '';
2687 foreach ( $media_ids as $media_id )
2688 if ( is_numeric($media_id) )
2689 $thumbs .= wp_get_attachment_url($media_id) ? "<span class='cpac-column-value-image'>".wp_get_attachment_image( $media_id, array(80,80), true )."</span>" : '';
2690
2691 return $thumbs;
2692 }
2693
2694 /**
2695 * Checks an URL for image extension
2696 *
2697 * @since 1.2
2698 */
2699 private function is_image($url)
2700 {
2701 $validExt = array('.jpg', '.jpeg', '.gif', '.png', '.bmp');
2702 $ext = strrchr($url, '.');
2703
2704 return in_array($ext, $validExt);
2705 }
2706
2707 /**
2708 * Admin body class
2709 *
2710 * @since 1.4
2711 */
2712 function admin_class()
2713 {
2714 global $current_screen;
2715
2716 // we dont need the 'edit-' part
2717 $screen = str_replace('edit-', '', $current_screen->id);
2718
2719 // media library exception
2720 if ( $current_screen->base == 'upload' && $current_screen->id == 'upload' ) {
2721 $screen = 'media';
2722 }
2723
2724 // link exception
2725 if ( $current_screen->base == 'link-manager' && $current_screen->id == 'link-manager' ) {
2726 $screen = 'links';
2727 }
2728
2729 // loop the available types
2730 foreach ( $this->get_types() as $type => $label ) {
2731
2732 // match against screen or wp-screen
2733 if ( $type == $screen || $type == "wp-{$screen}" )
2734 return "cp-{$type}";
2735 }
2736 return false;
2737 }
2738
2739 /**
2740 * Admin CSS for Column width
2741 *
2742 * @since 1.4
2743 */
2744 function admin_css()
2745 {
2746 $css = '';
2747
2748 // loop throug the available types...
2749 foreach ( $this->get_types() as $type ) {
2750 $cols = $this->get_stored_columns($type);
2751 if ( $cols ) {
2752
2753 // loop through each available column...
2754 foreach ( $cols as $col_name => $col ) {
2755
2756 // and check for stored width and add it to the css
2757 if (!empty($col['width']) && is_numeric($col['width']) && $col['width'] > 0 ) {
2758 $css .= ".cp-{$type} .wrap table th.column-{$col_name} { width: {$col['width']}% !important; }";
2759 }
2760 }
2761 }
2762 }
2763
2764 echo "<style type='text/css'>{$css}</style>";
2765 }
2766
2767 /**
2768 * Unlocks
2769 *
2770 * @since 1.3
2771 */
2772 protected function is_unlocked($type)
2773 {
2774 return preg_match('/^[a-f0-9]{40}$/i', $this->get_license_key($type));
2775 }
2776
2777 /**
2778 * Check license key with API
2779 *
2780 * @since 1.3.3
2781 */
2782 private function check_remote_key($type, $key)
2783 {
2784 if ( empty($type) || empty($key) )
2785 return false;
2786
2787 // check key with remote API
2788 $response = wp_remote_post( $this->api_url, array(
2789 'body' => array(
2790 'api' => 'addon',
2791 'key' => $key,
2792 'type' => $type
2793 )
2794 ));
2795
2796 // license will be valid in case of WP error or succes
2797 if ( is_wp_error($response) || ( isset($response['body']) && json_decode($response['body']) == 'valid' ) )
2798 return true;
2799
2800 return false;
2801 }
2802
2803 /**
2804 * Set masked license key
2805 *
2806 * @since 1.3.1
2807 */
2808 private function get_masked_license_key($type)
2809 {
2810 return '**************************'.substr( $this->get_license_key($type), -4 );
2811 }
2812
2813 /**
2814 * Ajax activation
2815 *
2816 * @since 1.3.1
2817 */
2818 public function ajax_activation()
2819 {
2820 // keys
2821 $key = $_POST['key'];
2822 $type = $_POST['type'];
2823
2824 // update key
2825 if ( $key == 'remove' ) {
2826 $this->remove_license_key($type);
2827 }
2828
2829 // set license key
2830 elseif ( $this->check_remote_key($type, $key) ) {
2831
2832 // set key
2833 $this->set_license_key($type, $key);
2834
2835 // returned masked key
2836 echo json_encode( $this->get_masked_license_key($type) );
2837 }
2838
2839 exit;
2840 }
2841
2842 /**
2843 * Get license key
2844 *
2845 * @since 1.3
2846 */
2847 private function get_license_key($type)
2848 {
2849 return get_option("cpac_{$type}_ac");
2850 }
2851
2852 /**
2853 * Set license key
2854 *
2855 * @since 1.3
2856 */
2857 private function set_license_key($type, $key)
2858 {
2859 update_option( "cpac_{$type}_ac", $key);
2860 }
2861
2862 /**
2863 * Remove license key
2864 *
2865 * @since 1.3.1
2866 */
2867 private function remove_license_key($type)
2868 {
2869 delete_option( "cpac_{$type}_ac" );
2870 delete_transient("cpac_{$type}_trnsnt");
2871 }
2872
2873 /**
2874 * Strip tags and trim
2875 *
2876 * @since 1.3
2877 */
2878 protected function strip_trim($string)
2879 {
2880 return trim(strip_tags($string));
2881 }
2882
2883 /**
2884 * Get date
2885 *
2886 * @since 1.3.1
2887 */
2888 protected function get_date($date)
2889 {
2890 if ( ! $date )
2891 return false;
2892
2893 if ( ! is_numeric($date) )
2894 $date = strtotime($date);
2895
2896 return date_i18n( get_option('date_format'), $date );
2897 }
2898
2899 /**
2900 * Get time
2901 *
2902 * @since 1.3.1
2903 */
2904 protected function get_time($date)
2905 {
2906 if ( ! $date )
2907 return false;
2908
2909 if ( ! is_numeric($date) )
2910 $date = strtotime($date);
2911
2912 return date_i18n( get_option('time_format'), $date );
2913 }
2914
2915 /**
2916 * Admin notices
2917 *
2918 * @since 1.3.1
2919 */
2920 private function admin_notice($message = '', $type = 'updated')
2921 {
2922 $this->notice_message = $message;
2923 $this->notice_type = $type; // updated, error
2924
2925 add_action('admin_notices', array( $this, 'callback_admin_notice' ) );
2926 }
2927
2928 /**
2929 * Output Notice
2930 *
2931 * @since 1.3.1
2932 */
2933 public function callback_admin_notice()
2934 {
2935 echo "<div class='{$this->notice_type}' id='message'><p>{$this->notice_message}</p></div>";
2936 }
2937
2938 /**
2939 * Add help tabs
2940 *
2941 * @since 1.3
2942 */
2943 public function help_tabs($page)
2944 {
2945 $screen = get_current_screen();
2946
2947 if ( $screen->id != $this->admin_page || ! method_exists($screen,'add_help_tab') )
2948 return;
2949
2950 $admin_url = get_admin_url();
2951
2952 // add help content
2953 $tabs = array(
2954 array(
2955 'title' => 'Overview',
2956 'content' => "
2957 <h5>Codepress Admin Columns</h5>
2958 <p>
2959 This plugin is for adding and removing additional columns to the administration screens for post(types), pages, media library, comments, links and users. Change the column's label and reorder them.
2960 </p>
2961
2962 "
2963 ),
2964 array(
2965 'title' => 'Basics',
2966 'content' => "
2967 <h5>Show / Hide</h5>
2968 <p>
2969 You can switch columns on or off by cliking on the checkbox. This will show or hide each column heading.
2970 </p>
2971 <h5>Change order</h5>
2972 <p>
2973 By dragging the columns you can change the order which they will appear in.
2974 </p>
2975 <h5>Change label</h5>
2976 <p>
2977 By clicking on the triangle you will see the column options. Here you can change each label of the columns heading.
2978 </p>
2979 <h5>Change coluimn width</h5>
2980 <p>
2981 By clicking on the triangle you will see the column options. By using the draggable slider yo can set the width of the columns in percentages.
2982 </p>
2983 "
2984 ),
2985 array(
2986 'title' => 'Custom Field',
2987 'content' => "
2988 <h5>'Custom Field' column</h5>
2989 <p>
2990 The custom field colum uses the custom fields from posts and users. There are 8 types which you can set.
2991 </p>
2992 <ul>
2993 <li><strong>Default</strong><br/>Value: Can be either a string or array. Arrays will be flattened and values are seperated by a ',' comma.</li>
2994 <li><strong>Image</strong><br/>Value: should only contain an image URL.</li>
2995 <li><strong>Media Library Icon</strong><br/>Value: should only contain Attachment IDs ( seperated by ',' ).</li>
2996 <li><strong>Excerpt</strong><br/>Value: This will show the first 20 words of the Post content.</li>
2997 <li><strong>Multiple Values</strong><br/>Value: should be an array. This will flatten any ( multi dimensional ) array.</li>
2998 <li><strong>Numeric</strong><br/>Value: Integers only.<br/>If you have the 'sorting addon' this will be used for sorting, so you can sort your posts on numeric (custom field) values.</li>
2999 <li><strong>Date</strong><br/>Value: Can be unix time stamp of date format as described in the <a href='http://codex.wordpress.org/Formatting_Date_and_Time'>Codex</a>. You can change the outputted date format at the <a href='{$admin_url}options-general.php'>general settings</a> page.</li>
3000 <li><strong>Post Titles</strong><br/>Value: can be one or more Post ID's (seperated by ',').</li>
3001 </ul>
3002 "
3003 )
3004 );
3005
3006 foreach ( $tabs as $k => $tab ) {
3007 $screen->add_help_tab(array(
3008 'id' => 'cpac-tab-'.$k, // unique id
3009 'title' => $tab['title'], // label
3010 'content' => $tab['content'], // body
3011 ));
3012 }
3013 }
3014
3015 /**
3016 * Activation settings
3017 *
3018 * @since 1.3.1
3019 */
3020 private function activation_settings()
3021 {
3022 $class_current_settings = $this->is_menu_type_current('plugin_settings') ? ' current' : ' hidden'; '';
3023
3024 /** Sortable */
3025 $masked_key = '';
3026 $class_sortorder_activate = '';
3027 $class_sortorder_deactivate = ' hidden';
3028
3029 // is unlocked
3030 if ( $this->is_unlocked('sortable') ) {
3031 $masked_key = $this->get_masked_license_key('sortable');
3032 $class_sortorder_activate = ' hidden';
3033 $class_sortorder_deactivate = '';
3034 }
3035
3036 // find out more
3037 $find_out_more = "<a href='{$this->codepress_url}/sortorder-addon/' class='button-primary alignright' target='_blank'>".__('find out more', $this->textdomain)." &raquo</a>";
3038
3039 // info box
3040 $sortable_tooltip = "
3041 <p>".__('This will make all of the new columns support sorting', $this->textdomain).".</p>
3042 <p>".__('By default WordPress let\'s you sort by title, date, comments and author. This will make you be able to <strong>sort by any column of any type!</strong>', $this->textdomain)."</p>
3043 <p>".__('Perfect for sorting your articles, media files, comments, links and users', $this->textdomain).".</p>
3044 <img src='" . $this->plugin_url('/assets/images/addon_sortable_1.png') . "' alt='' />
3045 {$find_out_more}
3046 ";
3047
3048 // markup
3049 $sortable = "
3050 <tr id='cpac-activation-sortable' class='last'>
3051 <td class='activation_type'>
3052 <span>" . __('Sortorder', $this->textdomain) . "</span>
3053 <div class='cpac-tooltip hidden'>
3054 <div class='qtip_title'>" . __('Sortorder', $this->textdomain) . "</div>
3055 <div class='qtip_content'>
3056 <p>" . __($sortable_tooltip, $this->textdomain) . "</p>
3057 </div>
3058 </div>
3059 </td>
3060 <td class='activation_status'>
3061 <div class='activate{$class_sortorder_activate}'>
3062 " . __('Inactive', $this->textdomain) . "
3063 </div>
3064 <div class='deactivate{$class_sortorder_deactivate}'>
3065 " . __('Active', $this->textdomain) . "
3066 </div>
3067 </td>
3068 <td class='activation_code'>
3069 <div class='activate{$class_sortorder_activate}'>
3070 <input type='text' value='" . __('Fill in your activation code', $this->textdomain) . "' name='cpac-sortable-key'>
3071 <a href='javascript:;' class='button'>" . __('Activate', $this->textdomain) . "<span></span></a>
3072 </div>
3073 <div class='deactivate{$class_sortorder_deactivate}'>
3074 <span class='masked_key'>{$masked_key}</span>
3075 <a href='javascript:;' class='button'>" . __('Deactivate', $this->textdomain) . "<span></span></a>
3076 </div>
3077 <div class='activation-error-msg'></div>
3078 </td>
3079 <td class='activation_more'>{$find_out_more}</td>
3080 </tr><!-- #cpac-activation-sortable -->
3081 ";
3082
3083 // settings
3084 $row = "
3085 <tr id='cpac-box-plugin_settings' valign='top' class='cpac-box-row {$class_current_settings}'>
3086 <td colspan='2'>
3087 <table class='nopadding'>
3088 <tr class='last'>
3089 <td>
3090 <h2>".__('Activate Add-ons', $this->textdomain)."</h2>
3091 <p>".__('Add-ons can be unlocked by purchasing a license key. Each key can be used on multiple sites', $this->textdomain)." <a target='_blank' href='{$this->codepress_url}/sortorder-addon/'>Visit the Plugin Store</a>.</p>
3092 <table class='widefat addons'>
3093 <thead>
3094 <tr>
3095 <th class='activation_type'>".__('Addon', $this->textdomain)."</th>
3096 <th class='activation_status'>".__('Status', $this->textdomain)."</th>
3097 <th class='activation_code'>".__('Activation Code', $this->textdomain)."</th>
3098 <th class='activation_more'></th>
3099 </tr>
3100 </thead>
3101 <tbody>
3102 {$sortable}
3103 </tbody>
3104 </table>
3105 <div class='addon-translation-string hidden'>
3106 <span class='tstring-fill-in'>" . __('Enter your activation code', $this->textdomain) . "</span>
3107 <span class='tstring-unrecognised'>" . __('Activation code unrecognised', $this->textdomain) . "</span>
3108 </div>
3109 </td>
3110 </tr>
3111 <!--
3112 <tr class='last'>
3113 <td colspan='2'>
3114 <h2>Options</h2>
3115 <ul class='cpac-options'>
3116 <li>
3117 <div class='cpac-option-label'>Thumbnail size</div>
3118 <div class='cpac-option-inputs'>
3119 <input type='text' id='thumbnail_size_w' class='small-text' name='cpac_options[settings][thumb_width]' value='80'/>
3120 <label for='thumbnail_size_w'>Width</label>
3121 <br/>
3122 <input type='text' id='thumbnail_size_h' class='small-text' name='cpac_options[settings][thumb_height]' value='80'/>
3123 <label for='thumbnail_size_h'>Height</label>
3124 </div>
3125 </li>
3126 <li>
3127 <div class='cpac-option-label'>Excerpt length</div>
3128 <div class='cpac-option-inputs'>
3129
3130 <input type='text' id='excerpt_length' class='small-text' name='cpac_options[settings][excerpt_length]' value='15'/>
3131 <label for='excerpt_length'>Number of words</label>
3132 </div>
3133 </li>
3134 </ul>
3135 </td>
3136 </tr>
3137 -->
3138 </table>
3139 </td>
3140 </tr><!-- #cpac-box-plugin_settings -->
3141 ";
3142
3143 return $row;
3144 }
3145
3146 /**
3147 * Settings Page Template.
3148 *
3149 * This function in conjunction with others usei the WordPress
3150 * Settings API to create a settings page where users can adjust
3151 * the behaviour of this plugin.
3152 *
3153 * @since 1.0
3154 */
3155 public function plugin_settings_page()
3156 {
3157
3158 // loop through post types
3159 $rows = '';
3160 foreach ( $this->get_types() as $type ) {
3161
3162 // post type label
3163 $label = $this->get_singular_name($type);
3164
3165 // screen link
3166 $screen_link = '';
3167 //$screen_link = $this->get_type_screen_link($type);
3168 //$screen_link = "<a href='{$screen_link}' class='go-to-screen'>" . sprintf( __('go to %s screen'), strtolower($label) ) . "</a>";
3169
3170 // id
3171 $id = $this->sanitize_string($type);
3172
3173 // build draggable boxes
3174 $boxes = $this->get_column_boxes($type);
3175
3176 // class
3177 $class = $this->is_menu_type_current($type) ? ' current' : ' hidden';
3178
3179 $rows .= "
3180 <tr id='cpac-box-{$id}' valign='top' class='cpac-box-row{$class}'>
3181 <th class='cpac_post_type' scope='row'>
3182 {$label}{$screen_link}
3183 </th>
3184 <td>
3185 <h3 class='cpac_post_type hidden'>{$label}</h3>
3186 {$boxes}
3187 </td>
3188 </tr>
3189 ";
3190 }
3191
3192 // Activation
3193 $activation_settings = $this->activation_settings();
3194
3195 // Post Type Menu
3196 $menu = $this->get_menu();
3197
3198 // Help screen message
3199 $help_text = '';
3200 if ( version_compare( get_bloginfo('version'), '3.2', '>' ) )
3201 $help_text = '<p>'.__('You will find a short overview at the <strong>Help</strong> section in the top-right screen.', $this->textdomain).'</p>';
3202
3203 // find out more
3204 $find_out_more = "<a href='{$this->codepress_url}/sortorder-addon/' class='alignright green' target='_blank'>".__('find out more', $this->textdomain)." &raquo</a>";
3205
3206 ?>
3207 <div id="cpac" class="wrap">
3208 <?php screen_icon($this->slug) ?>
3209 <h2><?php _e('Codepress Admin Columns', $this->textdomain); ?></h2>
3210 <?php echo $menu ?>
3211
3212 <div class="postbox-container cpac-col-right">
3213 <div class="metabox-holder">
3214 <div class="meta-box-sortables">
3215
3216 <div id="addons-cpac-settings" class="postbox">
3217 <div title="Click to toggle" class="handlediv"><br></div>
3218 <h3 class="hndle">
3219 <span><?php _e('Addons', $this->textdomain) ?></span>
3220 </h3>
3221 <div class="inside">
3222 <p><?php _e('By default WordPress let\'s you only sort by title, date, comments and author.', $this->textdomain) ?></p>
3223 <p><?php _e('Make <strong>all columns</strong> of <strong>all types</strong> support sorting &#8212; with the sorting addon.', $this->textdomain) ?></p>
3224 <?php echo $find_out_more ?>
3225 </div>
3226 </div><!-- addons-cpac-settings -->
3227
3228 <div id="likethisplugin-cpac-settings" class="postbox">
3229 <div title="Click to toggle" class="handlediv"><br></div>
3230 <h3 class="hndle">
3231 <span><?php _e('Like this plugin?', $this->textdomain) ?></span>
3232 </h3>
3233 <div class="inside">
3234 <p><?php _e('Why not do any or all of the following', $this->textdomain) ?>:</p>
3235 <ul>
3236 <li><a href="<?php echo $this->codepress_url ?>/"><?php _e('Link to it so other folks can find out about it.', $this->textdomain) ?></a></li>
3237 <li><a href="<?php echo $this->wordpress_url ?>"><?php _e('Give it a 5 star rating on WordPress.org.', $this->textdomain) ?></a></li>
3238 <li class="donate_link"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZDZRSYLQ4Z76J"><?php _e('Donate a token of your appreciation.', $this->textdomain) ?></a></li>
3239 </ul>
3240 </div>
3241 </div><!-- likethisplugin-cpac-settings -->
3242
3243 <div id="side-cpac-settings" class="postbox">
3244 <div title="Click to toggle" class="handlediv"><br></div>
3245 <h3 class="hndle">
3246 <span><?php _e('Need support?', $this->textdomain) ?></span>
3247 </h3>
3248 <div class="inside">
3249 <?php echo $help_text ?>
3250 <p><?php printf(__('If you are having problems with this plugin, please talk about them in the <a href="%s">Support forums</a> or send me an email %s.', $this->textdomain), 'http://wordpress.org/tags/codepress-admin-columns', '<a href="mailto:info@codepress.nl">info@codepress.nl</a>' );?></p>
3251 <p><?php printf(__("If you're sure you've found a bug, or have a feature request, please <a href='%s'>submit your feedback</a>.", $this->textdomain), "{$this->codepress_url}/feedback");?></p>
3252 </div>
3253 </div><!-- side-cpac-settings -->
3254
3255 </div>
3256 </div>
3257 </div><!-- .postbox-container -->
3258
3259 <div class="postbox-container cpac-col-left">
3260 <div class="metabox-holder">
3261 <div class="meta-box-sortables">
3262
3263 <div id="general-cpac-settings" class="postbox">
3264 <div title="Click to toggle" class="handlediv"><br></div>
3265 <h3 class="hndle">
3266 <span><?php _e('Admin Columns', $this->textdomain ); ?></span>
3267 </h3>
3268 <div class="inside">
3269 <form method="post" action="options.php">
3270
3271 <?php settings_fields( 'cpac-settings-group' ); ?>
3272
3273 <table class="form-table">
3274 <!-- columns -->
3275 <?php echo $rows; ?>
3276
3277 <!-- activation -->
3278 <?php echo $activation_settings; ?>
3279
3280 <tr class="bottom" valign="top">
3281 <th scope="row"></th>
3282 <td>
3283 <p class="submit">
3284 <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
3285 </p>
3286 </td>
3287 </tr>
3288 </table>
3289 </form>
3290 </div>
3291 </div><!-- general-settings -->
3292
3293 <div id="restore-cpac-settings" class="postbox">
3294 <div title="Click to toggle" class="handlediv"><br></div>
3295 <h3 class="hndle">
3296 <span><?php _e('Restore defaults', $this->textdomain) ?></span>
3297 </h3>
3298 <div class="inside">
3299 <form method="post" action="">
3300 <input type="submit" class="button" name="cpac-restore-defaults" value="<?php _e('Restore default settings', $this->textdomain ) ?>" onclick="return confirm('<?php _e("Warning! ALL saved admin columns data will be deleted. This cannot be undone. \'OK\' to delete, \'Cancel\' to stop", $this->textdomain); ?>');" />
3301 </form>
3302 <p class="description"><?php _e('This will delete all column settings and restore the default settings.', $this->textdomain); ?></p>
3303 </div>
3304 </div><!-- restore-cpac-settings -->
3305
3306 </div>
3307 </div>
3308 </div><!-- .postbox-container -->
3309 </div>
3310 <?php
3311 }
3312 }
3313
3314 /**
3315 * Init Class Codepress_Admin_Columns
3316 *
3317 * @since 1.0
3318 */
3319 new Codepress_Admin_Columns();
3320
3321
3322 /**
3323 * Init Class Codepress_Sortable_Columns
3324 *
3325 * @since 1.3
3326 */
3327 new Codepress_Sortable_Columns();
3328
3329 ?>