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

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

428 lines 12.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Install class.
4 *
5 * @package WPZinc\Social
6 * @author WP Zinc
7 */
8
9 namespace WPZinc\Social;
10
11 /**
12 * Runs any steps required on plugin activation and upgrade.
13 *
14 * @package WPZinc\Social
15 * @author WP Zinc
16 * @version 3.2.5
17 */
18 class Install {
19
20 /**
21 * Holds the base class object.
22 *
23 * @since 3.2.5
24 *
25 * @var object
26 */
27 public $base;
28
29 /**
30 * Constructor
31 *
32 * @since 3.4.7
33 *
34 * @param object $base Base Plugin Class.
35 */
36 public function __construct( $base ) {
37
38 // Store base class.
39 $this->base = $base;
40
41 }
42
43 /**
44 * Runs installation routines for first time users
45 *
46 * @since 3.4.0
47 */
48 public function install() {
49
50 // Enable logging by default.
51 $this->base->get_class( 'settings' )->update_option(
52 'log',
53 array(
54 'enabled' => 1,
55 'display_on_posts' => 1,
56 'preserve_days' => 30,
57 'log_level' => array(
58 'success',
59 'test',
60 'pending',
61 'warning',
62 'error',
63 ),
64 )
65 );
66
67 // Create logging database table.
68 $this->base->get_class( 'log' )->activate();
69
70 // Reschedule the cron events.
71 $this->base->get_class( 'cron' )->schedule_log_cleanup_event();
72 $this->base->get_class( 'cron' )->schedule_media_cleanup_event();
73
74 // Unschedule cron events we no longer use.
75 $this->base->get_class( 'cron' )->unschedule_refresh_token_event();
76
77 // Bail if settings already exist.
78 $settings = $this->base->get_class( 'settings' )->get_settings( 'post' );
79 if ( $settings !== false ) {
80 return;
81 }
82
83 // Get default installation settings.
84 $settings = $this->base->get_class( 'settings' )->default_installation_settings( 'post' );
85 $this->base->get_class( 'settings' )->update_settings( 'post', $settings );
86
87 }
88
89 /**
90 * Runs migrations whenever the Plugin's version is updated.
91 *
92 * @since 3.2.5
93 */
94 public function upgrade() {
95
96 // These sit outside of version checks, to ensure they run regardless of version.
97 // Otherwise, Free to Free Plugin updates for the multi account result in losing
98 // account data because there's also an API version switch.
99 // At a later relase, we'll need to remove these so they don't run on every upgrade.
100
101 // Migrate Access Tokens to multi account settings.
102 $this->migrate_access_tokens_to_new_multi_account_settings();
103
104 // Migrate Status Settings to new format that supports "Type"
105 // instead of a numerical setting for the status' index.
106 $this->migrate_status_settings_to_new_format();
107
108 // Get current installed version number.
109 // false | 1.1.7.
110 $installed_version = get_option( $this->base->plugin->name . '-version' );
111
112 // If the version number matches the plugin version, bail.
113 if ( $installed_version === $this->base->plugin->version ) {
114 return;
115 }
116
117 // Reschedule the cron events.
118 $this->base->get_class( 'cron' )->reschedule_log_cleanup_event();
119 $this->base->get_class( 'cron' )->reschedule_media_cleanup_event();
120
121 // Unschedule cron events we no longer use.
122 $this->base->get_class( 'cron' )->unschedule_refresh_token_event();
123
124 // Create log table if it doesn't exist.
125 $this->base->get_class( 'log' )->activate();
126
127 // Update the version number.
128 update_option( $this->base->plugin->name . '-version', $this->base->plugin->version );
129
130 }
131
132 /**
133 * Migrates the access token, refresh token and token expiry to the new multi account settings.
134 *
135 * @since 6.0.0
136 *
137 * @return void
138 */
139 private function migrate_access_tokens_to_new_multi_account_settings() {
140
141 // Check if the non-multi account settings exist.
142 $access_token = get_option( $this->base->plugin->settingsName . '-access-token' );
143 $refresh_token = get_option( $this->base->plugin->settingsName . '-refresh-token' );
144 $token_expires = get_option( $this->base->plugin->settingsName . '-token-expires' );
145
146 // Bail if no access token exists - either the Plugin isn't connected, or it has
147 // already been migrated to the new multi account settings.
148 if ( empty( $access_token ) ) {
149 return;
150 }
151
152 // Store tokens in new multi account settings.
153 // This will be stored under the ID 'default'.
154 $this->base->get_class( 'settings' )->update_account(
155 $access_token,
156 $refresh_token,
157 $token_expires
158 );
159
160 // Delete old settings.
161 delete_option( $this->base->plugin->settingsName . '-access-token' );
162 delete_option( $this->base->plugin->settingsName . '-refresh-token' );
163 delete_option( $this->base->plugin->settingsName . '-token-expires' );
164
165 }
166
167 /**
168 * Migrates Status Settings to the new format that supports
169 * a "Type" selection dropdown.
170 *
171 * @since 6.0.0
172 *
173 * @return void
174 */
175 private function migrate_status_settings_to_new_format() {
176
177 // Define option flags.
178 $migrated_status_settings_flag = $this->base->plugin->name . '-migrate-status-settings-completed';
179
180 // Bail if the migration has already run.
181 if ( get_option( $migrated_status_settings_flag ) ) {
182 return;
183 }
184
185 // Get accounts.
186 $accounts = $this->base->get_class( 'settings' )->get_accounts();
187
188 // Bail if no accounts exist.
189 if ( empty( $accounts ) ) {
190 return;
191 }
192
193 // Build array of all profiles across all accounts connected to the Plugin.
194 $profiles = array();
195 foreach ( $accounts as $account_id => $account ) {
196 $account_profiles = get_transient( $this->base->plugin->name . '_' . strtolower( $this->base->plugin->account ) . '_api_profiles_' . $account_id );
197 if ( ! $account_profiles ) {
198 continue;
199 }
200 $profiles = array_merge( $profiles, $account_profiles );
201 }
202
203 // If no profiles exist, bail.
204 if ( empty( $profiles ) ) {
205 return;
206 }
207
208 // Fetch actions (publish, update, repost, bulk publish).
209 $actions = $this->base->get_class( 'common' )->get_post_actions();
210
211 // Fetch all Post Type settings.
212 $post_types = $this->base->get_class( 'common' )->get_post_types();
213
214 // Iterate through Post Types, migrating their Status Settings.
215 foreach ( $post_types as $post_type ) {
216 // Get Post Type Settings.
217 $settings = $this->base->get_class( 'settings' )->get_settings( $post_type->name );
218
219 // Skip if not an array.
220 if ( ! is_array( $settings ) ) {
221 continue;
222 }
223
224 // Migrate.
225 $settings = $this->migrate_status_settings( $settings, $actions, $profiles );
226
227 // Save settings for this Post Type.
228 $this->base->get_class( 'settings' )->update_settings( $post_type->name, $settings );
229 }
230
231 // Mark the migration as completed.
232 update_option( $migrated_status_settings_flag, time(), false );
233
234 }
235
236 /**
237 * Migrates status settings to the new format that supports
238 * a "Type" selection dropdown.
239 *
240 * @since 6.0.0
241 *
242 * @param array $settings Post Type or individual Post Settings.
243 * @param array $actions Actions.
244 * @param array $profiles Profiles.
245 * @return array Migrated Settings.
246 */
247 public function migrate_status_settings( $settings, $actions, $profiles ) {
248
249 // Iterate through settings.
250 foreach ( $settings as $profile_id => $profile ) {
251 // Skip if profile isn't an array.
252 if ( ! is_array( $profile ) ) {
253 continue;
254 }
255
256 // Iterate through actions.
257 foreach ( $actions as $action => $action_label ) {
258 // Skip if the action isn't an array.
259 if ( ! array_key_exists( $action, $profile ) || ! is_array( $profile[ $action ] ) ) {
260 continue;
261 }
262
263 // Iterate through statuses.
264 foreach ( $profile[ $action ]['status'] as $status_index => $status ) {
265 // Skip if a post_type already exists.
266 if ( array_key_exists( 'post_type', $status ) ) {
267 continue;
268 }
269
270 // Status Type.
271 switch ( (string) $status['image'] ) {
272 // No Image.
273 case '-1':
274 $status['post_type'] = 'text';
275 $status['image'] = '';
276 break;
277
278 // Use Feat. Image, Linked to Post.
279 case '1':
280 $status['post_type'] = 'image';
281 $status['image'] = 'featured_image';
282 break;
283
284 // Use Feat. Image, not Linked to Post.
285 case '2':
286 $status['post_type'] = 'image';
287 $status['image'] = 'featured_image';
288 break;
289
290 // Use Text to Image, Linked to Post.
291 case '3':
292 $status['post_type'] = 'image';
293 $status['image'] = 'text_to_image';
294 break;
295
296 // Use Text to Image, not Linked to Post.
297 case '4':
298 $status['post_type'] = 'image';
299 $status['image'] = 'text_to_image';
300 break;
301
302 // OpenGraph / Link Preview.
303 case '0':
304 case '':
305 default:
306 if ( array_key_exists( 'link', $this->base->get_class( 'common' )->get_status_post_type_options() ) ) {
307 $status['post_type'] = 'link';
308 $status['image'] = '';
309
310 // Move the {url} or {url_short} from the message to the URL setting.
311 if ( strpos( $status['message'], '{url}' ) !== false ) {
312 $status['message'] = str_replace( '{url}', '', $status['message'] );
313 $status['url'] = '{url}';
314 } elseif ( strpos( $status['message'], '{url_short}' ) !== false ) {
315 $status['message'] = str_replace( '{url_short}', '', $status['message'] );
316 $status['url'] = '{url_short}';
317 } else {
318 // Status is OpenGraph but no URL included.
319 // Set the URL to the Post's URL.
320 $status['url'] = '{url}';
321 }
322 } else {
323 $status['post_type'] = 'text';
324 $status['image'] = '';
325 }
326 break;
327 }
328
329 // Schedule.
330 switch ( $status['schedule'] ) {
331 case 'queue_bottom':
332 $status['schedule'] = 'queue_end';
333 break;
334
335 case 'queue_top':
336 $status['schedule'] = 'queue_start';
337 break;
338
339 case 'now':
340 $status['schedule'] = 'immediate';
341 break;
342 }
343
344 // Adjust image_additional setting.
345 if ( array_key_exists( 'image_additional', $status ) ) {
346 switch ( $status['image_additional'] ) {
347 /**
348 * Blank means "Specified in Post settings" < 6.0.0.
349 * 6.0.0 sets blank as 'None'.
350 */
351 case '':
352 $status['image_additional'] = 'post_settings';
353 break;
354
355 /**
356 * 1 means "Auto populate from Post content" < 6.0.0.
357 */
358 case '1':
359 $status['image_additional'] = 'post_content';
360 break;
361 }
362 }
363
364 // Depending on the Profile Service, the Type may need to be adjusted.
365 // Don't do this if the profile_id = default.
366 foreach ( $profiles as $api_profile ) {
367 if ( $api_profile['id'] !== (string) $profile_id ) {
368 continue;
369 }
370
371 switch ( $api_profile['service'] ) {
372 case 'instagram':
373 $status['post_type'] = $status['update_type'] === 'story' ? 'story' : 'image';
374 break;
375
376 case 'pinterest':
377 $status['post_type'] = 'pin';
378 $status['url'] = array_key_exists( 'source_url', $status ) ? $status['source_url'] : '{url}';
379 if ( ! array_key_exists( 'pinterest', $status ) ) {
380 $status['pinterest'] = array();
381 }
382 if ( ! is_array( $status['pinterest'] ) ) {
383 $status['pinterest'] = array();
384 }
385 $status['pinterest']['board'] = array_key_exists( 'sub_profile', $status ) ? $status['sub_profile'] : '';
386 $status['pinterest']['title'] = array_key_exists( 'title', $status ) ? $status['title'] : '{title}';
387 break;
388
389 case 'googlebusiness':
390 $status['post_type'] = 'googlebusiness';
391 $status['url'] = '{url}';
392 break;
393 }
394 break;
395 }
396
397 // Remove unused status settings.
398 // update_type: Instagram Story/Post, which is now handled by the post_type setting.
399 // title: Pinterest Title, which is now handled by the pinterest array.
400 // source_url: Pinterest Source URL, which is now handled by the url setting.
401 unset( $status['update_type'], $status['title'], $status['source_url'], $status['sub_profile'] );
402
403 // Assign status back to settings.
404 $settings[ $profile_id ][ $action ]['status'][ $status_index ] = $status;
405 }
406 }
407 }
408
409 return $settings;
410
411 }
412
413 /**
414 * Runs uninstallation routines
415 *
416 * @since 3.7.2
417 */
418 public function uninstall() {
419
420 // Unschedule any CRON events.
421 $this->base->get_class( 'cron' )->unschedule_log_cleanup_event();
422 $this->base->get_class( 'cron' )->unschedule_media_cleanup_event();
423 $this->base->get_class( 'cron' )->unschedule_refresh_token_event();
424
425 }
426
427 }
428