';
} else if ( $notification['id'] === 'review' || $notification['id'] === 'discount' ) {
$image_html = sprintf(
'
',
SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] )
);
} else {
$image_html = '
';
$img_src = SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] );
$image_html .= '
';
if ( isset( $notification['image_overlay'] ) ) {
$image_html .= '
'. esc_html( str_replace( '%', '%%', $notification['image_overlay'] ) ).'
';
}
}
$image_html .= '
';
}
// Check if it's review notice then show step #1
if ( $type == 'review' ) {
$step1_img = SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] );
$step1_img_html = sprintf('
', $step1_img);
$review_consent = get_option( 'sbi_review_consent' );
$sbi_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=instagram-lite';
// step #1 for the review notice
if ( ! $review_consent ) {
$step1_btns = sprintf(
'
%s ',
__( 'Yes', 'instagram-feed' )
);
$step1_btns .= sprintf(
'
%s ',
$sbi_open_feedback_url,
__( 'No', 'instagram-feed' )
);
$notifications_html .= sprintf(
'
' . $step1_img_html . '
%1$s
%2$s
',
__( 'Are you enjoying the Instagram Feed Plugin?', 'instagram-feed' ),
$step1_btns,
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0
);
}
}
$review_consent = get_option( 'sbi_review_consent' );
$review_step2_style = '';
if ( $type == 'review' && ! $review_consent ) {
$review_step2_style = 'style="display: none;"';
}
// Build the notification HTML for review notice
if ( $type == 'review' ) {
$notifications_html .= sprintf(
'
' . $image_html . '
%1$s
%2$s
%3$s
',
__( 'Glad to hear you are enjoying it. Would you consider leaving a positive review?', 'instagram-feed' ),
__( 'It really helps to support the plugin and help others to discover it too!', 'instagram-feed' ),
$buttons_html,
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
$current_class,
( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : '',
( $type == 'review' ) ? 'rn_step_2' : ''
);
} else if ( $type == 'discount' ) {
// Build the notification HTML for discount notice
$notifications_html .= sprintf(
'
' . $image_html . '
%1$s
%2$s
%3$s
',
__( 'Exclusive offer - 60% off!', 'instagram-feed' ),
__( 'We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free Instagram Feed.', 'instagram-feed' ),
$buttons_html,
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
$current_class,
( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : '',
( $type == 'review' && ! $review_consent ) ? 'rn_step_2' : ''
);
} else {
// Notification HTML for other notices
$notifications_html .= sprintf(
'
' . $image_html . '
%1$s
%2$s
%3$s
',
! empty( $notification['title'] ) ? $this->replace_merge_fields( sanitize_text_field( $notification['title'] ), $notification ) : '',
! empty( $notification['content'] ) ? wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags ) : '',
$buttons_html,
! empty( $notification['id'] ) ? esc_attr( sanitize_text_field( $notification['id'] ) ) : 0,
$current_class,
( $notification['id'] == 'review' && ! empty( $review_step2_style ) ) ? $review_step2_style : ''
);
}
// Only first notification is current.
$current_class = '';
}
$close_href = wp_nonce_url( add_query_arg( array( 'sbi_dismiss' => $type ) ), 'sbi-' . $type, 'sbi_nonce' );
$type_class = '';
if ( $type === 'review' || $type == 'discount' ) {
$type_class = $type === 'review' ? 'sbi_review_notice' : 'sbi_discount_notice';
}
?>
has_access() || empty( $_POST['id'] ) ) {
wp_send_json_error();
}
$id = sanitize_text_field( wp_unslash( $_POST['id'] ) );
if ( $id === 'review' ) {
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
update_option( 'sbi_rating_notice', 'dismissed', false );
$sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
update_option( 'sbi_statuses', $sbi_statuses_option, false );
} elseif ( $id === 'discount' ) {
update_user_meta( get_current_user_id(), 'sbi_ignore_new_user_sale_notice', 'always' );
$current_month_number = (int)date('n', sbi_get_current_time() );
$not_early_in_the_year = ($current_month_number > 5);
if ( $not_early_in_the_year ) {
update_user_meta( get_current_user_id(), 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
}
}
$option = $this->get_option();
$type = is_numeric( $id ) ? 'feed' : 'events';
$option['dismissed'][] = $id;
$option['dismissed'] = array_unique( $option['dismissed'] );
// Remove notification.
if ( is_array( $option[ $type ] ) && ! empty( $option[ $type ] ) ) {
foreach ( $option[ $type ] as $key => $notification ) {
if ( $notification['id'] == $id ) { // phpcs:ignore WordPress.PHP.StrictComparisons
unset( $option[ $type ][ $key ] );
break;
}
}
}
update_option( 'sbi_notifications', $option );
wp_send_json_success();
}
}
inc/admin/blocks/class-sbi-blocks.php 0000644 00000006227 15051507456 0013545 0 ustar 00 hooks();
}
/**
* Integration hooks.
*
* @since 2.3
*/
protected function hooks() {
add_action( 'init', array( $this, 'register_block' ) );
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
}
/**
* Register Instagram Feed Gutenberg block on the backend.
*
* @since 2.3
*/
public function register_block() {
wp_register_style(
'sbi-blocks-styles',
trailingslashit( SBI_PLUGIN_URL ) . 'css/sb-blocks.css',
array( 'wp-edit-blocks' ),
SBIVER
);
$attributes = array(
'shortcodeSettings' => array(
'type' => 'string',
),
'noNewChanges' => array(
'type' => 'boolean',
)
);
register_block_type(
'sbi/sbi-feed-block',
array(
'attributes' => $attributes,
'render_callback' => array( $this, 'get_feed_html' ),
)
);
}
/**
* Load Instagram Feed Gutenberg block scripts.
*
* @since 2.3
*/
public function enqueue_block_editor_assets() {
$db = sbi_get_database_settings();
sb_instagram_scripts_enqueue();
wp_enqueue_style( 'sbi-blocks-styles' );
wp_enqueue_script(
'sbi-feed-block',
trailingslashit( SBI_PLUGIN_URL ) . 'js/sb-blocks.js',
array( 'wp-blocks', 'wp-i18n', 'wp-element' ),
SBIVER,
true
);
$shortcodeSettings = '';
$i18n = array(
'addSettings' => esc_html__( 'Add Settings', 'instagram-feed' ),
'shortcodeSettings' => esc_html__( 'Shortcode Settings', 'instagram-feed' ),
'example' => esc_html__( 'Example', 'instagram-feed' ),
'preview' => esc_html__( 'Apply Changes', 'instagram-feed' ),
);
wp_localize_script(
'sbi-feed-block',
'sbi_block_editor',
array(
'wpnonce' => wp_create_nonce( 'sb-instagram-blocks' ),
'canShowFeed' => ! empty( $db['connected_accounts'] ),
'configureLink' => admin_url( 'admin.php?page=sbi-settings' ),
'shortcodeSettings' => $shortcodeSettings,
'i18n' => $i18n,
)
);
}
/**
* Get form HTML to display in a Instagram Feed Gutenberg block.
*
* @param array $attr Attributes passed by Instagram Feed Gutenberg block.
*
* @since 2.3
*
* @return string
*/
public function get_feed_html( $attr ) {
$return = '';
$shortcode_settings = isset( $attr['shortcodeSettings'] ) ? $attr['shortcodeSettings'] : '';
$shortcode_settings = str_replace(array( '[instagram-feed', ']' ), '', $shortcode_settings );
$return .= do_shortcode( '[instagram-feed '.$shortcode_settings.']' );
return $return;
}
/**
* Checking if is Gutenberg REST API call.
*
* @since 2.3
*
* @return bool True if is Gutenberg REST API call.
*/
public static function is_gb_editor() {
return defined( 'REST_REQUEST' ) && REST_REQUEST && ! empty( $_REQUEST['context'] ) && 'edit' === $_REQUEST['context']; // phpcs:ignore
}
}
inc/admin/SBI_Onboarding_wizard.php 0000644 00000105373 15051507456 0013276 0 ustar 00 init();
}
/**
* Init Setup Dashboard.
*
* @since 6.0
*/
public function init() {
if ( is_admin() && self::should_init_wizard() ) {
add_action( 'admin_menu', array( $this, 'register_menu' ) );
// add ajax listeners
SBI_Feed_Saver_Manager::hooks();
SBI_Source::hooks();
self::hooks();
$this->ajax_hooks();
}
}
public function ajax_hooks() {
add_action( 'wp_ajax_sbi_feed_saver_manager_process_wizard', array( $this , 'process_wizard_data' ) );
add_action( 'wp_ajax_sbi_feed_saver_manager_dismiss_wizard', array( $this , 'dismiss_wizard' ) );
}
/**
* Check if we need to Init the Onboarding wizard
*
* @since 6.0
*/
public static function should_init_wizard() {
$statues = get_option( self::$statues_name, array() );
if(!isset($statues['wizard_dismissed']) || $statues['wizard_dismissed'] === false ){
return true;
}
return false;
}
/**
* Wizard Wrapper.
*
* @since 6.0
*/
public function feed_builder() {
include_once SBI_BUILDER_DIR . 'templates/wizard.php';
}
/**
* Register Menu.
*
* @since 6.0
*/
public function register_menu() {
$cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options';
$cap = apply_filters( 'sbi_settings_pages_capability', $cap );
$feed_builder = add_submenu_page(
'sb-instagram-feed',
__( 'Setup', 'instagram-feed' ),
__( 'Setup', 'instagram-feed' ),
$cap,
'sbi-setup',
array( $this, 'feed_builder' ),
0
);
add_action( 'load-' . $feed_builder, array( $this, 'builder_enqueue_admin_scripts' ) );
}
/**
* Onboarding Wizard Content & Steps
*
* @return array
*
* @since 6.X
*/
public static function get_onboarding_wizard_content()
{
$data = [
'heading' => __( 'Smash Balloon', 'instagram-feed' ),
'subheading' => __( 'Instagram Feed by', 'instagram-feed' ),
'logo' => SBI_BUILDER_URL . 'assets/img/instagram.png',
'balloon' => SBI_BUILDER_URL . 'assets/img/balloon.png',
'balloon1' => SBI_BUILDER_URL . 'assets/img/balloon-1.png',
'userIcon' => SBI_BUILDER_URL . 'assets/img/user.png',
'saveSettings' => [ 'featuresList', 'pluginsList' ],
'successMessages' => [
'connectAccount' => __( 'Connect an Instagram Account!', 'instagram-feed' ),
'setupFeatures' => __( 'Setup Features!', 'instagram-feed' ),
'feedPlugins' => __( 'Feed plugins for # installed', 'instagram-feed' )
],
'steps' => [
[
'id' => 'welcome',
'template' => SBI_BUILDER_DIR . 'templates/onboarding/welcome.php',
'heading' => __( 'Let\'s set up your plugin!', 'instagram-feed' ),
'description' => __( 'Ready to add a dash of Instagram to your website? Setting up your first feed is quick and easy. We\'ll get you up and running in no time.', 'instagram-feed' ),
'button' => __( 'Launch the Setup Wizard', 'instagram-feed' ),
'img' => SBI_BUILDER_URL . 'assets/img/waving-hand.png',
'banner' => SBI_BUILDER_URL . 'assets/img/onboarding-banner.jpg',
],
[
'id' => 'add-source',
'template' => SBI_BUILDER_DIR . 'templates/onboarding/add-source.php',
'heading' => __( 'Connect your Instagram Account', 'instagram-feed' ),
'smallHeading' => __( 'STEP 1', 'instagram-feed' ),
],
[
'id' => 'configure-features',
'template' => SBI_BUILDER_DIR . 'templates/onboarding/configure-features.php',
'heading' => __( 'Configure features', 'instagram-feed' ),
'smallHeading' => __( 'STEP 2', 'instagram-feed' ),
'featuresList' => [
[
'heading' => __( 'Instagram User Feed', 'instagram-feed' ),
'description' => __( 'Create and display Instagram feeds from connected accounts', 'instagram-feed' ),
'color' => 'green',
'active' => true,
'uncheck' => true,
'icon' => '
'
],
[
'data' => [
'id' => 'enable_email_report',
'type' => 'settings'
],
'heading' => __( 'Downtime Prevention', 'instagram-feed' ),
'description' => __( 'Prevent downtime in the event your feed is unable to update', 'instagram-feed' ),
'color' => 'green',
'active' => true,
'uncheck' => true,
'icon' => '
'
],
[
'data' => [
'id' => 'sb_instagram_disable_resize',
'type' => 'settings'
],
'heading' => __( 'Image Optimization', 'instagram-feed' ),
'description' => __( 'Optimize and locally store feed images to improve search rankings and page speed', 'instagram-feed' ),
'color' => 'green',
'active' => true,
'icon' => '
'
]
],
'proFeaturesList' => [
[
'heading' => __( 'Hashtag Feeds', 'instagram-feed' ),
'description' => __( 'Display Instagram posts that have a particular hashtag', 'instagram-feed' ),
'uncheck' => true,
'active' => false,
'icon' => '
'
],
[
'heading' => __( 'Tagged Feeds', 'instagram-feed' ),
'description' => __( 'Show Instagram posts that you have been tagged in', 'instagram-feed' ),
'uncheck' => true,
'active' => false,
'icon' => '
'
],
[
'heading' => __( 'Lightbox', 'instagram-feed' ),
'description' => __( 'View photos and videos in a popup lightbox directly on your site', 'instagram-feed' ),
'uncheck' => true,
'active' => false,
'icon' => '
'
],
]
],
[
'id' => 'install-plugins',
'template' => SBI_BUILDER_DIR . 'templates/onboarding/install-plugins.php',
'heading' => __( 'You might also be interested in...', 'instagram-feed' ),
'description' => __( 'Enable your favorite features and disable the ones you don\'t need', 'instagram-feed' ),
'pluginsList' => self::get_awesomemotive_plugins()
],
[
'id' => 'success-page',
'template' => SBI_BUILDER_DIR . 'templates/onboarding/success-page.php',
'heading' => __( 'Awesome. You are all set up!', 'instagram-feed' ),
'description' => __( 'Here\'s an overview of everything that is setup', 'instagram-feed' ),
'upgradeContent' => [
'heading' => __( 'Upgrade to unlock hashtag feeds, tagged feeds, a popup lightbox and more', 'instagram-feed' ),
'description' => __( 'To unlock these features and much more, upgrade to Pro and enter your license key below.', 'instagram-feed' ),
'button' => [
'text' => __( 'Upgrade to Instagram Feed Pro', 'instagram-feed' ),
'link' => 'https://smashballoon.com/pricing/instagram-feed/?license_key&upgrade=true&utm_campaign=instagram-free&utm_source=setup&utm_medium=upgrade-license'
],
'upgradeCouppon' => sprintf(
__( 'Upgrade today and %ssave 50%% on a Pro License!%s%s (auto-applied at checkout)', 'instagram-feed' ),
'
',
' ',
'
'
),
'banner' => SBI_BUILDER_URL . 'assets/img/success-banner.jpg',
'upgradeFeaturesList' => [
[
'heading' => __( 'Hashtag Feeds', 'instagram-feed' ),
'icon' => '
'
],
[
'heading' => __( 'Tagged Feeds', 'instagram-feed' ),
'icon' => '
'
],
[
'heading' => __( 'Lightbox', 'instagram-feed' ),
'icon' => '
'
],
[
'heading' => __( 'And many more', 'instagram-feed' ),
'icon' => '
'
]
]
]
],
]
];
$dynamic_features_list = self::get_dynamic_features_list();
if( isset($data['steps']) && sizeof($dynamic_features_list) > 0){
$key_cf_ft = array_search('configure-features', array_column($data['steps'], 'id'));
if( $key_cf_ft !== false){
$new_features_lit = array_merge($data['steps'][$key_cf_ft]['featuresList'] , $dynamic_features_list) ;
$data['steps'][$key_cf_ft]['featuresList'] = $new_features_lit;
}
}
return $data;
}
/**
* Return Dynamic Features List depending on multiple criteria
*
* @return array
*
* @since 6.X
*/
public static function get_dynamic_features_list()
{
$features_list = [];
$smash_plugin_list = self::get_smash_plugins_list();
if( isset($smash_plugin_list['plugins']) && sizeof($smash_plugin_list['plugins']) > 0 ){
$description_plugins = implode(', ', $smash_plugin_list['text']);
$search = ',';
$description_plugins_text = strrev(preg_replace(strrev("/$search/"),strrev(' and '),strrev($description_plugins),1));
array_push($features_list,
[
'data' => [
'id' => $description_plugins,
'type' => 'install_plugins',
'plugins' => 'smash'
],
'heading' => __( 'Social Feed Collection', 'instagram-feed' ),
'description' => __( 'Install' , 'instagram-feed') . ' ' . $description_plugins_text . ' ' . __('feed plugins for more fresh content', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => '
'
]
);
}
//Reviews Plugin
$reviews_plugin = self::get_smash_reviews_plugin();
if( $reviews_plugin !== false){
array_push($features_list, $reviews_plugin);
}
/*
[
'id' => '',
'heading' => __( 'Post and Schedule on Social Media', 'instagram-feed' ),
'description' => __( 'Install Click Social and get the ability to schedule Social media posts right from Wordpress', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => '
'
],
*/
return $features_list;
}
/**
* Return Uninstalled SmashBalloon Plugins
*
* @return array
*
* @since 6.X
*/
public static function get_smash_plugins_list(){
$installed_plugins = get_plugins();
// check whether the pro or free plugins are installed
$is_facebook_installed = false;
$facebook_plugin = 'custom-facebook-feed/custom-facebook-feed.php';
if ( isset( $installed_plugins['custom-facebook-feed-pro/custom-facebook-feed.php'] ) ) {
$is_facebook_installed = true;
$facebook_plugin = 'custom-facebook-feed-pro/custom-facebook-feed.php';
} else if ( isset( $installed_plugins['custom-facebook-feed/custom-facebook-feed.php'] ) ) {
$is_facebook_installed = true;
}
$is_instagram_installed = false;
$instagram_plugin = 'instagram-feed/instagram-feed.php';
if ( isset( $installed_plugins['instagram-feed-pro/instagram-feed.php'] ) ) {
$is_instagram_installed = true;
$instagram_plugin = 'instagram-feed-pro/instagram-feed.php';
} else if ( isset( $installed_plugins['instagram-feed/instagram-feed.php'] ) ) {
$is_instagram_installed = true;
}
$is_twitter_installed = false;
$twitter_plugin = 'custom-twitter-feeds/custom-twitter-feed.php';
if ( isset( $installed_plugins['custom-twitter-feeds-pro/custom-twitter-feed.php'] ) ) {
$is_twitter_installed = true;
$twitter_plugin = 'custom-twitter-feeds-pro/custom-twitter-feed.php';
} else if ( isset( $installed_plugins['custom-twitter-feeds/custom-twitter-feed.php'] ) ) {
$is_twitter_installed = true;
}
$is_youtube_installed = false;
$youtube_plugin = 'feeds-for-youtube/youtube-feed.php';
if ( isset( $installed_plugins['youtube-feed-pro/youtube-feed.php'] ) ) {
$is_youtube_installed = true;
$youtube_plugin = 'youtube-feed-pro/youtube-feed.php';
} else if ( isset( $installed_plugins['feeds-for-youtube/youtube-feed.php'] ) ) {
$is_youtube_installed = true;
}
$smash_list = [
'text' => [],
'plugins' => [
[
'type' => 'instagram',
'is_istalled' => $is_instagram_installed,
'download_link' => $instagram_plugin,
'min_php' => '5.6.0'
],
[
'type' => 'facebook',
'is_istalled' => $is_facebook_installed,
'download_link' => $facebook_plugin,
'min_php' => '5.6.0'
],
[
'type' => 'twitter',
'is_istalled' => $is_twitter_installed,
'download_link' => $twitter_plugin,
'min_php' => '5.6.0'
],
[
'type' => 'youtube',
'is_istalled' => $is_youtube_installed,
'download_link' => $youtube_plugin,
'min_php' => '5.6.0'
]
]
];
foreach ($smash_list['plugins'] as $mash_plugin) {
if( version_compare( PHP_VERSION , $mash_plugin['min_php'] , '<' ) ){
$mash_plugin['is_istalled'] = true;
}
if( $mash_plugin['type'] === self::$plugin_name || $mash_plugin['is_istalled'] === true){
unset($mash_plugin);
}else{
array_push($smash_list['text'], ucfirst($mash_plugin['type']));
}
}
return $smash_list;
}
/**
* Return Reviews Plugin if not Installed
*
* @return array
*
* @since 6.X
*/
public static function get_smash_reviews_plugin(){
$installed_plugins = get_plugins();
$min_php = '7.1';
$is_reviews_installed = false;
$reviews_plugin = 'reviews-feed/sb-reviews.php';
if ( isset( $installed_plugins['reviews-feed-pro/sb-reviews-pro.php'] ) ) {
$is_reviews_installed = true;
$reviews_plugin = 'reviews-feed-pro/sb-reviews-pro.php';
} else if ( isset( $installed_plugins['reviews-feed/sb-reviews.php'] ) ) {
$is_reviews_installed = true;
}
if( version_compare( PHP_VERSION , $min_php , '<' ) ){
$is_reviews_installed = true;
}
if( $is_reviews_installed === false ){
return [
'data' => [
'id' => 'reviews',
'type' => 'install_plugins'
],
'heading' => __( 'Customer Reviews Plugin', 'instagram-feed' ),
'description' => __( 'Install Reviews Feed to display customer reviews from Google or Yelp and build trust', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => '
'
];
}
return false;
}
/**
* Return Awesome Motive Plugins
*
* @return array
*
* @since 6.X
*/
public static function get_awesomemotive_plugins(){
$installed_plugins = get_plugins();
$awesomemotive_plugins_list = [
[
'plugin' => 'allinoneseo',
'data' => [
'type' => 'install_plugins',
'id' => 'allinoneseo',
'pluginName' => __('All in One SEO', 'instagram-feed' ),
],
'heading' => __( 'All in One SEO Toolkit', 'instagram-feed' ),
'description' => __( 'Out-of-the-box SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs, business sites, or ecommerce sites, and much more.', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => SBI_BUILDER_URL . 'assets/img/allinoneseo.png'
],
[
'plugin' => 'monsterinsight',
'data' => [
'type' => 'install_plugins',
'id' => 'monsterinsight',
'pluginName' => __('Monster Insights', 'instagram-feed' ),
],
'heading' => __( 'Analytics by MonsterInsights', 'instagram-feed' ),
'description' => __( 'Make it “effortless” to connect your WordPress site with Google Analytics, so you can start making data-driven decisions to grow your business.', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => SBI_BUILDER_URL . 'assets/img/monsterinsight.png',
],
[
'plugin' => 'wpforms',
'data' => [
'type' => 'install_plugins',
'id' => 'wpforms',
'pluginName' => __('WPForms', 'instagram-feed' ),
],
'heading' => __( 'Forms by WPForms', 'instagram-feed' ),
'description' => __( 'Create contact, subscription or payment forms with the most beginner friendly drag & drop WordPress forms plugin', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => SBI_BUILDER_URL . 'assets/img/wpforms.png'
],
[
'plugin' => 'seedprod',
'data' => [
'type' => 'install_plugins',
'id' => 'seedprod',
'pluginName' => __('SeedProd', 'instagram-feed' ),
],
'heading' => __( 'SeedProd Website Builder', 'instagram-feed' ),
'description' => __( 'A simple and powerful theme builder, landing page builder, "coming soon" page builder, and maintenance mode notice builder', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => SBI_BUILDER_URL . 'assets/img/seedprod.png'
],
[
'plugin' => 'optinmonster',
'data' => [
'type' => 'install_plugins',
'id' => 'optinmonster',
'pluginName' => __('OptinMonster', 'instagram-feed' ),
],
'heading' => __( 'OptinMonster Popup Builder', 'instagram-feed' ),
'description' => __( 'Make popups & opt-in forms to build your email newsletter subscribers, generate leads, and close sales', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => SBI_BUILDER_URL . 'assets/img/optinmonster.png'
],
[
'plugin' => 'pushengage',
'data' => [
'type' => 'install_plugins',
'id' => 'pushengage',
'pluginName' => __('PushEngage', 'instagram-feed' ),
],
'heading' => __( 'PushEngage Notifications', 'instagram-feed' ),
'description' => __( 'Create and send high-converting web push notifications to your website visitors.', 'instagram-feed' ),
'color' => 'blue',
'active' => true,
'icon' => SBI_BUILDER_URL . 'assets/img/pushengage.svg'
]
];
$available_plugins = [];
foreach ($awesomemotive_plugins_list as $plugin) {
if( !self::check_awesome_motive_plugin( $plugin['plugin'], $installed_plugins ) ){
array_push($available_plugins, $plugin);
}
}
return array_slice($available_plugins , 0, 3);
}
/**
* Check if AWESOME MOTIVE Plugin
*
* @return boolean
*
* @since 6.X
*/
public static function check_awesome_motive_plugin( $plugin, $installed_plugins ){
switch ($plugin) {
case 'allinoneseo':
if (
isset( $installed_plugins['all-in-one-seo-pack/all_in_one_seo_pack.php'] )
|| isset( $installed_plugins['all-in-one-seo-pack-pro/all_in_one_seo_pack.php'] )
) {
return true;
}
return false;
case 'monsterinsight':
if (
isset( $installed_plugins['google-analytics-for-wordpress/googleanalytics.php'] )
|| isset( $installed_plugins['google-analytics-premium/googleanalytics-premium.php'] )
) {
return true;
}
return false;
case 'wpforms':
if (
isset( $installed_plugins['wpforms-lite/wpforms.php'] )
|| isset( $installed_plugins['wpforms/wpforms.php'] )
) {
return true;
}
return false;
case 'seedprod':
if (
isset( $installed_plugins['coming-soon/coming-soon.php'] )
) {
return true;
}
return false;
case 'optinmonster':
if (
isset( $installed_plugins['optinmonster/optin-monster-wp-api.php'] )
) {
return true;
}
return false;
case 'pushengage':
if (
isset( $installed_plugins['pushengage/main.php'] )
) {
return true;
}
return false;
}
}
/**
* Get Plugin Download
*
*
* @since 6.X
*/
public static function get_plugin_download_link( $plugin_name ){
$plugin_download = false;
switch ( strtolower($plugin_name) ) {
case 'facebook':
$plugin_download = 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip';
break;
case 'instagram':
$plugin_download = 'https://downloads.wordpress.org/plugin/instagram-feed.zip';
break;
case 'twitter':
$plugin_download = 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip';
break;
case 'youtube':
$plugin_download = 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip';
break;
case 'reviews':
$plugin_download = 'https://downloads.wordpress.org/plugin/reviews-feed.zip';
break;
case 'allinoneseo':
$plugin_download = 'https://downloads.wordpress.org/plugin/all-in-one-seo-pack.zip';
break;
case 'monsterinsight':
$plugin_download = 'https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.zip';
break;
case 'wpforms':
$plugin_download = 'https://downloads.wordpress.org/plugin/wpforms-lite.zip';
break;
case 'seedprod':
$plugin_download = 'https://downloads.wordpress.org/plugin/coming-soon.zip';
break;
case 'optinmonster':
$plugin_download = 'https://downloads.wordpress.org/plugin/optinmonster.zip';
break;
case 'pushengage':
$plugin_download = 'https://downloads.wordpress.org/plugin/pushengage.zip';
break;
}
return $plugin_download;
}
/**
* Install Plugin
*
*
* @since 6.X
*/
public static function install_single_plugin( $plugin_name ){
$plugin_download = self::get_plugin_download_link( strtolower( str_replace(' ', '', $plugin_name) ) );
if( $plugin_download === false || !current_user_can ('install_plugins') ){
return false;
}
if ( strpos( $plugin_download , 'https://downloads.wordpress.org/plugin/' ) !== 0 ) {
return false;
}
set_current_screen( 'sbi-feed-builder' );
// Prepare variables.
$url = esc_url_raw(
add_query_arg(
array(
'page' => 'sbi-feed-builder',
),
admin_url( 'admin.php' )
)
);
$creds = request_filesystem_credentials( $url, '', false, false, null );
// Check for file system permissions.
if ( false === $creds || ! WP_Filesystem( $creds ) ) {
return false;
}
require_once SBI_PLUGIN_DIR . 'inc/admin/class-install-skin.php';
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
// Create the plugin upgrader with our custom skin.
$installer = new \Sbi\Helpers\PluginSilentUpgrader( new \Sbi_Install_Skin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) || empty( $plugin_download ) ) {
wp_send_json_error( $error );
}
$installer->install( esc_url_raw( wp_unslash( $plugin_download ) ) );
// Flush the cache and return the newly installed plugin basename.
wp_cache_flush();
$plugin_basename = $installer->plugin_info();
if ( $plugin_basename ) {
activate_plugin( $plugin_basename );
}
}
/**
* Process Wizard Data
* Save Settings, Install Plugins and more
*
* @since 6.0.8
*/
public function process_wizard_data(){
if( ! isset( $_POST['data'] ) ){
wp_send_json_error();
}
check_ajax_referer( 'sbi-admin' , 'nonce');
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
wp_send_json_error();
}
$sbi_settings = get_option( 'sb_instagram_settings', array() );
$onboarding_data = sanitize_text_field( stripslashes( $_POST['data'] ) );
$onboarding_data = json_decode( $onboarding_data, true);
foreach ($onboarding_data as $single_data) {
if( $single_data['type'] === 'settings' ){
$sbi_settings[$single_data['id']] = $single_data['id'] === 'sb_instagram_disable_resize' ? false : true;
}
if( $single_data['type'] === 'install_plugins' && current_user_can( 'install_plugins' ) ){
$plugins = explode(',' , $single_data['id']);
//Deleting Redirect Data for 3rd plugins
//$this->disable_installed_plugins_redirect();
foreach ($plugins as $plugin_name) {
@SBI_Onboarding_wizard::install_single_plugin( $plugin_name );
$this->disable_installed_plugins_redirect();
}
}
}
update_option( 'sb_instagram_settings', $sbi_settings );
wp_die();
}
/**
* Dismiss Onboarding Wizard
*
* @since 6.0.8
*/
public function dismiss_wizard(){
check_ajax_referer( 'sbi-admin' , 'nonce');
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
wp_send_json_error();
}
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
$sbi_statuses_option['wizard_dismissed'] = true;
update_option( 'sbi_statuses', $sbi_statuses_option );
wp_send_json_error();
}
/**
* Disable Installed Plugins Redirect
*
* @since 6.0.8
*/
public function disable_installed_plugins_redirect(){
//Monster Insight
delete_transient( '_monsterinsights_activation_redirect' );
//All in one SEO
update_option( 'aioseo_activation_redirect', true );
//WPForms
update_option( 'wpforms_activation_redirect', true );
//Optin Monster
delete_transient( 'optin_monster_api_activation_redirect' );
update_option( 'optin_monster_api_activation_redirect_disabled', true );
//Seed PROD
update_option( 'seedprod_dismiss_setup_wizard', true );
//PushEngage
delete_transient( 'pushengage_activation_redirect' );
}
} inc/admin/addon-functions.php 0000644 00000015113 15051507456 0012222 0 ustar 00 'sbi-about-us',
),
admin_url( 'admin.php' )
)
);
$creds = request_filesystem_credentials( $url, '', false, false, null );
// Check for file system permissions.
if ( false === $creds ) {
wp_send_json_error( $error );
}
if ( ! WP_Filesystem( $creds ) ) {
wp_send_json_error( $error );
}
/*
* We do not need any extra credentials if we have gotten this far, so let's install the plugin.
*/
require_once SBI_PLUGIN_DIR . 'inc/admin/class-install-skin.php';
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
// Create the plugin upgrader with our custom skin.
$installer = new Sbi\Helpers\PluginSilentUpgrader( new Sbi_Install_Skin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) || empty( $_POST['plugin'] ) ) {
wp_send_json_error( $error );
}
$installer->install( esc_url_raw( wp_unslash( $_POST['plugin'] ) ) );
// Flush the cache and return the newly installed plugin basename.
wp_cache_flush();
$plugin_basename = $installer->plugin_info();
if ( $plugin_basename ) {
$type = 'addon';
if ( ! empty( $_POST['type'] ) ) {
$type = sanitize_key( $_POST['type'] );
}
// Activate the plugin silently.
$activated = activate_plugin( $plugin_basename );
if ( ! is_wp_error( $activated ) ) {
wp_send_json_success(
array(
'msg' => 'plugin' === $type ? esc_html__( 'Plugin installed & activated.', 'instagram-feed' ) : esc_html__( 'Addon installed & activated.', 'instagram-feed' ),
'is_activated' => true,
'basename' => $plugin_basename,
)
);
} else {
wp_send_json_success(
array(
'msg' => 'plugin' === $type ? esc_html__( 'Plugin installed.', 'instagram-feed' ) : esc_html__( 'Addon installed.', 'instagram-feed' ),
'is_activated' => false,
'basename' => $plugin_basename,
)
);
}
}
wp_send_json_error( $error );
}
add_action( 'wp_ajax_sbi_install_addon', 'sbi_install_addon' );
/**
* Smash Balloon Encrypt or decrypt
*
* @param string @action
* @param string @string
*
* @return string $output
*/
function sbi_encrypt_decrypt( $action, $string ) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'SMA$H.BA[[OON#23121';
$secret_iv = '1231394873342102221';
// hash
$key = hash( 'sha256', $secret_key );
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
if ( $action === 'encrypt' ) {
$output = openssl_encrypt( $string, $encrypt_method, $key, 0, $iv );
$output = base64_encode( $output );
} else if ( $action === 'decrypt' ) {
$output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv );
}
return $output;
}
/**
* AJAX dismiss Uncanny Automator notice
*/
function sbi_dismiss_automator_notice() {
// Run a security check.
check_ajax_referer( 'sbi-admin', 'nonce' );
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
wp_send_json_error();
}
$user_id = get_current_user_id();
// update the source for the automator plugin
update_user_meta( $user_id, 'sbi_dismiss_automator_notice', strtotime( 'now' ) );
wp_send_json_success();
}
add_action( 'wp_ajax_sbi_dismiss_automator_notice', 'sbi_dismiss_automator_notice');
/**
* AJAX setup for the automator plugin to store the source information of Uncanny Automator
*/
function sbi_automator_setup_source() {
// Run a security check.
check_ajax_referer( 'sbi-admin', 'nonce' );
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
wp_send_json_error();
}
// update the source for the automator plugin
update_option( 'uncannyautomator_source', 'sb' );
wp_send_json_success();
}
add_action( 'wp_ajax_sbi_automator_setup_source', 'sbi_automator_setup_source'); inc/admin/class-install-skin.php 0000644 00000001116 15051507456 0012640 0 ustar 00 '', // Please always pass this.
'destination' => '', // And this
'clear_destination' => false,
'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please
'clear_working' => true,
'is_multi' => false,
'hook_extra' => array(), // Pass any extra $hook_extra args here, this will be passed to any hooked filters.
);
$options = wp_parse_args( $options, $defaults );
/**
* Filters the package options before running an update.
*
* See also {@see 'upgrader_process_complete'}.
*
* @since 4.3.0
*
* @param array $options {
* Options used by the upgrader.
*
* @type string $package Package for update.
* @type string $destination Update location.
* @type bool $clear_destination Clear the destination resource.
* @type bool $clear_working Clear the working resource.
* @type bool $abort_if_destination_exists Abort if the Destination directory exists.
* @type bool $is_multi Whether the upgrader is running multiple times.
* @type array $hook_extra {
* Extra hook arguments.
*
* @type string $action Type of action. Default 'update'.
* @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'.
* @type bool $bulk Whether the update process is a bulk update. Default true.
* @type string $plugin Path to the plugin file relative to the plugins directory.
* @type string $theme The stylesheet or template name of the theme.
* @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme',
* or 'core'.
* @type object $language_update The language pack update offer.
* }
* }
*/
$options = apply_filters( 'upgrader_package_options', $options );
if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times
$this->skin->header();
}
// Connect to the Filesystem first.
$res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) );
// Mainly for non-connected filesystem.
if ( ! $res ) {
if ( ! $options['is_multi'] ) {
$this->skin->footer();
}
return false;
}
$this->skin->before();
if ( is_wp_error( $res ) ) {
$this->skin->error( $res );
$this->skin->after();
if ( ! $options['is_multi'] ) {
$this->skin->footer();
}
return $res;
}
/*
* Download the package (Note, This just returns the filename
* of the file if the package is a local file)
*/
$download = $this->download_package( $options['package'], true );
// Allow for signature soft-fail.
// WARNING: This may be removed in the future.
if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
// Don't output the 'no signature could be found' failure message for now.
if ( 'signature_verification_no_signature' != $download->get_error_code() || WP_DEBUG ) {
// Outout the failure error as a normal feedback, and not as an error:
//$this->skin->feedback( $download->get_error_message() );
// Report this failure back to WordPress.org for debugging purposes.
wp_version_check(
array(
'signature_failure_code' => $download->get_error_code(),
'signature_failure_data' => $download->get_error_data(),
)
);
}
// Pretend this error didn't happen.
$download = $download->get_error_data( 'softfail-filename' );
}
if ( is_wp_error( $download ) ) {
$this->skin->error( $download );
$this->skin->after();
if ( ! $options['is_multi'] ) {
$this->skin->footer();
}
return $download;
}
$delete_package = ( $download != $options['package'] ); // Do not delete a "local" file
// Unzips the file into a temporary directory.
$working_dir = $this->unpack_package( $download, $delete_package );
if ( is_wp_error( $working_dir ) ) {
$this->skin->error( $working_dir );
$this->skin->after();
if ( ! $options['is_multi'] ) {
$this->skin->footer();
}
return $working_dir;
}
// With the given options, this installs it to the destination directory.
$result = $this->install_package(
array(
'source' => $working_dir,
'destination' => $options['destination'],
'clear_destination' => $options['clear_destination'],
'abort_if_destination_exists' => $options['abort_if_destination_exists'],
'clear_working' => $options['clear_working'],
'hook_extra' => $options['hook_extra'],
)
);
$this->skin->set_result( $result );
if ( is_wp_error( $result ) ) {
$this->skin->error( $result );
//$this->skin->feedback( 'process_failed' );
} else {
// Installation succeeded.
//$this->skin->feedback( 'process_success' );
}
$this->skin->after();
if ( ! $options['is_multi'] ) {
/**
* Fires when the upgrader process is complete.
*
* See also {@see 'upgrader_package_options'}.
*
* @since 3.6.0
* @since 3.7.0 Added to WP_Upgrader::run().
* @since 4.6.0 `$translations` was added as a possible argument to `$hook_extra`.
*
* @param WP_Upgrader $this WP_Upgrader instance. In other contexts, $this, might be a
* Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance.
* @param array $hook_extra {
* Array of bulk item update data.
*
* @type string $action Type of action. Default 'update'.
* @type string $type Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'.
* @type bool $bulk Whether the update process is a bulk update. Default true.
* @type array $plugins Array of the basename paths of the plugins' main files.
* @type array $themes The theme slugs.
* @type array $translations {
* Array of translations update data.
*
* @type string $language The locale the translation is for.
* @type string $type Type of translation. Accepts 'plugin', 'theme', or 'core'.
* @type string $slug Text domain the translation is for. The slug of a theme/plugin or
* 'default' for core translations.
* @type string $version The version of a theme, plugin, or core.
* }
* }
*/
do_action( 'upgrader_process_complete', $this, $options['hook_extra'] );
$this->skin->footer();
}
return $result;
}
/**
* Toggle maintenance mode for the site.
*
* Create/delete the maintenance file to enable/disable maintenance mode.
*
* @since 2.8.0
*
* @global WP_Filesystem_Base $wp_filesystem Subclass
*
* @param bool $enable True to enable maintenance mode, false to disable.
*/
public function maintenance_mode( $enable = false ) {
global $wp_filesystem;
$file = $wp_filesystem->abspath() . '.maintenance';
if ( $enable ) {
//$this->skin->feedback( 'maintenance_start' );
// Create maintenance file to signal that we are upgrading
$maintenance_string = '';
$wp_filesystem->delete( $file );
$wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
} elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
//$this->skin->feedback( 'maintenance_end' );
$wp_filesystem->delete( $file );
}
}
/**
* Download a package.
*
* @since 2.8.0
*
* @param string $package The URI of the package. If this is the full path to an
* existing local file, it will be returned untouched.
* @param bool $check_signatures Whether to validate file signatures. Default false.
* @return string|WP_Error The full path to the downloaded package file, or a WP_Error object.
*/
public function download_package( $package, $check_signatures = false, $hook_extra = array() ) {
/**
* Filters whether to return the package.
*
* @since 3.7.0
*
* @param bool $reply Whether to bail without returning the package.
* Default false.
* @param string $package The package file name.
* @param WP_Upgrader $this The WP_Upgrader instance.
*/
$reply = apply_filters( 'upgrader_pre_download', false, $package, $this );
if ( false !== $reply ) {
return $reply;
}
if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { //Local file or remote?
return $package; //must be a local file..
}
if ( empty( $package ) ) {
return new WP_Error( 'no_package', $this->strings['no_package'] );
}
//$this->skin->feedback( 'downloading_package', $package );
$download_file = download_url( $package, 300, $check_signatures );
if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() );
}
return $download_file;
}
/**
* Unpack a compressed package file.
*
* @since 2.8.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
*
* @param string $package Full path to the package file.
* @param bool $delete_package Optional. Whether to delete the package file after attempting
* to unpack it. Default true.
* @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure.
*/
public function unpack_package( $package, $delete_package = true ) {
global $wp_filesystem;
//$this->skin->feedback( 'unpack_package' );
$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
//Clean up contents of upgrade directory beforehand.
$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
if ( ! empty( $upgrade_files ) ) {
foreach ( $upgrade_files as $file ) {
$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
}
}
// We need a working directory - Strip off any .tmp or .zip suffixes
$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
// Clean up working directory
if ( $wp_filesystem->is_dir( $working_dir ) ) {
$wp_filesystem->delete( $working_dir, true );
}
// Unzip package to working directory
$result = unzip_file( $package, $working_dir );
// Once extracted, delete the package if required.
if ( $delete_package ) {
unlink( $package );
}
if ( is_wp_error( $result ) ) {
$wp_filesystem->delete( $working_dir, true );
if ( 'incompatible_archive' == $result->get_error_code() ) {
return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
}
return $result;
}
return $working_dir;
}
/**
* Install a package.
*
* Copies the contents of a package form a source directory, and installs them in
* a destination directory. Optionally removes the source. It can also optionally
* clear out the destination folder if it already exists.
*
* @since 2.8.0
*
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
* @global array $wp_theme_directories
*
* @param array|string $args {
* Optional. Array or string of arguments for installing a package. Default empty array.
*
* @type string $source Required path to the package source. Default empty.
* @type string $destination Required path to a folder to install the package in.
* Default empty.
* @type bool $clear_destination Whether to delete any files already in the destination
* folder. Default false.
* @type bool $clear_working Whether to delete the files form the working directory
* after copying to the destination. Default false.
* @type bool $abort_if_destination_exists Whether to abort the installation if
* the destination folder already exists. Default true.
* @type array $hook_extra Extra arguments to pass to the filter hooks called by
* WP_Upgrader::install_package(). Default empty array.
* }
*
* @return array|WP_Error The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure.
*/
public function install_package( $args = array() ) {
global $wp_filesystem, $wp_theme_directories;
$defaults = array(
'source' => '', // Please always pass this
'destination' => '', // and this
'clear_destination' => false,
'clear_working' => false,
'abort_if_destination_exists' => true,
'hook_extra' => array(),
);
$args = wp_parse_args( $args, $defaults );
// These were previously extract()'d.
$source = $args['source'];
$destination = $args['destination'];
$clear_destination = $args['clear_destination'];
set_time_limit( 300 );
if ( empty( $source ) || empty( $destination ) ) {
return new WP_Error( 'bad_request', $this->strings['bad_request'] );
}
//$this->skin->feedback( 'installing_package' );
/**
* Filters the install response before the installation has started.
*
* Returning a truthy value, or one that could be evaluated as a WP_Error
* will effectively short-circuit the installation, returning that value
* instead.
*
* @since 2.8.0
*
* @param bool|WP_Error $response Response.
* @param array $hook_extra Extra arguments passed to hooked filters.
*/
$res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] );
if ( is_wp_error( $res ) ) {
return $res;
}
//Retain the Original source and destinations
$remote_source = $args['source'];
$local_destination = $destination;
$source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) );
$remote_destination = $wp_filesystem->find_folder( $local_destination );
//Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
if ( 1 == count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { //Only one folder? Then we want its contents.
$source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
} elseif ( count( $source_files ) == 0 ) {
return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
} else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
$source = trailingslashit( $args['source'] );
}
/**
* Filters the source file location for the upgrade package.
*
* @since 2.8.0
* @since 4.4.0 The $hook_extra parameter became available.
*
* @param string $source File source location.
* @param string $remote_source Remote file source location.
* @param WP_Upgrader $this WP_Upgrader instance.
* @param array $hook_extra Extra arguments passed to hooked filters.
*/
$source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] );
if ( is_wp_error( $source ) ) {
return $source;
}
// Has the source location changed? If so, we need a new source_files list.
if ( $source !== $remote_source ) {
$source_files = array_keys( $wp_filesystem->dirlist( $source ) );
}
/*
* Protection against deleting files in any important base directories.
* Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
* destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
* to copy the directory into the directory, whilst they pass the source
* as the actual files to copy.
*/
$protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' );
if ( is_array( $wp_theme_directories ) ) {
$protected_directories = array_merge( $protected_directories, $wp_theme_directories );
}
if ( in_array( $destination, $protected_directories ) ) {
$remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
$destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
}
if ( $clear_destination ) {
// We're going to clear the destination if there's something there.
//$this->skin->feedback( 'remove_old' );
$removed = $this->clear_destination( $remote_destination );
/**
* Filters whether the upgrader cleared the destination.
*
* @since 2.8.0
*
* @param mixed $removed Whether the destination was cleared. true on success, WP_Error on failure
* @param string $local_destination The local package destination.
* @param string $remote_destination The remote package destination.
* @param array $hook_extra Extra arguments passed to hooked filters.
*/
$removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] );
if ( is_wp_error( $removed ) ) {
return $removed;
}
} elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) {
//If we're not clearing the destination folder and something exists there already, Bail.
//But first check to see if there are actually any files in the folder.
$_files = $wp_filesystem->dirlist( $remote_destination );
if ( ! empty( $_files ) ) {
$wp_filesystem->delete( $remote_source, true ); //Clear out the source files.
return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination );
}
}
//Create destination if needed
if ( ! $wp_filesystem->exists( $remote_destination ) ) {
if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination );
}
}
// Copy new version of item into place.
$result = copy_dir( $source, $remote_destination );
if ( is_wp_error( $result ) ) {
if ( $args['clear_working'] ) {
$wp_filesystem->delete( $remote_source, true );
}
return $result;
}
//Clear the Working folder?
if ( $args['clear_working'] ) {
$wp_filesystem->delete( $remote_source, true );
}
$destination_name = basename( str_replace( $local_destination, '', $destination ) );
if ( '.' == $destination_name ) {
$destination_name = '';
}
$this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
/**
* Filters the installation response after the installation has finished.
*
* @since 2.8.0
*
* @param bool $response Installation response.
* @param array $hook_extra Extra arguments passed to hooked filters.
* @param array $result Installation result data.
*/
$res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result );
if ( is_wp_error( $res ) ) {
$this->result = $res;
return $res;
}
//Bombard the calling function will all the info which we've just used.
return $this->result;
}
}
inc/admin/class-sbi-sitehealth.php 0000644 00000003572 15051507456 0013145 0 ustar 00 =' );
}
/**
* Loads an integration.
*
* @since 1.5.5
*/
public function load() {
$this->hooks();
}
/**
* Integration hooks.
*
* @since 1.5.5
*/
protected function hooks() {
add_filter( 'site_status_tests', array( $this, 'add_tests' ) );
}
/**
* Add MonsterInsights WP Site Health tests.
*
* @param array $tests The current filters array.
*
* @return array
*/
public function add_tests( $tests ) {
$tests['direct']['sbi_test_check_errors'] = array(
'label' => __( 'Instagram Feed Errors', 'instagram-feed' ),
'test' => array( $this, 'test_check_errors' )
);
return $tests;
}
/**
* Checks if there are Instagram API Errors
*/
public function test_check_errors() {
$result = array(
'label' => __( 'Instagram Feed has no critical errors', 'instagram-feed' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Instagram Feed', 'instagram-feed' ),
'color' => 'blue',
),
'description' => __( 'No critical errors have been detected.', 'instagram-feed' ),
'test' => 'sbi_test_check_errors',
);
global $sb_instagram_posts_manager;
if ( $sb_instagram_posts_manager->are_critical_errors() ) {
$link = admin_url( 'admin.php?page=sbi-settings');
$result['status'] = 'critical';
$result['label'] = __( 'Your Instagram Feed is experiencing an error.', 'instagram-feed' );
$result['description'] = sprintf( __( 'A critical issue has been detected with your Instagram Feed. Visit the %sInstagram Feed settings page%s to fix the issue.', 'instagram-feed' ), '
', ' ' );
}
return $result;
}
}
inc/admin/class-sbi-new-user.php 0000644 00000041600 15051507456 0012552 0 ustar 00 get_option();
foreach ( $notifications as $key => $notification ) {
// The message should never be empty, if they are, ignore.
if ( empty( $notification['content'] ) ) {
continue;
}
// Ignore if notification has already been dismissed.
if ( ! empty( $option['dismissed'] ) && in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
continue;
}
$data[ $key ] = $notification;
}
return $data;
}
/**
* Verify saved notification data for active notifications.
*
* @since 2.6
*
* @param array $notifications Array of notifications items to verify.
*
* @return array
*/
public function verify_active( $notifications ) {
if ( ! is_array( $notifications ) || empty( $notifications ) ) {
return array();
}
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
$current_time = sbi_get_current_time();
// rating notice logic
$sbi_rating_notice_option = get_option( 'sbi_rating_notice', false );
$sbi_rating_notice_waiting = get_transient( 'instagram_feed_rating_notice_waiting' );
$should_show_rating_notice = ($sbi_rating_notice_waiting !== 'waiting' && $sbi_rating_notice_option !== 'dismissed');
// new user discount logic
$in_new_user_month_range = true;
$should_show_new_user_discount = false;
$has_been_one_month_since_rating_dismissal = isset( $sbi_statuses_option['rating_notice_dismissed'] ) ? ((int)$sbi_statuses_option['rating_notice_dismissed'] + ((int)$notifications['review']['wait'] * DAY_IN_SECONDS)) < $current_time + 1: true;
if ( isset( $sbi_statuses_option['first_install'] ) && $sbi_statuses_option['first_install'] === 'from_update' ) {
global $current_user;
$user_id = $current_user->ID;
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
$ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
if ( $ignore_new_user_sale_notice_meta !== 'always' ) {
$should_show_new_user_discount = true;
}
} elseif ( $in_new_user_month_range && $has_been_one_month_since_rating_dismissal && $sbi_rating_notice_waiting !== 'waiting' ) {
global $current_user;
$user_id = $current_user->ID;
$ignore_new_user_sale_notice_meta = get_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice' );
$ignore_new_user_sale_notice_meta = isset( $ignore_new_user_sale_notice_meta[0] ) ? $ignore_new_user_sale_notice_meta[0] : '';
if ( $ignore_new_user_sale_notice_meta !== 'always'
&& isset( $sbi_statuses_option['first_install'] )
&& $current_time > (int)$sbi_statuses_option['first_install'] + ((int)$notifications['discount']['wait'] * DAY_IN_SECONDS) ) {
$should_show_new_user_discount = true;
}
}
if ( sbi_is_pro_version() ) {
$should_show_new_user_discount = false;
}
if ( isset( $notifications['review'] ) && $should_show_rating_notice ) {
return array( $notifications['review'] );
} elseif ( isset( $notifications['discount'] ) && $should_show_new_user_discount ) {
return array( $notifications['discount'] );
}
return array();
}
/**
* Get notification data.
*
* @since 2.6
*
* @return array
*/
public function get() {
if ( ! $this->has_access() ) {
return array();
}
$option = $this->get_option();
// Only update if does not exist.
if ( empty( $option['update'] ) ) {
$this->update();
}
$events = ! empty( $option['events'] ) ? $this->verify_active( $option['events'] ) : array();
$feed = ! empty( $option['feed'] ) ? $this->verify_active( $option['feed'] ) : array();
return array_merge( $events, $feed );
}
/**
* Add a manual notification event.
*
* @since 2.6
*
* @param array $notification Notification data.
*/
public function add( $notification ) {
if ( empty( $notification['id'] ) ) {
return;
}
$option = $this->get_option();
if ( in_array( $notification['id'], $option['dismissed'] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
return;
}
foreach ( $option['events'] as $item ) {
if ( $item['id'] === $notification['id'] ) {
return;
}
}
$notification = $this->verify( array( $notification ) );
update_option(
$this->option_name(),
array(
'update' => $option['update'],
'feed' => $option['feed'],
'events' => array_merge( $notification, $option['events'] ),
'dismissed' => $option['dismissed'],
)
);
}
/**
* Update notification data from feed.
*
* @since 2.6
*/
public function update() {
$feed = $this->fetch_feed();
$option = $this->get_option();
update_option(
$this->option_name(),
array(
'update' => time(),
'feed' => $feed,
'events' => $option['events'],
'dismissed' => $option['dismissed'],
)
);
}
/**
* Do not enqueue anything extra.
*
* @since 2.6
*/
public function enqueues() {
}
public function review_notice_consent() {
//Security Checks
check_ajax_referer( 'sbi_nonce', 'sbi_nonce' );
$cap = current_user_can( 'manage_instagram_feed_options' ) ? 'manage_instagram_feed_options' : 'manage_options';
$cap = apply_filters( 'sbi_settings_pages_capability', $cap );
if ( ! current_user_can( $cap ) ) {
wp_send_json_error(); // This auto-dies.
}
$consent = isset( $_POST[ 'consent' ] ) ? sanitize_text_field( $_POST[ 'consent' ] ) : '';
update_option( 'sbi_review_consent', $consent );
if ( $consent == 'no' ) {
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
update_option( 'sbi_rating_notice', 'dismissed', false );
$sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
update_option( 'sbi_statuses', $sbi_statuses_option, false );
}
wp_die();
}
/**
* Output notifications on Form Overview admin area.
*
* @since 2.6
*/
public function output() {
$notifications = $this->get();
if ( empty( $notifications ) ) {
return;
}
// new user notices included in regular settings page notifications so this
// checks to see if user is one of those pages
if ( ! empty( $_GET['page'] )
&& strpos( $_GET['page'], 'sbi' ) !== false ) {
return;
}
$content_allowed_tags = array(
'em' => array(),
'strong' => array(),
'span' => array(
'style' => array(),
),
'a' => array(
'href' => array(),
'target' => array(),
'rel' => array(),
),
);
$image_overlay = '';
$plugin_type = sbi_is_pro_version() ? 'pro' : 'free';
foreach ( $notifications as $notification ) {
$img_src = SBI_PLUGIN_URL . 'admin/assets/img/' . sanitize_text_field( $notification['image'] );
$type = sanitize_text_field( $notification['id'] );
// check if this is a review notice
if( $type == 'review' ) {
$review_consent = get_option( 'sbi_review_consent' );
$sbi_open_feedback_url = 'https://smashballoon.com/feedback/?plugin=instagram-' . $plugin_type;
// step #1 for the review notice
if ( ! $review_consent ) {
?>
%s',
__( 'Yes', 'instagram-feed' )
);
printf(
'
%s ',
$sbi_open_feedback_url,
__( 'No', 'instagram-feed' )
);
?>
$type ) ), 'sbi-' . $type, 'sbi_nonce' );
$title = $this->get_notice_title( $notification );
$content = $this->get_notice_content( $notification, $content_allowed_tags );
$buttons = array();
if ( ! empty( $notification['btns'] ) && is_array( $notification['btns'] ) ) {
foreach ( $notification['btns'] as $btn_type => $btn ) {
if ( ! is_array( $btn['url'] ) ) {
$buttons[ $btn_type ]['url'] = $this->replace_merge_fields( $btn['url'], $notification );
} elseif ( is_array( $btn['url'] ) ) {
$buttons[ $btn_type ]['url'] = wp_nonce_url( add_query_arg( $btn['url'] ), 'sbi-' . $type, 'sbi_nonce' );
$close_href = $buttons[ $btn_type ]['url'];
}
$buttons[ $btn_type ]['attr'] = '';
if ( ! empty( $btn['attr'] ) ) {
$buttons[ $btn_type ]['attr'] = ' target="_blank" rel="noopener noreferrer"';
}
$buttons[ $btn_type ]['class'] = '';
if ( ! empty( $btn['class'] ) ) {
$buttons[ $btn_type ]['class'] = ' ' . $btn['class'];
}
$buttons[ $btn_type ]['text'] = '';
if ( ! empty( $btn['text'] ) ) {
$buttons[ $btn_type ]['text'] = wp_kses( $btn['text'], $content_allowed_tags );
}
}
}
}
$review_consent = get_option( 'sbi_review_consent' );
$review_step2_style = '';
if ( $type == 'review' && ! $review_consent ) {
$review_step2_style = 'style="display: none;"';
}
?>
>
$button ) :
$btn_classes = array('sbi-btn');
$btn_classes[] = esc_attr( $button['class'] );
if ( $type == 'primary' ) {
$btn_classes[] = 'sbi-btn-blue';
} else {
$btn_classes[] = 'sbi-btn-grey';
}
?>
>
replace_merge_fields( $notification['title'], $notification );
}
return $title;
}
/**
* SBI Get Notice Content depending on the notice type
*
* @since 6.0
*
* @param array $notification
* @param array $content_allowed_tags
*
* @return string $content
*/
public function get_notice_content( $notification, $content_allowed_tags ) {
$type = $notification['id'];
$content = '';
// Notice content depending on notice type
if ( $type == 'review' ) {
$content = __( 'It really helps to support the plugin and help others to discover it too!', 'instagram-feed' );
} else if ( $type == 'discount' ) {
$content = __( 'We don’t run promotions very often, but for a limited time we’re offering 60% Off our Pro version to all users of our free Instagram Feed.', 'instagram-feed' );
} else {
if ( ! empty( $notification['content'] ) ) {
$content = wp_kses( $this->replace_merge_fields( $notification['content'], $notification ), $content_allowed_tags );
}
}
return $content;
}
/**
* SBI Get Notice Title depending on the notice type
*
* @since 6.0
*
* @param array $notification
*
* @return string $title
*/
public function dismiss() {
global $current_user;
$user_id = $current_user->ID;
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
if ( isset( $_GET['sbi_ignore_rating_notice_nag'] ) ) {
$rating_ignore = false;
if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-review' ) ) {
$rating_ignore = isset( $_GET['sbi_ignore_rating_notice_nag'] ) ? sanitize_text_field( $_GET['sbi_ignore_rating_notice_nag'] ) : false;
}
if ( 1 === (int) $rating_ignore ) {
update_option( 'sbi_rating_notice', 'dismissed', false );
$sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
update_option( 'sbi_statuses', $sbi_statuses_option, false );
} elseif ( 'later' === $rating_ignore ) {
set_transient( 'instagram_feed_rating_notice_waiting', 'waiting', 2 * WEEK_IN_SECONDS );
delete_option( 'sbi_review_consent' );
update_option( 'sbi_rating_notice', 'pending', false );
}
}
if ( isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ) {
$new_user_ignore = false;
if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-discount' ) ) {
$new_user_ignore = isset( $_GET['sbi_ignore_new_user_sale_notice'] ) ? sanitize_text_field( $_GET['sbi_ignore_new_user_sale_notice'] ) : false;
}
if ( 'always' === $new_user_ignore ) {
update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
$current_month_number = (int) date( 'n', sbi_get_current_time() );
$not_early_in_the_year = ( $current_month_number > 5 );
if ( $not_early_in_the_year ) {
update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
}
}
}
if ( isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ) {
$bfcm_ignore = false;
if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-bfcm' ) ) {
$bfcm_ignore = isset( $_GET['sbi_ignore_bfcm_sale_notice'] ) ? sanitize_text_field( $_GET['sbi_ignore_bfcm_sale_notice'] ) : false;
}
if ( 'always' === $bfcm_ignore ) {
update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', 'always' );
} elseif ( date( 'Y', sbi_get_current_time() ) === $bfcm_ignore ) {
update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
}
update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
}
if ( isset( $_GET['sbi_dismiss'] ) ) {
$notice_dismiss = false;
if ( isset( $_GET['sbi_nonce'] ) && wp_verify_nonce( $_GET['sbi_nonce'], 'sbi-notice-dismiss' ) ) {
$notice_dismiss = sanitize_text_field( $_GET['sbi_dismiss'] );
}
if ( 'review' === $notice_dismiss ) {
update_option( 'sbi_rating_notice', 'dismissed', false );
$sbi_statuses_option['rating_notice_dismissed'] = sbi_get_current_time();
update_option( 'sbi_statuses', $sbi_statuses_option, false );
update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
} elseif ( 'discount' === $notice_dismiss ) {
update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
$current_month_number = (int) date( 'n', sbi_get_current_time() );
$not_early_in_the_year = ( $current_month_number > 5 );
if ( $not_early_in_the_year ) {
update_user_meta( $user_id, 'sbi_ignore_bfcm_sale_notice', date( 'Y', sbi_get_current_time() ) );
}
update_user_meta( $user_id, 'sbi_ignore_new_user_sale_notice', 'always' );
}
}
}
}
inc/admin/actions.php 0000644 00000036565 15051507456 0010605 0 ustar 00 are_critical_errors() ) {
$notice = '
! ';
}
$notifications = false;
if ( class_exists( '\SBI_Notifications' ) ) {
$sbi_notifications = new \SBI_Notifications();
$notifications = $sbi_notifications->get();
}
$notice_bubble = '';
if ( empty( $notice ) && ! empty( $notifications ) && is_array( $notifications ) ) {
$notice_bubble = '
' . count( $notifications ) . ' ';
}
add_menu_page(
__( 'Instagram Feed', 'instagram-feed' ),
__( 'Instagram Feed', 'instagram-feed' ). $notice_bubble . $notice,
$cap,
'sb-instagram-feed',
'sb_instagram_settings_page'
);
add_submenu_page(
'sb-instagram-feed',
__( 'Upgrade to Pro', 'instagram-feed' ),
'
' . __( 'Upgrade to Pro', 'instagram-feed' ) . ' ',
$cap,
'https://smashballoon.com/instagram-feed/?utm_campaign=instagram-free&utm_source=menu-link&utm_medium=upgrade-link&utm_content=UpgradeToPro',
''
);
if ( version_compare(PHP_VERSION, '7.1.0') >= 0 && !is_plugin_active( 'reviews-feed/sb-reviews.php' ) && !is_plugin_active( 'reviews-feed-pro/sb-reviews-pro.php' ) ) {
add_submenu_page(
'sb-instagram-feed',
__( 'Reviews Feed', 'instagram-feed' ) ,
'
' . __( 'Reviews Feed', 'instagram-feed' ) . ' '. '
New! ',
$cap,
'admin.php?page=sbr',
''
);
}
//Show a Instagram plugin menu item if it isn't already installed
if( !is_plugin_active( 'custom-facebook-feed/custom-facebook-feed.php' ) && !is_plugin_active( 'custom-facebook-feed-pro/custom-facebook-feed.php' ) && current_user_can( 'activate_plugins' ) && current_user_can( 'install_plugins' ) ){
add_submenu_page(
'sb-instagram-feed',
__( 'Facebook Feed', 'instagram-feed' ),
'
' . __( 'Facebook Feed', 'instagram-feed' ) . ' ',
$cap,
'admin.php?page=cff-builder',
''
);
}
//Show a Twitter plugin menu item if it isn't already installed
if( !is_plugin_active( 'custom-twitter-feeds/custom-twitter-feed.php' ) && !is_plugin_active( 'custom-twitter-feeds-pro/custom-twitter-feed.php' ) && current_user_can( 'activate_plugins' ) && current_user_can( 'install_plugins' ) ){
add_submenu_page(
'sb-instagram-feed',
__( 'Twitter Feed', 'instagram-feed' ),
'
' . __( 'Twitter Feed', 'instagram-feed' ) . ' ',
$cap,
'admin.php?page=sb-instagram-feed&tab=more',
''
);
}
//Show a YouTube plugin menu item if it isn't already installed
if( !is_plugin_active( 'feeds-for-youtube/youtube-feed.php' ) && !is_plugin_active( 'youtube-feed-pro/youtube-feed.php' ) && current_user_can( 'activate_plugins' ) && current_user_can( 'install_plugins' ) ){
add_submenu_page(
'sb-instagram-feed',
__( 'YouTube Feed', 'instagram-feed' ),
'
' . __( 'YouTube Feed', 'instagram-feed' ) . ' ',
$cap,
'admin.php?page=sb-instagram-feed&tab=more',
''
);
}
}
add_action( 'admin_menu', 'sb_instagram_menu' );
function sbi_add_settings_link( $links ) {
$pro_link = '
' . __( 'Upgrade to Pro', 'instagram-feed' ) . ' ';
$sbi_settings_link = '
' . esc_html__( 'Settings', 'instagram-feed' ) . ' ';
array_unshift( $links, $pro_link, $sbi_settings_link );
return $links;
}
add_filter( "plugin_action_links_instagram-feed/instagram-feed.php", 'sbi_add_settings_link', 10, 2 );
function sb_instagram_admin_style() {
wp_register_style( 'sb_instagram_admin_css', SBI_PLUGIN_URL . 'css/sb-instagram-admin.css', array(), SBIVER );
wp_enqueue_style( 'sb_instagram_admin_css' );
wp_enqueue_style( 'wp-color-picker' );
}
add_action( 'admin_enqueue_scripts', 'sb_instagram_admin_style' );
function sb_instagram_admin_scripts() {
wp_enqueue_script( 'sb_instagram_admin_js', SBI_PLUGIN_URL . 'js/sb-instagram-admin-6.js', array(), SBIVER, true );
wp_localize_script(
'sb_instagram_admin_js',
'sbiA',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'sbi_nonce' => wp_create_nonce( 'sbi_nonce' ),
)
);
$strings = array(
'addon_activate' => esc_html__( 'Activate', 'instagram-feed' ),
'addon_activated' => esc_html__( 'Activated', 'instagram-feed' ),
'addon_active' => esc_html__( 'Active', 'instagram-feed' ),
'addon_deactivate' => esc_html__( 'Deactivate', 'instagram-feed' ),
'addon_inactive' => esc_html__( 'Inactive', 'instagram-feed' ),
'addon_install' => esc_html__( 'Install Addon', 'instagram-feed' ),
'addon_error' => esc_html__( 'Could not install addon. Please download from wpforms.com and install manually.', 'instagram-feed' ),
'plugin_error' => esc_html__( 'Could not install a plugin. Please download from WordPress.org and install manually.', 'instagram-feed' ),
'addon_search' => esc_html__( 'Searching Addons', 'instagram-feed' ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'cancel' => esc_html__( 'Cancel', 'instagram-feed' ),
'close' => esc_html__( 'Close', 'instagram-feed' ),
'nonce' => wp_create_nonce( 'sbi-admin' ),
'almost_done' => esc_html__( 'Almost Done', 'instagram-feed' ),
'oops' => esc_html__( 'Oops!', 'instagram-feed' ),
'ok' => esc_html__( 'OK', 'instagram-feed' ),
'plugin_install_activate_btn' => esc_html__( 'Install and Activate', 'instagram-feed' ),
'plugin_install_activate_confirm' => esc_html__( 'needs to be installed and activated to import its forms. Would you like us to install and activate it for you?', 'instagram-feed' ),
'plugin_activate_btn' => esc_html__( 'Activate', 'instagram-feed' ),
);
$strings = apply_filters( 'sbi_admin_strings', $strings );
wp_localize_script(
'sb_instagram_admin_js',
'sbi_admin',
$strings
);
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'jquery-ui-core' );
wp_enqueue_script( 'jquery-ui-draggable' );
wp_enqueue_script( 'wp-color-picker' );
}
add_action( 'admin_enqueue_scripts', 'sb_instagram_admin_scripts' );
function sbi_formatted_error( $response ) {
if ( isset( $response['error'] ) ) {
$response['error']['message'] = str_replace( 'Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api', '', $response['error']['message'] );
$error = '
' . sprintf( __( 'API error %s:', 'instagram-feed' ), esc_html( $response['error']['code'] ) ) . ' ' . esc_html( $response['error']['message'] ) . ' ';
$error .= '
';
return $error;
} else {
$message = '
' . sprintf( __( 'Error connecting to %s.', 'instagram-feed' ), $response['url'] ) . ' ';
if ( isset( $response['response'] ) && isset( $response['response']->errors ) ) {
foreach ( $response['response']->errors as $key => $item ) {
$message .= '
' . esc_html( $key ) . ' - ' . esc_html( $item[0] ) . ' ';
}
}
$message .= '
';
return $message;
}
}
function sbi_connect_new_account( $access_token, $account_id ) {
$split_id = explode( ' ', trim( $account_id ) );
$account_id = preg_replace( '/[^A-Za-z0-9 ]/', '', $split_id[0] );
if ( ! empty( $account_id ) ) {
$split_token = explode( ' ', trim( $access_token ) );
$access_token = preg_replace( '/[^A-Za-z0-9 ]/', '', $split_token[0] );
}
$account = array(
'access_token' => $access_token,
'user_id' => $account_id,
'type' => 'business',
);
if ( sbi_code_check( $access_token ) ) {
$account['type'] = 'basic';
}
$connector = new SBI_Account_Connector();
$response = $connector->fetch( $account );
if ( isset( $response['access_token'] ) ) {
$connector->add_account_data( $response );
$connector->update_stored_account();
$connector->after_update();
return $connector->get_account_data();
} else {
return $response;
}
}
add_action( 'sbi_admin_notices', 'sbi_admin_error_notices' );
function sbi_admin_error_notices() {
global $sb_instagram_posts_manager;
if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'sbi-settings' ), true) ) {
$errors = $sb_instagram_posts_manager->get_errors();
if ( ! empty( $errors ) && (! empty( $errors['database_create'] ) || ! empty( $errors['upload_dir'] )) ) : ?>
get_critical_errors();
if ( $sb_instagram_posts_manager->are_critical_errors() ) :
?>
remove_all_errors();
sbi_clear_caches();
wp_send_json_success( '1' );
}
add_action( 'wp_ajax_sbi_reset_log', 'sbi_reset_log' );
function sb_instagram_settings_page() {
$link = admin_url( 'admin.php?page=sbi-settings' );
?>
array(
'full' => 640,
'low' => 320,
'thumb' => 150,
),
'business' => array(
'full' => 640,
'low' => 320,
'thumb' => 150,
),
), $upload_dir = null, $upload_url = null ) {
$this->post_data = $post_data;
$this->image_sizes = $image_sizes;
if ( ! isset( $upload_dir ) || ! isset( $upload_url ) ) {
$upload = wp_upload_dir();
$upload_dir = $upload['basedir'];
$upload_dir = trailingslashit( $upload_dir ) . SBI_UPLOADS_NAME;
$upload_url = trailingslashit( $upload['baseurl'] ) . SBI_UPLOADS_NAME;
}
$this->upload_dir = $upload_dir;
$this->upload_url = $upload_url;
$this->transient_name = $transient_name;
$this->fill_in_timestamp = $fill_in_timestamp;
}
/**
* @return array
*
* @since 2.0/4.0
*/
public function get_post_data() {
if ( is_array( $this->post_data ) ) {
return $this->post_data;
} else {
return array();
}
}
/**
* @return array
*
* @since 2.0/4.0
*/
public function get_resized_image_data_for_set() {
return $this->resized_image_data_for_set;
}
/**
* Loop through set of posts and update or create resized images based on
* whether or not they have been created and whether or not a record has been
* saved for this feed id
*
* @since 2.0/4.0
*/
public function maybe_save_update_and_resize_images_for_posts() {
global $sb_instagram_posts_manager;
$posts_iterated_through = 0;
$number_resized = 0;
$number_updated = 0;
$resized_image_data_for_set = array();
$resizing_disabled = $sb_instagram_posts_manager->image_resizing_disabled( $this->transient_name ) || $sb_instagram_posts_manager->max_resizing_per_time_period_reached();
$is_top_post_feed = ( substr( $this->transient_name, 4, 1 ) === '+' );
foreach ( $this->post_data as $single_instagram_post_data ) {
if ( isset( $single_instagram_post_data['id'] ) && $posts_iterated_through < 100 ) {
$single_post = new SB_Instagram_Post( $single_instagram_post_data['id'] );
$single_post->set_instagram_api_data( $single_instagram_post_data );
$resized_image_data_for_set[ $single_instagram_post_data['id'] ] = array();
if ( $is_top_post_feed ) {
if ( empty( $this->first_post_top_time_stamp ) ) {
$this_post_top_time_stamp = $single_post->get_top_time_stamp();
if ( empty( $this_post_top_time_stamp ) ) {
$this->first_post_top_time_stamp = $this->fill_in_timestamp;
} else {
$this->first_post_top_time_stamp = $single_post->get_top_time_stamp();
}
}
}
if ( ! $resizing_disabled ) {
if ( ( ! $single_post->exists_in_posts_table() || ! $single_post->images_done_resizing() ) && $number_resized < 30 ) {
if ( $sb_instagram_posts_manager->max_total_records_reached() ) {
$sb_instagram_posts_manager->delete_least_used_image();
}
if ( ! $single_post->images_done_resizing() && $single_post->exists_in_posts_table() ) {
$single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url );
} else {
if ( $is_top_post_feed ) {
if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - ( 120 * $posts_iterated_through ) - 1 ) ) ) {
$single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url );
}
} else {
if ( $single_post->save_in_db( $this->transient_name, date( 'Y-m-d H:i:s', strtotime( $this->fill_in_timestamp ) - ( 120 * $posts_iterated_through ) ) ) ) {
$single_post->resize_and_save_image( $this->image_sizes, $this->upload_dir, $this->upload_url );
}
}
}
$number_resized++;
} else {
if ( $is_top_post_feed ) {
$single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url, date( 'Y-m-d H:i:s', strtotime( $this->first_post_top_time_stamp ) - ( 120 * $posts_iterated_through ) ) );
} else {
$single_post->update_db_data( true, $this->transient_name, $this->image_sizes, $this->upload_dir, $this->upload_url );
}
if ( ! $single_post->exists_in_feeds_posts_table( $this->transient_name ) ) {
$single_post->insert_sbi_instagram_feeds_posts( $this->transient_name );
}
$number_updated++;
}
$resized_image_data_for_set[ $single_instagram_post_data['id'] ] = $single_post->get_resized_image_array();
}
}
$posts_iterated_through++;
}
$this->resized_image_data_for_set = $resized_image_data_for_set;
}
}
inc/class-sb-instagram-education.php 0000644 00000011712 15051507456 0013503 0 ustar 00 hooks();
}
/**
* Hooks.
*
* @since 5.5
*/
public function hooks() {
$this->plugin_version = sbi_is_pro_version() ? 'pro' : 'free';
}
/**
* "Did You Know?" messages.
*
* @since 5.5
*/
public function dyk_messages() {
$free_messages = array(
array(
'title' => esc_html__( 'Get the Most out of Hashtags', 'instagram-feed' ),
'content' => esc_html__( 'You can use hashtags on Instagram for so many things; targeted promotions, engaging with your audience, running contests, or just for categorizing posts. Learn more about how you can display Instagram hashtag feeds on your website using the Instagram Feed Pro plugin.', 'instagram-feed' ),
'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=hashtag#hashtag',
'item' => 1,
),
array(
'title' => esc_html__( 'Keep Visitors on Your Site', 'instagram-feed' ),
'content' => esc_html__( "You've done the hard work of getting a visitor onto your site, now keep them there by displaying your Instagram content inside a pop-up lightbox, rather than sending your visitors away to Instagram. Learn more about the Instagram Feed Pro lightbox feature.", 'instagram-feed' ),
'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=popuplightbox#popuplightbox',
'item' => 2,
),
array(
'title' => esc_html__( 'Highlight Your Posts and Create Carousels', 'instagram-feed' ),
'content' => esc_html__( "Feature specific Instagram posts in your feeds by using the Highlight layout to feature specific posts, either by using their ID or a hashtag in their caption. Also create rotating carousels of your photos and videos to best utilize the space on your site. These layouts and more are available in our Pro version.", 'instagram-feed' ),
'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=highlight#highlight',
'item' => 3,
),
array(
'title' => esc_html__( 'Moderate your Feed Content', 'instagram-feed' ),
'content' => esc_html__( "Control exactly which posts show up in your feed by using the Visual Moderation Mode feature to pick and choose what to display. Remove specific posts or create a whitelist of approved content using Instagram Feed Pro.", 'instagram-feed' ),
'more' => 'https://smashballoon.com/instagram-feed/features/?utm_campaign=instagram-free&utm_source=dyk-messages&utm_content=moderation#moderation',
'item' => 4,
),
);
$pro_messages = array(
array(
'title' => esc_html__( 'Automated YouTube Live Streaming', 'instagram-feed' ),
'content' => esc_html__( 'You can automatically feed live YouTube videos to your website using our Feeds For YouTube Pro plugin. It takes all the hassle out of publishing live videos to your site by automating the process.', 'instagram-feed' ),
'more' => 'https://smashballoon.com/youtube-feed/',
'item' => 1,
),
array(
'title' => esc_html__( 'Display Facebook Pages and Groups', 'instagram-feed' ),
'content' => esc_html__( 'Have a Facebook Page or Group? Easily embed a feed of posts into your website, delivering fresh content automatically to your site from Facebook. Posts, Photos, Events, Videos, Albums, Reviews, and more!', 'instagram-feed' ),
'more' => 'https://smashballoon.com/custom-facebook-feed/',
'item' => 2,
),
array(
'title' => esc_html__( 'Adding Social Proof with Twitter Feeds', 'instagram-feed' ),
'content' => esc_html__( 'Twitter testimonials are one of the best ways to add verifiable social proof to your website. They add credibility to your brand, product, or service by displaying reviews from real people to your site, helping to convert more visitors into customers. Our free Custom Twitter Feeds plugin makes displaying Tweets on your website a breeze.', 'instagram-feed' ),
'more' => 'https://wordpress.org/plugins/custom-twitter-feeds/',
'item' => 3,
),
);
if ( $this->plugin_version === 'pro' ) {
return $pro_messages;
}
return $free_messages;
}
/**
* "Did You Know?" random message.
*
* @since 5.5
*/
public function dyk_message_rnd() {
$messages = $this->dyk_messages();
$index = array_rand( $messages );
return $messages[ $index ];
}
/**
* "Did You Know?" display message.
*
* @since 5.5
*
*/
public function dyk_display() {
$dyk_message = $this->dyk_message_rnd();
if ( ! empty( $dyk_message['more'] ) ) {
//utm_source=plugin-pro&utm_campaign=
$dyk_message['more'] = add_query_arg(
array(
'utm_source' => 'issueemail',
'utm_campaign' => 'instagram-'.$this->plugin_version,
'utm_medium' => $dyk_message['item'],
),
$dyk_message['more']
);
}
return $dyk_message;
}
}
inc/class-sb-instagram-feed.php 0000644 00000152460 15051507456 0012441 0 ustar 00 regular_feed_transient_name = $transient_name;
$this->backup_feed_transient_name = SBI_BACKUP_PREFIX . $transient_name;
$sbi_header_transient_name = str_replace( 'sbi_', 'sbi_header_', $transient_name );
$sbi_header_transient_name = substr($sbi_header_transient_name, 0, 44);
$this->header_transient_name = $sbi_header_transient_name;
$this->backup_header_transient_name = SBI_BACKUP_PREFIX . $sbi_header_transient_name;
$this->post_data = array();
$this->next_pages = array();
$this->cached_feed_error = array();
$this->pages_created = 0;
$this->should_paginate = true;
// this is a count of how many api calls have been made for each feed
// type and term.
// By default the limit is 10
$this->num_api_calls = 0;
$this->max_api_calls = apply_filters( 'sbi_max_concurrent_api_calls', 10 );
$this->should_use_backup = false;
// used for errors and the sbi_debug report
$this->report = array();
$this->resized_images = array();
$this->one_post_found = false;
}
public function get_feed_id() {
return str_replace( '*', '', $this->regular_feed_transient_name );
}
public function set_cache( $cache_seconds, $settings ) {
$feed_id = $this->regular_feed_transient_name;
$feed_page = 1;
$this->encryption = new SB_Instagram_Data_Encryption();
$this->cache = new SB_Instagram_Cache( $feed_id, $feed_page, $cache_seconds );
$this->cache->retrieve_and_set();
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_post_data() {
return $this->post_data;
}
/**
* @return array
*
* @since 2.7/5.10
*/
public function get_cached_feed_error() {
return $this->cached_feed_error;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_next_pages() {
return $this->next_pages;
}
/**
* @return array
*
* @since 2.1.1/5.2.1
*/
public function get_resized_images() {
return $this->resized_images;
}
/**
* @since 2.0/5.0
*/
public function set_post_data( $post_data ) {
$this->post_data = $post_data;
}
/**
* @since 2.1.1/5.2.1
*/
public function set_resized_images( $resized_image_data ) {
$this->resized_images = $resized_image_data;
}
public function set_pages_created( $num ) {
$this->pages_created = $num;
}
/**
* Checks the database option related the transient expiration
* to ensure it will be available when the page loads
*
* @return bool
*
* @since 2.0/4.0
*/
public function regular_cache_exists() {
return ! $this->cache->is_expired( 'posts' );
}
/**
* Checks the database option related the header transient
* expiration to ensure it will be available when the page loads
*
* @return bool
*
* @since 2.0/5.0
*/
public function regular_header_cache_exists() {
return ! $this->cache->is_expired( 'header' );
}
/**
* @return bool
*
* @since 2.0/5.0
*/
public function should_use_backup() {
return $this->should_use_backup || empty( $this->post_data );
}
public function should_cache_error() {
global $sb_instagram_posts_manager;
$error_messages = $sb_instagram_posts_manager->get_frontend_errors();
if ( ! empty( $error_messages ) ) {
$this->cached_feed_error = $error_messages;
return true;
}
return false;
}
/**
* The header is only displayed when the setting is enabled and
* an account has been connected
*
* Overwritten in the Pro version
*
* @param array $settings settings specific to this feed
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
*
* @return bool
*
* @since 2.0/5.0
*/
public function need_header( $settings, $feed_types_and_terms ) {
$customizer = $settings['customizer'];
if( $customizer ){
return true;
}else{
$showheader = ($settings['showheader'] === 'on' || $settings['showheader'] === 'true' || $settings['showheader'] === true);
return ($showheader && isset( $feed_types_and_terms['users'] ));
}
}
/**
* Use the transient name to retrieve cached data for header
*
* @since 2.0/5.0
*/
public function set_header_data_from_cache() {
$header_json = $this->cache->get( 'header' );
$header_cache = json_decode( $header_json, true );
if ( ! empty( $header_cache ) ) {
$this->header_data = $header_cache;
}
}
public function set_header_data( $header_data ) {
$this->header_data = $header_data;
}
/**
* @since 2.0/5.0
*/
public function get_header_data() {
return $this->header_data;
}
/**
* Sets the post data, pagination data, shortcode atts used (cron cache),
* and timestamp of last retrieval from transient (cron cache)
*
* @param array $atts available for cron caching
*
* @since 2.0/5.0
*/
public function set_post_data_from_cache( $atts = array() ) {
$posts_json = $this->cache->get( 'posts' );
$posts_data = json_decode( $posts_json, true );
if ( $posts_data ) {
$post_data = isset( $posts_data['data'] ) ? $posts_data['data'] : array();
$this->post_data = $post_data;
$this->next_pages = isset( $posts_data['pagination'] ) ? $posts_data['pagination'] : array();
$this->pages_created = isset( $posts_data['pages_created'] ) ? $posts_data['pages_created'] : 0;
if ( isset( $posts_data['atts'] ) ) {
$this->transient_atts = $posts_data['atts'];
$this->last_retrieve = $posts_data['last_retrieve'];
}
if ( isset( $posts_data['errors'] ) ) {
$this->cached_feed_error = $posts_data['errors'];
}
$this->add_report( 'pages created: ' . $this->pages_created .', next pages exist: ' . ! empty( $this->next_pages ) );
}
}
/**
* Sets post data from a permanent database backup of feed
* if it was created
*
* @since 2.0/5.0
* @since 2.0/5.1.2 if backup feed data used, header data also set from backup
*/
public function maybe_set_post_data_from_backup() {
$backup_data = $this->cache->get( 'posts_backup' );
if ( $backup_data ) {
$backup_data = json_decode( $backup_data, true );
$post_data = isset( $backup_data['data'] ) ? $backup_data['data'] : array();
$this->post_data = $post_data;
$this->next_pages = isset( $backup_data['pagination'] ) ? $backup_data['pagination'] : array();
if ( isset( $backup_data['atts'] ) ) {
$this->transient_atts = $backup_data['atts'];
$this->last_retrieve = $backup_data['last_retrieve'];
}
$this->maybe_set_header_data_from_backup();
return true;
} else {
$this->add_report( 'no backup post data found' );
return false;
}
}
/**
* Sets header data from a permanent database backup of feed
* if it was created
*
* @since 2.0/5.0
*/
public function maybe_set_header_data_from_backup() {
$backup_header_data = $this->cache->get( 'header_backup' );
if ( ! empty( $backup_header_data ) ) {
$backup_header_data = json_decode( $backup_header_data, true );
$this->header_data = $backup_header_data;
return true;
} else {
$this->add_report( 'no backup header data found' );
return false;
}
}
/**
* Returns recorded image IDs for this post set
* for use with image resizing
*
* @return array
*
* @since 2.0/5.0
*/
public function get_image_ids_post_set() {
return $this->image_ids_post_set;
}
/**
* Retrieves data related to resized images from custom
* tables using either a number, offset, and transient name
* or the ids of the posts.
*
* Retrieving by offset and transient name not used currently
* but may be needed in future updates.
*
* @param array/int $num_or_array_of_ids post ids from the Instagram
* API
* @param int $offset number of records to skip
* @param string $transient_name ID of the feed
*
* @return array
*
* @since 2.0/5.0
*/
public static function get_resized_images_source_set( $num_or_array_of_ids, $offset = 0, $transient_name = '', $should_cache = true ) {
global $sb_instagram_posts_manager;
if ( $sb_instagram_posts_manager->image_resizing_disabled( $transient_name ) ) {
return array();
}
$feed_id = $transient_name;
$feed_page = 1;
$cache_obj = new SB_Instagram_Cache( $feed_id, $feed_page, HOUR_IN_SECONDS );
$cache_obj->retrieve_and_set();
$cache = $offset === 0 ? $cache_obj->get( 'resized_images' ) : false;
if ( $cache ) {
$return = json_decode( $cache, true );
} else {
global $wpdb;
$offset = max( 0, $offset );
$posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
$feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
$feed_id_array = explode( '#', $transient_name );
$feed_id = $feed_id_array[0];
if ( is_array( $num_or_array_of_ids ) ) {
$ids = $num_or_array_of_ids;
$id_string = "'" . implode( "','", $ids ) . "'";
$results = $wpdb->get_results( "
SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes
FROM $posts_table_name AS p
INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
WHERE p.instagram_id IN($id_string)
AND p.images_done = 1", ARRAY_A );
$return = array();
if ( !empty( $results ) && is_array( $results ) ) {
foreach ( $results as $result ) {
$sizes = maybe_unserialize( $result['sizes'] );
if ( ! is_array( $sizes ) ) {
$sizes = array( 'full' => 640 );
}
$return[ $result['instagram_id'] ] = array(
'id' => $result['media_id'],
'ratio' => $result['aspect_ratio'],
'sizes' => $sizes
);
}
}
} else {
$num = $num_or_array_of_ids;
$results = $wpdb->get_results( $wpdb->prepare( "
SELECT p.media_id, p.instagram_id, p.aspect_ratio, p.sizes
FROM $posts_table_name AS p
INNER JOIN $feeds_posts_table_name AS f ON p.id = f.id
WHERE f.feed_id = %s
AND p.images_done = 1
ORDER BY p.time_stamp
DESC LIMIT %d, %d", $feed_id, $offset, (int)$num ), ARRAY_A );
$return = array();
if ( !empty( $results ) && is_array( $results ) ) {
foreach ( $results as $result ) {
$sizes = maybe_unserialize( $result['sizes'] );
if ( ! is_array( $sizes ) ) {
$sizes = array( 'full' => 640 );
}
$return[ $result['instagram_id'] ] = array(
'id' => $result['media_id'],
'ratio' => $result['aspect_ratio'],
'sizes' => $sizes
);
}
}
}
if ( $offset === 0 && $should_cache ) {
$cache_obj->update_or_insert( 'resized_images', sbi_json_encode( $return ) );
}
}
return $return;
}
/**
* The plugin tracks when a post was last requested so only the most
* recently displayed posts are kept in the database.
* This function updates the timestamp for a set of posts
* on the page.
*
* @param $array_of_ids
*
* @since 2.0/5.0
*/
public static function update_last_requested( $array_of_ids ) {
if ( empty( $array_of_ids ) ) {
return;
}
global $wpdb;
$table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
$id_string = "'" . implode( "','", $array_of_ids ) . "'";
$query = $wpdb->query( $wpdb->prepare( "UPDATE $table_name
SET last_requested = %s
WHERE instagram_id IN ({$id_string});", date( 'Y-m-d H:i:s' ) ) );
}
/**
* Cron caching needs additional data saved in the transient
* to work properly. This function checks to make sure it's present
*
* @return bool
*
* @since 2.0/5.0
*/
public function need_to_start_cron_job() {
return (( ! empty( $this->post_data ) && ! isset( $this->transient_atts )) || (empty( $this->post_data ) && empty( $this->cached_feed_error )));
}
/**
* Checks to see if there are enough posts available to create
* the current page of the feed
*
* @param int $num
* @param int $offset
*
* @return bool
*
* @since 2.0/5.0
*/
public function need_posts( $num, $offset = 0, $page = 0 ) {
$num_existing_posts = is_array( $this->post_data ) ? count( $this->post_data ) : 0;
$num_needed_for_page = (int)$num + (int)$offset;
$this->add_report( 'pages created ' .$this->pages_created . ' page on' . $page );
if ( $this->pages_created < $page ) {
$this->add_report( 'need another page' );
return true;
}
($num_existing_posts < $num_needed_for_page) ? $this->add_report( 'need more posts ' . $num_existing_posts . ' ' . $num_needed_for_page ) : $this->add_report( 'have enough posts' );
return ($num_existing_posts < $num_needed_for_page);
}
/**
* Checks to see if there are additional pages available for any of the
* accounts in the feed and that the max conccurrent api request limit
* has not been reached
*
* @return bool
*
* @since 2.0/5.0
*/
public function can_get_more_posts() {
$one_type_and_term_has_more_ages = $this->next_pages !== false;
$max_concurrent_api_calls_not_met = $this->num_api_calls < $this->max_api_calls;
$max_concurrent_api_calls_not_met ? $this->add_report( 'max conccurrent requests not met' ) : $this->add_report( 'max concurrent met' );
$one_type_and_term_has_more_ages ? $this->add_report( 'more pages available' ) : $this->add_report( 'no next page' );
return ($one_type_and_term_has_more_ages && $max_concurrent_api_calls_not_met);
}
/**
* Appends one filtered API request worth of posts for each feed term
*
* @param $settings
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
* @param array $connected_accounts_for_feed connected account data for the
* feed types and terms
*
* @since 2.0/5.0
* @since 2.0/5.1 added logic to make a second attempt at an API connection
* @since 2.0/5.1.2 remote posts only retrieved if API requests are not
* delayed, terms shuffled if there are more than 5
* @since 2.2/5.3 added logic to refresh the access token for basic display
* accounts if needed before using it in an API request
*/
public function add_remote_posts( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) {
$this->pages_created ++;
$new_post_sets = array();
$next_pages = $this->next_pages;
global $sb_instagram_posts_manager;
/**
* Number of posts to retrieve in each API call
*
* @param int Minimum number of posts needed in each API request
* @param array $settings Settings for this feed
*
* @since 2.0/5.0
*/
$num = apply_filters( 'sbi_num_in_request', $settings['minnum'], $settings );
$num = max( $num, (int)$settings['apinum'] );
$params = array(
'num' => $num
);
$one_successful_connection = false;
$one_post_found = false;
$next_page_found = false;
$one_api_request_delayed = false;
foreach ( $feed_types_and_terms as $type => $terms ) {
if ( is_array( $terms ) && count( $terms ) > 5 ) {
shuffle( $terms );
}
foreach ( $terms as $term_and_params ) {
if ( isset( $term_and_params['one_time_request'] ) ) {
$params['num'] = 13;
}
$term = $term_and_params['term'];
$params = array_merge( $params, $term_and_params['params'] );
if ( ! isset( $term_and_params['error'] )
&& (! isset( $next_pages[ $term . '_' . $type ] ) || $next_pages[ $term . '_' . $type ] !== false) ) {
$connected_account_for_term = isset( $connected_accounts_for_feed[ $term ] ) ? $connected_accounts_for_feed[ $term ] : array();
$account_type = isset( $connected_account_for_term['type'] ) ? $connected_account_for_term['type'] : 'personal';
// basic account access tokens need to be refreshed every 60 days
// normally done using WP Cron but can be done here as a fail safe
if ( $account_type === 'basic' ) {
if ( SB_Instagram_Token_Refresher::refresh_time_has_passed_threshold( $connected_account_for_term )
&& SB_Instagram_Token_Refresher::minimum_time_interval_since_last_attempt_has_passed( $connected_account_for_term ) ) {
$refresher = new SB_Instagram_Token_Refresher( $connected_account_for_term );
$refresher->attempt_token_refresh();
if ( $refresher->get_last_error_code() === 10 ) {
sbi_update_connected_account( $connected_accounts_for_feed[ $term ]['user_id'], array( 'private' => true ) );
$this->add_report( 'token needs refreshing ' . $term . '_' . $type );
} else {
$this->add_report( 'trying to refresh token ' . $term . '_' . $type );
}
}
}
if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
$next_page_term = $next_pages[ $term . '_' . $type ];
if ( strpos( $next_page_term, 'https://' ) !== false ) {
$connection = $this->make_api_connection( $next_page_term );
} else {
$params['cursor'] = $next_page_term;
$connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
}
} else {
$connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
}
$this->add_report( 'api call made for ' . $term . ' - ' . $type );
$connection->connect();
$this->num_api_calls++;
if ( ! $connection->has_encryption_error() && ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
$one_successful_connection = true;
if ( $type === 'hashtags_top' ) {
SB_Instagram_Posts_Manager::maybe_update_list_of_top_hashtags( $term_and_params['hashtag_name'] );
}
$sb_instagram_posts_manager->remove_error( 'connection', $connected_account_for_term );
$data = $connection->get_data();
if ( !$connected_account_for_term['is_valid'] ) {
$this->add_report( 'clearing invalid token' );
$this->clear_expired_access_token_notice( $connected_account_for_term );
}
if ( isset( $data[0]['id'] ) ) {
$one_post_found = true;
$post_set = $this->filter_posts( $data, $settings );
$post_set['term'] = $this->get_account_term( $term_and_params );
$new_post_sets[] = $post_set;
}
$next_page = $connection->get_next_page( $type );
if ( ! empty( $next_page ) ) {
$next_pages[ $term . '_' . $type ] = $next_page;
$next_page_found = true;
} else {
$next_pages[ $term . '_' . $type ] = false;
}
// One time requests are broken into smaller API requests
// to avoid an API error "1" due to too much data
if ( isset( $term_and_params['one_time_request'] ) && ! empty( $next_pages[ $term . '_' . $type ] ) ) {
for ( $k = 1; $k <= 3; $k++ ) {
if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
$next_page_term = $next_pages[ $term . '_' . $type ];
if ( strpos( $next_page_term, 'https://' ) !== false ) {
$additional_connection = $this->make_api_connection( $next_page_term );
} else {
$params['cursor'] = $next_page_term;
$additional_connection = $this->make_api_connection( $connected_account_for_term, $type, $params );
}
$additional_connection->connect();
}
if ( isset( $additional_connection )
&& ! $additional_connection->is_wp_error()
&& ! $additional_connection->is_instagram_error() ) {
$additional_data = $additional_connection->get_data();
if ( isset( $additional_data[0]['id'] ) ) {
$one_post_found = true;
$post_set = $this->filter_posts( $additional_data, $settings );
$post_set['term'] = $this->get_account_term( $term_and_params );
$new_post_sets[] = $post_set;
$this->add_report( 'additional posts sets found in loop ' . $k );
}
$next_page = $additional_connection->get_next_page( $type );
if ( ! empty( $next_page ) ) {
$next_pages[ $term . '_' . $type ] = $next_page;
$next_page_found = true;
} else {
$next_pages[ $term . '_' . $type ] = false;
}
}
}
}
} else {
if ( $this->can_try_another_request( $type, $connected_accounts_for_feed[ $term ] ) ) {
$this->add_report( 'trying other accounts' );
$i = 0;
$attempted = array( $connected_accounts_for_feed[ $term ]['access_token'] );
$success = false;
$different = true;
$error = false;
while ( $different
&& ! $success
&& $this->can_try_another_request( $type, $connected_accounts_for_feed[ $term ], $i ) ) {
$different = $this->get_different_connected_account( $type, $attempted );
$this->add_report( 'trying the account ' . $different['user_id'] );
if ( $different ) {
$connected_accounts_for_feed[ $term ] = $this->get_different_connected_account( $type, $attempted );
$attempted[] = $connected_accounts_for_feed[ $term ]['user_id'];
if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
$new_connection = $this->make_api_connection( $next_pages[ $term . '_' . $type ] );
} else {
$new_connection = $this->make_api_connection( $connected_accounts_for_feed[ $term ], $type, $params );
}
$this->num_api_calls++;
if ( ! $new_connection->is_wp_error() && ! $new_connection->is_instagram_error() ) {
$one_successful_connection = true;
$success = true;
$sb_instagram_posts_manager->maybe_remove_display_error( 'hashtag_limit' );
$data = $new_connection->get_data();
if ( isset( $data[0]['id'] ) ) {
$one_post_found = true;
$post_set = $this->filter_posts( $data, $settings );
$post_set['term'] = $this->get_account_term( $term_and_params );
$new_post_sets[] = $post_set;
}
$next_page = $new_connection->get_next_page( $type );
if ( ! empty( $next_page ) ) {
$next_pages[ $term . '_' . $type ] = $next_page;
$next_page_found = true;
} else {
$next_pages[ $term . '_' . $type ] = false;
}
} else {
if ( $new_connection->is_wp_error() ) {
$error = $new_connection->get_wp_error();
} else {
$error = $new_connection->get_data();
}
}
$i++;
} else {
$error = $connection->get_data();
}
}
if ( ! $success && $error ) {
if ( $connection->is_wp_error() ) {
SB_Instagram_API_Connect::handle_wp_remote_get_error( $error );
} else {
SB_Instagram_API_Connect::handle_instagram_error( $error, $connected_accounts_for_feed[ $term ], $type );
}
$next_pages[ $term . '_' . $type ] = false;
}
} else {
if ( $connection->is_wp_error() ) {
SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() );
} elseif ( $connection->has_encryption_error() ) {
$error = array(
'error' => array(
'code' => '999',
'message' => __( 'Your access token could not be decrypted on this website. Reconnect this account or go to our website to learn how to prevent this.', 'instagram-feed' )
)
);
SB_Instagram_API_Connect::handle_instagram_error( $error, $connected_accounts_for_feed[ $term ], $type );
} else {
SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $term ], $type );
}
$next_pages[ $term . '_' . $type ] = false;
}
}
}
}
}
if ( ! $one_successful_connection || ($one_api_request_delayed && empty( $new_post_sets )) ) {
$this->should_use_backup = true;
}
$posts = $this->merge_posts( $new_post_sets, $settings );
if ( ! $this->should_merge_after( $settings ) ) {
if ( ! empty( $this->post_data ) && is_array( $this->post_data ) ) {
$posts = array_merge( $this->post_data, $posts );
}
}
$posts = $this->sort_posts( $posts, $settings );
if ( $this->should_merge_after( $settings ) ) {
if ( ! empty( $this->post_data ) && is_array( $this->post_data ) ) {
$posts = array_merge( $this->post_data, $posts );
}
}
if ( $one_post_found ) {
$this->one_post_found = true;
}
$this->post_data = $posts;
if ( isset( $next_page_found ) && $next_page_found ) {
$this->next_pages = $next_pages;
} else {
$this->next_pages = false;
}
}
/**
* Connects to the Instagram API and records returned data
*
* @param $settings
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
* @param array $connected_accounts_for_feed connected account data for the
* feed types and terms
*
* @since 2.0/5.0
* @since 2.2/5.3 added logic to append bio data from the related
* connected account if not available in the API response
*/
public function set_remote_header_data( $settings, $feed_types_and_terms, $connected_accounts_for_feed ) {
$first_user = $this->get_first_user( $feed_types_and_terms );
if ( ! empty( $settings['headersource'] ) ) {
foreach ( $connected_accounts_for_feed as $connected_account ) {
if ( $connected_account['username'] === $settings['headersource'] ) {
$first_user = $connected_account['user_id'];
} elseif ( $connected_account['user_id'] === $settings['headersource'] ) {
$first_user = $connected_account['user_id'];
}
}
}
$this->header_data = false;
global $sb_instagram_posts_manager;
$api_requests_delayed = isset( $connected_accounts_for_feed[ $first_user ] ) ? $sb_instagram_posts_manager->are_current_api_request_delays( $connected_accounts_for_feed[ $first_user ] ) : false;
if ( isset( $connected_accounts_for_feed[ $first_user ] ) && ! $api_requests_delayed ) {
$connection = new SB_Instagram_API_Connect( $connected_accounts_for_feed[ $first_user ], 'header', array() );
$connection->connect();
if ( ! $connection->has_encryption_error() && ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
$this->header_data = $connection->get_data();
$this->header_data['local_avatar'] = false;
$sb_instagram_posts_manager->remove_error( 'connection', $connected_accounts_for_feed[ $first_user ] );
$single_source = InstagramFeed\Builder\SBI_Source::update_single_source( $connected_accounts_for_feed[ $first_user ] );
if ( ! empty( $single_source['local_avatar_url'] ) ) {
$this->header_data['local_avatar'] = $single_source['local_avatar_url'];
}
if( isset( $this->header_data['biography'] ) && ! empty( $this->header_data['biography'] ) ) {
$this->header_data['bio'] = sbi_decode_emoji( $this->header_data['biography'] );
}
} else {
$this->should_use_backup = true;
if ( $connection->is_wp_error() ) {
SB_Instagram_API_Connect::handle_wp_remote_get_error( $connection->get_wp_error() );
} else {
SB_Instagram_API_Connect::handle_instagram_error( $connection->get_data(), $connected_accounts_for_feed[ $first_user ], 'header' );
}
}
}
}
/**
* Stores feed data in a transient for a specified time
*
* @param int $cache_time
* @param bool $save_backup
* @param bool $force_cache
*
* @since 2.0/5.0
* @since 2.0/5.1 duplicate posts removed
*/
public function cache_feed_data( $cache_time, $save_backup = true, $force_cache = false ) {
if ( ! empty( $this->post_data ) || ! empty( $this->next_pages ) || ! empty( $this->cached_feed_error ) || $force_cache ) {
$this->remove_duplicate_posts();
$this->trim_posts_to_max();
$to_cache = array(
'data' => $this->post_data,
'pagination' => $this->next_pages,
'pages_created' => $this->pages_created
);
global $sb_instagram_posts_manager;
$error_messages = $sb_instagram_posts_manager->get_frontend_errors();
if ( ! empty( $error_messages ) ) {
$to_cache['errors'] = $error_messages;
}
$this->cache->update_or_insert( 'posts', sbi_json_encode( $to_cache ) );
if ( $save_backup ) {
if ( isset( $to_cache['errors'] ) ) {
unset( $to_cache['errors'] );
}
$this->cache->update_or_insert( 'posts_backup', sbi_json_encode( $to_cache ) );
}
} else {
$this->add_report( 'no data not caching' );
}
}
/**
* Stores feed data with additional data specifically for cron caching
*
* @param array $to_cache feed data with additional things like the shortcode
* settings, when the cache was last requested, when new posts were last retrieved
* @param int $cache_time how long the cache will last
* @param bool $save_backup whether or not to also save this as a permanent cache
*
* @since 2.0/5.0
* @since 2.0/5.1 duplicate posts removed, cache set trimmed to a maximum
*/
public function set_cron_cache( $to_cache, $cache_time, $save_backup = true ) {
if ( ! empty( $this->post_data )
|| ! empty( $this->next_pages )
|| ! empty( $to_cache['data'] )
|| $this->should_cache_error() ) {
$this->remove_duplicate_posts();
$this->trim_posts_to_max();
$to_cache['data'] = isset( $to_cache['data'] ) ? $to_cache['data'] : $this->post_data;
$to_cache['pagination'] = isset( $to_cache['next_pages'] ) ? $to_cache['next_pages'] : $this->next_pages;
$to_cache['atts'] = isset( $to_cache['atts'] ) ? $to_cache['atts'] : $this->transient_atts;
$to_cache['last_requested'] = isset( $to_cache['last_requested'] ) ? $to_cache['last_requested'] : time();
$to_cache['last_retrieve'] = isset( $to_cache['last_retrieve'] ) ? $to_cache['last_retrieve'] : $this->last_retrieve;
global $sb_instagram_posts_manager;
$error_messages = $sb_instagram_posts_manager->get_frontend_errors();
if ( ! empty( $error_messages ) ) {
$to_cache['errors'] = $error_messages;
} else {
$to_cache['errors'] = array();
}
$this->cache->update_or_insert( 'posts', sbi_json_encode( $to_cache ) );
if ( $save_backup ) {
if ( ! empty( $this->post_data )
|| ! empty( $this->next_pages )
|| ! empty( $to_cache['data'] ) ) {
if ( isset( $to_cache['errors'] ) ) {
unset( $to_cache['errors'] );
}
$this->cache->update_or_insert( 'posts_backup', sbi_json_encode( $to_cache ) );
}
}
} else {
$this->add_report( 'no data not caching' );
}
}
/**
* Stores header data for a specified time as a transient
*
* @param int $cache_time
* @param bool $save_backup
*
* @since 2.0/5.0
*/
public function cache_header_data( $cache_time, $save_backup = true ) {
if ( $this->header_data ) {
$this->cache->update_or_insert( 'header', sbi_json_encode( $this->header_data ) );
if ( $save_backup ) {
if ( isset( $this->header_data['errors'] ) ) {
unset( $this->header_data['errors'] );
}
$this->cache->update_or_insert( 'header_backup', sbi_json_encode( $this->header_data ) );
}
}
}
/**
* Used to randomly trigger an updating of the last requested data for cron caching
*
* @return bool
*
* @since 2.0/5.0
*/
public function should_update_last_requested() {
return (rand( 1, 20 ) === 20);
}
/**
* Determines if pagination can and should be used based on settings and available feed data
*
* @param array $settings
* @param int $offset
*
* @return bool
*
* @since 2.0/5.0
*/
public function should_use_pagination( $settings, $offset = 0 ) {
if ( $settings['minnum'] < 1 ) {
return false;
}
$posts_available = count( $this->post_data ) - ($offset + $settings['num']);
$show_loadmore_button_by_settings = ($settings['showbutton'] == 'on' || $settings['showbutton'] == 'true' || $settings['showbutton'] == true ) && $settings['showbutton'] !== 'false';
if ( $show_loadmore_button_by_settings ) {
// used for permanent and whitelist feeds
if ( $this->feed_is_complete( $settings, $offset ) ) {
$this->add_report( 'no pagination, feed complete' );
return false;
}
if ( $posts_available > 0 ) {
$this->add_report( 'do pagination, posts available' );
return true;
}
$pages = $this->next_pages;
if ( $pages && ! $this->should_use_backup() ) {
foreach ( $pages as $page ) {
if ( ! empty( $page ) ) {
return true;
}
}
}
}
$this->add_report( 'no pagination, no posts available' );
return false;
}
/**
* Generates the HTML for the feed if post data is available. Although it seems
* some of the variables ar not used they are set here to hide where they
* come from when used in the feed templates.
*
* @param array $settings
* @param array $atts
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
* @param array $connected_accounts_for_feed connected account data for the
* feed types and terms
*
* @return false|string
*
* @since 2.0/5.0
*/
public function get_the_feed_html( $settings, $atts, $feed_types_and_terms, $connected_accounts_for_feed ) {
global $sb_instagram_posts_manager;
if ( empty( $this->post_data ) && ! empty( $connected_accounts_for_feed ) && $settings['minnum'] > 0 ) {
$this->handle_no_posts_found( $settings, $feed_types_and_terms );
}
$posts = array_slice( $this->post_data, 0, $settings['minnum'] );
$header_data = ! empty( $this->header_data ) ? $this->header_data : false;
$first_user = ! empty( $feed_types_and_terms['users'][0] ) ? $feed_types_and_terms['users'][0]['term'] : false;
$first_username = false;
if ( $first_user ) {
$first_username = isset( $connected_accounts_for_feed[ $first_user ]['username'] ) ? $connected_accounts_for_feed[ $first_user ]['username'] : $first_user;
} elseif ( $header_data ) { // in case no connected account for feed
$first_username = SB_Instagram_Parse::get_username( $header_data );
} elseif ( isset( $feed_types_and_terms['users'] ) && isset( $this->post_data[0] ) ) { // in case no connected account and no header
$first_username = SB_Instagram_Parse::get_username( $this->post_data[0] );
}
$use_pagination = $this->should_use_pagination( $settings, 0 );
$feed_id = $this->regular_feed_transient_name;
$shortcode_atts = ! empty( $atts ) ? sbi_json_encode( $atts ) : '{}';
$settings['header_outside'] = false;
$settings['header_inside'] = false;
if ( $header_data && $settings['showheader'] ) {
$settings['header_inside'] = true;
}
$other_atts = '';
$additional_classes = $this->get_feed_container_css_classes( $settings );
$other_atts .= ' data-postid="' . esc_attr( get_the_ID() ) . '"';
$other_atts .= ' data-locatornonce="' . esc_attr( wp_create_nonce( 'sbi-locator-nonce-' . get_the_ID() . '-' . $this->regular_feed_transient_name ) ) . '"';
$other_atts = $this->add_other_atts( $other_atts, $settings );
$flags = array();
if ( $sb_instagram_posts_manager->image_resizing_disabled( $feed_types_and_terms ) || $settings['isgutenberg'] ) {
$flags[] = 'resizeDisable';
} elseif ( $settings['favor_local'] ) {
$flags[] = 'favorLocal';
}
if ( $settings['disable_js_image_loading'] ) {
$flags[] = 'imageLoadDisable';
}
if ( $settings['ajax_post_load'] ) {
$flags[] = 'ajaxPostLoad';
}
if ( SB_Instagram_GDPR_Integrations::doing_gdpr( $settings ) ) {
$flags[] = 'gdpr';
if ( ! SB_Instagram_GDPR_Integrations::blocking_cdn( $settings ) ) {
$flags[] = 'overrideBlockCDN';
}
}
if ( ! $settings['isgutenberg']
&& SB_Instagram_Feed_Locator::should_do_ajax_locating( $this->regular_feed_transient_name, get_the_ID() ) ) {
$this->add_report( 'doing feed locating' );
$flags[] = 'locator';
}
if ( isset( $_GET['sbi_debug'] ) || isset( $_GET['sb_debug'] ) ) {
$flags[] = 'debug';
}
$flags = apply_filters( 'sbi_flags', $flags, $settings );
if ( ! empty( $flags ) ) {
$other_atts .= ' data-sbi-flags="' . implode(',', $flags ) . '"';
}
if ( $settings['customizer'] ) {
$settings['vue_args'] = [
'condition' => ' && $parent.valueIsEnabled($parent.customizerFeedData.settings.headeroutside)'
];
}
ob_start();
include sbi_get_feed_template_part( 'feed', $settings );
$html = ob_get_contents();
ob_get_clean();
if ( $settings['ajaxtheme'] ) {
$html .= $this->get_ajax_page_load_html();
}
return $html;
}
/**
* Generates HTML for individual sbi_item elements
*
* @param array $settings
* @param int $offset
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
* @param array $connected_accounts_for_feed connected account data for the
* feed types and terms
*
* @return false|string
*
* @since 2.0/5.0
*/
public function get_the_items_html( $settings, $offset, $feed_types_and_terms, $connected_accounts_for_feed ) {
if ( empty( $this->post_data ) ) {
ob_start();
$html = ob_get_contents();
ob_get_clean(); ?>
post_data, $offset, $settings['num'] );
ob_start();
$this->posts_loop( $posts, $settings, $offset );
$html = ob_get_contents();
ob_get_clean();
return $html;
}
/**
* Overwritten in the Pro version
*
* @return object
*/
public function make_api_connection( $connected_account_or_page, $type = NULL, $params = NULL ) {
return new SB_Instagram_API_Connect( $connected_account_or_page, $type, $params );
}
/**
* When the feed is loaded with AJAX, the JavaScript for the plugin
* needs to be triggered again. This function is a workaround that adds
* the file and settings to the page whenever the feed is generated.
*
* @return string
*
* @since 2.0/5.0
*/
public static function get_ajax_page_load_html() {
if ( SB_Instagram_Blocks::is_gb_editor() ) {
return '';
}
$sbi_options = sbi_get_database_settings();
$font_method = 'svg';
$upload = wp_upload_dir();
$resized_url = trailingslashit( $upload['baseurl'] ) . trailingslashit( SBI_UPLOADS_NAME );
$js_options = array(
'font_method' => $font_method,
'placeholder' => trailingslashit( SBI_PLUGIN_URL ) . 'img/placeholder.png',
'resized_url' => $resized_url,
'ajax_url' => admin_url( 'admin-ajax.php' ),
);
$encoded_options = sbi_json_encode( $js_options );
$js_option_html = '';
$js_option_html .= "";
return $js_option_html;
}
/**
* Overwritten in the Pro version
*
* @param $feed_types_and_terms
*
* @return string
*
* @since 2.1/5.2
*/
public function get_first_user( $feed_types_and_terms ) {
if ( isset( $feed_types_and_terms['users'][0] ) ) {
return $feed_types_and_terms['users'][0]['term'];
} if ( isset( $feed_types_and_terms['tagged'][0] ) ) {
return $feed_types_and_terms['tagged'][0]['term'];
} else {
return '';
}
}
/**
* Adds recorded strings to an array
*
* @param $to_add
*
* @since 2.0/5.0
*/
public function add_report( $to_add ) {
$this->report[] = $to_add;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_report() {
return $this->report;
}
/**
* Additional options/settings added to the main div
* for the feed
*
* Overwritten in the Pro version
*
* @param $other_atts
* @param $settings
*
* @return string
*/
protected function add_other_atts( $other_atts, $settings ) {
return $other_atts;
}
/**
* Used for filtering a single API request worth of posts
*
* Overwritten in the Pro version
*
* @param array $post_set a single set of post data from the api
*
* @return mixed|array
*
* @since 2.0/5.0
*/
protected function filter_posts( $post_set, $settings = array() ) {
// array_unique( $post_set, SORT_REGULAR);
if ( $settings['media'] === 'all' ) {
return $post_set;
}
$media_filter = $settings['media'] !== 'all' ? $settings['media'] : false;
if ( $media_filter ) {
$media_filter = is_array( $media_filter ) ? $media_filter : array( $media_filter );
}
$video_types = ! empty( $settings['videotypes'] ) ? explode( ',', str_replace( ' ', '', strtolower( $settings['videotypes'] ) ) ) : array( 'igtv', 'regular', 'reels' );
$filtered_posts = array();
foreach ( $post_set as $post ) {
$keep_post = false;
$is_hidden = false;
$passes_media_filter = true;
if ( $media_filter ) {
$media_type = SB_Instagram_Parse::get_media_type( $post );
if ( $media_type === 'video' && in_array( 'videos', $media_filter, true ) ) {
if ( ! empty( $video_types ) ) {
$video_type = SB_Instagram_Parse::get_media_product_type( $post );
$video_type = 'feed' === $video_type ? 'regular' : $video_type;
if ( ! in_array( $video_type, $video_types, true ) ) {
$passes_media_filter = false;
}
}
} elseif ( $media_type === 'video' && ! in_array( 'videos', $media_filter, true ) ) {
$passes_media_filter = false;
} elseif ( $media_type === 'image' && ! in_array( 'photos', $media_filter, true ) ) {
$passes_media_filter = false;
} elseif ( $media_type === 'carousel' && ! in_array( 'photos', $media_filter, true ) ) {
$passes_media_filter = false;
}
}
if ( ! $is_hidden && $passes_media_filter ) {
$keep_post = true;
}
$keep_post = apply_filters( 'sbi_passes_filter', $keep_post, $post, $settings );
if ( $keep_post ) {
$filtered_posts[] = $post;
}
}
return $filtered_posts;
}
protected function handle_no_posts_found( $settings = array(), $feed_types_and_terms = array() ) {
global $sb_instagram_posts_manager;
$error_message_return = array(
'error_message' => __( 'Error: No posts found.', 'instagram-feed' ),
'admin_only' => __( 'Make sure this account has posts available on instagram.com.', 'instagram-feed' ),
'frontend_directions' => '
' . __( 'Click here to troubleshoot', 'instagram-feed' ) . ' ',
'backend_directions' => '
' . __( 'Click here to troubleshoot', 'instagram-feed' ) . ' '
);
$sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
}
protected function remove_duplicate_posts() {
$posts = $this->post_data;
$ids_in_feed = array();
$non_duplicate_posts = array();
$removed = array();
foreach ( $posts as $post ) {
$post_id = SB_Instagram_Parse::get_post_id( $post );
if ( ! in_array( $post_id, $ids_in_feed, true ) ) {
$ids_in_feed[] = $post_id;
$non_duplicate_posts[] = $post;
} else {
$removed[] = $post_id;
}
}
$this->add_report( 'removed duplicates: ' . implode(', ', $removed ) );
$this->set_post_data( $non_duplicate_posts );
}
/**
* Used for limiting the cache size
*
* @since 2.0/5.1.1
*/
protected function trim_posts_to_max() {
if ( ! is_array( $this->post_data ) ) {
return;
}
$max = apply_filters( 'sbi_max_cache_size', 500 );
$this->set_post_data( array_slice( $this->post_data , 0, $max ) );
}
/**
* Used for permanent feeds or white list feeds to
* stop pagination if all posts are already added
*
* Overwritten in the Pro version
*
* @param array $settings
* @param int $offset
*
* @return bool
*
* @since 2.0/5.0
*/
protected function feed_is_complete( $settings, $offset = 0 ) {
return false;
}
/**
* @param $connected_account_for_term
*
* @since 2.0/5.1.2
*/
private function clear_expired_access_token_notice( $connected_account_for_term ) {
InstagramFeed\Builder\SBI_Source::clear_error( $connected_account_for_term['user_id'] );
}
/**
* Iterates through post data and tracks the index of the current post.
* The actual post ids of the posts are stored in an array so the plugin
* can search for local images that may be available.
*
* @param array $posts final filtered post data for the feed
* @param array $settings
* @param int $offset
*
* @since 2.0/5.0
*/
private function posts_loop( $posts, $settings, $offset = 0 ) {
$image_ids = array();
$post_index = $offset;
$icon_type = 'svg';
$resized_images = $this->get_resized_images();
foreach ( $posts as $post ) {
$image_ids[] = SB_Instagram_Parse::get_post_id( $post );
$account_type = SB_Instagram_Parse::get_account_type( $post );
include sbi_get_feed_template_part( 'item', $settings );
$post_index++;
}
$this->image_ids_post_set = $image_ids;
}
private function get_account_term( $term_and_params ) {
if ( isset( $term_and_params['hashtag_name'] ) ) {
return '#' . $term_and_params['hashtag_name'];
} else {
return '';
}
}
/**
* Uses array of API request results and merges them based on how
* the feed should be sorted. Mixed feeds are always sorted alternating
* since there is no post date for hashtag feeds.
*
*
* @param array $post_sets an array of single API request worth
* of posts
* @param array $settings
*
* @return array
*
* @since 2.0/5.0
*/
private function merge_posts( $post_sets, $settings ) {
$merged_posts = array();
if ( $settings['sortby'] === 'alternate'
|| $settings['sortby'] === 'api' && isset( $post_sets[1] ) ) {
// don't bother merging posts if there is only one post set
if ( isset( $post_sets[1] ) ) {
$min_cycles = $settings['sortby'] === 'api' ? min( 200 / count( $post_sets ) + 5, 50 ) : max( 1, (int)$settings['minnum'] );
$terms = array();
for( $i = 0; $i <= $min_cycles; $i++ ) {
$ii = 0;
foreach ( $post_sets as $post_set ) {
if ( isset( $post_sets[ $ii ]['term'] ) ) {
$term = $post_sets[ $ii ]['term'];
unset( $post_sets[ $ii ]['term'] );
if ( ! isset( $terms[ $ii ] ) ) {
$terms[ $ii ] = $term;
//
}
if ( strpos( $term, '#' ) !== false ) {
$post_index = 0;
foreach ( $post_sets[ $ii ] as $post ) {
$post_sets[ $ii ][ $post_index ]['term'] = $term;
$post_index++;
}
}
}
if ( isset( $post_set[ $i ] ) && isset( $post_set[ $i ]['id'] ) ) {
$post_set[ $i ]['term'] = $terms[ $ii ];
$merged_posts[] = $post_set[ $i ];
}
$ii++;
}
}
} else {
if ( isset( $post_sets[0]['term'] ) ) {
$term = $post_sets[0]['term'];
unset( $post_sets[0]['term'] );
if ( strpos( $term, '#' ) !== false ) {
$post_index = 0;
foreach ( $post_sets[0] as $post ) {
$post_sets[0][ $post_index ]['term'] = $term;
$post_index++;
}
}
}
$merged_posts = isset( $post_sets[0] ) ? $post_sets[0] : array();
}
} elseif ( $settings['sortby'] === 'api' ) {
if ( isset( $post_sets[0] ) ) {
if ( isset( $post_sets[0]['term'] ) ) {
$term = $post_sets[0]['term'];
unset( $post_sets[0]['term'] );
if ( strpos( $term, '#' ) !== false ) {
$post_index = 0;
foreach ( $post_sets[0] as $post ) {
$post_sets[0][ $post_index ]['term'] = $term;
$post_index++;
}
}
}
$post_set_index = 0;
foreach ( $post_sets as $post_set ) {
if ( isset( $post_sets[ $post_set_index ]['term'] ) ) {
$term = $post_sets[ $post_set_index ]['term'];
unset( $post_sets[ $post_set_index ]['term'] );
if ( strpos( $term, '#' ) !== false ) {
$post_index = 0;
foreach ( $post_sets[0] as $post ) {
$post_sets[ $post_set_index ][ $post_index ]['term'] = $term;
$post_index++;
}
}
}
$merged_posts = array_merge( $merged_posts, $post_set );
$post_set_index ++;
}
}
} else {
// don't bother merging posts if there is only one post set
if ( isset( $post_sets[1] ) ) {
$terms = array();
$ii = 0;
foreach ( $post_sets as $post_set ) {
if ( isset( $post_set[0]['id'] ) ) {
if ( isset( $post_sets[ $ii ]['term'] ) ) {
if ( ! isset( $terms[ $ii ] ) ) {
$terms[ $ii ] = $post_set['term'];
}
unset( $post_sets[ $ii ]['term'] );
$iii = 0;
foreach ( $post_sets[ $ii ] as $post ) {
$post_sets[ $ii ][ $iii ]['term'] = $terms[ $ii ];
$iii++;
}
}
$merged_posts = array_merge( $merged_posts, $post_sets[ $ii ] );
$ii++;
}
}
} else {
if ( isset( $post_sets[0]['term'] ) ) {
$term = $post_sets[0]['term'];
unset( $post_sets[0]['term'] );
if ( strpos( $term, '#' ) !== false ) {
$post_index = 0;
foreach ( $post_sets[0] as $post ) {
$post_sets[0][ $post_index ]['term'] = $term;
$post_index++;
}
}
}
$merged_posts = isset( $post_sets[0] ) ? $post_sets[0] : array();
}
}
if ( isset( $merged_posts['term'] ) ) {
unset( $merged_posts['term'] );
}
return $merged_posts;
}
/**
* Sorting by date will be more accurate for multi-term
* feeds if posts are merged before sorting.
*
* @param array $settings
*
* @return bool
*
* @since 5.10.1
*/
protected function should_merge_after( $settings ) {
if ( ! isset( $settings['sortby'] ) ) {
return false;
}
$merge_befores = array(
'alternate',
'api',
'random',
'likes'
);
if ( ! in_array( $settings['sortby'], $merge_befores, true ) ) {
return false;
}
return true;
}
/**
* Sorts a post set based on sorting settings. Sorting by "alternate"
* is done when merging posts for efficiency's sake so the post set is
* just returned as it is.
*
* Overwritten in the Pro version.
*
* @param array $post_set
* @param array $settings
*
* @return mixed|array
*
* @since 2.0/5.0
* @since 2.1/5.2 added filter hook for applying custom sorting
*/
protected function sort_posts( $post_set, $settings ) {
if ( empty( $post_set ) ) {
return $post_set;
}
// sorting done with "merge_posts" to be more efficient
if ( $settings['sortby'] === 'alternate' || $settings['sortby'] === 'api' ) {
$return_post_set = $post_set;
} elseif ( $settings['sortby'] === 'random' ) {
/*
* randomly selects posts in a random order. Cache saves posts
* in this random order so paginating does not cause some posts to show up
* twice or not at all
*/
usort($post_set, 'sbi_rand_sort' );
$return_post_set = $post_set;
} else {
// compares posted on dates of posts
usort($post_set, 'sbi_date_sort' );
$return_post_set = $post_set;
}
/**
* Apply a custom sorting of posts
*
* @param array $return_post_set Ordered set of filtered posts
* @param array $settings Settings for this feed
*
* @since 2.1/5.2
*/
return apply_filters( 'sbi_sorted_posts', $return_post_set, $settings );
}
/**
* Can trigger a second attempt at getting posts from the API
*
* Overwritten in the Pro version
*
* @param string $type
* @param array $connected_account_with_error
* @param int $attempts
*
* @return bool
*
* @since 2.0/5.1.1
*/
protected function can_try_another_request( $type, $connected_account_with_error, $attempts = 0 ) {
return false;
}
/**
* returns a second connected account if it exists
*
* Overwritten in the Pro version
*
* @param string $type
* @param array $attempted_connected_accounts
*
* @return bool
*
* @since 2.0/5.1.1
*/
protected function get_different_connected_account( $type, $attempted_connected_accounts ) {
return false;
}
/**
* Generates The Feed Container CSS classes
*
* @param array $settings
*
* @return string
*
* @since 6.0
*/
function get_feed_container_css_classes( $settings ){
$customizer = $settings['customizer'];
if($customizer){
}else{
$classes = array();
if ( empty( $settings['widthresp'] ) || $settings['widthresp'] == 'on' || $settings['widthresp'] == 'true' || $settings['widthresp'] === true ) {
if ( $settings['widthresp'] !== 'false' ) {
$classes[] = 'sbi_width_resp';
}
}
if ( ! empty( $settings['class'] ) ) {
$classes[] = esc_attr( $settings['class'] );
}
if ( ! empty( $settings['height'] )
&& (((int)$settings['height'] < 100 && $settings['heightunit'] === '%') || $settings['heightunit'] === 'px') ) {
$classes[] = 'sbi_fixed_height';
}
if ( ! empty( $settings['disablemobile'] )
&& ($settings['disablemobile'] == 'on' || $settings['disablemobile'] == 'true' || $settings['disablemobile'] == true) ) {
if ( $settings['disablemobile'] !== 'false' ) {
$classes[] = 'sbi_disable_mobile';
}
}
$additional_classes = '';
if ( ! empty( $classes ) ) {
$additional_classes = ' ' . implode( ' ', $classes );
}
return $additional_classes;
}
return '';
}
}
inc/class-sb-instagram-single.php 0000644 00000015325 15051507456 0013015 0 ustar 00 permalink = $permalink_or_permalink_id;
$exploded_permalink = explode( '/', $permalink_or_permalink_id );
$permalink_id = $exploded_permalink[4];
$this->permalink_id = $permalink_id;
} else {
$this->permalink_id = $permalink_or_permalink_id;
$this->permalink = 'https://www.instagram.com/p/' . $this->permalink_id;
}
$this->error = false;
$this->encryption = new SB_Instagram_Data_Encryption();
}
/**
* Sets post data from cache or fetches new data
* if it doesn't exist or hasn't been updated recently
*
* @since 2.5.3/5.8.3
*/
public function init() {
$this->post = $this->maybe_saved_data();
if ( empty( $this->post )
|| ! $this->was_recently_updated() ) {
if ( ! $this->should_delay_oembed_request() ) {
$data = $this->fetch();
if ( ! empty( $data ) ) {
$data = $this->parse_and_restructure( $data );
$this->post = $data;
$this->update_last_update_timestamp();
$this->update_single_cache();
} elseif ( $data === false ) {
$this->add_oembed_request_delay();
}
}
}
}
/**
* @return array
*
* @since 2.5.3/5.8.3
*/
public function get_post() {
return $this->post;
}
public function get_error() {
return $this->error;
}
/**
* Image URLs expire so this will compare when the data
* was last updated from the API
*
* @return bool
*
* @since 2.5.3/5.8.3
*/
public function was_recently_updated() {
if ( ! isset( $this->post['last_update'] ) ) {
return false;
}
return ( time() - 14 * DAY_IN_SECONDS ) < $this->post['last_update'];
}
/**
* Makes an HTTP request for fresh data from the oembed
* endpoint. Returns false if no new data or there isn't
* a business access token found.
*
* @return bool|mixed|null
*
* @since 2.5.3/5.8.3
*/
public function fetch() {
// need a connected business account for this to work
$access_token = SB_Instagram_Oembed::last_access_token();
if ( empty( $access_token ) ) {
$this->error = 'No access token';
return false;
}
$url = SB_Instagram_Oembed::oembed_url();
$fetch_url = add_query_arg(
array(
'url' => $this->permalink,
'access_token' => $access_token,
),
$url
);
$result = wp_remote_get( esc_url_raw( $fetch_url ) );
$data = false;
if ( ! is_wp_error( $result ) ) {
$data = isset( $result['body'] ) ? json_decode( $result['body'], true ) : false;
if ( $data && isset( $data['error'] ) ) {
$this->add_oembed_request_delay();
$this->error = sprintf( __( 'API error %s:', 'instagram-feed' ), $data['error']['code'] ) . ' ' . $data['error']['message'];
$data = false;
}
} else {
$error = '';
foreach ( $result->errors as $key => $item ) {
$error .= $key . ' - ' . $item[0] . ' ';
}
$this->error = $error;
}
return $data;
}
/**
* If there was a problem with the last oEmbed request, the plugin
* waits 5 minutes to try again to prevent burning out the access token
* or causing Instagram to throttle HTTP requests from the server
*
* @return bool
*
* @since 2.5.3/5.8.3
*/
public function should_delay_oembed_request() {
return ( get_transient( 'sbi_delay_oembeds_' . $this->permalink_id ) !== false );
}
/**
* If there's an error, API requests are delayed 5 minutes
* for the specific permalink/post
*
* @since 2.5.3/5.8.3
*/
public function add_oembed_request_delay() {
set_transient( 'sbi_delay_oembeds_' . $this->permalink_id, true, 300 );
}
/**
* Track last API request due to some data expiring and
* needing to be refreshed
*
* @since 2.5.3/5.8.3
*/
private function update_last_update_timestamp() {
$this->post['last_update'] = time();
}
/**
* Data retrieved with this method has it's own cache
*
* @since 2.5.3/5.8.3
*/
private function update_single_cache() {
$stored_option = get_option( 'sbi_single_cache', array() );
if ( ! is_array( $stored_option ) ) {
$stored_option = json_decode( $this->encryption->decrypt( $stored_option ), true );
}
$new = array( $this->permalink_id => $this->post );
$stored_option = array_merge( $new, (array) $stored_option );
// only latest 400 posts
$stored_option = array_slice( $stored_option, 0, 400 );
update_option( 'sbi_single_cache', $this->encryption->encrypt( sbi_json_encode( $stored_option ) ), false );
}
/**
* Data is restructured to look like regular API data
* for ease of use with other plugin features
*
* @param $data array
*
* @return array
*
* @since 2.5.3/5.8.3
*/
private function parse_and_restructure( $data ) {
// TODO: parse all of the available data for this post, currently just thumbnail
$return = array(
'thumbnail_url' => '',
'id' => $this->permalink_id,
'media_type' => 'OEMBED',
);
if ( ! empty( $data['thumbnail_url'] ) ) {
$return['thumbnail_url'] = $data['thumbnail_url'];
}
apply_filters( 'sbi_single_parse_and_restructure', $return );
return $return;
}
/**
* Returns whatever data exists or empty array
*
* @return array
*
* @since 2.5.3/5.8.3
*/
private function maybe_saved_data() {
$stored_option = get_option( 'sbi_single_cache', array() );
if ( ! is_array( $stored_option ) ) {
$stored_option = json_decode( $this->encryption->decrypt( $stored_option ), true );
}
$data = array();
if ( ! empty( $stored_option[ $this->permalink_id ] ) ) {
return $stored_option[ $this->permalink_id ];
} else {
$settings = get_option( 'sb_instagram_settings', array() );
$resize_disabled = isset( $settings['sb_instagram_disable_resize'] ) && $settings['sb_instagram_disable_resize'] === 'on';
if ( ! $resize_disabled ) {
global $wpdb;
$posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
$results = $wpdb->get_col(
$wpdb->prepare(
"SELECT json_data FROM $posts_table_name
WHERE instagram_id = %s
LIMIT 1",
$this->permalink_id
)
);
if ( isset( $results[0] ) ) {
$data = json_decode( $this->encryption->decrypt( $results[0] ), true );
}
}
}
return $data;
}
}
inc/class-sb-instagram-token-refresher.php 0000644 00000011663 15051507456 0014640 0 ustar 00 connected_account = $connected_account;
$this->report = array();
}
public function get_report() {
return $this->report;
}
/**
* The plugin will attempt to refresh the token well
* before it expires. This function determines if the
* minimum amount of time has passed before the token
* can be refreshed
*
* @param $connected_account
*
* @return bool
*/
public static function refresh_time_has_passed_threshold( $connected_account ) {
$expiration_timestamp = isset( $connected_account['expires_timestamp'] ) ? $connected_account['expires_timestamp'] : time();
$current_time = sbi_get_current_timestamp();
$refresh_threshold = $expiration_timestamp - SBI_REFRESH_THRESHOLD_OFFSET;
if ( $refresh_threshold < $current_time ) {
return true;
}
return false;
}
/**
* Instagram will automatically reject API calls if
* done too frequently. This method returns true if
* there has been a minimum amount of time since the last
* API connection was attemplted
*
* @param $connected_account
*
* @return bool
*/
public static function minimum_time_interval_since_last_attempt_has_passed( $connected_account ) {
$last_attempt = isset( $connected_account['last_refresh_attempt'] ) ? (int) $connected_account['last_refresh_attempt'] : 0;
$current_time = sbi_get_current_timestamp();
if ( $current_time > $last_attempt + SBI_MINIMUM_INTERVAL ) {
return true;
}
return false;
}
/**
* Returns true if the minimum time has passed since the last
* successfull access token refresh and the minimum time has passed
* since the last attempt.
*
* @return bool
*/
public function should_attempt_refresh() {
if ( self::refresh_time_has_passed_threshold( $this->connected_account ) ) {
if ( self::minimum_time_interval_since_last_attempt_has_passed( $this->connected_account ) ) {
$this->report['should_do_update'] = true;
$this->report['reason'] = '';
return true;
} else {
$this->report['should_do_update'] = false;
$this->report['reason'] = 'has not been enough time since last attempt';
}
} else {
$this->report['should_do_update'] = false;
$this->report['reason'] = 'token expiration date not close enough';
}
return false;
}
/**
* Attempts to refresh the token by connecting to the
* Instagram API. Logs information about the error if unsuccessful.
*
* @return bool
*/
public function attempt_token_refresh() {
$this->update_last_attempt_timestamp();
$connection = new SB_Instagram_API_Connect( $this->connected_account, 'access_token', array() );
$connection->connect();
if ( ! $connection->is_wp_error() && ! $connection->is_instagram_error() ) {
$access_token_data = $connection->get_data();
if ( ! empty( $access_token_data ) && ! empty( $access_token_data['expires_in'] ) ) {
$this->report['did_update'] = true;
$this->add_renewal_data( $access_token_data );
return true;
} else {
$this->report['did_update'] = false;
$this->report['reason'] = 'successful connection but no data returned';
}
} else {
$this->report['did_update'] = false;
$this->report['reason'] = 'could not connect to Instagram';
$this->report['error_log'] = $connection;
}
return false;
}
/**
* Updates data related to when the last attempt was made to refresh
* the access token for a connected account and saves it in the database.
*/
public function update_last_attempt_timestamp() {
sbi_update_connected_account( $this->connected_account['user_id'], array( 'last_updated' => time() ) );
}
/**
* Helps determine if an access token is from a private
* account which can't be refreshed
*
* @return bool
*
* @since 2.4.7/5.7.1
*/
public function get_last_error_code() {
if ( isset( $this->report['error_log'] ) ) {
if ( ! is_wp_error( $this->report['error_log'] ) ) {
$error = $this->report['error_log']->get_data();
return $error['error']['code'];
}
}
return false;
}
/**
* Updates data related to the renewed access token
* for a connected account and saves it in the database.
*
* @param $token_data
*/
private function add_renewal_data( $token_data ) {
$expires_in = $token_data['expires_in'];
$expires_timestamp = sbi_get_current_timestamp() + $expires_in;
$to_update = array(
'access_token' => $token_data['access_token'],
'expires' => date( 'Y-m-d H:i:s', $expires_timestamp ),
);
sbi_update_connected_account( $this->connected_account['user_id'], $to_update );
}
}
inc/email.php 0000644 00000030107 15051507456 0007126 0 ustar 00
' . esc_html( wp_specialchars_decode( get_bloginfo( 'name' ) ) ) . '' );
?>
•
', '' );
?>
inc/class-sb-instagram-connected-account.php 0000644 00000030117 15051507456 0015124 0 ustar 00 account = $search_term_or_account;
} else {
$this->account = self::lookup( $search_term_or_account, $search_type );
}
}
/**
* @return array
*
* @since 5.10
*/
public function get_account_data() {
return $this->account;
}
/**
* Returns data for a connected account based on a search by term
* or type (business, user)
*
* @param $search_term string
* @param string $search_type string
*
* @return array|bool|mixed
*
* @since 5.10
*/
public static function lookup( $search_term, $search_type = 'user' ) {
if ( is_array( $search_term ) ) {
return false;
}
if ( $search_type === 'business' ) {
if ( $search_term === '' ) {
$args = array(
'all_businesses' => true,
);
$sources = \InstagramFeed\Builder\SBI_Db::source_query( $args );
if ( empty( $sources ) ) {
$sources = \InstagramFeed\Builder\SBI_Db::source_query();
}
$connected_accounts = \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources );
$business_accounts = array();
$access_tokens_found = array();
foreach ( $connected_accounts as $connected_account ) {
if ( isset( $connected_account['type'] )
&& $connected_account['type'] === 'business'
&& ! in_array( $connected_account['access_token'], $access_tokens_found, true ) ) {
$business_accounts[] = $connected_account;
$access_tokens_found[] = $connected_account['access_token'];
}
}
return $business_accounts;
} else {
$connected_accounts = self::get_all_connected_accounts();
foreach ( $connected_accounts as $connected_account ) {
if ( isset( $connected_account['type'] )
&& $connected_account['type'] === 'business' ) {
return $connected_account;
}
}
}
} else {
$connected_accounts = self::get_all_connected_accounts();
if ( isset( $connected_accounts[ $search_term ] ) ) {
return $connected_accounts[ $search_term ];
} else {
foreach ( $connected_accounts as $connected_account ) {
if ( strpos( $connected_account['access_token'], '.' ) === false ) {
if ( strtolower( $connected_account['username'] ) === trim( strtolower( $search_term ) ) ) {
return $connected_account;
} elseif ( $connected_account['access_token'] === trim( strtolower( $search_term ) ) ) {
return $connected_account;
}
}
}
}
}
return false;
}
/**
* Generates a local version of the avatar image file
* and stores related information for easy retrieval and
* management
*
* @param $username string
* @param $file_name string
*
* @return bool
*
* @since 5.10
*/
public static function create_local_avatar( $username, $file_name ) {
if ( empty( $file_name ) ) {
return false;
}
$options = sbi_get_database_settings();
if ( ! $options['sb_instagram_disable_resize'] ) {
$image_editor = wp_get_image_editor( $file_name );
$upload = wp_upload_dir();
$full_file_name = trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg';
if ( ! is_wp_error( $image_editor ) ) {
$image_editor->set_quality( 80 );
$image_editor->resize( 150, null );
$saved_image = $image_editor->save( $full_file_name );
if ( ! $saved_image ) {
global $sb_instagram_posts_manager;
$sb_instagram_posts_manager->add_error( 'image_editor', __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name );
} else {
return true;
}
} else {
if ( ! function_exists( 'download_url' ) ) {
include_once ABSPATH . 'wp-admin/includes/file.php';
}
$timeout_seconds = 5;
// Download file to temp dir.
$temp_file = download_url( $file_name, $timeout_seconds );
if ( is_wp_error( $image_editor ) ) {
return false;
}
$image_editor = wp_get_image_editor( $temp_file );
global $sb_instagram_posts_manager;
$details = __( 'Using backup editor method.', 'instagram-feed' ) . ' ' . $file_name;
$sb_instagram_posts_manager->add_error( 'image_editor', $details );
// not uncommon for the image editor to not work using it this way
if ( ! is_wp_error( $image_editor ) ) {
$image_editor->set_quality( 80 );
$image_editor->resize( 150, null );
$saved_image = $image_editor->save( $full_file_name );
if ( ! $saved_image ) {
global $sb_instagram_posts_manager;
$details = __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name;
$sb_instagram_posts_manager->add_error( 'image_editor', $details );
} else {
return true;
}
} else {
$message = __( 'Error editing image.', 'instagram-feed' );
if ( isset( $image_editor ) && isset( $image_editor->errors ) ) {
foreach ( $image_editor->errors as $key => $item ) {
$message .= ' ' . $key . ' - ' . $item[0] . ' |';
}
if ( isset( $image_editor ) && isset( $image_editor->error_data ) ) {
$message .= ' ' . sbi_json_encode( $image_editor->error_data ) . ' |';
}
}
global $sb_instagram_posts_manager;
$sb_instagram_posts_manager->add_error( 'image_editor', $message );
}
if ( ! empty( $temp_file ) ) {
@unlink( $temp_file );
}
}
}
return false;
}
/**
* Whether or not we should attempt to create a local avatar
*
* @param string $username
*
* @return bool
*
* @since 6.0
*/
public static function should_create_local_avatar( $username ) {
$options = sbi_get_database_settings();
if ( ! $options['sb_instagram_disable_resize'] ) {
$avatars = get_option( 'sbi_local_avatars', array() );
return ! isset( $avatars[ $username ] ) || $avatars[ $username ] !== false;
}
return false;
}
/**
* Delete and update the status of a local avatar
*
* @param string $username
*
* @since 6.0
*/
public static function delete_local_avatar( $username ) {
$upload = wp_upload_dir();
$image_files = glob( trailingslashit( $upload['basedir'] ) . trailingslashit( SBI_UPLOADS_NAME ) . $username . '.jpg' ); // get all matching images
foreach ( $image_files as $file ) { // iterate files
if ( is_file( $file ) ) {
unlink( $file );
}
}
self::update_local_avatar_status( $username, 'unset' );
}
/**
* Whether or not the local avatar file exists
*
* @param string $username
*
* @return bool
*
* @since 6.0
*/
public static function local_avatar_exists( $username ) {
$avatars = get_option( 'sbi_local_avatars', array() );
return ! empty( $avatars[ $username ] );
}
/**
* Full URL to local avatar for username
*
* @param string $username
*
* @return string
*
* @since 6.0
*/
public static function get_local_avatar_url( $username ) {
$avatar_url = sbi_get_resized_uploads_url() . $username . '.jpg';
return $avatar_url;
}
/**
* Store a record of which avatars have been created
*
* @param string $username
* @param string $status
*
* @since 6.0
*/
public static function update_local_avatar_status( $username, $status ) {
$avatars = get_option( 'sbi_local_avatars', array() );
if ( $status === 'unset' ) {
if ( isset( $avatars[ $username ] ) ) {
unset( $avatars[ $username ] );
}
} else {
$avatars[ $username ] = $status;
}
update_option( 'sbi_local_avatars', $avatars );
}
/**
* If an avatar exists, return the URL otherwise try to create one.
* If we can't create one or it was not successful, return false.
*
* @param string $username
* @param string $profile_picture
*
* @return bool|string
*
* @since 6.0
*/
public static function maybe_local_avatar( $username, $profile_picture ) {
if ( self::local_avatar_exists( $username ) ) {
return self::get_local_avatar_url( $username );
}
if ( self::should_create_local_avatar( $username ) ) {
$created = self::create_local_avatar( $username, $profile_picture );
self::update_local_avatar_status( $username, $created );
if ( $created ) {
return self::get_local_avatar_url( $username );
}
}
return false;
}
/**
* Encrypt string (access token) with an included initialization vector
*
* @param string $access_token
* @param string $initialization_vector
*
* @return string
*
* @since 5.12.4
*/
public static function encrypt_access_token( $access_token ) {
$encryption = new SB_Instagram_Data_Encryption();
return $encryption->encrypt( $access_token );
}
/**
* Attempt to decrypt access token
*
* @param string $access_token
* @param string $initialization_vector
*
* @return string
*
* @since 5.12.4
*/
public static function decrypt_access_token( $access_token ) {
$encryption = new SB_Instagram_Data_Encryption();
return $encryption->decrypt( $access_token );
}
/**
* Encrypt access tokens in a connected account and return it
*
* @param array $connected_account
*
* @return mixed
* @throws Exception
*
* @since 5.12.4
*/
public static function encrypt_connected_account_tokens( $connected_account ) {
if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) {
$encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] );
$connected_account['access_token'] = $encrypted_access_token;
if ( isset( $connected_account['page_access_token'] ) ) {
$encrypted_page_access_token = self::encrypt_access_token( $connected_account['page_access_token'] );
$connected_account['page_access_token'] = $encrypted_page_access_token;
}
$connected_account['wp_user'] = get_current_user_id();
}
return $connected_account;
}
/**
* Encrypt all access tokens in all connected accounts. Used for
* a one-time update.
*
* @return array
* @throws Exception
*
* @since 5.12.4
*/
public static function encrypt_all_access_tokens() {
$options = sbi_get_database_settings();
$connected_accounts = isset( $options['connected_accounts'] ) ? $options['connected_accounts'] : array();
$updated = array();
foreach ( $connected_accounts as $key => $connected_account ) {
$updated[ $key ] = $connected_account;
if ( ! self::decrypt_access_token( $connected_account['access_token'] ) ) {
$encrypted_access_token = self::encrypt_access_token( $connected_account['access_token'] );
$updated[ $key ]['access_token'] = $encrypted_access_token;
if ( isset( $connected_account['page_access_token'] ) ) {
$encrypted_page_access_token = self::encrypt_access_token( $connected_account['page_access_token'] );
$updated[ $key ]['page_access_token'] = $encrypted_page_access_token;
}
$updated[ $key ]['wp_user'] = get_current_user_id();
}
}
$options['connected_accounts'] = $updated;
update_option( 'sb_instagram_settings', $options );
return $connected_accounts;
}
/**
* Returns all connected accounts
*
* @return array
*
* @since 6.0
*/
public static function get_all_connected_accounts() {
$i = 1;
$empty_sources = false;
$connected_accounts = array();
while ( ! $empty_sources && $i < 20 ) {
$sources = \InstagramFeed\Builder\SBI_Db::source_query( array( 'page' => $i ) );
if ( empty( $sources ) ) {
$empty_sources = true;
} else {
$connected_accounts = array_merge( $connected_accounts, \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources ) );
}
$i++;
}
return $connected_accounts;
}
/**
* Update an array of connected accounts
*
* @return array
*
* @since 5.14.4
*/
public static function update_connected_accounts( $connected_accounts ) {
$options = sbi_get_database_settings();
$options['connected_accounts'] = $connected_accounts;
update_option( 'sb_instagram_settings', $options );
return $connected_accounts;
}
}
inc/class-sb-instagram-settings.php 0000644 00000141530 15051507456 0013372 0 ustar 00 feed_type_and_terms = array();
$this->connected_accounts_in_feed = array();
$this->atts = $this->filter_atts_for_legacy( $atts );
$this->db = $db;
if ( ! empty( $atts['feed'] ) && $atts['feed'] !== 'legacy' ) {
$this->settings = SB_Instagram_Settings::get_settings_by_feed_id( $atts['feed'], $preview_settings );
if ( ! empty( $this->settings ) ) {
$this->settings['customizer'] = isset($atts['customizer']) && $atts['customizer'] == true ? true : false;
$this->settings['feed'] = intval( $atts['feed'] );
$this->connected_accounts = $this->get_connected_accounts_from_settings();
if ( $this->settings['type'] === 'mixed' ) {
$this->atts['tagged'] = $this->settings['tagged'];
$this->atts['user'] = $this->settings['id'];
$this->atts['hashtag'] = $this->settings['hashtag'];
}
foreach ( $this->atts as $key => $value ) {
$this->settings[ $key ] = $value;
}
} else {
return array();
}
}
if ( empty( $this->settings ) ) {
if ( ! empty( $preview_settings ) ) {
$this->settings = $preview_settings;
} else {
$sbi_statuses = get_option( 'sbi_statuses', array() );
if ( ! empty( $sbi_statuses['support_legacy_shortcode'] ) ) {
$legacy_settings_option = self::get_legacy_feed_settings();
if ( empty( $legacy_settings_option ) ) {
$this->settings = SB_Instagram_Settings::get_settings_by_legacy_shortcode( $atts, $db );
} else {
$this->settings = wp_parse_args( $this->atts, $legacy_settings_option );
}
}
}
if ( ! empty( $this->settings ) ) {
if ( ! is_array( $this->settings ) ) {
$this->settings = array();
}
$this->settings['customizer'] = isset($atts['customizer']) && $atts['customizer'] == true ? true : false;
$this->settings['feed'] = 'legacy';
$this->connected_accounts = $this->get_connected_accounts_from_settings();
}
$this->settings = wp_parse_args( $this->settings, \InstagramFeed\Builder\SBI_Feed_Saver::settings_defaults() );
}
if ( empty( $this->settings ) ) {
return;
}
$this->settings = $this->filter_for_builder( $this->settings, $atts );
$this->settings = $this->filter_for_legacy( $this->settings, $atts );
if ( ! empty( $this->settings['customizer'] ) ) {
$this->settings = $this->filter_for_customizer( $this->settings );
}
if ( empty( $this->settings['feed_is_moderated'] ) ) {
$this->settings['feed_is_moderated'] = false;
}
$this->connected_accounts = apply_filters( 'sbi_connected_accounts', $this->connected_accounts, $this->atts );
$this->settings['customtemplates'] = $this->settings['customtemplates'] === 'true' || $this->settings['customtemplates'] === 'on' || $this->settings['customtemplates'] === true;
if ( isset( $_GET['sbi_debug'] ) ) {
$this->settings['customtemplates'] = false;
}
$this->settings['minnum'] = max( (int)$this->settings['num'], (int)$this->settings['nummobile'] );
$this->settings['showbio'] = $this->settings['showbio'] === 'true' || $this->settings['showbio'] === 'on' || $this->settings['showbio'] === true;
if ( isset( $this->atts['showbio'] ) && $this->atts['showbio'] === 'false' ) {
$this->settings['showbio'] = false;
}
if ( isset( $this->atts['showheader'] ) && $this->atts['showheader'] === 'false' ) {
$this->settings['showheader'] = false;
} elseif ( isset( $this->atts['showheader'] ) && $this->atts['showheader'] === 'true' ) {
$this->settings['showheader'] = true;
}
$this->settings['heightunit'] = ! empty( $this->settings['heightunit'] ) ? $this->settings['heightunit'] : 'px';
$this->settings['disable_resize'] = isset( $db['sb_instagram_disable_resize'] ) && ($db['sb_instagram_disable_resize'] === 'on' || $db['sb_instagram_disable_resize'] === true);
$this->settings['favor_local'] = true;
$this->settings['backup_cache_enabled'] = ! isset( $db['sb_instagram_backup'] ) || $db['sb_instagram_backup'] === 'on' || $db['sb_instagram_backup'] === true;
$this->settings['headeroutside'] = ($this->settings['headeroutside'] === true || $this->settings['headeroutside'] === 'on' || $this->settings['headeroutside'] === 'true');
$this->settings['disable_js_image_loading'] = isset( $db['disable_js_image_loading'] ) && ($db['disable_js_image_loading'] === 'on' || $db['disable_js_image_loading'] === true);
$this->settings['sb_ajax_initial'] = isset( $db['sb_ajax_initial'] ) && ($db['sb_ajax_initial'] === 'on' || $db['sb_ajax_initial'] === true);
$this->settings['ajax_post_load'] = $this->settings['sb_ajax_initial'];
switch ( $db['sbi_cache_cron_interval'] ) {
case '30mins' :
$this->settings['sbi_cache_cron_interval'] = 60*30;
break;
case '1hour' :
$this->settings['sbi_cache_cron_interval'] = 60*60;
break;
default :
$this->settings['sbi_cache_cron_interval'] = 60*60*12;
}
$this->settings['showfollow'] = ( $this->settings['showfollow'] == 'on' || $this->settings['showfollow'] == 'true' || $this->settings['showfollow'] == true ) && $this->settings['showfollow'] !== 'false';
$this->settings['sb_instagram_cache_time'] = isset( $this->db['sb_instagram_cache_time'] ) ? $this->db['sb_instagram_cache_time'] : 1;
$this->settings['sb_instagram_cache_time_unit'] = isset( $this->db['sb_instagram_cache_time_unit'] ) ? $this->db['sb_instagram_cache_time_unit'] : 'hours';
$this->settings['gdpr'] = isset( $this->db['gdpr'] ) ? $this->db['gdpr'] : 'auto';
if ( ! empty( $this->atts['cachetime'] ) ) {
$this->settings['caching_type'] = 'page';
$cache_time = max( 1, (int) $this->atts['cachetime'] );
$this->settings['cachetimeseconds'] = 60 * $cache_time;
} elseif ( ! empty( $this->db['legacy_page_cache'] ) ) {
$this->settings['caching_type'] = 'page';
$cache_time = max( 1, (int) $this->db['legacy_page_cache'] );
$this->settings['cachetimeseconds'] = 60 * $cache_time;
} else {
$this->settings['caching_type'] = 'background';
}
$this->settings['isgutenberg'] = SB_Instagram_Blocks::is_gb_editor();
if ( $this->settings['isgutenberg'] ) {
$this->settings['sb_ajax_initial'] = false;
$this->settings['disable_js_image_loading'] = true;
}
if ( SB_Instagram_GDPR_Integrations::doing_gdpr( $this->settings ) ) {
SB_Instagram_GDPR_Integrations::init();
}
if ( $this->settings['feedid'] === 'false' ) {
$this->settings['feedid'] = false;
}
}
public static function legacy_to_builder_convert( $instagram_feed_settings ) {
$moderation_json_array = array(
'list_type_selected' => 'allow',
'allow_list' => array(),
'block_list' => ! empty( $instagram_feed_settings['hidephotos'] ) ? explode( ',', str_replace(',', ' ', $instagram_feed_settings['hidephotos'] ) ) : array()
);
if ( ! empty( $instagram_feed_settings['whitelist_ids'] ) ) {
$moderation_json_array['allow_list'] = $instagram_feed_settings['whitelist_ids'];
} else {
$moderation_json_array['list_type_selected'] = 'block';
}
$instagram_feed_settings['moderationlist'] = json_encode( $moderation_json_array );
$instagram_feed_settings['customizer'] = false;
$instagram_feed_settings['feed'] = 'legacy';
$unsets = array(
'feed_is_moderated',
'whitelist_ids',
'whitelist_num',
'minnum',
'disable_resize',
'favor_local',
'backup_cache_enabled',
'font_method',
'disable_js_image_loading',
'sbi_cache_cron_interval',
'sb_instagram_cache_time',
'sb_instagram_cache_time_unit',
'addModerationModeLink',
'caching_type',
'sb_ajax_initial',
'isgutenberg',
'hidephotos',
);
foreach ( $unsets as $unset_key ) {
if ( isset( $instagram_feed_settings[ $unset_key ] ) ) {
unset( $instagram_feed_settings[ $unset_key ] );
}
}
return $instagram_feed_settings;
}
public static function get_settings_by_legacy_shortcode( $atts, $db ) {
$settings = shortcode_atts(
array(
'id' => isset( $db['sb_instagram_user_id'] ) ? $db['sb_instagram_user_id'] : '',
'width' => isset( $db['sb_instagram_width'] ) ? $db['sb_instagram_width'] : '',
'widthunit' => isset( $db['sb_instagram_width_unit'] ) ? $db['sb_instagram_width_unit'] : '',
'widthresp' => isset( $db['sb_instagram_feed_width_resp'] ) ? $db['sb_instagram_feed_width_resp'] : '',
'height' => isset( $db['sb_instagram_height'] ) ? $db['sb_instagram_height'] : '',
'heightunit' => isset( $db['sb_instagram_height_unit'] ) ? $db['sb_instagram_height_unit'] : '',
'sortby' => isset( $db['sb_instagram_sort'] ) ? $db['sb_instagram_sort'] : '',
'num' => isset( $db['sb_instagram_num'] ) ? $db['sb_instagram_num'] : '',
'apinum' => isset( $db['sb_instagram_minnum'] ) ? $db['sb_instagram_minnum'] : '',
'nummobile' => isset($db[ 'sb_instagram_nummobile' ]) ? $db[ 'sb_instagram_nummobile' ] : '',
'cols' => isset( $db['sb_instagram_cols'] ) ? $db['sb_instagram_cols'] : '',
'disablemobile' => isset( $db['sb_instagram_disable_mobile'] ) ? $db['sb_instagram_disable_mobile'] : '',
'imagepadding' => isset( $db['sb_instagram_image_padding'] ) ? $db['sb_instagram_image_padding'] : '',
'imagepaddingunit' => isset( $db['sb_instagram_image_padding_unit'] ) ? $db['sb_instagram_image_padding_unit'] : '',
'background' => isset( $db['sb_instagram_background'] ) ? $db['sb_instagram_background'] : '',
'showbutton' => isset( $db['sb_instagram_show_btn'] ) ? $db['sb_instagram_show_btn'] : '',
'buttoncolor' => isset( $db['sb_instagram_btn_background'] ) ? $db['sb_instagram_btn_background'] : '',
'buttontextcolor' => isset( $db['sb_instagram_btn_text_color'] ) ? $db['sb_instagram_btn_text_color'] : '',
'buttontext' => isset( $db['sb_instagram_btn_text'] ) ? $db['sb_instagram_btn_text'] : '',
'imageres' => isset( $db['sb_instagram_image_res'] ) ? $db['sb_instagram_image_res'] : '',
'showfollow' => isset( $db['sb_instagram_show_follow_btn'] ) ? $db['sb_instagram_show_follow_btn'] : '',
'followcolor' => isset( $db['sb_instagram_folow_btn_background'] ) ? $db['sb_instagram_folow_btn_background'] : '',
'followtextcolor' => isset( $db['sb_instagram_follow_btn_text_color'] ) ? $db['sb_instagram_follow_btn_text_color'] : '',
'followtext' => isset( $db['sb_instagram_follow_btn_text'] ) ? $db['sb_instagram_follow_btn_text'] : '',
'showheader' => isset( $db['sb_instagram_show_header'] ) ? $db['sb_instagram_show_header'] : '',
'headersize' => isset( $db['sb_instagram_header_size'] ) ? $db['sb_instagram_header_size'] : '',
'showbio' => isset( $db['sb_instagram_show_bio'] ) ? $db['sb_instagram_show_bio'] : '',
'custombio' => isset($db[ 'sb_instagram_custom_bio' ]) ? $db[ 'sb_instagram_custom_bio' ] : '',
'customavatar' => isset($db[ 'sb_instagram_custom_avatar' ]) ? $db[ 'sb_instagram_custom_avatar' ] : '',
'headercolor' => isset( $db['sb_instagram_header_color'] ) ? $db['sb_instagram_header_color'] : '',
'class' => '',
'ajaxtheme' => isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] : '',
'cachetime' => isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : '',
'media' => isset( $db['sb_instagram_media_type'] ) ? $db['sb_instagram_media_type'] : '',
'headeroutside' => isset($db[ 'sb_instagram_outside_scrollable' ]) ? $db[ 'sb_instagram_outside_scrollable' ] : '',
'accesstoken' => '',
'user' => isset( $db['sb_instagram_user'] ) ? $db['sb_instagram_user'] : false,
'feedid' => isset( $db['sb_instagram_feed_id'] ) ? $db['sb_instagram_feed_id'] : false,
'resizeprocess' => isset( $db['sb_instagram_resizeprocess'] ) ? $db['sb_instagram_resizeprocess'] : 'background',
'customtemplates' => isset( $db['custom_template'] ) ? $db['custom_template'] : '',
'gdpr' => isset( $db['gdpr'] ) ? $db['gdpr'] : 'auto',
'altresize' => isset( $db['altresize'] ) ? $db['altresize'] : true,
), $atts );
$settings['sources'] = is_string( $settings['id'] ) ? explode( ',', str_replace( ' ', '', $settings['id'] ) ) : array();
return $settings;
}
/**
* Converts settings from the builder to settings used in the feed
*
* @param $settings
* @param $atts
*
* @return mixed
*/
public function filter_for_builder( $settings, $atts ) {
if ( ! isset( $atts['media'] ) ) {
if( isset( $settings['reelsposts'] ) ) {
$include_reels = $settings['reelsposts'] !== 'false' && ! empty( $settings['reelsposts'] ) ? true : false;
} else {
$include_reels = $settings['media'] === 'all' ? true : false;
$settings['reelsposts'] = $include_reels ? true : false;
}
$settings['media'] = $include_reels ? 'all' : array( 'photos', 'videos' );
} else {
$include_reels = $settings['media'] === 'all' && strpos( $settings['videotypes'], 'reels' ) !== false;
}
if ( ! isset( $atts['videotypes'] ) ) {
$video_types = array();
if ( $include_reels ) {
$video_types[] = 'reels';
$video_types[] = 'regular';
} else {
$video_types[] = 'regular';
}
$settings['videotypes'] = implode( ',', $video_types );
}
if ( isset( $atts['ajaxtheme'] ) ) {
$settings['ajaxtheme'] = $atts['ajaxtheme'] === 'true';
} else {
$db = sbi_get_database_settings();
$settings['ajaxtheme'] = isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] === '1' || $db['sb_instagram_ajax_theme'] === true || $db['sb_instagram_ajax_theme'] === 'on' : false;
}
return $settings;
}
/**
* Disables or enables certain settings when using the
* customizer
*
* @param $settings
*
* @return mixed
*/
public function filter_for_customizer( $settings ) {
$settings['customtemplates'] = false;
$settings['moderationmode'] = false;
$settings['sb_ajax_initial'] = false;
$settings['disable_js_image_loading'] = false;
$settings['showheader'] = true;
return $settings;
}
/**
* Filters out or converts allowed/disallowed shortcode settings
*
* @param $atts
*
* @return mixed
*/
public function filter_atts_for_legacy( $atts ) {
if ( ! empty( $atts['from_update'] ) ) {
unset( $atts['from_update'] );
return $atts;
}
$sbi_statuses = get_option( 'sbi_statuses', array() );
$allowed_legacy_shortcode = array(
'feed',
'headersource',
'customizer',
'class'
);
if ( ! empty( $sbi_statuses['support_legacy_shortcode'] )
&& empty( $atts['feed'] ) ) {
if ( is_array( $sbi_statuses['support_legacy_shortcode'] ) ) {
$atts_diff = array_diff( $sbi_statuses['support_legacy_shortcode'], $atts ); // determines if the shortcode settings match the shortcode settings of an existing feed
foreach ( $atts_diff as $key => $value ) {
if ( in_array( $key, $allowed_legacy_shortcode, true ) ) {
unset( $atts_diff[ $key ] );
}
}
if ( empty( $atts_diff ) ) {
$atts['feed'] = 1;
}
}
if ( empty( $atts['feed'] ) ) {
return $atts;
}
}
foreach ( $atts as $key => $value ) {
if ( ! in_array( $key, $allowed_legacy_shortcode ) ) {
unset( $atts[ $key ] );
}
}
return $atts;
}
/**
* Converts legacy feed settings to work with new settings
*
* @param $settings
* @param $atts
*
* @return mixed
*/
public function filter_for_legacy( $settings, $atts ) {
return $settings;
}
public static function get_settings_by_feed_id( $feed_id, $preview_settings = false ) {
if ( is_array( $preview_settings ) ) {
return $preview_settings;
}
if ( intval( $feed_id ) < 1 ) {
return false;
}
$feed_saver = new \InstagramFeed\Builder\SBI_Feed_Saver( $feed_id );
return $feed_saver->get_feed_settings();
}
public static function get_legacy_feed_settings() {
return json_decode( get_option( 'sbi_legacy_feed_settings', '{}' ), true );
}
public function feed_type_and_terms_display() {
if ( ! isset( $this->feed_type_and_terms ) ) {
return array();
}
$return = array();
foreach ( $this->feed_type_and_terms as $feed_type => $type_terms ) {
foreach ( $type_terms as $term ) {
if ( $feed_type === 'users'
|| $feed_type === 'tagged' ) {
if ( ! in_array( $this->connected_accounts_in_feed[ $term['term'] ]['username'], $return, true ) ) {
$return[] = $this->connected_accounts_in_feed[ $term['term'] ]['username'];
}
} elseif ( $feed_type === 'hashtags_recent'
|| $feed_type === 'hashtags_top' ) {
if ( ! in_array( $term['hashtag_name'], $return, true ) ) {
$return[] = $term['hashtag_name'];
}
}
}
}
return $return;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_settings() {
return $this->settings;
}
/**
* The plugin will output settings on the frontend for debugging purposes.
* Safe settings to display are added here.
*
* Overwritten in the Pro version.
*
* @return array
*
* @since 2.0/5.0
*/
public static function get_public_db_settings_keys() {
$public = array(
'sb_instagram_user_id',
'sb_instagram_cache_time',
'sb_instagram_cache_time_unit',
'sbi_caching_type',
'sbi_cache_cron_interval',
'sbi_cache_cron_time',
'sbi_cache_cron_am_pm',
'sb_instagram_width',
'sb_instagram_width_unit',
'sb_instagram_feed_width_resp',
'sb_instagram_height',
'sb_instagram_num',
'sb_instagram_height_unit',
'sb_instagram_cols',
'sb_instagram_disable_mobile',
'sb_instagram_image_padding',
'sb_instagram_image_padding_unit',
'sb_instagram_sort',
'sb_instagram_background',
'sb_instagram_show_btn',
'sb_instagram_btn_background',
'sb_instagram_btn_text_color',
'sb_instagram_btn_text',
'sb_instagram_image_res',
//Header
'sb_instagram_show_header',
'sb_instagram_header_size',
'sb_instagram_header_color',
//Follow button
'sb_instagram_show_follow_btn',
'sb_instagram_folow_btn_background',
'sb_instagram_follow_btn_text_color',
'sb_instagram_follow_btn_text',
//Misc
'sb_instagram_cron',
'sb_instagram_backup',
'sb_instagram_ajax_theme',
'sb_instagram_disable_resize',
'disable_js_image_loading',
'enqueue_js_in_head',
'sb_instagram_disable_awesome',
'sb_ajax_initial',
'use_custom'
);
return $public;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_connected_accounts() {
return $this->connected_accounts;
}
/**
* @return array|bool
*
* @since 2.0/5.0
*/
public function get_connected_accounts_in_feed() {
if ( isset( $this->connected_accounts_in_feed ) ) {
return $this->connected_accounts_in_feed;
} else {
return false;
}
}
/**
* @return bool|string
*
* @since 2.0/5.0
*/
public function get_transient_name() {
if ( isset( $this->transient_name ) ) {
return $this->transient_name;
} else {
return false;
}
}
/**
* Uses the feed types and terms as well as as some
* settings to create a semi-unique feed id used for
* caching and other features.
*
* Overwritten in the Pro version.
*
* @param string $transient_name
*
* @since 2.0/5.0
*/
public function set_transient_name( $transient_name = '' ) {
if ( ! empty( $transient_name ) ) {
$this->transient_name = $transient_name;
} elseif ( ! empty( $this->settings['feed'] ) && $this->settings['feed'] !== 'legacy' && intval( $this->settings['feed'] ) > 0 ) {
$this->transient_name = '*' . $this->settings['feed'];
} elseif ( ! empty( $this->settings['feedid'] ) ) {
$this->transient_name = 'sbi_' . $this->settings['feedid'];
} else {
$feed_type_and_terms = $this->feed_type_and_terms;
$sbi_transient_name = 'sbi_';
if ( isset( $feed_type_and_terms['users'] ) ) {
foreach ( $feed_type_and_terms['users'] as $term_and_params ) {
$user = $term_and_params['term'];
$connected_account = isset( $this->connected_accounts_in_feed[ $user ] ) ? $this->connected_accounts_in_feed[ $user ] : array();
if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) {
$sbi_transient_name .= $connected_account['username'];
} else {
$sbi_transient_name .= $user;
}
}
}
$num = $this->settings['num'];
$num_length = strlen( $num ) + 1;
//Add both parts of the caching string together and make sure it doesn't exceed 45
$sbi_transient_name = substr( $sbi_transient_name, 0, 45 - $num_length );
if ( $this->settings['sortby'] === 'random' ) {
$sbi_transient_name .= 'rdm';
}
$sbi_transient_name .= '#' . $num;
$this->transient_name = $sbi_transient_name;
}
}
/**
* @return array|bool
*
* @since 2.0/5.0
*/
public function get_feed_type_and_terms() {
if ( isset( $this->feed_type_and_terms ) ) {
return $this->feed_type_and_terms;
} else {
return false;
}
}
private function add_connected_accounts_in_feed( $connected_accounts ) {
foreach ( $connected_accounts as $key => $connected_account ) {
$this->connected_accounts_in_feed[ $key ] = $connected_account;
}
}
private function add_feed_type_and_terms( $feed_type_and_terms ) {
$this->feed_type_and_terms = array_merge( $this->feed_type_and_terms, $feed_type_and_terms );
}
private function set_user_feed( $users = false ) {
global $sb_instagram_posts_manager;
if ( ! $users ) {
$set = false;
if ( empty( $this->connected_accounts ) && empty( $this->settings['feed']) ) {
if ( empty( $this->atts['feed'] ) ) {
$error_message_return = array(
'error_message' => __( 'Error: No Feed ID Set.', 'instagram-feed' ),
'admin_only' => __( 'Visit the Instagram Feed settings page to see which feeds have been created and how to embed them.', 'instagram-feed' ),
'frontend_directions' => '',
'backend_directions' => ''
);
} else {
$error_message_return = array(
'error_message' => __( 'Error: Invalid Feed ID.', 'instagram-feed' ),
'admin_only' => __( 'Visit the Instagram Feed settings page to see which feeds have been created and how to embed them.', 'instagram-feed' ),
'frontend_directions' => '',
'backend_directions' => ''
);
}
$sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
return;
}
foreach ( $this->connected_accounts as $connected_account ) {
if ( ! $set ) {
$set = true;
$this->settings['user'] = $connected_account['username'];
$this->connected_accounts_in_feed = array( $connected_account['user_id'] => $connected_account );
$feed_type_and_terms = array(
'users'=> array(
array(
'term' => $connected_account['user_id'],
'params' => array()
)
)
);
if ( $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) {
$feed_type_and_terms['users'][0]['error'] = true;
}
$this->feed_type_and_terms = $feed_type_and_terms;
}
}
return;
} else {
$connected_accounts_in_feed = array();
$feed_type_and_terms = array(
'users' => array()
);
$usernames_included = array();
$usernames_not_connected = array();
foreach ( $users as $user_id_or_name ) {
$connected_account = ! empty( $this->connected_accounts[ $user_id_or_name ] ) ? $this->connected_accounts[ $user_id_or_name ] : SB_Instagram_Connected_Account::lookup( $user_id_or_name );
if ( $connected_account ) {
if ( ! in_array( $connected_account['username'], $usernames_included, true ) ) {
if ( ! $sb_instagram_posts_manager->are_current_api_request_delays( $connected_account ) ) {
$feed_type_and_terms['users'][] = array(
'term' => $connected_account['user_id'],
'params' => array()
);
} else {
$feed_type_and_terms['users'][] = array(
'term' => $connected_account['user_id'],
'params' => array(),
'error' => true
);
}
$connected_accounts_in_feed[ $connected_account['user_id'] ] = $connected_account;
$usernames_included[] = $connected_account['username'];
}
} else {
$feed_type_and_terms['users'][] = array(
'term' => $user_id_or_name,
'params' => array(),
'error' => true
);
$usernames_not_connected[] = $user_id_or_name;
}
}
if ( ! empty( $usernames_not_connected ) ) {
global $sb_instagram_posts_manager;
if ( count( $usernames_not_connected ) === 1 ) {
$user = $usernames_not_connected[0];
} else {
$user = implode( ', ', $usernames_not_connected );
}
$settings_link = '
' . __( 'plugin Settings page', 'instagram-feed' ) . ' ';
$error_message_return = array(
'error_message' => sprintf( __( 'Error: There is no connected account for the user %s.', 'instagram-feed' ), $user ),
'admin_only' => sprintf( __( 'A connected account related to the user is required to display user feeds. Please connect an account for this user on the %s.', 'instagram-feed' ), $settings_link ),
'frontend_directions' => '',
'backend_directions' => ''
);
$sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
}
$this->add_feed_type_and_terms( $feed_type_and_terms );
$this->add_connected_accounts_in_feed( $connected_accounts_in_feed );
}
}
/**
* Based on the settings related to retrieving post data from the API,
* this setting is used to make sure all endpoints needed for the feed are
* connected and stored for easily looping through when adding posts
*
* Overwritten in the Pro version.
*
* @since 2.0/5.0
*/
public function set_feed_type_and_terms() {
global $sb_instagram_posts_manager;
$is_using_access_token_in_shortcode = ! empty( $this->atts['accesstoken'] );
$settings_link = '
' . __( 'plugin Settings page', 'instagram-feed' ) . ' ';
if ( $is_using_access_token_in_shortcode ) {
$error_message_return = array(
'error_message' => __( 'Error: Cannot add access token directly to the shortcode.', 'instagram-feed' ),
'admin_only' => sprintf( __( 'Due to recent Instagram platform changes, it\'s no longer possible to create a feed by adding the access token to the shortcode. Remove the access token from the shortcode and connect an account on the %s instead.', 'instagram-feed' ), $settings_link ),
'frontend_directions' => '',
'backend_directions' => ''
);
$sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
$this->atts['accesstoken'] = '';
}
if ( empty( $this->settings['id'] )
&& empty( $this->settings['user'] )
&& ! empty ( $this->connected_accounts ) ) {
$this->set_user_feed();
} else {
$user_array = array();
if ( ! empty( $this->settings['user'] ) ) {
$user_array = is_array( $this->settings['user'] ) ? $this->settings['user'] : explode( ',', str_replace( ' ', '', $this->settings['user'] ) );
} elseif ( ! empty( $this->settings['id'] ) ) {
$user_array = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace( ' ', '', $this->settings['id'] ) );
}
$this->set_user_feed( $user_array );
}
if ( empty( $this->feed_type_and_terms['users'] ) ) {
$error_message_return = array(
'error_message' => __( 'Error: No users set.', 'instagram-feed' ),
'admin_only' => __( 'Please visit the plugin\'s settings page to select a user account or add one to the shortcode - user="username".', 'instagram-feed' ),
'frontend_directions' => '',
'backend_directions' => ''
);
$sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
}
foreach ( $this->connected_accounts_in_feed as $connected_account_in_feed ) {
if ( isset( $connected_account_in_feed['private'] )
&& sbi_private_account_near_expiration( $connected_account_in_feed ) ) {
$link_1 = '
';
$link_2 = ' ';
$error_message_return = array(
'error_message' => __( 'Error: Private Instagram Account.', 'instagram-feed' ),
'admin_only' => sprintf( __( 'It looks like your Instagram account is private. Instagram requires private accounts to be reauthenticated every 60 days. Refresh your account to allow it to continue updating, or %smake your Instagram account public%s.', 'instagram-feed' ), $link_1, $link_2 ),
'frontend_directions' => '
' . __( 'Click here to troubleshoot', 'instagram-feed' ) . ' ',
'backend_directions' => ''
);
$sb_instagram_posts_manager->maybe_set_display_error( 'configuration', $error_message_return );
}
}
}
/**
* @return float|int
*
* @since 2.0/5.0
*/
public function get_cache_time_in_seconds() {
if ( $this->settings['caching_type'] === 'background' ) {
return SBI_CRON_UPDATE_CACHE_TIME;
} else {
//If the caching time doesn't exist in the database then set it to be 1 hour
$cache_time = isset( $this->settings['sb_instagram_cache_time'] ) ? (int)$this->settings['sb_instagram_cache_time'] : 1;
$cache_time_unit = isset( $this->settings['sb_instagram_cache_time_unit'] ) ? $this->settings['sb_instagram_cache_time_unit'] : 'hours';
//Calculate the cache time in seconds
if ( $cache_time_unit == 'minutes' ) $cache_time_unit = 60;
if ( $cache_time_unit == 'hours' ) $cache_time_unit = 60*60;
if ( $cache_time_unit == 'days' ) $cache_time_unit = 60*60*24;
$cache_time_return = min( $cache_time * $cache_time_unit, DAY_IN_SECONDS );
return $cache_time_return;
}
}
public static function default_settings() {
$defaults = array(
'sb_instagram_at' => '',
'sb_instagram_type' => 'user',
'sb_instagram_order' => 'top',
'sb_instagram_user_id' => '',
'sb_instagram_tagged_ids' => '',
'sb_instagram_hashtag' => '',
'sb_instagram_type_self_likes' => '',
'sb_instagram_location' => '',
'sb_instagram_coordinates' => '',
'sb_instagram_preserve_settings' => '',
'sb_instagram_ajax_theme' => false,
'enqueue_js_in_head' => false,
'disable_js_image_loading' => false,
'sb_instagram_disable_resize' => false,
'sb_instagram_favor_local' => true,
'sb_instagram_cache_time' => '1',
'sb_instagram_cache_time_unit' => 'hours',
'sbi_caching_type' => 'background',
'sbi_cache_cron_interval' => '12hours',
'sbi_cache_cron_time' => '1',
'sbi_cache_cron_am_pm' => 'am',
'sb_instagram_width' => '100',
'sb_instagram_width_unit' => '%',
'sb_instagram_feed_width_resp' => false,
'sb_instagram_height' => '',
'sb_instagram_num' => '20',
'sb_instagram_nummobile' => '',
'sb_instagram_height_unit' => '',
'sb_instagram_cols' => '4',
'sb_instagram_colsmobile' => 'auto',
'sb_instagram_image_padding' => '5',
'sb_instagram_image_padding_unit' => 'px',
//Layout Type
'sb_instagram_layout_type' => 'grid',
'sb_instagram_highlight_type' => 'pattern',
'sb_instagram_highlight_offset' => 0,
'sb_instagram_highlight_factor' => 6,
'sb_instagram_highlight_ids' => '',
'sb_instagram_highlight_hashtag' => '',
//Hover style
'sb_hover_background' => '',
'sb_hover_text' => '',
'sbi_hover_inc_username' => true,
'sbi_hover_inc_icon' => true,
'sbi_hover_inc_date' => true,
'sbi_hover_inc_instagram' => true,
'sbi_hover_inc_location' => false,
'sbi_hover_inc_caption' => false,
'sbi_hover_inc_likes' => false,
// 'sb_instagram_hover_text_size' => '',
'sb_instagram_sort' => 'none',
'sb_instagram_disable_lightbox' => false,
'sb_instagram_captionlinks' => false,
'sb_instagram_background' => '',
'sb_instagram_show_btn' => true,
'sb_instagram_btn_background' => '',
'sb_instagram_btn_text_color' => '',
'sb_instagram_btn_text' => __( 'Load More', 'instagram-feed' ),
'sb_instagram_image_res' => 'auto',
'sb_instagram_media_type' => 'all',
'sb_instagram_moderation_mode' => 'manual',
'sb_instagram_hide_photos' => '',
'sb_instagram_block_users' => '',
'sb_instagram_ex_apply_to' => 'all',
'sb_instagram_inc_apply_to' => 'all',
'sb_instagram_show_users' => '',
'sb_instagram_exclude_words' => '',
'sb_instagram_include_words' => '',
//Text
'sb_instagram_show_caption' => true,
'sb_instagram_caption_length' => '50',
'sb_instagram_caption_color' => '',
'sb_instagram_caption_size' => '13',
//lightbox comments
'sb_instagram_lightbox_comments' => true,
'sb_instagram_num_comments' => '20',
//Meta
'sb_instagram_show_meta' => true,
'sb_instagram_meta_color' => '',
'sb_instagram_meta_size' => '13',
//Header
'sb_instagram_show_header' => true,
'sb_instagram_header_color' => '',
'sb_instagram_header_style' => 'standard',
'sb_instagram_show_followers' => true,
'sb_instagram_show_bio' => true,
'sb_instagram_custom_bio' => '',
'sb_instagram_custom_avatar' => '',
'sb_instagram_header_primary_color' => '517fa4',
'sb_instagram_header_secondary_color' => 'eeeeee',
'sb_instagram_header_size' => 'small',
'sb_instagram_outside_scrollable' => false,
'sb_instagram_stories' => true,
'sb_instagram_stories_time' => 5000,
//Follow button
'sb_instagram_show_follow_btn' => true,
'sb_instagram_folow_btn_background' => '',
'sb_instagram_follow_btn_text_color' => '',
'sb_instagram_follow_btn_text' => __( 'Follow on Instagram', 'instagram-feed' ),
//Autoscroll
'sb_instagram_autoscroll' => false,
'sb_instagram_autoscrolldistance' => 200,
//Misc
'sb_instagram_custom_css' => '',
'sb_instagram_custom_js' => '',
'sb_instagram_requests_max' => '5',
'sb_instagram_minnum' => '0',
'sb_instagram_cron' => 'unset',
'sb_instagram_disable_font' => false,
'sb_instagram_backup' => true,
'sb_ajax_initial' => false,
'enqueue_css_in_shortcode' => false,
'sb_instagram_disable_mob_swipe' => false,
'sbi_br_adjust' => true,
'sb_instagram_media_vine' => false,
'custom_template' => false,
'disable_admin_notice' => false,
'enable_email_report' => 'on',
'email_notification' => 'monday',
'email_notification_addresses' => get_option( 'admin_email' ),
//Carousel
'sb_instagram_carousel' => false,
'sb_instagram_carousel_rows' => 1,
'sb_instagram_carousel_loop' => 'rewind',
'sb_instagram_carousel_arrows' => false,
'sb_instagram_carousel_pag' => true,
'sb_instagram_carousel_autoplay' => false,
'sb_instagram_carousel_interval' => '5000'
);
return $defaults;
}
public function get_connected_accounts_from_settings() {
if ( $this->settings['feed'] === 'legacy' ) {
$sources = \InstagramFeed\Builder\SBI_Db::source_query();
return \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources );
}
$include_all_businesses = false;
$account_ids = [];
if ( $this->settings['type'] === 'hashtag' ) {
$include_all_businesses = true;
}
if ( $this->settings['type'] === 'mixed' ) {
$include_all_businesses = ! empty( $this->settings['hashtag'] );
}
$ids = is_array( $this->settings['id'] ) ? $this->settings['id'] : explode( ',', str_replace(' ', '', $this->settings['id'] ) );
$tagged = ! empty( $this->settings['tagged'] ) && is_array( $this->settings['tagged'] ) ? $this->settings['tagged'] : array();
$account_ids = array_merge( $ids, $tagged );
$args = array(
'all_businesses' => $include_all_businesses,
'id' => $account_ids
);
$sources = \InstagramFeed\Builder\SBI_Db::source_query( $args );
if ( empty( $sources ) ) {
$sources = \InstagramFeed\Builder\SBI_Db::source_query();
}
return \InstagramFeed\Builder\SBI_Source::convert_sources_to_connected_accounts( $sources );
}
/**
* Compares given array with an allow list of
* setting keys and how they should be sanitized
*
* @param array $atts
*
* @return array
*/
public static function sanitize_raw_atts( $atts ) {
$sanitized_atts = array();
$allowed_atts = array(
'id' => array(
'method' => 'alpha_numeric_and_comma',
'allowed_vals' => 'any'
),
'width' => array(
'method' => 'page_load_only',
),
'widthunit'=> array(
'method' => 'page_load_only',
),
'widthresp' => array(
'method' => 'page_load_only',
),
'height' => array(
'method' => 'page_load_only',
),
'heightunit' => array(
'method' => 'page_load_only',
),
'sortby' => array(
'method' => 'enum',
'allowed_vals' => array( 'none', 'random', 'likes' )
),
'num' => array(
'method' => 'intval',
'allowed_vals' => 500
),
'nummobile' => array(
'method' => 'intval',
'allowed_vals' => 500
),
'apinum' => array(
'method' => 'intval',
'allowed_vals' => 100
),
'cols' => array(
'method' => 'intval',
'allowed_vals' => 15
),
'disablemobile' => array(
'method' => 'page_load_only',
),
'imagepadding' => array(
'method' => 'page_load_only',
),
'imagepaddingunit' => array(
'method' => 'page_load_only',
),
'background' => array(
'method' => 'page_load_only',
),
'showbutton' => array(
'method' => 'page_load_only',
),
'buttoncolor' => array(
'method' => 'page_load_only',
),
'buttontextcolor' => array(
'method' => 'page_load_only',
),
'buttontext' => array(
'method' => 'page_load_only',
),
'imageres' => array(
'method' => 'enum',
'allowed_vals' => array( 'auto', 'thumb', 'low', 'full' )
),
'showfollow' => array(
'method' => 'page_load_only',
),
'followcolor' => array(
'method' => 'page_load_only',
),
'followtextcolor' => array(
'method' => 'page_load_only',
),
'followtext' => array(
'method' => 'page_load_only',
),
'showheader' => array(
'method' => 'page_load_only',
),
'headersize' => array(
'method' => 'page_load_only',
),
'showbio' => array(
'method' => 'page_load_only',
),
'custombio' => array(
'method' => 'page_load_only',
),
'customavatar' => array(
'method' => 'page_load_only',
),
'headercolor' => array(
'method' => 'page_load_only',
),
'class' => array(
'method' => 'page_load_only',
),
'ajaxtheme' => array(
'method' => 'page_load_only',
),
'cachetime' => array(
'method' => 'page_load_only',
),
'media' => array(
'method' => 'page_load_only',
),
'headeroutside' => array(
'method' => 'page_load_only',
),
'user' => array(
'method' => 'alpha_numeric_and_comma',
'allowed_vals' => 'any'
),
'feedid' => array(
'method' => 'feedid_chars',
'allowed_vals' => 'any'
),
'feed' => array(
'method' => 'alpha_numeric_and_comma',
'allowed_vals' => 'any'
),
'resizeprocess' => array(
'method' => 'enum',
'allowed_vals' => array( 'page', 'background' )
),
'customtemplates' => array(
'method' => 'string_true',
'allowed_vals' => 'any'
),
'gdpr' => array(
'method' => 'enum',
'allowed_vals' => array( 'auto', 'yes', 'no' )
)
);
foreach ( $atts as $key => $value ) {
$value = (string)$value;
if ( isset( $allowed_atts[ $key ] ) && strlen( $value ) < 500 ) {
$sanitization_method = $allowed_atts[ $key ]['method'];
switch ( $sanitization_method ) {
case 'enum' :
if ( in_array( $value, $allowed_atts[ $key ]['allowed_vals'] ) ) {
$sanitized_atts[ $key ] = sanitize_text_field( $value );
}
break;
case 'alpha_numeric_and_comma' :
$sanitized_atts[ $key ] = preg_replace( "/[^A-Za-z0-9,]/", '', $value );
break;
case 'feedid_chars' :
$sanitized_atts[ $key ] = preg_replace( "/[^A-Za-z0-9#_%-\/?]/", '', urlencode( $value ) );
break;
case 'intval' :
$value = intval( $value );
if ( $value < (int)$allowed_atts[ $key ]['allowed_vals'] ) {
$sanitized_atts[ $key ] = $value;
}
break;
case 'floatval' :
$value = floatval( $value );
if ( $allowed_atts[ $key ]['allowed_vals'] === 'any' ) {
$sanitized_atts[ $key ] = $value;
} elseif ( $value < (float)$allowed_atts[ $key ]['allowed_vals'] ) {
$sanitized_atts[ $key ] = $value;
}
if ( floor( $value ) === $value ) {
$sanitized_atts[ $key ] = (int)$value;
}
break;
case 'string_true' :
$value = floatval( $value );
if ( $value === 'true' || $value === 'on' || $value === true ) {
$sanitized_atts[ $key ] = 'true';
} else {
$sanitized_atts[ $key ] = 'false';
}
break;
}
}
}
return $sanitized_atts;
}
public static function legacy_shortcode_atts( $atts, $db ) {
$settings = shortcode_atts(
array(
'id' => isset( $db['sb_instagram_user_id'] ) ? $db['sb_instagram_user_id'] : '',
'width' => isset( $db['sb_instagram_width'] ) ? $db['sb_instagram_width'] : '',
'widthunit' => isset( $db['sb_instagram_width_unit'] ) ? $db['sb_instagram_width_unit'] : '',
'widthresp' => isset( $db['sb_instagram_feed_width_resp'] ) ? $db['sb_instagram_feed_width_resp'] : '',
'height' => isset( $db['sb_instagram_height'] ) ? $db['sb_instagram_height'] : '',
'heightunit' => isset( $db['sb_instagram_height_unit'] ) ? $db['sb_instagram_height_unit'] : '',
'sortby' => isset( $db['sb_instagram_sort'] ) ? $db['sb_instagram_sort'] : '',
'num' => isset( $db['sb_instagram_num'] ) ? $db['sb_instagram_num'] : '',
'apinum' => isset( $db['sb_instagram_minnum'] ) ? $db['sb_instagram_minnum'] : '',
'nummobile' => isset( $db['sb_instagram_nummobile'] ) ? $db['sb_instagram_nummobile'] : '',
'cols' => isset( $db['sb_instagram_cols'] ) ? $db['sb_instagram_cols'] : '',
'disablemobile' => isset( $db['sb_instagram_disable_mobile'] ) ? $db['sb_instagram_disable_mobile'] : '',
'imagepadding' => isset( $db['sb_instagram_image_padding'] ) ? $db['sb_instagram_image_padding'] : '',
'imagepaddingunit' => isset( $db['sb_instagram_image_padding_unit'] ) ? $db['sb_instagram_image_padding_unit'] : '',
'background' => isset( $db['sb_instagram_background'] ) ? $db['sb_instagram_background'] : '',
'showbutton' => isset( $db['sb_instagram_show_btn'] ) ? $db['sb_instagram_show_btn'] : '',
'buttoncolor' => isset( $db['sb_instagram_btn_background'] ) ? $db['sb_instagram_btn_background'] : '',
'buttontextcolor' => isset( $db['sb_instagram_btn_text_color'] ) ? $db['sb_instagram_btn_text_color'] : '',
'buttontext' => isset( $db['sb_instagram_btn_text'] ) ? $db['sb_instagram_btn_text'] : '',
'imageres' => isset( $db['sb_instagram_image_res'] ) ? $db['sb_instagram_image_res'] : '',
'showfollow' => isset( $db['sb_instagram_show_follow_btn'] ) ? $db['sb_instagram_show_follow_btn'] : '',
'followcolor' => isset( $db['sb_instagram_folow_btn_background'] ) ? $db['sb_instagram_folow_btn_background'] : '',
'followtextcolor' => isset( $db['sb_instagram_follow_btn_text_color'] ) ? $db['sb_instagram_follow_btn_text_color'] : '',
'followtext' => isset( $db['sb_instagram_follow_btn_text'] ) ? $db['sb_instagram_follow_btn_text'] : '',
'showheader' => isset( $db['sb_instagram_show_header'] ) ? $db['sb_instagram_show_header'] : '',
'headersize' => isset( $db['sb_instagram_header_size'] ) ? $db['sb_instagram_header_size'] : '',
'showbio' => isset( $db['sb_instagram_show_bio'] ) ? $db['sb_instagram_show_bio'] : '',
'custombio' => isset( $db['sb_instagram_custom_bio'] ) ? $db['sb_instagram_custom_bio'] : '',
'customavatar' => isset( $db['sb_instagram_custom_avatar'] ) ? $db['sb_instagram_custom_avatar'] : '',
'headercolor' => isset( $db['sb_instagram_header_color'] ) ? $db['sb_instagram_header_color'] : '',
'class' => '',
'ajaxtheme' => isset( $db['sb_instagram_ajax_theme'] ) ? $db['sb_instagram_ajax_theme'] : '',
'cachetime' => isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : '',
'media' => isset( $db['sb_instagram_media_type'] ) ? $db['sb_instagram_media_type'] : '',
'headeroutside' => isset( $db['sb_instagram_outside_scrollable'] ) ? $db['sb_instagram_outside_scrollable'] : '',
'accesstoken' => '',
'user' => isset( $db['sb_instagram_user'] ) ? $db['sb_instagram_user'] : false,
'feedid' => isset( $db['sb_instagram_feed_id'] ) ? $db['sb_instagram_feed_id'] : false,
'resizeprocess' => isset( $db['sb_instagram_resizeprocess'] ) ? $db['sb_instagram_resizeprocess'] : 'background',
'customtemplates' => isset( $db['custom_template'] ) ? $db['custom_template'] : '',
'gdpr' => isset( $db['gdpr'] ) ? $db['gdpr'] : 'auto',
'altresize' => isset( $db['altresize'] ) ? $db['altresize'] : true,
),
$atts
);
$settings['customtemplates'] = $settings['customtemplates'] === 'true' || $settings['customtemplates'] === 'on' || $settings['customtemplates'] === true;
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_GET['sbi_debug'] ) ) {
$settings['customtemplates'] = false;
}
$settings['minnum'] = max( (int) $settings['num'], (int) $settings['nummobile'] );
$settings['showbio'] = $settings['showbio'] === 'true' || $settings['showbio'] === 'on' || $settings['showbio'] === true;
if ( isset( $atts['showbio'] ) && $atts['showbio'] === 'false' ) {
$settings['showbio'] = false;
}
if ( isset( $atts['showheader'] ) && $atts['showheader'] === 'false' ) {
$settings['showheader'] = false;
} elseif ( isset( $atts['showheader'] ) && $atts['showheader'] === 'true' ) {
$settings['showheader'] = true;
}
$settings['disable_resize'] = isset( $db['sb_instagram_disable_resize'] ) && ( $db['sb_instagram_disable_resize'] === 'on' || $db['sb_instagram_disable_resize'] === true );
$settings['favor_local'] = true;
$settings['backup_cache_enabled'] = ! isset( $db['sb_instagram_backup'] ) || ( $db['sb_instagram_backup'] === 'on' ) || $db['sb_instagram_backup'] === true;
$settings['headeroutside'] = ( $settings['headeroutside'] === true || $settings['headeroutside'] === 'on' || $settings['headeroutside'] === 'true' );
$settings['disable_js_image_loading'] = isset( $db['disable_js_image_loading'] ) && ( $db['disable_js_image_loading'] === 'on' || $db['disable_js_image_loading'] === true );
$settings['ajax_post_load'] = isset( $db['sb_ajax_initial'] ) && ( $db['sb_ajax_initial'] === 'on' || $db['sb_ajax_initial'] === true );
switch ( $db['sbi_cache_cron_interval'] ) {
case '30mins':
$settings['sbi_cache_cron_interval'] = 60 * 30;
break;
case '1hour':
$settings['sbi_cache_cron_interval'] = 60 * 60;
break;
default:
$settings['sbi_cache_cron_interval'] = 60 * 60 * 12;
}
$settings['sb_instagram_cache_time'] = isset( $db['sb_instagram_cache_time'] ) ? $db['sb_instagram_cache_time'] : 1;
$settings['sb_instagram_cache_time_unit'] = isset( $db['sb_instagram_cache_time_unit'] ) ? $db['sb_instagram_cache_time_unit'] : 'hours';
// use our new colsmobile and colstablet instead of disable mobile if from the DB setting
if ( ! empty( $settings['disablemobile'] ) ) {
$settings['colstablet'] = $settings['cols'];
$settings['colsmobile'] = $settings['cols'];
$settings['disablemobile'] = false;
}
return $settings;
}
}
inc/class-sb-instagram-cron-updater.php 0000644 00000017245 15051507456 0014142 0 ustar 00 true ) );
$num = count( $cron_records );
if ( $num === \InstagramFeed\Builder\SBI_Db::RESULTS_PER_CRON_UPDATE ) {
wp_schedule_single_event( time() + 120, 'sbi_cron_additional_batch' );
}
self::update_batch( $cron_records );
}
/**
* @param $cron_records
*
* @since 6.0
*/
public static function update_batch( $cron_records ) {
$report = array(
'notes' => array(
'time_ran' => date( 'Y-m-d H:i:s' ),
'num_found_transients' => count( $cron_records ),
),
);
$settings = sbi_get_database_settings();
foreach ( $cron_records as $feed_cache ) {
$feed_id = $feed_cache['feed_id'];
$report[ $feed_id ] = array();
$cache = new SB_Instagram_Cache( $feed_id );
$cache->retrieve_and_set();
$cache->update_last_updated();
$posts_cache = $cache->get( 'posts' );
if ( $posts_cache ) {
$feed_data = json_decode( $posts_cache, true );
$atts = isset( $feed_data['atts'] ) ? $feed_data['atts'] : false;
$last_retrieve = isset( $feed_data['last_retrieve'] ) ? (int) $feed_data['last_retrieve'] : 0;
$last_requested = isset( $feed_data['last_requested'] ) ? (int) $feed_data['last_requested'] : false;
$report[ $feed_id ]['last_retrieve'] = date( 'Y-m-d H:i:s', $last_retrieve );
if ( $atts !== false ) { // not needed after v6?
if ( ! $last_requested || $last_requested > ( time() - 60 * 60 * 24 * 30 ) ) {
$instagram_feed_settings = new SB_Instagram_Settings( $atts, $settings );
self::do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts );
$report[ $feed_id ]['did_update'] = 'yes';
} else {
$report[ $feed_id ]['did_update'] = 'no - not recently requested';
}
} else {
$report[ $feed_id ]['did_update'] = 'no - missing atts';
}
} else {
$report[ $feed_id ]['did_update'] = 'no - no post cache found';
}
}
update_option( 'sbi_cron_report', $report, false );
}
/**
* Update a single feed cache based on settings. Local image storing and
* resizing is done in the background here as well unless this is the initial
* time the feed is created and no cached data exists yet.
*
* Overwritten in the Pro version
*
* @param array $instagram_feed_settings associative array generated from
* the sb_instagram_settings class
* @param array $feed_data post, header, shortcode settings, and other info
* associated with the feed that is saved in the cache
* @param array $atts shortcode settings
* @param bool $include_resize whether or not to resize images during the update since
* images can also be resized with an ajax call when the feed is viewed on the frontend
*
* @return object
*
* @since 2.0/5.0
*/
public static function do_single_feed_cron_update( $instagram_feed_settings, $feed_data, $atts, $include_resize = true ) {
$instagram_feed_settings->set_feed_type_and_terms();
$instagram_feed_settings->set_transient_name();
$transient_name = $instagram_feed_settings->get_transient_name();
$settings = $instagram_feed_settings->get_settings();
$feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
$instagram_feed = new SB_Instagram_Feed( $transient_name );
$instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings );
while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
$instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
}
$to_cache = array(
'atts' => $atts,
'last_requested' => $feed_data['last_requested'],
'last_retrieve' => time()
);
$instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
if ( $instagram_feed->need_header( $settings, $feed_type_and_terms ) ) {
$instagram_feed->set_remote_header_data( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
$instagram_feed->cache_header_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
if ( $include_resize ) {
$post_data = $instagram_feed->get_post_data();
$post_data = array_slice( $post_data, 0, $settings['num'] );
$image_sizes = array(
'personal' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 ),
'business' => array( 'full' => 640, 'low' => 320, 'thumb' => 150 )
);
$post_set = new SB_Instagram_Post_Set( $post_data, $transient_name, NULL, $image_sizes );
$post_set->maybe_save_update_and_resize_images_for_posts();
}
sbi_delete_image_cache( $transient_name );
return $instagram_feed;
}
/**
* Retrieve option name column values for all feed cache transients
*
* @return array
*
* @since 2.0/5.0
*/
public static function get_feed_cache_option_names() {
global $wpdb;
$feed_caches = apply_filters( 'sbi_feed_cache_option_names', array() );
if ( ! empty( $feed_caches ) ) {
return $feed_caches;
}
$results = $wpdb->get_results( "
SELECT option_name
FROM $wpdb->options
WHERE `option_name` LIKE ('%\_transient\_sbi\_%')
AND `option_name` NOT LIKE ('%\_transient\_sbi\_header%');", ARRAY_A );
if ( isset( $results[0] ) ) {
$feed_caches = $results;
}
return $feed_caches;
}
/**
* Start cron jobs based on user's settings for cron cache update frequency.
* This is triggered when settings are saved on the "Configure" tab.
*
* @param string $sbi_cache_cron_interval arbitrary name from one of the
* settings on the "Configure" tab
* @param string $sbi_cache_cron_time hour of the day (1 = 1:00)
* @param string $sbi_cache_cron_am_pm am or pm (time of day)
*
* @since 2.0/5.0
*/
public static function start_cron_job( $sbi_cache_cron_interval, $sbi_cache_cron_time, $sbi_cache_cron_am_pm ) {
wp_clear_scheduled_hook( 'sbi_feed_update' );
if ( $sbi_cache_cron_interval === '12hours' || $sbi_cache_cron_interval === '24hours' ) {
$relative_time_now = time() + sbi_get_utc_offset();
$base_day = strtotime( date( 'Y-m-d', $relative_time_now ) );
$add_time = $sbi_cache_cron_am_pm === 'pm' ? (int)$sbi_cache_cron_time + 12 : (int)$sbi_cache_cron_time;
$utc_start_time = $base_day + (($add_time * 60 * 60) - sbi_get_utc_offset());
if ( $utc_start_time < time() ) {
if ( $sbi_cache_cron_interval === '12hours' ) {
$utc_start_time += 60*60*12;
} else {
$utc_start_time += 60*60*24;
}
}
if ( $sbi_cache_cron_interval === '12hours' ) {
wp_schedule_event( $utc_start_time, 'twicedaily', 'sbi_feed_update' );
} else {
wp_schedule_event( $utc_start_time, 'daily', 'sbi_feed_update' );
}
} else {
if ( $sbi_cache_cron_interval === '30mins' ) {
wp_schedule_event( time(), 'sbi30mins', 'sbi_feed_update' );
} else {
wp_schedule_event( time(), 'hourly', 'sbi_feed_update' );
}
}
}
}
inc/class-sb-instagram-post.php 0000644 00000044476 15051507456 0012532 0 ustar 00 prefix . SBI_INSTAGRAM_POSTS_TYPE;
$feed_id_match = $wpdb->get_results( $wpdb->prepare( "SELECT id, media_id, top_time_stamp, images_done FROM $table_name WHERE instagram_id = %s LIMIT 1", $instagram_post_id ), ARRAY_A );
$this->db_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['id'] : '';
$this->media_id = ! empty( $feed_id_match ) ? $feed_id_match[0]['media_id'] : '';
$this->top_time_stamp = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['top_time_stamp'] ) ? $feed_id_match[0]['top_time_stamp'] : '';
$this->images_done = ! empty( $feed_id_match ) && isset( $feed_id_match[0]['images_done'] ) ? $feed_id_match[0]['images_done'] === '1' : 0;
$this->instagram_post_id = $instagram_post_id;
$this->encryption = new SB_Instagram_Data_Encryption();
}
/**
* Whether or not this post has already been saved in the custom table
*
* @return bool
*
* @since 2.0/4.0
*/
public function exists_in_posts_table() {
return ! empty( $this->db_id );
}
/**
* Whether or not resized image files have already been recorded as being created
* in the database table
*
* @return bool|int
*
* @since 2.0/4.0
*/
public function images_done_resizing() {
return $this->images_done;
}
/**
* @param array $instagram_api_data
*
* @since 2.0/4.0
*/
public function set_instagram_api_data( $instagram_api_data ) {
$this->instagram_api_data = $instagram_api_data;
}
/**
* Used for sorting top posts since they don't have a posted on date
*
* @return string
*
* @since 2.0/4.0
*/
public function get_top_time_stamp() {
return $this->top_time_stamp;
}
/**
* Record newly created images so they can be returned and used right away.
*
* Not used in version 2.0/5.0 but can be used to resize and use
* images "on the fly" when the feed is being displayed.
*
* @param string $key
* @param string $val
*
* @since 2.0/4.0
*/
public function add_resized_image_to_obj_array( $key, $val ) {
$this->resized_image_array[ $key ] = $val;
}
/**
* Used to save information about the post before image resizing is done to
* prevent a potentially storing multiple entries for the same post
*
* @param mixed|string|bool $transient_name (optional)
* @param null $timestamp_override (optional)
*
* @return bool
*
* @since 2.0/4.0
*/
public function save_in_db( $transient_name = false, $timestamp_override = null ) {
global $wpdb;
$parsed_data = $this->get_parsed_post_data();
$timestamp = ! empty( $timestamp_override ) && empty( $parsed_data['timestamp'] ) ? $timestamp_override : $parsed_data['timestamp'];
$entry_data = array(
"'" . date( 'Y-m-d H:i:s' ) . "'",
"'" . esc_sql( $parsed_data['id'] ) . "'",
"'" . esc_sql( $timestamp ) . "'",
"'" . esc_sql( $timestamp ) . "'",
"'" . esc_sql( $this->encryption->encrypt( sbi_json_encode( $this->instagram_api_data ) ) ) . "'",
"'pending'",
"'pending'",
0,
"'" . date( 'Y-m-d H:i:s' ) . "'",
);
$entry_string = implode( ',', $entry_data );
$table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
$timestamp_column = 'time_stamp';
if ( substr( $transient_name, 4, 1 ) === '+' ) {
$timestamp_column = 'top_time_stamp';
}
$error = $wpdb->query(
"INSERT INTO $table_name
(created_on,instagram_id,time_stamp,top_time_stamp,json_data,media_id,sizes,images_done,last_requested) VALUES ($entry_string);"
);
if ( $error !== false ) {
$this->db_id = $wpdb->insert_id;
$this->insert_sbi_instagram_feeds_posts( $transient_name );
} else {
global $sb_instagram_posts_manager;
$error = $wpdb->last_error;
$query = $wpdb->last_query;
$sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . $error . '
' . $query . '
' );
}
return true;
}
/**
* Uses the post's data to get a relevant full size image url and resize it
*
* @param array $image_sizes
* @param string $upload_dir
* @param string $upload_url
*
* @since 2.0/4.0
* @since 2.0/5.0 loop through assoc array (res setting => desired width of image) to
* accommodate personal accounts and possible
* custom sizes in the future
*/
public function resize_and_save_image( $image_sizes, $upload_dir, $upload_url ) {
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
if ( isset( $this->instagram_api_data['id'] ) ) {
$image_source_set = SB_Instagram_Parse::get_media_src_set( $this->instagram_api_data );
$account_type = SB_Instagram_Parse::get_account_type( $this->instagram_api_data );
$image_sizes_to_make = isset( $image_sizes[ $account_type ] ) ? $image_sizes[ $account_type ] : array();
// if it's a personal account or a weird url, the post id is used, otherwise the last part of the image url is used
if ( $account_type === 'business' ) {
$new_file_name = explode( '?', SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' ) );
if ( strlen( basename( $new_file_name[0], '.jpg' ) ) > 10 ) {
$new_file_name = basename( $new_file_name[0], '.jpg' );
} else {
$new_file_name = $this->instagram_api_data['id'];
}
} else {
$new_file_name = $this->instagram_api_data['id'];
}
// the process is considered a success if one image is successfully resized
$one_successful_image_resize = false;
foreach ( $image_sizes_to_make as $res_setting => $image_size ) {
if ( $account_type === 'business' ) {
$file_name = SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' );
} else {
$file_name = isset( $image_source_set[ $image_size ] ) ? $image_source_set[ $image_size ] : SB_Instagram_Parse::get_media_url( $this->instagram_api_data, 'lightbox' );
}
if ( strpos( $file_name, 'placeholder' ) !== false ) {
$file_name = '';
}
if ( ! empty( $file_name ) ) {
$sizes = array(
'height' => 1,
'width' => 1,
);
$suffix = $res_setting;
$this_image_file_name = $new_file_name . $suffix . '.jpg';
$image_editor = wp_get_image_editor( $file_name );
// If there is an error then lets try a fallback approach
if ( is_wp_error( $image_editor ) ) {
// Gives us access to the download_url() and wp_handle_sideload() functions.
require_once ABSPATH . 'wp-admin/includes/file.php';
$timeout_seconds = 5;
// Download file to temp dir.
$temp_file = download_url( $file_name, $timeout_seconds );
$image_editor = wp_get_image_editor( $temp_file );
global $sb_instagram_posts_manager;
$details = __( 'Using backup editor method.', 'instagram-feed' ) . ' ' . $file_name;
$sb_instagram_posts_manager->add_error( 'image_editor', $details );
}
// not uncommon for the image editor to not work using it this way
if ( ! is_wp_error( $image_editor ) ) {
$image_editor->set_quality( 80 );
$sizes = $image_editor->get_size();
$image_editor->resize( $image_size, null );
$full_file_name = trailingslashit( $upload_dir ) . $this_image_file_name;
$saved_image = $image_editor->save( $full_file_name );
if ( ! $saved_image ) {
global $sb_instagram_posts_manager;
$details = __( 'Error saving edited image.', 'instagram-feed' ) . ' ' . $full_file_name;
$sb_instagram_posts_manager->add_error( 'image_editor', $details );
} else {
$one_successful_image_resize = true;
}
} else {
$message = __( 'Error editing image.', 'instagram-feed' );
if ( isset( $image_editor ) && isset( $image_editor->errors ) ) {
foreach ( $image_editor->errors as $key => $item ) {
$message .= ' ' . $key . ' - ' . $item[0] . ' |';
}
if ( isset( $image_editor ) && isset( $image_editor->error_data ) ) {
$message .= ' ' . sbi_json_encode( $image_editor->error_data ) . ' |';
}
}
global $sb_instagram_posts_manager;
$sb_instagram_posts_manager->add_error( 'image_editor', $message );
}
if ( ! empty( $temp_file ) ) {
@unlink( $temp_file );
}
}
}
if ( $one_successful_image_resize ) {
$aspect_ratio = round( $sizes['width'] / $sizes['height'], 2 );
$this->update_sbi_instagram_posts(
array(
'media_id' => $new_file_name,
'sizes' => maybe_serialize( $image_sizes_to_make ),
'aspect_ratio' => $aspect_ratio,
'images_done' => 1,
)
);
$this->add_resized_image_to_obj_array( 'id', $new_file_name );
} else {
// an error status means that image resizing won't be attempted again for this post
$this->update_sbi_instagram_posts(
array(
'media_id' => 'error',
'sizes' => maybe_serialize( $image_sizes_to_make ),
'aspect_ratio' => 1,
'images_done' => 1,
)
);
}
}
}
/**
* Return relevant data for resized images for this post
*
* @return array
*
* @since 2.0/4.0
*/
public function get_resized_image_array() {
if ( empty( $this->resized_image_array ) ) {
global $wpdb;
$posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
$stored = $wpdb->get_results(
$wpdb->prepare(
"SELECT media_id, aspect_ratio FROM $posts_table_name
WHERE instagram_id = %s
LIMIT 1",
$this->instagram_post_id
),
ARRAY_A
);
if ( isset( $stored[0] ) ) {
$return = array(
'id' => $stored[0]['media_id'],
'ratio' => $stored[0]['aspect_ratio'],
);
$this->resized_image_array = $return;
return $return;
} else {
return array();
}
} else {
return $this->resized_image_array;
}
}
/**
* Controls whether or not the database record will be updated for this post.
* Called after images are successfully created.
*
* @param bool $update_last_requested
* @param bool $transient_name
* @param array $image_sizes
* @param string $upload_dir
* @param string $upload_url
* @param bool $timestamp_for_update
*
* @return bool
*
* @since 2.0/4.0
*/
public function update_db_data( $update_last_requested = true, $transient_name = false, $image_sizes = array(), $upload_dir = '', $upload_url = '', $timestamp_for_update = false ) {
if ( empty( $this->db_id ) ) {
return false;
}
$to_update = array(
'json_data' => $this->encryption->encrypt( sbi_json_encode( $this->instagram_api_data ) ),
);
if ( $update_last_requested ) {
$to_update['last_requested'] = date( 'Y-m-d H:i:s' );
}
if ( $timestamp_for_update ) {
$to_update['top_time_stamp'] = $timestamp_for_update;
}
if ( $transient_name ) {
$this->maybe_add_feed_id( $transient_name );
}
if ( $this->media_id === 'pending' ) {
$this->resize_and_save_image( $image_sizes, $upload_dir, $upload_url );
} else {
$this->update_sbi_instagram_posts( $to_update );
}
return true;
}
/**
* Updates columns that need to be updated in the posts types table.
* Called after images successfully resized and if any information
* needs to be updated.
*
* @param array $to_update assoc array of columns and values to update
*
* @since 2.0/4.0
*/
public function update_sbi_instagram_posts( $to_update ) {
global $wpdb;
$table_name = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
foreach ( $to_update as $column => $value ) {
$query = $wpdb->query(
$wpdb->prepare(
"UPDATE $table_name
SET $column = %s
WHERE id = %d;",
$value,
$this->db_id
)
);
if ( $query === false ) {
global $sb_instagram_posts_manager;
$error = $wpdb->last_error;
$query = $wpdb->last_query;
$sb_instagram_posts_manager->add_error( 'storage', __( 'Error updating post.', 'instagram-feed' ) . ' ' . $error . '
' . $query . '
' );
}
}
}
/**
* Checks database for matching record for post and feed ID.
* There shouldn't be duplicate records
*
* @param string $transient_name
*
* @return bool
*
* @since 2.0/4.1
*/
public function exists_in_feeds_posts_table( $transient_name ) {
global $wpdb;
$table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
$feed_id_array = explode( '#', $transient_name );
$feed_id = $feed_id_array[0];
$results = $wpdb->get_results( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE instagram_id = %s AND feed_id = %s LIMIT 1", $this->instagram_post_id, $feed_id ), ARRAY_A );
if ( isset( $results[0]['feed_id'] ) ) {
return true;
}
if ( isset( $this->instagram_api_data['term'] ) ) {
$results = $wpdb->get_results( $wpdb->prepare( "SELECT hashtag FROM $table_name WHERE instagram_id = %s AND hashtag = %s LIMIT 1", $this->instagram_post_id, strtolower( str_replace( '#', '', $this->instagram_api_data['term'] ) ) ), ARRAY_A );
return isset( $results[0]['hashtag'] );
}
return false;
}
/**
* Add a record of this post being used for the specified transient name (feed id)
*
* @param string $transient_name
*
* @return int
*
* @since 2.0/4.0
*/
public function insert_sbi_instagram_feeds_posts( $transient_name ) {
global $wpdb;
$table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
// the number is removed from the transient name for backwards compatibilty.
$feed_id_array = explode( '#', $transient_name );
$feed_id = $feed_id_array[0];
if ( ! empty( $this->db_id ) ) {
$entry_data = array(
$this->db_id,
"'" . esc_sql( $this->instagram_api_data['id'] ) . "'",
"'" . esc_sql( $feed_id ) . "'",
);
if ( ! empty( $this->instagram_api_data['term'] ) ) {
$entry_data[] = "'" . esc_sql( strtolower( str_replace( '#', '', $this->instagram_api_data['term'] ) ) ) . "'";
$entry_string = implode( ',', $entry_data );
$error = $wpdb->query(
"INSERT INTO $table_name
(id,instagram_id,feed_id,hashtag) VALUES ($entry_string);"
);
} else {
$entry_string = implode( ',', $entry_data );
$error = $wpdb->query(
"INSERT INTO $table_name
(id,instagram_id,feed_id) VALUES ($entry_string);"
);
}
} else {
global $sb_instagram_posts_manager;
$sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . __( 'No database ID.', 'instagram-feed' ) );
return false;
}
if ( $error !== false ) {
return $wpdb->insert_id;
} else {
global $sb_instagram_posts_manager;
$error = $wpdb->last_error;
$query = $wpdb->last_query;
$sb_instagram_posts_manager->add_error( 'storage', __( 'Error inserting post.', 'instagram-feed' ) . ' ' . $error . '
' . $query . '
' );
}
}
/**
* Uses the saved json for the post to be used for updating records
*
* @param bool $all
*
* @return array
*
* @since 2.0/4.0
*/
private function get_parsed_post_data( $all = true ) {
$instagram_post_id = isset( $this->instagram_api_data['id'] ) ? $this->instagram_api_data['id'] : '';
$comments_count = isset( $this->instagram_api_data['comments_count'] ) ? $this->instagram_api_data['comments_count'] : '';
$like_count = isset( $this->instagram_api_data['like_count'] ) ? $this->instagram_api_data['like_count'] : '';
$parsed_data = array(
'comments_count' => $comments_count,
'like_count' => $like_count,
);
if ( $all ) {
$caption = isset( $this->instagram_api_data['caption'] ) ? $this->instagram_api_data['caption'] : '';
$media_url = isset( $this->instagram_api_data['media_url'] ) ? $this->instagram_api_data['media_url'] : '';
$media_type = isset( $this->instagram_api_data['media_type'] ) ? $this->instagram_api_data['media_type'] : '';
$timestamp = '';
if ( isset( $this->instagram_api_data['timestamp'] ) ) {
$timestamp_parts = explode( ' ', $this->instagram_api_data['timestamp'] );
$timestamp = str_replace( 'T', ' ', $timestamp_parts[0] );
}
$username = isset( $this->instagram_api_data['username'] ) ? $this->instagram_api_data['username'] : '';
$permalink = isset( $this->instagram_api_data['permalink'] ) ? $this->instagram_api_data['permalink'] : '';
$children = isset( $this->instagram_api_data['children'] ) ? sbi_json_encode( $this->instagram_api_data['children'] ) : '';
$parsed_data['caption'] = $caption;
$parsed_data['media_url'] = $media_url;
$parsed_data['id'] = $instagram_post_id;
$parsed_data['media_type'] = $media_type;
$parsed_data['timestamp'] = $timestamp;
$parsed_data['username'] = $username;
$parsed_data['permalink'] = $permalink;
$parsed_data['children'] = $children;
}
return $parsed_data;
}
/**
* If a record hasn't been made for this transient name/feed id,
* make a record
*
* @param string $feed_id
*
* @since 2.0/4.0
*/
private function maybe_add_feed_id( $feed_id ) {
if ( empty( $this->instagram_post_id ) ) {
return;
}
global $wpdb;
$table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
// the number is removed from the transient name for backwards compatibilty.
$feed_id_array = explode( '#', $feed_id );
$feed_id = str_replace( '+', '', $feed_id_array[0] );
$feed_id_match = $wpdb->get_col( $wpdb->prepare( "SELECT feed_id FROM $table_name WHERE feed_id = %s AND instagram_id = %s", $feed_id, $this->instagram_post_id ) );
if ( ! isset( $feed_id_match[0] ) ) {
$entry_data = array(
$this->db_id,
"'" . esc_sql( $this->instagram_post_id ) . "'",
"'" . esc_sql( $feed_id ) . "'",
);
$entry_string = implode( ',', $entry_data );
$error = $wpdb->query(
"INSERT INTO $table_name
(id,instagram_id,feed_id) VALUES ($entry_string);"
);
}
}
}
inc/class-sb-instagram-gdpr-integrations.php 0000644 00000014566 15051507456 0015202 0 ustar 00 prefix . SBI_INSTAGRAM_POSTS_TYPE;
$sbi_statuses_option['gdpr']['tables'] = true;
if ( $wpdb->get_var( "show tables like '$table_name'" ) !== $table_name ) {
$sbi_statuses_option['gdpr']['tables'] = false;
}
$feeds_posts_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
if ( $wpdb->get_var( "show tables like '$feeds_posts_table_name'" ) !== $feeds_posts_table_name ) {
$sbi_statuses_option['gdpr']['tables'] = false;
}
update_option( 'sbi_statuses', $sbi_statuses_option );
}
if ( $retest ) {
global $sb_instagram_posts_manager;
$sb_instagram_posts_manager->add_action_log( 'Retesting GDPR features.' );
}
if ( ! $sbi_statuses_option['gdpr']['upload_dir']
|| ! $sbi_statuses_option['gdpr']['tables']
|| ! $sbi_statuses_option['gdpr']['image_editor'] ) {
return false;
}
return true;
}
public static function gdpr_tests_error_message() {
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
$errors = array();
if ( ! $sbi_statuses_option['gdpr']['upload_dir'] ) {
$errors[] = __( 'A folder for storing resized images was not successfully created.', 'instagram-feed' );
}
if ( ! $sbi_statuses_option['gdpr']['tables'] ) {
$errors[] = __( 'Tables used for storing information about resized images were not successfully created.', 'instagram-feed' );
}
if ( ! $sbi_statuses_option['gdpr']['image_editor'] ) {
$errors[] = sprintf( __( 'An image editor is not available on your server. Instagram Feed is unable to create local resized images. See %1$sthis FAQ%2$s for more information', 'instagram-feed' ), '
', ' ' );
}
if ( isset( $_GET['tab'] ) && $_GET['tab'] !== 'support' ) {
$tab = sbi_is_pro_version() ? 'customize-advanced' : 'customize';
$errors[] = '
' . __( 'Retest', 'instagram-feed' ) . ' ';
}
return implode( '
', $errors );
}
public static function statuses() {
$sbi_statuses_option = get_option( 'sbi_statuses', array() );
$return = isset( $sbi_statuses_option['gdpr'] ) ? $sbi_statuses_option['gdpr'] : array();
return $return;
}
}
inc/class-sb-instagram-oembed.php 0000644 00000022250 15051507456 0012762 0 ustar 00 ' . str_replace( 'class="instagram-media"', 'class="instagram-media sbi-embed"', $html ) . '
';
}
}
return $html;
}
/**
* Extend the "time to live" for oEmbeds created with access tokens that expire
*
* @param $ttl
* @param $url
* @param $attr
* @param $post_ID
*
* @return float|int
*
* @since 2.5/5.8
*/
public static function oembed_ttl( $ttl, $url, $attr, $post_ID ) {
if ( preg_match( '#https?://(www\.)?instagr(\.am|am\.com)/(p|tv|reel)/.*#i', $url ) === 1 ) {
$ttl = 30 * YEAR_IN_SECONDS;
}
return $ttl;
}
/**
* Depending on whether a business or personal account is connected,
* a different oembed endpoint is used
*
* @return bool|string
*
* @since 2.5/5.8
*/
public static function oembed_url() {
return 'https://graph.facebook.com/v8.0/instagram_oembed';
}
/**
* Any access token will work for oembeds so the most recently connected account's
* access token is returned
*
* @return bool|string
*
* @since 2.5/5.8
*/
public static function last_access_token() {
$oembed_token_settings = get_option( 'sbi_oembed_token', array() );
$will_expire = SB_Instagram_Oembed::oembed_access_token_will_expire();
if ( ! empty( $oembed_token_settings['access_token'] )
&& (! $will_expire || $will_expire > time()) ) {
$return = sbi_maybe_clean( $oembed_token_settings['access_token'] );
return $return;
} else {
$if_database_settings = sbi_get_database_settings();
if ( isset( $if_database_settings['connected_accounts'] ) ) {
$connected_accounts = $if_database_settings['connected_accounts'];
foreach ( $connected_accounts as $connected_account ) {
if ( empty( $oembed_token_settings['access_token'] ) ) {
if ( isset( $connected_account['type'] ) && $connected_account['type'] === 'business' ) {
$oembed_token_settings['access_token'] = $connected_account['access_token'];
}
}
}
}
if ( ! empty( $oembed_token_settings['access_token'] ) ) {
$return = sbi_maybe_clean( $oembed_token_settings['access_token'] );
return $return;
}
if ( class_exists( 'CFF_Oembed' ) ) {
$cff_oembed_token_settings = get_option( 'cff_oembed_token', array() );
if ( ! empty( $cff_oembed_token_settings['access_token'] ) ) {
return $cff_oembed_token_settings['access_token'];
}
}
}
return false;
}
/**
* Access tokens created from FB accounts not connected to an
* FB page expire after 60 days.
*
* @return bool|int
*/
public static function oembed_access_token_will_expire() {
$oembed_token_settings = get_option( 'sbi_oembed_token', array() );
$will_expire = isset( $oembed_token_settings['expiration_date'] ) && (int)$oembed_token_settings['expiration_date'] > 0 ? (int)$oembed_token_settings['expiration_date'] : false;
return $will_expire;
}
/**
* Before links in the content are processed, old oembed post meta
* records are deleted so new oembed data will be retrieved and saved.
* If this check has been done and no old oembeds are found, a flag
* is saved as post meta to skip the process.
*
* @since 2.5/5.8
*/
public static function check_page_for_old_oembeds() {
if ( is_admin() ) {
return;
}
$post_ID = get_the_ID();
$done_checking = (int)get_post_meta( $post_ID, '_sbi_oembed_done_checking', true ) === 1;
if ( ! $done_checking ) {
$num_found = SB_Instagram_Oembed::delete_instagram_oembed_caches( $post_ID );
if ( $num_found === 0 ) {
update_post_meta( $post_ID, '_sbi_oembed_done_checking', 1 );
}
}
}
/**
* Loop through post meta data and if it's an oembed and has content
* that looks like an Instagram oembed, delete it
*
* @param $post_ID
*
* @return int number of old oembed caches found
*
* @since 2.5/5.8
*/
public static function delete_instagram_oembed_caches( $post_ID ) {
$post_metas = get_post_meta( $post_ID );
if ( empty( $post_metas ) ) {
return 0;
}
$total_found = 0;
foreach ( $post_metas as $post_meta_key => $post_meta_value ) {
if ( '_oembed_' === substr( $post_meta_key, 0, 8 ) ) {
if ( strpos( $post_meta_value[0], 'class="instagram-media"' ) !== false
&& strpos( $post_meta_value[0], 'sbi-embed-wrap' ) === false ) {
$total_found++;
delete_post_meta( $post_ID, $post_meta_key );
if ( '_oembed_time_' !== substr( $post_meta_key, 0, 13 ) ) {
delete_post_meta( $post_ID, str_replace( '_oembed_', '_oembed_time_', $post_meta_key ) );
}
}
}
}
return $total_found;
}
/**
* Used for clearing the oembed update check flag for all posts
*
* @since 2.5/5.8
*/
public static function clear_checks() {
global $wpdb;
$table_name = esc_sql( $wpdb->prefix . "postmeta" );
$result = $wpdb->query("
DELETE
FROM $table_name
WHERE meta_key = '_sbi_oembed_done_checking';");
}
}
function sbiOembedInit() {
return new SB_Instagram_Oembed();
}
sbiOembedInit(); inc/if-functions.php 0000644 00000166447 15051507456 0010464 0 ustar 00 get_settings();;
if ( empty( $early_settings ) && ! sbi_doing_customizer( $atts ) ) {
$style = current_user_can( 'manage_instagram_feed_options' ) ? ' style="display: block;"' : '';
$id = isset( $atts['feed'] ) ? (int)$atts['feed'] : false;
if ( $id ) {
$message = sprintf( __( 'Error: No feed with the ID %s found.', 'instagram-feed' ), $id );
} else {
$message = __( 'Error: No feed found.', 'instagram-feed' );
}
ob_start(); ?>
set_feed_type_and_terms();
$instagram_feed_settings->set_transient_name();
$transient_name = $instagram_feed_settings->get_transient_name();
$settings = $instagram_feed_settings->get_settings();
$feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
$instagram_feed = new SB_Instagram_Feed( $transient_name );
$instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings );
if ( $settings['caching_type'] === 'background' ) {
$instagram_feed->add_report( 'background caching used' );
if ( $instagram_feed->regular_cache_exists() ) {
$instagram_feed->add_report( 'setting posts from cache' );
$instagram_feed->set_post_data_from_cache();
}
if ( $instagram_feed->need_to_start_cron_job() ) {
$instagram_feed->add_report( 'setting up feed for cron cache' );
$to_cache = array(
'atts' => $atts,
'last_requested' => time(),
);
$instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() );
SB_Instagram_Cron_Updater::do_single_feed_cron_update( $instagram_feed_settings, $to_cache, $atts, false );
$instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings );
$instagram_feed->set_post_data_from_cache();
} elseif ( $instagram_feed->should_update_last_requested() ) {
$instagram_feed->add_report( 'updating last requested' );
$to_cache = array(
'last_requested' => time(),
);
$instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
} elseif ( $instagram_feed->regular_cache_exists() ) {
$instagram_feed->add_report( 'page load caching used and regular cache exists' );
$instagram_feed->set_post_data_from_cache();
if ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
$instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
}
$instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
} else {
$instagram_feed->add_report( 'no feed cache found' );
while ( $instagram_feed->need_posts( $settings['num'] ) && $instagram_feed->can_get_more_posts() ) {
$instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
}
if ( ! $instagram_feed->should_use_backup() ) {
$instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
}
if ( $instagram_feed->should_use_backup() ) {
$instagram_feed->add_report( 'trying to use backup' );
$instagram_feed->maybe_set_post_data_from_backup();
$instagram_feed->maybe_set_header_data_from_backup();
}
// if need a header
if ( $instagram_feed->need_header( $settings, $feed_type_and_terms ) ) {
if ( $instagram_feed->should_use_backup() && $settings['minnum'] > 0 ) {
$instagram_feed->add_report( 'trying to set header from backup' );
$header_cache_success = $instagram_feed->maybe_set_header_data_from_backup();
} elseif ( $instagram_feed->regular_header_cache_exists() ) {
// set_post_data_from_cache
$instagram_feed->add_report( 'page load caching used and regular header cache exists' );
$instagram_feed->set_header_data_from_cache();
} else {
$instagram_feed->add_report( 'no header cache exists' );
$instagram_feed->set_remote_header_data( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
$instagram_feed->cache_header_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
} else {
$instagram_feed->add_report( 'no header needed' );
}
if ( $settings['resizeprocess'] === 'page' ) {
$instagram_feed->add_report( 'resizing images for post set' );
$post_data = $instagram_feed->get_post_data();
$post_data = array_slice( $post_data, 0, $settings['num'] );
$post_set = new SB_Instagram_Post_Set( $post_data, $transient_name );
$post_set->maybe_save_update_and_resize_images_for_posts();
}
if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
global $sb_instagram_posts_manager;
$post_data = $instagram_feed->get_post_data();
if ( ! $sb_instagram_posts_manager->image_resizing_disabled() ) {
$image_ids = array();
foreach ( $post_data as $post ) {
$image_ids[] = SB_Instagram_Parse::get_post_id( $post );
}
$resized_images = SB_Instagram_Feed::get_resized_images_source_set( $image_ids, 0, $transient_name );
$instagram_feed->set_resized_images( $resized_images );
}
}
return $instagram_feed->get_the_feed_html( $settings, $atts, $instagram_feed_settings->get_feed_type_and_terms(), $instagram_feed_settings->get_connected_accounts_in_feed() );
}
/**
* For efficiency, local versions of image files available for the images actually displayed on the page
* are added at the end of the feed.
*
* @param object $instagram_feed
* @param string $feed_id
*/
function sbi_add_resized_image_data( $instagram_feed, $feed_id ) {
global $sb_instagram_posts_manager;
if ( ! $sb_instagram_posts_manager->image_resizing_disabled() ) {
if ( $instagram_feed->should_update_last_requested() ) {
SB_Instagram_Feed::update_last_requested( $instagram_feed->get_image_ids_post_set() );
}
}
?>
set_feed_type_and_terms();
$instagram_feed_settings->set_transient_name();
$transient_name = $instagram_feed_settings->get_transient_name();
if ( $transient_name !== $feed_id ) {
die( 'id does not match' );
}
$settings = $instagram_feed_settings->get_settings();
$location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( wp_unslash( $_POST['location'] ) ) : 'unknown';
$post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
$feed_details = array(
'feed_id' => $transient_name,
'atts' => $atts,
'location' => array(
'post_id' => $post_id,
'html' => $location
)
);
$can_do_background_tasks = false;
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
$nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : '';
if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) {
$can_do_background_tasks = true;
}
} else {
$can_do_background_tasks = true;
}
if ( $can_do_background_tasks ) {
sbi_do_background_tasks( $feed_details );
}
$feed_type_and_terms = $instagram_feed_settings->get_feed_type_and_terms();
$instagram_feed = new SB_Instagram_Feed( $transient_name );
$instagram_feed->set_cache( $instagram_feed_settings->get_cache_time_in_seconds(), $settings );
if ( $settings['caching_type'] === 'background' ) {
$instagram_feed->add_report( 'background caching used' );
if ( $instagram_feed->regular_cache_exists() ) {
$instagram_feed->add_report( 'setting posts from cache' );
$instagram_feed->set_post_data_from_cache();
}
if ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
while ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
$instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
}
$normal_method = true;
if ( $instagram_feed->need_to_start_cron_job() ) {
$instagram_feed->add_report( 'needed to start cron job' );
$to_cache = array(
'atts' => $atts,
'last_requested' => time(),
);
$normal_method = false;
} else {
$instagram_feed->add_report( 'updating last requested and adding to cache' );
$to_cache = array(
'last_requested' => time(),
);
}
if ( $normal_method ) {
$instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
} else {
$instagram_feed->set_cron_cache( $to_cache, $instagram_feed_settings->get_cache_time_in_seconds() );
}
}
} elseif ( $instagram_feed->regular_cache_exists() ) {
$instagram_feed->add_report( 'regular cache exists' );
$instagram_feed->set_post_data_from_cache();
if ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
while ( $instagram_feed->need_posts( $settings['minnum'], $offset, $page ) && $instagram_feed->can_get_more_posts() ) {
$instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
}
$instagram_feed->add_report( 'adding to cache' );
$instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
} else {
$instagram_feed->add_report( 'no feed cache found' );
while ( $instagram_feed->need_posts( $settings['num'], $offset ) && $instagram_feed->can_get_more_posts() ) {
$instagram_feed->add_remote_posts( $settings, $feed_type_and_terms, $instagram_feed_settings->get_connected_accounts_in_feed() );
}
if ( $instagram_feed->should_use_backup() ) {
$instagram_feed->add_report( 'trying to use a backup cache' );
$instagram_feed->maybe_set_post_data_from_backup();
} else {
$instagram_feed->add_report( 'transient gone, adding to cache' );
$instagram_feed->cache_feed_data( $instagram_feed_settings->get_cache_time_in_seconds(), $settings['backup_cache_enabled'] );
}
}
if ( $settings['disable_js_image_loading'] || $settings['imageres'] !== 'auto' ) {
global $sb_instagram_posts_manager;
$post_data = array_slice( $instagram_feed->get_post_data(), $offset, $settings['minnum'] );
if ( ! $sb_instagram_posts_manager->image_resizing_disabled() ) {
$image_ids = array();
foreach ( $post_data as $post ) {
$image_ids[] = SB_Instagram_Parse::get_post_id( $post );
}
$resized_images = SB_Instagram_Feed::get_resized_images_source_set( $image_ids, 0, $feed_id );
$instagram_feed->set_resized_images( $resized_images );
}
}
$feed_status = array( 'shouldPaginate' => $instagram_feed->should_use_pagination( $settings, $offset ) );
$return = array(
'html' => $instagram_feed->get_the_items_html( $settings, $offset, $instagram_feed_settings->get_feed_type_and_terms(), $instagram_feed_settings->get_connected_accounts_in_feed() ),
'feedStatus' => $feed_status,
'report' => $instagram_feed->get_report(),
'resizedImages' => SB_Instagram_Feed::get_resized_images_source_set( $instagram_feed->get_image_ids_post_set(), 1, $feed_id )
);
header( 'Content-Type: application/json; charset=utf-8' );
echo sbi_json_encode( $return );
die();
}
add_action( 'wp_ajax_sbi_load_more_clicked', 'sbi_get_next_post_set' );
add_action( 'wp_ajax_nopriv_sbi_load_more_clicked', 'sbi_get_next_post_set' );
/**
* Posts that need resized images are processed after being sent to the server
* using AJAX
*
* @return string
*/
function sbi_process_submitted_resize_ids() {
if ( ! sbi_current_user_can( 'manage_instagram_feed_options') ) {
if ( ! isset( $_POST['feed_id'] ) || (strpos( $_POST['feed_id'], 'sbi' ) === false && strpos( $_POST['feed_id'], '*' ) === false ) ) {
die( 'invalid feed ID');
}
}
$feed_id = sanitize_text_field( $_POST['feed_id'] );
$images_need_resizing_raw = isset( $_POST['needs_resizing'] ) ? $_POST['needs_resizing'] : array();
if ( is_array( $images_need_resizing_raw ) ) {
array_map( 'sbi_sanitize_instagram_ids', $images_need_resizing_raw );
} else {
$images_need_resizing_raw = array();
}
$images_need_resizing = $images_need_resizing_raw;
$atts_raw = isset( $_POST['atts'] ) ? json_decode( wp_unslash( $_POST['atts'] ), true ) : array();
if ( is_array( $atts_raw ) ) {
$atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw );
} else {
$atts_raw = array();
}
$atts = $atts_raw; // now sanitized
$offset = isset( $_POST['offset'] ) ? (int)$_POST['offset'] : 0;
$cache_all = isset( $_POST['cache_all'] ) ? $_POST['cache_all'] === 'true' : false;
$database_settings = sbi_get_database_settings();
$instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
$instagram_feed_settings->set_feed_type_and_terms();
$instagram_feed_settings->set_transient_name();
$transient_name = $instagram_feed_settings->get_transient_name();
$settings = $instagram_feed_settings->get_settings();
$location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown';
$post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
$feed_details = array(
'feed_id' => $transient_name,
'atts' => $atts,
'location' => array(
'post_id' => $post_id,
'html' => $location
)
);
$can_do_background_tasks = false;
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
$nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : '';
if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) {
$can_do_background_tasks = true;
}
} else {
$can_do_background_tasks = true;
}
if ( $can_do_background_tasks ) {
sbi_do_background_tasks( $feed_details );
}
if ( $cache_all ) {
$settings['cache_all'] = true;
}
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
if ( $transient_name !== $feed_id ) {
die( 'id does not match' );
}
}
sbi_resize_posts_by_id( $images_need_resizing, $transient_name, $settings );
sbi_delete_image_cache( $transient_name );
global $sb_instagram_posts_manager;
if ( ! $sb_instagram_posts_manager->image_resizing_disabled( $transient_name ) ) {
$num = $settings['minnum'] * 2 + 5;
header( 'Content-Type: application/json; charset=utf-8' );
echo sbi_json_encode( SB_Instagram_Feed::get_resized_images_source_set( $num, $offset - $settings['minnum'], $feed_id, false ) );
die();
}
die( 'resizing success' );
}
add_action( 'wp_ajax_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' );
add_action( 'wp_ajax_nopriv_sbi_resized_images_submit', 'sbi_process_submitted_resize_ids' );
function sbi_do_locator() {
if ( ! sbi_current_user_can( 'manage_instagram_feed_options') ) {
if ( ! isset( $_POST['feed_id'] ) || (strpos( $_POST['feed_id'], 'sbi' ) === false && strpos( $_POST['feed_id'], '*' ) === false ) ) {
die( 'invalid feed ID');
}
}
$feed_id = sanitize_text_field( wp_unslash( $_POST['feed_id'] ) );
$atts_raw = isset( $_POST['atts'] ) ? json_decode( wp_unslash( $_POST['atts'] ), true ) : array();
if ( is_array( $atts_raw ) ) {
$atts_raw = SB_Instagram_Settings::sanitize_raw_atts( $atts_raw );
} else {
$atts_raw = array();
}
$atts = $atts_raw; // now sanitized
$database_settings = sbi_get_database_settings();
$instagram_feed_settings = new SB_Instagram_Settings( $atts, $database_settings );
$instagram_feed_settings->set_feed_type_and_terms();
$instagram_feed_settings->set_transient_name();
$transient_name = $instagram_feed_settings->get_transient_name();
$location = isset( $_POST['location'] ) && in_array( $_POST['location'], array( 'header', 'footer', 'sidebar', 'content' ), true ) ? sanitize_text_field( $_POST['location'] ) : 'unknown';
$post_id = isset( $_POST['post_id'] ) && $_POST['post_id'] !== 'unknown' ? (int)$_POST['post_id'] : 'unknown';
$feed_details = array(
'feed_id' => $feed_id,
'atts' => $atts,
'location' => array(
'post_id' => $post_id,
'html' => $location
)
);
$can_do_background_tasks = false;
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
$nonce = isset( $_POST['locator_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['locator_nonce'] ) ) : '';
if ( wp_verify_nonce( $nonce, esc_attr( 'sbi-locator-nonce-' . $post_id . '-' . $transient_name ) ) ) {
$can_do_background_tasks = true;
}
} else {
$can_do_background_tasks = true;
}
if ( $can_do_background_tasks ) {
sbi_do_background_tasks( $feed_details );
wp_die( 'locating success' );
}
wp_die( 'skipped locating' );
}
add_action( 'wp_ajax_sbi_do_locator', 'sbi_do_locator' );
add_action( 'wp_ajax_nopriv_sbi_do_locator', 'sbi_do_locator' );
function sbi_do_background_tasks( $feed_details ) {
if ( is_admin()
&& isset( $_GET['page'] )
&& $_GET['page'] === 'sbi-feed-builder') {
return;
}
$locator = new SB_Instagram_Feed_Locator( $feed_details );
$locator->add_or_update_entry();
if ( $locator->should_clear_old_locations() ) {
$locator->delete_old_locations();
}
}
/**
* Outputs an organized error report for the front end.
* This hooks into the end of the feed before the closing div
*
* @param object $instagram_feed
* @param string $feed_id
*/
function sbi_error_report( $instagram_feed, $feed_id ) {
global $sb_instagram_posts_manager;
if ( ! sbi_current_user_can( 'manage_instagram_feed_options' ) ) {
$sb_instagram_posts_manager->reset_frontend_errors();
return;
}
$error_messages = $sb_instagram_posts_manager->get_frontend_errors( $instagram_feed );
if ( ! empty( $error_messages ) ) {?>