PluginProbe
Admin Columns / 1.4.4
Admin Columns v1.4.4
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 in Admin Columns 1.4.4, at codepress-admin-columns.php

2,373 lines 63.8 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.4
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.4' );
30 define( 'CPAC_TEXTDOMAIN', 'codepress-admin-columns' );
31 define( 'CPAC_SLUG', 'codepress-admin-columns' );
32 define( 'CPAC_URL', plugins_url('', __FILE__) );
33
34 // only run plugin in the admin interface
35 if ( !is_admin() )
36 return false;
37
38 /**
39 * Dependencies
40 *
41 * @since 1.3
42 */
43 require_once dirname( __FILE__ ) . '/classes/sortable.php';
44 require_once dirname( __FILE__ ) . '/classes/values.php';
45 require_once dirname( __FILE__ ) . '/classes/values/posts.php';
46 require_once dirname( __FILE__ ) . '/classes/values/users.php';
47 require_once dirname( __FILE__ ) . '/classes/values/media.php';
48 require_once dirname( __FILE__ ) . '/classes/values/link.php';
49 require_once dirname( __FILE__ ) . '/classes/values/comments.php';
50
51 /**
52 * Codepress Admin Columns Class
53 *
54 * @since 1.0
55 *
56 */
57 class Codepress_Admin_Columns
58 {
59 private $post_types,
60 $codepress_url,
61 $wordpress_url,
62 $api_url;
63
64 /**
65 * Constructor
66 *
67 * @since 1.0
68 */
69 function __construct()
70 {
71 $this->api_url = 'http://www.codepress.nl/';
72
73 // wp is loaded
74 add_action( 'wp_loaded', array( $this, 'init') );
75 }
76
77 /**
78 * Initialize plugin.
79 *
80 * Loading sequence is determined and intialized.
81 *
82 * @since 1.0
83 */
84 public function init()
85 {
86 // vars
87 $this->post_types = self::get_post_types();
88
89 // set
90 $this->codepress_url = 'http://www.codepress.nl/plugins/codepress-admin-columns';
91 $this->wordpress_url = 'http://wordpress.org/tags/codepress-admin-columns';
92
93 // translations
94 load_plugin_textdomain( CPAC_TEXTDOMAIN, false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
95
96 // register settings
97 add_action( 'admin_menu', array( $this, 'settings_menu') );
98 add_action( 'admin_init', array( $this, 'register_settings') );
99
100 // styling & scripts
101 add_action( 'admin_enqueue_scripts' , array( $this, 'column_styles') );
102 add_filter( 'admin_body_class', array( $this, 'admin_class' ) );
103 add_action( 'admin_head', array( $this, 'admin_css') );
104
105 // register columns
106 add_action( 'admin_init', array( $this, 'register_columns_headings' ) );
107 add_action( 'admin_init', array( $this, 'register_columns_values' ) );
108
109 // action ajax
110 add_action( 'wp_ajax_cpac_addon_activation', array( $this, 'ajax_activation'));
111
112 // handle requests gets a low priority so it will trigger when all other plugins have loaded their columns
113 add_action( 'admin_init', array( $this, 'handle_requests' ), 1000 );
114
115 // filters
116 add_filter( 'plugin_action_links', array( $this, 'add_settings_link'), 1, 2);
117 }
118
119 /**
120 * Admin Menu.
121 *
122 * Create the admin menu link for the settings page.
123 *
124 * @since 1.0
125 */
126 public function settings_menu()
127 {
128 $page = add_options_page(
129 // Page title
130 esc_html__( 'Admin Columns Settings', CPAC_TEXTDOMAIN ),
131 // Menu Title
132 esc_html__( 'Admin Columns', CPAC_TEXTDOMAIN ),
133 // Capability
134 'manage_options',
135 // Menu slug
136 CPAC_SLUG,
137 // Callback
138 array( $this, 'plugin_settings_page')
139 );
140
141 // set admin page
142 $this->admin_page = $page;
143
144 // settings page specific styles and scripts
145 add_action( "admin_print_styles-$page", array( $this, 'admin_styles') );
146 add_action( "admin_print_scripts-$page", array( $this, 'admin_scripts') );
147
148 // add help tabs
149 add_action("load-$page", array( $this, 'help_tabs'));
150 }
151
152 /**
153 * Add Settings link to plugin page
154 *
155 * @since 1.0
156 */
157 function add_settings_link( $links, $file )
158 {
159 if ( $file != plugin_basename( __FILE__ ))
160 return $links;
161
162 array_unshift($links, '<a href="' . admin_url("admin.php") . '?page=' . CPAC_SLUG . '">' . __( 'Settings' ) . '</a>');
163 return $links;
164 }
165
166 /**
167 * Register Column Values
168 *
169 * apply_filters location in includes/screen.php
170 *
171 * @since 1.0
172 */
173 public function register_columns_values()
174 {
175 new CPAC_Posts_Values();
176 new CPAC_Link_Values();
177 new CPAC_Media_Values();
178 new CPAC_Users_Values();
179 new CPAC_Comments_Values();
180 }
181 /**
182 * Register Columns Headings
183 *
184 * apply_filters location in includes/screen.php
185 *
186 * @since 1.0
187 */
188 public function register_columns_headings()
189 {
190 /** Posts */
191 foreach ( $this->post_types as $post_type ) {
192
193 // register column per post type
194 add_filter("manage_edit-{$post_type}_columns", array($this, 'callback_add_posts_column_headings'));
195 }
196
197 /** Users */
198 add_filter( "manage_users_columns", array($this, 'callback_add_users_column_headings'), 9);
199 // give higher priority, so it will load just before other plugins to prevent conflicts
200
201 /** Media */
202 add_filter( "manage_upload_columns", array($this, 'callback_add_media_column_headings'));
203
204 /** Links */
205 add_filter( "manage_link-manager_columns", array($this, 'callback_add_links_column_headings'));
206
207 /** Comments */
208 add_filter( "manage_edit-comments_columns", array($this, 'callback_add_comments_column_headings'));
209 }
210
211 /**
212 * Callback add Posts Column
213 *
214 * @since 1.0
215 */
216 public function callback_add_posts_column_headings($columns)
217 {
218 global $post;
219
220 return $this->add_columns_headings($post->post_type, $columns);
221 }
222
223 /**
224 * Callback add Users column
225 *
226 * @since 1.1
227 */
228 public function callback_add_users_column_headings($columns)
229 {
230 return $this->add_columns_headings('wp-users', $columns);
231 }
232
233 /**
234 * Callback add Media column
235 *
236 * @since 1.3
237 */
238 public function callback_add_media_column_headings($columns)
239 {
240 return $this->add_columns_headings('wp-media', $columns);
241 }
242
243 /**
244 * Callback add Links column
245 *
246 * @since 1.3.1
247 */
248 public function callback_add_links_column_headings($columns)
249 {
250 return $this->add_columns_headings('wp-links', $columns);
251 }
252
253 /**
254 * Callback add Comments column
255 *
256 * @since 1.3.1
257 */
258 public function callback_add_comments_column_headings($columns)
259 {
260 return $this->add_columns_headings('wp-comments', $columns);
261 }
262
263 /**
264 * Add managed columns by Type
265 *
266 * @since 1.1
267 */
268 protected function add_columns_headings( $type, $columns )
269 {
270 // only get stored columns.. the rest we don't need
271 $db_columns = self::get_stored_columns($type);
272
273 if ( !$db_columns )
274 return $columns;
275
276 // filter already loaded columns by plugins
277 $set_columns = $this->filter_preset_columns( $type, $columns );
278
279 // loop through columns
280 foreach ( $db_columns as $id => $values ) {
281 // is active
282 if ( isset($values['state']) && $values['state'] == 'on' ){
283
284 // register format
285 $set_columns[$id] = $values['label'];
286 }
287 }
288
289 return $set_columns;
290 }
291
292 /**
293 * Filter preset columns. These columns apply either for every post or set by a plugin.
294 *
295 * @since 1.0
296 */
297 private function filter_preset_columns( $type, $columns )
298 {
299 $options = get_option('cpac_options_default');
300
301 if ( !$options )
302 return $columns;
303
304 // we use the wp default columns for filtering...
305 $stored_wp_default_columns = $options[$type];
306
307 // ... the ones that are set by plugins, theme functions and such.
308 $dif_columns = array_diff(array_keys($columns), array_keys($stored_wp_default_columns));
309
310 // we add those to the columns
311 $pre_columns = array();
312 if ( $dif_columns ) {
313 foreach ( $dif_columns as $column ) {
314 $pre_columns[$column] = $columns[$column];
315 }
316 }
317
318 return $pre_columns;
319 }
320
321 /**
322 * Get a list of Column options per post type
323 *
324 * @since 1.0
325 */
326 private function get_column_boxes($type)
327 {
328 // merge all columns
329 $display_columns = $this->get_merged_columns($type);
330
331 // define
332 $list = '';
333
334 // loop throught the active columns
335 if ( $display_columns ) {
336 foreach ( $display_columns as $id => $values ) {
337
338 // add items to the list
339 $list .= $this->get_box($type, $id, $values);
340
341 }
342 }
343
344 // custom field button
345 $button_add_column = '';
346 if ( $this->get_meta_by_type($type) )
347 $button_add_column = "<a href='javacript:;' class='cpac-add-customfield-column button'>+ " . __('Add Custom Field Column', CPAC_TEXTDOMAIN) . "</a>";
348
349 return "
350 <div class='cpac-box'>
351 <ul class='cpac-option-list'>
352 {$list}
353 </ul>
354 {$button_add_column}
355 <div class='cpac-reorder-msg'>" . __('drag and drop to reorder', CPAC_TEXTDOMAIN) . "</div>
356 </div>
357 ";
358 }
359
360 /**
361 * Get merged columns
362 *
363 * @since 1.0
364 */
365 protected function get_merged_columns( $type )
366 {
367 /** Comments */
368 if ( $type == 'wp-comments' ) {
369 $wp_default_columns = $this->get_wp_default_comments_columns();
370 $wp_custom_columns = $this->get_custom_comments_columns();
371 }
372
373 /** Links */
374 elseif ( $type == 'wp-links' ) {
375 $wp_default_columns = $this->get_wp_default_links_columns();
376 $wp_custom_columns = $this->get_custom_links_columns();
377 }
378
379 /** Users */
380 elseif ( $type == 'wp-users' ) {
381 $wp_default_columns = $this->get_wp_default_users_columns();
382 $wp_custom_columns = $this->get_custom_users_columns();
383 }
384
385 /** Media */
386 elseif ( $type == 'wp-media' ) {
387 $wp_default_columns = $this->get_wp_default_media_columns();
388 $wp_custom_columns = $this->get_custom_media_columns();
389 }
390
391 /** Posts */
392 else {
393 $wp_default_columns = $this->get_wp_default_posts_columns($type);
394 $wp_custom_columns = $this->get_custom_posts_columns($type);
395 }
396
397 // merge columns
398 $display_columns = $this->parse_columns($wp_custom_columns, $wp_default_columns, $type);
399
400 return $display_columns;
401 }
402
403 /**
404 * Merge the default columns (set by WordPress) and the added custom columns (set by plugins, theme etc.)
405 *
406 * @since 1.3.3
407 */
408 function parse_columns($wp_custom_columns, $wp_default_columns, $type)
409 {
410 // merge columns
411 $default_columns = wp_parse_args($wp_custom_columns, $wp_default_columns);
412
413 //get saved database columns
414 $db_columns = self::get_stored_columns($type);
415 if ( $db_columns ) {
416
417 // let's remove any unavailable columns.. such as disabled plugins
418 $db_columns = $this->remove_unavailable_columns($db_columns, $default_columns);
419
420 // loop throught the active columns
421 foreach ( $db_columns as $id => $values ) {
422
423 // get column meta options from custom columns
424 if ( $this->is_column_meta($id) )
425 $db_columns[$id]['options'] = $wp_custom_columns['column-meta-1']['options'];
426
427 // add static options
428 elseif ( isset($default_columns[$id]['options']) )
429 $db_columns[$id]['options'] = $default_columns[$id]['options'];
430
431 unset($default_columns[$id]);
432 }
433 }
434
435 // merge all
436 return wp_parse_args($db_columns, $default_columns);
437 }
438
439 /**
440 * Remove deactivated (plugin) columns
441 *
442 * This will remove any columns that have been stored, but are no longer available. This happends
443 * when plugins are deactivated or when they are removed from the theme functions.
444 *
445 * @since 1.2
446 */
447 private function remove_unavailable_columns( array $db_columns, array $default_columns)
448 {
449 // check or differences
450 $diff = array_diff( array_keys($db_columns), array_keys($default_columns) );
451
452 if ( ! empty($diff) && is_array($diff) ) {
453 foreach ( $diff as $column_name ){
454 // make an exception for column-meta-xxx
455 if ( ! $this->is_column_meta($column_name) ) {
456 unset($db_columns[$column_name]);
457 }
458 }
459 }
460
461 return $db_columns;
462 }
463
464 /**
465 * Get checkbox
466 *
467 * @since 1.0
468 */
469 private function get_box($type, $id, $values)
470 {
471 $classes = array();
472
473 // set state
474 $state = isset($values['state']) ? $values['state'] : '';
475
476 // class
477 $classes[] = "cpac-box-{$id}";
478 if ( $state )
479 $classes[] = 'active';
480 if ( ! empty($values['options']['class']) )
481 $classes[] = $values['options']['class'];
482 $class = implode(' ', $classes);
483
484 // more box options
485 $more_options = $this->get_additional_box_options($type, $id, $values);
486 $action = "<a class='cpac-action' href='#open'>open</a>";
487
488 // type label
489 $type_label = isset($values['options']['type_label']) ? $values['options']['type_label'] : '';
490
491 // label
492 $label = isset($values['label']) ? str_replace("'", '"', $values['label']) : '';
493
494 // width
495 $width = isset($values['width']) ? $values['width'] : 0;
496 $width_descr = isset($values['width']) && $values['width'] > 0 ? $values['width'] . '%' : __('default', CPAC_TEXTDOMAIN);
497
498 // hide box options
499 $label_hidden = '';
500 if ( ! empty($values['options']['hide_options']) || strpos($label, '<img') !== false ) {
501 $label_hidden = ' style="display:none"';
502 }
503
504 $list = "
505 <li class='{$class}'>
506 <div class='cpac-sort-handle'></div>
507 <div class='cpac-type-options'>
508 <div class='cpac-checkbox'></div>
509 <input type='hidden' class='cpac-state' name='cpac_options[columns][{$type}][{$id}][state]' value='{$state}'/>
510 <label class='main-label'>{$values['label']}</label>
511 </div>
512 <div class='cpac-meta-title'>
513 {$action}
514 <span>{$type_label}</span>
515 </div>
516 <div class='cpac-type-inside'>
517 <label for='cpac_options-{$type}-{$id}-label'{$label_hidden}>Label: </label>
518 <input type='text' name='cpac_options[columns][{$type}][{$id}][label]' id='cpac_options-{$type}-{$id}-label' value='{$label}' class='text'{$label_hidden}/>
519 <label for='cpac_options-{$type}-{$id}-width'>".__('Width', CPAC_TEXTDOMAIN).":</label>
520 <input type='hidden' maxlength='4' class='input-width' name='cpac_options[columns][{$type}][{$id}][width]' id='cpac_options-{$type}-{$id}-width' value='{$width}' />
521 <div class='description width-decription' title='".__('default', CPAC_TEXTDOMAIN)."'>{$width_descr}</div>
522 <div class='input-width-range'></div>
523 <br/>
524 {$more_options}
525 </div>
526 </li>
527 ";
528
529 return $list;
530 }
531
532 /**
533 * Get additional box option fields
534 *
535 * @since 1.0
536 */
537 private function get_additional_box_options($type, $id, $values)
538 {
539 $fields = '';
540
541 // Custom Fields
542 if ( $this->is_column_meta($id) )
543 $fields = $this->get_box_options_customfields($type, $id, $values);
544
545 return $fields;
546 }
547
548 /**
549 * Box Options: Custom Fields
550 *
551 * @since 1.0
552 */
553 private function get_box_options_customfields($type, $id, $values)
554 {
555 // get post meta fields
556 $fields = $this->get_meta_by_type($type);
557
558 if ( empty($fields) )
559 return false;
560
561 // set meta field options
562 $current = ! empty($values['field']) ? $values['field'] : '' ;
563 $field_options = '';
564 foreach ($fields as $field) {
565 $field_options .= sprintf
566 (
567 '<option value="%s"%s>%s</option>',
568 $field,
569 $field == $current? ' selected="selected"':'',
570 $field
571 );
572 }
573
574 // set meta fieldtype options
575 $currenttype = ! empty($values['field_type']) ? $values['field_type'] : '' ;
576 $fieldtype_options = '';
577 $fieldtypes = array(
578 '' => __('Default'),
579 'image' => __('Image'),
580 'library_id' => __('Media Library Icon', CPAC_TEXTDOMAIN),
581 'excerpt' => __('Excerpt'),
582 'array' => __('Multiple Values', CPAC_TEXTDOMAIN),
583 'numeric' => __('Numeric', CPAC_TEXTDOMAIN),
584 'date' => __('Date', CPAC_TEXTDOMAIN),
585 'title_by_id' => __('Post Title (Post ID\'s)', CPAC_TEXTDOMAIN),
586 );
587
588 // add filter
589 $fieldtypes = apply_filters('cpac-field-types', $fieldtypes );
590
591 // set select options
592 foreach ( $fieldtypes as $fkey => $fieldtype ) {
593 $fieldtype_options .= sprintf
594 (
595 '<option value="%s"%s>%s</option>',
596 $fkey,
597 $fkey == $currenttype? ' selected="selected"':'',
598 $fieldtype
599 );
600 }
601
602 // before and after string
603 $before = ! empty($values['before']) ? $values['before'] : '' ;
604 $after = ! empty($values['after']) ? $values['after'] : '' ;
605
606 if ( empty($field_options) )
607 return false;
608
609 // add remove button
610 $remove = '<p class="remove-description description">'.__('This field can not be removed', CPAC_TEXTDOMAIN).'</p>';
611 if ( $id != 'column-meta-1') {
612 $remove = "
613 <p>
614 <a href='javascript:;' class='cpac-delete-custom-field-box'>".__('Remove')."</a>
615 </p>
616 ";
617 }
618
619 $inside = "
620 <label for='cpac-{$type}-{$id}-field'>Custom Field: </label>
621 <select name='cpac_options[columns][{$type}][{$id}][field]' id='cpac-{$type}-{$id}-field'>{$field_options}</select>
622 <br/>
623 <label for='cpac-{$type}-{$id}-field_type'>Field Type: </label>
624 <select name='cpac_options[columns][{$type}][{$id}][field_type]' id='cpac-{$type}-{$id}-field_type'>{$fieldtype_options}</select>
625 <br/>
626 <label for='cpac-{$type}-{$id}-before'>Before: </label>
627 <input type='text' class='cpac-before' name='cpac_options[columns][{$type}][{$id}][before]' id='cpac-{$type}-{$id}-before' value='{$before}'/>
628 <br/>
629 <label for='cpac-{$type}-{$id}-after'>After: </label>
630 <input type='text' class='cpac-after' name='cpac_options[columns][{$type}][{$id}][after]' id='cpac-{$type}-{$id}-after' value='{$after}'/>
631 <br/>
632 {$remove}
633 ";
634
635 return $inside;
636 }
637
638 /**
639 * Get post meta fields by type; post(types) or users.
640 *
641 * @since 1.0
642 */
643 private function get_meta_by_type($type = 'post')
644 {
645 global $wpdb;
646
647 /** Comments */
648 if ( $type == 'wp-comments') {
649 $sql = "SELECT DISTINCT meta_key FROM {$wpdb->commentmeta} ORDER BY 1";
650 }
651
652 /** Users */
653 elseif ( $type == 'wp-users') {
654 $sql = "SELECT DISTINCT meta_key FROM {$wpdb->usermeta} ORDER BY 1";
655 }
656
657 /** Media */
658 elseif ( $type == 'wp-media') {
659 $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 = 'attachment' ORDER BY 1");
660 }
661
662 /** Posts */
663 else {
664 $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);
665 }
666
667 // run sql
668 $fields = $wpdb->get_results($sql, ARRAY_N);
669
670 // postmeta
671 if ( $fields ) {
672 $meta_fields = array();
673 foreach ($fields as $field) {
674 // filter out hidden meta fields
675 if (substr($field[0],0,1) != "_") {
676 $meta_fields[] = $field[0];
677 }
678 }
679 return $meta_fields;
680 }
681
682 return false;
683 }
684
685 /**
686 * Register admin scripts
687 *
688 * @since 1.0
689 */
690 public function admin_scripts()
691 {
692 wp_enqueue_script( 'jquery-ui-slider' );
693 wp_enqueue_script( 'cpac-qtip2', CPAC_URL.'/assets/js/jquery.qtip.js', array('jquery'), CPAC_VERSION );
694 wp_enqueue_script( 'cpac-admin', CPAC_URL.'/assets/js/admin-column.js', array('jquery', 'dashboard', 'jquery-ui-sortable'), CPAC_VERSION );
695 }
696
697 /**
698 * Get column types
699 *
700 * @since 1.1
701 */
702 private function get_types()
703 {
704 $types = $this->post_types;
705 $types['wp-users'] = 'wp-users';
706 $types['wp-media'] = 'wp-media';
707 $types['wp-links'] = 'wp-links';
708 $types['wp-comments'] = 'wp-comments';
709
710 return $types;
711 }
712
713 /**
714 * Get post types
715 *
716 * @since 1.0
717 */
718 public static function get_post_types()
719 {
720 $post_types = get_post_types(array(
721 '_builtin' => false
722 ));
723 $post_types['post'] = 'post';
724 $post_types['page'] = 'page';
725
726 return apply_filters('cpac-get-post-types', $post_types);
727 }
728
729 /**
730 * Register admin css
731 *
732 * @since 1.0
733 */
734 public function admin_styles()
735 {
736 wp_enqueue_style( 'jquery-ui-lightness', CPAC_URL.'/assets/ui-theme/jquery-ui-1.8.18.custom.css', array(), CPAC_VERSION, 'all' );
737 wp_enqueue_style( 'cpac-admin', CPAC_URL.'/assets/css/admin-column.css', array(), CPAC_VERSION, 'all' );
738 }
739
740 /**
741 * Register column css
742 *
743 * @since 1.0
744 */
745 public function column_styles()
746 {
747 wp_enqueue_style( 'cpac-columns', CPAC_URL.'/assets/css/column.css', array(), CPAC_VERSION, 'all' );
748 }
749
750 /**
751 * Register plugin options
752 *
753 * @since 1.0
754 */
755 public function register_settings()
756 {
757 // If we have no options in the database, let's add them now.
758 if ( false === get_option('cpac_options') )
759 add_option( 'cpac_options', array($this, 'get_default_plugin_options') );
760
761 register_setting( 'cpac-settings-group', 'cpac_options', array($this, 'options_callback') );
762 }
763
764 /**
765 * Returns the default plugin options.
766 *
767 * @since 1.0
768 */
769 public function get_default_plugin_options()
770 {
771 $default_plugin_options = array(
772 'post' => '',
773 'page' => ''
774 );
775 return apply_filters( 'cpac_default_plugin_options', $default_plugin_options );
776 }
777
778 /**
779 * Optional callback.
780 *
781 * @since 1.0
782 */
783 public function options_callback($options)
784 {
785 return $options;
786 }
787
788 /**
789 * Handle requests.
790 *
791 * @since 1.0
792 */
793 public function handle_requests()
794 {
795 // settings updated
796 if ( ! empty($_REQUEST['settings-updated']) )
797 $this->store_wp_default_columns();
798
799 // restore defaults
800 if ( ! empty($_REQUEST['cpac-restore-defaults']) )
801 $this->restore_defaults();
802
803 }
804
805 /**
806 * Stores WP default columns
807 *
808 * This will store columns that are set by WordPress core or theme
809 *
810 * @since 1.2
811 */
812 private function store_wp_default_columns()
813 {
814 // stores the default columns that are set by WP or theme.
815 $wp_default_columns = array();
816
817 // Posts
818 foreach ( $this->post_types as $post_type ) {
819 $wp_default_columns[$post_type] = $this->get_wp_default_posts_columns($post_type);
820 }
821
822 // Users
823 $wp_default_columns['wp-users'] = $this->get_wp_default_users_columns();
824
825 // Media
826 $wp_default_columns['wp-media'] = $this->get_wp_default_media_columns();
827
828 // Links
829 $wp_default_columns['wp-links'] = $this->get_wp_default_links_columns();
830
831 // Comments
832 $wp_default_columns['wp-comments'] = $this->get_wp_default_comments_columns();
833
834 update_option( 'cpac_options_default', $wp_default_columns );
835 }
836
837 /**
838 * Restore defaults
839 *
840 * @since 1.0
841 */
842 private function restore_defaults()
843 {
844 delete_option( 'cpac_options' );
845 delete_option( 'cpac_options_default' );
846 }
847
848 /**
849 * Get WP default supported admin columns per post type.
850 *
851 * @since 1.0
852 */
853 private function get_wp_default_posts_columns($post_type = 'post')
854 {
855 // load dependencies
856
857 // deprecated as of wp3.3
858 if ( file_exists(ABSPATH . 'wp-admin/includes/template.php') )
859 require_once(ABSPATH . 'wp-admin/includes/template.php');
860
861 // introduced since wp3.3
862 if ( file_exists(ABSPATH . 'wp-admin/includes/screen.php') )
863 require_once(ABSPATH . 'wp-admin/includes/screen.php');
864
865 // used for getting columns
866 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
867 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
868 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php') )
869 require_once(ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php');
870
871 // some plugins depend on settings the $_GET['post_type'] variable such as ALL in One SEO
872 $_GET['post_type'] = $post_type;
873
874 // for 3rd party plugin support we will call load-edit.php so all the
875 // additional columns that are set by them will be avaible for us
876 do_action('load-edit.php');
877
878 // we need to change the current screen
879 global $current_screen;
880 $org_current_screen = $current_screen;
881
882 // overwrite current_screen global with our post type of choose...
883 $current_screen->post_type = $post_type;
884
885 // ...so we can get its columns
886 $columns = WP_Posts_List_Table::get_columns();
887
888 if ( empty ( $columns ) )
889 return false;
890
891 // change to uniform format
892 $posts_columns = $this->get_uniform_format($columns);
893
894 // reset current screen
895 $current_screen = $org_current_screen;
896
897 return $posts_columns;
898 }
899
900 /**
901 * Get WP default users columns per post type.
902 *
903 * @since 1.1
904 */
905 private function get_wp_default_users_columns()
906 {
907 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
908 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
909 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php') )
910 require_once(ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php');
911
912 // turn off site users
913 $this->is_site_users = false;
914
915 // get users columns
916 $columns = WP_Users_List_Table::get_columns();
917
918 // change to uniform format
919 $columns = $this->get_uniform_format($columns);
920
921 // add sorting to some of the default links columns
922 $columns = $this->set_sorting_to_default_users_columns($columns);
923
924 return apply_filters('cpac-default-users-columns', $columns);
925 }
926
927 /**
928 * Add Sorting to WP default Users columns
929 *
930 * @since 1.4
931 */
932 private function set_sorting_to_default_users_columns($columns)
933 {
934 // Comment
935 if ( !empty($columns['role']) ) {
936 $columns['role']['options']['sortorder'] = 'on';
937 }
938 return $columns;
939 }
940
941 /**
942 * Get WP default media columns.
943 *
944 * @since 1.2.1
945 */
946 private function get_wp_default_media_columns()
947 {
948 // could use _get_list_table('WP_Media_List_Table') ?
949 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
950 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
951 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-media-list-table.php') )
952 require_once(ABSPATH . 'wp-admin/includes/class-wp-media-list-table.php');
953
954 global $current_screen;
955 $org_current_screen = $current_screen;
956
957 // overwrite current_screen global with our media id...
958 $current_screen->id = 'upload';
959
960 // init media class
961 $wp_media = new WP_Media_List_Table;
962
963 // get media columns
964 $columns = $wp_media->get_columns();
965
966 // reset current screen
967 $current_screen = $org_current_screen;
968
969 // change to uniform format
970 return $this->get_uniform_format($columns);
971 }
972
973 /**
974 * Get WP default links columns.
975 *
976 * @since 1.3.1
977 */
978 private function get_wp_default_links_columns()
979 {
980 // dependencies
981 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
982 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
983 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-links-list-table.php') )
984 require_once(ABSPATH . 'wp-admin/includes/class-wp-links-list-table.php');
985
986 // get links columns
987 $columns = WP_Links_List_Table::get_columns();
988
989 // change to uniform format
990 $columns = $this->get_uniform_format($columns);
991
992 // add sorting to some of the default links columns
993 $columns = $this->set_sorting_to_default_links_columns($columns);
994
995 return apply_filters('cpac-default-links-columns', $columns);
996 }
997
998 /**
999 * Add Sorting to WP default links columns
1000 *
1001 * @since 1.4
1002 */
1003 private function set_sorting_to_default_links_columns($columns)
1004 {
1005 // Relationship
1006 if ( !empty($columns['rel']) ) {
1007 $columns['rel']['options']['sortorder'] = 'on';
1008 }
1009 return $columns;
1010 }
1011
1012 /**
1013 * Get WP default links columns.
1014 *
1015 * @since 1.3.1
1016 */
1017 private function get_wp_default_comments_columns()
1018 {
1019 // dependencies
1020 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1021 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1022 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-comments-list-table.php') )
1023 require_once(ABSPATH . 'wp-admin/includes/class-wp-comments-list-table.php');
1024
1025 global $current_screen;
1026 $org_current_screen = $current_screen;
1027
1028 // overwrite current_screen global with our media id...
1029 $current_screen->id = 'edit-comments';
1030
1031 // init table object
1032 $wp_comment = new WP_Comments_List_Table;
1033
1034 // get comments
1035 $columns = $wp_comment->get_columns();
1036
1037 // reset current screen
1038 $current_screen = $org_current_screen;
1039
1040 // change to uniform format
1041 $columns = $this->get_uniform_format($columns);
1042
1043 // add sorting to some of the default links columns
1044 $columns = $this->set_sorting_to_default_comments_columns($columns);
1045
1046 return apply_filters('cpac-default-comments-columns', $columns);
1047 }
1048
1049 /**
1050 * Add Sorting to WP default comments columns
1051 *
1052 * @since 1.4
1053 */
1054 private function set_sorting_to_default_comments_columns($columns)
1055 {
1056 // Comment
1057 if ( !empty($columns['comment']) ) {
1058 $columns['comment']['options']['sortorder'] = 'on';
1059 }
1060 return $columns;
1061 }
1062
1063 /**
1064 * Build uniform format for all columns
1065 *
1066 * @since 1.0
1067 */
1068 private function get_uniform_format($columns)
1069 {
1070 // we remove the checkbox column as an option...
1071 if ( isset($columns['cb']) )
1072 unset($columns['cb']);
1073
1074 // change to uniform format
1075 $uniform_columns = array();
1076 foreach ( (array) $columns as $id => $label ) {
1077 $hide_options = false;
1078 $type_label = $label;
1079
1080 // comment exception
1081 if ( strpos( $label, 'comment-grey-bubble.png') ) {
1082 $type_label = __('Comments', CPAC_TEXTDOMAIN);
1083 $hide_options = true;
1084 }
1085
1086 // user icon excerption
1087 if ( $id == 'icon' ) {
1088 $type_label = __('Icon', CPAC_TEXTDOMAIN);
1089 }
1090
1091 $uniform_colums[$id] = array(
1092 'label' => $label,
1093 'state' => 'on',
1094 'options' => array(
1095 'type_label' => $type_label,
1096 'hide_options' => $hide_options,
1097 'class' => 'cpac-box-wp-native',
1098 )
1099 );
1100 }
1101 return $uniform_colums;
1102 }
1103
1104 /**
1105 * Custom posts columns
1106 *
1107 * @since 1.0
1108 */
1109 private function get_custom_posts_columns($post_type)
1110 {
1111 $custom_columns = array(
1112 'column-featured_image' => array(
1113 'label' => __('Featured Image', CPAC_TEXTDOMAIN)
1114 ),
1115 'column-excerpt' => array(
1116 'label' => __('Excerpt', CPAC_TEXTDOMAIN)
1117 ),
1118 'column-order' => array(
1119 'label' => __('Page Order', CPAC_TEXTDOMAIN)
1120 ),
1121 'column-post_formats' => array(
1122 'label' => __('Post Format', CPAC_TEXTDOMAIN)
1123 ),
1124 'column-postid' => array(
1125 'label' => __('ID', CPAC_TEXTDOMAIN)
1126 ),
1127 'column-page-slug' => array(
1128 'label' => __('Slug', CPAC_TEXTDOMAIN)
1129 ),
1130 'column-attachment' => array(
1131 'label' => __('Attachment', CPAC_TEXTDOMAIN)
1132 ),
1133 'column-attachment-count' => array(
1134 'label' => __('No. of Attachments', CPAC_TEXTDOMAIN)
1135 ),
1136 'column-roles' => array(
1137 'label' => __('Roles', CPAC_TEXTDOMAIN)
1138 ),
1139 'column-status' => array(
1140 'label' => __('Status', CPAC_TEXTDOMAIN)
1141 ),
1142 'column-comment-status' => array(
1143 'label' => __('Comment status', CPAC_TEXTDOMAIN)
1144 ),
1145 'column-ping-status' => array(
1146 'label' => __('Ping status', CPAC_TEXTDOMAIN)
1147 ),
1148 'column-actions' => array(
1149 'label' => __('Actions', CPAC_TEXTDOMAIN),
1150 'options' => array(
1151 'sortorder' => false
1152 )
1153 ),
1154 'column-modified' => array(
1155 'label' => __('Last modified', CPAC_TEXTDOMAIN)
1156 ),
1157 'column-comment-count' => array(
1158 'label' => __('Comment count', CPAC_TEXTDOMAIN)
1159 )
1160 );
1161
1162 // Word count support
1163 if ( post_type_supports($post_type, 'editor') ) {
1164 $custom_columns['column-word-count'] = array(
1165 'label' => __('Word count', CPAC_TEXTDOMAIN)
1166 );
1167 }
1168
1169 // Sticky support
1170 if ( $post_type == 'post' ) {
1171 $custom_columns['column-sticky'] = array(
1172 'label' => __('Sticky', CPAC_TEXTDOMAIN)
1173 );
1174 }
1175
1176 // Order support
1177 if ( post_type_supports($post_type, 'page-attributes') ) {
1178 $custom_columns['column-order'] = array(
1179 'label' => __('Page Order', CPAC_TEXTDOMAIN),
1180 'options' => array(
1181 'type_label' => __('Order', CPAC_TEXTDOMAIN)
1182 )
1183 );
1184 }
1185
1186 // Page Template
1187 if ( $post_type == 'page' ) {
1188 $custom_columns['column-page-template'] = array(
1189 'label' => __('Page Template', CPAC_TEXTDOMAIN)
1190 );
1191 }
1192
1193 // Post Formats
1194 if ( post_type_supports($post_type, 'post-formats') ) {
1195 $custom_columns['column-post_formats'] = array(
1196 'label' => __('Post Format', CPAC_TEXTDOMAIN)
1197 );
1198 }
1199
1200 // Taxonomy support
1201 $taxonomies = get_object_taxonomies($post_type, 'objects');
1202 if ( $taxonomies ) {
1203 foreach ( $taxonomies as $tax_slug => $tax ) {
1204 if ( $tax_slug != 'post_tag' && $tax_slug != 'category' && $tax_slug != 'post_format' ) {
1205 $custom_columns['column-taxonomy-'.$tax->name] = array(
1206 'label' => $tax->label,
1207 'show_filter' => true,
1208 'options' => array(
1209 'type_label' => __('Taxonomy', CPAC_TEXTDOMAIN)
1210 )
1211 );
1212 }
1213 }
1214 }
1215
1216 // Custom Field support
1217 if ( $this->get_meta_by_type($post_type) ) {
1218 $custom_columns['column-meta-1'] = array(
1219 'label' => __('Custom Field', CPAC_TEXTDOMAIN),
1220 'field' => '',
1221 'field_type' => '',
1222 'before' => '',
1223 'after' => '',
1224 'options' => array(
1225 'type_label' => __('Field', CPAC_TEXTDOMAIN),
1226 'class' => 'cpac-box-metafield'
1227 )
1228 );
1229 }
1230
1231 // merge with defaults
1232 $custom_columns = $this->parse_defaults($custom_columns);
1233
1234 return apply_filters('cpac-custom-posts-columns', $custom_columns);
1235 }
1236
1237 /**
1238 * Custom users columns
1239 *
1240 * @since 1.1
1241 */
1242 private function get_custom_users_columns()
1243 {
1244 $custom_columns = array(
1245 'column-user_id' => array(
1246 'label' => __('User ID', CPAC_TEXTDOMAIN)
1247 ),
1248 'column-nickname' => array(
1249 'label' => __('Nickname', CPAC_TEXTDOMAIN)
1250 ),
1251 'column-first_name' => array(
1252 'label' => __('First name', CPAC_TEXTDOMAIN)
1253 ),
1254 'column-last_name' => array(
1255 'label' => __('Last name', CPAC_TEXTDOMAIN)
1256 ),
1257 'column-user_url' => array(
1258 'label' => __('Url', CPAC_TEXTDOMAIN)
1259 ),
1260 'column-user_registered' => array(
1261 'label' => __('Registered', CPAC_TEXTDOMAIN)
1262 ),
1263 'column-user_description' => array(
1264 'label' => __('Description', CPAC_TEXTDOMAIN)
1265 ),
1266 'column-actions' => array(
1267 'label' => __('Actions', CPAC_TEXTDOMAIN),
1268 'options' => array(
1269 'sortorder' => false
1270 )
1271 ),
1272 );
1273
1274 // User total number of posts
1275 foreach ( self::get_post_types() as $post_type ) {
1276 $label = $this->get_plural_name($post_type);
1277 $custom_columns['column-user_postcount-'.$post_type] = array(
1278 'label' => __( sprintf('No. of %s',$label), CPAC_TEXTDOMAIN),
1279 'options' => array(
1280 'type_label' => __('Postcount', CPAC_TEXTDOMAIN)
1281 )
1282 );
1283 }
1284
1285 // Custom Field support
1286 $custom_columns['column-meta-1'] = array(
1287 'label' => __('Custom Field', CPAC_TEXTDOMAIN),
1288 'field' => '',
1289 'field_type' => '',
1290 'before' => '',
1291 'after' => '',
1292 'options' => array(
1293 'type_label' => __('Field', CPAC_TEXTDOMAIN),
1294 'class' => 'cpac-box-metafield'
1295 )
1296 );
1297
1298 // merge with defaults
1299 $custom_columns = $this->parse_defaults($custom_columns);
1300
1301 return apply_filters('cpac-custom-users-columns', $custom_columns);
1302 }
1303
1304 /**
1305 * Custom media columns
1306 *
1307 * @since 1.3
1308 */
1309 private function get_custom_media_columns()
1310 {
1311 $custom_columns = array(
1312 'column-mediaid' => array(
1313 'label' => __('ID', CPAC_TEXTDOMAIN)
1314 ),
1315 'column-mime_type' => array(
1316 'label' => __('Mime type', CPAC_TEXTDOMAIN)
1317 ),
1318 'column-file_name' => array(
1319 'label' => __('File name', CPAC_TEXTDOMAIN)
1320 ),
1321 'column-dimensions' => array(
1322 'label' => __('Dimensions', CPAC_TEXTDOMAIN)
1323 ),
1324 'column-height' => array(
1325 'label' => __('Height', CPAC_TEXTDOMAIN)
1326 ),
1327 'column-width' => array(
1328 'label' => __('Width', CPAC_TEXTDOMAIN)
1329 ),
1330 'column-caption' => array(
1331 'label' => __('Caption', CPAC_TEXTDOMAIN)
1332 ),
1333 'column-description' => array(
1334 'label' => __('Description', CPAC_TEXTDOMAIN)
1335 ),
1336 'column-alternate_text' => array(
1337 'label' => __('Alt', CPAC_TEXTDOMAIN)
1338 ),
1339 'column-file_paths' => array(
1340 'label' => __('Upload paths', CPAC_TEXTDOMAIN),
1341 'options' => array(
1342 'sortorder' => false
1343 )
1344 )
1345 );
1346
1347 // Get extended image metadata, exif or iptc as available.
1348 // uses exif_read_data()
1349 if ( function_exists('exif_read_data') ) {
1350 $custom_columns = array_merge( $custom_columns, array(
1351 'column-image-aperture' => array(
1352 'label' => __('Aperture', CPAC_TEXTDOMAIN),
1353 'options' => array(
1354 'type_label' => __('Aperture EXIF', CPAC_TEXTDOMAIN)
1355 )
1356 ),
1357 'column-image-credit' => array(
1358 'label' => __('Credit', CPAC_TEXTDOMAIN),
1359 'options' => array(
1360 'type_label' => __('Credit EXIF', CPAC_TEXTDOMAIN)
1361 )
1362 ),
1363 'column-image-camera' => array(
1364 'label' => __('Camera', CPAC_TEXTDOMAIN),
1365 'options' => array(
1366 'type_label' => __('Camera EXIF', CPAC_TEXTDOMAIN)
1367 )
1368 ),
1369 'column-image-caption' => array(
1370 'label' => __('Caption', CPAC_TEXTDOMAIN),
1371 'options' => array(
1372 'type_label' => __('Caption EXIF', CPAC_TEXTDOMAIN)
1373 )
1374 ),
1375 'column-image-created_timestamp' => array(
1376 'label' => __('Timestamp', CPAC_TEXTDOMAIN),
1377 'options' => array(
1378 'type_label' => __('Timestamp EXIF', CPAC_TEXTDOMAIN)
1379 )
1380 ),
1381 'column-image-copyright' => array(
1382 'label' => __('Copyright', CPAC_TEXTDOMAIN),
1383 'options' => array(
1384 'type_label' => __('Copyright EXIF', CPAC_TEXTDOMAIN)
1385 )
1386 ),
1387 'column-image-focal_length' => array(
1388 'label' => __('Focal Length', CPAC_TEXTDOMAIN),
1389 'options' => array(
1390 'type_label' => __('Focal Length EXIF', CPAC_TEXTDOMAIN)
1391 )
1392 ),
1393 'column-image-iso' => array(
1394 'label' => __('ISO', CPAC_TEXTDOMAIN),
1395 'options' => array(
1396 'type_label' => __('ISO EXIF', CPAC_TEXTDOMAIN)
1397 )
1398 ),
1399 'column-image-shutter_speed' => array(
1400 'label' => __('Shutter Speed', CPAC_TEXTDOMAIN),
1401 'options' => array(
1402 'type_label' => __('Shutter Speed EXIF', CPAC_TEXTDOMAIN)
1403 )
1404 ),
1405 'column-image-title' => array(
1406 'label' => __('Title', CPAC_TEXTDOMAIN),
1407 'options' => array(
1408 'type_label' => __('Title EXIF', CPAC_TEXTDOMAIN)
1409 )
1410 )
1411 ));
1412 }
1413
1414 // Custom Field support
1415 if ( $this->get_meta_by_type('wp-media') ) {
1416 $custom_columns['column-meta-1'] = array(
1417 'label' => __('Custom Field', CPAC_TEXTDOMAIN),
1418 'field' => '',
1419 'field_type' => '',
1420 'before' => '',
1421 'after' => '',
1422 'options' => array(
1423 'type_label' => __('Field', CPAC_TEXTDOMAIN),
1424 'class' => 'cpac-box-metafield'
1425 )
1426 );
1427 }
1428
1429 // merge with defaults
1430 $custom_columns = $this->parse_defaults($custom_columns);
1431
1432 return apply_filters('cpac-custom-media-columns', $custom_columns);
1433 }
1434
1435 /**
1436 * Custom links columns
1437 *
1438 * @since 1.3.1
1439 */
1440 private function get_custom_links_columns()
1441 {
1442 $custom_columns = array(
1443 'column-link_id' => array (
1444 'label' => __('ID', CPAC_TEXTDOMAIN)
1445 ),
1446 'column-description' => array (
1447 'label' => __('Description', CPAC_TEXTDOMAIN)
1448 ),
1449 'column-image' => array(
1450 'label' => __('Image', CPAC_TEXTDOMAIN)
1451 ),
1452 'column-target' => array(
1453 'label' => __('Target', CPAC_TEXTDOMAIN)
1454 ),
1455 'column-owner' => array(
1456 'label' => __('Owner', CPAC_TEXTDOMAIN)
1457 ),
1458 'column-notes' => array(
1459 'label' => __('Notes', CPAC_TEXTDOMAIN)
1460 ),
1461 'column-rss' => array(
1462 'label' => __('Rss', CPAC_TEXTDOMAIN)
1463 ),
1464 'column-length' => array(
1465 'label' => __('Length', CPAC_TEXTDOMAIN)
1466 )
1467 );
1468
1469 // merge with defaults
1470 $custom_columns = $this->parse_defaults($custom_columns);
1471
1472 return apply_filters('cpac-custom-links-columns', $custom_columns);
1473 }
1474
1475 /**
1476 * Custom comments columns
1477 *
1478 * @since 1.3.1
1479 */
1480 private function get_custom_comments_columns()
1481 {
1482 $custom_columns = array(
1483 'column-comment_id' => array(
1484 'label' => __('ID', CPAC_TEXTDOMAIN)
1485 ),
1486 'column-author_author' => array(
1487 'label' => __('Author Name', CPAC_TEXTDOMAIN)
1488 ),
1489 'column-author_avatar' => array(
1490 'label' => __('Avatar', CPAC_TEXTDOMAIN)
1491 ),
1492 'column-author_url' => array(
1493 'label' => __('Author url', CPAC_TEXTDOMAIN)
1494 ),
1495 'column-author_ip' => array(
1496 'label' => __('Author IP', CPAC_TEXTDOMAIN)
1497 ),
1498 'column-author_email' => array(
1499 'label' => __('Author email', CPAC_TEXTDOMAIN)
1500 ),
1501 'column-reply_to' => array(
1502 'label' => __('In Reply To', CPAC_TEXTDOMAIN),
1503
1504 // options
1505 'options' => array(
1506 'sortorder' => false
1507 )
1508 ),
1509 'column-approved' => array(
1510 'label' => __('Approved', CPAC_TEXTDOMAIN)
1511 ),
1512 'column-date' => array(
1513 'label' => __('Date', CPAC_TEXTDOMAIN)
1514 ),
1515 'column-date_gmt' => array(
1516 'label' => __('Date GMT', CPAC_TEXTDOMAIN)
1517 ),
1518 'column-agent' => array(
1519 'label' => __('Agent', CPAC_TEXTDOMAIN)
1520 ),
1521 'column-excerpt' => array(
1522 'label' => __('Excerpt', CPAC_TEXTDOMAIN)
1523 )
1524 );
1525
1526 // Custom Field support
1527 if ( $this->get_meta_by_type('wp-comments') ) {
1528 $custom_columns['column-meta-1'] = array(
1529 'label' => __('Custom Field', CPAC_TEXTDOMAIN),
1530 'field' => '',
1531 'field_type' => '',
1532 'before' => '',
1533 'after' => '',
1534 'options' => array(
1535 'type_label' => __('Field', CPAC_TEXTDOMAIN),
1536 'class' => 'cpac-box-metafield',
1537 'sortorder' => false,
1538 )
1539 );
1540 }
1541
1542 // merge with defaults
1543 $custom_columns = $this->parse_defaults($custom_columns);
1544
1545 return apply_filters('cpac-custom-comments-columns', $custom_columns);
1546 }
1547
1548 /**
1549 * Parse defaults
1550 *
1551 * @since 1.1
1552 */
1553 private function parse_defaults($columns)
1554 {
1555 // default arguments
1556 $defaults = array(
1557
1558 // stored values
1559 'label' => '',
1560 'state' => '',
1561 'width' => '',
1562
1563 // static values
1564 'options' => array(
1565 'type_label' => __('Custom', CPAC_TEXTDOMAIN),
1566 'hide_options' => false,
1567 'class' => 'cpac-box-custom',
1568 'sortorder' => 'on',
1569 )
1570 );
1571
1572 // parse args
1573 foreach ( $columns as $k => $column ) {
1574 $c[$k] = wp_parse_args( $column, $defaults);
1575
1576 // parse options args
1577 if ( isset($column['options']) )
1578 $c[$k]['options'] = wp_parse_args( $column['options'], $defaults['options']);
1579
1580 // set type label
1581 if ( empty($column['options']['type_label']) && !empty($column['label']) )
1582 $c[$k]['options']['type_label'] = $column['label'];
1583 }
1584
1585 return $c;
1586 }
1587
1588 /**
1589 * Admin requests for orderby column
1590 *
1591 * @since 1.0
1592 */
1593 public static function get_stored_columns($type)
1594 {
1595 // get plugin options
1596 $options = get_option('cpac_options');
1597
1598 // get saved columns
1599 if ( isset($options['columns'][$type]) )
1600 return $options['columns'][$type];
1601
1602 return false;
1603 }
1604
1605 /**
1606 * Post Type Menu
1607 *
1608 * @since 1.0
1609 */
1610 private function get_menu()
1611 {
1612 // set
1613 $menu = '';
1614 $count = 1;
1615
1616 // referer
1617 $referer = ! empty($_REQUEST['cpac_type']) ? $_REQUEST['cpac_type'] : '';
1618
1619 // loop
1620 foreach ( $this->get_types() as $type ) {
1621 $label = $this->get_singular_name($type);
1622 $clean_label = $this->sanitize_string($type);
1623
1624 // divider
1625 $divider = $count++ == 1 ? '' : ' | ';
1626
1627 // current
1628 $current = '';
1629 if ( $this->is_menu_type_current($type) )
1630 $current = ' class="current"';
1631
1632 // menu list
1633 $menu .= "
1634 <li>{$divider}<a{$current} href='#cpac-box-{$clean_label}'>{$label}</a></li>
1635 ";
1636 }
1637
1638 // settings url
1639 $class_current_settings = $this->is_menu_type_current('plugin_settings') ? ' current': '';
1640
1641 // options button
1642 $options_btn = "<a href='#cpac-box-plugin_settings' class='cpac-settings-link{$class_current_settings}'>".__('Addons')."</a>";
1643 //$options_btn = '';
1644
1645 return "
1646 <div class='cpac-menu'>
1647 <ul class='subsubsub'>
1648 {$menu}
1649 </ul>
1650 {$options_btn}
1651 </div>
1652 ";
1653 }
1654
1655 /**
1656 * Checks if menu type is currently viewed
1657 *
1658 * @since 1.0
1659 */
1660 private function is_menu_type_current( $type )
1661 {
1662 // referer
1663 $referer = ! empty($_REQUEST['cpac_type']) ? $_REQUEST['cpac_type'] : '';
1664
1665 // get label
1666 $clean_label = $this->sanitize_string($type);
1667
1668 // get first element from post-types
1669 $first = array_shift( array_values($this->post_types) );
1670
1671 // display the page that was being viewed before saving
1672 if ( $referer ) {
1673 if ( $referer == 'cpac-box-'.$clean_label ) {
1674 return true;
1675 }
1676
1677 // settings page has not yet been saved
1678 } elseif ( $first == $type ) {
1679 return true;
1680 }
1681
1682 return false;
1683 }
1684
1685 /**
1686 * Get singular name of post type
1687 *
1688 * @since 1.0
1689 */
1690 private function get_singular_name( $type )
1691 {
1692 // Links
1693 if ( $type == 'wp-links' )
1694 $label = 'Links';
1695
1696 // Comments
1697 elseif ( $type == 'wp-comments' )
1698 $label = 'Comments';
1699
1700 // Users
1701 elseif ( $type == 'wp-users' )
1702 $label = 'Users';
1703
1704 // Media
1705 elseif ( $type == 'wp-media' )
1706 $label = 'Media Library';
1707
1708 // Posts
1709 else {
1710 $posttype_obj = get_post_type_object($type);
1711 $label = $posttype_obj->labels->singular_name;
1712 }
1713
1714 return $label;
1715 }
1716
1717 /**
1718 * Get plural name of post type
1719 *
1720 * @since 1.3.1
1721 */
1722 private function get_plural_name( $type )
1723 {
1724 $posttype_obj = get_post_type_object($type);
1725 if ( $posttype_obj )
1726 return $posttype_obj->labels->name;
1727
1728 return false;
1729 }
1730
1731 /**
1732 * Get screen link to overview screen
1733 *
1734 * @since 1.3.1
1735 */
1736 private function get_type_screen_link( $type )
1737 {
1738 // Links
1739 if ( $type == 'wp-comments' )
1740 $link = get_admin_url() . 'edit-comments.php';
1741
1742 // Links
1743 if ( $type == 'wp-links' )
1744 $link = get_admin_url() . 'link-manager.php';
1745
1746 // Users
1747 if ( $type == 'wp-users' )
1748 $link = get_admin_url() . 'users.php';
1749
1750 // Media
1751 elseif ( $type == 'wp-media' )
1752 $link = get_admin_url() . 'upload.php';
1753
1754 // Posts
1755 else
1756 $link = get_admin_url() . "edit.php?post_type={$type}";
1757
1758 return $link;
1759 }
1760
1761 /**
1762 * Sanitize label
1763 *
1764 * Uses intern wordpress function esc_url so it matches the label sorting url.
1765 *
1766 * @since 1.0
1767 */
1768 protected function sanitize_string($string)
1769 {
1770 $string = esc_url($string);
1771 $string = str_replace('http://','', $string);
1772 $string = str_replace('https://','', $string);
1773
1774 return $string;
1775 }
1776
1777 /**
1778 * Checks if column-meta key exists
1779 *
1780 * @since 1.0
1781 */
1782 public static function is_column_meta( $id = '' )
1783 {
1784 if ( strpos($id, 'column-meta-') !== false )
1785 return true;
1786
1787 return false;
1788 }
1789
1790 /**
1791 * Get column value of post attachments
1792 *
1793 * @since 1.2.1
1794 */
1795 public static function get_attachment_ids( $post_id )
1796 {
1797 return get_posts(array(
1798 'post_type' => 'attachment',
1799 'numberposts' => -1,
1800 'post_status' => null,
1801 'post_parent' => $post_id,
1802 'fields' => 'ids'
1803 ));
1804 }
1805
1806 /**
1807 * Strip tags and trim
1808 *
1809 * @since 1.3
1810 */
1811 public static function strip_trim($string)
1812 {
1813 return trim(strip_tags($string));
1814 }
1815
1816 /**
1817 * Admin body class
1818 *
1819 * @since 1.4
1820 */
1821 function admin_class()
1822 {
1823 global $current_screen;
1824
1825 // we dont need the 'edit-' part
1826 $screen = str_replace('edit-', '', $current_screen->id);
1827
1828 // media library exception
1829 if ( $current_screen->base == 'upload' && $current_screen->id == 'upload' ) {
1830 $screen = 'media';
1831 }
1832
1833 // link exception
1834 if ( $current_screen->base == 'link-manager' && $current_screen->id == 'link-manager' ) {
1835 $screen = 'links';
1836 }
1837
1838 // loop the available types
1839 foreach ( $this->get_types() as $type => $label ) {
1840
1841 // match against screen or wp-screen
1842 if ( $type == $screen || $type == "wp-{$screen}" )
1843 return "cp-{$type}";
1844 }
1845 return false;
1846 }
1847
1848 /**
1849 * Admin CSS for Column width
1850 *
1851 * @since 1.4
1852 */
1853 function admin_css()
1854 {
1855 $css = '';
1856
1857 // loop throug the available types...
1858 foreach ( $this->get_types() as $type ) {
1859 $cols = self::get_stored_columns($type);
1860 if ( $cols ) {
1861
1862 // loop through each available column...
1863 foreach ( $cols as $col_name => $col ) {
1864
1865 // and check for stored width and add it to the css
1866 if (!empty($col['width']) && is_numeric($col['width']) && $col['width'] > 0 ) {
1867 $css .= ".cp-{$type} .wrap table th.column-{$col_name} { width: {$col['width']}% !important; }";
1868 }
1869 }
1870 }
1871 }
1872
1873 echo "<style type='text/css'>{$css}</style>";
1874 }
1875
1876 /**
1877 * Unlocks
1878 *
1879 * @since 1.3
1880 */
1881 protected function is_unlocked($type)
1882 {
1883 return preg_match('/^[a-f0-9]{40}$/i', $this->get_license_key($type));
1884 }
1885
1886 /**
1887 * Check license key with API
1888 *
1889 * @since 1.3.3
1890 */
1891 private function check_remote_key($type, $key)
1892 {
1893 if ( empty($type) || empty($key) )
1894 return false;
1895
1896 // check key with remote API
1897 $response = wp_remote_post( $this->api_url, array(
1898 'body' => array(
1899 'api' => 'addon',
1900 'key' => $key,
1901 'type' => $type
1902 )
1903 ));
1904
1905 // license will be valid in case of WP error or succes
1906 if ( is_wp_error($response) || ( isset($response['body']) && json_decode($response['body']) == 'valid' ) )
1907 return true;
1908
1909 return false;
1910 }
1911
1912 /**
1913 * Set masked license key
1914 *
1915 * @since 1.3.1
1916 */
1917 private function get_masked_license_key($type)
1918 {
1919 return '**************************'.substr( $this->get_license_key($type), -4 );
1920 }
1921
1922 /**
1923 * Ajax activation
1924 *
1925 * @since 1.3.1
1926 */
1927 public function ajax_activation()
1928 {
1929 // keys
1930 $key = $_POST['key'];
1931 $type = $_POST['type'];
1932
1933 // update key
1934 if ( $key == 'remove' ) {
1935 $this->remove_license_key($type);
1936 }
1937
1938 // set license key
1939 elseif ( $this->check_remote_key($type, $key) ) {
1940
1941 // set key
1942 $this->set_license_key($type, $key);
1943
1944 // returned masked key
1945 echo json_encode( $this->get_masked_license_key($type) );
1946 }
1947
1948 exit;
1949 }
1950
1951 /**
1952 * Get license key
1953 *
1954 * @since 1.3
1955 */
1956 private function get_license_key($type)
1957 {
1958 return get_option("cpac_{$type}_ac");
1959 }
1960
1961 /**
1962 * Set license key
1963 *
1964 * @since 1.3
1965 */
1966 private function set_license_key($type, $key)
1967 {
1968 update_option( "cpac_{$type}_ac", $key);
1969 }
1970
1971 /**
1972 * Remove license key
1973 *
1974 * @since 1.3.1
1975 */
1976 private function remove_license_key($type)
1977 {
1978 delete_option( "cpac_{$type}_ac" );
1979 delete_transient("cpac_{$type}_trnsnt");
1980 }
1981
1982 /**
1983 * Add help tabs
1984 *
1985 * @since 1.3
1986 */
1987 public function help_tabs($page)
1988 {
1989 $screen = get_current_screen();
1990
1991 if ( $screen->id != $this->admin_page || ! method_exists($screen,'add_help_tab') )
1992 return;
1993
1994 $admin_url = get_admin_url();
1995
1996 // add help content
1997 $tabs = array(
1998 array(
1999 'title' => 'Overview',
2000 'content' => "
2001 <h5>Codepress Admin Columns</h5>
2002 <p>
2003 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.
2004 </p>
2005
2006 "
2007 ),
2008 array(
2009 'title' => 'Basics',
2010 'content' => "
2011 <h5>Show / Hide</h5>
2012 <p>
2013 You can switch columns on or off by cliking on the checkbox. This will show or hide each column heading.
2014 </p>
2015 <h5>Change order</h5>
2016 <p>
2017 By dragging the columns you can change the order which they will appear in.
2018 </p>
2019 <h5>Change label</h5>
2020 <p>
2021 By clicking on the triangle you will see the column options. Here you can change each label of the columns heading.
2022 </p>
2023 <h5>Change coluimn width</h5>
2024 <p>
2025 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.
2026 </p>
2027 "
2028 ),
2029 array(
2030 'title' => 'Custom Field',
2031 'content' => "
2032 <h5>'Custom Field' column</h5>
2033 <p>
2034 The custom field colum uses the custom fields from posts and users. There are 8 types which you can set.
2035 </p>
2036 <ul>
2037 <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>
2038 <li><strong>Image</strong><br/>Value: should only contain an image URL.</li>
2039 <li><strong>Media Library Icon</strong><br/>Value: should only contain Attachment IDs ( seperated by ',' ).</li>
2040 <li><strong>Excerpt</strong><br/>Value: This will show the first 20 words of the Post content.</li>
2041 <li><strong>Multiple Values</strong><br/>Value: should be an array. This will flatten any ( multi dimensional ) array.</li>
2042 <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>
2043 <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>
2044 <li><strong>Post Titles</strong><br/>Value: can be one or more Post ID's (seperated by ',').</li>
2045 </ul>
2046 "
2047 )
2048 );
2049
2050 foreach ( $tabs as $k => $tab ) {
2051 $screen->add_help_tab(array(
2052 'id' => 'cpac-tab-'.$k, // unique id
2053 'title' => $tab['title'], // label
2054 'content' => $tab['content'], // body
2055 ));
2056 }
2057 }
2058
2059 /**
2060 * Activation settings
2061 *
2062 * @since 1.3.1
2063 */
2064 private function activation_settings()
2065 {
2066 $class_current_settings = $this->is_menu_type_current('plugin_settings') ? ' current' : ' hidden'; '';
2067
2068 /** Sortable */
2069 $masked_key = '';
2070 $class_sortorder_activate = '';
2071 $class_sortorder_deactivate = ' hidden';
2072
2073 // is unlocked
2074 if ( $this->is_unlocked('sortable') ) {
2075 $masked_key = $this->get_masked_license_key('sortable');
2076 $class_sortorder_activate = ' hidden';
2077 $class_sortorder_deactivate = '';
2078 }
2079
2080 // find out more
2081 $find_out_more = "<a href='{$this->codepress_url}/sortorder-addon/' class='button-primary alignright' target='_blank'>".__('find out more', CPAC_TEXTDOMAIN)." &raquo</a>";
2082
2083 // info box
2084 $sortable_tooltip = "
2085 <p>".__('This will make all of the new columns support sorting', CPAC_TEXTDOMAIN).".</p>
2086 <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>', CPAC_TEXTDOMAIN)."</p>
2087 <p>".__('Perfect for sorting your articles, media files, comments, links and users', CPAC_TEXTDOMAIN).".</p>
2088 <img src='" . CPAC_URL.'/assets/images/addon_sortable_1.png' . "' alt='' />
2089 {$find_out_more}
2090 ";
2091
2092 // markup
2093 $sortable = "
2094 <tr id='cpac-activation-sortable' class='last'>
2095 <td class='activation_type'>
2096 <span>" . __('Sortorder', CPAC_TEXTDOMAIN) . "</span>
2097 <div class='cpac-tooltip hidden'>
2098 <div class='qtip_title'>" . __('Sortorder', CPAC_TEXTDOMAIN) . "</div>
2099 <div class='qtip_content'>
2100 <p>" . __($sortable_tooltip, CPAC_TEXTDOMAIN) . "</p>
2101 </div>
2102 </div>
2103 </td>
2104 <td class='activation_status'>
2105 <div class='activate{$class_sortorder_activate}'>
2106 " . __('Inactive', CPAC_TEXTDOMAIN) . "
2107 </div>
2108 <div class='deactivate{$class_sortorder_deactivate}'>
2109 " . __('Active', CPAC_TEXTDOMAIN) . "
2110 </div>
2111 </td>
2112 <td class='activation_code'>
2113 <div class='activate{$class_sortorder_activate}'>
2114 <input type='text' value='" . __('Fill in your activation code', CPAC_TEXTDOMAIN) . "' name='cpac-sortable-key'>
2115 <a href='javascript:;' class='button'>" . __('Activate', CPAC_TEXTDOMAIN) . "<span></span></a>
2116 </div>
2117 <div class='deactivate{$class_sortorder_deactivate}'>
2118 <span class='masked_key'>{$masked_key}</span>
2119 <a href='javascript:;' class='button'>" . __('Deactivate', CPAC_TEXTDOMAIN) . "<span></span></a>
2120 </div>
2121 <div class='activation-error-msg'></div>
2122 </td>
2123 <td class='activation_more'>{$find_out_more}</td>
2124 </tr><!-- #cpac-activation-sortable -->
2125 ";
2126
2127 // settings
2128 $row = "
2129 <tr id='cpac-box-plugin_settings' valign='top' class='cpac-box-row {$class_current_settings}'>
2130 <td colspan='2'>
2131 <table class='nopadding'>
2132 <tr class='last'>
2133 <td>
2134 <h2>".__('Activate Add-ons', CPAC_TEXTDOMAIN)."</h2>
2135 <p>".__('Add-ons can be unlocked by purchasing a license key. Each key can be used on multiple sites', CPAC_TEXTDOMAIN)." <a target='_blank' href='{$this->codepress_url}/sortorder-addon/'>Visit the Plugin Store</a>.</p>
2136 <table class='widefat addons'>
2137 <thead>
2138 <tr>
2139 <th class='activation_type'>".__('Addon', CPAC_TEXTDOMAIN)."</th>
2140 <th class='activation_status'>".__('Status', CPAC_TEXTDOMAIN)."</th>
2141 <th class='activation_code'>".__('Activation Code', CPAC_TEXTDOMAIN)."</th>
2142 <th class='activation_more'></th>
2143 </tr>
2144 </thead>
2145 <tbody>
2146 {$sortable}
2147 </tbody>
2148 </table>
2149 <div class='addon-translation-string hidden'>
2150 <span class='tstring-fill-in'>" . __('Enter your activation code', CPAC_TEXTDOMAIN) . "</span>
2151 <span class='tstring-unrecognised'>" . __('Activation code unrecognised', CPAC_TEXTDOMAIN) . "</span>
2152 </div>
2153 </td>
2154 </tr>
2155 <!--
2156 <tr class='last'>
2157 <td colspan='2'>
2158 <h2>Options</h2>
2159 <ul class='cpac-options'>
2160 <li>
2161 <div class='cpac-option-label'>Thumbnail size</div>
2162 <div class='cpac-option-inputs'>
2163 <input type='text' id='thumbnail_size_w' class='small-text' name='cpac_options[settings][thumb_width]' value='80'/>
2164 <label for='thumbnail_size_w'>Width</label>
2165 <br/>
2166 <input type='text' id='thumbnail_size_h' class='small-text' name='cpac_options[settings][thumb_height]' value='80'/>
2167 <label for='thumbnail_size_h'>Height</label>
2168 </div>
2169 </li>
2170 <li>
2171 <div class='cpac-option-label'>Excerpt length</div>
2172 <div class='cpac-option-inputs'>
2173
2174 <input type='text' id='excerpt_length' class='small-text' name='cpac_options[settings][excerpt_length]' value='15'/>
2175 <label for='excerpt_length'>Number of words</label>
2176 </div>
2177 </li>
2178 </ul>
2179 </td>
2180 </tr>
2181 -->
2182 </table>
2183 </td>
2184 </tr><!-- #cpac-box-plugin_settings -->
2185 ";
2186
2187 return $row;
2188 }
2189
2190 /**
2191 * Settings Page Template.
2192 *
2193 * This function in conjunction with others usei the WordPress
2194 * Settings API to create a settings page where users can adjust
2195 * the behaviour of this plugin.
2196 *
2197 * @since 1.0
2198 */
2199 public function plugin_settings_page()
2200 {
2201
2202 // loop through post types
2203 $rows = '';
2204 foreach ( $this->get_types() as $type ) {
2205
2206 // post type label
2207 $label = $this->get_singular_name($type);
2208
2209 // screen link
2210 $screen_link = '';
2211 //$screen_link = $this->get_type_screen_link($type);
2212 //$screen_link = "<a href='{$screen_link}' class='go-to-screen'>" . sprintf( __('go to %s screen'), strtolower($label) ) . "</a>";
2213
2214 // id
2215 $id = $this->sanitize_string($type);
2216
2217 // build draggable boxes
2218 $boxes = $this->get_column_boxes($type);
2219
2220 // class
2221 $class = $this->is_menu_type_current($type) ? ' current' : ' hidden';
2222
2223 $rows .= "
2224 <tr id='cpac-box-{$id}' valign='top' class='cpac-box-row{$class}'>
2225 <th class='cpac_post_type' scope='row'>
2226 {$label}{$screen_link}
2227 </th>
2228 <td>
2229 <h3 class='cpac_post_type hidden'>{$label}</h3>
2230 {$boxes}
2231 </td>
2232 </tr>
2233 ";
2234 }
2235
2236 // Activation
2237 $activation_settings = $this->activation_settings();
2238
2239 // Post Type Menu
2240 $menu = $this->get_menu();
2241
2242 // Help screen message
2243 $help_text = '';
2244 if ( version_compare( get_bloginfo('version'), '3.2', '>' ) )
2245 $help_text = '<p>'.__('You will find a short overview at the <strong>Help</strong> section in the top-right screen.', CPAC_TEXTDOMAIN).'</p>';
2246
2247 // find out more
2248 $find_out_more = "<a href='{$this->codepress_url}/sortorder-addon/' class='alignright green' target='_blank'>".__('find out more', CPAC_TEXTDOMAIN)." &raquo</a>";
2249
2250 ?>
2251 <div id="cpac" class="wrap">
2252 <?php screen_icon(CPAC_SLUG) ?>
2253 <h2><?php _e('Codepress Admin Columns', CPAC_TEXTDOMAIN); ?></h2>
2254 <?php echo $menu ?>
2255
2256 <div class="postbox-container cpac-col-right">
2257 <div class="metabox-holder">
2258 <div class="meta-box-sortables">
2259
2260 <div id="addons-cpac-settings" class="postbox">
2261 <div title="Click to toggle" class="handlediv"><br></div>
2262 <h3 class="hndle">
2263 <span><?php _e('Addons', CPAC_TEXTDOMAIN) ?></span>
2264 </h3>
2265 <div class="inside">
2266 <p><?php _e('By default WordPress let\'s you only sort by title, date, comments and author.', CPAC_TEXTDOMAIN) ?></p>
2267 <p><?php _e('Make <strong>all columns</strong> of <strong>all types</strong> support sorting &#8212; with the sorting addon.', CPAC_TEXTDOMAIN) ?></p>
2268 <?php echo $find_out_more ?>
2269 </div>
2270 </div><!-- addons-cpac-settings -->
2271
2272 <div id="likethisplugin-cpac-settings" class="postbox">
2273 <div title="Click to toggle" class="handlediv"><br></div>
2274 <h3 class="hndle">
2275 <span><?php _e('Like this plugin?', CPAC_TEXTDOMAIN) ?></span>
2276 </h3>
2277 <div class="inside">
2278 <p><?php _e('Why not do any or all of the following', CPAC_TEXTDOMAIN) ?>:</p>
2279 <ul>
2280 <li><a href="<?php echo $this->codepress_url ?>/"><?php _e('Link to it so other folks can find out about it.', CPAC_TEXTDOMAIN) ?></a></li>
2281 <li><a href="<?php echo $this->wordpress_url ?>"><?php _e('Give it a 5 star rating on WordPress.org.', CPAC_TEXTDOMAIN) ?></a></li>
2282 <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.', CPAC_TEXTDOMAIN) ?></a></li>
2283 </ul>
2284 </div>
2285 </div><!-- likethisplugin-cpac-settings -->
2286
2287 <div id="side-cpac-settings" class="postbox">
2288 <div title="Click to toggle" class="handlediv"><br></div>
2289 <h3 class="hndle">
2290 <span><?php _e('Need support?', CPAC_TEXTDOMAIN) ?></span>
2291 </h3>
2292 <div class="inside">
2293 <?php echo $help_text ?>
2294 <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.', CPAC_TEXTDOMAIN), 'http://wordpress.org/tags/codepress-admin-columns', '<a href="mailto:info@codepress.nl">info@codepress.nl</a>' );?></p>
2295 <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>.", CPAC_TEXTDOMAIN), "{$this->codepress_url}/feedback");?></p>
2296 </div>
2297 </div><!-- side-cpac-settings -->
2298
2299 </div>
2300 </div>
2301 </div><!-- .postbox-container -->
2302
2303 <div class="postbox-container cpac-col-left">
2304 <div class="metabox-holder">
2305 <div class="meta-box-sortables">
2306
2307 <div id="general-cpac-settings" class="postbox">
2308 <div title="Click to toggle" class="handlediv"><br></div>
2309 <h3 class="hndle">
2310 <span><?php _e('Admin Columns', CPAC_TEXTDOMAIN ); ?></span>
2311 </h3>
2312 <div class="inside">
2313 <form method="post" action="options.php">
2314
2315 <?php settings_fields( 'cpac-settings-group' ); ?>
2316
2317 <table class="form-table">
2318 <!-- columns -->
2319 <?php echo $rows; ?>
2320
2321 <!-- activation -->
2322 <?php echo $activation_settings; ?>
2323
2324 <tr class="bottom" valign="top">
2325 <th scope="row"></th>
2326 <td>
2327 <p class="submit">
2328 <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
2329 </p>
2330 </td>
2331 </tr>
2332 </table>
2333 </form>
2334 </div>
2335 </div><!-- general-settings -->
2336
2337 <div id="restore-cpac-settings" class="postbox">
2338 <div title="Click to toggle" class="handlediv"><br></div>
2339 <h3 class="hndle">
2340 <span><?php _e('Restore defaults', CPAC_TEXTDOMAIN) ?></span>
2341 </h3>
2342 <div class="inside">
2343 <form method="post" action="">
2344 <input type="submit" class="button" name="cpac-restore-defaults" value="<?php _e('Restore default settings', CPAC_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", CPAC_TEXTDOMAIN); ?>');" />
2345 </form>
2346 <p class="description"><?php _e('This will delete all column settings and restore the default settings.', CPAC_TEXTDOMAIN); ?></p>
2347 </div>
2348 </div><!-- restore-cpac-settings -->
2349
2350 </div>
2351 </div>
2352 </div><!-- .postbox-container -->
2353 </div>
2354 <?php
2355 }
2356 }
2357
2358 /**
2359 * Init Class Codepress_Admin_Columns
2360 *
2361 * @since 1.0
2362 */
2363 new Codepress_Admin_Columns();
2364
2365
2366 /**
2367 * Init Class Codepress_Sortable_Columns
2368 *
2369 * @since 1.3
2370 */
2371 new Codepress_Sortable_Columns();
2372
2373 ?>