This commit is contained in:
2026-04-26 23:47:49 +02:00
parent 1b95f03d1e
commit b073e009d8
5288 changed files with 1112699 additions and 55536 deletions

View File

@@ -0,0 +1,650 @@
<?php
/**
* YouTube Feed Source
*
* @since 6.0
*
* Current Connected Account Data Example
*
*/
namespace Smashballoon\Customizer;
use function SmashBalloon\YoutubeFeed\Vendor\DI\value;
/** @internal */
class Source
{
const BATCH_SIZE = 10;
/**
* @var Config
*/
private $config;
public function __construct(\Smashballoon\Customizer\Config $config)
{
$this->config = $config;
}
/**
* AJAX hooks for various feed data related functionality
*
* @since 6.0
*/
public static function hooks()
{
\add_action('wp_ajax_sbi_source_builder_update', array(self::class, 'builder_update'));
\add_action('wp_ajax_sbi_source_builder_update_multiple', array(self::class, 'builder_update_multiple'));
\add_action('wp_ajax_sbi_source_get_page', array(self::class, 'get_page'));
\add_action('wp_ajax_sbi_source_get_featured_post_preview', array(self::class, 'get_featured_post_preview'));
\add_action('wp_ajax_sbi_source_get_playlist_post_preview', array(self::class, 'get_playlist_post_preview'));
\add_action('admin_init', array(self::class, 'batch_process_legacy_source_queue'));
}
/**
* Used in an AJAX call to update sources based on selections or
* input from a user. Makes an API request to add additiona info
* about the connected source.
*
* @since 6.0
*/
public static function builder_update()
{
if (!\check_ajax_referer('sbi_admin_nonce', 'nonce', \false) && !\check_ajax_referer('sby-admin', 'nonce', \false)) {
\wp_send_json_error();
}
if (!sbi_current_user_can('manage_instagram_feed_options')) {
\wp_send_json_error();
}
$source_data = array('access_token' => \sanitize_text_field($_POST['access_token']), 'id' => \sanitize_text_field($_POST['id']), 'type' => \sanitize_text_field($_POST['type']), 'username' => isset($_POST['username']) ? \sanitize_text_field($_POST['username']) : '');
$return = sbi_connect_new_account($source_data['access_token'], $source_data['id']);
if (empty($return['error'])) {
\wp_send_json_success(\Smashballoon\Customizer\SBI_Feed_Builder::get_source_list());
}
\wp_send_json_error(array('message' => $return['error']));
}
/**
* Add our update a source from raw API data.
*
* @param $source_data
*
* @return string
*/
public static function process_connecting_source_data($source_data)
{
$connected_account = array('id' => $source_data['id'], 'user_id' => $source_data['id'], 'type' => $source_data['type'], 'account_type' => $source_data['type'], 'username' => $source_data['username'], 'access_token' => $source_data['access_token'], 'privilege' => $source_data['privilege']);
$single_source = self::update_single_source($connected_account, \false);
if (!empty($single_source['error'])) {
$message = !empty($single_source['error']['error']['message']) ? \esc_html($single_source['error']['error']['message']) : '';
$code = !empty($single_source['error']['error']['code']) ? \esc_html($single_source['error']['error']['code']) : '';
if (isset($single_source['error']['response']) && \is_wp_error($single_source['error']['response'])) {
$response = $single_source['error']['response'];
$message = \sprintf(\__('Error connecting to %s.', 'feeds-for-youtube'), $single_source['error']['url']);
if (isset($response) && isset($response->errors)) {
foreach ($response->errors as $key => $item) {
$code = $key;
$message .= $item[0];
}
}
}
$message .= ' <a href="https://smashballoon.com/instagram-feed/docs/errors/" target="_blank" rel="noopener">' . \__('Directions on how to resolve this issue', 'feeds-for-youtube') . '</a>';
$return_html = '<div class="sb-alerts-wrap"><div class="sb-alert">';
$return_html .= '<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">';
$return_html .= '<path d="M8.99935 0.666504C4.39935 0.666504 0.666016 4.39984 0.666016 8.99984C0.666016 13.5998 4.39935 17.3332 8.99935 17.3332C13.5993 17.3332 17.3327 13.5998 17.3327 8.99984C17.3327 4.39984 13.5993 0.666504 8.99935 0.666504ZM9.83268 13.1665H8.16602V11.4998H9.83268V13.1665ZM9.83268 9.83317H8.16602V4.83317H9.83268V9.83317Z" fill="#995C00"/>';
$return_html .= '</svg>';
$return_html .= '<span><strong>' . \sprintf(\__('Connection Error: %s ', 'feeds-for-youtube'), $code) . '</strong></span><br>' . $message . '</div></div>';
$return = array('success' => \false, 'message' => $return_html);
return \json_encode($return);
} else {
global $sb_instagram_posts_manager;
$sb_instagram_posts_manager->remove_error('connection');
}
$manager = new \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Data_Manager();
$manager->update_last_used();
return \json_encode(\Smashballoon\Customizer\SBI_Feed_Builder::get_source_list());
}
/**
* Used in an AJAX call to update Multiple sources based on selections or
* input from a user. Makes an API request to add additiona info
* about the connected source.
*
* @since 6.0
*/
public static function builder_update_multiple()
{
if (!\check_ajax_referer('sbi_admin_nonce', 'nonce', \false) && !\check_ajax_referer('sby-admin', 'nonce', \false)) {
\wp_send_json_error();
}
if (!sbi_current_user_can('manage_instagram_feed_options')) {
\wp_send_json_error();
}
if (isset($_POST['sourcesList']) && !empty($_POST['sourcesList']) && \is_array($_POST['sourcesList'])) {
foreach ($_POST['sourcesList'] as $single_source) {
$source_data = array('access_token' => \sanitize_text_field($single_source['access_token']), 'id' => \sanitize_text_field($single_source['id']), 'type' => \sanitize_text_field($single_source['type']), 'username' => isset($single_source['username']) ? \sanitize_text_field($single_source['username']) : '');
if ($single_source['type'] === 'business') {
$source_data['privilege'] = 'tagged';
}
if (!empty($single_source['name'])) {
$source_data['name'] = \sanitize_text_field($single_source['name']);
}
self::process_connecting_source_data($source_data);
}
}
echo \json_encode(\Smashballoon\Customizer\SBI_Feed_Builder::get_source_list());
\wp_die();
}
/**
* Get a list of sources with a limit and offset like a page
*
* @since 6.0
*/
public static function get_page()
{
if (!\check_ajax_referer('sbi_admin_nonce', 'nonce', \false) && !\check_ajax_referer('sby-admin', 'nonce', \false)) {
\wp_send_json_error();
}
if (!sbi_current_user_can('manage_instagram_feed_options')) {
\wp_send_json_error();
}
$args = array('page' => $_POST['page']);
$source_data = \Smashballoon\Customizer\SBI_Db::source_query($args);
echo \json_encode($source_data);
\wp_die();
}
/**
* Connection URLs are based on the website connecting accounts so that is
* configured here and returned
*
* @param bool $is_settings
*
* @return array
*
* @since 6.0
*/
public function get_connection_urls($is_settings = \false)
{
$urls = array();
$admin_url_state = $is_settings ? \admin_url(\sprintf('admin.php?page=%s-settings', $this->config->plugin_slug)) : \admin_url(\sprintf('admin.php?page=%s-feed-builder', $this->config->plugin_slug));
//If the admin_url isn't returned correctly then use a fallback
if ($admin_url_state === \sprintf('/wp-admin/admin.php?page=%s-feed-builder', $this->config->plugin_slug) || $admin_url_state === \sprintf('/wp-admin/admin.php?page=%s-feed-builder&tab=configuration', $this->config->plugin_slug)) {
$admin_url_state = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
}
#$urls['personal'] ='https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER . '&state=';
#$urls['business'] = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER . '&state=';
$urls['personal'] = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER;
$urls['business'] = 'https://connect.smashballoon.com/auth/ig/?wordpress_user=&v=pro&vn=' . SBYVER;
$urls['stateURL'] = $admin_url_state;
return $urls;
}
/**
* Used as a listener for the account connection process. If
* data is returned from the account connection processed it's used
* to generate the list of possible sources to chose from.
*
* @return array|bool
*
* @since 6.0
*/
public static function maybe_source_connection_data()
{
if (isset($_GET['sbi_access_token']) && isset($_GET['sbi_graph_api'])) {
$return = self::retrieve_available_business_accounts();
return $return;
} elseif (isset($_GET['sbi_access_token']) && isset($_GET['sbi_account_type'])) {
$return = self::retrieve_available_personal_accounts();
return $return;
}
return \false;
}
/**
* Uses the Instagram Basic Display API to get available personal
* accounts
*
* @return array|bool
*
* @since 6.0
*/
public static function retrieve_available_personal_accounts()
{
$encryption = new \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Data_Encryption();
$return = array('type' => 'personal', 'unconnectedAccounts' => array(), 'matchingExistingAccounts' => array(), 'didQuickUpdate' => \false);
$access_token = \sanitize_text_field($_GET['sbi_access_token']);
if (empty($access_token)) {
return array();
}
$user_id = \sanitize_text_field($_GET['sbi_id']);
$user_name = \sanitize_text_field($_GET['sbi_username']);
$expires_in = (int) $_GET['sbi_expires_in'];
$expires_timestamp = \time() + $expires_in;
$source_data = array('access_token' => $access_token, 'id' => $user_id, 'user_id' => $user_id, 'type' => 'basic', 'username' => $user_name, 'privilege' => '', 'expires' => \date('Y-m-d H:i:s', $expires_timestamp));
$connection = new \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_API_Connect($source_data, 'header', array());
$connection->connect();
$header_details = '{}';
$source_data['error'] = '';
if (!$connection->is_wp_error() && !$connection->is_instagram_error()) {
$header_details_array = $connection->get_data();
$header_details_array = self::merge_account_details($header_details_array, $source_data);
$source_data['username'] = $header_details_array['username'];
$header_details = \json_encode($header_details_array);
} else {
$source_data['error'] = $connection;
if ($connection->is_wp_error()) {
$page_error = $connection->get_wp_error();
if (!empty($page_error) && isset($page_error['response']->errors)) {
$error_message = '';
foreach ($page_error['response']->errors as $key => $item) {
$error_message .= $key . ': ' . $item[0] . ' ';
}
return array('error' => array('code' => 'HTTP Request', 'message' => $error_message, 'details' => $error_message));
}
} else {
$error = $connection->get_data();
return array('error' => array('code' => $error['error']['code'], 'message' => $error['error']['message'], 'details' => $error['error']['message']));
}
}
$source_data['info'] = $header_details;
$return['unconnectedAccounts'][] = $source_data;
$args = array('id' => $user_id);
$results = \Smashballoon\Customizer\SBI_Db::source_query($args);
$already_connected_as_business_account = isset($results[0]) && $results[0]['account_type'] === 'business';
$matches_existing_personal = isset($results[0]) && $results[0]['account_type'] === 'personal';
if ($already_connected_as_business_account) {
$return['matchingExistingAccounts'] = $results[0];
$instagram_account_data = \json_decode($encryption->decrypt($results[0]['info']), \true);
$return['matchingExistingAccounts']['avatar'] = isset($instagram_account_data['profile_picture_url']) ? $instagram_account_data['profile_picture_url'] : \false;
$return['notice'] = \__('The Instagram account you are logged into is already connected as a "business" account. Remove the business account if you\'d like to connect as a basic account instead (not recommended).', 'feeds-for-youtube');
} elseif ($matches_existing_personal) {
$return['matchingExistingAccounts'] = $results[0];
self::update_or_insert($source_data);
$return['notice'] = '';
$return['didQuickUpdate'] = \true;
} else {
self::update_or_insert($source_data);
$return['didQuickUpdate'] = \true;
}
return $return;
}
/**
* Uses the Facebook API to retrieve a list of business accounts
*
* @return array|bool
*
* @since 6.0
*/
public static function retrieve_available_business_accounts()
{
$return = array('type' => 'business', 'unconnectedAccounts' => array(), 'matchingExistingAccounts' => array(), 'didQuickUpdate' => \false);
$access_token = sbi_maybe_clean(\urldecode($_GET['sbi_access_token']));
if (empty($access_token)) {
return array();
}
$url = 'https://graph.facebook.com/me/accounts?fields=instagram_business_account,access_token&limit=500&access_token=' . $access_token;
$args = array('timeout' => 60);
$result = \wp_remote_get($url, $args);
$pages_data = '{}';
if (!\is_wp_error($result)) {
$pages_data = $result['body'];
} else {
$page_error = $result;
}
if (isset($page_error) && isset($page_error->errors)) {
$error_message = '';
foreach ($page_error->errors as $key => $item) {
$error_message .= $key . ': ' . $item[0] . ' ';
}
return array('error' => array('code' => 'HTTP Request', 'message' => \__('Your server could not complete a remote request to Facebook\'s API. Your host may be blocking access or there may be a problem with your server.', 'feeds-for-youtube'), 'details' => $error_message));
}
$pages_data_arr = \json_decode($pages_data, \true);
if (empty($pages_data_arr['data'])) {
return array('error' => array('code' => 'No Accounts Found', 'message' => \__('Couldn\'t find Business Profile', 'feeds-for-youtube'), 'details' => \sprintf(\__('Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the %1$sFacebook account%2$s in this browser which is associated with your Instagram Business Profile.', 'feeds-for-youtube'), '<a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">', '</a>')));
}
$user_url = 'https://graph.facebook.com/me?fields=name,id,picture&access_token=' . $access_token;
$args = array('timeout' => 60);
$result = \wp_remote_get($user_url, $args);
if (!\is_wp_error($result)) {
$user_data = $result['body'];
$user_data_arr = \json_decode($user_data, \true);
$return['user'] = $user_data_arr;
}
$return['numFound'] = \count($pages_data_arr['data']);
foreach ($pages_data_arr['data'] as $page_data) {
if (isset($page_data['instagram_business_account'])) {
$instagram_business_id = $page_data['instagram_business_account']['id'];
$page_access_token = isset($page_data['access_token']) ? $page_data['access_token'] : '';
$instagram_account_url = 'https://graph.facebook.com/' . $instagram_business_id . '?fields=name,username,profile_picture_url&access_token=' . $access_token;
$args = array('timeout' => 60);
$result = \wp_remote_get($instagram_account_url, $args);
if (!\is_wp_error($result)) {
$instagram_account_info = $result['body'];
$instagram_account_data = \json_decode($instagram_account_info, \true);
$instagram_biz_img = isset($instagram_account_data['profile_picture_url']) ? $instagram_account_data['profile_picture_url'] : \false;
$source_data = array('access_token' => $access_token, 'id' => $instagram_business_id, 'user_id' => $instagram_business_id, 'type' => 'business', 'username' => $instagram_account_data['username'], 'avatar' => $instagram_biz_img, 'privilege' => 'tagged');
$source_data['info'] = \json_encode($instagram_account_data);
$return['unconnectedAccounts'][] = $source_data;
$args = array('id' => $instagram_business_id);
$results = \Smashballoon\Customizer\SBI_Db::source_query($args);
$already_connected_as_business_account = isset($results[0]) && $results[0]['account_type'] === 'business';
$matches_existing_personal = isset($results[0]) && $results[0]['account_type'] === 'personal';
if ($already_connected_as_business_account) {
self::update_or_insert($source_data);
} elseif ($matches_existing_personal && $return['numFound'] === 1) {
$return['didQuickUpdate'] = \true;
self::update_or_insert($source_data);
}
} else {
$page_error = $result;
}
}
}
if (empty($return['unconnectedAccounts'])) {
return array('error' => array('code' => 'No Accounts Found', 'message' => \__('Couldn\'t find Business Profile', 'feeds-for-youtube'), 'details' => \sprintf(\__('Uh oh. It looks like this Facebook account is not currently connected to an Instagram Business profile. Please check that you are logged into the %1$sFacebook account%2$s in this browser which is associated with your Instagram Business Profile. If you are, in fact, logged-in to the correct account please make sure you have Instagram accounts connected with your Facebook account by following %3$sthis FAQ%4$s', 'feeds-for-youtube'), '<a href="https://www.facebook.com/" target="_blank" rel="noopener noreferrer">', '</a>', '<a href="https://smashballoon.com/reconnecting-an-instagram-business-profile/" target="_blank" rel="noopener noreferrer">', '</a>')));
}
return $return;
}
/**
* Used to update or insert connected accounts (sources)
*
* @param array $source_data
*
* @return bool
*
* @since 6.0
*/
public static function update_or_insert($source_data)
{
if (!isset($source_data['id'])) {
return \false;
}
if (isset($source_data['info'])) {
// data from an API request related to the source is saved as a JSON string
if (\is_object($source_data['info']) || \is_array($source_data['info'])) {
$source_data['info'] = \json_encode($source_data['info']);
}
}
if (self::exists_in_database($source_data)) {
$source_data['last_updated'] = \date('Y-m-d H:i:s');
self::update($source_data, \false);
} else {
if (!isset($source_data['access_token'])) {
return \false;
}
self::insert($source_data);
}
return \true;
}
/**
* Whether or not the source exists in the database
*
* @param array $args
*
* @return bool
*
* @since 6.0
*/
public static function exists_in_database($args)
{
$results = \Smashballoon\Customizer\SBI_Db::source_query($args);
return isset($results[0]);
}
/**
* Add a new source as a row in the sbi_sources table
*
* @param array $source_data
*
* @return false|int
*
* @since 6.0
*/
public static function insert($source_data)
{
if (isset($source_data['name'])) {
$source_data['username'] = $source_data['name'];
}
$data = $source_data;
return \Smashballoon\Customizer\SBI_Db::source_insert($data);
}
/**
* Update info in rows that match the source data
*
* @param array $source_data
*
* @return false|int
*
* @since 6.0
*/
public static function update($source_data, $where_privilige = \true)
{
$where = array('id' => $source_data['id']);
unset($source_data['id']);
if ($where_privilige && isset($source_data['privilege'])) {
$where['privilege'] = $source_data['privilege'];
}
// usernames are more common in the other plugins so
// that is the name of the column that is used as the
// page or group "name" data
if (isset($source_data['name'])) {
$source_data['username'] = $source_data['name'];
}
$data = $source_data;
return \Smashballoon\Customizer\SBI_Db::source_update($data, $where);
}
/**
* Creates a queue of connected accounts that need to be added to
* the sources table
*
* @since 6.0
*/
public static function set_legacy_source_queue()
{
$sbi_statuses_option = \get_option('sbi_statuses', array());
$options = \get_option('sb_instagram_settings', array());
$connected_accounts = isset($options['connected_accounts']) ? $options['connected_accounts'] : array();
$sbi_statuses_option['legacy_source_queue'] = \array_chunk(\array_keys($connected_accounts), self::BATCH_SIZE);
\update_option('sbi_statuses', $sbi_statuses_option);
return $sbi_statuses_option['legacy_source_queue'];
}
/**
* Whether or not there are still sources in the queue and
* this isn't disabled
*
* @return bool
*
* @since 6.0
*/
public static function should_do_source_updates()
{
$sbi_statuses_option = \get_option('sbi_statuses', array());
$should_do_source_updates = isset($sbi_statuses_option['legacy_source_queue']) ? !empty($sbi_statuses_option['legacy_source_queue']) : \false;
return \apply_filters('should_do_source_updates', $should_do_source_updates);
}
/**
* Processes one set of connected accounts
*
* @since 6.0
*/
public static function batch_process_legacy_source_queue()
{
if (!self::should_do_source_updates()) {
return;
}
$sbi_statuses_option = \get_option('sbi_statuses', array());
$batch = \array_shift($sbi_statuses_option['legacy_source_queue']);
\update_option('sbi_statuses', $sbi_statuses_option);
// updated early just in case there is a fatal error
if (empty($batch)) {
return;
}
$options = \get_option('sb_instagram_settings', array());
$connected_accounts = isset($options['connected_accounts']) ? $options['connected_accounts'] : array();
foreach ($batch as $account_key) {
$connected_account = isset($connected_accounts[$account_key]) ? $connected_accounts[$account_key] : \false;
if ($connected_account) {
self::update_single_source($connected_account);
}
}
return $sbi_statuses_option['legacy_source_queue'];
}
/**
* Transfer data from a connected account to the sources table
* after it's been validated with an API call
*
* @param array $connected_account
* @param bool $connect_if_error
*
* @return array
*
* @since 6.0
*/
public static function update_single_source($connected_account, $connect_if_error = \true)
{
$account_type = isset($connected_account['account_type']) ? $connected_account['account_type'] : 'business';
$connection = new \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_API_Connect($connected_account, 'header', array());
$connection->connect();
if (isset($connected_account['privilege']) && $connected_account['privilege'] === 'tagged') {
$connected_account['use_tagged'] = \true;
}
$source_data = array('access_token' => $connected_account['access_token'], 'id' => $connected_account['user_id'], 'type' => $account_type, 'username' => $connected_account['username'], 'privilege' => !empty($connected_account['use_tagged']) ? 'tagged' : '');
if (!empty($connected_account['expires_timestamp'])) {
$source_data['expires'] = \date('Y-m-d H:i:s', $connected_account['expires_timestamp']);
}
if ($connected_account['local_avatar']) {
\SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Connected_Account::update_local_avatar_status($connected_account['username'], \true);
}
$header_details = '{}';
$source_data['error'] = '';
if (!$connection->is_wp_error() && !$connection->is_instagram_error()) {
$header_details_array = $connection->get_data();
$header_details_array = self::merge_account_details($header_details_array, $connected_account);
$cdn_avatar_url = \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Parse::get_avatar($header_details_array, array(), \true);
if (!empty($cdn_avatar_url)) {
$created = \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Connected_Account::create_local_avatar($header_details_array['username'], $cdn_avatar_url);
\SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Connected_Account::update_local_avatar_status($header_details_array['username'], $created);
}
$source_data['username'] = $header_details_array['username'];
$header_details = \json_encode($header_details_array);
} else {
$source_data['error'] = $connection;
if ($connection->is_wp_error()) {
$source_data['error'] = $connection->get_wp_error();
} else {
$source_data['error'] = $connection->get_data();
}
}
$source_data['info'] = $header_details;
if (!empty($connected_account['private'])) {
$source_data['info']['private'] = $connected_account['private'];
}
if (empty($source_data['error']) || $connect_if_error) {
self::update_or_insert($source_data);
}
$source_data['record_id'] = 0;
$source_data['account_id'] = $connected_account['user_id'];
$source_data['account_type'] = $account_type;
return $source_data;
}
/**
* Creates a source from the access token and
* source ID saved in 3.x settings
*
* @since 6.0
*/
public static function update_source_from_legacy_settings()
{
// not needed
}
public static function merge_account_details($header_details_array, $connected_account)
{
$header_details_array['local_avatar'] = !empty($connected_account['local_avatar']);
$header_details_array['name'] = !empty($connected_account['name']) ? $connected_account['name'] : '{}';
$header_details_array['page_access_token'] = !empty($connected_account['page_access_token']) ? $connected_account['page_access_token'] : '';
return $header_details_array;
}
/**
* If the plugin is still updating legacy sources this function
* can be used to udpate a single source if needed before
* the update is done.
*
* @param string $slug_or_id
*
* @return array|bool
*/
public static function maybe_one_off_connected_account_update($slug_or_id)
{
if (!self::should_do_source_updates()) {
return \false;
}
$connected_accounts = (array) \json_decode(\stripcslashes(\get_option('sbi_connected_accounts')), \true);
$connected_account = isset($connected_accounts[$slug_or_id]) ? $connected_accounts[$slug_or_id] : \false;
if ($connected_account) {
return self::update_single_source($connected_account);
}
return \false;
}
/**
* Clears the "error" column in the sbi_sources table for a specific
* account
*
* @param string $account_id
*
* @return bool
*
* @since 6.0
*/
public static function clear_error($account_id)
{
$source_data = array('id' => $account_id, 'error' => '');
return self::update_or_insert($source_data);
}
/**
* Adds an error to the error table by account ID
*
* @param string $account_id
* @param string|object|array $error
*
* @return bool
*
* @since 6.0
*/
public static function add_error($account_id, $error)
{
$source_data = array('id' => $account_id, 'error' => \is_string($error) ? $error : \json_encode($error));
return self::update_or_insert($source_data);
}
/**
* Uses query results from the sbi_sources table to convert them
* into connected account data and return them as a connected account
* array as would be used in versions 5.x and below
*
* @param array $source_data
*
* @return array
*
* @since 6.0
*/
public static function convert_sources_to_connected_accounts($source_data)
{
$encryption = new \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Data_Encryption();
$connected_accounts = array();
foreach ($source_data as $source_datum) {
$info = !empty($source_datum['info']) ? \json_decode($encryption->decrypt($source_datum['info']), \true) : array();
$settings = array('gdpr' => 'no');
$avatar = \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Parse::get_avatar($info, $settings, \true);
$connected_account = array('id' => $source_datum['account_id'], 'user_id' => $source_datum['account_id'], 'type' => $source_datum['account_type'], 'account_type' => $source_datum['account_type'], 'username' => $source_datum['username'], 'access_token' => sbi_maybe_clean($source_datum['access_token']), 'privilege' => $source_datum['privilege'], 'expires_timestamp' => \strtotime($source_datum['expires']), 'is_valid' => empty($source_datum['error']), 'profile_picture' => $avatar, 'last_checked' => isset($source_datum['last_updated']) ? \strtotime($source_datum['last_updated']) : \time());
if (!empty($info['private'])) {
$connected_account['private'] = $info['private'];
}
$connected_account['local_avatar_url'] = \SmashBalloon\YoutubeFeed\Vendor\SB_Instagram_Connected_Account::maybe_local_avatar($source_datum['username'], $avatar);
$connected_accounts[$source_datum['account_id']] = $connected_account;
}
return $connected_accounts;
}
/**
* Returns a batch of accounts that have expiring access tokens
*
* @return array|bool
*
* @since 6.0
*/
public static function get_expiring()
{
$args = array('expiring' => \true);
$results = \Smashballoon\Customizer\SBI_Db::source_query($args);
return $results;
}
}