PluginProbe
Guest Author / 2.2
Guest Author v2.2
2.4 2.5 2.6 2.61 2.62 trunk 2.1.6 2.1.7 2.1.8 2.1.9 2.1.91 2.2 2.3
guest-author / guest-author.php

guest-author.php in Guest Author 2.2, at guest-author.php

715 lines 24.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Guest Author class definition
4 *
5 * @package guest-author
6 * @since 1.0
7 */
8
9 if ( !class_exists( 'BS_Guest_Author' ) ) :
10
11 class BS_Guest_Author {
12
13
14 function __construct() {
15
16 /**
17 * This is done this way, because in ajax requests is_admin() returns true from the frontend and backend
18 */
19 if ( ! is_admin() || ( function_exists('wp_doing_ajax') && wp_doing_ajax() ) ) {
20 $this->plugin_front_setup();
21 }
22
23 if ( is_admin() ) {
24 $this->plugin_admin_setup();
25 }
26 }
27
28 /**
29 * Sets up the plugin on the front site,
30 * by adding the necessary filters and actions.
31 *
32 * @since 1.0
33 *
34 * @return void
35 */
36 public function plugin_front_setup () {
37 add_action( 'wp_head',array($this, 'simple_front_end_css') );
38 add_filter( 'body_class',array($this, 'add_body_class') );
39
40 add_action( 'pre_get_posts', array($this, 'filter_guest_authors'));
41 add_action( 'the_post', array($this, 'register_authordata'));
42
43 add_filter( 'the_author', array( $this, 'author_name' ), 12 );
44 add_filter( 'get_the_author_display_name', array( $this, 'author_name' ), 12 );
45 add_filter( 'get_the_author_user_nicename', array( $this, 'author_name' ), 12 );
46 add_filter( 'get_the_author_nickname', array( $this, 'author_name' ), 12 );
47 add_filter( 'get_the_author_ID', array( $this, 'author_ID' ), 12 );
48 add_filter( 'author_link', array( $this, 'author_link' ), 12 );
49 add_filter( 'get_the_author_link', array( $this, 'author_link' ), 12 );
50 add_filter( 'get_the_author_url', array( $this, 'author_link' ), 21 );
51
52 // This affects markup and we don't want to do that
53 // add_filter( 'the_author_posts_link', array( $this, 'author_link_html' ), 21 );
54 add_filter( 'author_description', array( $this, 'author_description'), 12);
55 add_filter( 'get_the_author_description', array( $this, 'author_description' ), 12 );
56
57 add_filter( 'get_the_author_user_email', array( $this, '__return_null_meta' ), 12 );
58
59 // add_filter( 'get_avatar', array( $this, 'author_avatar') );
60 add_filter( 'pre_get_avatar_data', array( $this, 'pre_get_author_avatar_data'), 12, 2 );
61
62 // add_action( 'loop_end', array( $this, 'remove_author_avatar_filter' ));
63 // add_filter( 'comments_template', array( $this, 'remove_author_avatar_filter_at_comments' ));
64 }
65
66 /**
67 * Sets up the plugin on the dashboard,
68 * by adding the necessary filters and actions.
69 *
70 * @since 1.0
71 * @return void
72 */
73 public function plugin_admin_setup() {
74 add_action( 'save_post', array( $this, 'save' ) );
75
76 add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
77 add_action( 'current_screen', array( $this, 'remove_default_author_meta_box') );
78 add_action( 'add_meta_boxes', array( $this, 'add_new_author_box' ) );
79
80 add_filter('manage_posts_columns', array( $this, 'add_author_column') );
81 add_action('manage_posts_custom_column', array( $this, 'modify_author_column'), 10, 2 );
82
83 // Ajax action to refresh the user image
84 add_action( 'wp_ajax_BS_get_image', array($this, 'BS_ajax_get_image') );
85 }
86
87 /*
88 * Adds the class 'guest-author' to the body of a post that's using a guest author
89 * */
90 public function add_body_class( $classes ) {
91 if ( $this->is_guest_author_available() ) {
92 $classes[] = 'guest-author-'. BS_GUEST_AUTHOR_VERSION;
93 }
94
95 return $classes;
96 }
97
98 /*
99 * Adds the class 'guest-author' to the body of a post that's using a guest author
100 * */
101 public function simple_front_end_css() {
102 if ( $this->is_guest_author_available() ) {
103 ?>
104 <style type="text/css">
105 body[class^="guest-author"] a[href=''] {
106 pointer-events: none;
107 color: inherit;
108 text-decoration: inherit;
109 }
110 </style>
111 <?php
112 }
113 }
114
115
116 /**
117 * Filters the author query results that are written by a guest author.
118 *
119 *
120 * This is needed because each post has the author ID under post_author.
121 * Therefore, even if the admin user adds a guest author to a post their ID
122 * will still be attached to the post.
123 *
124 * That being said, when a website user clicks on the a registered user's author link,
125 * we don't want to list the posts that have a guest author's name showing in the meta.
126 *
127 * @since 1.0
128 * @return void
129 */
130 public function filter_guest_authors( $query ) {
131 if (is_author()
132 || $query->is_author
133 || (isset ($query->author__in) && count ($query->author__in) > 0 )
134 || (isset($query->author_name) && !empty($query->author_name) )
135 || (isset($query->author) && !empty($query->author) ) ) {
136 $query->set('meta_query', array(
137 'relation' => 'OR',
138 array(
139 'key' => "BS_author_type",
140 'value' => 'BS_author_is_guest',
141 'compare' => '!='
142 ),
143 array(
144 'key' => "BS_author_type",
145 'compare' => 'NOT EXISTS'
146 )
147 )
148 );
149 };
150 }
151
152 /**
153 * Removes the default author meta box (surprise!). This is because
154 * we will replace it with an identical box that has a little more to it.
155 *
156 * @since 1.0
157 * @return void
158 */
159 public function remove_default_author_meta_box () {
160 if ( BS_is_gutenberg () ) return;
161
162 $post_type = $this->get_current_post_type();
163
164 if ( ! $this->is_eligible_post_type($post_type) ) {
165 $post_type = 'post';
166 }
167
168 remove_meta_box( 'authordiv', $post_type, 'normal');
169
170 }
171
172 /**
173 * Adds an author meta box that has more to it than the default one.
174 *
175 * @since 1.0
176 * @return void
177 */
178 public function add_new_author_box( $post_type ) {
179 $post_type = $this->get_current_post_type();
180
181 if ( ! $this->is_eligible_post_type($post_type) ) {
182 $post_type = 'post';
183 }
184
185 $context = ( BS_is_gutenberg () ) ? 'side' : 'normal';
186
187 add_meta_box( 'BS_authordiv', __( 'Author' ), array($this, 'render_meta_box'), $post_type, $context, 'core' );
188 }
189
190 /**
191 * Renders the new author meta box
192 *
193 * @since 1.0
194 * @return void
195 */
196 public function render_meta_box () {
197 include_once "templates/meta-box-content.php";
198 }
199
200 /**
201 * Adds the admin scripts and styles
202 *
203 * @since 1.0
204 * @return void
205 */
206 public function admin_scripts ($page) {
207 if ($page === 'post.php' || $page === 'post-new.php') {
208 wp_enqueue_style('BS_guest_author_styles', plugins_url('/css/style.css', __FILE__), [], BS_GUEST_AUTHOR_VERSION);
209
210 // Enqueue WordPress media scripts
211 wp_enqueue_media();
212 // Enqueue custom script that will interact with wp.media
213 wp_enqueue_script( 'BS_guest_author_script', plugins_url( '/js/script.js' , __FILE__ ), array('jquery'), BS_GUEST_AUTHOR_VERSION );
214 }
215 }
216
217 /**
218 * Renders the new author meta box
219 *
220 * @since 1.0
221 * @return void
222 */
223 public function BS_ajax_get_image() {
224 if(isset($_GET['id']) ) {
225
226 $image = wp_get_attachment_image( filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT ), 'medium', false, array( 'id' => 'BS-preview-image' ) );
227 $data = array( 'image' => $image );
228 wp_send_json_success( $data );
229
230 } else {
231 wp_send_json_error();
232 }
233 }
234
235 /**
236 * Saves the custom meta fields when the post is saved/updated
237 *
238 * @since 1.0
239 * @return void
240 */
241 public function save( $post_id ) {
242 global $post;
243
244 $post_type = $this->get_current_post_type();
245 if (!$post || ! $this->is_eligible_post_type($post_type)) return;
246
247 if (!isset( $_POST['BS_author_type'] )
248 || !isset( $_POST['BS_guest_author_name'] ) ) return;
249
250 $meta = [
251 'BS_author_type' => $_POST['BS_author_type'],
252 'BS_guest_author_name' => ( $_POST['BS_guest_author_name'] ),
253 'BS_guest_author_url' => esc_url( isset($_POST['BS_guest_author_url']) ? $_POST['BS_guest_author_url'] : '' ),
254 'BS_guest_author_description' => ( isset( $_POST['BS_guest_author_description'] ) ? $_POST['BS_guest_author_description'] : '' ),
255 'BS_guest_author_image_id' => isset( $_POST['BS_guest_author_image_id'] ) ? $_POST['BS_guest_author_image_id'] : ''
256 ];
257
258 foreach ($meta as $key => $value) {
259 update_post_meta( $post_id, $key, $value );
260 }
261
262 }
263
264 /**
265 * Retrieves the author's ID
266 *
267 * @since 2.2
268 *
269 * @global object $post
270 *
271 * @param string $id This parameter is only needed for when
272 * WordPress uses this function as filter.
273 *
274 * @return string | NULL returns NULL if it's a guest author post
275 *
276 */
277 public function author_ID( $id = '' ) {
278 global $post;
279
280 if ( $post AND $this->is_guest_author_available() ) {
281 return NULL;
282 }
283
284 return $id;
285 }
286
287 /**
288 * Retrieves the author's name
289 *
290 * @since 1.0
291 *
292 * @global object $post
293 *
294 * @param string $name This parameter is only needed for when
295 * WordPress uses this function as filter.
296 *
297 * @return string The guest author's name if available, otherwise
298 * it will return the original author's name.
299 */
300 public function author_name( $name = '' ) {
301 global $post;
302
303 if ( $post ) {
304 $guest_name = get_post_meta ($post->ID, 'BS_guest_author_name', true);
305 if ( !$this->is_guest_author_available() ) {
306 return $name;
307 }
308 }
309
310 if ( isset($guest_name) ) return $guest_name;
311
312 return $name;
313 }
314
315
316 /**
317 * Retrieves the author's email
318 *
319 * @since 2.1
320 *
321 * @global object $post
322 *
323 * @param string $info This parameter is only needed for when
324 * WordPress uses this function as filter.
325 *
326 * @return string|NULL .
327 */
328 public function __return_null_meta( $info = '' ) {
329 global $post;
330
331 if ( $post && $this->is_guest_author_available() ) {
332 return NULL;
333 }
334
335 return $info;
336 }
337
338 /**
339 * Retrieves the author's link
340 *
341 * @since 1.0
342 *
343 * @global object $post
344 *
345 * @param string $link This parameter is only needed for when WordPress
346 * uses this function as filter.
347 *
348 * @return string The guest author's link if the guest author
349 * is available, otherwise it is the original author's link
350 */
351 public function author_link ( $link = '' ) {
352 if ( !$this->is_guest_author_available() ) return $link;
353
354 global $post;
355 return get_post_meta ($post->ID, 'BS_guest_author_url', true);
356 }
357
358 /**
359 * Retrieves the author's descriptions
360 *
361 * @since 1.0
362 *
363 * @global object $post
364 *
365 * @param string $desc This parameter is only needed for when WordPress
366 * uses this function as filter.
367 *
368 * @return string The guest author's description if the guest author
369 * is available, otherwise it is the original author's description
370 */
371 public function author_description ( $desc = "" ) {
372 global $post;
373
374 if ( !$this->is_guest_author_available() ) {
375 return $desc;
376 }
377
378 return get_post_meta ($post->ID, 'BS_guest_author_description', true);
379 }
380
381
382 /**
383 * Retrieves the author's avatar
384 *
385 * @since 1.0
386 *
387 * @global object $post
388 *
389 * @param string $img This parameter is only needed for when WordPress
390 * uses this function as filter.
391 *
392 * @return string The guest author's avatar as an <img> element if the guest author
393 * is available, otherwise it is the original author's avatar
394 */
395 public function author_avatar ( $img = '' ) {
396 global $post;
397
398 if ( !$this->is_guest_author_available() ) {
399 return $img;
400 }
401
402 $image_id = get_post_meta( $post->ID, 'BS_guest_author_image_id', true );
403
404 if ($image_id) {
405 return wp_get_attachment_image( $image_id, array (100, 100), false );
406
407 } else {
408 // Default image
409 return "<img src=\"". plugins_url( '/img/default.jpg' , __FILE__ ) . "\">";
410 }
411
412 }
413
414 /**
415 * Retrieves the author's avatar
416 *
417 * @since 1.9.1
418 *
419 * @global object $post
420 *
421 * @param string $args This parameter is only needed for when WordPress
422 * uses this function as filter.
423 *
424 * @return string The URL of the author image
425 *
426 */
427 public function pre_get_author_avatar_data ( $args = [], $id_or_email = '' ) {
428 global $post;
429
430 if ( !$post ) return $args;
431
432 if ( !$this->is_guest_author_available() ) {
433 return $args;
434 }
435
436 // This assumes that if the id passed is empty, it means we're trying to get the guest author
437 //
438 // It also assumes that if the author id being fetched is the id of the real post author, then it probably
439 // means that we should replace it with the guest author. This is for developers that use $post->post_author to
440 // call the get_avatar_data() function
441 //
442 if ( empty($id_or_email) || ($post && $post->post_author === $id_or_email )) {
443
444 if ( isset( $args['url'] ) ) {
445 return $args;
446 }
447
448 $image_id = get_post_meta( $post->ID, 'BS_guest_author_image_id', true );
449
450 if ($image_id) {
451
452 $img_size = $args['size'];
453
454 if ( $args['width'] && $args['height'] ) {
455 $img_size = [$args['width'], $args['height']];
456 }
457
458 $image = wp_get_attachment_image_src( intval($image_id), $img_size );
459
460 $args['url'] = $image[0];
461 $args['found_avatar'] = true;
462 }
463 }
464
465 return $args;
466
467 }
468
469 /**
470 * Disables the avatar filter
471 *
472 * @since 1.0
473 *
474 * @return void
475 */
476 public function remove_author_avatar_filter() {
477 remove_filter('get_avatar', array( $this, 'author_avatar' ));
478 }
479
480 /**
481 * Disables the avatar filter when the comments are rendered. Why?
482 * This kind of a weird measure, but it is needed because if we don't
483 * remove the filter at some point, EVERY avatar in page will have the author's
484 * image. So we figure, in MOST cases the comments will be rendered AFTER the post itself.
485 *
486 * @since 1.0
487 *
488 * @return void
489 */
490 public function remove_author_avatar_filter_at_comments() {
491 $this->remove_author_avatar_filter();
492 }
493
494 /**
495 * Registers the guest author info into the global variable $authordata
496 *
497 * @since 1.2
498 *
499 * @return void
500 */
501 public function register_authordata() {
502 global $authordata;
503 global $post;
504
505 if ( !$this->is_guest_author_available() ) {
506 return;
507 }
508
509 $guest_author = new WP_User();
510
511 $guest_author->ID = NULL;
512
513 $guest_author->user_url = $this->author_link();
514 $guest_author->user_description = $this->author_description();
515 $guest_author->display_name = $this->author_name();
516 $guest_author->user_nicename = $this->author_name();
517
518 $guest_author->user_login = NULL;
519 $guest_author->user_pass = NULL;
520 $guest_author->user_email = NULL;
521 $guest_author->user_registered = NULL;
522 $guest_author->user_activation_key = NULL;
523 $guest_author->user_status = NULL;
524
525 $authordata = $guest_author;
526
527 }
528
529 /**
530 * Simply replaces the default author column in the posts list (of the dashboard),
531 * with an identical one. The difference? the posts who have a guest author, will have the
532 * notation ' — Guest Entry' next to the authoring user's name
533 *
534 * @since 1.0
535 *
536 * @return array the new columns array.
537 */
538 public function add_author_column($columns) {
539 $new_columns_array = [];
540
541 foreach ($columns as $key => $value) {
542 if ($key === 'author') {
543 $new_columns_array['author_modified'] = $value;
544 } else {
545 $new_columns_array[$key] = $value;
546 }
547 }
548 return $new_columns_array;
549 }
550 public function modify_author_column($columns) {
551 global $post;
552 switch ($columns) {
553 case 'author_modified':
554 $is_guest_author = $this->is_guest_author_selected();
555 $args = array(
556 'post_type' => $post->post_type,
557 'author' => get_the_author_meta( 'ID' )
558 );
559 $author_text = $this->get_edit_link( $args, get_the_author() );
560 if ($is_guest_author) {
561 $author_text .= ' — <b>Guest Entry</b>';
562 }
563 echo $author_text;
564 }
565 }
566
567 /**
568 * From WordPress core: /wp-admin/includes/class-wp-posts-list-table.php
569 *
570 * But it was protected so I had to copy it over
571 */
572 private function get_edit_link ($args, $label) {
573 $url = add_query_arg( $args, 'edit.php' );
574
575 $class_html = $aria_current = '';
576 if ( ! empty( $class ) ) {
577 $class_html = sprintf(
578 ' class="%s"',
579 esc_attr( $class )
580 );
581
582 if ( 'current' === $class ) {
583 $aria_current = ' aria-current="page"';
584 }
585 }
586
587 return sprintf(
588 '<a href="%s"%s%s>%s</a>',
589 esc_url( $url ),
590 $class_html,
591 $aria_current,
592 $label
593 );
594 }
595
596 /**
597 * Determines whether the guest author tab is selected
598 *
599 * @since 1.0
600 *
601 * @global object $post
602 *
603 * @return boolean True if the is guest author tab is selected instead of the user author.
604 */
605 protected function is_guest_author_selected () {
606 global $post;
607 $author_type = get_post_meta($post->ID, 'BS_author_type', true);
608
609 return $author_type === 'BS_author_is_guest';
610 }
611
612 /**
613 * Determines whether the guest author's name is empty or not
614 *
615 * @since 1.0
616 *
617 * @global object $post
618 *
619 * @return boolean True if there is a name entered to the guest author's field
620 */
621 protected function guest_author_has_name() {
622 global $post;
623 $name = get_post_meta ($post->ID, 'BS_guest_author_name', true);
624 return !empty($name);
625 }
626
627 /**
628 * Combines the previous two.
629 *
630 * @since 1.0
631 *
632 * @return boolean True if the guest author is available to use
633 */
634 public function is_guest_author_available() {
635 return $this->is_eligible_post_type() && $this->is_guest_author_selected() && $this->guest_author_has_name();
636 }
637
638 /**
639 * Checks to see if the post type is selected in the backend options
640 *
641 * @since 1.3
642 *
643 * @return boolean True if the guest author is available to use
644 */
645 protected function is_eligible_post_type ( $post_type = null ) {
646 if ($post_type === null)
647 $post_type = $this->get_current_post_type();
648
649 if ( class_exists('BS_Guest_Author_Settings') ) {
650 $valid_post_types = BS_Guest_Author_Settings::$options['bs-guest-author-integration']['post-types'];
651 if ( in_array($post_type, $valid_post_types) ) {
652 return true;
653 }
654 } else if ( $post_type === 'post' ) {
655 return true;
656 }
657
658 return false;
659 }
660
661 /**
662 * Gets the current post type in the WordPress Admin
663 *
664 * @since 1.3
665 *
666 * @credit: https://gist.github.com/bradvin/1980309
667 *
668 * @return string|null post type name
669 */
670 function get_current_post_type() {
671 global $post, $typenow, $current_screen;
672
673 //we have a post so we can just get the post type from that
674 if ( $post && $post->post_type )
675 return $post->post_type;
676
677 //check the global $typenow - set in admin.php
678 elseif( $typenow )
679 return $typenow;
680
681 //check the global $current_screen object - set in sceen.php
682 elseif( $current_screen && $current_screen->post_type )
683 return $current_screen->post_type;
684
685 //lastly check the post_type querystring
686 elseif( isset( $_REQUEST['post_type'] ) )
687 return sanitize_key( $_REQUEST['post_type'] );
688
689 //we do not know the post type!
690 return null;
691 }
692
693 /**
694 * Checks if Gutenberg is enabled
695 *
696 * @since 1.9.1
697 *
698 * @credit: https://wordpress.stackexchange.com/questions/321368/how-to-check-if-current-admin-page-is-gutenberg-editor
699 *
700 * @return boolean True if gutenberg is enabled
701 */
702 protected function is_gutenberg () {
703 global $current_screen;
704 $current_screen = get_current_screen();
705
706 return
707 (method_exists($current_screen, 'is_block_editor') && $current_screen->is_block_editor())
708 || ( ( function_exists('is_gutenberg_page')) && is_gutenberg_page() );
709
710 }
711
712 }
713
714 endif;
715