PluginProbe
Media Cloud Sync / trunk
Media Cloud Sync vtrunk
1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 All 34 releases
← All changes | includes/admin.php +121 -36 1.0.2trunk View file →
@@ -2,8 +2,9 @@
2 2 namespace Dudlewebs\WPMCS;
3 3
4 4 defined('ABSPATH') || exit;
5 5
6 +use WP_Site;
6 7 class Admin {
7 8 private static $instance = null;
8 9 private $assets_url;
9 10 private $version;
@@ -34,8 +35,9 @@
34 35 // Admin Init
35 36 add_action('admin_init', [$this, 'adminInit']);
36 37
37 38 add_action('admin_menu', [$this, 'add_menu'], 10);
39 + add_action('admin_notices', [$this, 'storage_credentials_admin_notice']);
38 40
39 41 add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts'], 10, 1);
40 42 add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_styles'], 10, 1);
41 43 // Load media scripts
@@ -42,8 +44,14 @@
42 44 add_action( 'load-upload.php', [ $this, 'load_media_assets' ], 11 );
43 45
44 46 // Plugin Deactivation Survey
45 47 add_action('admin_footer', array($this, 'wpmcs_deactivation_form'));
48 +
49 + if (is_multisite()) {
50 + // Register multisite site creation hooks
51 + add_action('wp_initialize_site', [$this, 'create_multisite_table'], 10, 1);
52 + add_action('wpmu_new_blog', [$this, 'create_multisite_table'], 10, 1);
53 + }
46 54 }
47 55
48 56 /**
49 57 * Method that is used on plugin initialization time
@@ -49,18 +57,35 @@
49 57 * Method that is used on plugin initialization time
50 58 * @since 1.0.0
51 59 */
52 60 public function adminInit() {
53 - if(get_option( $this->token.'_db_version' ) !== WPMCS_DB_VERSION) {
54 - $database = Db::instance();
55 - $database->do_database_upgrade();
61 + $current_db_version = get_option( $this->token . '_db_version', false );
62 + /**
63 + * Run DB upgrades only if:
64 + * - DB version exists
65 + * - DB version is lower than plugin DB version
66 + */
67 + if (
68 + $current_db_version === false ||
69 + version_compare( $current_db_version, WPMCS_DB_VERSION, '<' )
70 + ) {
71 + Db::instance()->do_database_upgrade();
56 72 }
57 73
58 - if (get_option($this->token.'_do_activation_redirect', false) && !Utils::get_service()) {
59 - delete_option($this->token.'_do_activation_redirect');
60 - wp_redirect(admin_url('admin.php?page=' . $this->token . '-admin-ui#/configure'));
61 - } else {
62 - delete_option($this->token.'_do_activation_redirect');
74 + /**
75 + * One-time activation redirect
76 + */
77 + $do_redirect = get_option( $this->token . '_do_activation_redirect', false );
78 +
79 + if ( $do_redirect ) {
80 + delete_option( $this->token . '_do_activation_redirect' );
81 +
82 + if ( ! Utils::get_service() ) {
83 + wp_redirect(
84 + admin_url( 'admin.php?page=' . $this->token . '-admin-ui#/configure' )
85 + );
86 + exit;
87 + }
63 88 }
64 89 }
65 90
66 91 /**
@@ -69,18 +94,16 @@
69 94 * @access public
70 95 * @return void
71 96 * @since 1.0.0
72 97 */
73 - public function install(){
74 - $database = Db::instance();
98 + public static function install($network_wide = false) {
99 + Db::handle_tables($network_wide);
75 100
76 - $database->create_table();
77 -
78 101 // Redirection on activation
79 - add_option($this->token.'_do_activation_redirect', true);
102 + add_option(WPMCS_TOKEN . '_do_activation_redirect', true);
80 103
81 104 //Protect directories
82 - $this->_protect_upload_dir();
105 + self::_protect_upload_dir();
83 106 }
84 107
85 108 /**
86 109 * Create plugin specific upload directory
@@ -87,9 +110,9 @@
87 110 * @since 1.0.0
88 111 */
89 112 public function create_plugin_dir() {
90 113 //Protect directories
91 - $this->_protect_upload_dir();
114 + self::_protect_upload_dir();
92 115 }
93 116
94 117 /**
95 118 * Protect Directory from external access.
@@ -95,27 +118,26 @@
95 118 * Protect Directory from external access.
96 119 *
97 120 * @access private
98 121 * @return void
99 - * @since 1.0.0
122 + * @since 1.3.0
123 + * @see \Dudlewebs\WPMCS\Admin::_protect_upload_dir
100 124 */
101 - private function _protect_upload_dir(){
125 + private static function _protect_upload_dir(){
102 126 $upload_dir = wp_upload_dir();
103 127
128 + $upload_base = $upload_dir['basedir'] . '/' . Schema::getConstant('UPLOADS');
129 +
104 130 $files = array(
105 131 array(
106 - 'base' => $upload_dir['basedir'] . '/' . Schema::getConstant('UPLOADS'),
132 + 'base' => $upload_base,
107 133 'file' => '.htaccess',
108 - 'content' => 'Options -Indexes' . "\n"
109 - . '<Files *.php>' . "\n"
110 - . 'deny from all' . "\n"
111 - . '</Files>'
134 + 'content' => "Options -Indexes\nDeny from all"
112 135 ),
113 136 array(
114 - 'base' => $upload_dir['basedir'] . '/' . Schema::getConstant('UPLOADS'),
137 + 'base' => $upload_base,
115 138 'file' => 'index.php',
116 - 'content' => '<?php ' . "\n"
117 - . '// Silence is golden.'
139 + 'content' => "<?php\n// Silence is golden."
118 140 )
119 141 );
120 142
121 143 foreach ($files as $file) {
@@ -131,12 +153,30 @@
131 153
132 154 /**
133 155 * Deactivation hook
134 156 */
135 - public function deactivation(){
157 + public static function deactivation(){
136 158 }
137 159
160 +
138 161 /**
162 + * Handle multisite site creation.
163 + */
164 + public function create_multisite_table($site) {
165 + if (is_numeric($site)) {
166 + $site_id = (int) $site;
167 + } elseif ($site instanceof \WP_Site) {
168 + $site_id = $site->blog_id;
169 + } else {
170 + return; // Invalid input
171 + }
172 +
173 + switch_to_blog($site_id);
174 + Db::instance()->create_table();
175 + restore_current_blog();
176 + }
177 +
178 + /**
139 179 * Load admin Javascript.
140 180 * @access public
141 181 * @return void
142 182 * @since 1.0.0
@@ -169,9 +209,15 @@
169 209 $this->token . '_object',
170 210 array(
171 211 'api_nonce' => wp_create_nonce('wp_rest'),
172 212 'root' => rest_url($this->token . '/v1/'),
213 + 'pro_root' => rest_url($this->token . '/pro/v1/'),
173 214 'assets_url' => $this->assets_url,
215 + 'admin_url' => admin_url(),
216 + 'is_db_upgrade_required' => Upgrade::instance()->is_upgrade_needed(),
217 + 'is_cron_disabled' => defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON,
218 + 'is_pro_active' => defined('WPMCS_PRO_VERSION'),
219 + 'license_status' => defined('WPMCS_PRO_VERSION') ? Utils::get_safe_license_data() : [],
174 220 )
175 221 );
176 222 }
177 223 }
@@ -212,8 +258,12 @@
212 258 'getstarted' => '<a href="' . admin_url('admin.php?page=' . $this->token . '-admin-ui#/configure') . '">' . esc_html__('Get Started', 'media-cloud-sync') . '</a>',
213 259 'settings' => '<a href="' . admin_url('admin.php?page=' . $this->token . '-admin-ui/') . '">' . esc_html__('Settings', 'media-cloud-sync') . '</a>',
214 260 );
215 261
262 + if (!Utils::is_pro_licensed()) {
263 + $action_links['upgrade'] = '<a href="https://dudlewebs.com/product/media-cloud-sync/" target="_blank" style="color:#d54e21;font-weight:600;">' . esc_html__('Upgrade', 'media-cloud-sync') . '</a>';
264 + }
265 +
216 266 return array_merge($action_links, $links);
217 267 }
218 268
219 269
@@ -228,10 +278,10 @@
228 278 esc_html__('Media Cloud Sync', 'media-cloud-sync'),
229 279 'manage_options',
230 280 $this->token.'-admin-ui',
231 281 array($this, 'adminUi'),
232 - 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA5MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTcwLjMwODYgMjMuMDM1N0w3MC42MDQxIDI0LjUzOUw3Mi4xMzI0IDI0LjY0NTJDODAuODA4NiAyNS4yNDgzIDg3LjYzODYgMzIuNDE0MyA4Ny42Mzg2IDQxLjI1Qzg3LjYzODYgNTAuNTAzIDgwLjE2MDEgNTggNzAuOTYzOSA1OEgyMi40MDk2QzExLjE1OTEgNTggMiA0OC44MTU1IDIgMzcuNVYzNy40OTk4QzEuOTk5NDIgMzIuNDQ3IDMuODU4NjYgMjcuNTczNSA3LjIxODQ4IDIzLjgxNTVDMTAuNTc4MSAyMC4wNTc3IDE1LjIwMDggMTcuNjgwNSAyMC4xOTc3IDE3LjEzODNMMjEuMjYzNiAxNy4wMjI3TDIxLjc1NzMgMTYuMDcwOUMyNi4wOTc2IDcuNzAzOTEgMzQuODA1MyAyIDQ0LjgxOTMgMkg0NC44MTk3QzUwLjgzNDggMS45OTg2MyA1Ni42NjQ3IDQuMDk0MDEgNjEuMzEzOCA3LjkyOTg2QzY1Ljk2MyAxMS43NjU4IDY5LjE0MyAxNy4xMDQ4IDcwLjMwODYgMjMuMDM1N1oiIHN0cm9rZT0iIzAyMDQ0QSIgc3Ryb2tlLXdpZHRoPSI0Ii8+CjxjaXJjbGUgY3g9IjQ1IiBjeT0iMzMiIHI9IjEyIiBzdHJva2U9IiMwMjA0NEEiIHN0cm9rZS13aWR0aD0iNCIvPgo8ZyBmaWx0ZXI9InVybCgjZmlsdGVyMF9kXzE4MV80OTgpIj4KPHBhdGggZD0iTTQ4LjA4NyAzMC41VjQwLjYyNzFMNDYuMTk1NyA0MlYyNEw1Mi41IDMwLjVINDguMDg3WiIgZmlsbD0iIzAyMDQ0QSIvPgo8cGF0aCBkPSJNNDIuNDEzIDM1LjVWMjUuMzcyOUw0NC4zMDQ0IDI0VjQyTDM4IDM1LjVINDIuNDEzWiIgZmlsbD0iIzAyMDQ0QSIvPgo8L2c+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2RfMTgxXzQ5OCIgeD0iMzAiIHk9IjE2IiB3aWR0aD0iMzAuNSIgaGVpZ2h0PSIzNCIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVDb2xvck1hdHJpeCBpbj0iU291cmNlQWxwaGEiIHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAxMjcgMCIgcmVzdWx0PSJoYXJkQWxwaGEiLz4KPGZlT2Zmc2V0Lz4KPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iNCIvPgo8ZmVDb21wb3NpdGUgaW4yPSJoYXJkQWxwaGEiIG9wZXJhdG9yPSJvdXQiLz4KPGZlQ29sb3JNYXRyaXggdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMC4wMDc4NDMxNCAwIDAgMCAwIDAuMDE1Njg2MyAwIDAgMCAwIDAuMjkwMTk2IDAgMCAwIDAuMTYgMCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9ImVmZmVjdDFfZHJvcFNoYWRvd18xODFfNDk4Ii8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iZWZmZWN0MV9kcm9wU2hhZG93XzE4MV80OTgiIHJlc3VsdD0ic2hhcGUiLz4KPC9maWx0ZXI+CjwvZGVmcz4KPC9zdmc+Cg==',
233 - 25
282 + 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTczIiBoZWlnaHQ9IjEyMiIgdmlld0JveD0iMCAwIDE3MyAxMjIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xMzkuNTggNzYuMDA4MkMxNDYuNDQxIDc1LjgyMyAxNTEuOTAyIDc4LjgxNTggMTU2LjE3OSA4My44NzkzQzE2MS42OTUgOTAuNDA5OCAxNjEuMzQ5IDk4LjY5MjEgMTU1LjkyMyAxMDUuMzI0QzE1Mi40ODUgMTA5LjUyNiAxNDYuOTI5IDExMC42OTMgMTQyLjIwNyAxMDguMTZDMTM5LjU4OSAxMDYuNzU1IDEzNy45NDIgMTA0LjUxIDEzNy4wMzEgMTAxLjcwMUMxMzYuNzc0IDEwMC45MDYgMTM3LjA3MiAxMDAuNjE1IDEzNy44NSAxMDAuNjMxQzEzOC41OTggMTAwLjY0NyAxMzkuMzQ3IDEwMC42MzUgMTQwLjQ0NCAxMDAuNjM1QzE0MS43MDkgMTAwLjUyMSAxNDMuMTc4IDEwMC44MTggMTQ0LjY3MiAxMDEuNThDMTQ3Ljc2NyAxMDMuMTU5IDE1Mi4xNTcgMTAxLjY1OCAxNTMuOTY1IDk4LjYwNTlDMTU2LjA3OSA5NS4wMzcgMTU1LjQxMSA5MS4wMDY3IDE1Mi4zMjkgODguNzM2N0MxNDguNTkgODUuOTgyOSAxNDQuNDg0IDg2LjQzNzggMTQxLjM0NyA4OS44OTg4QzEzOS41NzUgOTEuODUzNyAxMzcuMzYzIDkzLjAwNDMgMTM0LjcwMiA5My4yMDk0QzEzMC4zNjUgOTMuNTQzNiAxMjcuMzE1IDg5Ljk3OTIgMTI4LjEzMyA4NS41Mzg1QzEyOS4xMjUgODAuMTU4NSAxMzMuOTE2IDc2LjE2MTEgMTM5LjU4IDc2LjAwODJaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQyLjIxNyA5NC4xMzMyQzE0Mi42MjQgOTQuMTMzMiAxNDIuOTU1IDk0LjQ2MzMgMTQyLjk1NSA5NC44NzA1Vjk5LjY3OTFDMTQyLjk1NSAxMDAuMDg2IDE0Mi42MjQgMTAwLjQxNSAxNDIuMjE3IDEwMC40MTVIMTM3LjU1OEMxMzcuMTUxIDEwMC40MTUgMTM2LjgyMSAxMDAuMDg2IDEzNi44MiA5OS42NzkxVjk0Ljg3MDVDMTM2LjgyIDk0LjQ2MzMgMTM3LjE1IDk0LjEzMzIgMTM3LjU1OCA5NC4xMzMySDE0Mi4yMTdaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQ5LjE5NyA5NC4xMzQyQzE0OS42MDUgOTQuMTM0MiAxNDkuOTM2IDk0LjQ2NDMgMTQ5LjkzNiA5NC44NzE1Vjk2LjU3NTZDMTQ5LjkzNiA5Ni45ODI4IDE0OS42MDUgOTcuMzEyOSAxNDkuMTk3IDk3LjMxMjlIMTQ3LjU2OUMxNDcuMTYxIDk3LjMxMjkgMTQ2LjgzMSA5Ni45ODI4IDE0Ni44MzEgOTYuNTc1NlY5NC44NzE1QzE0Ni44MzEgOTQuNDY0MyAxNDcuMTYxIDk0LjEzNDIgMTQ3LjU2OSA5NC4xMzQySDE0OS4xOTdaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQ1LjMzMiA5NC4xMzMyQzE0NS43MzkgOTQuMTMzNSAxNDYuMDcgOTQuNDYzNSAxNDYuMDcgOTQuODcwNVY5NS44MDUxQzE0Ni4wNyA5Ni4yMTIxIDE0NS43MzkgOTYuNTQyMSAxNDUuMzMyIDk2LjU0MjRIMTQ0LjQ1NEMxNDQuMDQ3IDk2LjU0MjQgMTQzLjcxNyA5Ni4yMTIzIDE0My43MTcgOTUuODA1MVY5NC44NzA1QzE0My43MTcgOTQuNDYzMyAxNDQuMDQ3IDk0LjEzMzIgMTQ0LjQ1NCA5NC4xMzMySDE0NS4zMzJaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE3MyA5Mi41MDAxQzE3MyAxMDguMjQgMTYwLjI0IDEyMSAxNDQuNSAxMjFDMTI4Ljc2IDEyMSAxMTYgMTA4LjI0IDExNiA5Mi41MDAxQzExNiA3Ni43NiAxMjguNzYgNjQuMDAwMSAxNDQuNSA2NC4wMDAxQzE2MC4yNCA2NC4wMDAxIDE3MyA3Ni43NiAxNzMgOTIuNTAwMVpNMTQ0LjUgMTE0QzE1Ni4zNzQgMTE0IDE2NiAxMDQuMzc0IDE2NiA5Mi41MDAxQzE2NiA4Ni43MDIyIDE2My43MDUgODEuNDQwMyAxNTkuOTc0IDc3LjU3MzNDMTU2LjA2NCA3My41MjA3IDE1MC41NzYgNzEuMDAwMSAxNDQuNSA3MS4wMDAxQzEzMi42MjYgNzEuMDAwMSAxMjMgODAuNjI2IDEyMyA5Mi41MDAxQzEyMyAxMDAuNTQzIDEyNy40MTYgMTA3LjU1NCAxMzMuOTU2IDExMS4yNDFDMTM3LjA3MSAxMTIuOTk4IDE0MC42NjkgMTE0IDE0NC41IDExNFoiIGZpbGw9ImJsYWNrIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzUuMjY1OSA0My40MTY4QzM3LjI3OTMgMzEuMjg3IDQzLjUzMjQgMjAuMjY1NSA1Mi45MTE3IDEyLjMxNDdDNjIuMjkxIDQuMzYzOTEgNzQuMTg3NyAwIDg2LjQ4MzUgMEM5OC43NzkzIDAgMTEwLjY3NiA0LjM2MzkxIDEyMC4wNTUgMTIuMzE0N0MxMjkuNDM1IDIwLjI2NTUgMTM1LjY4OCAzMS4yODcgMTM3LjcwMSA0My40MTY4QzE0Ny42NjIgNDQuMzU5IDE1Ni44NzcgNDkuMDk5NiAxNjMuNDM1IDU2LjY1NTFDMTY5Ljk5NCA2NC4yMTA2IDE3My4zOTIgNzQuMDAwOSAxNzIuOTI0IDgzLjk5NDlDMTcyLjQ1NyA5My45ODg5IDE2OC4xNiAxMDMuNDE5IDE2MC45MjUgMTEwLjMzQzE1My42OSAxMTcuMjQgMTQ0LjA3MiAxMjEuMSAxMzQuMDY3IDEyMS4xMDhIMzguODk5NkMyOC44OTQ3IDEyMS4xIDE5LjI3NyAxMTcuMjQgMTIuMDQyIDExMC4zM0M0LjgwNjk1IDEwMy40MTkgMC41MDk5NzUgOTMuOTg4OSAwLjA0MjU0OTUgODMuOTk0OUMtMC40MjQ4NzYgNzQuMDAwOSAyLjk3MzEzIDY0LjIxMDYgOS41MzE1OSA1Ni42NTUxQzE2LjA5IDQ5LjA5OTYgMjUuMzA1NSA0NC4zNTkgMzUuMjY1OSA0My40MTY4Wk00Mi45NzE1IDQ1LjkyNTJDNDQuNjgyNyAzNS42MDkgNDkuOTk3IDI2LjIzNTQgNTcuOTY4MiAxOS40NzM1QzY1LjkzOTQgMTIuNzExNSA3Ni4wNTAxIDkuMDAwMSA4Ni40OTk5IDkuMDAwMUM5Ni45NDk4IDkuMDAwMSAxMDcuMDYgMTIuNzExNSAxMTUuMDMyIDE5LjQ3MzVDMTIzLjAwMyAyNi4yMzU0IDEyOC4zMTcgMzUuNjA5IDEzMC4wMjggNDUuOTI1MkMxMzguNDkzIDQ2LjcyNjUgMTQ2LjMyNSA1MC43NTgzIDE1MS44OTkgNTcuMTg0QzE1Ni44NDUgNjIuODg2MSAxNTkuNjc2IDcwLjA4NDkgMTU5Ljk3NCA3Ny41NzMzQzE2My43MDUgODEuNDQwMyAxNjYgODYuNzAyMiAxNjYgOTIuNTAwMUMxNjYgMTA0LjM3NCAxNTYuMzc0IDExNCAxNDQuNSAxMTRDMTQwLjY2OSAxMTQgMTM3LjA3MSAxMTIuOTk4IDEzMy45NTYgMTExLjI0MUMxMzEuNjY4IDExMS43NCAxMjkuMzE3IDExMS45OTggMTI2Ljk0IDExMkg0Ni4wNTk3QzM3LjU1NjggMTExLjk5MyAyOS4zODI5IDEwOC43MSAyMy4yMzQxIDEwMi44MzNDMTcuMDg1MiA5Ni45NTYxIDEzLjQzMzMgODguOTM1NyAxMy4wMzYxIDgwLjQzNkMxMi42Mzg4IDcxLjkzNjMgMTUuNTI2NyA2My42MDk4IDIxLjEwMDYgNTcuMTg0QzI2LjY3NDQgNTAuNzU4MyAzNC41MDY0IDQ2LjcyNjUgNDIuOTcxNSA0NS45MjUyWiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTkzLjUyMTEgNDEuMTc0OEw3Ny4xNDE3IDE4LjY1MDJDNzYuOTk1MyAxOC40NDk1IDc2LjgwMjUgMTguMjg1OCA3Ni41NzkyIDE4LjE3MjhDNzYuMzU1OSAxOC4wNTk4IDc2LjEwODUgMTguMDAwNiA3NS44NTc0IDE4LjAwMDJINzUuODUzNkM3NS42MDE1IDE4LjAwMDcgNzUuMzUzMiAxOC4wNjA0IDc1LjEyOTMgMTguMTc0M0M3NC45MDU0IDE4LjI4ODIgNzQuNzEyMyAxOC40NTMxIDc0LjU2NjEgMTguNjU1Mkw1OC4yOTI0IDQxLjE3OTdDNTguMTI0IDQxLjQxMjUgNTguMDI0MSA0MS42ODY1IDU4LjAwMzggNDEuOTcxNUM1Ny45ODM1IDQyLjI1NjYgNTguMDQzNSA0Mi41NDE2IDU4LjE3NzMgNDIuNzk1MkM1OC4zMTAzIDQzLjA0OTIgNTguNTExOCA0My4yNjIxIDU4Ljc1OTggNDMuNDEwN0M1OS4wMDc4IDQzLjU1OTIgNTkuMjkyNyA0My42Mzc1IDU5LjU4MyA0My42MzdINjcuMjQxOEw2Ny4yNDEyIDc2LjE0MUM2Ny4yNDExIDc2LjM0NTQgNjcuMjgxOSA3Ni41NDc3IDY3LjM2MTQgNzYuNzM2NUM2Ny40NDA5IDc2LjkyNTMgNjcuNTU3NCA3Ny4wOTY5IDY3LjcwNDMgNzcuMjQxM0M2Ny44NTEyIDc3LjM4NTggNjguMDI1NiA3Ny41MDA0IDY4LjIxNzUgNzcuNTc4NUM2OC40MDk0IDc3LjY1NjYgNjguNjE1MSA3Ny42OTY3IDY4LjgyMjggNzcuNjk2Nkw4Mi45OTMxIDc3LjY5NTlDODMuMjAwOSA3Ny42OTYgODMuNDA2NyA3Ny42NTU4IDgzLjU5ODcgNzcuNTc3NkM4My43OTA2IDc3LjQ5OTQgODMuOTY1MSA3Ny4zODQ3IDg0LjExMiA3Ny4yNDAxQzg0LjI1ODkgNzcuMDk1NSA4NC4zNzUzIDc2LjkyMzkgODQuNDU0OCA3Ni43MzVDODQuNTM0MiA3Ni41NDYxIDg0LjU3NSA3Ni4zNDM2IDg0LjU3NDggNzYuMTM5MlY0My42Mzc2SDkyLjIzNjFDOTIuODI3IDQzLjYzNzYgOTMuMzY5NiA0My4zMDk4IDkzLjY0MjQgNDIuNzkyMUM5My43NzU3IDQyLjUzNzcgOTMuODM0OSA0Mi4yNTIgOTMuODEzNSA0MS45NjY2QzkzLjc5MjEgNDEuNjgxMiA5My42OTA5IDQxLjQwNzEgOTMuNTIxMSA0MS4xNzQ4WiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTgyLjE0NDkgODUuNDcxNUw5Ni44MzM4IDEwMi4xMzZDOTYuOTY1IDEwMi4yODUgOTcuMTM3OSAxMDIuNDA2IDk3LjMzODIgMTAyLjQ5Qzk3LjUzODQgMTAyLjU3MyA5Ny43NjAzIDEwMi42MTcgOTcuOTg1NSAxMDIuNjE3Qzk4LjIxMTYgMTAyLjYxNyA5OC40Mzc3IDEwMi41NzMgOTguNjM4NSAxMDIuNDg4Qzk4LjgzOTMgMTAyLjQwNCA5OS4wMTI0IDEwMi4yODIgOTkuMTQzNSAxMDIuMTMzTDExMy43MzggODUuNDY3OUMxMTMuODg5IDg1LjI5NTYgMTEzLjk3OCA4NS4wOTI5IDExMy45OTYgODQuODgyQzExNC4wMTUgODQuNjcxMSAxMTMuOTYxIDg0LjQ2MDMgMTEzLjg0MSA4NC4yNzI2QzExMy43MjIgODQuMDg0NyAxMTMuNTQxIDgzLjkyNzIgMTEzLjMxOCA4My44MTczQzExMy4wOTYgODMuNzA3NCAxMTIuODQxIDgzLjY0OTUgMTEyLjU4IDgzLjY0OThIMTA1LjcxMkwxMDUuNzEyIDU5LjYwMTZDMTA1LjcxMyA1OS40NTA1IDEwNS42NzYgNTkuMzAwNyAxMDUuNjA1IDU5LjE2MTFDMTA1LjUzMyA1OS4wMjE0IDEwNS40MjkgNTguODk0NSAxMDUuMjk3IDU4Ljc4NzZDMTA1LjE2NSA1OC42ODA3IDEwNS4wMDkgNTguNTk1OSAxMDQuODM3IDU4LjUzODFDMTA0LjY2NSA1OC40ODAzIDEwNC40OCA1OC40NTA3IDEwNC4yOTQgNTguNDUwOEw5MS41ODYyIDU4LjQ1MTJDOTEuMzk5OSA1OC40NTEyIDkxLjIxNTQgNTguNDgwOSA5MS4wNDMyIDU4LjUzODhDOTAuODcxMSA1OC41OTY3IDkwLjcxNDYgNTguNjgxNSA5MC41ODI5IDU4Ljc4ODVDOTAuNDUxMiA1OC44OTU1IDkwLjM0NjcgNTkuMDIyNCA5MC4yNzU1IDU5LjE2MjJDOTAuMjA0MiA1OS4zMDIgOTAuMTY3NyA1OS40NTE4IDkwLjE2NzggNTkuNjAzVjgzLjY0OTRIODMuMjk3MkM4Mi43NjczIDgzLjY0OTQgODIuMjgwOCA4My44OTE5IDgyLjAzNjEgODQuMjc0OUM4MS45MTY2IDg0LjQ2MzEgODEuODYzNSA4NC42NzQ1IDgxLjg4MjcgODQuODg1N0M4MS45MDE5IDg1LjA5NjggODEuOTkyNiA4NS4yOTk2IDgyLjE0NDkgODUuNDcxNVoiIGZpbGw9ImJsYWNrIi8+Cjwvc3ZnPgo=',
283 + 999
234 284 );
235 285
236 286 $this->hook_suffix[] = add_submenu_page(
237 287 $this->token . '-admin-ui',
@@ -241,9 +291,9 @@
241 291 $this->token . '-admin-ui' ,
242 292 array($this, 'adminUi')
243 293 );
244 294
245 - if(Utils::is_service_enabled()) {
295 + if(Utils::get_service()) {
246 296 $this->hook_suffix[] = add_submenu_page(
247 297 $this->token . '-admin-ui',
248 298 esc_html__('Settings', 'media-cloud-sync'),
249 299 esc_html__('Settings', 'media-cloud-sync'),
@@ -263,8 +313,32 @@
263 313 }
264 314 }
265 315
266 316 /**
317 + * Admin notice when storage credentials are incomplete.
318 + * @since 1.3.11
319 + */
320 + public function storage_credentials_admin_notice() {
321 + if(!current_user_can('manage_options') || !Utils::get_service() || Utils::is_service_enabled()) {
322 + return;
323 + }
324 +
325 + $error = Utils::get_service_configuration_error();
326 + if(empty($error)) {
327 + return;
328 + }
329 +
330 + $settings_url = admin_url('admin.php?page=' . $this->token . '-admin-ui#/settings');
331 + $message = esc_html($error) . ' ' . sprintf(
332 + '<a href="%1$s">%2$s</a>',
333 + esc_url($settings_url),
334 + esc_html__('Open Media Cloud Sync settings', 'media-cloud-sync')
335 + );
336 +
337 + echo wp_kses_post(sprintf('<div class="notice notice-error is-dismissible"><p>%s</p></div>', $message));
338 + }
339 +
340 + /**
267 341 * Calling view function for admin page components
268 342 */
269 343 public function adminUi() {
270 344 echo wp_kses_post(sprintf(
@@ -286,8 +360,12 @@
286 360 /**
287 361 * Load the media assets
288 362 */
289 363 public function load_media_assets() {
364 + if(!Utils::is_service_enabled()) {
365 + return;
366 + }
367 +
290 368 /** CSS */
291 369 wp_enqueue_style($this->token . '-media', esc_url($this->assets_url) . 'css/media.css', array(), $this->version);
292 370
293 371 /** JS */
@@ -336,12 +414,12 @@
336 414 <div id="dw-wpmcs-survey-form">
337 415 <h2>We Value Your Feedback</h2>
338 416 <p>We're sorry to see you go! Please let us know why you are deactivating this plugin. Your feedback is anonymous and will help us improve.</p>
339 417 <form method="POST">
340 - <input name="plugin_name" type="hidden" value="<?= $this->token ?>" required>
341 - <input name="website" type="hidden" value="<?= get_site_url(); ?>" required>
342 - <input name="title" type="hidden" value="<?= get_bloginfo('name'); ?>" required>
343 - <input name="version" type="hidden" value="<?= $this->version; ?>" required>
418 + <input name="plugin_name" type="hidden" value="<?= esc_attr($this->token); ?>" required>
419 + <input name="website" type="hidden" value="<?= esc_url(get_site_url()); ?>" required>
420 + <input name="title" type="hidden" value="<?= esc_attr(get_bloginfo('name')); ?>" required>
421 + <input name="version" type="hidden" value="<?= esc_attr($this->version); ?>" required>
344 422
345 423 <div class="dw-wpmcs-reason">
346 424 <label><input type="radio" name="reason" value="I\'m only deactivating temporarily"> I'm only deactivating temporarily</label>
347 425 <label><input type="radio" name="reason" value="I no longer need the plugin"> I no longer need the plugin</label>
@@ -359,13 +437,20 @@
359 437 <textarea name="comments" placeholder="Please specify" rows="3"></textarea>
360 438 <p>Need help? <a href="https://dudlewebs.com/" target="_blank">Use live chat support</a></p>
361 439 </div>
362 440
363 - <p id="dw-wpmcs-error" class="dw-wpmcs-error"></p>
441 + <p id="dw-wpmcs-error" class="dw-wpmcs-error">
442 + <svg viewBox="0 0 16 16" fill="none" aria-hidden="true">
443 + <path d="M8 2.2L14.6 13.3H1.4L8 2.2Z" stroke="currentColor" stroke-width="1.3" stroke-linejoin="round"/>
444 + <path d="M8 6.7V9.7" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/>
445 + <circle cx="8" cy="11.4" r="0.85" fill="currentColor"/>
446 + </svg>
447 + <span id="dw-wpmcs-error-text"></span>
448 + </p>
364 449 <div class="dw-wpmcs-actions">
450 + <button type="button" class="dw-button dw-skip" id="dw-wpmcs-skip">Skip & Deactivate</button>
451 + <button type="button" class="dw-button dw-secondary" id="dw-wpmcs-cancel">Cancel</button>
365 452 <button type="submit" class="dw-button dw-primary" id="dw-wpmcs-deactivate">Submit & Deactivate</button>
366 - <button type="button" class="dw-button dw-secondary" id="dw-wpmcs-cancel">Cancel</button>
367 - <button type="button" class="dw-button dw-skip" id="dw-wpmcs-skip">Skip & Deactivate</button>
368 453 </div>
369 454 </form>
370 455 </div>
371 456 </div>