PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.2
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.2
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 / WPDataAccess / Utilities / WPDA_Repository.php

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

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