PluginProbe
Admin Columns / 1.2.1
Admin Columns v1.2.1
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,020 lines 50.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.2.1
5 Description: This plugin makes it easy to Manage Custom Columns for your Posts, Pages and Custom Post Type Screens.
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.2.1' );
30
31 /**
32 * Init Class
33 *
34 * @since 1.0
35 */
36 new Codepress_Admin_Columns();
37
38 /**
39 * Advanced Admin Columns Class
40 *
41 * @since 1.0
42 *
43 */
44 class Codepress_Admin_Columns
45 {
46 private $post_types,
47 $slug,
48 $textdomain,
49 $excerpt_length;
50
51 /**
52 * Construct
53 *
54 * @since 1.0
55 */
56 function __construct()
57 {
58 add_action( 'wp_loaded', array( &$this, 'init') );
59 }
60
61 /**
62 * Initialize plugin.
63 *
64 * Loading sequence is determined and intialized.
65 *
66 * @since 1.0
67 */
68 function init()
69 {
70 // vars
71 $this->post_types = $this->get_post_types();
72
73 // set
74 $this->slug = 'codepress-admin-columns';
75 $this->textdomain = 'codepress-admin-columns';
76 $this->excerpt_length = 100;
77
78 // translations
79 load_plugin_textdomain( $this->textdomain, false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
80
81 // actions
82 add_action( 'admin_menu', array( &$this, 'settings_menu') );
83 add_action( 'admin_init', array( &$this, 'register_settings') );
84 add_action( 'admin_init', array( &$this, 'register_columns' ) );
85 add_action( 'manage_pages_custom_column', array( &$this, 'manage_posts_column_value'), 10, 2 );
86 add_action( 'manage_posts_custom_column', array( &$this, 'manage_posts_column_value'), 10, 2 );
87 add_action( 'manage_users_custom_column', array( &$this, 'manage_users_column_value'), 10, 3 );
88 add_action( 'admin_print_styles' , array( &$this, 'column_styles') );
89
90 // handle requests gets a low priority so it will trigger when all other plugins have loaded their columns
91 add_action( 'admin_init', array( &$this, 'handle_requests' ), 1000 );
92
93 // filters
94 add_filter( 'request', array( &$this, 'handle_requests_orderby_column') );
95 add_filter( 'plugin_action_links', array( &$this, 'add_settings_link'), 1, 2);
96 }
97
98 /**
99 * Admin Menu.
100 *
101 * Create the admin menu link for the settings page.
102 *
103 * @since 1.0
104 */
105 public function settings_menu()
106 {
107 $page = add_options_page(
108 // Page title
109 esc_html__( 'Admin Columns Settings', $this->textdomain ),
110 // Menu Title
111 esc_html__( 'Admin Columns', $this->textdomain ),
112 // Capability
113 'manage_options',
114 // Menu slug
115 $this->slug,
116 // Callback
117 array( &$this, 'plugin_settings_page')
118 );
119
120 // settings page specific styles and scripts
121 add_action( "admin_print_styles-$page", array( &$this, 'admin_styles') );
122 add_action( "admin_print_scripts-$page", array( &$this, 'admin_scripts') );
123 }
124
125 /**
126 * Add Settings link to plugin page
127 *
128 * @since 1.0
129 */
130 function add_settings_link( $links, $file )
131 {
132 if ( $file != plugin_basename( __FILE__ ))
133 return $links;
134
135 array_unshift($links, '<a href="' . admin_url("admin.php") . '?page=' . $this->slug . '">' . __( 'Settings' ) . '</a>');
136 return $links;
137 }
138
139 /**
140 * Register Columns
141 *
142 * @since 1.0
143 */
144 public function register_columns()
145 {
146 /** Posts */
147 foreach ( $this->post_types as $post_type ) {
148
149 // register column per post type
150 add_filter("manage_edit-{$post_type}_columns", array(&$this, 'callback_add_posts_column'));
151
152 // register column as sortable
153 add_filter( "manage_edit-{$post_type}_sortable_columns", array(&$this, 'callback_add_sortable_posts_column'));
154 }
155
156 /** Users */
157 add_filter( "manage_users_columns", array(&$this, 'callback_add_users_column'));
158 add_filter( "manage_users_sortable_columns", array(&$this, 'callback_add_sortable_users_column'));
159 }
160
161 /**
162 * Callback add Posts Column
163 *
164 * @since 1.0
165 */
166 public function callback_add_posts_column($columns)
167 {
168 global $post_type;
169
170 return $this->add_managed_columns($post_type, $columns);
171 }
172
173 /**
174 * Callback add Users column
175 *
176 * @since 1.1
177 */
178 public function callback_add_users_column($columns)
179 {
180 return $this->add_managed_columns('wp-users', $columns);
181 }
182
183 /**
184 * Add managed columns by Type
185 *
186 * @since 1.1
187 */
188 private function add_managed_columns( $type = 'post', $columns )
189 {
190 // only get stored columns.. the rest we don't need
191 $db_columns = $this->get_stored_columns($type);
192
193 if ( !$db_columns )
194 return $columns;
195
196 // filter already loaded columns by plugins
197 $set_columns = $this->filter_preset_columns($columns, $type);
198
199 // loop through columns
200 foreach ( $db_columns as $id => $values ) {
201
202 // is active
203 if ( isset($values['state']) && $values['state'] == 'on' ){
204
205 // register format
206 $set_columns[$id] = $values['label'];
207 }
208 }
209
210 return $set_columns;
211 }
212
213 /**
214 * Callback add Posts sortable column
215 *
216 * @since 1.0
217 */
218 public function callback_add_sortable_posts_column($columns)
219 {
220 global $post_type;
221
222 return $this->add_managed_sortable_columns($post_type, $columns);
223 }
224
225 /**
226 * Callback add Users sortable column
227 *
228 * @since 1.1
229 */
230 public function callback_add_sortable_users_column($columns)
231 {
232 return $this->add_managed_sortable_columns('wp-users', $columns);
233 }
234
235 /**
236 * Add managed sortable columns by Type
237 *
238 * @since 1.1
239 */
240 private function add_managed_sortable_columns( $type = 'post', $columns )
241 {
242 $display_columns = $this->get_merged_columns($type);
243
244 if ( ! $display_columns )
245 return $columns;
246
247 foreach ( $display_columns as $id => $vars ) {
248 if ( isset($vars['options']['sortorder']) && $vars['options']['sortorder'] == 'on' ){
249
250 // register format
251 $columns[$id] = $this->sanitize_string($vars['label']);
252 }
253 }
254 return $columns;
255 }
256
257 /**
258 * Get a list of Column options per post type
259 *
260 * @since 1.0
261 */
262 private function get_column_boxes($type)
263 {
264 // merge all columns
265 $display_columns = $this->get_merged_columns($type);
266
267 // define
268 $list = '';
269
270 // loop throught the active columns
271 if ( $display_columns ) {
272 foreach ( $display_columns as $id => $values ) {
273
274 // add items to the list
275 $list .= $this->get_box($type, $id, $values);
276
277 }
278 }
279
280 // custom field button
281 $button_add_column = '';
282 if ( $this->get_meta_by_type($type) )
283 $button_add_column = "<a href='javacript:;' class='cpac-add-customfield-column button'>+ " . __('Add Custom Field Column') . "</a>";
284
285 return "
286 <div class='cpac-box'>
287 <ul class='cpac-option-list'>
288 {$list}
289 </ul>
290 {$button_add_column}
291 <div class='cpac-reorder-msg'>" . __('drag and drop to reorder', $this->textdomain) . "</div>
292 </div>
293 ";
294 }
295
296 /**
297 * Get merged columns
298 *
299 * @since 1.0
300 */
301 private function get_merged_columns( $type )
302 {
303 //get saved database columns
304 $db_columns = $this->get_stored_columns($type);
305
306 /** Users */
307 if ( $type == 'wp-users' ) {
308 $wp_default_columns = $this->get_wp_default_users_columns();
309 $wp_custom_columns = $this->get_custom_users_columns();
310 }
311
312 /** Posts */
313 else {
314 $wp_default_columns = $this->get_wp_default_posts_columns($type);
315 $wp_custom_columns = $this->get_custom_posts_columns($type);
316 }
317
318 // merge columns
319 $default_columns = wp_parse_args($wp_custom_columns, $wp_default_columns);
320
321 // loop throught the active columns
322 if ( $db_columns ) {
323
324 // let's remove any unavailable columns.. such as disabled plugins
325 $db_columns = $this->remove_unavailable_columns($db_columns, $default_columns);
326
327 foreach ( $db_columns as $id => $values ) {
328
329 // get column meta options from custom columns
330 if ( $this->is_column_meta($id) )
331 $db_columns[$id]['options'] = $wp_custom_columns['column-meta-1']['options'];
332
333 // add static options
334 elseif ( isset($default_columns[$id]['options']) )
335 $db_columns[$id]['options'] = $default_columns[$id]['options'];
336
337 unset($default_columns[$id]);
338 }
339 }
340
341 // merge all
342 $display_columns = wp_parse_args($db_columns, $default_columns);
343
344 return $display_columns;
345 }
346
347 /**
348 * Remove deactivated (plugin) columns
349 *
350 * This will remove any columns that have been stored, but are no longer available. This happends
351 * when plugins are deactivated or when they are removed from the theme functions.
352 *
353 * @since 1.2
354 */
355 private function remove_unavailable_columns( array $db_columns, array $default_columns)
356 {
357 // check or differences
358 $diff = array_diff( array_keys($db_columns), array_keys($default_columns) );
359 if ( ! empty($diff) && is_array($diff) ) {
360 foreach ( $diff as $column_name ){
361 // make an exception for column-meta-xxx
362 if ( ! $this->is_column_meta($column_name) ) {
363 unset($db_columns[$column_name]);
364 }
365 }
366 }
367
368 return $db_columns;
369 }
370
371 /**
372 * Get checkbox
373 *
374 * @since 1.0
375 */
376 private function get_box($type, $id, $values)
377 {
378 $classes = array();
379
380 // set state
381 $state = isset($values['state']) ? $values['state'] : '';
382
383 // class
384 $classes[] = "cpac-box-{$id}";
385 if ( $state )
386 $classes[] = 'active';
387 if ( ! empty($values['options']['class']) )
388 $classes[] = $values['options']['class'];
389 $class = implode(' ', $classes);
390
391 // more box options
392 $more_options = $this->get_additional_box_options($type, $id, $values);
393 $action = "<a class='cpac-action' href='#open'>open</a>";
394
395 // type label
396 $type_label = isset($values['options']['type_label']) ? $values['options']['type_label'] : '';
397
398 // label
399 $label = isset($values['label']) ? str_replace("'", '"', $values['label']) : '';
400
401 // hide box options
402 if ( ! empty($values['options']['hide_options']) || strpos($label, '<img') !== false ) {
403 $action = $more_options = '';
404 }
405
406 $list = "
407 <li class='{$class}'>
408 <div class='cpac-sort-handle'></div>
409 <div class='cpac-type-options'>
410
411 <div class='cpac-checkbox'></div>
412 <input type='hidden' class='cpac-state' name='cpac_options[columns][{$type}][{$id}][state]' value='{$state}'/>
413 <label class='main-label'>{$values['label']}</label>
414 </div>
415 <div class='cpac-meta-title'>
416 {$action}
417 <span>{$type_label}</span>
418 </div>
419 <div class='cpac-type-inside'>
420 <label for='cpac_options[columns][{$type}][{$id}][label]'>Label: </label>
421 <input type='text' name='cpac_options[columns][{$type}][{$id}][label]' value='{$label}' class='text'/>
422 <br/>
423 {$more_options}
424 </div>
425 </li>
426 ";
427
428 return $list;
429 }
430
431 /**
432 * Get additional box option fields
433 *
434 * @since 1.0
435 */
436 private function get_additional_box_options($post_type, $id, $values)
437 {
438 $fields = '';
439
440 // Custom Fields
441 if ( $this->is_column_meta($id) )
442 $fields .= $this->get_box_options_customfields($post_type, $id, $values);
443
444 return $fields;
445 }
446
447 /**
448 * Box Options: Custom Fields
449 *
450 * @since 1.0
451 */
452 private function get_box_options_customfields($type, $id, $values)
453 {
454 // get post meta fields
455 $fields = $this->get_meta_by_type($type);
456
457 if ( empty($fields) )
458 return false;
459
460 // set meta field options
461 $current = ! empty($values['field']) ? $values['field'] : '' ;
462 $field_options = '';
463 foreach ($fields as $field) {
464 $field_options .= sprintf
465 (
466 '<option value="%s"%s>%s</option>',
467 $field,
468 $field == $current? ' selected="selected"':'',
469 $field
470 );
471 }
472
473 // set meta fieldtype options
474 $currenttype = ! empty($values['field_type']) ? $values['field_type'] : '' ;
475 $fieldtype_options = '';
476 $fieldtypes = array(
477 '' => __('Default'),
478 'image' => __('Image'),
479 'library_id' => __('Media Library Icon', $this->textdomain),
480 'excerpt' => __('Excerpt'),
481 'array' => __('Multiple Values', $this->textdomain),
482 'numeric' => __('Numeric', $this->textdomain),
483 );
484
485 // add filter
486 $fieldtypes = apply_filters('cpac-field-types', $fieldtypes );
487
488 // set select options
489 foreach ( $fieldtypes as $fkey => $fieldtype ) {
490 $fieldtype_options .= sprintf
491 (
492 '<option value="%s"%s>%s</option>',
493 $fkey,
494 $fkey == $currenttype? ' selected="selected"':'',
495 $fieldtype
496 );
497 }
498
499 // before and after string
500 $before = ! empty($values['before']) ? $values['before'] : '' ;
501 $after = ! empty($values['after']) ? $values['after'] : '' ;
502
503 if ( empty($field_options) )
504 return false;
505
506 // add remove button
507 $remove = '<p class="remove-description description">'.__('This field can not be removed', $this->textdomain).'</p>';
508 if ( $id != 'column-meta-1') {
509 $remove = "
510 <p>
511 <a href='javascript:;' class='cpac-delete-custom-field-box'>".__('Remove')."</a>
512 </p>
513 ";
514 }
515
516 $inside = "
517 <label for='cpac_options[columns][{$type}][{$id}][field]'>Custom Field: </label>
518 <select name='cpac_options[columns][{$type}][{$id}][field]'>{$field_options}</select>
519 <br/>
520 <label for='cpac_options[columns][{$type}][{$id}][field_type]'>Field Type: </label>
521 <select name='cpac_options[columns][{$type}][{$id}][field_type]'>{$fieldtype_options}</select>
522 <br/>
523 <label for='cpac_options[columns][{$type}][{$id}][before]'>Before: </label>
524 <input type='text' class='cpac-before' name='cpac_options[columns][{$type}][{$id}][before]' value='{$before}'/>
525 <br/>
526 <label for='cpac_options[columns][{$type}][{$id}][before]'>After: </label>
527 <input type='text' class='cpac-after' name='cpac_options[columns][{$type}][{$id}][after]' value='{$after}'/>
528 <br/>
529 {$remove}
530 ";
531
532 return $inside;
533 }
534
535 /**
536 * Get post meta fields by type; post(types) or users.
537 *
538 * @since 1.0
539 */
540 private function get_meta_by_type($type = 'post')
541 {
542 global $wpdb;
543
544 /** Users */
545 if ( $type == 'wp-users') {
546 $sql = 'SELECT DISTINCT meta_key FROM '.$wpdb->usermeta.' ORDER BY 1';
547 }
548
549 /** Posts */
550 else {
551 $sql = 'SELECT DISTINCT meta_key FROM '.$wpdb->postmeta.' pm JOIN '.$wpdb->posts.' p ON pm.post_id = p.ID WHERE p.post_type = "' . mysql_real_escape_string($type) . '" ORDER BY 1';
552 }
553
554 // run sql
555 $fields = $wpdb->get_results($sql, ARRAY_N);
556
557 // postmeta
558 if ( $fields ) {
559 $meta_fields = array();
560 foreach ($fields as $field) {
561 // filter out hidden meta fields
562 if (substr($field[0],0,1) != "_") {
563 $meta_fields[] = $field[0];
564 }
565 }
566 return $meta_fields;
567 }
568
569 return false;
570 }
571
572 /**
573 * Register admin scripts
574 *
575 * @since 1.0
576 */
577 public function admin_scripts()
578 {
579 wp_enqueue_script( 'cpac-admin', $this->plugin_url('/assets/js/admin-column.js'), array('jquery', 'dashboard', 'jquery-ui-sortable'), CPAC_VERSION );
580 }
581
582 /**
583 * Get column types
584 *
585 * @since 1.1
586 */
587 private function get_types()
588 {
589 $types = $this->post_types;
590 $types['wp-users'] = 'wp-users';
591
592 return $types;
593 }
594
595 /**
596 * Get post types
597 *
598 * @since 1.0
599 */
600 private function get_post_types()
601 {
602 $post_types = get_post_types(array(
603 '_builtin' => false
604 ));
605 $post_types['post'] = 'post';
606 $post_types['page'] = 'page';
607
608 return $post_types;
609 }
610
611 /**
612 * Register admin css
613 *
614 * @since 1.0
615 */
616 public function admin_styles()
617 {
618 wp_enqueue_style( 'cpac-admin', $this->plugin_url('/assets/css/admin-column.css'), array(), CPAC_VERSION, 'all' );
619 }
620
621 /**
622 * Register column css
623 *
624 * @since 1.0
625 */
626 public function column_styles()
627 {
628 wp_enqueue_style( 'cpac-columns', $this->plugin_url('/assets/css/column.css'), array(), CPAC_VERSION, 'all' );
629 }
630
631 /**
632 * Register plugin options
633 *
634 * @since 1.0
635 */
636 public function register_settings()
637 {
638 // If we have no options in the database, let's add them now.
639 if ( false === get_option('cpac_options') )
640 add_option( 'cpac_options', array(&$this, 'get_default_plugin_options') );
641
642 register_setting( 'cpac-settings-group', 'cpac_options', array(&$this, 'options_callback') );
643 }
644
645 /**
646 * Returns the default plugin options.
647 *
648 * @since 1.0
649 */
650 public function get_default_plugin_options()
651 {
652 $default_plugin_options = array(
653 'post' => '',
654 'page' => ''
655 );
656 return apply_filters( 'cpac_default_plugin_options', $default_plugin_options );
657 }
658
659 /**
660 * Optional callback.
661 *
662 * @since 1.0
663 */
664 public function options_callback($options)
665 {
666 return $options;
667 }
668
669 /**
670 * Handle requests.
671 *
672 * @since 1.0
673 */
674 public function handle_requests()
675 {
676 // settings updated
677 if ( ! empty($_REQUEST['settings-updated']) )
678 $this->store_wp_default_columns();
679
680 // restore defaults
681 if ( ! empty($_REQUEST['cpac-restore-defaults']) )
682 $this->restore_defaults();
683
684 }
685
686 /**
687 * Stores WP default columns
688 *
689 * This will store columns that are set by WordPress core or
690 * set by the theme for page, post(types) and user columns
691 *
692 * @since 1.2
693 */
694 private function store_wp_default_columns()
695 {
696 // stores the default columns that are set by WP or set in the theme.
697 $wp_default_columns = array();
698
699 // Posts
700 foreach ( $this->post_types as $post_type ) {
701 $wp_default_columns[$post_type] = $this->get_wp_default_posts_columns($post_type);
702 }
703
704 // Users
705 $wp_default_columns['wp-users'] = $this->get_wp_default_users_columns();
706
707 update_option( 'cpac_options_default', $wp_default_columns );
708 }
709
710 /**
711 * Restore defaults
712 *
713 * @since 1.0
714 */
715 private function restore_defaults()
716 {
717 delete_option( 'cpac_options' );
718 delete_option( 'cpac_options_default' );
719 }
720
721 /**
722 * Returns excerpt
723 *
724 * @since 1.0
725 */
726 private function get_post_excerpt($post_id)
727 {
728 global $post;
729
730 $save_post = $post;
731 $post = get_post($post_id);
732 $excerpt = get_the_excerpt();
733 $post = $save_post;
734
735 $output = $this->get_shortened_string($excerpt, $this->excerpt_length );
736
737 return $output;
738 }
739
740 /**
741 * Returns shortened string
742 *
743 * @since 1.0
744 */
745 private function get_shortened_string($string = '', $charlength = 100)
746 {
747 if (!$string)
748 return false;
749
750 $output = '';
751 if ( strlen($string) > $charlength ) {
752 $subex = substr($string,0,$charlength-5);
753 $exwords = explode(" ",$subex);
754 $excut = -(strlen($exwords[count($exwords)-1]));
755 $output .= $excut < 0 ? substr($subex,0,$excut) : $subex;
756 $output .= "[...]";
757 } else {
758 $output = $string;
759 }
760 return $output;
761 }
762
763 /**
764 * Manage custom column for Post Types.
765 *
766 * @since 1.0
767 */
768 public function manage_posts_column_value($column_name, $post_id)
769 {
770 $type = $column_name;
771
772 // Check for taxonomies, such as column-taxonomy-[taxname]
773 if ( strpos($type, 'column-taxonomy-') !== false )
774 $type = 'column-taxonomy';
775
776 // Check for custom fields, such as column-meta-[customfieldname]
777 if ( $this->is_column_meta($type) )
778 $type = 'column-post-meta';
779
780 // Hook
781 do_action('cpac-manage-posts-column', $type, $column_name, $post_id);
782
783 // Switch Types
784 $result = '';
785 switch ($type) :
786
787 // Post ID
788 case "column-postid" :
789 $result = $post_id;
790 break;
791
792 // Excerpt
793 case "column-excerpt" :
794 $result = $this->get_post_excerpt($post_id);
795 break;
796
797 // Featured Image
798 case "column-featured_image" :
799 $result = get_the_post_thumbnail($post_id, array(80,80));
800 break;
801
802 // Sticky Post
803 case "column-sticky" :
804 if ( is_sticky($post_id) ) {
805 $src = $this->plugin_url('assets/images/checkmark.png');
806 $result = "<img alt='sticky' src='{$src}' />";
807 }
808 break;
809
810 // Order
811 case "column-order" :
812 $result = get_post_field('menu_order', $post_id);
813 break;
814
815 // Post Formats
816 case "column-post_formats" :
817 $result = get_post_format($post_id);
818 break;
819
820 // Page template
821 case "column-page-template" :
822 // file name
823 $page_template = get_post_meta($post_id, '_wp_page_template', true);
824
825 // get template nice name
826 $result = array_search($page_template, get_page_templates());
827 break;
828
829 // Slug
830 case "column-page-slug" :
831 $result = get_post($post_id)->post_name;
832 break;
833
834 // Slug
835 case "column-word-count" :
836 $result = str_word_count( strip_tags( get_post($post_id)->post_content ) );
837 break;
838
839 // Taxonomy
840 case "column-taxonomy" :
841 $tax = str_replace('column-taxonomy-', '', $column_name);
842 $tags = get_the_terms($post_id, $tax);
843 $tarr = array();
844 if ( $tax == 'post_format' && empty($tags) ) {
845 $result = __('Standard');
846 }
847 elseif ( !empty($tags) ) {
848 foreach($tags as $tag) {
849 $tarr[] = $tag->name;
850 }
851 $result = implode(', ', $tarr);
852 }
853 break;
854
855 // Custom Field
856 case "column-post-meta" :
857 $result = $this->get_column_value_custom_field($post_id, $column_name, 'post');
858 break;
859
860 // Attachment
861 case "column-attachment" :
862 $result = $this->get_column_value_attachments($post_id);
863 break;
864
865 // Attachment count
866 case "column-attachment-count" :
867 $result = count($this->get_attachment_ids($post_id));
868 break;
869
870 default :
871 $result = get_post_meta( $post_id, $column_name, true );
872
873 endswitch;
874
875 if ( empty($result) )
876 echo '&nbsp;';
877
878 echo $result;
879 }
880
881 /**
882 * Manage custom column for Users.
883 *
884 * @since 1.1
885 */
886 public function manage_users_column_value( $value, $column_name, $user_id )
887 {
888 $type = $column_name;
889
890 $userdata = get_userdata( $user_id );
891
892 if ( ! $userdata )
893 return false;
894
895 // Check for user custom fields, such as column-meta-[customfieldname]
896 if ( $this->is_column_meta($type) )
897 $type = 'column-user-meta';
898
899 // Hook
900 do_action('cpac-manage-users-column', $type, $column_name, $user_id);
901
902 $result = '';
903 switch ($type) :
904
905 // user id
906 case "column-user_id" :
907 $result = $user_id;
908 break;
909
910 // first name
911 case "column-first_name" :
912 $result = $userdata->first_name;
913 break;
914
915 // last name
916 case "column-last_name" :
917 $result = $userdata->last_name;
918 break;
919
920 // user url
921 case "column-user_url" :
922 $result = $userdata->user_url;
923 break;
924
925 // user registration date
926 case "column-user_registered" :
927 $result = $userdata->user_registered;
928 break;
929
930 // user description
931 case "column-user_description" :
932 $result = $this->get_shortened_string( get_the_author_meta('user_description', $user_id), $this->excerpt_length );
933 break;
934
935 // user meta data ( custom field )
936 case "column-user-meta" :
937 $result = $this->get_column_value_custom_field($user_id, $column_name, 'user');
938 break;
939
940 default :
941 $result = get_user_meta( $user_id, $column_name, true );
942
943 endswitch;
944
945 if ( empty($result) )
946 $result = '&nbsp;';
947
948 return $result;
949 }
950
951 /**
952 * Get column value of post attachments
953 *
954 * @since 1.0
955 */
956 private function get_column_value_attachments( $post_id )
957 {
958 $result = '';
959 $attachment_ids = $this->get_attachment_ids($post_id);
960 if ( $attachment_ids ) {
961 foreach ( $attachment_ids as $attach_id ) {
962 $result .= wp_get_attachment_image( $attach_id, array(80,80), true );
963 }
964 }
965 return $result;
966 }
967
968 /**
969 * Get column value of post attachments
970 *
971 * @since 1.2.1
972 */
973 private function get_attachment_ids( $post_id )
974 {
975 return get_posts(array(
976 'post_type' => 'attachment',
977 'numberposts' => -1,
978 'post_status' => null,
979 'post_parent' => $post_id,
980 'fields' => 'ids'
981 ));
982 }
983
984 /**
985 * Get column value of Custom Field
986 *
987 * @since 1.0
988 */
989 private function get_column_value_custom_field($object_id, $column_name, $meta_type = 'post')
990 {
991 /** Users */
992 if ( $meta_type == 'user' ) {
993 $type = 'wp-users';
994 }
995
996 /** Posts */
997 else {
998 $type = get_post_type($object_id);
999 }
1000
1001 // get column
1002 $columns = $this->get_stored_columns($type);
1003
1004 // inputs
1005 $field = isset($columns[$column_name]['field']) ? $columns[$column_name]['field'] : '';
1006 $fieldtype = isset($columns[$column_name]['field_type']) ? $columns[$column_name]['field_type'] : '';
1007 $before = isset($columns[$column_name]['before']) ? $columns[$column_name]['before'] : '';
1008 $after = isset($columns[$column_name]['after']) ? $columns[$column_name]['after'] : '';
1009
1010 // Get meta field value
1011 $meta = get_metadata($meta_type, $object_id, $field, true);
1012
1013 // multiple meta values
1014 if ( ( $fieldtype == 'array' && is_array($meta) ) || is_array($meta) ) {
1015 $meta = get_metadata($meta_type, $object_id, $field, true);
1016 $meta = $this->recursive_implode(', ', $meta);
1017 }
1018
1019 // make sure there are no serialized arrays or empty meta data
1020 if ( empty($meta) || !is_string($meta) )
1021 return false;
1022
1023 // handles each field type differently..
1024 switch ($fieldtype) :
1025
1026 // Image
1027 case "image" :
1028 $meta = $this->get_thumbnail($meta);
1029 break;
1030
1031 // Media Library ID
1032 case "library_id" :
1033 // check if media exists
1034 $meta = wp_get_attachment_url($meta) ? wp_get_attachment_image( $meta, array(80,80), true ) : '';
1035 break;
1036
1037 // Excerpt
1038 case "excerpt" :
1039 $meta = $this->get_shortened_string($meta, $this->excerpt_length);
1040 break;
1041
1042 endswitch;
1043
1044 // add before and after string
1045 $meta = "{$before}{$meta}{$after}";
1046
1047 return $meta;
1048 }
1049
1050 /**
1051 * Get column value of Custom Field
1052 *
1053 * @since 1.2
1054 */
1055 private function get_user_column_value_custom_field($user_id, $id)
1056 {
1057 $columns = $this->get_stored_columns('wp-users');
1058
1059 // inputs
1060 $field = isset($columns[$id]['field']) ? $columns[$id]['field'] : '';
1061 $fieldtype = isset($columns[$id]['field_type']) ? $columns[$id]['field_type'] : '';
1062 $before = isset($columns[$id]['before']) ? $columns[$id]['before'] : '';
1063 $after = isset($columns[$id]['after']) ? $columns[$id]['after'] : '';
1064
1065 // Get meta field value
1066 $meta = get_user_meta($user_id, $field, true);
1067
1068 // multiple meta values
1069 if ( ( $fieldtype == 'array' && is_array($meta) ) || is_array($meta) ) {
1070 $meta = get_user_meta($user_id, $field);
1071 $meta = $this->recursive_implode(', ', $meta);
1072 }
1073
1074 // make sure there are no serialized arrays or empty meta data
1075 if ( empty($meta) || !is_string($meta) )
1076 return false;
1077
1078 // handles each field type differently..
1079 switch ($fieldtype) :
1080
1081 // Image
1082 case "image" :
1083 $meta = $this->get_thumbnail($meta);
1084 break;
1085
1086 // Media Library ID
1087 case "library_id" :
1088 $meta = wp_get_attachment_url($meta) ? wp_get_attachment_image( $meta, array(80,80), true ) : '';
1089 break;
1090
1091 // Excerpt
1092 case "excerpt" :
1093 $meta = $this->get_shortened_string($meta, $this->excerpt_length);
1094 break;
1095
1096 endswitch;
1097
1098 // add before and after string
1099 $meta = "{$before}{$meta}{$after}";
1100
1101 return $meta;
1102 }
1103
1104 /**
1105 * Implode for multi dimensional array
1106 *
1107 * @since 1.0
1108 */
1109 private function recursive_implode( $glue, $pieces )
1110 {
1111 foreach( $pieces as $r_pieces ) {
1112 if( is_array( $r_pieces ) ) {
1113 $retVal[] = $this->recursive_implode( $glue, $r_pieces );
1114 }
1115 else {
1116 $retVal[] = $r_pieces;
1117 }
1118 }
1119 if ( isset($retVal) && is_array($retVal) )
1120 return implode( $glue, $retVal );
1121
1122 return false;
1123 }
1124
1125 /**
1126 * Set columns. These columns apply either for every post or set by a plugin.
1127 *
1128 * @since 1.0
1129 */
1130 private function filter_preset_columns($columns, $type = 'post')
1131 {
1132 $options = get_option('cpac_options_default');
1133
1134 if ( !$options )
1135 return $columns;
1136
1137 // we use the wp default columns for filtering...
1138 $stored_wp_default_columns = $options[$type];
1139
1140 // ... the ones that are set by plugins, theme functions and such.
1141 $dif_columns = array_diff(array_keys($columns), array_keys($stored_wp_default_columns));
1142
1143 // we add those to the columns
1144 $pre_columns = array();
1145 if ( $dif_columns ) {
1146 foreach ( $dif_columns as $column ) {
1147 $pre_columns[$column] = $columns[$column];
1148 }
1149 }
1150
1151 return $pre_columns;
1152 }
1153
1154 /**
1155 * Get WP default supported admin columns per post type.
1156 *
1157 * @since 1.0
1158 */
1159 private function get_wp_default_posts_columns($post_type = 'post')
1160 {
1161 // load dependencies
1162
1163 // deprecated as of wp3.3
1164 if ( file_exists(ABSPATH . 'wp-admin/includes/template.php') )
1165 require_once(ABSPATH . 'wp-admin/includes/template.php');
1166
1167 // introduced since wp3.3
1168 if ( file_exists(ABSPATH . 'wp-admin/includes/screen.php') )
1169 require_once(ABSPATH . 'wp-admin/includes/screen.php');
1170
1171 // used for getting columns
1172 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1173 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1174 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php') )
1175 require_once(ABSPATH . 'wp-admin/includes/class-wp-posts-list-table.php');
1176
1177 // we need to change the current screen
1178 global $current_screen;
1179 $org_current_screen = $current_screen;
1180
1181 // overwrite current_screen global with our post type of choose...
1182 $current_screen->post_type = $post_type;
1183
1184 // ...so we can get its columns
1185 $columns = WP_Posts_List_Table::get_columns();
1186
1187 if ( empty ( $columns ) )
1188 return false;
1189
1190 // change to uniform format
1191 $posts_columns = $this->get_uniform_format($columns);
1192
1193 // reset current screen
1194 $current_screen = $org_current_screen;
1195
1196 return $posts_columns;
1197 }
1198
1199 /**
1200 * Get WP default users columns per post type.
1201 *
1202 * @since 1.1
1203 */
1204 private function get_wp_default_users_columns()
1205 {
1206 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-list-table.php') )
1207 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
1208 if ( file_exists(ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php') )
1209 require_once(ABSPATH . 'wp-admin/includes/class-wp-users-list-table.php');
1210
1211 // turn off site users
1212 $this->is_site_users = false;
1213
1214 // get users columns
1215 $columns = WP_Users_List_Table::get_columns();
1216
1217 // change to uniform format
1218 $users_columns = $this->get_uniform_format($columns);
1219
1220 return $users_columns;
1221 }
1222
1223 /**
1224 * Build uniform format for all columns
1225 *
1226 * @since 1.0
1227 */
1228 private function get_uniform_format($columns)
1229 {
1230 // we remove the checkbox column as an option...
1231 if ( isset($columns['cb']) )
1232 unset($columns['cb']);
1233
1234 // change to uniform format
1235 $uniform_columns = array();
1236 foreach ( (array) $columns as $id => $label ) {
1237 $hide_options = false;
1238 $type_label = $label;
1239
1240 // comment exception
1241 if ( strpos( $label, 'comment-grey-bubble.png') ) {
1242 $type_label = __('Comments', $this->textdomain);
1243 $hide_options = true;
1244 }
1245
1246 $uniform_colums[$id] = array(
1247 'label' => $label,
1248 'state' => 'on',
1249 'options' => array(
1250 'type_label' => $type_label,
1251 'hide_options' => $hide_options,
1252 'class' => 'cpac-box-wp-native',
1253 )
1254 );
1255 }
1256 return $uniform_colums;
1257 }
1258
1259 /**
1260 * Custom posts columns
1261 *
1262 * @since 1.0
1263 */
1264 private function get_custom_posts_columns($post_type)
1265 {
1266 $custom_columns = array();
1267
1268 // Thumbnail support
1269 if ( post_type_supports($post_type, 'thumbnail') ) {
1270 $custom_columns['column-featured_image'] = array(
1271 'label' => __('Featured Image', $this->textdomain),
1272 'options' => array(
1273 'type_label' => __('Image', $this->textdomain)
1274 )
1275 );
1276 }
1277
1278 // Excerpt support
1279 if ( post_type_supports($post_type, 'editor') ) {
1280 $custom_columns['column-excerpt'] = array(
1281 'label' => __('Excerpt', $this->textdomain),
1282 'options' => array(
1283 'type_label' => __('Excerpt', $this->textdomain)
1284 )
1285 );
1286 }
1287
1288 // Sticky support
1289 if ( $post_type == 'post' ) {
1290 $custom_columns['column-sticky'] = array(
1291 'label' => __('Sticky', $this->textdomain),
1292 'options' => array(
1293 'type_label' => __('Sticky', $this->textdomain)
1294 )
1295 );
1296 }
1297
1298 // Order support
1299 if ( post_type_supports($post_type, 'page-attributes') ) {
1300 $custom_columns['column-order'] = array(
1301 'label' => __('Page Order', $this->textdomain),
1302 'options' => array(
1303 'type_label' => __('Order', $this->textdomain),
1304 'sortorder' => 'on',
1305 )
1306 );
1307 }
1308
1309 // Page Template
1310 if ( $post_type == 'page' ) {
1311 $custom_columns['column-page-template'] = array(
1312 'label' => __('Page Template', $this->textdomain),
1313 'options' => array(
1314 'type_label' => __('Page Template', $this->textdomain),
1315 'sortorder' => 'on',
1316 )
1317 );
1318 }
1319
1320 // Post Formats
1321 if ( post_type_supports($post_type, 'post-formats') ) {
1322 $custom_columns['column-post_formats'] = array(
1323 'label' => __('Post Format', $this->textdomain),
1324 'options' => array(
1325 'type_label' => __('Post Format', $this->textdomain)
1326 )
1327 );
1328 }
1329
1330 // Taxonomy support
1331 $taxonomies = get_object_taxonomies($post_type, 'objects');
1332 if ( $taxonomies ) {
1333 foreach ( $taxonomies as $tax_slug => $tax ) {
1334 if ( $tax_slug != 'post_tag' && $tax_slug != 'category' && $tax_slug != 'post_format' ) {
1335 $custom_columns['column-taxonomy-'.$tax->name] = array(
1336 'label' => $tax->label,
1337 'options' => array(
1338 'type_label' => __('Taxonomy', $this->textdomain)
1339 )
1340 );
1341 }
1342 }
1343 }
1344
1345 // Post ID support
1346 $custom_columns['column-postid'] = array(
1347 'label' => 'ID',
1348 'options' => array(
1349 'type_label' => 'ID',
1350 'sortorder' => 'on',
1351 )
1352 );
1353
1354 // Slug support
1355 $custom_columns['column-page-slug'] = array(
1356 'label' => __('Slug', $this->textdomain),
1357 'options' => array(
1358 'type_label' => __('Slug', $this->textdomain),
1359 'sortorder' => 'on',
1360 )
1361 );
1362
1363 // Word count support
1364 $custom_columns['column-word-count'] = array(
1365 'label' => __('Word count', $this->textdomain),
1366 'options' => array(
1367 'type_label' => __('Word count', $this->textdomain),
1368 'sortorder' => 'on'
1369 )
1370 );
1371
1372 // Attachment support
1373 $custom_columns['column-attachment'] = array(
1374 'label' => __('Attachment', $this->textdomain),
1375 'options' => array(
1376 'type_label' => __('Attachment', $this->textdomain),
1377 'sortorder' => 'on'
1378 )
1379 );
1380
1381 // Attachment count support
1382 $custom_columns['column-attachment-count'] = array(
1383 'label' => __('No. of Attachments', $this->textdomain),
1384 'options' => array(
1385 'type_label' => __('No. of Attachments', $this->textdomain),
1386 'sortorder' => 'on'
1387 )
1388 );
1389
1390 // Custom Field support
1391 if ( $this->get_meta_by_type($post_type) ) {
1392 $custom_columns['column-meta-1'] = array(
1393 'label' => __('Custom Field', $this->textdomain),
1394 'field' => '',
1395 'field_type' => '',
1396 'before' => '',
1397 'after' => '',
1398 'options' => array(
1399 'type_label' => __('Field', $this->textdomain),
1400 'class' => 'cpac-box-metafield',
1401 'sortorder' => 'on',
1402 )
1403 );
1404 }
1405
1406 // merge with defaults
1407 $custom_columns = $this->parse_defaults($custom_columns);
1408
1409 return apply_filters('cpac-custom-posts-columns', $custom_columns);
1410 }
1411
1412 /**
1413 * Custom users columns
1414 *
1415 * @since 1.1
1416 */
1417 private function get_custom_users_columns()
1418 {
1419 $custom_columns = array();
1420
1421 // User ID
1422 $custom_columns['column-user_id'] = array(
1423 'label' => __('User ID', $this->textdomain),
1424 'options' => array(
1425 'type_label' => __('User ID', $this->textdomain),
1426 'sortorder' => 'on'
1427 )
1428 );
1429
1430 // First name
1431 $custom_columns['column-first_name'] = array(
1432 'label' => __('First name', $this->textdomain),
1433 'options' => array(
1434 'type_label' => __('First name', $this->textdomain),
1435 )
1436 );
1437
1438 // Last name
1439 $custom_columns['column-last_name'] = array(
1440 'label' => __('Last name', $this->textdomain),
1441 'options' => array(
1442 'type_label' => __('Last name', $this->textdomain),
1443 )
1444 );
1445
1446 // User url
1447 $custom_columns['column-user_url'] = array(
1448 'label' => __('Url', $this->textdomain),
1449 'options' => array(
1450 'type_label' => __('Url', $this->textdomain),
1451 )
1452 );
1453
1454 // User registration date
1455 $custom_columns['column-user_registered'] = array(
1456 'label' => __('Registered', $this->textdomain),
1457 'options' => array(
1458 'type_label' => __('Registered', $this->textdomain),
1459 )
1460 );
1461
1462 // User description
1463 $custom_columns['column-user_description'] = array(
1464 'label' => __('Description', $this->textdomain),
1465 'options' => array(
1466 'type_label' => __('Description', $this->textdomain),
1467 )
1468 );
1469
1470 // Custom Field support
1471 $custom_columns['column-meta-1'] = array(
1472 'label' => __('Custom Field', $this->textdomain),
1473 'field' => '',
1474 'field_type' => '',
1475 'before' => '',
1476 'after' => '',
1477 'options' => array(
1478 'type_label' => __('Field', $this->textdomain),
1479 'class' => 'cpac-box-metafield',
1480 'sortorder' => '',
1481 )
1482 );
1483
1484 // merge with defaults
1485 $custom_columns = $this->parse_defaults($custom_columns);
1486
1487 return apply_filters('cpac-custom-users-columns', $custom_columns);
1488 }
1489
1490 /**
1491 * Parse defaults
1492 *
1493 * @since 1.1
1494 */
1495 private function parse_defaults($columns)
1496 {
1497 // default arguments
1498 $defaults = array(
1499
1500 // stored values
1501 'label' => '',
1502 'state' => '',
1503
1504 // static values
1505 'options' => array(
1506 'type_label' => __('Custom', $this->textdomain),
1507 'hide_options' => false,
1508 'class' => 'cpac-box-custom',
1509 'sortorder' => '',
1510 )
1511 );
1512
1513 foreach ( $columns as $k => $column ) {
1514 $c[$k] = wp_parse_args( $column, $defaults);
1515 }
1516
1517 return $c;
1518 }
1519
1520 /**
1521 * Admin requests for orderby column
1522 *
1523 * @since 1.0
1524 */
1525 private function get_stored_columns($type)
1526 {
1527 // get plugin options
1528 $options = get_option('cpac_options');
1529
1530 // get saved columns
1531 if ( isset($options['columns'][$type]) )
1532 return $options['columns'][$type];
1533
1534 return false;
1535 }
1536
1537 /**
1538 * Post Type Menu
1539 *
1540 * @since 1.0
1541 */
1542 private function get_menu()
1543 {
1544 // set
1545 $menu = '';
1546 $count = 1;
1547
1548 // referer
1549 $referer = '';
1550 if ( isset($_REQUEST['cpac_type']) && $_REQUEST['cpac_type'] )
1551 $referer = $_REQUEST['cpac_type'];
1552
1553 // loop
1554 foreach ( $this->get_types() as $type ) {
1555 $label = $this->get_singular_name($type);
1556 $clean_label = $this->sanitize_string($type);
1557
1558 // divider
1559 $divider = $count++ == 1 ? '' : ' | ';
1560
1561 // current
1562 $current = '';
1563 if ( $this->is_menu_type_current($type) )
1564 $current = ' class="current"';
1565
1566 // menu list
1567 $menu .= "
1568 <li>{$divider}<a{$current} href='#cpac-box-{$clean_label}'>{$label}</a></li>
1569 ";
1570 }
1571
1572 return "
1573 <div class='cpac-menu'>
1574 <ul class='subsubsub'>
1575 {$menu}
1576 </ul>
1577 </div>
1578 ";
1579 }
1580
1581 /**
1582 * Checks if menu type is currently viewed
1583 *
1584 * @since 1.0
1585 */
1586 private function is_menu_type_current( $post_type )
1587 {
1588 // referer
1589 $referer = '';
1590 if ( ! empty($_REQUEST['cpac_type']) )
1591 $referer = $_REQUEST['cpac_type'];
1592
1593 // get label
1594 $label = $this->get_singular_name($post_type);
1595 $clean_label = $this->sanitize_string($post_type);
1596
1597 // get first element from post-types
1598 $first = array_shift(array_values($this->post_types));
1599
1600 // display the page that was being viewed before saving
1601 if ( $referer ) {
1602 if ( $referer == 'cpac-box-'.$clean_label ) {
1603 return true;
1604 }
1605
1606 // settings page has not yet been saved
1607 } elseif ( $first == $post_type ) {
1608 return true;
1609 }
1610
1611 return false;
1612 }
1613
1614 /**
1615 * Get singular name of post type
1616 *
1617 * @since 1.0
1618 */
1619 private function get_singular_name( $type )
1620 {
1621 // Users
1622 if ( $type == 'wp-users' )
1623 $label = 'Users';
1624
1625 // Posts
1626 else {
1627 $posttype_obj = get_post_type_object($type);
1628 $label = $posttype_obj->labels->singular_name;
1629 }
1630
1631 return $label;
1632 }
1633
1634 /**
1635 * Admin requests for orderby column
1636 *
1637 * @since 1.0
1638 */
1639 public function handle_requests_orderby_column( $vars )
1640 {
1641 if ( ! isset( $vars['orderby'] ) )
1642 return $vars;
1643
1644 $column = $this->get_orderby_type( $vars['orderby'], $vars['post_type'] );
1645
1646 $post_type = !empty($vars['post_type']) ? $vars['post_type'] : '';
1647
1648 if ( $column ) {
1649 $id = key($column);
1650
1651 // Page Order
1652 if ( $id == 'column-order' ) {
1653 $vars['orderby'] = 'menu_order';
1654 }
1655
1656 // Custom Fields
1657 if ( $this->is_column_meta($id) ) {
1658 $field = $column[$id]['field'];
1659
1660 // orderby type
1661 $field_type = 'meta_value';
1662 if ( $column[$id]['field_type'] == 'numeric' || $column[$id]['field_type'] == 'library_id' )
1663 $field_type = 'meta_value_num';
1664
1665 // set vars
1666 $vars = array_merge( $vars, array(
1667 'meta_key' => $field,
1668 'orderby' => $field_type
1669 ) );
1670 }
1671
1672 // Wordcount
1673 if ( $id == 'column-word-count' ) {
1674 // add wordcount to the post ids
1675 $wordcount_posts = array();
1676 foreach ( (array) $this->get_any_posts_by_posttype($post_type) as $p ) {
1677 $wordcount_posts[$p->ID] = str_word_count( strip_tags( $p->post_content ) );
1678 }
1679
1680 // we will add the sorted post ids to vars['post__in'] and remove unused vars
1681 $this->set_vars_post__in( &$vars, $wordcount_posts, SORT_NUMERIC );
1682 }
1683
1684 // Page Template
1685 if ( $id == 'column-page-template' ) {
1686 // add template filename to the post ids
1687 $template_posts = array();
1688 $templates = get_page_templates();
1689 foreach ( (array) $this->get_any_posts_by_posttype($post_type) as $p ) {
1690 $page_template = get_post_meta($p->ID, '_wp_page_template', true);
1691 $template_posts[$p->ID] = array_search($page_template, $templates);
1692 }
1693 $this->set_vars_post__in( &$vars, $template_posts );
1694 }
1695
1696 // Attachments
1697 if ( $id == 'column-attachment' || $id == 'column-attachment-count' ) {
1698 // add number of attachment to the post ids
1699 $attachment_posts = array();
1700 foreach ( (array) $this->get_any_posts_by_posttype($post_type) as $p ) {
1701 $attachment_posts[$p->ID] = count( $this->get_attachment_ids($p->ID) );
1702 }
1703 $this->set_vars_post__in( &$vars, $attachment_posts, SORT_NUMERIC );
1704 }
1705
1706
1707 // Slug
1708 if ( $id == 'column-page-slug' ) {
1709 // add slug to the post ids
1710 $slug_posts = array();
1711 foreach ( (array) $this->get_any_posts_by_posttype($post_type) as $p ) {
1712 $slug_posts[$p->ID] = $p->post_name;
1713 }
1714 $this->set_vars_post__in( &$vars, $slug_posts );
1715 }
1716 }
1717
1718 return $vars;
1719 }
1720
1721 /**
1722 * Set post__in for use in WP_Query
1723 *
1724 * This will order the ID's asc or desc and set the appropriate filters.
1725 *
1726 * @since 1.2.1
1727 */
1728 private function set_vars_post__in( &$vars, $sortposts, $sort_flags = SORT_REGULAR )
1729 {
1730 // sort post ids by value
1731 if ( $vars['order'] == 'asc' )
1732 asort($sortposts, $sort_flags);
1733 else
1734 arsort($sortposts, $sort_flags);
1735
1736 // this will make sure WP_Query will use the order of the ids that we have just set in 'post__in'
1737 add_filter('posts_orderby', array( &$this, 'filter_orderby_post__in'), 10, 2 );
1738
1739 // cleanup the vars we dont need
1740 $vars['order'] = '';
1741 $vars['orderby'] = '';
1742
1743 // add the sorted post ids to the query with the use of post__in
1744 $vars['post__in'] = array_keys($sortposts);
1745 }
1746
1747 /**
1748 * Get any posts by post_type
1749 *
1750 * @since 1.2.1
1751 */
1752 private function get_any_posts_by_posttype( $post_type )
1753 {
1754 $allposts = get_posts(array(
1755 'numberposts' => -1,
1756 'post_status' => 'any',
1757 'post_type' => $post_type
1758 ));
1759 return $allposts;
1760 }
1761
1762 /**
1763 * Get orderby type
1764 *
1765 * @since 1.1
1766 */
1767 private function get_orderby_type($orderby, $type)
1768 {
1769 $db_columns = $this->get_stored_columns($type);
1770
1771 if ( $db_columns ) {
1772 foreach ( $db_columns as $id => $vars ) {
1773
1774 // check which custom column was clicked
1775 if ( isset( $vars['label'] ) && $orderby == $this->sanitize_string( $vars['label'] ) ) {
1776 $column[$id] = $vars;
1777 return $column;
1778 }
1779 }
1780 }
1781 return false;
1782 }
1783
1784 /**
1785 * Maintain order of ids that are set in the post__in var.
1786 *
1787 * This will force the returned posts to use the order of the ID's that
1788 * have been set in post__in. Without this the ID's will be set in numeric order.
1789 * See the WP_Query object for more info about the use of post__in.
1790 *
1791 * @since 1.2.1
1792 */
1793 public function filter_orderby_post__in($orderby, $wp)
1794 {
1795 global $wpdb;
1796
1797 // we need the query vars
1798 $vars = $wp->query_vars;
1799 if ( ! empty ( $vars['post__in'] ) ) {
1800 // now we can get the ids
1801 $ids = implode(',', $vars['post__in']);
1802
1803 // by adding FIELD to the SQL query we are forcing the order of the ID's
1804 return "FIELD ({$wpdb->prefix}posts.ID,{$ids})";
1805 }
1806 }
1807
1808 /**
1809 * Sanitize label
1810 *
1811 * Uses intern wordpress function esc_url so it matches the label sorting url.
1812 *
1813 * @since 1.0
1814 */
1815 private function sanitize_string($string)
1816 {
1817 return str_replace('http://','', esc_url($string) );
1818 }
1819
1820 /**
1821 * Get plugin url.
1822 *
1823 * @since 1.0
1824 */
1825 private function plugin_url( $file = '' )
1826 {
1827 return plugins_url($file, __FILE__);
1828 }
1829
1830 /**
1831 * Checks if column-meta key exists
1832 *
1833 * @since 1.0
1834 */
1835 private function is_column_meta( $id = '' )
1836 {
1837 if ( strpos($id, 'column-meta-') !== false )
1838 return true;
1839
1840 return false;
1841 }
1842
1843 /**
1844 * Get a thumbnail
1845 *
1846 * @since 1.0
1847 */
1848 private function get_thumbnail( $image = '' )
1849 {
1850 if ( empty($image) )
1851 return false;
1852
1853 // get correct image path
1854 $image_path = str_replace( WP_CONTENT_URL, WP_CONTENT_DIR, $image);
1855
1856 // resize image
1857 if ( file_exists($image_path) && $this->is_image($image_path) ) {
1858 $resized = image_resize( $image_path, 120, 80, true);
1859
1860 if ( ! is_wp_error( $resized ) ) {
1861 $image = str_replace( WP_CONTENT_DIR, WP_CONTENT_URL, $resized);
1862
1863 return "<img src='{$image}' alt='' width='120' height='80' />";
1864 }
1865
1866 return $resized->get_error_message();
1867 }
1868
1869 return false;
1870 }
1871
1872 /**
1873 * Checks an URL for image extension
1874 *
1875 * @since 1.2
1876 */
1877 private function is_image($url)
1878 {
1879 $validExt = array('.jpg', '.jpeg', '.gif', '.png', '.bmp');
1880 $ext = strrchr($url, '.');
1881
1882 return in_array($ext, $validExt);
1883 }
1884
1885 /**
1886 * Settings Page Template.
1887 *
1888 * This function in conjunction with others usei the WordPress
1889 * Settings API to create a settings page where users can adjust
1890 * the behaviour of this plugin.
1891 *
1892 * @since 1.0
1893 */
1894 public function plugin_settings_page()
1895 {
1896
1897 // loop through post types
1898 $rows = '';
1899 foreach ( $this->get_types() as $type ) {
1900
1901 // post type label
1902 $label = $this->get_singular_name($type);
1903
1904 // id
1905 $id = $this->sanitize_string($type);
1906
1907 // build draggable boxes
1908 $boxes = $this->get_column_boxes($type);
1909
1910 // class
1911 $class = $this->is_menu_type_current($type) ? ' current' : ' hidden';
1912
1913 $rows .= "
1914 <tr id='cpac-box-{$id}' valign='top' class='cpac-box-row{$class}'>
1915 <th class='cpac_post_type' scope='row'>
1916 {$label}
1917 </th>
1918 <td>
1919 <h3 class='cpac_post_type hidden'>{$label}</h3>
1920 {$boxes}
1921 </td>
1922 </tr>
1923 ";
1924 }
1925
1926 // Post Type Menu
1927 $menu = $this->get_menu();
1928
1929 ?>
1930 <div id="cpac" class="wrap">
1931 <?php screen_icon($this->slug) ?>
1932 <h2><?php _e('Codepress Admin Columns', $this->textdomain); ?></h2>
1933 <?php echo $menu ?>
1934 <div class="postbox-container" style="width:70%;">
1935 <div class="metabox-holder">
1936 <div class="meta-box-sortables">
1937
1938 <div id="general-cpac-settings" class="postbox">
1939 <div title="Click to toggle" class="handlediv"><br></div>
1940 <h3 class="hndle">
1941 <span><?php _e('Admin Columns', $this->textdomain ); ?></span>
1942 </h3>
1943 <div class="inside">
1944 <form method="post" action="options.php">
1945
1946 <?php settings_fields( 'cpac-settings-group' ); ?>
1947
1948 <table class="form-table">
1949
1950 <?php echo $rows ?>
1951
1952 <tr class="bottom" valign="top">
1953 <th scope="row"></th>
1954 <td>
1955 <p class="submit">
1956 <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
1957 </p>
1958 </td>
1959 </tr>
1960 </table>
1961 </form>
1962 </div>
1963 </div><!-- general-settings -->
1964
1965 <div id="restore-cpac-settings" class="postbox">
1966 <div title="Click to toggle" class="handlediv"><br></div>
1967 <h3 class="hndle">
1968 <span><?php _e('Restore defaults', $this->textdomain) ?></span>
1969 </h3>
1970 <div class="inside">
1971 <form method="post" action="">
1972 <input type="submit" class="button" name="cpac-restore-defaults" value="<?php _e('Restore default settings', $this->textdomain ) ?>" onclick="return confirm('<?php _e("Warning! ALL saved admin columns data will be deleted. This cannot be undone. \'OK\' to delete, \'Cancel\' to stop", $this->textdomain); ?>');" />
1973 </form>
1974 <p class="description"><?php _e('This will delete all column settings and restore the default settings.', $this->textdomain); ?></p>
1975 </div>
1976 </div><!-- restore-cpac-settings -->
1977
1978 </div>
1979 </div>
1980 </div><!-- .postbox-container -->
1981
1982 <div class="postbox-container" style="width:20%;">
1983 <div class="metabox-holder">
1984 <div class="meta-box-sortables">
1985
1986 <div id="likethisplugin-cpac-settings" class="postbox">
1987 <div title="Click to toggle" class="handlediv"><br></div>
1988 <h3 class="hndle">
1989 <span><?php _e('Like this plugin?', $this->textdomain) ?></span>
1990 </h3>
1991 <div class="inside">
1992 <p><?php _e('Why not do any or all of the following', $this->textdomain) ?>:</p>
1993 <ul>
1994 <li><a href="http://www.codepress.nl/plugins/codepress-admin-columns/"><?php _e('Link to it so other folks can find out about it.', $this->textdomain) ?></a></li>
1995 <li><a href="http://wordpress.org/extend/plugins/codepress-admin-columns/"><?php _e('Give it a 5 star rating on WordPress.org.', $this->textdomain) ?></a></li>
1996 <li class="donate_link"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=ZDZRSYLQ4Z76J"><?php _e('Donate a token of your appreciation.', $this->textdomain) ?></a></li>
1997 </ul>
1998 </div>
1999 </div><!-- likethisplugin-cpac-settings -->
2000
2001 <div id="side-cpac-settings" class="postbox">
2002 <div title="Click to toggle" class="handlediv"><br></div>
2003 <h3 class="hndle">
2004 <span><?php _e('Need support?', $this->textdomain) ?></span>
2005 </h3>
2006 <div class="inside">
2007 <p><?php printf(__('If you are having problems with this plugin, please talk about them in the <a href="%s">Support forums</a> or send me an email %s.', $this->textdomain), 'http://wordpress.org/tags/codepress-admin-columns', '<a href="mailto:info@codepress.nl">info@codepress.nl</a>' );?></p>
2008 <p><?php printf(__("If you're sure you've found a bug, or have a feature request, please <a href='%s'>submit your feedback</a>.", $this->textdomain), 'http://www.codepress.nl/plugins/codepress-admin-columns#feedback');?></p>
2009 </div>
2010 </div><!-- side-cpac-settings -->
2011
2012 </div>
2013 </div>
2014 </div><!-- .postbox-container -->
2015
2016 </div>
2017 <?php
2018 }
2019 }
2020 ?>