PluginProbe
Social Media Auto Poster – Schedule & Publish to Buffer / 6.2.5
Social Media Auto Poster – Schedule & Publish to Buffer v6.2.5
6.2.5 6.2.4 6.2.3 6.2.2 6.2.1 6.2.0 6.1.2 6.1.1 6.1.0 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 6.0.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 All 126 releases
wp-to-buffer / lib / social / includes / class-settings.php

class-settings.php in Social Media Auto Poster – Schedule & Publish to Buffer 6.2.5, at lib/social/includes/class-settings.php

993 lines 28.7 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 WPZinc\Social
6 * @author WP Zinc
7 */
8
9 namespace WPZinc\Social;
10
11 /**
12 * Handles reading and writing settings.
13 *
14 * @package WPZinc\Social
15 * @author WP Zinc
16 * @version 3.0.0
17 */
18 class Settings {
19
20 /**
21 * Holds the class object.
22 *
23 * @since 3.1.4
24 *
25 * @var object
26 */
27 public static $instance;
28
29 /**
30 * Holds the base object.
31 *
32 * @since 3.4.7
33 *
34 * @var object
35 */
36 public $base;
37
38 /**
39 * Constructor
40 *
41 * @since 3.4.7
42 *
43 * @param object $base Base Plugin Class.
44 */
45 public function __construct( $base ) {
46
47 // Store base class.
48 $this->base = $base;
49
50 }
51
52 /**
53 * Retrieves a setting from the options table.
54 *
55 * Safely checks if the key(s) exist before returning the default
56 * or the value.
57 *
58 * @since 3.0.0
59 *
60 * @param string $type Setting Type.
61 * @param string $key Setting key value to retrieve.
62 * @param string $default_value Default Value.
63 * @return string Value/Default Value
64 */
65 public function get_setting( $type, $key, $default_value = '' ) {
66
67 // Get settings.
68 $settings = $this->get_settings( $type );
69
70 // Convert string to keys.
71 $keys = explode( '][', $key );
72
73 foreach ( $keys as $count => $key ) {
74 // Cleanup key.
75 $key = trim( $key, '[]' );
76
77 // Check if key exists.
78 if ( ! isset( $settings[ $key ] ) ) {
79 return $default_value;
80 }
81
82 // Key exists - make settings the value (which could be an array or the final value)
83 // of this key.
84 $settings = $settings[ $key ];
85 }
86
87 // If here, setting exists.
88 // This will be a non-array value.
89 return $settings;
90
91 }
92
93 /**
94 * Returns the settings for the given Post Type
95 *
96 * @since 3.0.0
97 *
98 * @param string $type Type.
99 * @return array Settings
100 */
101 public function get_settings( $type ) {
102
103 // Get current settings.
104 $settings = get_option( $this->base->plugin->settingsName . '-' . $type );
105
106 /**
107 * Filters Post Type Settings before they are returned.
108 *
109 * @since 3.0.0
110 *
111 * @param array $settings Settings.
112 * @param string $type Post Type.
113 */
114 $settings = apply_filters( $this->base->plugin->filter_name . '_get_settings', $settings, $type );
115
116 // Return result.
117 return $settings;
118
119 }
120
121 /**
122 * Stores the given settings for the given Post Type into the options table
123 *
124 * @since 3.0.0
125 *
126 * @param string $type Type.
127 * @param array $settings Settings.
128 * @return mixed array (error) | bool (success)
129 */
130 public function update_settings( $type, $settings ) {
131
132 // Get old settings.
133 $existing_settings = $this->get_settings( $type );
134
135 // Iterate through array of Post Type Settings to strip HTML tags.
136 $settings = $this->strip_tags_deep( $settings );
137
138 /**
139 * Filters Post Type Settings before they are saved.
140 *
141 * @since 3.0.0
142 *
143 * @param array $settings Settings.
144 * @param string $type Post Type.
145 * @param array $existing_settings Existing Settings.
146 */
147 $settings = apply_filters( $this->base->plugin->filter_name . '_update_settings', $settings, $type, $existing_settings );
148
149 // Save.
150 $result = $this->update_option( $type, $settings );
151
152 // If update_option failed, either no settings were changed, or they were changeed but the DB collation is wrong.
153 if ( ! $result ) {
154 // Check if the existing and new settings differ i.e. the user actually made a change.
155 if ( md5( maybe_serialize( $existing_settings ) ) !== md5( maybe_serialize( $settings ) ) ) {
156 // Settings were changed, but could not be saved using update_option.
157 // Check the DB collation.
158 if ( ! $this->base->get_class( 'common' )->is_table_charset_and_collation_correct( 'options', 'utf8mb4' ) ) {
159 return new \WP_Error(
160 $this->base->plugin->filter_name . '_settings_update_settings_db_collation_error',
161 sprintf(
162 /* translators: %1$s: Documentation URL */
163 __( 'Unable to save settings due to an invalid database collation and charset on the options table. Please refer to the <a href="%1$s" target="_blank">Documentation</a>.', 'wp-to-buffer' ),
164 'https://www.wpzinc.com/documentation/wordpress-buffer-pro/debugging-issues/#unable-to-save-settings-due-to-an-invalid-database-collation-and-charset-on-the-options-table'
165 ),
166 );
167 }
168
169 // No changes were made to the settings.
170 return new \WP_Error(
171 $this->base->plugin->filter_name . '_settings_update_settings_no_changes',
172 __( 'Unable to save settings due to an error. Please try again.', 'wp-to-buffer' )
173 );
174 }
175 }
176
177 // Check for duplicate statuses.
178 $duplicates = $this->base->get_class( 'validation' )->check_for_duplicates( $settings );
179 if ( is_array( $duplicates ) ) {
180 // Fetch Post Type Name, Profile Name and Action Name.
181 $post_type_object = get_post_type_object( $type );
182
183 // Determine the Profile Name for the duplicate.
184 if ( $duplicates['profile_id'] === 'default' ) {
185 $profile = __( 'Defaults', 'wp-to-buffer' );
186 } else {
187 // Fetch connected Profiles, keyed by Profile ID.
188 $profiles = array();
189 foreach ( $this->get_accounts() as $account_id => $account ) {
190 $this->base->get_class( 'api' )->set_tokens( $account['access_token'], $account['refresh_token'], $account['token_expires'] );
191 $account_profiles = $this->base->get_class( 'api' )->profiles( false, $account_id );
192 if ( is_wp_error( $account_profiles ) ) {
193 continue;
194 }
195 foreach ( $account_profiles as $account_profile ) {
196 $profiles[ $account_profile['id'] ] = $account_profile;
197 }
198 }
199
200 // Use the Profile's formatted name if found, else the Profile ID.
201 $profile = ( isset( $profiles[ $duplicates['profile_id'] ] )
202 ? $profiles[ $duplicates['profile_id'] ]['formatted_service'] . ': ' . $profiles[ $duplicates['profile_id'] ]['formatted_username']
203 : $duplicates['profile_id'] );
204 }
205 $post_actions = $this->base->get_class( 'common' )->get_post_actions();
206 $action = $post_actions[ $duplicates['action'] ];
207
208 // Return error object.
209 return new \WP_Error(
210 $this->base->plugin->filter_name . '_settings_update_settings_duplicates',
211 sprintf(
212 /* translators: %1$s: Post Type Name, Plural, %2$s: Social Media Profile Name, %3$s: Action (Publish, Update, Repost, Bulk Publish), %4$s: Social Media Service Name (Buffer, Hootsuite) */
213 __( 'Two or more statuses defined in %1$s > %2$s > %3$s are the same. Please correct this to ensure each status update is unique, otherwise your status updates will NOT publish to %4$s as they will be seen as duplicates, which violate Facebook and Twitter\'s Terms of Service.', 'wp-to-buffer' ),
214 $post_type_object->label,
215 $profile,
216 $action,
217 $this->base->plugin->account
218 )
219 );
220 }
221
222 // No duplicate statuses found.
223 return true;
224
225 }
226
227 /**
228 * Strip HTML tags from the given array or string.
229 *
230 * @since 4.8.9
231 *
232 * @param string|array $value Setting value.
233 * @return ($value is array ? array : string) Setting value
234 */
235 private function strip_tags_deep( $value ) {
236
237 return is_array( $value ) ? array_map( array( $this, 'strip_tags_deep' ), $value ) : wp_strip_all_tags( $value );
238
239 }
240
241 /**
242 * Returns an array of default settings for a new installation.
243 *
244 * @since 3.4.0
245 *
246 * @param string $post_type Post Type.
247 * @return array Settings
248 */
249 public function default_installation_settings( $post_type ) {
250
251 // Define default settings.
252 $settings = array(
253 'default' => array(
254 'publish' => array(
255 'enabled' => 1,
256 'status' => array(
257 $this->get_default_status( $post_type, 'New ' . ucfirst( $post_type ) . ': {title}', $this->base->plugin->default_schedule ),
258 ),
259 ),
260 'update' => array(
261 'enabled' => 1,
262 'status' => array(
263 $this->get_default_status( $post_type, 'Updated ' . ucfirst( $post_type ) . ': {title}', $this->base->plugin->default_schedule ),
264 ),
265 ),
266 ),
267 );
268
269 /**
270 * Filters Default Post Type Settings used on Plugin Activation before they are returned.
271 *
272 * @since 3.4.0
273 *
274 * @param array $settings Settings.
275 */
276 $settings = apply_filters( $this->base->plugin->filter_name . '_default_installation_settings', $settings );
277
278 // Return.
279 return $settings;
280
281 }
282
283 /**
284 * Merges the given status array with the default status array,
285 * to ensure that the returned status has all expected keys
286 *
287 * @since 4.4.0
288 *
289 * @param array $status Status.
290 * @param string $post_type Post Type.
291 * @return array Status
292 */
293 public function get_status( $status, $post_type ) {
294
295 return array_merge( $this->get_default_status( $post_type, false, $this->base->plugin->default_schedule ), $status );
296
297 }
298
299 /**
300 * Returns value => label key/value arrays for Authors and Taxonomies,
301 * so that selectize instances can be populated with both labels and their values
302 *
303 * @since 4.4.0
304 *
305 * @param array $status Status.
306 * @param string $post_type Post Type.
307 * @return array Labels
308 */
309 public function get_status_value_labels( $status, $post_type ) {
310
311 $labels = array(
312 'authors' => array(),
313 );
314
315 // Authors.
316 if ( $status['authors'] !== false && $status['authors'] !== '' ) {
317 foreach ( $status['authors'] as $index => $user_id ) {
318 // Get user.
319 $user = get_user_by( 'id', absint( $user_id ) );
320
321 // Remove setting if the user no longer exists.
322 if ( ! $user ) {
323 unset( $status['authors'][ $index ] );
324 continue;
325 }
326
327 // Add label.
328 $labels['authors'][ $index ] = array(
329 'id' => $user_id,
330 'text' => $user->user_login,
331 );
332 }
333 }
334
335 // Taxonomies.
336 $taxonomies = $this->base->get_class( 'common' )->get_taxonomies( $post_type );
337 if ( is_array( $taxonomies ) && count( $taxonomies ) > 0 ) {
338 foreach ( $taxonomies as $taxonomy => $details ) {
339 $labels[ $taxonomy ] = array();
340
341 // Skip if conditions don't exist for this Taxonomy.
342 if ( ! isset( $status['terms'][ $taxonomy ] ) ) {
343 continue;
344 }
345 if ( ! is_array( $status['terms'][ $taxonomy ] ) ) {
346 continue;
347 }
348 if ( ! count( $status['terms'][ $taxonomy ] ) ) {
349 continue;
350 }
351
352 // Term(s) exist.
353 foreach ( $status['terms'][ $taxonomy ] as $index => $term_id ) {
354 // Get Term.
355 $term = get_term_by( 'id', absint( $term_id ), $taxonomy );
356
357 // Remove setting if the Term no longer exists.
358 if ( ! $term ) {
359 unset( $status['terms'][ $taxonomy ][ $index ] );
360 continue;
361 }
362
363 // Add label.
364 $labels[ $taxonomy ][ $index ] = array(
365 'id' => $term_id,
366 'text' => $term->name,
367 );
368 }
369 }
370 }
371
372 // Return.
373 return $labels;
374
375 }
376
377 /**
378 * Returns an array of a status' information that can be output in
379 * the table row cells
380 *
381 * @since 4.4.0
382 *
383 * @param array $status Status.
384 * @param string $post_type Post Type.
385 * @param string $action Action (publish,update,repost,bulk_publish).
386 * @return array Table Row Cell Status (message, image, schedule)
387 */
388 public function get_status_row( $status, $post_type, $action ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
389
390 // Get Options.
391 $featured_image_options = $this->base->get_class( 'image' )->get_status_image_options( false, $post_type );
392 $schedule = $this->base->get_class( 'common' )->get_schedule_options( $post_type, true );
393
394 // Define row.
395 return array(
396 'message' => ( ( strlen( $status['message'] ) > 100 ) ? substr( $status['message'], 0, 100 ) . '...' : $status['message'] ),
397 'post_type' => $status['post_type'],
398 'schedule' => $schedule[ $status['schedule'] ],
399 );
400
401 }
402
403 /**
404 * Returns a default status array
405 *
406 * @since 4.4.0
407 *
408 * @param string $post_type Post Type.
409 * @param mixed $default_message Default Message (if false, uses {title} {url}).
410 * @param string $default_schedule Default Schedule.
411 * @return array Status
412 */
413 public function get_default_status( $post_type, $default_message = false, $default_schedule = 'immediate' ) {
414
415 // Get Taxonomies supported by this Post Type.
416 $conditions = array();
417 $terms = array();
418 foreach ( $this->base->get_class( 'common' )->get_taxonomies( $post_type ) as $taxonomy => $object ) {
419 $conditions[ $taxonomy ] = '';
420 $terms[ $taxonomy ] = array();
421 }
422
423 // Define skeleton status to be used for new statuses.
424 $status = array(
425 // All Profiles.
426 'post_type' => 'link',
427 'message' => ( ! $default_message ? '{title}' : $default_message ),
428 'first_comment' => '',
429 'url' => '{url}',
430 'schedule' => $default_schedule,
431 'image' => 'featured_image',
432 'image_additional' => '',
433 'image_additional_limit' => '',
434 'days' => 0,
435 'hours' => 0,
436 'minutes' => 0,
437 'schedule_relative_day' => '',
438 'schedule_relative_time' => '00:00:00',
439 'schedule_custom_field_name' => '',
440 'schedule_custom_field_relation' => 'after',
441 'schedule_tec_relation' => 'after',
442 'schedule_specific' => '',
443
444 // Text to Image.
445 'text_to_image' => '',
446
447 // Profiles: Pinterest.
448 'pinterest' => array(
449 'board' => '',
450 'title' => '{title}',
451 ),
452
453 // Profiles: Google Business.
454 'googlebusiness' => array(
455 'post_type' => 'whats_new', // whats_new, offer, event.
456
457 // What's New, Event.
458 'cta' => '', // book,order,shop,learn_more,signup.
459
460 // Offer, Event.
461 'start_date_option' => 'custom',
462 'start_date' => '',
463 'end_date_option' => 'custom',
464 'end_date' => '',
465 'title' => '',
466
467 // Offer.
468 'code' => '',
469 'terms' => '',
470 ),
471
472 // Post Conditions.
473 'post_title' => array(
474 'compare' => 0,
475 'value' => '',
476 ),
477 'post_excerpt' => array(
478 'compare' => 0,
479 'value' => '',
480 ),
481 'post_content' => array(
482 'compare' => 0,
483 'value' => '',
484 ),
485 'start_date' => array(
486 'month' => '',
487 'day' => '',
488 ),
489 'end_date' => array(
490 'month' => '',
491 'day' => '',
492 ),
493
494 // Author Conditions.
495 'authors' => false,
496 'authors_compare' => '=',
497 'authors_roles' => false,
498 'authors_roles_compare' => '=',
499
500 // Taxonomy Conditions.
501 'conditions' => $conditions,
502 'terms' => $terms,
503
504 // Custom Field Conditions.
505 'custom_fields' => array(),
506 );
507
508 /**
509 * Returns a skeleton status object for the given action, used when defining new status(es)
510 *
511 * @since 4.4.0
512 *
513 * @param array $status Status.
514 */
515 $status = apply_filters( $this->base->plugin->filter_name . '_settings_get_default_status', $status );
516
517 // Return.
518 return $status;
519
520 }
521
522 /**
523 * Helper method to determine whether the given Post Type has at least
524 * one social media account enabled, and there is a publish or update
525 * action enabled in the Defaults for the Post Type or the Social Media account.
526 *
527 * @since 3.4.0
528 *
529 * @param string $post_type Post Type.
530 * @return bool Enabled
531 */
532 public function is_post_type_enabled( $post_type ) {
533
534 // Get Settings for Post Type.
535 $settings = $this->get_settings( $post_type );
536
537 // If no settings, bail.
538 if ( ! $settings ) {
539 return false;
540 }
541
542 /**
543 * Default Publish or Update enabled
544 * 1+ Profiles enabled without override
545 */
546 $default_publish_action_enabled = $this->get_setting( $post_type, '[default][publish][enabled]', '0' );
547 $default_update_action_enabled = $this->get_setting( $post_type, '[default][update][enabled]', '0' );
548 if ( $default_publish_action_enabled || $default_update_action_enabled ) {
549 foreach ( $settings as $profile_id => $profile_settings ) {
550 // Skip defaults.
551 if ( $profile_id === 'default' ) {
552 continue;
553 }
554
555 // Profile enabled, no override.
556 if ( isset( $profile_settings['enabled'] ) && $profile_settings['enabled'] ) {
557 if ( ! isset( $profile_settings['override'] ) || ! $profile_settings['override'] ) {
558 // Post Type is enabled with Defaults + 1+ Profile not using override settings.
559 return true;
560 }
561 }
562 }
563 }
564
565 /**
566 * 1+ Profiles enabled with override and publish / update enabled
567 */
568 foreach ( $settings as $profile_id => $profile_settings ) {
569 // Skip defaults.
570 if ( $profile_id === 'default' ) {
571 continue;
572 }
573
574 // Skip if profile not enabled.
575 if ( ! isset( $profile_settings['enabled'] ) || ! $profile_settings['enabled'] ) {
576 continue;
577 }
578
579 // Skip if override not enabled.
580 if ( ! isset( $profile_settings['override'] ) || ! $profile_settings['override'] ) {
581 continue;
582 }
583
584 // Profile action enabled.
585 if ( isset( $profile_settings['publish']['enabled'] ) && $profile_settings['publish']['enabled'] == '1' ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
586 // Post Type is enabled with 1+ Profile with override and publish enabled.
587 return true;
588 }
589 if ( isset( $profile_settings['update']['enabled'] ) && $profile_settings['update']['enabled'] == '1' ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
590 // Post Type is enabled with 1+ Profile with override and update enabled.
591 return true;
592 }
593 if ( isset( $profile_settings['repost']['enabled'] ) && $profile_settings['repost']['enabled'] == '1' ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
594 // Post Type is enabled with 1+ Profile with override and repost enabled.
595 return true;
596 }
597 if ( isset( $profile_settings['bulk_publish']['enabled'] ) && $profile_settings['bulk_publish']['enabled'] == '1' ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual
598 // Post Type is enabled with 1+ Profile with override and bulk publish enabled.
599 return true;
600 }
601 }
602
603 // If here, Post Type can't be sent to the API.
604 return false;
605
606 }
607
608 /**
609 * Returns all accounts and their access token, refresh token and token expiry values.
610 *
611 * @since 5.4.0
612 *
613 * @return array
614 */
615 public function get_accounts() {
616
617 return get_option( $this->base->plugin->settingsName . '-accounts', array() );
618
619 }
620
621 /**
622 * Checks if at least one account is connected.
623 *
624 * @since 5.4.0
625 *
626 * @return bool
627 */
628 public function account_connected() {
629
630 $accounts = $this->get_accounts();
631 return ! empty( $accounts );
632
633 }
634
635 /**
636 * Stores the given account, including its credentials.
637 *
638 * @since 3.5.0
639 *
640 * @param string $access_token Access Token.
641 * @param string $refresh_token Refresh Token.
642 * @param bool|int $token_expires Token Expires (false | timestamp).
643 * @param string $account_id Account ID.
644 * @param string $account_name Account Name.
645 * @param string $account_email Account Email.
646 * @param int $account_channel_limit Account Channel Limit.
647 * @param string $plan Plan Name.
648 * @param array $profile_ids Profile IDs.
649 */
650 public function update_account( $access_token = '', $refresh_token = '', $token_expires = false, $account_id = 'default', $account_name = 'Default', $account_email = '', $account_channel_limit = 0, $plan = 'free', $profile_ids = array() ) {
651
652 // Get existing accounts.
653 $accounts = $this->get_accounts();
654
655 // Update account.
656 $accounts[ $account_id ] = array(
657 'id' => $account_id,
658 'name' => $account_name,
659 'email' => $account_email,
660 'channel_limit' => $account_channel_limit,
661 'plan' => $plan,
662 'access_token' => $access_token,
663 'refresh_token' => $refresh_token,
664 'token_expires' => $token_expires,
665 'profile_ids' => $profile_ids,
666 );
667
668 // Update the accounts.
669 update_option( $this->base->plugin->settingsName . '-accounts', $accounts, false );
670
671 }
672
673 /**
674 * Updates the credentials for the given account ID.
675 *
676 * @since 6.0.0
677 *
678 * @param string $access_token Access Token.
679 * @param string $refresh_token Refresh Token.
680 * @param bool|int $token_expires Token Expires (false | timestamp).
681 * @param string $account_id Account ID.
682 */
683 public function update_account_credentials( $access_token, $refresh_token, $token_expires = false, $account_id = 'default' ) {
684
685 // Get existing accounts.
686 $accounts = $this->get_accounts();
687
688 // If the account doesn't exist, bail.
689 if ( ! isset( $accounts[ $account_id ] ) ) {
690 return;
691 }
692
693 // Update the account credentials.
694 $accounts[ $account_id ]['access_token'] = $access_token;
695 $accounts[ $account_id ]['refresh_token'] = $refresh_token;
696 $accounts[ $account_id ]['token_expires'] = $token_expires;
697
698 // Update the accounts.
699 update_option( $this->base->plugin->settingsName . '-accounts', $accounts, false );
700
701 }
702
703 /**
704 * Clears the stored tokens for the account holding the given refresh token.
705 * Keyed on the refresh token, so a token already rotated by another request won't match.
706 *
707 * @since 6.2.5
708 *
709 * @param string $refresh_token Refresh Token that was rejected.
710 * @return bool Whether an account was cleared.
711 */
712 public function clear_account_credentials_by_refresh_token( $refresh_token ) {
713
714 if ( empty( $refresh_token ) ) {
715 return false;
716 }
717
718 $accounts = $this->get_accounts();
719 foreach ( $accounts as $account_id => $account ) {
720 if ( $account['refresh_token'] !== $refresh_token ) {
721 continue;
722 }
723
724 // Clear tokens so the dead token stops being presented and the Reconnect button shows.
725 $accounts[ $account_id ]['access_token'] = '';
726 $accounts[ $account_id ]['refresh_token'] = '';
727 $accounts[ $account_id ]['token_expires'] = 0;
728
729 // Update the accounts.
730 update_option( $this->base->plugin->settingsName . '-accounts', $accounts, false );
731 return true;
732 }
733
734 return false;
735
736 }
737
738 /**
739 * Updates the information for the given account ID.
740 *
741 * @since 6.0.0
742 *
743 * @param string $account_id Account ID.
744 * @param string $account_name Account Name.
745 * @param string $account_email Account Email.
746 * @param int $account_channel_limit Account Channel Limit.
747 * @param string $plan Plan Name.
748 * @param array $profile_ids Profile IDs.
749 */
750 public function update_account_information( $account_id = 'default', $account_name = 'Default', $account_email = '', $account_channel_limit = 0, $plan = 'free', $profile_ids = array() ) {
751
752 // Get existing accounts.
753 $accounts = $this->get_accounts();
754
755 // If the account doesn't exist, bail.
756 if ( ! isset( $accounts[ $account_id ] ) ) {
757 return;
758 }
759
760 // Update the account information.
761 $accounts[ $account_id ]['name'] = $account_name;
762 $accounts[ $account_id ]['plan'] = $plan;
763 $accounts[ $account_id ]['email'] = $account_email;
764 $accounts[ $account_id ]['channel_limit'] = $account_channel_limit;
765 $accounts[ $account_id ]['profile_ids'] = $profile_ids;
766
767 // Update the accounts.
768 update_option( $this->base->plugin->settingsName . '-accounts', $accounts, false );
769
770 }
771
772 /**
773 * Stores the given profile IDs against the given account ID.
774 *
775 * @since 5.4.7
776 *
777 * @param string $account_id Account ID.
778 * @param array $profile_ids Profile IDs.
779 */
780 public function update_account_profile_ids( $account_id, $profile_ids ) {
781
782 // Get existing accounts.
783 $accounts = $this->get_accounts();
784
785 // If the account doesn't exist, bail.
786 if ( ! isset( $accounts[ $account_id ] ) ) {
787 return;
788 }
789
790 // Update the account profile IDs.
791 $accounts[ $account_id ]['profile_ids'] = $profile_ids;
792
793 // Update the accounts.
794 update_option( $this->base->plugin->settingsName . '-accounts', $accounts, false );
795
796 }
797
798 /**
799 * Deletes the access, refresh and token expiry values for the specified account ID.
800 *
801 * @since 3.5.0
802 *
803 * @param string $account_id Account ID.
804 * @return bool
805 */
806 public function delete_account( $account_id = 'default' ) {
807
808 // Get existing accounts.
809 $accounts = $this->get_accounts();
810
811 // Delete the account.
812 unset( $accounts[ $account_id ] );
813
814 // Delete the stored profiles for this account.
815 delete_option( $this->base->plugin->name . '-profiles-' . $account_id );
816
817 // Update the accounts.
818 return update_option( $this->base->plugin->settingsName . '-accounts', $accounts, false );
819
820 }
821
822 /**
823 * Retrieves the account IDs for the given access token.
824 *
825 * @since 6.0.1
826 *
827 * @param string $access_token Access Token.
828 * @return array
829 */
830 public function get_account_ids_by_access_token( $access_token ) {
831
832 $account_ids = array();
833
834 // Get existing accounts.
835 $accounts = $this->get_accounts();
836
837 // Iterate through accounts to find the account that contains the given access token.
838 foreach ( $accounts as $account_id => $account ) {
839 if ( $account['access_token'] === $access_token ) {
840 $account_ids[] = $account_id;
841 }
842 }
843
844 return $account_ids;
845
846 }
847
848 /**
849 * Retrieves the access token for the given profile ID.
850 *
851 * @since 5.4.0
852 *
853 * @param string $profile_id Profile ID.
854 * @return string
855 */
856 public function get_access_token_by_profile_id( $profile_id = '' ) {
857
858 // Get existing accounts.
859 $accounts = $this->get_accounts();
860
861 // Iterate through accounts to find the account that contains the given profile ID.
862 foreach ( $accounts as $account ) {
863 if ( in_array( $profile_id, $account['profile_ids'], true ) ) {
864 return $account['access_token'];
865 }
866 }
867
868 return '';
869
870 }
871
872 /**
873 * Retrieves the refresh token for the given profile ID.
874 *
875 * @since 5.4.0
876 *
877 * @param string $profile_id Profile ID.
878 * @return string
879 */
880 public function get_refresh_token_by_profile_id( $profile_id = '' ) {
881
882 // Get existing accounts.
883 $accounts = $this->get_accounts();
884
885 // Iterate through accounts to find the account that contains the given profile ID.
886 foreach ( $accounts as $account ) {
887 if ( in_array( $profile_id, $account['profile_ids'], true ) ) {
888 return $account['refresh_token'];
889 }
890 }
891
892 return '';
893
894 }
895
896 /**
897 * Retrieves the access token for the given profile ID.
898 *
899 * @since 5.4.0
900 *
901 * @param string $profile_id Profile ID.
902 * @return string
903 */
904 public function get_token_expires_by_profile_id( $profile_id = '' ) {
905
906 // Get existing accounts.
907 $accounts = $this->get_accounts();
908
909 // Iterate through accounts to find the account that contains the given profile ID.
910 foreach ( $accounts as $account ) {
911 if ( in_array( $profile_id, $account['profile_ids'], true ) ) {
912 return $account['token_expires'];
913 }
914 }
915
916 return '';
917
918 }
919
920 /**
921 * Helper method to get a value from the options table
922 *
923 * @since 3.0.0
924 *
925 * @param string $key Option Key.
926 * @param string $default_value Default Value if key does not exist.
927 * @return string Option Value
928 */
929 public function get_option( $key, $default_value = '' ) {
930
931 $result = get_option( $this->base->plugin->settingsName . '-' . $key );
932 if ( ! $result ) {
933 return $default_value;
934 }
935
936 return $result;
937
938 }
939
940 /**
941 * Helper method to store a value to the options table
942 *
943 * @since 3.0.0
944 *
945 * @param string $key Key.
946 * @param string|array $value Value.
947 * @return bool Success
948 */
949 public function update_option( $key, $value ) {
950
951 // Depending on the key, perform some validation before saving.
952 switch ( $key ) {
953 /**
954 * Custom Tags
955 * - Remove duplicate keys.
956 */
957 case 'custom_tags':
958 // Skip validation if there are no custom field key/values to validate.
959 if ( ! is_array( $value ) || count( $value ) === 0 ) {
960 break;
961 }
962
963 foreach ( $value as $post_type => $custom_tags ) {
964 // Remove duplicate keys.
965 $value[ $post_type ]['key'] = array_unique( array_filter( $custom_tags['key'] ) );
966
967 // Iterate through labels, removing them if there is now no key.
968 foreach ( $custom_tags['label'] as $label_key => $label ) {
969 if ( ! isset( $value[ $post_type ]['key'][ $label_key ] ) ) {
970 unset( $value[ $post_type ]['label'][ $label_key ] );
971 }
972 }
973 }
974 break;
975 }
976
977 /**
978 * Filters the key and value pair before saving to the options table.
979 *
980 * @since 3.0.0
981 *
982 * @param string $value Option Value.
983 * @param string $key Option Key.
984 */
985 $value = apply_filters( $this->base->plugin->filter_name . '_update_option', $value, $key );
986
987 // Update.
988 return update_option( $this->base->plugin->settingsName . '-' . $key, $value );
989
990 }
991
992 }
993