PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
jetpack / jetpack_vendor / automattic / jetpack-publicize / src / jetpack-social-settings / class-settings.php

class-settings.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-beta, at jetpack_vendor/automattic/jetpack-publicize/src/jetpack-social-settings/class-settings.php

497 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Settings class.
4 *
5 * @package automattic/jetpack-publicize
6 */
7
8 namespace Automattic\Jetpack\Publicize\Jetpack_Social_Settings;
9
10 use Automattic\Jetpack\Modules;
11 use Automattic\Jetpack\Publicize\Social_Image_Generator\Templates;
12
13 /**
14 * This class is used to get and update Jetpack_Social_Settings.
15 * Currently supported features:
16 * - Social Image Generator
17 * - UTM Settings
18 * - Social Notes
19 *
20 * @phan-constructor-used-for-side-effects
21 */
22 class Settings {
23 /**
24 * Name of the database option.
25 *
26 * @var string
27 */
28 const OPTION_PREFIX = 'jetpack_social_';
29 const IMAGE_GENERATOR_SETTINGS = 'image_generator_settings';
30
31 const DEFAULT_IMAGE_GENERATOR_SETTINGS = array(
32 'enabled' => false,
33 'template' => Templates::DEFAULT_TEMPLATE,
34 );
35
36 const UTM_SETTINGS = 'utm_settings';
37
38 const DEFAULT_UTM_SETTINGS = array(
39 'enabled' => false,
40 );
41
42 const NOTES_CONFIG = 'notes_config';
43
44 const DEFAULT_NOTES_CONFIG = array(
45 'append_link' => true,
46 );
47
48 const MESSAGE_TEMPLATE = 'message_template';
49
50 /**
51 * Default global message template.
52 */
53 const DEFAULT_MESSAGE_TEMPLATE = "{title}\n\n{excerpt}\n\n{url}";
54
55 /**
56 * Storage cap for message templates, in characters. Real-world templates are a few hundred characters at most.
57 */
58 const MESSAGE_TEMPLATE_MAX_LENGTH = 8000;
59
60 // Legacy named options.
61 const JETPACK_SOCIAL_NOTE_CPT_ENABLED = 'jetpack-social-note';
62 const JETPACK_SOCIAL_SHOW_PRICING_PAGE = 'jetpack-social_show_pricing_page';
63 const NOTES_FLUSH_REWRITE_RULES_FLUSHED = 'jetpack_social_rewrite_rules_flushed';
64
65 /**
66 * Whether the actions have been hooked into.
67 *
68 * @var bool
69 */
70 protected static $actions_hooked_in = false;
71
72 /**
73 * Constructor.
74 */
75 public function __construct() {
76
77 if ( ! self::$actions_hooked_in ) {
78 add_action( 'rest_api_init', array( $this, 'register_settings' ) );
79 add_action( 'admin_init', array( $this, 'register_settings' ) );
80
81 self::$actions_hooked_in = true;
82 }
83 }
84
85 /**
86 * Migrate old options to the new settings. Previously SIG settings were stored in the
87 * jetpack_social_image_generator_settings option. Now they are stored in the jetpack_social_settings.
88 *
89 * TODO: Work out if this is possible on plugin upgrade
90 *
91 * @return void
92 */
93 private function migrate_old_option() {
94 // Delete the old options if they exist.
95 if ( get_option( 'jetpack_social_settings' ) ) {
96 delete_option( 'jetpack_social_settings' );
97 }
98 if ( get_option( 'jetpack_social_autoconvert_images' ) ) {
99 delete_option( 'jetpack_social_autoconvert_images' );
100 }
101
102 $sig_settings = get_option( 'jetpack_social_image_generator_settings' );
103 // If the option is not set, we don't need to migrate.
104 if ( false === $sig_settings ) {
105 return;
106 }
107
108 $enabled = false;
109 $template = Templates::DEFAULT_TEMPLATE;
110
111 if ( isset( $sig_settings['defaults']['template'] ) ) {
112 $template = $sig_settings['defaults']['template'];
113 }
114
115 if ( isset( $sig_settings['enabled'] ) ) {
116 $enabled = $sig_settings['enabled'];
117 }
118
119 if ( ! isset( $sig_settings['template'] ) ) {
120 update_option(
121 self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS,
122 array(
123 'enabled' => $enabled,
124 'template' => $template,
125 )
126 );
127 }
128 }
129
130 /**
131 * Register the settings.
132 *
133 * @return void
134 */
135 public function register_settings() {
136
137 register_setting(
138 'jetpack_social',
139 self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS,
140 array(
141 'type' => 'object',
142 'default' => array(
143 'enabled' => false,
144 'template' => Templates::DEFAULT_TEMPLATE,
145 ),
146 'show_in_rest' => array(
147 'schema' => array(
148 'type' => 'object',
149 'properties' => array(
150 'enabled' => array(
151 'type' => 'boolean',
152 ),
153 'template' => array(
154 'type' => 'string',
155 ),
156 'font' => array(
157 'type' => 'string',
158 ),
159 'default_image_id' => array(
160 'type' => 'number',
161 ),
162 ),
163 ),
164 ),
165 )
166 );
167
168 register_setting(
169 'jetpack_social',
170 self::OPTION_PREFIX . self::UTM_SETTINGS,
171 array(
172 'type' => 'boolean',
173 'default' => array(
174 'enabled' => false,
175 ),
176 'show_in_rest' => array(
177 'schema' => array(
178 'type' => 'object',
179 'properties' => array(
180 'enabled' => array(
181 'type' => 'boolean',
182 ),
183 ),
184 ),
185 ),
186 )
187 );
188
189 register_setting(
190 'jetpack_social',
191 self::JETPACK_SOCIAL_SHOW_PRICING_PAGE,
192 array(
193 'type' => 'boolean',
194 'default' => true,
195 'show_in_rest' => array(
196 'schema' => array(
197 'type' => 'boolean',
198 ),
199 ),
200 )
201 );
202
203 register_setting(
204 'jetpack_social',
205 self::JETPACK_SOCIAL_NOTE_CPT_ENABLED,
206 array(
207 'type' => 'boolean',
208 'default' => false,
209 'show_in_rest' => array(
210 'schema' => array(
211 'type' => 'boolean',
212 ),
213 ),
214 )
215 );
216
217 register_setting(
218 'jetpack_social',
219 self::OPTION_PREFIX . self::NOTES_CONFIG,
220 array(
221 'type' => 'object',
222 'default' => self::DEFAULT_NOTES_CONFIG,
223 'show_in_rest' => array(
224 'schema' => array(
225 'type' => 'object',
226 'context' => array( 'view', 'edit' ),
227 'properties' => array(
228 'append_link' => array(
229 'type' => 'boolean',
230 ),
231 'link_format' => array(
232 'type' => 'string',
233 'enum' => array( 'full_url', 'shortlink', 'permashortcitation' ),
234 ),
235 ),
236 ),
237 ),
238 )
239 );
240
241 register_setting(
242 'jetpack_social',
243 self::OPTION_PREFIX . self::MESSAGE_TEMPLATE,
244 array(
245 'type' => 'string',
246 'default' => self::DEFAULT_MESSAGE_TEMPLATE,
247 'sanitize_callback' => array( __CLASS__, 'sanitize_message_template' ),
248 'show_in_rest' => array(
249 'schema' => array(
250 'type' => 'string',
251 'context' => array( 'view', 'edit' ),
252 ),
253 ),
254 )
255 );
256
257 add_filter( 'rest_pre_update_setting', array( $this, 'update_settings' ), 10, 3 );
258 }
259
260 /**
261 * Sanitize a user-authored message template string.
262 *
263 * @param mixed $value The raw setting input. Non-string values coerce to ''.
264 * @return string The sanitised template.
265 */
266 public static function sanitize_message_template( $value ) {
267 if ( ! is_string( $value ) ) {
268 return '';
269 }
270
271 $value = sanitize_textarea_field( $value );
272
273 if ( mb_strlen( $value, 'UTF-8' ) > self::MESSAGE_TEMPLATE_MAX_LENGTH ) {
274 $value = mb_substr( $value, 0, self::MESSAGE_TEMPLATE_MAX_LENGTH, 'UTF-8' );
275 }
276
277 return $value;
278 }
279
280 /**
281 * Get the image generator settings.
282 *
283 * @return array
284 */
285 public function get_image_generator_settings() {
286 return get_option( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS, self::DEFAULT_IMAGE_GENERATOR_SETTINGS );
287 }
288
289 /**
290 * Get if the UTM params is enabled.
291 *
292 * @return array
293 */
294 public function get_utm_settings() {
295 return get_option( self::OPTION_PREFIX . self::UTM_SETTINGS, self::DEFAULT_UTM_SETTINGS );
296 }
297
298 /**
299 * Get the global message template.
300 *
301 * @return string
302 */
303 public function get_message_template() {
304 return (string) get_option( self::OPTION_PREFIX . self::MESSAGE_TEMPLATE, self::DEFAULT_MESSAGE_TEMPLATE );
305 }
306
307 /**
308 * Get the social notes config.
309 *
310 * @return array The social notes config.
311 */
312 public function get_social_notes_config() {
313 return get_option( self::OPTION_PREFIX . self::NOTES_CONFIG, self::DEFAULT_NOTES_CONFIG );
314 }
315
316 /**
317 * Check if the pricing page should be displayed.
318 *
319 * @return bool
320 */
321 public static function should_show_pricing_page() {
322 return (bool) get_option( self::JETPACK_SOCIAL_SHOW_PRICING_PAGE, true );
323 }
324
325 /**
326 * Get if the social notes feature is enabled.
327 *
328 * @return bool
329 */
330 public function is_social_notes_enabled() {
331 return (bool) get_option( self::JETPACK_SOCIAL_NOTE_CPT_ENABLED, false );
332 }
333
334 /**
335 * Get the current settings.
336 *
337 * @param bool $with_available Whether to include the available status of the features.
338 *
339 * @return array
340 */
341 public function get_settings( $with_available = false ) {
342 $this->migrate_old_option();
343
344 $settings = array(
345 'socialImageGeneratorSettings' => $this->get_image_generator_settings(),
346 );
347
348 // The feature cannot be enabled without Publicize.
349 if ( ! ( new Modules() )->is_active( 'publicize' ) ) {
350 $settings['socialImageGeneratorSettings']['enabled'] = false;
351 }
352
353 if ( $with_available ) {
354 $settings['socialImageGeneratorSettings']['available'] = $this->is_sig_available();
355 }
356
357 return $settings;
358 }
359
360 /**
361 * Get the initial state.
362 * Deprecated method, stub left here to avoid fatal.
363 *
364 * @deprecated 0.62.0
365 */
366 public function get_initial_state() {
367 return array();
368 }
369
370 /**
371 * Update the settings.
372 *
373 * @param bool $updated The updated settings.
374 * @param string $name The name of the setting.
375 * @param mixed $value The value of the setting.
376 *
377 * @return bool
378 */
379 public function update_settings( $updated, $name, $value ) {
380
381 // Social Image Generator.
382 if ( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS === $name ) {
383 return $this->update_social_image_generator_settings( $value );
384 }
385
386 // UTM Settings.
387 if ( self::OPTION_PREFIX . self::UTM_SETTINGS === $name ) {
388 $current_utm_settings = $this->get_utm_settings();
389
390 if ( empty( $current_utm_settings ) || ! is_array( $current_utm_settings ) ) {
391 $current_utm_settings = self::DEFAULT_UTM_SETTINGS;
392 }
393
394 return update_option( self::OPTION_PREFIX . self::UTM_SETTINGS, array_replace_recursive( $current_utm_settings, $value ) );
395 }
396
397 // Social Notes.
398 if ( self::JETPACK_SOCIAL_NOTE_CPT_ENABLED === $name ) {
399 // Delete this option, so the rules get flushed in maybe_flush_rewrite_rules when the CPT is registered.
400 delete_option( self::NOTES_FLUSH_REWRITE_RULES_FLUSHED );
401 return update_option( self::JETPACK_SOCIAL_NOTE_CPT_ENABLED, (bool) $value );
402 }
403 if ( self::OPTION_PREFIX . self::NOTES_CONFIG === $name ) {
404 $old_config = $this->get_social_notes_config();
405 $new_config = array_merge( $old_config, $value );
406 return update_option( self::OPTION_PREFIX . self::NOTES_CONFIG, $new_config );
407 }
408
409 if ( self::JETPACK_SOCIAL_SHOW_PRICING_PAGE === $name ) {
410 return update_option( self::JETPACK_SOCIAL_SHOW_PRICING_PAGE, (int) $value );
411 }
412
413 return $updated;
414 }
415
416 /**
417 * Update the social image generator settings.
418 *
419 * @param array $new_setting The new settings.
420 *
421 * @return bool
422 */
423 public function update_social_image_generator_settings( $new_setting ) {
424 $this->migrate_old_option();
425 $sig_settings = get_option( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS );
426
427 if ( empty( $sig_settings ) || ! is_array( $sig_settings ) ) {
428 $sig_settings = self::DEFAULT_IMAGE_GENERATOR_SETTINGS;
429 }
430
431 return update_option( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS, array_replace_recursive( $sig_settings, $new_setting ) );
432 }
433
434 /**
435 * Check if SIG is available.
436 *
437 * @return bool True if SIG is available, false otherwise.
438 */
439 public function is_sig_available() {
440 global $publicize;
441
442 if ( ! $publicize ) {
443 return false;
444 }
445
446 return $publicize->has_social_image_generator_feature();
447 }
448
449 /**
450 * Get the default template.
451 *
452 * @return string
453 */
454 public function sig_get_default_template() {
455 $this->migrate_old_option();
456 $sig_settings = get_option( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS );
457 if ( empty( $sig_settings ) || ! is_array( $sig_settings ) ) {
458 $sig_settings = self::DEFAULT_IMAGE_GENERATOR_SETTINGS;
459 }
460 return $sig_settings['template'];
461 }
462
463 /**
464 * Get the default image ID.
465 *
466 * @return int
467 */
468 public function sig_get_default_image_id() {
469 $this->migrate_old_option();
470 $sig_settings = get_option( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS );
471 if ( empty( $sig_settings ) || ! is_array( $sig_settings ) ) {
472 return 0;
473 }
474
475 if ( isset( $sig_settings['default_image_id'] ) ) {
476 return $sig_settings['default_image_id'];
477 }
478
479 return 0;
480 }
481
482 /**
483 * Get the default font.
484 *
485 * @return string
486 */
487 public function sig_get_default_font() {
488 $this->migrate_old_option();
489 $sig_settings = get_option( self::OPTION_PREFIX . self::IMAGE_GENERATOR_SETTINGS );
490 if ( empty( $sig_settings ) || ! is_array( $sig_settings ) ) {
491 return '';
492 }
493
494 return $sig_settings['font'] ?? '';
495 }
496 }
497