PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.42
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.42
5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 5.5.42 5.5.43 All 159 releases
wp-data-access / includes / class-wp-data-access.php

class-wp-data-access.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.42, at includes/class-wp-data-access.php

504 lines 21.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 *
6 * @package plugin\includes
7 */
8 use WPDataAccess\Connection\WPDADB;
9 use WPDataAccess\Cookies\WPDA_Cookies;
10 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Lists;
11 use WPDataAccess\Data_Tables\WPDA_Data_Tables;
12 use WPDataAccess\Utilities\WPDA_Table_Actions;
13 use WPDataAccess\Utilities\WPDA_Export;
14 use WPDataAccess\Utilities\WPDA_Favourites;
15 use WPDataAccess\WPDA;
16 use WPDataProjects\Utilities\WPDP_Export_Project;
17 use WPDataAccess\Backup\WPDA_Data_Export;
18 use WPDataAccess\Plugin_Table_Models\WPDA_CSV_Uploads_Model;
19 use WPDataRoles\WPDA_Roles;
20 use WPDataAccess\Utilities\WPDA_Autocomplete;
21 use WPDataAccess\Premium\WPDAPRO_Geo_Location\WPDAPRO_Geo_Location_WS;
22 use WPDataAccess\Premium\WPDAPRO_Geo_Location\WPDAPRO_Geo_Location;
23 use WPDataAccess\Query_Builder\WPDA_Query_Builder;
24 use WPDataAccess\Dashboard\WPDA_Dashboard;
25 use WPDataAccess\Dashboard\WPDA_Widget_Code;
26 use WPDataAccess\Dashboard\WPDA_Widget_Publication;
27 use WPDataAccess\Dashboard\WPDA_Widget_Dbms;
28 use WPDataAccess\Dashboard\WPDA_Widget_Google_Chart;
29 use WPDataAccess\Premium\WPDAPRO_Dashboard\WPDAPRO_Widget_Project;
30 /**
31 * Class WP_Data_Access
32 *
33 * Core plugin class used to define:
34 * + admin specific functionality {@see WP_Data_Access_Admin}
35 * + public specific functionality {@see WP_Data_Access_Public}
36 * + internationalization {@see WP_Data_Access_I18n}
37 * + plugin activation and deactivation {@see WP_Data_Access_Loader}
38 *
39 * @author Peter Schulz
40 * @since 1.0.0
41 *
42 * @see WP_Data_Access_Admin
43 * @see WP_Data_Access_Public
44 * @see WP_Data_Access_I18n
45 * @see WP_Data_Access_Loader
46 */
47 class WP_Data_Access {
48 /**
49 * Reference to plugin loader
50 *
51 * @var WP_Data_Access_Loader
52 *
53 * @since 1.0.0
54 *
55 * @see WP_Data_Access_Loader
56 */
57 protected $loader;
58
59 /**
60 * Menu slug or null
61 *
62 * @var null
63 */
64 protected $page = null;
65
66 /**
67 * WP_Data_Access constructor
68 *
69 * Calls method the following methods to setup plugin:
70 * + {@see WP_Data_Access::load_dependencies()}
71 * + {@see WP_Data_Access::set_locale()}
72 * + {@see WP_Data_Access::define_admin_hooks()}
73 * + {@see WP_Data_Access::define_public_hooks()}
74 *
75 * @since 1.0.0
76 *
77 * @see WP_Data_Access::load_dependencies()
78 * @see WP_Data_Access::set_locale()
79 * @see WP_Data_Access::define_admin_hooks()
80 * @see WP_Data_Access::define_public_hooks()
81 */
82 public function __construct() {
83 if ( isset( $_REQUEST['page'] ) ) {
84 // phpcs:ignore WordPress.Security.NonceVerification
85 $this->page = sanitize_text_field( wp_unslash( $_REQUEST['page'] ) );
86 // phpcs:ignore WordPress.Security.NonceVerification
87 }
88 $this->load_dependencies();
89 $this->set_locale();
90 $this->define_admin_hooks();
91 $this->define_public_hooks();
92 // WP Data Access REST API.
93 $this->api();
94 }
95
96 /**
97 * Add WP Data Access JSON REST API
98 *
99 * @return void
100 */
101 private function api() {
102 $api = new \WPDataAccess\API\WPDA_API();
103 $this->loader->add_action( 'init', $api, 'hide' );
104 $this->loader->add_action( 'rest_api_init', $api, 'init' );
105 }
106
107 /**
108 * Load required dependencies
109 *
110 * Loads required plugin files and initiates the plugin loader.
111 *
112 * @since 1.0.0
113 *
114 * @see WP_Data_Access_Loader
115 */
116 private function load_dependencies() {
117 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-data-access-loader.php';
118 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-data-access-i18n.php';
119 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-wp-data-access-admin.php';
120 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'public/class-wp-data-access-public.php';
121 $this->loader = new WP_Data_Access_Loader();
122 }
123
124 /**
125 * Set locale for internationalization
126 *
127 * @since 1.0.0
128 *
129 * @see WP_Data_Access_I18n
130 */
131 private function set_locale() {
132 $wpda_i18n = new WP_Data_Access_I18n();
133 $this->loader->add_action( 'init', $wpda_i18n, 'load_plugin_textdomain' );
134 }
135
136 /**
137 * Add admin hooks
138 *
139 * Initiates {@see WP_Data_Access_Admin} (admin functionality) and {@see WPDA_Export} (export functionality).
140 * Adds the appropriate actions to the loader.
141 *
142 * @since 1.0.0
143 *
144 * @see WP_Data_Access_Admin
145 * @see WPDA_Export
146 */
147 private function define_admin_hooks() {
148 $plugin_admin = new WP_Data_Access_Admin();
149 if ( WPDA::is_plugin_page( $this->page ) ) {
150 // Handle plugin cookies.
151 $wpda_cookies = new WPDA_Cookies();
152 $this->loader->add_action( 'admin_init', $wpda_cookies, 'handle_plugin_cookies' );
153 }
154 // Admin menu.
155 $this->loader->add_action( 'admin_menu', $plugin_admin, 'add_menu_items' );
156 $this->loader->add_action(
157 'admin_menu',
158 $plugin_admin,
159 'add_menu_my_tables',
160 11
161 );
162 $this->loader->add_filter( 'submenu_file', $plugin_admin, 'wpda_submenu_filter' );
163 // Admin scripts.
164 $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_styles' );
165 $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts' );
166 $this->loader->add_action( 'in_admin_header', $plugin_admin, 'user_admin_notices' );
167 $this->loader->add_action( 'admin_head', $plugin_admin, 'remove_icons' );
168 // Add settings page.
169 $this->loader->add_action( 'admin_menu', $this, 'wpdataaccess_register_settings_page' );
170 // Query Builder.
171 $query_builder = new WPDA_Query_Builder();
172 $this->loader->add_action( 'admin_action_wpda_query_builder_execute_sql', $query_builder, 'execute' );
173 $this->loader->add_action( 'admin_action_wpda_query_builder_save_sql', $query_builder, 'save' );
174 $this->loader->add_action( 'admin_action_wpda_query_builder_open_sql', $query_builder, 'open' );
175 $this->loader->add_action( 'admin_action_wpda_query_builder_delete_sql', $query_builder, 'delete' );
176 $this->loader->add_action( 'admin_action_wpda_query_builder_get_db_hints', $query_builder, 'get_db_hints' );
177 $this->loader->add_action( 'admin_action_wpda_query_builder_set_db_hints', $query_builder, 'set_db_hints' );
178 $this->loader->add_action( 'admin_action_wpda_query_builder_get_vqb', $query_builder, 'get_visual_query' );
179 // Run unattended scheduled export
180 $this->loader->add_action( \WPDataAccess\Utilities\WPDA_Export_Scheduler::SCHEDULER_HOOK_NAME, \WPDataAccess\Utilities\WPDA_Export_Scheduler::class, 'run_scheduled_export' );
181 // Mail service.
182 $wpda_mail_server = \WPDataAccess\Utilities\WPDA_Mail::get_option();
183 if ( isset(
184 $wpda_mail_server['host'],
185 $wpda_mail_server['port'],
186 $wpda_mail_server['authenticate'],
187 $wpda_mail_server['encryption'],
188 $wpda_mail_server['skip_verify'],
189 $wpda_mail_server['username'],
190 $wpda_mail_server['password']
191 ) ) {
192 add_action(
193 'phpmailer_init',
194 function ( $phpmailer ) use($wpda_mail_server) {
195 $phpmailer->isSMTP();
196 $phpmailer->isHTML( false );
197 $phpmailer->SMTPDebug = $wpda_mail_server['debug'] ?? 0;
198 $phpmailer->Host = $wpda_mail_server['host'];
199 $phpmailer->Port = $wpda_mail_server['port'];
200 $phpmailer->SMTPAuth = 'on' === $wpda_mail_server['authenticate'];
201 $phpmailer->SMTPSecure = $wpda_mail_server['encryption'];
202 if ( 'on' === $wpda_mail_server['skip_verify'] ) {
203 $phpmailer->SMTPOptions = array(
204 'ssl' => array(
205 'verify_peer' => false,
206 'verify_peer_name' => false,
207 'allow_self_signed' => true,
208 ),
209 );
210 }
211 $phpmailer->Username = $wpda_mail_server['username'];
212 $phpmailer->Password = $wpda_mail_server['password'];
213 $phpmailer->From = $wpda_mail_server['username'];
214 },
215 10,
216 1
217 );
218 }
219 // Export action.
220 $this->loader->add_action( 'admin_action_wpda_export', WPDA_Export::class, 'export' );
221 // Dashboard and widgets.
222 $this->loader->add_action( 'wp_ajax_wpda_save_dashboard', WPDA_Dashboard::class, 'save' );
223 $this->loader->add_action( 'wp_ajax_wpda_dashboard_list', WPDA_Dashboard::class, 'get_list' );
224 $this->loader->add_action( 'wp_ajax_wpda_widget_load_panel', WPDA_Dashboard::class, 'load_widget' );
225 $this->loader->add_action( 'wp_ajax_wpda_widget_delete', WPDA_Dashboard::class, 'delete_widget' );
226 $this->loader->add_action( 'wp_ajax_wpda_widget_code_add', WPDA_Widget_Code::class, 'ajax_widget' );
227 $this->loader->add_action( 'wp_ajax_wpda_widget_dbms_add', WPDA_Widget_Dbms::class, 'ajax_widget' );
228 $this->loader->add_action( 'wp_ajax_wpda_widget_dbms_refresh', WPDA_Widget_Dbms::class, 'ajax_refresh' );
229 $this->loader->add_action( 'wp_ajax_wpda_remove_new_dashboard_message', WPDA_Dashboard::class, 'remove_new_dashboard_message' );
230 $this->loader->add_action( 'wp_ajax_wpda_widget_pub_add', WPDA_Widget_Publication::class, 'ajax_widget' );
231 $this->loader->add_action( 'wp_ajax_wpda_widget_chart_add', WPDA_Widget_Google_Chart::class, 'ajax_widget' );
232 $this->loader->add_action( 'wp_ajax_wpda_widget_chart_refresh', WPDA_Widget_Google_Chart::class, 'ajax_refresh' );
233 // Add/remove favourites.
234 $plugin_favourites = new WPDA_Favourites();
235 $this->loader->add_action( 'admin_action_wpda_add_favourite', $plugin_favourites, 'add' );
236 $this->loader->add_action( 'admin_action_wpda_rem_favourite', $plugin_favourites, 'rem' );
237 // Show tables actions.
238 $plugin_table_actions = new WPDA_Table_Actions();
239 $this->loader->add_action( 'admin_action_wpda_show_table_actions', $plugin_table_actions, 'show' );
240 $plugin_dictionary_list = new WPDA_Dictionary_Lists();
241 // Get tables for a specific database.
242 $this->loader->add_action( 'admin_action_wpda_get_tables', $plugin_dictionary_list, 'get_tables_ajax' );
243 // Get columns for a specific table.
244 $this->loader->add_action( 'admin_action_wpda_get_columns', $plugin_dictionary_list, 'get_columns' );
245 // Get row count for a specific table.
246 $this->loader->add_action( 'admin_action_wpda_get_table_row_count', $plugin_dictionary_list, 'get_table_row_count_ajax' );
247 // Get table widget info.
248 $this->loader->add_action( 'admin_action_wpda_get_table_widget_info', $plugin_dictionary_list, 'get_table_widget_info' );
249 // Global database search and replace.
250 $this->loader->add_action( 'wp_ajax_wpda_global_search', \WPDataAccess\Global_Search\WPDA_Global_Search::class, 'search' );
251 $this->loader->add_action( 'wp_ajax_wpda_global_replace', \WPDataAccess\Global_Search\WPDA_Global_Search::class, 'replace' );
252 // Export project.
253 $plugin_export_project = new WPDP_Export_Project();
254 $this->loader->add_action( 'admin_action_wpda_export_project', $plugin_export_project, 'export' );
255 // Data backup.
256 $wpda_data_backup = new WPDA_Data_Export();
257 $this->loader->add_action( 'wpda_data_backup', $wpda_data_backup, 'wpda_data_backup' );
258 // Allow to add multiple user roles.
259 $wpda_roles = new WPDA_Roles();
260 $this->loader->add_action( 'user_new_form', $wpda_roles, 'multiple_roles_selection' );
261 $this->loader->add_action( 'edit_user_profile', $wpda_roles, 'multiple_roles_selection' );
262 $this->loader->add_action( 'profile_update', $wpda_roles, 'multiple_roles_update' );
263 $this->loader->add_filter( 'manage_users_columns', $wpda_roles, 'multiple_roles_label' );
264 // Check if a remote db connection can be established via ajax.
265 $wpdadb = new WPDADB();
266 $this->loader->add_action( 'admin_action_wpda_check_remote_database_connection', $wpdadb, 'check_remote_database_connection' );
267 // Make WordPress user ID available to database connections.
268 add_action(
269 'wpda_dbinit',
270 function ( $wpdadb ) {
271 if ( null !== $wpdadb ) {
272 $suppress_errors = $wpdadb->suppress_errors( true );
273 $wpdadb->query( 'set @wpda_wp_user_id = ' . get_current_user_id() );
274 $wpdadb->suppress_errors( $suppress_errors );
275 }
276 },
277 10,
278 1
279 );
280 add_action(
281 'wp_ajax_wpda_dbinit_admin',
282 function () {
283 if ( !isset( $_POST['wpnonce'], $_POST['wpdaschema_name'] ) ) {
284 WPDA::sent_header( 'application/json' );
285 echo WPDA::sent_msg( 'ERROR', 'Invalid arguments' );
286 // phpcs:ignore WordPress.Security.EscapeOutput
287 wp_die();
288 }
289 $wpnonce = sanitize_text_field( wp_unslash( $_REQUEST['wpnonce'] ) );
290 // input var okay.
291 if ( !WPDA::current_user_is_admin() || !wp_verify_nonce( $wpnonce, 'wpda_dbinit_admin_' . WPDA::get_current_user_login() ) ) {
292 WPDA::sent_header( 'application/json' );
293 echo WPDA::sent_msg( 'ERROR', 'Not authorized' );
294 // phpcs:ignore WordPress.Security.EscapeOutput
295 wp_die();
296 }
297 $wpdaschema_name = sanitize_text_field( wp_unslash( $_REQUEST['wpdaschema_name'] ) );
298 // input var okay.
299 $wpdadb = WPDADB::get_db_connection( $wpdaschema_name );
300 if ( null === $wpdadb ) {
301 WPDA::sent_header( 'application/json' );
302 echo WPDA::sent_msg( 'ERROR', 'Cannot connect to database' );
303 // phpcs:ignore WordPress.Security.EscapeOutput
304 wp_die();
305 }
306 $suppress_errors = $wpdadb->suppress_errors( true );
307 $wpdadb->query( 'create function wpda_get_wp_user_id() returns integer deterministic no sql return @wpda_wp_user_id' );
308 $error = $wpdadb->last_error;
309 $wpdadb->suppress_errors( $suppress_errors );
310 if ( '' === $error ) {
311 //phpcs:ignore - 8.1 proof
312 echo WPDA::sent_msg( 'OK', '' );
313 // phpcs:ignore WordPress.Security.EscapeOutput
314 } else {
315 echo WPDA::sent_msg( 'ERROR', "Function not created [{$error}]" );
316 // phpcs:ignore WordPress.Security.EscapeOutput
317 }
318 wp_die();
319 },
320 10,
321 1
322 );
323 // Add id to wpda_datatables.js (for IE).
324 $this->loader->add_filter(
325 'script_loader_tag',
326 $this,
327 'add_id_to_script',
328 10,
329 3
330 );
331 // Add CSV mapping calls.
332 $wpda_csv_uploads_model = new WPDA_CSV_Uploads_Model();
333 $this->loader->add_action( 'admin_action_wpda_save_csv_mapping', $wpda_csv_uploads_model, 'save_mapping' );
334 $this->loader->add_action( 'admin_action_wpda_csv_preview_mapping', $wpda_csv_uploads_model, 'preview_mapping' );
335 // Data Tables services.
336 $this->loader->add_action( 'wp_ajax_wpda_test_publication', \WPDataAccess\Data_Publisher\WPDA_Publisher_Form::class, 'test_publication' );
337 // Add custom CSS to freemius pages.
338 add_action(
339 'admin_footer',
340 function () {
341 if ( WP_Data_Access_Admin::MAIN_PAGE_SLUG . '-account' === $this->page || WP_Data_Access_Admin::MAIN_PAGE_SLUG . '-pricing' === $this->page ) {
342 ?>
343 <script type="application/javascript">
344 jQuery(function() {
345 jQuery.each(document.styleSheets, function (index, cssFile) {
346 if (cssFile.href!==null && cssFile.href.toString().includes("load-styles.php")) {
347 var classes = cssFile.rules || cssFile.cssRules;
348 for (var x=0; x<classes.length; x++) {
349 if (
350 classes[x].selectorText!==undefined &&
351 classes[x].selectorText!==null &&
352 classes[x].selectorText.includes("#adminmenu li.current a.menu-top")
353 ) {
354 jQuery("#adminmenu #toplevel_page_wpda a.menu-top").attr("style", classes[x].style.cssText);
355 }
356 }
357 }
358 });
359 });
360 </script>
361 <?php
362 }
363 },
364 10,
365 1
366 );
367 }
368
369 /**
370 * Needed for JDT to support IE
371 *
372 * @param string $tag Tag.
373 * @param string $handle Handle.
374 * @param string $src Source.
375 * @return mixed|string
376 */
377 public function add_id_to_script( $tag, $handle, $src ) {
378 if ( 'wpda_datatables' === $handle ) {
379 $tag = '<script id="wpda_datatables" src="' . $src . '"></script>';
380 // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
381 }
382 return $tag;
383 }
384
385 /**
386 * Add public hooks
387 *
388 * Initiates {@see WP_Data_Access_Public} (public functionality), {@see WPDA_Data_Tables} (ajax call to support
389 * server side jQuery DataTables functionality). Adds the appropriate actions to
390 * the loader.
391 *
392 * @since 1.0.0
393 *
394 * @see WP_Data_Access_Public
395 * @see WPDA_Data_Tables
396 * @see WPDA_Dictionary_Lists
397 */
398 private function define_public_hooks() {
399 $plugin_public = new WP_Data_Access_Public();
400 // Shortcodes.
401 $this->loader->add_action( 'init', $plugin_public, 'register_shortcodes' );
402 // Public scripts.
403 $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
404 $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
405 $this->loader->add_action(
406 'admin_bar_menu',
407 $plugin_public,
408 'add_apps_to_admin_toolbar',
409 9999
410 );
411 $this->loader->add_action(
412 'admin_bar_menu',
413 $plugin_public,
414 'add_data_projects_to_admin_toolbar',
415 9999
416 );
417 // Ajax calls.
418 $plugin_datatables = new WPDA_Data_Tables();
419 $this->loader->add_action( 'wp_ajax_wpda_datatables', $plugin_datatables, 'get_data' );
420 $this->loader->add_action( 'wp_ajax_nopriv_wpda_datatables', $plugin_datatables, 'get_data' );
421 // Export action.
422 $this->loader->add_action( 'wp_ajax_wpda_export', WPDA_Export::class, 'export_ajax' );
423 $this->loader->add_action( 'wp_ajax_nopriv_wpda_export', WPDA_Export::class, 'export_ajax' );
424 // Add id to wpda_datatables.js (for IE).
425 $this->loader->add_filter(
426 'script_loader_tag',
427 $this,
428 'add_id_to_script',
429 10,
430 3
431 );
432 // Autocomplete.
433 $autocomplete_service = new WPDA_Autocomplete();
434 $this->loader->add_action( 'wp_ajax_wpda_autocomplete', $autocomplete_service, 'autocomplete' );
435 $this->loader->add_action( 'wp_ajax_nopriv_wpda_autocomplete', $autocomplete_service, 'autocomplete_anonymous' );
436 }
437
438 /**
439 * Start plugin loader
440 *
441 * @since 1.0.0
442 */
443 public function run() {
444 $this->loader->run();
445 }
446
447 /**
448 * Add plugin settings page
449 */
450 public function wpdataaccess_register_settings_page() {
451 add_options_page(
452 'WP Data Access',
453 'WP Data Access',
454 'manage_options',
455 WP_Data_Access_Admin::PAGE_SETTINGS,
456 array($this, 'wpdataaccess_settings_page')
457 );
458 }
459
460 /**
461 * Show settings page
462 */
463 public function wpdataaccess_settings_page() {
464 WPDA_Dashboard::add_dashboard();
465 $current_tab = ( isset( $_REQUEST['tab'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['tab'] ) ) : 'plugin' );
466 // phpcs:ignore WordPress.Security.NonceVerification
467 switch ( $current_tab ) {
468 case 'backend':
469 $wpda_settings_class_name = 'WPDA_Settings_BackEnd';
470 break;
471 case 'frontend':
472 $wpda_settings_class_name = 'WPDA_Settings_FrontEnd';
473 break;
474 case 'pds':
475 $wpda_settings_class_name = 'WPDA_Settings_PDS';
476 break;
477 case 'uninstall':
478 $wpda_settings_class_name = 'WPDA_Settings_Uninstall';
479 break;
480 case 'repository':
481 $wpda_settings_class_name = 'WPDA_Settings_ManageRepository';
482 break;
483 case 'system':
484 $wpda_settings_class_name = 'WPDA_Settings_SystemInfo';
485 break;
486 case 'mail':
487 $wpda_settings_class_name = 'WPDA_Settings_Mail';
488 break;
489 case 'drives':
490 $wpda_settings_class_name = 'WPDA_Settings_Drives';
491 break;
492 case 'legacy':
493 $wpda_settings_class_name = 'WPDA_Settings_Legacy';
494 break;
495 default:
496 $wpda_settings_class_name = 'WPDA_Settings_Plugin';
497 }
498 $wpda_settings_class_name = '\\WPDataAccess\\Settings\\' . $wpda_settings_class_name;
499 $wpda_settings = new $wpda_settings_class_name($current_tab);
500 $wpda_settings->show();
501 }
502
503 }
504