PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.6
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.6
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / integrations / admin / ryte-integration.php

ryte-integration.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.6, at src/integrations/admin/ryte-integration.php

252 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Integrations\Admin;
4
5 use wfConfig;
6 use WP_Error;
7 use WPSEO_Ryte_Option;
8 use WPSEO_Ryte_Request;
9 use Yoast\WP\SEO\Conditionals\Admin_Conditional;
10 use Yoast\WP\SEO\Helpers\Options_Helper;
11 use Yoast\WP\SEO\Integrations\Integration_Interface;
12
13 /**
14 * Handles the request for getting the Ryte status.
15 */
16 class Ryte_Integration implements Integration_Interface {
17
18 /**
19 * Holds the Ryte API response.
20 *
21 * @var array
22 */
23 private $ryte_response = null;
24
25 /**
26 * The options helper object used to determine if Ryte is active or not.
27 *
28 * @var Options_Helper
29 */
30 private $options_helper;
31
32 /**
33 * Constructor.
34 *
35 * @param Options_Helper $options_helper The options helper object used to determine if Ryte is active or not.
36 */
37 public function __construct(
38 Options_Helper $options_helper
39 ) {
40 $this->options_helper = $options_helper;
41 $this->maybe_add_weekly_schedule();
42 }
43
44 /**
45 * Sets up the hooks.
46 *
47 * @return void
48 */
49 public function register_hooks() {
50 if ( ! $this->is_active() ) {
51 return;
52 }
53
54 // Sets the action for the Ryte fetch cron job.
55 add_action( 'wpseo_ryte_fetch', [ $this, 'fetch_from_ryte' ] );
56 }
57
58 /**
59 * Returns the conditionals based on which this loadable should be active.
60 *
61 * In this case: only when on an admin page.
62 *
63 * @return array The conditionals.
64 */
65 public static function get_conditionals() {
66 return [ Admin_Conditional::class ];
67 }
68
69 /**
70 * Determines if we can use the functionality.
71 *
72 * @return bool True if this functionality can be used.
73 */
74 public function is_active() {
75 if ( wp_doing_ajax() ) {
76 return false;
77 }
78
79 if ( ! $this->options_helper->get( 'ryte_indexability' ) ) {
80 return false;
81 }
82
83 return true;
84 }
85
86 /**
87 * Hooks to run on plugin activation.
88 */
89 public function activate_hooks() {
90 if ( $this->get_option()->is_enabled() ) {
91 $this->schedule_cron();
92
93 return;
94 }
95
96 $this->unschedule_cron();
97 }
98
99 /**
100 * Determines whether to add a custom cron weekly schedule.
101 *
102 * @return void
103 */
104 public function maybe_add_weekly_schedule() {
105 // If there's no default cron weekly schedule, add a custom one.
106 add_filter( 'cron_schedules', [ $this, 'add_weekly_schedule' ] );
107 }
108
109 /**
110 * Adds a custom weekly cron schedule.
111 *
112 * @param array $schedules The existing custom cron schedules.
113 *
114 * @return array Enriched list of custom cron schedules.
115 */
116 public function add_weekly_schedule( $schedules ) {
117 if ( ! is_array( $schedules ) ) {
118 $schedules = [];
119 }
120
121 /*
122 * Starting with version 5.4, WordPress does have a default weekly cron
123 * schedule. See https://core.trac.wordpress.org/changeset/47062.
124 * We need to add a custom one only if the default one doesn't exist.
125 */
126 if ( isset( $schedules['weekly'] ) ) {
127 return $schedules;
128 }
129
130 $schedules['weekly'] = [
131 'interval' => WEEK_IN_SECONDS,
132 'display' => __( 'Once Weekly', 'wordpress-seo' ),
133 ];
134
135 return $schedules;
136 }
137
138 /**
139 * Fetches the data from Ryte.
140 *
141 * @return bool Whether the request ran.
142 */
143 public function fetch_from_ryte() {
144 // Don't do anything when the WordPress environment type isn't "production".
145 if ( wp_get_environment_type() !== 'production' ) {
146 return false;
147 }
148
149 $ryte_option = $this->get_option();
150 if ( ! $ryte_option->should_be_fetched() ) {
151 return false;
152 }
153
154 $new_status = $this->request_indexability();
155
156 // Updates the timestamp in the option.
157 $ryte_option->set_last_fetch( time() );
158
159 $ryte_option->set_status( $new_status );
160 $ryte_option->save_option();
161
162 return true;
163 }
164
165 /**
166 * Retrieves the option to use.
167 *
168 * @return WPSEO_Ryte_Option The option.
169 */
170 public function get_option() {
171 return new WPSEO_Ryte_Option();
172 }
173
174 /**
175 * Sends a request to Ryte to get the indexability status.
176 *
177 * @return int The indexability status value.
178 */
179 protected function request_indexability() {
180 $parameters = [];
181 if ( $this->wordfence_protection_enabled() ) {
182 $parameters['wf_strict'] = 1;
183 }
184
185 $request = new WPSEO_Ryte_Request();
186 $response = $request->do_request( get_option( 'home' ), $parameters );
187
188 // Populate the ryte_response property.
189 $this->ryte_response = $response;
190
191 // It's a valid Ryte response because the array contains an `is_indexable` element.
192 if ( isset( $response['is_indexable'] ) ) {
193 return (int) $response['is_indexable'];
194 }
195
196 // It's not a valid Ryte response.
197 return WPSEO_Ryte_Option::CANNOT_FETCH;
198 }
199
200 /**
201 * Schedules the cronjob to get the new indexability status.
202 *
203 * @return void
204 */
205 private function schedule_cron() {
206 if ( wp_next_scheduled( 'wpseo_ryte_fetch' ) ) {
207 return;
208 }
209
210 wp_schedule_event( time(), 'weekly', 'wpseo_ryte_fetch' );
211 }
212
213 /**
214 * Unschedules the cronjob to get the new indexability status.
215 *
216 * @return void
217 */
218 private function unschedule_cron() {
219 if ( ! wp_next_scheduled( 'wpseo_ryte_fetch' ) ) {
220 return;
221 }
222
223 wp_clear_scheduled_hook( 'wpseo_ryte_fetch' );
224 }
225
226 /**
227 * Checks if WordFence protects the site against 'fake' Google crawlers.
228 *
229 * @return bool True if WordFence protects the site.
230 */
231 private function wordfence_protection_enabled() {
232 if ( ! class_exists( wfConfig::class ) ) {
233 return false;
234 }
235
236 if ( ! method_exists( wfConfig::class, 'get' ) ) {
237 return false;
238 }
239
240 return (bool) wfConfig::get( 'blockFakeBots' );
241 }
242
243 /**
244 * Retrieves the Ryte API response property.
245 *
246 * @return array|WP_Error The response or WP_Error on failure.
247 */
248 public function get_response() {
249 return $this->ryte_response;
250 }
251 }
252