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
media-cloud-sync / includes / admin.php

admin.php in Media Cloud Sync trunk, at includes/admin.php

504 lines 25.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Dudlewebs\WPMCS;
3
4 defined('ABSPATH') || exit;
5
6 use WP_Site;
7 class Admin {
8 private static $instance = null;
9 private $assets_url;
10 private $version;
11 private $token;
12 private $script_suffix;
13
14 protected $hook_suffix = [];
15 /**
16 * Admin constructor.
17 * @since 1.0.0
18 */
19 public function __construct() {
20 $this->assets_url = WPMCS_ASSETS_URL;
21 $this->version = WPMCS_VERSION;
22 $this->token = WPMCS_TOKEN;
23 $this->script_suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
24
25 $plugin = plugin_basename(WPMCS_FILE);
26
27 // Create file directory on action do
28 add_action( $this->token.'_create_plugin_dir', [ $this, 'create_plugin_dir' ] );
29
30 // add action links to link to link list display on the plugins page.
31 add_filter("plugin_action_links_$plugin", [$this, 'plugin_action_links']);
32
33 // add our custom CSS classes to <body>
34 add_filter( 'admin_body_class', [ $this, 'admin_body_class' ] );
35 // Admin Init
36 add_action('admin_init', [$this, 'adminInit']);
37
38 add_action('admin_menu', [$this, 'add_menu'], 10);
39 add_action('admin_notices', [$this, 'storage_credentials_admin_notice']);
40
41 add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts'], 10, 1);
42 add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_styles'], 10, 1);
43 // Load media scripts
44 add_action( 'load-upload.php', [ $this, 'load_media_assets' ], 11 );
45
46 // Plugin Deactivation Survey
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 }
54 }
55
56 /**
57 * Method that is used on plugin initialization time
58 * @since 1.0.0
59 */
60 public function adminInit() {
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();
72 }
73
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 }
88 }
89 }
90
91 /**
92 * Installation. Runs on activation.
93 *
94 * @access public
95 * @return void
96 * @since 1.0.0
97 */
98 public static function install($network_wide = false) {
99 Db::handle_tables($network_wide);
100
101 // Redirection on activation
102 add_option(WPMCS_TOKEN . '_do_activation_redirect', true);
103
104 //Protect directories
105 self::_protect_upload_dir();
106 }
107
108 /**
109 * Create plugin specific upload directory
110 * @since 1.0.0
111 */
112 public function create_plugin_dir() {
113 //Protect directories
114 self::_protect_upload_dir();
115 }
116
117 /**
118 * Protect Directory from external access.
119 *
120 * @access private
121 * @return void
122 * @since 1.3.0
123 * @see \Dudlewebs\WPMCS\Admin::_protect_upload_dir
124 */
125 private static function _protect_upload_dir(){
126 $upload_dir = wp_upload_dir();
127
128 $upload_base = $upload_dir['basedir'] . '/' . Schema::getConstant('UPLOADS');
129
130 $files = array(
131 array(
132 'base' => $upload_base,
133 'file' => '.htaccess',
134 'content' => "Options -Indexes\nDeny from all"
135 ),
136 array(
137 'base' => $upload_base,
138 'file' => 'index.php',
139 'content' => "<?php\n// Silence is golden."
140 )
141 );
142
143 foreach ($files as $file) {
144 if ((wp_mkdir_p($file['base'])) && (!file_exists(trailingslashit($file['base']) . $file['file'])) // If file not exist
145 ) {
146 if ($file_handle = @fopen(trailingslashit($file['base']) . $file['file'], 'w')) {
147 fwrite($file_handle, $file['content']);
148 fclose($file_handle);
149 }
150 }
151 }
152 }
153
154 /**
155 * Deactivation hook
156 */
157 public static function deactivation(){
158 }
159
160
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 /**
179 * Load admin Javascript.
180 * @access public
181 * @return void
182 * @since 1.0.0
183 */
184 public function admin_enqueue_scripts($hook = '') {
185 if (!isset($this->hook_suffix) || empty($this->hook_suffix)) {
186 return;
187 }
188
189 $screen = get_current_screen();
190
191 // deactivate form js
192 if ($screen->id == 'plugins') {
193 wp_enqueue_script($this->token . '-deactivate-form', esc_url($this->assets_url) . 'js/deactivate.js', array('jquery'), $this->version, true);
194 }
195
196
197 if (in_array($screen->id, $this->hook_suffix, true)) {
198 // Enqueue WordPress media scripts.
199 if (!did_action('wp_enqueue_media')) {
200 wp_enqueue_media();
201 }
202
203 // Enqueue custom backend script.
204 wp_enqueue_script($this->token . '-backend', esc_url($this->assets_url) . 'js/backend.js', array('wp-i18n'), $this->version, true);
205
206 // Localize a script.
207 wp_localize_script(
208 $this->token . '-backend',
209 $this->token . '_object',
210 array(
211 'api_nonce' => wp_create_nonce('wp_rest'),
212 'root' => rest_url($this->token . '/v1/'),
213 'pro_root' => rest_url($this->token . '/pro/v1/'),
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() : [],
220 )
221 );
222 }
223 }
224
225
226
227 /**
228 * Load admin CSS.
229 * @access public
230 * @return void
231 * @since 1.0.0
232 */
233 public function admin_enqueue_styles($hook = '') {
234 if ( ! isset($this->hook_suffix) || empty($this->hook_suffix)) {
235 return;
236 }
237 $screen = get_current_screen();
238 if (in_array($screen->id, $this->hook_suffix)) {
239 wp_register_style($this->token.'-backend',
240 esc_url($this->assets_url).'css/backend.css?nocache='.rand(0, 10000), array(), $this->version);
241 wp_enqueue_style($this->token.'-backend');
242 }
243
244 if ($screen->id == 'plugins') {
245 wp_enqueue_style($this->token . '-deactivate-form', esc_url($this->assets_url) . 'css/deactivate.css', array(), $this->version);
246 }
247 }
248
249 /**
250 * Show action links on the plugin screen.
251 *
252 * @param mixed $links Plugin Action links.
253 *
254 * @return array
255 */
256 public function plugin_action_links($links){
257 $action_links = array(
258 'getstarted' => '<a href="' . admin_url('admin.php?page=' . $this->token . '-admin-ui#/configure') . '">' . esc_html__('Get Started', 'media-cloud-sync') . '</a>',
259 'settings' => '<a href="' . admin_url('admin.php?page=' . $this->token . '-admin-ui/') . '">' . esc_html__('Settings', 'media-cloud-sync') . '</a>',
260 );
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
266 return array_merge($action_links, $links);
267 }
268
269
270
271
272 /**
273 * Add Admin Menu
274 */
275 public function add_menu() {
276 $this->hook_suffix[] = add_menu_page(
277 esc_html__('Media Cloud Sync', 'media-cloud-sync'),
278 esc_html__('Media Cloud Sync', 'media-cloud-sync'),
279 'manage_options',
280 $this->token.'-admin-ui',
281 array($this, 'adminUi'),
282 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTczIiBoZWlnaHQ9IjEyMiIgdmlld0JveD0iMCAwIDE3MyAxMjIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xMzkuNTggNzYuMDA4MkMxNDYuNDQxIDc1LjgyMyAxNTEuOTAyIDc4LjgxNTggMTU2LjE3OSA4My44NzkzQzE2MS42OTUgOTAuNDA5OCAxNjEuMzQ5IDk4LjY5MjEgMTU1LjkyMyAxMDUuMzI0QzE1Mi40ODUgMTA5LjUyNiAxNDYuOTI5IDExMC42OTMgMTQyLjIwNyAxMDguMTZDMTM5LjU4OSAxMDYuNzU1IDEzNy45NDIgMTA0LjUxIDEzNy4wMzEgMTAxLjcwMUMxMzYuNzc0IDEwMC45MDYgMTM3LjA3MiAxMDAuNjE1IDEzNy44NSAxMDAuNjMxQzEzOC41OTggMTAwLjY0NyAxMzkuMzQ3IDEwMC42MzUgMTQwLjQ0NCAxMDAuNjM1QzE0MS43MDkgMTAwLjUyMSAxNDMuMTc4IDEwMC44MTggMTQ0LjY3MiAxMDEuNThDMTQ3Ljc2NyAxMDMuMTU5IDE1Mi4xNTcgMTAxLjY1OCAxNTMuOTY1IDk4LjYwNTlDMTU2LjA3OSA5NS4wMzcgMTU1LjQxMSA5MS4wMDY3IDE1Mi4zMjkgODguNzM2N0MxNDguNTkgODUuOTgyOSAxNDQuNDg0IDg2LjQzNzggMTQxLjM0NyA4OS44OTg4QzEzOS41NzUgOTEuODUzNyAxMzcuMzYzIDkzLjAwNDMgMTM0LjcwMiA5My4yMDk0QzEzMC4zNjUgOTMuNTQzNiAxMjcuMzE1IDg5Ljk3OTIgMTI4LjEzMyA4NS41Mzg1QzEyOS4xMjUgODAuMTU4NSAxMzMuOTE2IDc2LjE2MTEgMTM5LjU4IDc2LjAwODJaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQyLjIxNyA5NC4xMzMyQzE0Mi42MjQgOTQuMTMzMiAxNDIuOTU1IDk0LjQ2MzMgMTQyLjk1NSA5NC44NzA1Vjk5LjY3OTFDMTQyLjk1NSAxMDAuMDg2IDE0Mi42MjQgMTAwLjQxNSAxNDIuMjE3IDEwMC40MTVIMTM3LjU1OEMxMzcuMTUxIDEwMC40MTUgMTM2LjgyMSAxMDAuMDg2IDEzNi44MiA5OS42NzkxVjk0Ljg3MDVDMTM2LjgyIDk0LjQ2MzMgMTM3LjE1IDk0LjEzMzIgMTM3LjU1OCA5NC4xMzMySDE0Mi4yMTdaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQ5LjE5NyA5NC4xMzQyQzE0OS42MDUgOTQuMTM0MiAxNDkuOTM2IDk0LjQ2NDMgMTQ5LjkzNiA5NC44NzE1Vjk2LjU3NTZDMTQ5LjkzNiA5Ni45ODI4IDE0OS42MDUgOTcuMzEyOSAxNDkuMTk3IDk3LjMxMjlIMTQ3LjU2OUMxNDcuMTYxIDk3LjMxMjkgMTQ2LjgzMSA5Ni45ODI4IDE0Ni44MzEgOTYuNTc1NlY5NC44NzE1QzE0Ni44MzEgOTQuNDY0MyAxNDcuMTYxIDk0LjEzNDIgMTQ3LjU2OSA5NC4xMzQySDE0OS4xOTdaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBkPSJNMTQ1LjMzMiA5NC4xMzMyQzE0NS43MzkgOTQuMTMzNSAxNDYuMDcgOTQuNDYzNSAxNDYuMDcgOTQuODcwNVY5NS44MDUxQzE0Ni4wNyA5Ni4yMTIxIDE0NS43MzkgOTYuNTQyMSAxNDUuMzMyIDk2LjU0MjRIMTQ0LjQ1NEMxNDQuMDQ3IDk2LjU0MjQgMTQzLjcxNyA5Ni4yMTIzIDE0My43MTcgOTUuODA1MVY5NC44NzA1QzE0My43MTcgOTQuNDYzMyAxNDQuMDQ3IDk0LjEzMzIgMTQ0LjQ1NCA5NC4xMzMySDE0NS4zMzJaIiBmaWxsPSJibGFjayIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE3MyA5Mi41MDAxQzE3MyAxMDguMjQgMTYwLjI0IDEyMSAxNDQuNSAxMjFDMTI4Ljc2IDEyMSAxMTYgMTA4LjI0IDExNiA5Mi41MDAxQzExNiA3Ni43NiAxMjguNzYgNjQuMDAwMSAxNDQuNSA2NC4wMDAxQzE2MC4yNCA2NC4wMDAxIDE3MyA3Ni43NiAxNzMgOTIuNTAwMVpNMTQ0LjUgMTE0QzE1Ni4zNzQgMTE0IDE2NiAxMDQuMzc0IDE2NiA5Mi41MDAxQzE2NiA4Ni43MDIyIDE2My43MDUgODEuNDQwMyAxNTkuOTc0IDc3LjU3MzNDMTU2LjA2NCA3My41MjA3IDE1MC41NzYgNzEuMDAwMSAxNDQuNSA3MS4wMDAxQzEzMi42MjYgNzEuMDAwMSAxMjMgODAuNjI2IDEyMyA5Mi41MDAxQzEyMyAxMDAuNTQzIDEyNy40MTYgMTA3LjU1NCAxMzMuOTU2IDExMS4yNDFDMTM3LjA3MSAxMTIuOTk4IDE0MC42NjkgMTE0IDE0NC41IDExNFoiIGZpbGw9ImJsYWNrIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzUuMjY1OSA0My40MTY4QzM3LjI3OTMgMzEuMjg3IDQzLjUzMjQgMjAuMjY1NSA1Mi45MTE3IDEyLjMxNDdDNjIuMjkxIDQuMzYzOTEgNzQuMTg3NyAwIDg2LjQ4MzUgMEM5OC43NzkzIDAgMTEwLjY3NiA0LjM2MzkxIDEyMC4wNTUgMTIuMzE0N0MxMjkuNDM1IDIwLjI2NTUgMTM1LjY4OCAzMS4yODcgMTM3LjcwMSA0My40MTY4QzE0Ny42NjIgNDQuMzU5IDE1Ni44NzcgNDkuMDk5NiAxNjMuNDM1IDU2LjY1NTFDMTY5Ljk5NCA2NC4yMTA2IDE3My4zOTIgNzQuMDAwOSAxNzIuOTI0IDgzLjk5NDlDMTcyLjQ1NyA5My45ODg5IDE2OC4xNiAxMDMuNDE5IDE2MC45MjUgMTEwLjMzQzE1My42OSAxMTcuMjQgMTQ0LjA3MiAxMjEuMSAxMzQuMDY3IDEyMS4xMDhIMzguODk5NkMyOC44OTQ3IDEyMS4xIDE5LjI3NyAxMTcuMjQgMTIuMDQyIDExMC4zM0M0LjgwNjk1IDEwMy40MTkgMC41MDk5NzUgOTMuOTg4OSAwLjA0MjU0OTUgODMuOTk0OUMtMC40MjQ4NzYgNzQuMDAwOSAyLjk3MzEzIDY0LjIxMDYgOS41MzE1OSA1Ni42NTUxQzE2LjA5IDQ5LjA5OTYgMjUuMzA1NSA0NC4zNTkgMzUuMjY1OSA0My40MTY4Wk00Mi45NzE1IDQ1LjkyNTJDNDQuNjgyNyAzNS42MDkgNDkuOTk3IDI2LjIzNTQgNTcuOTY4MiAxOS40NzM1QzY1LjkzOTQgMTIuNzExNSA3Ni4wNTAxIDkuMDAwMSA4Ni40OTk5IDkuMDAwMUM5Ni45NDk4IDkuMDAwMSAxMDcuMDYgMTIuNzExNSAxMTUuMDMyIDE5LjQ3MzVDMTIzLjAwMyAyNi4yMzU0IDEyOC4zMTcgMzUuNjA5IDEzMC4wMjggNDUuOTI1MkMxMzguNDkzIDQ2LjcyNjUgMTQ2LjMyNSA1MC43NTgzIDE1MS44OTkgNTcuMTg0QzE1Ni44NDUgNjIuODg2MSAxNTkuNjc2IDcwLjA4NDkgMTU5Ljk3NCA3Ny41NzMzQzE2My43MDUgODEuNDQwMyAxNjYgODYuNzAyMiAxNjYgOTIuNTAwMUMxNjYgMTA0LjM3NCAxNTYuMzc0IDExNCAxNDQuNSAxMTRDMTQwLjY2OSAxMTQgMTM3LjA3MSAxMTIuOTk4IDEzMy45NTYgMTExLjI0MUMxMzEuNjY4IDExMS43NCAxMjkuMzE3IDExMS45OTggMTI2Ljk0IDExMkg0Ni4wNTk3QzM3LjU1NjggMTExLjk5MyAyOS4zODI5IDEwOC43MSAyMy4yMzQxIDEwMi44MzNDMTcuMDg1MiA5Ni45NTYxIDEzLjQzMzMgODguOTM1NyAxMy4wMzYxIDgwLjQzNkMxMi42Mzg4IDcxLjkzNjMgMTUuNTI2NyA2My42MDk4IDIxLjEwMDYgNTcuMTg0QzI2LjY3NDQgNTAuNzU4MyAzNC41MDY0IDQ2LjcyNjUgNDIuOTcxNSA0NS45MjUyWiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTkzLjUyMTEgNDEuMTc0OEw3Ny4xNDE3IDE4LjY1MDJDNzYuOTk1MyAxOC40NDk1IDc2LjgwMjUgMTguMjg1OCA3Ni41NzkyIDE4LjE3MjhDNzYuMzU1OSAxOC4wNTk4IDc2LjEwODUgMTguMDAwNiA3NS44NTc0IDE4LjAwMDJINzUuODUzNkM3NS42MDE1IDE4LjAwMDcgNzUuMzUzMiAxOC4wNjA0IDc1LjEyOTMgMTguMTc0M0M3NC45MDU0IDE4LjI4ODIgNzQuNzEyMyAxOC40NTMxIDc0LjU2NjEgMTguNjU1Mkw1OC4yOTI0IDQxLjE3OTdDNTguMTI0IDQxLjQxMjUgNTguMDI0MSA0MS42ODY1IDU4LjAwMzggNDEuOTcxNUM1Ny45ODM1IDQyLjI1NjYgNTguMDQzNSA0Mi41NDE2IDU4LjE3NzMgNDIuNzk1MkM1OC4zMTAzIDQzLjA0OTIgNTguNTExOCA0My4yNjIxIDU4Ljc1OTggNDMuNDEwN0M1OS4wMDc4IDQzLjU1OTIgNTkuMjkyNyA0My42Mzc1IDU5LjU4MyA0My42MzdINjcuMjQxOEw2Ny4yNDEyIDc2LjE0MUM2Ny4yNDExIDc2LjM0NTQgNjcuMjgxOSA3Ni41NDc3IDY3LjM2MTQgNzYuNzM2NUM2Ny40NDA5IDc2LjkyNTMgNjcuNTU3NCA3Ny4wOTY5IDY3LjcwNDMgNzcuMjQxM0M2Ny44NTEyIDc3LjM4NTggNjguMDI1NiA3Ny41MDA0IDY4LjIxNzUgNzcuNTc4NUM2OC40MDk0IDc3LjY1NjYgNjguNjE1MSA3Ny42OTY3IDY4LjgyMjggNzcuNjk2Nkw4Mi45OTMxIDc3LjY5NTlDODMuMjAwOSA3Ny42OTYgODMuNDA2NyA3Ny42NTU4IDgzLjU5ODcgNzcuNTc3NkM4My43OTA2IDc3LjQ5OTQgODMuOTY1MSA3Ny4zODQ3IDg0LjExMiA3Ny4yNDAxQzg0LjI1ODkgNzcuMDk1NSA4NC4zNzUzIDc2LjkyMzkgODQuNDU0OCA3Ni43MzVDODQuNTM0MiA3Ni41NDYxIDg0LjU3NSA3Ni4zNDM2IDg0LjU3NDggNzYuMTM5MlY0My42Mzc2SDkyLjIzNjFDOTIuODI3IDQzLjYzNzYgOTMuMzY5NiA0My4zMDk4IDkzLjY0MjQgNDIuNzkyMUM5My43NzU3IDQyLjUzNzcgOTMuODM0OSA0Mi4yNTIgOTMuODEzNSA0MS45NjY2QzkzLjc5MjEgNDEuNjgxMiA5My42OTA5IDQxLjQwNzEgOTMuNTIxMSA0MS4xNzQ4WiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTgyLjE0NDkgODUuNDcxNUw5Ni44MzM4IDEwMi4xMzZDOTYuOTY1IDEwMi4yODUgOTcuMTM3OSAxMDIuNDA2IDk3LjMzODIgMTAyLjQ5Qzk3LjUzODQgMTAyLjU3MyA5Ny43NjAzIDEwMi42MTcgOTcuOTg1NSAxMDIuNjE3Qzk4LjIxMTYgMTAyLjYxNyA5OC40Mzc3IDEwMi41NzMgOTguNjM4NSAxMDIuNDg4Qzk4LjgzOTMgMTAyLjQwNCA5OS4wMTI0IDEwMi4yODIgOTkuMTQzNSAxMDIuMTMzTDExMy43MzggODUuNDY3OUMxMTMuODg5IDg1LjI5NTYgMTEzLjk3OCA4NS4wOTI5IDExMy45OTYgODQuODgyQzExNC4wMTUgODQuNjcxMSAxMTMuOTYxIDg0LjQ2MDMgMTEzLjg0MSA4NC4yNzI2QzExMy43MjIgODQuMDg0NyAxMTMuNTQxIDgzLjkyNzIgMTEzLjMxOCA4My44MTczQzExMy4wOTYgODMuNzA3NCAxMTIuODQxIDgzLjY0OTUgMTEyLjU4IDgzLjY0OThIMTA1LjcxMkwxMDUuNzEyIDU5LjYwMTZDMTA1LjcxMyA1OS40NTA1IDEwNS42NzYgNTkuMzAwNyAxMDUuNjA1IDU5LjE2MTFDMTA1LjUzMyA1OS4wMjE0IDEwNS40MjkgNTguODk0NSAxMDUuMjk3IDU4Ljc4NzZDMTA1LjE2NSA1OC42ODA3IDEwNS4wMDkgNTguNTk1OSAxMDQuODM3IDU4LjUzODFDMTA0LjY2NSA1OC40ODAzIDEwNC40OCA1OC40NTA3IDEwNC4yOTQgNTguNDUwOEw5MS41ODYyIDU4LjQ1MTJDOTEuMzk5OSA1OC40NTEyIDkxLjIxNTQgNTguNDgwOSA5MS4wNDMyIDU4LjUzODhDOTAuODcxMSA1OC41OTY3IDkwLjcxNDYgNTguNjgxNSA5MC41ODI5IDU4Ljc4ODVDOTAuNDUxMiA1OC44OTU1IDkwLjM0NjcgNTkuMDIyNCA5MC4yNzU1IDU5LjE2MjJDOTAuMjA0MiA1OS4zMDIgOTAuMTY3NyA1OS40NTE4IDkwLjE2NzggNTkuNjAzVjgzLjY0OTRIODMuMjk3MkM4Mi43NjczIDgzLjY0OTQgODIuMjgwOCA4My44OTE5IDgyLjAzNjEgODQuMjc0OUM4MS45MTY2IDg0LjQ2MzEgODEuODYzNSA4NC42NzQ1IDgxLjg4MjcgODQuODg1N0M4MS45MDE5IDg1LjA5NjggODEuOTkyNiA4NS4yOTk2IDgyLjE0NDkgODUuNDcxNVoiIGZpbGw9ImJsYWNrIi8+Cjwvc3ZnPgo=',
283 999
284 );
285
286 $this->hook_suffix[] = add_submenu_page(
287 $this->token . '-admin-ui',
288 esc_html__('Dashboard', 'media-cloud-sync'),
289 esc_html__('Dashboard', 'media-cloud-sync'),
290 'manage_options',
291 $this->token . '-admin-ui' ,
292 array($this, 'adminUi')
293 );
294
295 if(Utils::get_service()) {
296 $this->hook_suffix[] = add_submenu_page(
297 $this->token . '-admin-ui',
298 esc_html__('Settings', 'media-cloud-sync'),
299 esc_html__('Settings', 'media-cloud-sync'),
300 'manage_options',
301 $this->token . '-admin-ui#/settings' ,
302 array($this, 'adminUi')
303 );
304 } else {
305 $this->hook_suffix[] = add_submenu_page(
306 $this->token . '-admin-ui',
307 esc_html__('Configure', 'media-cloud-sync'),
308 esc_html__('Configure', 'media-cloud-sync'),
309 'manage_options',
310 $this->token . '-admin-ui#/configure' ,
311 array($this, 'adminUi')
312 );
313 }
314 }
315
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 /**
341 * Calling view function for admin page components
342 */
343 public function adminUi() {
344 echo wp_kses_post(sprintf(
345 '<div id="%s_ui_root">
346 <div class="%s_loader">
347 <h1>%s</h1>
348 <p>%s</p>
349 </div>
350 </div>',
351 $this->token,
352 $this->token,
353 esc_html__('Media Cloud Sync By Dudlewebs','media-cloud-sync'),
354 esc_html__('Plugin is loading Please wait for a while..', 'media-cloud-sync')
355 ));
356
357 }
358
359
360 /**
361 * Load the media assets
362 */
363 public function load_media_assets() {
364 if(!Utils::is_service_enabled()) {
365 return;
366 }
367
368 /** CSS */
369 wp_enqueue_style($this->token . '-media', esc_url($this->assets_url) . 'css/media.css', array(), $this->version);
370
371 /** JS */
372 wp_enqueue_script(
373 $this->token . '-media',
374 esc_url($this->assets_url) . 'js/media.js',
375 array(
376 'jquery',
377 'media-views',
378 'media-grid',
379 'wp-util'
380 ),
381 $this->version,
382 true
383 );
384
385 // Localize a script.
386 wp_localize_script(
387 $this->token . '-media',
388 $this->token . '_media_object',
389 array(
390 'file_details_nonce' => wp_create_nonce('get_media_provider_details'),
391 'admin_ajax_url' => admin_url('admin-ajax.php'),
392 'strings' => array(
393 'provider' => esc_html__("Provider: ", "media-cloud-sync"),
394 'region' => esc_html__("Region: ", "media-cloud-sync"),
395 'access' => esc_html__("Access: ", "media-cloud-sync"),
396 'access_private' => esc_html__("Private", "media-cloud-sync"),
397 'access_public' => esc_html__("Public", "media-cloud-sync"),
398 )
399 )
400 );
401 }
402
403
404 /**
405 * Deactivation form
406 * @since 1.0.2
407 */
408 public function wpmcs_deactivation_form() {
409 $currentScreen = get_current_screen();
410 $screenID = $currentScreen->id;
411 if ($screenID == 'plugins') {
412 ?>
413 <div id="dw-wpmcs-survey-form-wrap">
414 <div id="dw-wpmcs-survey-form">
415 <h2>We Value Your Feedback</h2>
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>
417 <form method="POST">
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>
422
423 <div class="dw-wpmcs-reason">
424 <label><input type="radio" name="reason" value="I\'m only deactivating temporarily"> I'm only deactivating temporarily</label>
425 <label><input type="radio" name="reason" value="I no longer need the plugin"> I no longer need the plugin</label>
426 <label><input type="radio" name="reason" value="I only needed the plugin for a short period"> I only needed the plugin for a short period</label>
427 <label><input type="radio" name="reason" value="I found a better plugin"> I found a better plugin</label>
428 <label><input type="radio" name="reason" value="Upgrading to PRO version"> Upgrading to PRO version</label>
429 <label><input type="radio" name="reason" value="Plugin doesn\'t meet my requirements"> Plugin doesn't meet my requirements</label>
430 <label><input type="radio" name="reason" value="Plugin broke my site"> Plugin broke my site</label>
431 <label><input type="radio" name="reason" value="Plugin suddenly stopped working"> Plugin suddenly stopped working</label>
432 <label><input type="radio" name="reason" value="I found a bug"> I found a bug</label>
433 <label><input type="radio" name="reason" value="Other"> Other</label>
434 </div>
435
436 <div class="dw-wpmcs-comments" style="display:none;">
437 <textarea name="comments" placeholder="Please specify" rows="3"></textarea>
438 <p>Need help? <a href="https://dudlewebs.com/" target="_blank">Use live chat support</a></p>
439 </div>
440
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>
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>
452 <button type="submit" class="dw-button dw-primary" id="dw-wpmcs-deactivate">Submit & Deactivate</button>
453 </div>
454 </form>
455 </div>
456 </div>
457 <?php }
458 }
459
460
461
462 /**
463 * Add custom classes to the HTML body tag
464 *
465 * @param string $classes
466 *
467 * @return string
468 */
469 public function admin_body_class( $classes ) {
470 if ( ! $classes ) {
471 $classes = array();
472 } else {
473 $classes = explode( ' ', $classes );
474 }
475 $classes[] = $this->token.'_page';
476 /**
477 * Recommended way to target WP 3.8+
478 * http://make.wordpress.org/ui/2013/11/19/targeting-the-new-dashboard-design-in-a-post-mp6-world/
479 *
480 */
481 if ( version_compare( $GLOBALS['wp_version'], '3.8-alpha', '>' ) ) {
482 if ( ! in_array( 'mp6', $classes ) ) {
483 $classes[] = 'mp6';
484 }
485 }
486 return implode( ' ', $classes );
487 }
488
489
490 /**
491 * Ensures only one instance of Class is loaded or can be loaded.
492 *
493 * @return Main Class instance
494 * @since 1.0.0
495 * @static
496 */
497 public static function instance(){
498 if (is_null(self::$instance)) {
499 self::$instance = new self();
500 }
501 return self::$instance;
502 }
503
504 }