PluginProbe
Social Media Auto Poster – Schedule & Publish to Buffer / 3.8.1
Social Media Auto Poster – Schedule & Publish to Buffer v3.8.1
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 / vendor / includes / admin / admin.php

admin.php in Social Media Auto Poster – Schedule & Publish to Buffer 3.8.1, at vendor/includes/admin/admin.php

854 lines 33.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Administration class
4 *
5 * @package WP_To_Social_Pro
6 * @author Tim Carr
7 * @version 3.0.0
8 */
9 class WP_To_Social_Pro_Admin {
10
11 /**
12 * Holds the base class object.
13 *
14 * @since 3.2.0
15 *
16 * @var object
17 */
18 public $base;
19
20 /**
21 * Holds the success and error messages
22 *
23 * @since 3.2.6
24 *
25 * @var array
26 */
27 public $notices = array(
28 'success' => array(),
29 'error' => array(),
30 );
31
32 /**
33 * Constructor
34 *
35 * @since 3.0.0
36 *
37 * @param object $base Base Plugin Class
38 */
39 public function __construct( $base ) {
40
41 // Store base class
42 $this->base = $base;
43
44 // Actions
45 add_action( 'init', array( $this, 'oauth' ) );
46 add_action( 'init', array( $this, 'check_plugin_setup' ) );
47 add_action( 'admin_notices', array( $this, 'admin_notices' ) );
48 add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts_css' ) );
49 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
50 add_action( 'plugins_loaded', array( $this, 'load_language_files' ) );
51
52 }
53
54 /**
55 * Stores the access token if supplied, showing a success message
56 * Displays any errors from the oAuth process
57 *
58 * @since 3.3.3
59 */
60 public function oauth() {
61
62 // Setup notices class
63 $this->base->get_class( 'notices' )->set_key_prefix( $this->base->plugin->filter_name . '_' . wp_get_current_user()->ID );
64
65 /**
66 * Perform any pre-oAuth actions now, such as starting the oAuth process
67 *
68 * @since 4.2.0
69 */
70 do_action( $this->base->plugin->filter_name . '_save_settings_auth' );
71
72 // If we've returned from the oAuth process and an error occured, add it to the notices
73 if ( isset( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-error' ] ) ) {
74 switch( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-error' ] ) {
75 /**
76 * Access Denied
77 * - User denied our app access
78 */
79 case 'access_denied':
80 $this->base->get_class( 'notices' )->add_error_notice(
81 sprintf(
82 /* translators: %1$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot), %2$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot) */
83 __( 'You did not grant our Plugin access to your %1$s account. We are unable to post to %2$s until you do this. Please click on the Authorize Plugin button.', 'wp-to-social-pro' ),
84 $this->base->plugin->account,
85 $this->base->plugin->account
86 )
87 );
88 break;
89
90 /**
91 * Invalid Grant
92 * - A parameter sent by the oAuth gateway is wrong
93 */
94 case 'invalid_grant':
95 $this->base->get_class( 'notices' )->add_error_notice(
96 sprintf(
97 /* translators: %1$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot), %2$s: Support URL */
98 __( 'We were unable to complete authentication with %1$s. Please try again, or <a href="%2$s" target="_blank">contact us for support</a>.', 'wp-to-social-pro' ),
99 $this->base->plugin->account,
100 $this->base->plugin->support_url
101 )
102 );
103 break;
104
105 /**
106 * Expired Token
107 * - The oAuth gateway did not exchange the code for an access token within 30 seconds
108 */
109 case 'expired_token':
110 $this->base->get_class( 'notices' )->add_error_notice(
111 sprintf(
112 /* translators: Support URL */
113 __( 'The oAuth process has expired. Please try again, or <a href="%s" target="_blank">contact us for support</a> if this issue persists.', 'wp-to-social-pro' ),
114 $this->base->plugin->support_url
115 )
116 );
117 break;
118
119 /**
120 * Other Error
121 */
122 default:
123 $this->base->get_class( 'notices' )->add_error_notice(
124 esc_html( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-error' ] )
125 );
126 break;
127 }
128 }
129
130 // If an Access Token is included in the request, store it and show a success message
131 if ( isset( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-access-token' ] ) ) {
132 // Define expiry
133 $expiry = sanitize_text_field( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-expires' ] );
134 if ( $expiry > 0 ) {
135 $expiry = strtotime( '+' . sanitize_text_field( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-expires' ] ) . ' seconds' );
136 }
137 // Setup API
138 $this->base->get_class( 'api' )->set_tokens(
139 sanitize_text_field( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-access-token' ] ),
140 sanitize_text_field( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-refresh-token' ] ),
141 $expiry
142 );
143
144 // Fetch Profiles
145 $profiles = $this->base->get_class( 'api' )->profiles( true, $this->base->get_class( 'common' )->get_transient_expiration_time() );
146
147 // If something went wrong, show an error
148 if ( is_wp_error( $profiles ) ) {
149 $this->base->get_class( 'notices' )->add_error_notice( $profiles->get_error_message() );
150 return;
151 }
152
153 // Test worked! Save Tokens and Expiry
154 $this->base->get_class( 'settings' )->update_tokens(
155 sanitize_text_field( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-access-token' ] ),
156 sanitize_text_field( $_REQUEST[ $this->base->plugin->settingsName . '-oauth-refresh-token' ] ),
157 $expiry
158 );
159
160 // Store success message
161 $this->base->get_class( 'notices' )->enable_store();
162 $this->base->get_class( 'notices' )->add_success_notice(
163 sprintf(
164 /* translators: %1$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot) */
165 __( 'Thanks! You\'ve connected our Plugin to %1$s.', 'wp-to-social-pro' ),
166 $this->base->plugin->account
167 )
168 );
169
170 // Redirect to Post tab
171 wp_redirect( 'admin.php?page=' . $this->base->plugin->name . '-settings&tab=post&type=post' );
172 die();
173 }
174
175 }
176
177 /**
178 * Checks that the oAuth authorization flow has been completed, and that
179 * at least one Post Type with one Social Media account has been enabled.
180 *
181 * Displays a dismissible WordPress notification if this has not been done.
182 *
183 * @since 1.0.0
184 */
185 public function check_plugin_setup() {
186
187 // Show an error if cURL hasn't been installed
188 if ( ! function_exists( 'curl_init' ) ) {
189 $this->base->get_class( 'notices' )->add_error_notice(
190 sprintf(
191 /* translators: Plugin Name */
192 __( '%s requires the PHP cURL extension to be installed and enabled by your web host.', 'wp-to-social-pro' ),
193 $this->base->plugin->displayName
194 )
195 );
196 }
197
198 // Check the API is connected
199 if ( ! $this->base->get_class( 'validation' )->api_connected() ) {
200 // Don't display the notice if this request is for the settings auth screen
201 $screen = $this->base->get_class( 'screen' )->get_current_screen();
202 if ( $screen['screen'] == 'settings' && $screen['section'] == 'auth' ) {
203 return;
204 }
205
206 // Display the notice
207 $this->base->get_class( 'notices' )->add_error_notice(
208 sprintf(
209 /*
210 * translators:
211 * %1$s: Plugin Name
212 * %2$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot)
213 * %3$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot)
214 * %4$s: URL to Authorize Plugin Screen
215 * %5$s: URL to Register Account with Service
216 */
217 __( '%1$s needs to be authorized with %2$s before you can start sending Posts to %3$s. <a href="%4$s">Click here to Authorize.</a>', 'wp-to-social-pro' ),
218 $this->base->plugin->displayName,
219 $this->base->plugin->account,
220 $this->base->plugin->account,
221 admin_url( 'admin.php?page=' . $this->base->plugin->name . '-settings' )
222 )
223 );
224 }
225
226 }
227
228 /**
229 * Checks the transient to see if any admin notices need to be output now.
230 *
231 * @since 3.9.6
232 */
233 public function admin_notices() {
234
235 // Output notices
236 $this->base->get_class( 'notices' )->set_key_prefix( $this->base->plugin->filter_name . '_' . wp_get_current_user()->ID );
237 $this->base->get_class( 'notices' )->output_notices();
238
239 }
240
241 /**
242 * Register and enqueue any JS and CSS for the WordPress Administration
243 *
244 * @since 1.0.0
245 */
246 public function admin_scripts_css() {
247
248 global $id, $post;
249
250 // Get current screen
251 $screen = $this->base->get_class( 'screen' )->get_current_screen();
252
253 // CSS - always load
254 // Menu Icon is inline, because when Gravity Forms no conflict mode is ON, it kills all enqueued styles,
255 // which results in a large menu SVG icon displaying.
256 // However, don't load this on customize.php, as it wrongly outputs above the opening <html> tag.
257 if ( $screen['screen'] != 'customize' ) {
258 ?>
259 <style type="text/css">
260 li.toplevel_page_<?php echo $this->base->plugin->settingsName; ?>-settings a div.wp-menu-image,
261 li.toplevel_page_<?php echo $this->base->plugin->settingsName; ?> a div.wp-menu-image,
262 li.toplevel_page_<?php echo $this->base->plugin->name; ?>-settings a div.wp-menu-image,
263 li.toplevel_page_<?php echo $this->base->plugin->name; ?> a div.wp-menu-image {
264 background: url(<?php echo $this->base->plugin->url; ?>/vendor/assets/images/icons/<?php echo strtolower( $this->base->plugin->account ); ?>-light.svg) center no-repeat;
265 background-size: 16px 16px;
266 }
267 li.toplevel_page_<?php echo $this->base->plugin->settingsName; ?>-settings a div.wp-menu-image img,
268 li.toplevel_page_<?php echo $this->base->plugin->settingsName; ?> a div.wp-menu-image img,
269 li.toplevel_page_<?php echo $this->base->plugin->name; ?>-settings a div.wp-menu-image img,
270 li.toplevel_page_<?php echo $this->base->plugin->name; ?> a div.wp-menu-image img {
271 display: none;
272 }
273 </style>
274 <?php
275 }
276 wp_enqueue_style( $this->base->plugin->name, $this->base->plugin->url . 'vendor/assets/css/admin.css', array(), $this->base->plugin->version );
277
278 // Don't load anything else if we're not on a Plugin or Post screen
279 if ( ! $screen['screen'] ) {
280 return;
281 }
282
283 // Determine whether to load minified versions of JS
284 $minified = $this->base->dashboard->should_load_minified_js();
285
286 // Define JS and localization
287 wp_register_script( $this->base->plugin->name . '-log', $this->base->plugin->url . 'vendor/assets/js/' . ( $minified ? 'min/' : '' ) . 'log' . ( $minified ? '-min' : '' ) . '.js', array( 'jquery' ), $this->base->plugin->version, true );
288 wp_register_script( $this->base->plugin->name . '-statuses', $this->base->plugin->url . 'vendor/assets/js/' . ( $minified ? 'min/' : '' ) . 'statuses' . ( $minified ? '-min' : '' ) . '.js', array( 'jquery' ), $this->base->plugin->version, true );
289
290 $localization = array(
291 'ajax' => admin_url( 'admin-ajax.php' ),
292
293 'clear_log_nonce' => wp_create_nonce( $this->base->plugin->name . '-clear-log' ),
294 'clear_log_completed' => sprintf(
295 /* translators: Social Media Service Name (Buffer, Hootsuite, SocialPilot) */
296 __( 'No log entries exist, or no status updates have been sent to %s.', 'wp-to-social-pro' ),
297 $this->base->plugin->account
298 ),
299
300 'get_log_nonce' => wp_create_nonce( $this->base->plugin->name . '-get-log' ),
301
302 'delete_condition_message' => __( 'Are you sure you want to delete this condition?', 'wp-to-social-pro' ),
303 'delete_status_message' => __( 'Are you sure you want to delete this status?', 'wp-to-social-pro' ),
304
305 'get_status_row_action' => $this->base->plugin->filter_name . '_get_status_row',
306 'get_status_row_nonce' => wp_create_nonce( $this->base->plugin->name . '-get-status-row' ),
307
308 'post_id' => ( isset( $post->ID ) ? $post->ID : (int) $id ),
309
310 // Plugin specific Status Form Container and Status Form, so statuses.js knows where to look for the form
311 // relative to this Plugin
312 'plugin_name' => $this->base->plugin->name,
313 'status_form_container' => '#' . $this->base->plugin->name . '-status-form-container',
314 'status_form' => '#' . $this->base->plugin->name . '-status-form',
315 );
316
317 // If here, we're on a Plugin or Post screen
318 // Conditionally load scripts and styles depending on which section of the Plugin we're loading
319 switch ( $screen['screen'] ) {
320 /**
321 * Post
322 */
323 case 'post':
324 switch ( $screen['section'] ) {
325 /**
326 * WP_List_Table
327 */
328 case 'wp_list_table':
329 break;
330
331 /**
332 * Add/Edit
333 */
334 case 'edit':
335 // Plugin JS
336 wp_enqueue_script( $this->base->plugin->name . '-log' );
337 wp_localize_script( $this->base->plugin->name . '-log', 'wp_to_social_pro', $localization );
338 break;
339 }
340 break;
341
342 /**
343 * Settings
344 */
345 case 'settings':
346 // JS
347 wp_enqueue_script( 'wpzinc-admin-conditional' );
348 wp_enqueue_script( 'wpzinc-admin-tabs' );
349 wp_enqueue_script( 'wpzinc-admin' );
350
351 switch ( $screen['section'] ) {
352 /**
353 * General
354 */
355 case 'auth':
356 break;
357
358 /**
359 * Post Type
360 */
361 default:
362 // JS
363 wp_enqueue_script( 'wpzinc-admin-autocomplete' );
364 wp_enqueue_script( 'wpzinc-admin-autosize' );
365 wp_enqueue_script( 'wpzinc-admin-modal' );
366 wp_enqueue_script( 'jquery-ui-sortable' );
367
368 // Plugin JS
369 wp_enqueue_script( $this->base->plugin->name . '-statuses' );
370
371 // Add Post Type, Action and Nonce to allow AJAX saving
372 $localization['post_type'] = $this->get_post_type_tab();
373 $localization['prompt_unsaved_changes'] = true;
374 $localization['save_statuses_action'] = $this->base->plugin->filter_name . '_save_statuses';
375 $localization['save_statuses_modal'] = array(
376 'title' => __( 'Saving', 'wp-to-social-pro' ),
377 'title_success' => __( 'Saved!', 'wp-to-social-pro' ),
378 );
379 $localization['save_statuses_nonce'] = wp_create_nonce( $this->base->plugin->name . '-save-statuses' );
380
381 // Localize Statuses
382 wp_localize_script( $this->base->plugin->name . '-statuses', 'wp_to_social_pro', $localization );
383
384 // Localize Autocomplete
385 wp_localize_script( 'wpzinc-admin-autocomplete', 'wpzinc_autocomplete', $this->get_autocomplete_configuration( $localization['post_type'] ) );
386 break;
387 }
388 break;
389
390 /**
391 * Log
392 */
393 case 'log':
394 // Plugin JS
395 wp_enqueue_script( $this->base->plugin->name . '-log' );
396
397 // Localize
398 wp_localize_script( $this->base->plugin->name . '-log', 'wp_to_social_pro', $localization );
399 break;
400 }
401
402 }
403
404 /**
405 * Returns configuration for tribute.js autocomplete instances for Tags
406 *
407 * @since 4.5.7
408 *
409 * @param string $post_type Post Type
410 * @return array Javascript Autocomplete Configuration
411 */
412 private function get_autocomplete_configuration( $post_type ) {
413
414 $autocomplete_configuration = array(
415 // Tags
416 array(
417 'fields' => array(
418 'textarea.message',
419 ),
420 'triggers' => array(
421 // Tags
422 array(
423 'trigger' => '{',
424 'values' => $this->base->get_class( 'common' )->get_tags_flat( $post_type ),
425 ),
426 ),
427 ),
428 );
429
430 /**
431 * Defines configuration for tribute.js autocomplete instances for Tags
432 *
433 * @since 4.5.7
434 *
435 * @param array $autocomplete_configuration Javascript Autocomplete Configuration
436 * @param string $post_type Post Type
437 */
438 $autocomplete_configuration = apply_filters( $this->base->plugin->filter_name . '_admin_get_autocomplete_configuration', $autocomplete_configuration );
439
440 // Return
441 return $autocomplete_configuration;
442
443 }
444
445 /**
446 * Add the Plugin to the WordPress Administration Menu
447 *
448 * @since 1.0.0
449 */
450 public function admin_menu() {
451
452 // Menus
453 add_menu_page( $this->base->plugin->displayName, $this->base->plugin->displayName, 'manage_options', $this->base->plugin->name . '-settings', array( $this, 'settings_screen' ), $this->base->plugin->url . 'vendor/assets/images/icons/' . strtolower( $this->base->plugin->account ) . '-light.svg' );
454
455 // Register Submenu Pages
456 $settings_page = add_submenu_page( $this->base->plugin->name . '-settings', __( 'Settings', $this->base->plugin->name ), __( 'Settings', $this->base->plugin->name ), 'manage_options', $this->base->plugin->name . '-settings', array( $this, 'settings_screen' ) );
457
458 // Logs
459 if ( $this->base->get_class( 'log' )->is_enabled() ) {
460 $log_page = add_submenu_page( $this->base->plugin->name . '-settings', __( 'Logs', $this->base->plugin->name ), __( 'Logs', $this->base->plugin->name ), 'manage_options', $this->base->plugin->name . '-log', array( $this, 'log_screen' ) );
461 add_action( "load-$log_page", array( $this->base->get_class( 'log' ), 'add_screen_options' ) );
462 }
463
464 $upgrade_page = add_submenu_page( $this->base->plugin->name . '-settings', __( 'Upgrade', $this->base->plugin->name ), __( 'Upgrade', $this->base->plugin->name ), 'manage_options', $this->base->plugin->name . '-upgrade', array( $this, 'upgrade_screen' ) );
465
466 }
467
468 /**
469 * Upgrade Screen
470 *
471 * @since 3.2.5
472 */
473 public function upgrade_screen() {
474 // We never reach here, as we redirect earlier in the process
475 }
476
477 /**
478 * Outputs the Settings Screen
479 *
480 * @since 3.0.0
481 */
482 public function settings_screen() {
483
484 // Setup notices class
485 $this->base->get_class( 'notices' )->set_key_prefix( $this->base->plugin->filter_name . '_' . wp_get_current_user()->ID );
486
487 // Maybe disconnect
488 if ( isset( $_GET[ $this->base->plugin->name . '-disconnect' ] ) ) {
489 $this->disconnect();
490 $this->base->get_class( 'notices' )->add_success_notice(
491 sprintf(
492 /* translators: Social Media Service Name (Buffer, Hootsuite, SocialPilot) */
493 __( '%s account disconnected successfully.', 'wp-to-social-pro' ),
494 $this->base->plugin->account
495 )
496 );
497 }
498
499 // Maybe save settings
500 $result = $this->save_settings();
501 if ( is_wp_error( $result ) ) {
502 // Error notice
503 $this->base->get_class( 'notices' )->add_error_notice( $result->get_error_message() );
504 } elseif ( $result === true ) {
505 // Success notice
506 $this->base->get_class( 'notices' )->add_success_notice( __( 'Settings saved successfully.', 'wp-to-social-pro' ) );
507 }
508
509 // If the Plugin isn't connected to the API, show the screen to do this now
510 if ( ! $this->base->get_class( 'validation' )->api_connected() ) {
511 $this->auth_screen();
512 return;
513 }
514
515 // Authentication
516 $access_token = $this->base->get_class( 'settings' )->get_access_token();
517 $refresh_token = $this->base->get_class( 'settings' )->get_refresh_token();
518 $expires = $this->base->get_class( 'settings' )->get_token_expires();
519 if ( ! empty( $access_token ) ) {
520 $this->base->get_class( 'api' )->set_tokens( $access_token, $refresh_token, $expires );
521 }
522
523 // Profiles
524 $profiles = $this->base->get_class( 'api' )->profiles( true, $this->base->get_class( 'common' )->get_transient_expiration_time() );
525 if ( is_wp_error( $profiles ) ) {
526 // If the error is a 401, the user revoked access to the plugin
527 // Disconnect the Plugin, and explain why this happened
528 if ( $profiles->get_error_code() == 401 ) {
529 // Disconnect the Plugin
530 $this->disconnect();
531
532 // Error notice
533 $this->base->get_class( 'notices' )->add_error_notice(
534 sprintf(
535 /* translators: %1$s: Plugin Name, %2$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot) */
536 __( 'Hmm, it looks like you revoked access to %1$s through your %2$s account, or your account no longer exists. This means we can no longer post updates to your social networks. To re-authorize, click the Authorize Plugin button.', 'wp-to-social-pro' ),
537 $this->base->plugin->displayName,
538 $this->base->plugin->account
539 )
540 );
541 } else {
542 // Some other error
543 $this->base->get_class( 'notices' )->add_error_notice( $profiles->get_error_message() );
544 }
545 }
546
547 // Get Settings Tab and Post Type we're managing settings for
548 $tab = $this->get_tab( $profiles );
549 $post_type = $this->get_post_type_tab();
550 $disable_save_button = false;
551
552 // Post Types
553 $post_types = $this->base->get_class( 'common' )->get_post_types();
554
555 // Depending on the screen we're on, load specific options
556 switch ( $tab ) {
557 /**
558 * Settings
559 */
560 case 'auth':
561 // Log Settings
562 $log_levels = $this->base->get_class( 'log' )->get_level_options();
563
564 // Documentation URL
565 $documentation_url = $this->base->plugin->documentation_url . '/authentication-settings';
566 break;
567
568 /**
569 * No Profiles
570 */
571 case 'profiles-missing':
572 // Disable Save button, as there are no settings displayed to save
573 $disable_save_button = true;
574
575 // Documentation URL
576 $documentation_url = $this->base->plugin->documentation_url . '/status-settings';
577 break;
578
579 /**
580 * Profiles Error
581 */
582 case 'profiles-error':
583 // Disable Save button, as there are no settings displayed to save
584 $disable_save_button = true;
585
586 // Documentation URL
587 $documentation_url = $this->base->plugin->documentation_url . '/status-settings';
588 break;
589
590 /**
591 * Post Type
592 */
593 default:
594 // Get original statuses that will be stored in a hidden field so they are preserved if the screen is saved
595 // with no changes that trigger an update to the hidden field
596 $original_statuses = $this->base->get_class( 'settings' )->get_settings( $post_type );
597
598 // Get some other information
599 $post_type_object = get_post_type_object( $post_type );
600 $actions_plural = $this->base->get_class( 'common' )->get_post_actions_past_tense();
601 $post_actions = $this->base->get_class( 'common' )->get_post_actions();
602 $documentation_url = $this->base->plugin->documentation_url . '/status-settings';
603
604 // Check if this Post Type is enabled
605 if ( ! $this->base->get_class( 'settings' )->is_post_type_enabled( $post_type ) ) {
606 $this->base->get_class( 'notices' )->add_warning_notice(
607 /* translators: %1$s: Post Type, %2$s: Social Media Service Name (Buffer, Hootsuite, SocialPilot), %3$s: Documentation URL */
608 sprintf(
609 __( 'To send %1$s to %2$s, at least one action on the Defaults tab must be enabled with a status defined, and at least one social media profile must be enabled below by clicking the applicable profile name and ticking the "Account Enabled" box. <a href="%3$s" target="_blank">See Documentation</a>', 'wp-to-social-pro' ),
610 $post_type_object->label,
611 $this->base->plugin->account,
612 $documentation_url
613 )
614 );
615 }
616 break;
617 }
618
619 // Load View
620 include_once( $this->base->plugin->folder . 'vendor/views/settings.php' );
621
622 // Add footer action to output overlay modal markup
623 add_action( 'admin_footer', array( $this, 'output_modal' ) );
624
625 }
626
627 /**
628 * Outputs the auth screen, allowing the user to begin the process of connecting the Plugin
629 * to the API, without showing other settings.
630 *
631 * @since 4.6.4
632 */
633 public function auth_screen() {
634
635 // Load View
636 include_once( $this->base->plugin->folder . 'vendor/views/settings-auth-required.php' );
637
638 }
639
640 /**
641 * Outputs the hidden Javascript Modal and Overlay in the Footer
642 *
643 * @since 1.0.0
644 */
645 public function output_modal() {
646
647 // Load view
648 require_once( $this->base->plugin->folder . '_modules/dashboard/views/modal.php' );
649
650 }
651
652 /**
653 * Outputs the Log Screen
654 *
655 * @since 3.9.6
656 */
657 public function log_screen() {
658
659 // Init table
660 $table = new WP_To_Social_Pro_Log_Table( $this->base );
661 $table->prepare_items();
662
663 // Load View
664 include_once( $this->base->plugin->folder . 'vendor/views/log.php' );
665
666 }
667
668 /**
669 * Helper method to get the setting value from the plugin settings
670 *
671 * @since 3.0.0
672 *
673 * @param string $type Setting Type
674 * @param string $keys Setting Key(s)
675 * @param mixed $default Default Value if Setting does not exist
676 * @return mixed Value
677 */
678 public function get_setting( $type = '', $key = '', $default = '' ) {
679
680 // Post Type Setting or Bulk Setting
681 if ( post_type_exists( $type ) ) {
682 return $this->base->get_class( 'settings' )->get_setting( $type, $key, $default );
683 }
684
685 // Access token
686 if ( $key == 'access_token' ) {
687 return $this->base->get_class( 'settings' )->get_access_token();
688 }
689
690 // Refresh token
691 if ( $key == 'refresh_token' ) {
692 return $this->base->get_class( 'settings' )->get_refresh_token();
693 }
694
695 // Depending on the type, return settings / options
696 switch ( $type ) {
697 case 'text_to_image':
698 case 'log':
699 case 'hide_meta_box_by_roles':
700 case 'roles':
701 case 'custom_tags':
702 case 'repost':
703 return $this->base->get_class( 'settings' )->get_setting( $type, $key, $default );
704 break;
705
706 default:
707 return $this->base->get_class( 'settings' )->get_option( $key, $default );
708 break;
709 }
710
711 }
712
713 /**
714 * Disconnect by removing the access token
715 *
716 * @since 3.0.0
717 *
718 * @return string Result
719 */
720 public function disconnect() {
721
722 return $this->base->get_class( 'settings' )->delete_tokens();
723
724 }
725
726 /**
727 * Helper method to save settings
728 *
729 * @since 3.0.0
730 *
731 * @return mixed WP_Error | bool
732 */
733 public function save_settings() {
734
735 // Bail if security checks fail
736 $result = $this->validate_nonce();
737 if ( $result != true ) {
738 return $result;
739 }
740
741 // Get URL parameters
742 $tab = $this->get_tab();
743 $post_type = $this->get_post_type_tab();
744
745 switch ( $tab ) {
746 /**
747 * Authentication
748 */
749 case 'auth':
750 // oAuth settings are now handled by this class' oauth() function
751 // Save other Settings
752
753 // General Settings
754 $this->base->get_class( 'settings' )->update_option( 'test_mode', ( isset( $_POST['test_mode'] ) ? 1 : 0 ) );
755 $this->base->get_class( 'settings' )->update_option( 'force_trailing_forwardslash', ( isset( $_POST['force_trailing_forwardslash'] ) ? 1 : 0 ) );
756 $this->base->get_class( 'settings' )->update_option( 'proxy', ( isset( $_POST['proxy'] ) ? 1 : 0 ) );
757
758 // Log Settings
759 // Always force errors
760 $log = $_POST['log'];
761 if ( ! isset( $log['log_level'] ) ) {
762 $log['log_level'] = array(
763 'error',
764 );
765 } else {
766 // 'Error' is disabled on the form and not sent if another option is chosen
767 // We always want errors to be logged so add it to the log levels now
768 $log['log_level'][] = 'error';
769 }
770 $this->base->get_class( 'settings' )->update_option( 'log', $log );
771
772 // Done
773 return true;
774
775 break;
776
777 /**
778 * Post Type
779 */
780 default:
781 // Unslash and decode JSON field
782 $settings = json_decode( wp_unslash( $_POST[ $this->base->plugin->name ]['statuses'] ), true );
783 return $this->base->get_class( 'settings' )->update_settings( $post_type, $settings );
784 break;
785 }
786
787 }
788
789 /**
790 * Returns the settings tab that the user has selected.
791 *
792 * @since 3.7.2
793 *
794 * @return string Tab
795 */
796 private function get_tab() {
797
798 return ( isset( $_GET['tab'] ) ? sanitize_text_field( $_GET['tab'] ) : 'auth' );
799
800 }
801
802 /**
803 * Returns the Post Type tab that the user has selected.
804 *
805 * @since 3.7.2
806 *
807 * @return string Tab
808 */
809 private function get_post_type_tab() {
810
811 return ( isset( $_GET['type'] ) ? sanitize_text_field( $_GET['type'] ) : '' );
812
813 }
814
815 /**
816 * Validates the nonce field on submitted POST data
817 *
818 * @since 3.4.7
819 *
820 * @return mixed WP_Error | boolean
821 */
822 private function validate_nonce() {
823
824 // Check if a POST request was made
825 if ( ! isset( $_POST['submit'] ) ) {
826 return false;
827 }
828
829 // Missing nonce
830 if ( ! isset( $_POST[ $this->base->plugin->name . '_nonce' ] ) ) {
831 return __( 'Nonce field is missing. Settings NOT saved.', 'wp-to-social-pro' );
832 }
833
834 // Invalid nonce
835 if ( ! wp_verify_nonce( $_POST[ $this->base->plugin->name . '_nonce' ], 'wp-to-social-pro' ) ) {
836 return __( 'Invalid nonce specified. Settings NOT saved.', 'wp-to-social-pro' );
837 }
838
839 return true;
840
841 }
842
843 /**
844 * Loads plugin textdomain
845 *
846 * @since 3.0.0
847 */
848 public function load_language_files() {
849
850 load_plugin_textdomain( 'wp-to-social-pro', false, $this->base->plugin->name . '/languages/' );
851
852 }
853
854 }