PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.4
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.4
5.5.84 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 All 160 releases
wp-data-access / WPDataAccess / Utilities / WPDA_Repository.php

WPDA_Repository.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.4, at WPDataAccess/Utilities/WPDA_Repository.php

473 lines 13.9 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 WPDataAccess\Utilities
7 */
8
9 namespace WPDataAccess\Utilities {
10
11 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Exist;
12 use WPDataAccess\Plugin_Table_Models\WPDA_Logging_Model;
13 use WPDataAccess\Plugin_Table_Models\WPDA_Media_Model;
14 use WPDataAccess\Plugin_Table_Models\WPDA_Publisher_Model;
15 use WPDataAccess\Plugin_Table_Models\WPDA_Design_Table_Model;
16 use WPDataAccess\Plugin_Table_Models\WPDA_Table_Settings_Model;
17 use WPDataAccess\Plugin_Table_Models\WPDA_User_Menus_Model;
18 use WPDataAccess\Plugin_Table_Models\WPDP_Page_Model;
19 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Model;
20 use WPDataAccess\Plugin_Table_Models\WPDP_Project_Design_Table_Model;
21 use WPDataAccess\WPDA;
22
23 /**
24 * Class WPDA_Repository
25 *
26 * Recreate repository objects.
27 *
28 * @author Peter Schulz
29 * @since 1.0.0
30 */
31 class WPDA_Repository {
32
33 const CREATE_TABLE = array(
34 'wpda_logging' => array(
35 'create_table_logging.sql',
36 ),
37 'wpda_menus' => array(
38 'create_table_menus.sql',
39 ),
40 'wpda_table_settings' => array(
41 'create_table_table_settings.sql',
42 ),
43 'wpda_table_design' => array(
44 'create_table_table_design.sql',
45 'create_table_table_design_alter1.sql',
46 'create_table_table_design_alter3.sql',
47 'create_table_table_design_alter3.sql',
48 ),
49 'wpda_publisher' => array( // Old plugin table name: do NOT change!
50 'create_table_publisher.sql',
51 ),
52 'wpda_media' => array(
53 'create_table_media.sql',
54 ),
55 'wpda_project' => array(
56 'create_table_project.sql',
57 ),
58 'wpda_project_page' => array(
59 'create_table_project_page.sql',
60 ),
61 'wpda_project_table' => array(
62 'create_table_project_table.sql',
63 ),
64 'wpda_csv_uploads' => array(
65 'create_table_csv_uploads.sql',
66 ),
67 'wpda_app' => array(
68 'create_table_app.sql',
69 ),
70 'wpda_app_container' => array(
71 'create_table_app_container.sql',
72 ),
73 'wpda_app_apps' => array(
74 'create_table_app_apps.sql',
75 'create_table_app_apps_alter1.sql',
76 'create_table_app_apps_alter2.sql',
77 ),
78 );
79
80 const DROP_TABLE = array(
81 'wpda_logging' => array(
82 'drop_table_logging.sql',
83 ),
84 'wpda_menus' => array(
85 'drop_table_menus.sql',
86 ),
87 'wpda_table_settings' => array(
88 'drop_table_table_settings.sql',
89 ),
90 'wpda_table_design' => array(
91 'drop_table_table_design.sql',
92 ),
93 'wpda_publisher' => array( // Old plugin table name: do NOT change!
94 'drop_table_publisher.sql',
95 ),
96 'wpda_media' => array(
97 'drop_table_media.sql',
98 ),
99 'wpda_project' => array(
100 'drop_table_project.sql',
101 ),
102 'wpda_project_page' => array(
103 'drop_table_project_page.sql',
104 ),
105 'wpda_project_table' => array(
106 'drop_table_project_table.sql',
107 ),
108 'wpda_csv_uploads' => array(
109 'drop_table_csv_uploads.sql',
110 ),
111 'wpda_app' => array(
112 'drop_table_app.sql',
113 ),
114 'wpda_app_container' => array(
115 'drop_table_app_container.sql',
116 ),
117 'wpda_app_apps' => array(
118 'drop_table_app_apps.sql',
119 ),
120 );
121
122 protected $sql_repository_dir = '';
123
124 public function __construct() {
125 $this->sql_repository_dir = plugin_dir_path( dirname( __FILE__ ) ) . '../admin/repository/';
126 }
127
128 /**
129 * Recreate repository (save as much data as possible)
130 *
131 * @since 2.0.11
132 */
133 public function recreate() {
134 global $wpdb;
135
136 $suppress = $wpdb->suppress_errors( true );
137
138 $bck_postfix = WPDA_Restore_Repository::BACKUP_TABLE_EXTENSION . date( 'YmdHis' );
139 foreach ( static::CREATE_TABLE as $key => $value ) {
140 $table_name = $wpdb->prefix . $key;
141
142 // Check if table exists
143 $table_exists = new WPDA_Dictionary_Exist( $wpdb->dbname, $table_name );
144 $table_check = $table_exists->table_exists( false );
145
146 $bck_table_name = null;
147 $same_cols = null;
148
149 if ( $table_check ) {
150 // Create backup table
151 $bck_table_name = $wpdb->prefix . $key . $bck_postfix;
152 $wpdb->query(
153 $wpdb->prepare(
154 'create table `%1s` as select * from `%1s`', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
155 array(
156 WPDA::remove_backticks( $bck_table_name ),
157 WPDA::remove_backticks( $table_name ),
158 )
159 )
160 );
161 }
162
163 if ( $table_check ) {
164 // Create temporary table to check for changes
165 if ( $this->run_script( $value[0], '_new' ) ) {
166 // Check if table structure was changed
167 $table_diff = $wpdb->get_row(
168 $wpdb->prepare(
169 'select column_name,ordinal_position,data_type,column_type from (
170 select column_name, ordinal_position, data_type, column_type, count(1) rowcount
171 from information_schema.columns
172 where table_schema = %s
173 and table_name in (%s,%s)
174 group by column_name, ordinal_position, data_type, column_type
175 having count(1) = 1
176 ) A',
177 $wpdb->dbname,
178 $table_name,
179 "{$table_name}_new"
180 )
181 );
182
183 // Drop check table
184 $this->run_script( static::DROP_TABLE[ $key ][0], '_new' );
185
186 if ( $table_diff !== null ) {
187 // Drop old repository table
188 $this->run_script( static::DROP_TABLE[ $key ][0], '' );
189
190 // Create new repository table
191 foreach ( $value as $sql_file ) {
192 $this->run_script( $sql_file );
193 }
194
195 // Get columns matching old and new repository table columns to restore as much values as possible
196 $same_cols = $wpdb->get_results(
197 $wpdb->prepare(
198 'select c1.column_name as column_name
199 from information_schema.columns c1
200 where c1.table_schema = %s
201 and c1.table_name = %s
202 and c1.column_name in (
203 select c2.column_name
204 from information_schema.columns c2
205 where c2.table_schema = %s
206 and c2.table_name = %s
207 )
208 ',
209 $wpdb->dbname,
210 $table_name,
211 $wpdb->dbname,
212 $bck_table_name
213 ),
214 'ARRAY_A'
215 );
216
217 // Restore repository table data
218 $selected_columns = '';
219 foreach ( $same_cols as $same_col ) {
220 $selected_columns .= $same_col['column_name'] . ',';
221 }
222 $selected_columns = substr( $selected_columns, 0, strlen( $selected_columns ) - 1 );
223 $wpdb->query(
224 $wpdb->prepare(
225 'insert into `%1s` (%1s) select %1s from `%1s`', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
226 array(
227 WPDA::remove_backticks( $table_name ),
228 $selected_columns,
229 $selected_columns,
230 WPDA::remove_backticks( $bck_table_name ),
231 )
232 )
233 );
234 }
235 }
236 } else {
237 // Create table
238 foreach ( $value as $sql_file ) {
239 $this->run_script( $sql_file );
240 }
241 }
242
243 if ( 'on' !== WPDA::get_option( WPDA::OPTION_MR_KEEP_BACKUP_TABLES ) ) {
244 // Drop backup table
245 $this->run_script( static::DROP_TABLE[ $key ][0], $bck_postfix );
246 }
247 }
248
249 $this->cleanup();
250 $this->remove_old_backups();
251
252 $wpdb->suppress_errors( $suppress );
253 }
254
255 public function remove_old_backups() {
256 if ( 'on' === WPDA::get_option( WPDA::OPTION_MR_KEEP_BACKUP_TABLES ) ) {
257 $backup_tables_kept = WPDA::get_option( WPDA::OPTION_MR_BACKUP_TABLES_KEPT );
258 $base_table_name = WPDA_Publisher_Model::get_base_table_name() . WPDA_Restore_Repository::BACKUP_TABLE_EXTENSION;
259
260 global $wpdb;
261 $rows = $wpdb->get_results(
262 $wpdb->prepare(
263 '
264 select table_name as table_name
265 from information_schema.tables
266 where table_schema = %s
267 and table_name like %s
268 order by 1 desc
269 ',
270 array(
271 $wpdb->dbname,
272 "{$base_table_name}%",
273 )
274 ),
275 'ARRAY_A'
276 );
277
278 for ( $i = $backup_tables_kept; $i < count( $rows ); $i ++ ) {//phpcs:ignore - 8.1 proof
279 $backup_date = substr( $rows[ $i ]['table_name'], strlen( $base_table_name ) );
280 $this->remove_backup( $backup_date );
281 }
282 }
283 }
284
285 public function remove_backup( $backup_date ) {
286 global $wpdb;
287 $backup_date_sanitized = WPDA::remove_backticks( $backup_date );
288
289 $suppress = $wpdb->suppress_errors( true );
290 $extension = WPDA_Restore_Repository::BACKUP_TABLE_EXTENSION;
291 foreach ( self::CREATE_TABLE as $key => $value ) {
292 $wpdb->query(
293 $wpdb->prepare(
294 'drop table `%1s`', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
295 array(
296 WPDA::remove_backticks( "{$wpdb->prefix}{$key}{$extension}{$backup_date_sanitized}" ),
297 )
298 )
299 );
300 }
301 $wpdb->suppress_errors( $suppress );
302 }
303
304 /**
305 * Cleanup plugin repository tables
306 */
307 protected function cleanup() {
308 global $wpdb;
309
310 // Remove previous data table list table settings
311 $wpdb->query(
312 "delete from {$wpdb->prefix}usermeta where meta_key like '%columnshidden%' and meta_key like '%wpda_publisher%'"
313 );
314
315 // Remove previous project page list table settings
316 $wpdb->query(
317 "delete from {$wpdb->prefix}usermeta where meta_key like '%columnshidden%' and meta_key like '%wpda_project%'"
318 );
319
320 // Allow column to contain null values
321 $wpdb->query(
322 "alter table {$wpdb->prefix}wpda_project_page modify page_allow_full_export enum('yes','no') null default 'no'"
323 );
324
325 // Remove material sort icons from data tables
326 $wpdb->query(
327 "update {$wpdb->prefix}wpda_publisher set pub_sort_icons = 'default' where pub_sort_icons = 'plugin'"
328 );
329 $wpdb->query(
330 "alter table {$wpdb->prefix}wpda_publisher modify pub_sort_icons enum('default','none')"
331 );
332
333 // Remove plugin configuration settings: wrong values installed with 5.0.0 (needs to be reset on next deployment)
334 delete_option( 'wpda_plugin_navigation' );
335 delete_option( 'wpda_plugin_hide_notices' );
336 }
337
338 /**
339 * Create repository
340 *
341 * @since 1.0.0
342 */
343 public function create() {
344 foreach ( static::CREATE_TABLE as $key => $value ) {
345 foreach ( $value as $sql_file ) {
346 $this->run_script( $sql_file );
347 }
348 }
349 }
350
351 /**
352 * Drop repository
353 *
354 * @since 1.0.0
355 */
356 public function drop() {
357 foreach ( static::DROP_TABLE as $key => $value ) {
358 foreach ( $value as $sql_file ) {
359 $this->run_script( $sql_file );
360 }
361 }
362 }
363
364 /**
365 * Run SQL script file
366 *
367 * @param string $sql_file SQL script file name
368 * @param string $wpda_postfix WPDA postfix
369 *
370 * @return mixed Result of the query taken from the SQL script file
371 *
372 * @since 2.0.11
373 */
374 public function run_script( $sql_file, $wpda_postfix = '' ) {
375 $sql_repository_file = $this->sql_repository_dir . $sql_file;
376 $sql_repository_handle = fopen( $sql_repository_file, 'r' );
377
378 if ( $sql_repository_handle ) {
379 // Read file content and close handle.
380 $sql_repository_file_content = fread( $sql_repository_handle, filesize( $sql_repository_file ) );
381 fclose( $sql_repository_handle );
382
383 global $wpdb;
384
385 // Replace WP prefix and WPDA prefix.
386 $sql_repository_file_content = str_replace( '{wp_prefix}', $wpdb->prefix, $sql_repository_file_content );
387 $sql_repository_file_content = str_replace( '{wpda_prefix}', 'wpda', $sql_repository_file_content ); // for backward compatibility
388 $sql_repository_file_content = str_replace( '{wpda_postfix}', $wpda_postfix, $sql_repository_file_content );
389 $sql_repository_file_content = str_replace( '{wpda_collate}', $wpdb->get_charset_collate(), $sql_repository_file_content );
390
391 // Run script from admin/repository.
392 return $wpdb->query( $sql_repository_file_content ); // phpcs:ignore WordPress.DB.PreparedSQL
393 }
394 }
395
396
397 /**
398 * Inform user if repository is invalid
399 *
400 * @since 1.0.0
401 */
402 public function inform_user() {
403 if ( ! is_admin() ) {
404 return;
405 }
406
407 if ( isset( $_REQUEST['setup_error'] ) && 'off' === $_REQUEST['setup_error'] ) {
408 // Turn off menu management not available message.
409 WPDA::set_option( WPDA::OPTION_WPDA_SETUP_ERROR, 'off' );
410 } else {
411 if ( 'off' !== WPDA::get_option( WPDA::OPTION_WPDA_SETUP_ERROR ) ) {
412 // Check if repository tables exist.
413 if ( ! WPDA_User_Menus_Model::table_exists() ||
414 ! WPDA_Design_Table_Model::table_exists() ||
415 ! WPDP_Project_Design_Table_Model::table_exists() ||
416 ! WPDA_Publisher_Model::table_exists() ||
417 ! WPDA_Logging_Model::table_exists() ||
418 ! WPDA_Media_Model::table_exists() ||
419 ! WPDP_Project_Model::table_exists() ||
420 ! WPDP_Page_Model::table_exists() ||
421 ! WPDA_Table_Settings_Model::table_exists()
422 ) {
423 $msg = new WPDA_Message_Box(
424 array(
425 'message_text' =>
426 __( 'Some features of WP Data Access are currently not available.', 'wp-data-access' ) .
427 ' ' .
428 __( 'ACTION', 'wp-data-access' ) .
429 ': ' .
430 '<a href="?page=wpdataaccess&tab=repository">' . __( 'Recreate repository', 'wp-data-access' ) . '</a>' .
431 ' ' .
432 __( 'to to solve this problem.', 'wp-data-access' ) .
433 ' [' .
434 '<a href="?' . esc_url( sanitize_text_field( wp_unslash( $_SERVER['QUERY_STRING'] ) ) ) . '&setup_error=off">' . __( 'do not show this message again', 'wp-data-access' ) . '</a>' .
435 ']',
436 )
437 );
438
439 $msg->box();
440 }
441 }
442 }
443 }
444
445 public function create_new_backup() {
446 global $wpdb;
447
448 $bck_postfix = WPDA_Restore_Repository::BACKUP_TABLE_EXTENSION . date( 'YmdHis' );
449 foreach ( static::CREATE_TABLE as $key => $value ) {
450 $table_name = $wpdb->prefix . $key;
451
452 // Check if table exists
453 $table_exists = new WPDA_Dictionary_Exist( $wpdb->dbname, $table_name );
454
455 if ( $table_exists->table_exists( false ) ) {
456 // Create backup table
457 $wpdb->query(
458 $wpdb->prepare(
459 'create table `%1s` as select * from `%1s`', // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
460 array(
461 WPDA::remove_backticks( $wpdb->prefix . $key . $bck_postfix ),
462 WPDA::remove_backticks( $table_name ),
463 )
464 )
465 ); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
466 }
467 }
468 }
469
470 }
471
472 }
473