PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 27.6
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v27.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 / watchers / addon-update-watcher.php

addon-update-watcher.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 27.6, at src/integrations/watchers/addon-update-watcher.php

230 lines 7.1 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\Watchers;
4
5 use Yoast\WP\SEO\Conditionals\Admin_Conditional;
6 use Yoast\WP\SEO\Integrations\Integration_Interface;
7
8 /**
9 * Enables Yoast add-on auto updates when Yoast SEO is enabled and the other way around.
10 *
11 * Also removes the auto-update toggles from the Yoast SEO add-ons.
12 */
13 class Addon_Update_Watcher implements Integration_Interface {
14
15 /**
16 * ID string used by WordPress to identify the free plugin.
17 *
18 * @var string
19 */
20 public const WPSEO_FREE_PLUGIN_ID = 'wordpress-seo/wp-seo.php';
21
22 /**
23 * A list of Yoast add-on identifiers.
24 *
25 * @var string[]
26 */
27 public const ADD_ON_PLUGIN_FILES = [
28 'wordpress-seo-premium/wp-seo-premium.php',
29 'wpseo-video/video-seo.php',
30 'wpseo-local/local-seo.php', // When installing Local through a released zip, the path is different from the path on a dev environment.
31 'wpseo-woocommerce/wpseo-woocommerce.php',
32 'wpseo-news/wpseo-news.php',
33 'acf-content-analysis-for-yoast-seo/yoast-acf-analysis.php', // When installing ACF for Yoast through a released zip, the path is different from the path on a dev environment.
34 ];
35
36 /**
37 * Registers the hooks.
38 *
39 * @return void
40 */
41 public function register_hooks() {
42 \add_action( 'add_site_option_auto_update_plugins', [ $this, 'call_toggle_auto_updates_with_empty_array' ], 10, 2 );
43 \add_action( 'update_site_option_auto_update_plugins', [ $this, 'toggle_auto_updates_for_add_ons' ], 10, 3 );
44 \add_filter( 'plugin_auto_update_setting_html', [ $this, 'replace_auto_update_toggles_of_addons' ], 10, 2 );
45 \add_action( 'activated_plugin', [ $this, 'maybe_toggle_auto_updates_for_new_install' ] );
46 }
47
48 /**
49 * Returns the conditionals based on which this loadable should be active.
50 *
51 * @return string[] The conditionals.
52 */
53 public static function get_conditionals() {
54 return [ Admin_Conditional::class ];
55 }
56
57 /**
58 * Replaces the auto-update toggle links for the Yoast add-ons
59 * with a text explaining that toggling the Yoast SEO auto-update setting
60 * automatically toggles the one for the setting for the add-ons as well.
61 *
62 * @param string $old_html The old HTML.
63 * @param string $plugin The plugin.
64 *
65 * @return string The new HTML, with the auto-update toggle link replaced.
66 */
67 public function replace_auto_update_toggles_of_addons( $old_html, $plugin ) {
68 if ( ! \is_string( $old_html ) ) {
69 return $old_html;
70 }
71
72 $not_a_yoast_addon = ! \in_array( $plugin, self::ADD_ON_PLUGIN_FILES, true );
73
74 if ( $not_a_yoast_addon ) {
75 return $old_html;
76 }
77
78 $auto_updated_plugins = \get_site_option( 'auto_update_plugins' );
79
80 if ( $this->are_auto_updates_enabled( self::WPSEO_FREE_PLUGIN_ID, $auto_updated_plugins ) ) {
81 return \sprintf(
82 '<em>%s</em>',
83 \sprintf(
84 /* Translators: %1$s resolves to Yoast SEO. */
85 \esc_html__( 'Auto-updates are enabled based on this setting for %1$s.', 'wordpress-seo' ),
86 'Yoast SEO',
87 ),
88 );
89 }
90
91 return \sprintf(
92 '<em>%s</em>',
93 \sprintf(
94 /* Translators: %1$s resolves to Yoast SEO. */
95 \esc_html__( 'Auto-updates are disabled based on this setting for %1$s.', 'wordpress-seo' ),
96 'Yoast SEO',
97 ),
98 );
99 }
100
101 /**
102 * Handles the situation where the auto_update_plugins option did not previously exist.
103 *
104 * @param string $option The name of the option that is being created.
105 * @param array|mixed $value The new (and first) value of the option that is being created.
106 *
107 * @return void
108 */
109 public function call_toggle_auto_updates_with_empty_array( $option, $value ) {
110 if ( $option !== 'auto_update_plugins' ) {
111 return;
112 }
113
114 $this->toggle_auto_updates_for_add_ons( $option, $value, [] );
115 }
116
117 /**
118 * Enables premium auto updates when free are enabled and the other way around.
119 *
120 * @param string $option The name of the option that has been updated.
121 * @param array $new_value The new value of the `auto_update_plugins` option.
122 * @param array $old_value The old value of the `auto_update_plugins` option.
123 *
124 * @return void
125 */
126 public function toggle_auto_updates_for_add_ons( $option, $new_value, $old_value ) {
127 if ( $option !== 'auto_update_plugins' ) {
128 // If future versions of WordPress change this filter's behavior, our behavior should stay consistent.
129 return;
130 }
131
132 if ( ! \is_array( $old_value ) || ! \is_array( $new_value ) ) {
133 return;
134 }
135
136 $auto_updates_are_enabled = $this->are_auto_updates_enabled( self::WPSEO_FREE_PLUGIN_ID, $new_value );
137 $auto_updates_were_enabled = $this->are_auto_updates_enabled( self::WPSEO_FREE_PLUGIN_ID, $old_value );
138
139 if ( $auto_updates_are_enabled === $auto_updates_were_enabled ) {
140 // Auto-updates for Yoast SEO have stayed the same, so have neither been enabled or disabled.
141 return;
142 }
143
144 $auto_updates_have_been_enabled = $auto_updates_are_enabled && ! $auto_updates_were_enabled;
145
146 if ( $auto_updates_have_been_enabled ) {
147 $this->enable_auto_updates_for_addons( $new_value );
148 return;
149 }
150 else {
151 $this->disable_auto_updates_for_addons( $new_value );
152 return;
153 }
154
155 if ( ! $auto_updates_are_enabled ) {
156 return;
157 }
158
159 $auto_updates_have_been_removed = false;
160 foreach ( self::ADD_ON_PLUGIN_FILES as $addon ) {
161 if ( ! $this->are_auto_updates_enabled( $addon, $new_value ) ) {
162 $auto_updates_have_been_removed = true;
163 break;
164 }
165 }
166
167 if ( $auto_updates_have_been_removed ) {
168 $this->enable_auto_updates_for_addons( $new_value );
169 }
170 }
171
172 /**
173 * Trigger a change in the auto update detection whenever a new Yoast addon is activated.
174 *
175 * @param string $plugin The plugin that is activated.
176 *
177 * @return void
178 */
179 public function maybe_toggle_auto_updates_for_new_install( $plugin ) {
180 $not_a_yoast_addon = ! \in_array( $plugin, self::ADD_ON_PLUGIN_FILES, true );
181
182 if ( $not_a_yoast_addon ) {
183 return;
184 }
185
186 $enabled_auto_updates = \get_site_option( 'auto_update_plugins' );
187 $this->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] );
188 }
189
190 /**
191 * Enables auto-updates for all addons.
192 *
193 * @param string[] $auto_updated_plugins The current list of auto-updated plugins.
194 *
195 * @return void
196 */
197 protected function enable_auto_updates_for_addons( $auto_updated_plugins ) {
198 $plugins = \array_unique( \array_merge( $auto_updated_plugins, self::ADD_ON_PLUGIN_FILES ) );
199 \update_site_option( 'auto_update_plugins', $plugins );
200 }
201
202 /**
203 * Disables auto-updates for all addons.
204 *
205 * @param string[] $auto_updated_plugins The current list of auto-updated plugins.
206 *
207 * @return void
208 */
209 protected function disable_auto_updates_for_addons( $auto_updated_plugins ) {
210 $plugins = \array_values( \array_diff( $auto_updated_plugins, self::ADD_ON_PLUGIN_FILES ) );
211 \update_site_option( 'auto_update_plugins', $plugins );
212 }
213
214 /**
215 * Checks whether auto updates for a plugin are enabled.
216 *
217 * @param string $plugin_id The plugin ID.
218 * @param array $auto_updated_plugins The array of auto updated plugins.
219 *
220 * @return bool Whether auto updates for a plugin are enabled.
221 */
222 protected function are_auto_updates_enabled( $plugin_id, $auto_updated_plugins ) {
223 if ( $auto_updated_plugins === false || ! \is_array( $auto_updated_plugins ) ) {
224 return false;
225 }
226
227 return \in_array( $plugin_id, $auto_updated_plugins, true );
228 }
229 }
230