PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.10.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.10.0
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / includes / seo / class-author-archives-manager.php

class-author-archives-manager.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.10.0, at includes/seo/class-author-archives-manager.php

183 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Author Archives Manager
5 *
6 * Handles author archives functionality including redirects
7 *
8 * @package ThinkRank
9 * @subpackage SEO
10 * @since 1.0.0
11 */
12
13 declare(strict_types=1);
14
15 namespace ThinkRank\SEO;
16
17 use ThinkRank\Core\Settings;
18
19 /**
20 * Author Archives Manager Class
21 *
22 * @since 1.0.0
23 */
24 class Author_Archives_Manager {
25
26 /**
27 * Initialize the manager
28 *
29 * @since 1.0.0
30 * @return void
31 */
32 public function init(): void {
33 add_action('template_redirect', [$this, 'maybe_redirect_author_archives']);
34 add_filter('thinkrank_robots_meta', [$this, 'filter_robots']);
35 add_filter('pre_get_document_title', [$this, 'modify_document_title'], 15);
36 add_action('wp_head', [$this, 'add_meta_description'], 5);
37 }
38
39 /**
40 * Add meta description for author archives
41 *
42 * @since 1.0.0
43 * @return void
44 */
45 public function add_meta_description(): void {
46 if (is_author()) {
47 $settings = new Settings();
48 // Default value matches what we set in endpoint
49 $template = $settings->get('author_archives_meta_desc', 'Articles written by %author_name% on %site_title%');
50 if (empty($template)) {
51 return;
52 }
53
54 // Get variables
55 $author_id = get_queried_object_id();
56 $author_name = get_the_author_meta('display_name', $author_id);
57 $site_title = get_bloginfo('name');
58
59 $replacements = [
60 '%author_name%' => $author_name,
61 '%site_title%' => $site_title
62 ];
63
64 $meta_desc = str_replace(array_keys($replacements), array_values($replacements), $template);
65 $meta_desc = trim($meta_desc);
66
67 if (!empty($meta_desc)) {
68 echo '<meta name="description" content="' . esc_attr($meta_desc) . '" />' . "\n";
69 }
70 }
71 }
72
73 /**
74 * Modify document title for author archives
75 *
76 * @since 1.0.0
77 * @param string $title Original title
78 * @return string Modified title
79 */
80 public function modify_document_title(string $title): string {
81 if (is_author()) {
82 $settings = new Settings();
83 $template = $settings->get('author_archives_title', '%author_name% – %site_title% %page%');
84
85 if (empty($template)) {
86 return $title;
87 }
88
89 // Get variables
90 $author_id = get_queried_object_id();
91 $author_name = get_the_author_meta('display_name', $author_id);
92 $site_title = get_bloginfo('name');
93
94 // Separator
95 $separator = '-';
96 if (class_exists('ThinkRank\SEO\Site_Identity_Manager')) {
97 $separator = \ThinkRank\SEO\Site_Identity_Manager::get_active_separator_symbol();
98 }
99
100 // Page number
101 $page_str = '';
102 $paged = get_query_var('paged') ? (int) get_query_var('paged') : 1;
103 if ($paged > 1) {
104 $page_str = sprintf(__('Page %d', 'thinkrank'), $paged);
105 }
106
107 $replacements = [
108 '%author_name%' => $author_name,
109 '%site_title%' => $site_title,
110 '%separator%' => $separator,
111 '%page%' => $page_str
112 ];
113
114 return str_replace(array_keys($replacements), array_values($replacements), $template);
115 }
116 return $title;
117 }
118
119 /**
120 * Filter robots meta tag
121 *
122 * @since 1.0.0
123 * @param array $robots Robots meta array
124 * @return array Filtered robots meta
125 */
126 public function filter_robots(array $robots): array {
127 if (is_author()) {
128 $settings = new Settings();
129 $index = $settings->get('author_archives_index', true);
130
131 if (!$index) {
132 // Remove 'index' if present
133 if (($key = array_search('index', $robots)) !== false) {
134 unset($robots[$key]);
135 }
136 // Add 'noindex' if not present
137 if (!in_array('noindex', $robots)) {
138 $robots[] = 'noindex';
139 }
140 } else {
141 // If showing in search results, check if empty archives should be hidden
142 $show_empty = $settings->get('author_archives_show_empty', false);
143 if (!$show_empty) {
144 $author_id = get_queried_object_id();
145 // Check if author has any published posts
146 $post_count = count_user_posts($author_id, 'post', true); // true = only public posts
147 if ($post_count == 0) {
148 // Remove 'index' if present
149 if (($key = array_search('index', $robots)) !== false) {
150 unset($robots[$key]);
151 }
152 // Add 'noindex' if not present
153 if (!in_array('noindex', $robots)) {
154 $robots[] = 'noindex';
155 }
156 }
157 }
158 }
159 }
160
161 return array_values($robots);
162 }
163
164 /**
165 * Redirect author archives to homepage if disabled
166 *
167 * @since 1.0.0
168 * @return void
169 */
170 public function maybe_redirect_author_archives(): void {
171 if (is_author()) {
172 $settings = new Settings();
173 // Default to true (enabled)
174 $enabled = $settings->get('author_archives_enabled', true);
175
176 if (!$enabled) {
177 wp_safe_redirect(home_url(), 301);
178 exit;
179 }
180 }
181 }
182 }
183