PluginProbe ʕ •ᴥ•ʔ
Smash Balloon Social Photo Feed – Easy Social Feeds Plugin / 6.11.0
Smash Balloon Social Photo Feed – Easy Social Feeds Plugin v6.11.0
6.11.0 1.11.1 1.11.2 1.11.3 1.12 1.12.1 1.12.2 1.2 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.10 1.3.11 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.6.2 1.4.7 1.4.8 1.4.9 1.5 1.5.1 1.6 1.6.1 1.6.2 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9 1.9.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.2 2.2.1 2.2.2 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5 2.5.1 2.5.2 2.5.3 2.5.4 2.6 2.6.1 2.6.2 2.7 2.8 2.8.1 2.8.2 2.9 2.9.1 2.9.10 2.9.2 2.9.3 2.9.3.1 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8 2.9.9 6.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.0.8 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.10.0 6.10.1 6.2 6.2.1 6.2.10 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.7 6.2.8 6.2.9 6.3 6.3.1 6.4 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.6.0 6.6.1 6.7.0 6.7.1 6.8.0 6.9.0 6.9.1 trunk 1.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.10 1.10.1 1.10.2 1.11
instagram-feed / instagram-feed.php
instagram-feed Last commit date
admin 2 weeks ago assets 2 weeks ago css 2 weeks ago img 2 weeks ago inc 2 weeks ago js 2 weeks ago languages 2 weeks ago templates 2 weeks ago vendor 2 weeks ago README.txt 2 weeks ago gpl-2.0.txt 2 weeks ago index.php 2 weeks ago instagram-feed.php 2 weeks ago widget.php 2 weeks ago wpml-config.xml 2 weeks ago
instagram-feed.php
1325 lines
1 <?php
2
3 /*
4 Plugin Name: Smash Balloon Instagram Feed
5 Plugin URI: https://smashballoon.com/instagram-feed
6 Description: Display beautifully clean, customizable, and responsive Instagram feeds.
7 Version: 6.11.0
8 Requires PHP: 7.4
9 Author: Smash Balloon
10 Author URI: https://smashballoon.com/
11 License: GPLv2 or later
12 Text Domain: instagram-feed
13
14 Copyright 2025 Smash Balloon LLC (email : hey@smashballoon.com)
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28 // Check PHP version
29 if (version_compare(PHP_VERSION, '7.4', '<')) {
30 add_action('admin_notices', function () {
31 ?>
32 <div class="notice notice-error">
33 <p><?php _e('Instagram Feed now requires PHP 7.4 or higher. Your PHP version is not compatible. Reach out to your host and ask to update your PHP version.', 'instagram-feed'); ?></p>
34 <p><a href="https://smashballoon.com/doc/what-php-version-is-required-for-instagram-feeds/?utm_source=%7Bcampaign%7D&utm_medium=plugin-dashboard-notices&utm_campaign=phpupgrade&utm_content=how-upgrade" class="button button-primary" target="_blank" rel="noopener noreferrer"><?php _e('How do I upgrade PHP?', 'instagram-feed'); ?></a></p>
35 </div>
36 <?php
37 });
38 return;
39 }
40
41 use InstagramFeed\Builder\SBI_Db;
42 use InstagramFeed\Builder\SBI_Feed_Saver;
43 use InstagramFeed\Builder\SBI_Source;
44 use InstagramFeed\Helpers\SB_Instagram_Tracking;
45 use InstagramFeed\Integrations\FeedAnalytics;
46 use InstagramFeed\Services\ServiceContainer;
47 use InstagramFeed\Vendor\Smashballoon\Framework\Packages\Blocks\RecommendedBlocks;
48 use InstagramFeed\Vendor\Smashballoon\Framework\Packages\Notification\Notices\SBNotices;
49
50 if (!defined('SBI_STORE_URL')) {
51 define('SBI_STORE_URL', 'https://smashballoon.com/');
52 }
53 if (!defined('SBI_PLUGIN_NAME')) {
54 define('SBI_PLUGIN_NAME', 'Instagram Feed Free');
55 }
56 if (!defined('SBIVER')) {
57 define('SBIVER', '6.11.0');
58 }
59 // Db version.
60 if (!defined('SBI_DBVERSION')) {
61 define('SBI_DBVERSION', '2.4');
62 }
63 // Bump when a release invalidates cached feed data. See sbi_cache_invalidation_registry().
64 if (!defined('SBI_CACHE_VERSION')) {
65 define('SBI_CACHE_VERSION', '1');
66 }
67
68 // Upload folder name for local image files for posts.
69 if (!defined('SBI_UPLOADS_NAME')) {
70 define('SBI_UPLOADS_NAME', 'sb-instagram-feed-images');
71 }
72 // Name of the database table that contains instagram posts.
73 if (!defined('SBI_INSTAGRAM_POSTS_TYPE')) {
74 define('SBI_INSTAGRAM_POSTS_TYPE', 'sbi_instagram_posts');
75 }
76 // Name of the database table that contains feed ids and the ids of posts.
77 if (!defined('SBI_INSTAGRAM_FEEDS_POSTS')) {
78 define('SBI_INSTAGRAM_FEEDS_POSTS', 'sbi_instagram_feeds_posts');
79 }
80 if (!defined('SBI_INSTAGRAM_FEED_LOCATOR')) {
81 define('SBI_INSTAGRAM_FEED_LOCATOR', 'sbi_instagram_feed_locator');
82 }
83 if (!defined('SBI_REFRESH_THRESHOLD_OFFSET')) {
84 define('SBI_REFRESH_THRESHOLD_OFFSET', 40 * 86400);
85 }
86 if (!defined('SBI_MINIMUM_INTERVAL')) {
87 define('SBI_MINIMUM_INTERVAL', 600);
88 }
89 if (!defined('SBI_CONNECT_URL')) {
90 define('SBI_CONNECT_URL', 'https://connect-ig.smashballoon.com/');
91 }
92 if (!defined('SBI_OEMBED_CONNECT_URL')) {
93 define('SBI_OEMBED_CONNECT_URL', 'https://connect-tools.smashballoon.com/');
94 }
95
96 if (!defined('ABSPATH')) {
97 exit; // Exit if accessed directly.
98 }
99 if (!function_exists('sb_instagram_feed_init')) {
100 /**
101 * Define constants and load plugin files
102 *
103 * @since 2.0
104 */
105 function sb_instagram_feed_init()
106 {
107 // Plugin Folder Path.
108 if (!defined('SBI_PLUGIN_DIR')) {
109 define('SBI_PLUGIN_DIR', plugin_dir_path(__FILE__));
110 }
111 // Plugin Folder URL.
112 if (!defined('SBI_PLUGIN_URL')) {
113 define('SBI_PLUGIN_URL', plugin_dir_url(__FILE__));
114 }
115 // Plugin Base Name.
116 if (!defined('SBI_PLUGIN_BASENAME')) {
117 define('SBI_PLUGIN_BASENAME', plugin_basename(__FILE__));
118 }
119 // Plugin Base Name.
120 if (!defined('SBI_BACKUP_PREFIX')) {
121 define('SBI_BACKUP_PREFIX', '!');
122 }
123 // Plugin Base Name.
124 if (!defined('SBI_FPL_PREFIX')) {
125 define('SBI_FPL_PREFIX', '$');
126 }
127 // Plugin Base Name.
128 if (!defined('SBI_USE_BACKUP_PREFIX')) {
129 define('SBI_USE_BACKUP_PREFIX', '&');
130 }
131 // Cron Updating Cache Time 60 days.
132 if (!defined('SBI_CRON_UPDATE_CACHE_TIME')) {
133 define('SBI_CRON_UPDATE_CACHE_TIME', 60 * 60 * 24 * 60);
134 }
135 // Max Records in Database for Image Resizing.
136 if (!defined('SBI_MAX_RECORDS')) {
137 define('SBI_MAX_RECORDS', 350);
138 }
139
140 if (!defined('SBI_BUILDER_DIR')) {
141 define('SBI_BUILDER_DIR', SBI_PLUGIN_DIR . 'admin/builder/');
142 }
143
144 if (!defined('SBI_BUILDER_URL')) {
145 define('SBI_BUILDER_URL', SBI_PLUGIN_URL . 'admin/builder/');
146 }
147
148 require SBI_PLUGIN_DIR . 'vendor/autoload.php';
149
150 // Initialize the deactivation feedback survey.
151 if (class_exists('\InstagramFeed\Vendor\Smashballoon\Framework\Packages\Feedback\FeedbackManager')) {
152 \InstagramFeed\Vendor\Smashballoon\Framework\Packages\Feedback\FeedbackManager::init([
153 'plugin_slug' => 'instagram-feed',
154 'plugin_name' => 'Smash Balloon Instagram Feed',
155 'plugin_version' => SBIVER,
156 'plugin_file' => SBI_PLUGIN_DIR . 'instagram-feed.php',
157 'support_url' => 'https://smashballoon.com/support/',
158 ]);
159 }
160
161 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/if-functions.php';
162 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-api-connect.php';
163 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-cache.php';
164 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-connected-account.php';
165 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-cron-updater.php';
166 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-data-encryption.php';
167 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-data-manager.php';
168 $manager = new SB_Instagram_Data_Manager();
169 $manager->init();
170 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-display-elements.php';
171 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-feed.php';
172 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-feed-locator.php';
173 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-gdpr-integrations.php';
174 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-oembed.php';
175 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-parse.php';
176 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-post.php';
177 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-post-set.php';
178 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-posts-manager.php';
179 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-settings.php';
180 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-single.php';
181 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-token-refresher.php';
182 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/blocks/class-sbi-blocks.php';
183
184 global $sbi_notices;
185 $sbi_notices = SBNotices::instance('instagram-feed');
186
187 $sbi_blocks = new SB_Instagram_Blocks();
188 new SB_Instagram_Tracking();
189
190 // Boot all services.
191 $service_container = new ServiceContainer();
192 $service_container->register();
193
194 if ($sbi_blocks->allow_load()) {
195 $sbi_blocks->load();
196 }
197
198 if (is_admin()) {
199 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/actions.php';
200 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/class-sbi-account-connector.php';
201
202 if (
203 version_compare(PHP_VERSION, '5.3.0') >= 0
204 && version_compare(get_bloginfo('version'), '4.6', '>=')
205 ) {
206 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/class-sbi-notifications.php';
207 $sbi_notifications = new SBI_Notifications();
208 $sbi_notifications->init();
209
210 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/class-sbi-new-user.php';
211 $sbi_newuser = new SBI_New_User();
212 $sbi_newuser->init();
213
214 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/addon-functions.php';
215 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/PluginSilentUpgrader.php';
216 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/PluginSilentUpgraderSkin.php';
217 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/class-install-skin.php';
218 }
219
220 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/admin/class-sbi-sitehealth.php';
221
222 $sbi_sitehealth = new SB_Instagram_SiteHealth();
223
224 if ($sbi_sitehealth->allow_load()) {
225 $sbi_sitehealth->load();
226 }
227
228 $recommended_blocks = new RecommendedBlocks();
229 $recommended_blocks->setup();
230 }
231 include_once trailingslashit(SBI_PLUGIN_DIR) . 'widget.php';
232
233 global $sb_instagram_posts_manager;
234 $sb_instagram_posts_manager = new SB_Instagram_Posts_Manager();
235
236 include SBI_PLUGIN_DIR . '/inc/Builder/SBI_Feed_Builder.php';
237 include SBI_PLUGIN_DIR . '/inc/Builder/SBI_Tooltip_Wizard.php';
238
239 sbi_builder_free();
240 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_View.php';
241
242 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_About_Us.php';
243 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Admin_Notices.php';
244 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Global_Settings.php';
245 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_HTTP_Request.php';
246 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_oEmbeds.php';
247 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Response.php';
248 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Support.php';
249 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Upgrader.php';
250 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_View.php';
251 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Support_Tool.php';
252
253 $sbi_oembed = new InstagramFeed\Admin\SBI_oEmbeds();
254 $sbi_global_settings = new InstagramFeed\Admin\SBI_Global_Settings();
255 $sbi_support = new InstagramFeed\Admin\SBI_Support();
256 $sbi_upgrader = new InstagramFeed\Admin\SBI_Upgrader();
257 $sbi_upgrader->hooks();
258 $sbi_about_us = new InstagramFeed\Admin\SBI_About_Us();
259 $sbi_admin_notices = new InstagramFeed\Admin\SBI_Admin_Notices();
260 $sbi_tooltip_wizard = new InstagramFeed\Builder\SBI_Tooltip_Wizard();
261 $sbi_onboarding_wizard = new InstagramFeed\admin\SBI_Onboarding_wizard();
262
263 $sbi_support_tool = new InstagramFeed\Admin\SBI_Support_Tool();
264
265 InstagramFeed\Integrations\Elementor\SBI_Elementor_Base::register();
266 $sbi_divi_handler = new InstagramFeed\Integrations\Divi\SBI_Divi_Handler();
267
268 require_once trailingslashit(SBI_PLUGIN_DIR) . 'admin/SBI_Callout.php';
269 $sbi_callout = new InstagramFeed\Admin\SBI_Callout();
270
271 $sbi_analytics = new FeedAnalytics();
272 $sbi_analytics->loadFilters();
273 }
274
275 add_action('init', 'sb_instagram_feed_init');
276
277 /**
278 * Add custom intervals for cron caching.
279 *
280 * @param array $schedules The current list of cron intervals.
281 * @return array The modified list of cron intervals.
282 * @since 2.0
283 */
284 function sbi_cron_custom_interval($schedules)
285 {
286 $schedules['sbi30mins'] = array(
287 'interval' => 30 * 60,
288 'display' => __('Every 30 minutes')
289 );
290 $schedules['sbiweekly'] = array(
291 'interval' => 3600 * 24 * 7,
292 'display' => __('Weekly')
293 );
294
295 return $schedules;
296 }
297
298 add_filter('cron_schedules', 'sbi_cron_custom_interval');
299
300 /**
301 * Create database tables, schedule cron events, initiate capabilities
302 *
303 * @param bool $network_wide is a multisite network activation
304 *
305 * @since 2.0 database tables and capabilties created
306 * @since 1.0
307 */
308 function sb_instagram_activate($network_wide)
309 {
310 // Clear page caching plugins and autoptomize.
311 require_once trailingslashit(plugin_dir_path(__FILE__)) . 'inc/if-functions.php';
312
313 // Run cron twice daily when plugin is first activated for new users.
314 if (!wp_next_scheduled('sb_instagram_cron_job')) {
315 wp_schedule_event(time(), 'twicedaily', 'sb_instagram_cron_job');
316 }
317 if (!wp_next_scheduled('sb_instagram_twicedaily')) {
318 wp_schedule_event(time(), 'twicedaily', 'sb_instagram_twicedaily');
319 }
320 if (!wp_next_scheduled('sb_instagram_feed_issue_email')) {
321 sbi_schedule_report_email();
322 }
323
324 $sbi_settings = get_option('sb_instagram_settings', array());
325 if (isset($sbi_settings['sbi_caching_type']) && $sbi_settings['sbi_caching_type'] === 'background') {
326 require_once trailingslashit(plugin_dir_path(__FILE__)) . 'inc/if-functions.php';
327 require_once trailingslashit(plugin_dir_path(__FILE__)) . 'inc/class-sb-instagram-cron-updater.php';
328 SB_Instagram_Cron_Updater::start_cron_job($sbi_settings['sbi_cache_cron_interval'], $sbi_settings['sbi_cache_cron_time'], $sbi_settings['sbi_cache_cron_am_pm']);
329 }
330
331 require_once(trailingslashit(dirname(__FILE__)) . 'inc/class-sb-instagram-posts-manager.php');
332 $sb_instagram_posts_manager = new SB_Instagram_Posts_Manager();
333
334 if (is_multisite() && $network_wide && function_exists('get_sites') && class_exists('WP_Site_Query')) {
335 // Get all blogs in the network and activate plugin on each one.
336 $sites = get_sites();
337 foreach ($sites as $site) {
338 switch_to_blog($site->blog_id);
339
340 $upload = wp_upload_dir();
341 $upload_dir = $upload['basedir'];
342 $upload_dir = trailingslashit($upload_dir) . SBI_UPLOADS_NAME;
343 if (!file_exists($upload_dir)) {
344 $created = wp_mkdir_p($upload_dir);
345 if ($created) {
346 $sb_instagram_posts_manager->remove_error('upload_dir');
347 } else {
348 $sb_instagram_posts_manager->add_error('upload_dir', array(
349 __('There was an error creating the folder for storing resized images.', 'instagram-feed'),
350 $upload_dir
351 ));
352 }
353 } else {
354 $sb_instagram_posts_manager->remove_error('upload_dir');
355 }
356
357 sbi_create_database_table();
358 restore_current_blog();
359 }
360 } else {
361 $upload = wp_upload_dir();
362 $upload_dir = $upload['basedir'];
363 $upload_dir = trailingslashit($upload_dir) . SBI_UPLOADS_NAME;
364 if (!file_exists($upload_dir)) {
365 $created = wp_mkdir_p($upload_dir);
366 if ($created) {
367 $sb_instagram_posts_manager->remove_error('upload_dir');
368 } else {
369 $sb_instagram_posts_manager->add_error('upload_dir', array(
370 __('There was an error creating the folder for storing resized images.', 'instagram-feed'),
371 $upload_dir
372 ));
373 }
374 } else {
375 $sb_instagram_posts_manager->remove_error('upload_dir');
376 }
377
378 sbi_create_database_table();
379 }
380
381 global $wp_roles;
382 $wp_roles->add_cap('administrator', 'manage_instagram_feed_options');
383
384 // set usage tracking to false if fresh install.
385 $usage_tracking = sbi_get_option('sbi_usage_tracking', false);
386
387 if (!is_array($usage_tracking)) {
388 $usage_tracking = array(
389 'enabled' => false,
390 'last_send' => 0
391 );
392
393 sbi_update_option('sbi_usage_tracking', $usage_tracking, false);
394 }
395 if (!wp_next_scheduled('sbi_notification_update')) {
396 $timestamp = strtotime('next monday');
397 $timestamp = $timestamp + (3600 * 24 * 7);
398 $six_am_local = $timestamp + sbi_get_utc_offset() + (6 * 60 * 60);
399
400 wp_schedule_event($six_am_local, 'sbiweekly', 'sbi_notification_update');
401 }
402
403 $sbi_statuses_option = get_option('sbi_statuses', array());
404 if (!isset($sbi_statuses_option['wizard_dismissed']) || $sbi_statuses_option['wizard_dismissed'] === false) {
405 add_option('sbi_plugin_do_activation_redirect', true);
406 }
407 }
408
409 register_activation_hook(__FILE__, 'sb_instagram_activate');
410
411
412 function sbi_activation_plugin_redirect()
413 {
414
415 if (!sbi_current_user_can('manage_instagram_feed_options')) {
416 return false;
417 }
418
419 if (get_option('sbi_plugin_do_activation_redirect', false)) {
420 delete_option('sbi_plugin_do_activation_redirect');
421 wp_safe_redirect(admin_url('/admin.php?page=sbi-setup'));
422 exit();
423 }
424 }
425
426 add_action('admin_init', 'sbi_activation_plugin_redirect');
427
428 /**
429 * Stop cron events when deactivated
430 *
431 * @since 1.0
432 */
433 function sb_instagram_deactivate()
434 {
435 wp_clear_scheduled_hook('sb_instagram_twicedaily');
436 wp_clear_scheduled_hook('sb_instagram_cron_job');
437 wp_clear_scheduled_hook('sb_instagram_feed_issue_email');
438 wp_clear_scheduled_hook('sbi_notification_update');
439 InstagramFeed\Admin\SBI_Support_Tool::delete_temp_user();
440 }
441
442 register_deactivation_hook(__FILE__, 'sb_instagram_deactivate');
443
444 /**
445 * Creates custom database tables and directory for storing custom
446 * images
447 *
448 * @param bool $include_charset_collate Whether to include charset collate in the query.
449 * @return void
450 * @since 2.0
451 */
452 function sbi_create_database_table($include_charset_collate = true)
453 {
454 if (!function_exists('dbDelta')) {
455 require_once ABSPATH . '/wp-admin/includes/upgrade.php';
456 }
457
458 global $wpdb;
459 $max_index_length = 191;
460 $charset_collate = '';
461 if ($include_charset_collate && method_exists($wpdb, 'get_charset_collate')) { // get_charset_collate introduced in WP 3.5.
462 $charset_collate = $wpdb->get_charset_collate();
463 }
464
465 global $sb_instagram_posts_manager;
466 $had_error = false;
467
468 if (!isset($sb_instagram_posts_manager)) {
469 require_once(trailingslashit(dirname(__FILE__)) . 'inc/class-sb-instagram-posts-manager.php');
470 $sb_instagram_posts_manager = new SB_Instagram_Posts_Manager();
471 }
472
473 $table_name = esc_sql($wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE);
474
475 if ($wpdb->get_var("show tables like '$table_name'") !== $table_name) {
476 $sql = "CREATE TABLE " . $table_name . " (
477 id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
478 created_on DATETIME,
479 instagram_id VARCHAR(1000) DEFAULT '' NOT NULL,
480 time_stamp DATETIME,
481 top_time_stamp DATETIME,
482 json_data LONGTEXT DEFAULT '' NOT NULL,
483 media_id VARCHAR(1000) DEFAULT '' NOT NULL,
484 sizes VARCHAR(1000) DEFAULT '' NOT NULL,
485 aspect_ratio DECIMAL (4,2) DEFAULT 0 NOT NULL,
486 images_done TINYINT(1) DEFAULT 0 NOT NULL,
487 last_requested DATE,
488 mime_type VARCHAR(100) DEFAULT '' NOT NULL
489 ) $charset_collate;";
490 $wpdb->query($sql);
491 }
492 $error = $wpdb->last_error;
493 $query = $wpdb->last_query;
494
495 if ($wpdb->get_var("show tables like '$table_name'") !== $table_name) {
496 $had_error = true;
497 $sb_instagram_posts_manager->add_error('database_create', '<strong>' . __('There was an error when trying to create the database tables used for resizing images.', 'instagram-feed') . '</strong><br>' . $error . '<br><code>' . $query . '</code>');
498 }
499
500 $feeds_posts_table_name = esc_sql($wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS);
501
502 if ($wpdb->get_var("show tables like '$feeds_posts_table_name'") != $feeds_posts_table_name) {
503 $sql = "CREATE TABLE " . $feeds_posts_table_name . " (
504 record_id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
505 id INT(11) UNSIGNED NOT NULL,
506 instagram_id VARCHAR(1000) DEFAULT '' NOT NULL,
507 feed_id VARCHAR(1000) DEFAULT '' NOT NULL,
508 hashtag VARCHAR(1000) DEFAULT '' NOT NULL,
509 INDEX hashtag (hashtag($max_index_length)),
510 INDEX feed_id (feed_id($max_index_length))
511 ) $charset_collate;";
512 $wpdb->query($sql);
513 $sbi_statuses_option = get_option('sbi_statuses', array());
514
515 $sbi_statuses_option['database']['hashtag_column'] = true;
516
517 update_option('sbi_statuses', $sbi_statuses_option);
518 }
519 $error = $wpdb->last_error;
520 $query = $wpdb->last_query;
521
522 if ($wpdb->get_var("show tables like '$feeds_posts_table_name'") != $feeds_posts_table_name) {
523 $had_error = true;
524 $sb_instagram_posts_manager->add_error('database_create', '<strong>' . __('There was an error when trying to create the database tables used for resizing images.', 'instagram-feed') . '</strong><br>' . $error . '<br><code>' . $query . '</code>');
525 }
526
527 if (!$had_error) {
528 $sb_instagram_posts_manager->remove_error('database_create');
529 }
530
531 $sources_table_name = esc_sql($wpdb->prefix . 'sbi_sources');
532
533 // Safely check if the table exists.
534 $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $sources_table_name));
535 if ($table_exists === $sources_table_name) {
536 // Get the list of columns in the table.
537 $columns = $wpdb->get_col("DESC $sources_table_name", 0);
538 // If the 'connect_type' column does not exist, add it.
539 if (!in_array('connect_type', $columns, true)) {
540 $alter_result = $wpdb->query(
541 "ALTER TABLE $sources_table_name
542 ADD COLUMN connect_type VARCHAR(100) DEFAULT '' NOT NULL"
543 );
544 // If the ALTER query was successful, update existing rows with appropriate values.
545 if (false !== $alter_result) {
546 $update_result = $wpdb->query(
547 "UPDATE $sources_table_name
548 SET connect_type = CASE
549 WHEN account_type = 'business' THEN 'business_advanced'
550 ELSE 'personal'
551 END"
552 );
553 // If updating rows fails, log an error; otherwise, clear notices and errors.
554 if (false === $update_result) {
555 $sb_instagram_posts_manager->add_error(
556 'database_error',
557 sprintf(
558 __('<strong>There was an error when trying to update the database for connected accounts:</strong><br><br><code>%s</code><br>', 'instagram-feed'),
559 $wpdb->last_error
560 )
561 );
562 } else {
563 delete_option('sb_instagram_feed_notices');
564 $sb_instagram_posts_manager->remove_error('database_error');
565 }
566 } else {
567 // If ALTER TABLE failed, log the error.
568 $sb_instagram_posts_manager->add_error(
569 'database_error',
570 sprintf(
571 __('<strong>There was an error when trying to update the database for connected accounts:</strong><br><br><code>%s</code><br>', 'instagram-feed'),
572 $wpdb->last_error
573 )
574 );
575 }
576 }
577 }
578 }
579
580 /**
581 * Compares previous plugin version and updates database related
582 * items as needed
583 *
584 * @since 2.0
585 */
586 function sbi_check_for_db_updates()
587 {
588 $db_ver = get_option('sbi_db_version', 0);
589
590 if ((float)$db_ver < 1.2) {
591 $upload = wp_upload_dir();
592 $upload_dir = $upload['basedir'];
593 $upload_dir = trailingslashit($upload_dir) . SBI_UPLOADS_NAME;
594 if (!file_exists($upload_dir)) {
595 $created = wp_mkdir_p($upload_dir);
596 }
597
598 sbi_create_database_table();
599
600 global $wp_roles;
601 $wp_roles->add_cap('administrator', 'manage_instagram_feed_options');
602
603 // Delete all transients.
604 global $wpdb;
605 $table_name = $wpdb->prefix . "options";
606 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_sbi\_%')");
607 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')");
608 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')");
609 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')");
610 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')");
611 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')");
612
613 $sbi_statuses_option = get_option('sbi_statuses', array());
614
615 if (!isset($sbi_statuses_option['first_install'])) {
616 $options_set = get_option('sb_instagram_settings', false);
617
618 if ($options_set) {
619 $sbi_statuses_option['first_install'] = 'from_update';
620 } else {
621 $sbi_statuses_option['first_install'] = time();
622 }
623
624 $sbi_rating_notice_option = get_option('sbi_rating_notice', false);
625
626 if ($sbi_rating_notice_option === 'dismissed') {
627 $sbi_statuses_option['rating_notice_dismissed'] = time();
628 }
629
630 $sbi_rating_notice_waiting = get_transient('instagram_feed_rating_notice_waiting');
631
632 if (
633 $sbi_rating_notice_waiting === false
634 && $sbi_rating_notice_option === false
635 ) {
636 $time = 2 * WEEK_IN_SECONDS;
637 set_transient('instagram_feed_rating_notice_waiting', 'waiting', $time);
638 update_option('sbi_rating_notice', 'pending', false);
639 }
640
641 update_option('sbi_statuses', $sbi_statuses_option, false);
642 }
643
644 update_option('sbi_db_version', SBI_DBVERSION);
645 }
646
647 if ((float)$db_ver < 1.3) {
648 // removed code that was giving a one week waiting period before notice appeared.
649
650 update_option('sbi_db_version', SBI_DBVERSION);
651 }
652
653 if ((float)$db_ver < 1.4) {
654 if (!wp_next_scheduled('sb_instagram_twicedaily')) {
655 wp_schedule_event(time(), 'twicedaily', 'sb_instagram_twicedaily');
656 }
657
658 update_option('sbi_db_version', SBI_DBVERSION);
659 }
660
661 if ((float)$db_ver < 1.5) {
662 if (!wp_next_scheduled('sb_instagram_feed_issue_email')) {
663 $timestamp = strtotime('next monday');
664 $timestamp = $timestamp + (3600 * 24 * 7);
665 $six_am_local = $timestamp + sbi_get_utc_offset() + (6 * 60 * 60);
666
667 wp_schedule_event($six_am_local, 'sbiweekly', 'sb_instagram_feed_issue_email');
668 }
669
670 delete_option('sb_instagram_errors');
671
672
673 update_option('sbi_db_version', SBI_DBVERSION);
674 }
675
676 if ((float)$db_ver < 1.6) {
677 if (!wp_next_scheduled('sbi_notification_update')) {
678 $timestamp = strtotime('next monday');
679 $timestamp = $timestamp + (3600 * 24 * 7);
680 $six_am_local = $timestamp + sbi_get_utc_offset() + (6 * 60 * 60);
681
682 wp_schedule_event($six_am_local, 'sbiweekly', 'sbi_notification_update');
683 }
684
685 update_option('sbi_db_version', SBI_DBVERSION);
686 }
687
688 if ((float)$db_ver < 1.7) {
689 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-gdpr-integrations.php';
690 $sbi_options = get_option('sb_instagram_settings', array());
691 $disable_resizing = isset($sbi_options['sb_instagram_disable_resize']) ? $sbi_options['sb_instagram_disable_resize'] === 'on' || $sbi_options['sb_instagram_disable_resize'] === true : false;
692
693 $sbi_statuses_option = get_option('sbi_statuses', array());
694
695 if ($disable_resizing || !SB_Instagram_GDPR_Integrations::gdpr_tests_successful(true)) {
696 $sbi_statuses_option['gdpr']['from_update_success'] = false;
697 } else {
698 $sbi_statuses_option['gdpr']['from_update_success'] = true;
699 }
700
701 update_option('sbi_statuses', $sbi_statuses_option);
702
703 update_option('sbi_db_version', SBI_DBVERSION);
704 }
705
706 if ((float)$db_ver < 1.8) {
707 $sbi_statuses_option = get_option('sbi_statuses', array());
708
709 if (empty($sbi_statuses_option['database']['hashtag_column'])) {
710 global $wpdb;
711
712 $table_name = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
713 $wpdb->query("ALTER TABLE $table_name ADD hashtag VARCHAR(1000) NOT NULL;");
714
715 $wpdb->query("ALTER TABLE $table_name ADD INDEX hashtag (hashtag(100))");
716
717 $sbi_statuses_option['database']['hashtag_column'] = true;
718 update_option('sbi_statuses', $sbi_statuses_option);
719 }
720
721 update_option('sbi_db_version', SBI_DBVERSION);
722 }
723
724 if ((float)$db_ver < 1.9) {
725 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-posts-manager.php';
726 include_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-feed-locator.php';
727
728 SB_Instagram_Feed_Locator::create_table();
729
730 update_option('sbi_db_version', SBI_DBVERSION);
731 }
732
733 if ((float)$db_ver < 1.91) {
734 $manager = new SB_Instagram_Data_Manager();
735 $manager->update_db_for_dpa();
736
737 update_option('sbi_db_version', SBI_DBVERSION);
738 }
739
740 /**
741 * for 4.0 update
742 */
743 if ((float)$db_ver < 2.0) {
744 $sbi_statuses_option = get_option('sbi_statuses', array());
745 $options = get_option('sb_instagram_settings', array());
746 $db = sbi_get_database_settings();
747
748 $connected_accounts = isset($options['connected_accounts']) ? $options['connected_accounts'] : array();
749
750 SBI_Db::create_tables();
751 update_option('sbi_db_version', SBI_DBVERSION);
752
753 $options_support_legacy = false;
754 if (!empty($connected_accounts)) {
755 $sbi_statuses_option['legacy_source_queue'] = SBI_Source::set_legacy_source_queue();
756
757 $sbi_statuses_option['legacy_source_queue'] = SBI_Source::batch_process_legacy_source_queue();
758 $options_support_legacy = true;
759
760 /** Caching Type */
761 if (!empty($db['sbi_caching_type']) && $db['sbi_caching_type'] === 'page') {
762 if (!empty($db['sb_instagram_cache_time_unit']) && $db['sb_instagram_cache_time_unit'] === 'minutes') {
763 if ((int)$db['sb_instagram_cache_time'] < 30) {
764 $db['legacy_page_cache'] = max((int)$db['sb_instagram_cache_time'], 1);
765 }
766
767 $db['sbi_cache_cron_interval'] = '30mins';
768
769 update_option('sb_instagram_settings', $db);
770 }
771 include_once trailingslashit(plugin_dir_path(__FILE__)) . 'inc/class-sb-instagram-cron-updater.php';
772 SB_Instagram_Cron_Updater::start_cron_job($db['sbi_cache_cron_interval'], $db['sbi_cache_cron_time'], $db['sbi_cache_cron_am_pm']);
773 }
774 /** End Caching Type */
775
776 if (sbi_is_pro_version()) {
777 $base_settings = SB_Instagram_Settings_Pro::legacy_shortcode_atts(array(), $db);
778 } else {
779 $base_settings = SB_Instagram_Settings::legacy_shortcode_atts(array(), $db);
780 }
781
782 update_option('sbi_legacy_feed_settings', sbi_json_encode($base_settings), false);
783 }
784
785 // how many legacy feeds?
786 $args = array(
787 'html_location' => array('header', 'footer', 'sidebar', 'content', 'unknown'),
788 'group_by' => 'shortcode_atts',
789 'page' => 1
790 );
791 $feeds_data = SB_Instagram_Feed_Locator::legacy_instagram_feed_locator_query($args);
792 $num_legacy = count($feeds_data);
793
794 $sbi_statuses_option['support_legacy_shortcode'] = $options_support_legacy;
795
796 if ($num_legacy > 0) {
797 if ($num_legacy > 1) {
798 $sbi_statuses_option['legacy_onboarding'] = array(
799 'active' => true,
800 'type' => 'multiple'
801 );
802 $sbi_statuses_option['support_legacy_shortcode'] = true;
803 } else {
804 $sbi_statuses_option['legacy_onboarding'] = array(
805 'active' => true,
806 'type' => 'single'
807 );
808
809 $shortcode_atts = !empty($feeds_data[0]) && $feeds_data[0]['shortcode_atts'] != '[""]' ? json_decode($feeds_data[0]['shortcode_atts'], true) : [];
810 $shortcode_atts = is_array($shortcode_atts) ? $shortcode_atts : array();
811
812 $sbi_statuses_option['support_legacy_shortcode'] = $shortcode_atts;
813
814 $shortcode_atts['from_update'] = true;
815
816 $db = sbi_get_database_settings();
817 if (sbi_is_pro_version()) {
818 $base_settings = SB_Instagram_Settings_Pro::legacy_shortcode_atts($shortcode_atts, $db);
819 } else {
820 $base_settings = SB_Instagram_Settings::legacy_shortcode_atts($shortcode_atts, $db);
821 }
822
823 $feed_saver = new SBI_Feed_Saver(false);
824 $feed_saver->set_data($base_settings);
825 $base_settings['type'] = 'user';
826 if ($base_settings['type'] === 'hashtag') {
827 $feed_name = str_replace(',', ' ', $base_settings['hashtag']);
828 } else {
829 if ($base_settings['type'] === 'user') {
830 if (!empty($base_settings['id'])) {
831 $base_settings['user'] = array();
832 foreach ($base_settings['id'] as $id) {
833 if (!empty($connected_accounts[$id])) {
834 $base_settings['user'][] = $connected_accounts[$id]['username'];
835 }
836 }
837 }
838 } elseif ($base_settings['type'] === 'tagged') {
839 if (!empty($base_settings['tagged'])) {
840 $base_settings['user'] = array();
841 foreach ($base_settings['tagged'] as $id) {
842 if (!empty($connected_accounts[$id])) {
843 $base_settings['user'][] = $connected_accounts[$id]['username'];
844 }
845 }
846 }
847 }
848
849 $feed_name = 'My Feed';
850 if (!empty($base_settings['user'])) {
851 $feed_name = implode(', ', $base_settings['user']);
852 $feed_name = trim($feed_name);
853 }
854 }
855
856 $feed_saver->set_feed_name($feed_name);
857
858 $new_feed_id = $feed_saver->update_or_insert();
859
860 $args = array(
861 'new_feed_id' => $new_feed_id,
862 'legacy_feed_id' => $feeds_data[0]['feed_id'],
863 );
864
865 SB_Instagram_Feed_Locator::update_legacy_to_builder($args);
866 }
867 } elseif ($num_legacy === 0 && $options_support_legacy) {
868 $sbi_statuses_option['support_legacy_shortcode'] = true;
869 }
870
871 if (!wp_next_scheduled('sbi_feed_update')) {
872 wp_schedule_event(time() + 60, 'twicedaily', 'sbi_feed_update');
873 }
874
875 update_option('sbi_statuses', $sbi_statuses_option, true);
876 }
877
878 if (version_compare($db_ver, '2.1', '<')) {
879 SBI_Db::create_tables();
880 $sbi_statuses_option = get_option('sbi_statuses', array());
881 $sbi_statuses_option['wizard_dismissed'] = false;
882 update_option('sbi_statuses', $sbi_statuses_option);
883 update_option('sbi_db_version', SBI_DBVERSION);
884 }
885
886 if (version_compare($db_ver, '2.2', '<')) {
887 $sbi_statuses_option = get_option('sbi_statuses', array());
888 if (!isset($sbi_statuses_option['wizard_dismissed'])) {
889 $sbi_statuses_option['wizard_dismissed'] = true;
890 update_option('sbi_statuses', $sbi_statuses_option);
891 }
892 update_option('sbi_db_version', SBI_DBVERSION);
893 }
894
895 if (version_compare($db_ver, '2.3', '<')) {
896 $sbi_statuses = get_option('sbi_statuses', array());
897
898 if (empty($sbi_statuses['database']['mime_type_column'])) {
899 global $wpdb;
900
901 $table_name = esc_sql($wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE);
902 $column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_name LIKE 'mime_type'");
903 if (empty($column_exists)) {
904 $wpdb->query("ALTER TABLE $table_name ADD COLUMN mime_type VARCHAR(100) DEFAULT '' NOT NULL");
905 }
906
907 $sbi_statuses = is_array($sbi_statuses) ? $sbi_statuses : array();
908 $sbi_statuses['database'] = is_array($sbi_statuses['database']) ? $sbi_statuses['database'] : array();
909
910 $sbi_statuses['database']['mime_type_column'] = true;
911 update_option('sbi_statuses', $sbi_statuses);
912 }
913
914 update_option('sbi_db_version', SBI_DBVERSION);
915 }
916
917 if (version_compare($db_ver, '2.4', '<')) {
918 global $wpdb;
919 $sbi_statuses = get_option('sbi_statuses', array());
920 $sbi_statuses = is_array($sbi_statuses) ? $sbi_statuses : array();
921
922 if (empty($sbi_statuses['database']['connect_type_column'])) {
923 $table_name = esc_sql($wpdb->prefix . 'sbi_sources');
924 $column_exists = $wpdb->get_results("SHOW COLUMNS FROM $table_name LIKE 'connect_type'");
925 if (empty($column_exists)) {
926 $wpdb->query("ALTER TABLE $table_name ADD COLUMN connect_type VARCHAR(100) DEFAULT '' NOT NULL");
927 $wpdb->query("
928 UPDATE $table_name
929 SET connect_type = CASE
930 WHEN account_type = 'business' THEN 'business_advanced'
931 ELSE 'personal'
932 END
933 ");
934 }
935
936 $sbi_statuses['database'] = is_array($sbi_statuses['database']) ? $sbi_statuses['database'] : array();
937 $sbi_statuses['database']['connect_type_column'] = true;
938 }
939
940 if (empty($sbi_statuses['source_details_update'])) {
941 $feeds_table_name = esc_sql($wpdb->prefix . 'sbi_feeds');
942 $feeds = $wpdb->get_results("SELECT * FROM $feeds_table_name");
943
944 if (!empty($feeds) && is_array($feeds)) {
945 foreach ($feeds as $feed) {
946 if (!isset($feed->id, $feed->feed_name, $feed->settings)) {
947 continue;
948 }
949
950 $feed_id = $feed->id;
951 $feed_name = $feed->feed_name;
952 $settings = json_decode($feed->settings, true);
953 $settings = is_array($settings) ? $settings : array();
954
955 if (empty($settings['id'])) {
956 continue;
957 }
958
959 $source_ids = $settings['id'];
960 $args = array('id' => $source_ids);
961 $source_query = SBI_Db::source_query($args);
962
963 $source_details = array();
964 if (!empty($source_query) && is_array($source_query)) {
965 foreach ($source_query as $source) {
966 if (isset($source['account_id'], $source['username'])) {
967 $source_details[] = array(
968 'id' => $source['account_id'],
969 'username' => $source['username']
970 );
971 }
972 }
973 }
974 $settings['feed_name'] = $feed_name;
975 $settings['source_details'] = $source_details;
976
977 $feed_saver = new SBI_Feed_Saver($feed_id);
978 $feed_saver->set_feed_name($feed_name);
979 $feed_saver->set_data($settings);
980 $feed_saver->update_or_insert();
981 }
982 }
983 $sbi_statuses['source_details_update'] = true;
984 }
985
986 update_option('sbi_statuses', $sbi_statuses);
987 update_option('sbi_db_version', SBI_DBVERSION);
988 }
989 }
990
991 add_action('wp_loaded', 'sbi_check_for_db_updates');
992
993 /**
994 * Keyed by cache version. Reasons are surfaced in the action log when a clear fires.
995 */
996 function sbi_cache_invalidation_registry()
997 {
998 return apply_filters('sbi_cache_invalidation_registry', array(
999 '1' => 'SMASH-1105: trial-reel filter needs fresh is_shared_to_feed field',
1000 ));
1001 }
1002
1003 /**
1004 * Auto-clears feed caches on upgrade. Hooked to wp_loaded; short-circuits on version match.
1005 */
1006 function sbi_check_for_cache_invalidations()
1007 {
1008 $stored_version = get_option('sbi_cache_version', null);
1009
1010 // Null = fresh install OR pre-this-release upgrade. Probe the cache table to disambiguate.
1011 if ($stored_version === null) {
1012 global $wpdb;
1013 $cache_table = $wpdb->prefix . 'sbi_feed_caches';
1014 $has_any_cache = (bool) $wpdb->get_var("SELECT 1 FROM $cache_table LIMIT 1");
1015
1016 if (!$has_any_cache) {
1017 update_option('sbi_cache_version', SBI_CACHE_VERSION);
1018 return;
1019 }
1020
1021 $stored_version = '0';
1022 }
1023
1024 if (version_compare((string) $stored_version, SBI_CACHE_VERSION, '>=')) {
1025 return;
1026 }
1027
1028 if (!apply_filters('sbi_auto_clear_cache_on_upgrade', true, (string) $stored_version, SBI_CACHE_VERSION)) {
1029 update_option('sbi_cache_version', SBI_CACHE_VERSION);
1030 return;
1031 }
1032
1033 // Concurrent-request guard.
1034 if (get_transient('sbi_cache_invalidation_lock')) {
1035 return;
1036 }
1037 set_transient('sbi_cache_invalidation_lock', time(), 60);
1038
1039 // Bump before clear so a mid-flight fatal doesn't loop on every page load.
1040 update_option('sbi_cache_version', SBI_CACHE_VERSION);
1041
1042 sbi_clear_all_feed_caches();
1043
1044 global $sb_instagram_posts_manager;
1045 if (isset($sb_instagram_posts_manager) && method_exists($sb_instagram_posts_manager, 'add_action_log')) {
1046 $registry = sbi_cache_invalidation_registry();
1047 $reasons = array();
1048 if (is_array($registry)) {
1049 foreach ($registry as $ver => $reason) {
1050 if (version_compare((string) $stored_version, (string) $ver, '<')) {
1051 $reasons[] = $ver . ': ' . $reason;
1052 }
1053 }
1054 }
1055 $sb_instagram_posts_manager->add_action_log(
1056 'Auto-cleared caches on upgrade (' . $stored_version . '' . SBI_CACHE_VERSION . '). '
1057 . implode(' | ', $reasons)
1058 );
1059 }
1060
1061 delete_transient('sbi_cache_invalidation_lock');
1062 }
1063 add_action('wp_loaded', 'sbi_check_for_cache_invalidations');
1064
1065 /**
1066 * Deletes saved data for the plugin unless setting to preserve
1067 * settings is enabled
1068 *
1069 * @since 2.0 custom tables, custom images, and image directory deleted
1070 * @since 1.0
1071 */
1072 function sb_instagram_uninstall()
1073 {
1074 if (!current_user_can('activate_plugins')) {
1075 return;
1076 }
1077
1078 $is_pro = !defined('SBI_PLUGIN_NAME') || SBI_PLUGIN_NAME !== 'Instagram Feed Free';
1079
1080 $installed_plugins = get_plugins();
1081
1082 $free_plugin_is_installed = isset($installed_plugins['instagram-feed/instagram-feed.php']);
1083 $pro_plugin_is_installed = isset($installed_plugins['instagram-feed-pro/instagram-feed.php']);
1084
1085 if (($is_pro && $free_plugin_is_installed) || (!$is_pro && $pro_plugin_is_installed)) {
1086 // Do nothing.
1087 return;
1088 }
1089
1090 // If the user is preserving the settings then don't delete them
1091 $options = get_option('sb_instagram_settings', array());
1092 $sb_instagram_preserve_settings = isset($options['sb_instagram_preserve_settings']) ? $options['sb_instagram_preserve_settings'] : false;
1093
1094 /*
1095 ALL platform Data */
1096 /* Backup Caches */
1097 global $wpdb;
1098 $table_name = $wpdb->prefix . "options";
1099
1100 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%!sbi\_%')");
1101 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')");
1102 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')");
1103
1104 /*
1105 Regular Caches */
1106 // Delete all transients.
1107 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_sbi\_%')");
1108 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_sbi\_%')");
1109 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')");
1110 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')");
1111 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')");
1112 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')");
1113
1114 delete_option('sbi_single_cache');
1115 delete_transient('sbinst_comment_cache');
1116 delete_option('sbi_oembed_token');
1117 // image resizing.
1118 $upload = wp_upload_dir();
1119 $posts_table_name = $wpdb->prefix . 'sbi_instagram_posts';
1120 $feeds_posts_table_name = esc_sql($wpdb->prefix . 'sbi_instagram_feeds_posts');
1121
1122 $image_files = glob(trailingslashit($upload['basedir']) . trailingslashit('sb-instagram-feed-images') . '*'); // get all file names.
1123 foreach ($image_files as $file) { // iterate files.
1124 if (is_file($file)) {
1125 unlink($file);
1126 } // delete file.
1127 }
1128
1129 global $wp_filesystem;
1130
1131 $wp_filesystem->delete(trailingslashit($upload['basedir']) . trailingslashit('sb-instagram-feed-images'), true);
1132 // Delete tables.
1133 $wpdb->query("DROP TABLE IF EXISTS $posts_table_name");
1134 $wpdb->query("DROP TABLE IF EXISTS $feeds_posts_table_name");
1135 $locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR;
1136 $wpdb->query("DROP TABLE IF EXISTS $locator_table_name");
1137
1138 $table_name = $wpdb->prefix . "options";
1139 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')");
1140 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')");
1141 delete_option('sbi_db_version');
1142
1143 $feed_caches_table_name = $wpdb->prefix . 'sbi_feed_caches';
1144 $wpdb->query("DROP TABLE IF EXISTS $feed_caches_table_name");
1145
1146 $sources_table_name = $wpdb->prefix . 'sbi_sources';
1147 $wpdb->query("DROP TABLE IF EXISTS $sources_table_name");
1148
1149 $table_name = $wpdb->prefix . "options";
1150 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_\$sbi\_%')");
1151 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_\$sbi\_%')");
1152 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%!sbi\_%')");
1153 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_&sbi\_%')");
1154 $wpdb->query("DELETE FROM $table_name WHERE `option_name` LIKE ('%\_transient\_timeout\_&sbi\_%')");
1155
1156 delete_option('sbi_hashtag_ids');
1157 delete_option('sbi_local_avatars');
1158 delete_option('sbi_local_avatars_info');
1159
1160 /* End Platform Data */
1161 if ($sb_instagram_preserve_settings) {
1162 return;
1163 }
1164
1165 // Delete tables.
1166 $wpdb->query("DROP TABLE IF EXISTS $posts_table_name");
1167 $wpdb->query("DROP TABLE IF EXISTS $feeds_posts_table_name");
1168 $locator_table_name = $wpdb->prefix . SBI_INSTAGRAM_FEED_LOCATOR;
1169 $wpdb->query("DROP TABLE IF EXISTS $locator_table_name");
1170
1171 $feeds_table_name = $wpdb->prefix . 'sbi_feeds';
1172 $wpdb->query("DROP TABLE IF EXISTS $feeds_table_name");
1173
1174 $table_name = esc_sql($wpdb->prefix . 'postmeta');
1175 $result = $wpdb->query("DELETE FROM $table_name WHERE meta_key = '_sbi_oembed_done_checking';");
1176
1177 $usermeta_table_name = $wpdb->prefix . 'usermeta';
1178 $result = $wpdb->query("DELETE FROM $usermeta_table_name WHERE meta_key LIKE ('sbi\_%')");
1179
1180 delete_option('sb_instagram_errors');
1181 delete_option('sbi_usage_tracking_config');
1182 delete_option('sbi_usage_tracking');
1183 delete_option('sbi_oembed_token');
1184 delete_option('sbi_top_api_calls');
1185 delete_option('sbi_rating_notice');
1186 delete_option('sbi_refresh_report');
1187 delete_option('sbi_welcome_seen');
1188 delete_option('sbi_notifications');
1189 delete_option('sbi_newuser_notifications');
1190 delete_option('sbi_statuses');
1191 delete_option('sb_instagram_settings');
1192 delete_option('sbi_ver');
1193 delete_option('sb_expired_tokens');
1194 delete_option('sbi_cron_report');
1195 delete_option('sb_instagram_ajax_status');
1196 delete_option('sbi_legacy_feed_settings');
1197 delete_option('sbi_check_license_api_when_expires');
1198 delete_option('sbi_license_last_check_timestamp');
1199 delete_option('sbi_license_data');
1200 delete_option('sbi_license_key');
1201 delete_option('sbi_license_status');
1202
1203 global $wp_roles;
1204 $wp_roles->remove_cap('administrator', 'manage_instagram_feed_options');
1205 wp_clear_scheduled_hook('sbi_feed_update');
1206 wp_clear_scheduled_hook('sbi_usage_tracking_cron');
1207
1208 delete_option('sb_instagram_feed_notices');
1209 delete_option('sb_instagram_feed_group_notices');
1210 }
1211
1212 register_uninstall_hook(__FILE__, 'sb_instagram_uninstall');
1213
1214 /**
1215 * Create database tables for sub-site if multisite.
1216 *
1217 * @param int $blog_id The ID of the new blog.
1218 * @param int $user_id The ID of the user who created the blog.
1219 * @param string $domain The domain of the new blog.
1220 * @param string $path The path of the new blog.
1221 * @param string $site_id The site ID of the new blog.
1222 * @param array $meta Additional meta data for the new blog.
1223 *
1224 * @since 2.0
1225 */
1226 function sbi_on_create_blog($blog_id, $user_id, $domain, $path, $site_id, $meta)
1227 {
1228 if (is_plugin_active_for_network('instagram-feed/instagram-feed.php')) {
1229 switch_to_blog($blog_id);
1230 sbi_create_database_table();
1231 restore_current_blog();
1232 }
1233 }
1234
1235 add_action('wpmu_new_blog', 'sbi_on_create_blog', 10, 6);
1236
1237 /**
1238 * Delete custom tables if not preserving settings
1239 *
1240 * @param array $tables Array of tables to delete.
1241 * @return array Updated array of tables to delete.
1242 * @since 2.0
1243 */
1244 function sbi_on_delete_blog($tables)
1245 {
1246 $options = get_option('sb_instagram_settings');
1247 $sb_instagram_preserve_settings = $options['sb_instagram_preserve_settings'];
1248 if ($sb_instagram_preserve_settings) {
1249 return;
1250 }
1251
1252 global $wpdb;
1253 $tables[] = $wpdb->prefix . SBI_INSTAGRAM_POSTS_TYPE;
1254 $tables[] = $wpdb->prefix . SBI_INSTAGRAM_FEEDS_POSTS;
1255
1256 return $tables;
1257 }
1258
1259 add_filter('wpmu_drop_tables', 'sbi_on_delete_blog');
1260
1261 /**
1262 * Load the plugin's translated strings.
1263 *
1264 * @return void
1265 */
1266 function sbi_text_domain()
1267 {
1268 load_plugin_textdomain('instagram-feed', false, basename(dirname(__FILE__)) . '/languages');
1269 }
1270
1271 add_action('init', 'sbi_text_domain');
1272
1273 /**
1274 * Refresh Instagram tokens for connected accounts.
1275 *
1276 * Retrieves expiring Instagram sources, converts them to connected accounts,
1277 * and attempts to refresh their tokens. Marks accounts as private if refresh fails.
1278 * Saves a report of the refresh attempts.
1279 *
1280 * @return void
1281 */
1282 function sbi_do_token_refreshes()
1283 {
1284 $basic_sources = SBI_Source::get_expiring();
1285
1286 $connected_accounts = SBI_Source::convert_sources_to_connected_accounts($basic_sources);
1287 if (is_array($connected_accounts) && !empty($connected_accounts)) {
1288 require_once trailingslashit(SBI_PLUGIN_DIR) . 'inc/class-sb-instagram-token-refresher.php';
1289
1290 $report = array(
1291 'notes' => array(
1292 'time_ran' => date('Y-m-d H:i:s')
1293 )
1294 );
1295 foreach ($connected_accounts as $connected_account) {
1296 $refresher = new SB_Instagram_Token_Refresher($connected_account);
1297 $refresher->attempt_token_refresh();
1298 if ($refresher->get_last_error_code() === 10) {
1299 sbi_update_connected_account($connected_account['user_id'], array('private' => true));
1300 }
1301
1302 $report[$connected_account['user_id']] = $refresher->get_report();
1303 }
1304
1305 update_option('sbi_refresh_report', $report, false);
1306 }
1307 }
1308
1309 add_action('sb_instagram_twicedaily', 'sbi_do_token_refreshes');
1310 }
1311
1312 /**
1313 * Retrieves the singleton instance of the SBI_Feed_Builder class.
1314 *
1315 * This function returns the singleton instance of the
1316 * InstagramFeed\Builder\SBI_Feed_Builder class, which is used to build
1317 * Instagram feeds.
1318 *
1319 * @return InstagramFeed\Builder\SBI_Feed_Builder The singleton instance of the SBI_Feed_Builder class.
1320 */
1321 function sbi_builder_free()
1322 {
1323 return InstagramFeed\Builder\SBI_Feed_Builder::instance();
1324 }
1325