PluginProbe
Admin Columns / 1.4.6.4
Admin Columns v1.4.6.4
7.1.4 7.0.19 2.3.5 2.4 2.4.1 2.4.10 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.6.1 2.5.6.2 2.5.6.3 2.5.6.4 3.0 3.0.1 All 113 releases
codepress-admin-columns / codepress-admin-columns.php

codepress-admin-columns.php in Admin Columns 1.4.6.4, at codepress-admin-columns.php

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