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