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.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_Import_File.php

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

172 lines 5.0 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\Connection\WPDADB;
12
13 /**
14 * Class WPDA_Import_File
15 *
16 * Loads the content of an import file and imports it.
17 *
18 * @author Peter Schulz
19 * @since 1.0.0
20 */
21 class WPDA_Import_File {
22
23 /**
24 * Pointer to import file
25 *
26 * @var string
27 */
28 protected $file_pointer;
29
30 /**
31 * Content of import file
32 *
33 * @var string
34 */
35 protected $file_content;
36
37 /**
38 * WPDA_Import constructor
39 *
40 * Create file pointer.
41 *
42 * @param string $file_path Full path of script (import) file.
43 *
44 * @since 1.0.0
45 */
46 public function __construct( $file_path ) {
47
48 $this->file_pointer = fopen( $file_path, 'rb' );
49
50 }
51
52 /**
53 * Close file.
54 *
55 * @since 2.0.12
56 */
57 public function __destruct() {
58 fclose( $this->file_pointer );
59 }
60
61 /**
62 * Import file content
63 *
64 * Import method writes the content of the import file to the database. Security checks:
65 * + Only INSERT INTO is allowed: no other DML, DDL and DCL statements allowed
66 * + Only inserts into the table name provided are allowed
67 * + Use explain to check the number of tables affect: more than 1 looks like SQL injection
68 *
69 * Since wpdb-query() only processes one query at a time we only need to check the type of statement at the
70 * beginning of the script ($file_content).
71 *
72 * This method only return -1 if a failure occurs or the number of rows inserted. The number of probable error
73 * cause is to huge and complex to check all possibilities. Exports created from the WP Data Access table list
74 * should normally import without problems. For manually created imports responsibility is with the developer.
75 *
76 * @param string $schema_name Schema in which this import allowes inserts.
77 * @param string $table_name Table in which this import allowes inserts.
78 * @param string $hide_errors ON = hide errors, OFF = show errors.
79 *
80 * @since 1.0.0
81 */
82 public function import( $schema_name, $table_name, $hide_errors ) {
83 global $wpdb;
84
85 $wpdadb = WPDADB::get_db_connection( $schema_name );
86 if ( null === $wpdadb ) {
87 wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $schema_name ) ) );
88 }
89
90 $suppress = $wpdadb->suppress_errors( 'on' === $hide_errors );
91
92 $this->file_content = '';
93 $rows = 0;
94 $rows_failed = 0;
95
96 if ( false !== $this->file_pointer ) {
97 while ( ! feof( $this->file_pointer ) ) {
98 $this->file_content .= fread( $this->file_pointer, 4096 );
99
100 // Replace WP prefix and WPDA prefix.
101 $this->file_content = str_replace( '{wp_schema}', $wpdb->dbname, $this->file_content );
102 $this->file_content = str_replace( '{wp_prefix}', $wpdb->prefix, (string) $this->file_content );
103 $this->file_content = str_replace( '{wpda_prefix}', 'wpda', (string) $this->file_content ); // for backward compatibility
104
105 // Find and process SQL statements.
106 $sql_end_unix = strpos( $this->file_content, ";\n" );
107 $sql_end_windows = strpos( $this->file_content, ";\r\n" );
108 while ( false !== $sql_end_unix || false !== $sql_end_windows ) {
109 if ( false === $sql_end_unix ) {
110 $sql_end = $sql_end_windows;
111 } elseif ( false === $sql_end_windows ) {
112 $sql_end = $sql_end_unix;
113 } else {
114 $sql_end = min( $sql_end_unix, $sql_end_windows );
115 }
116 $sql = rtrim( substr( $this->file_content, 0, $sql_end ) );
117
118 $this->file_content = substr( $this->file_content, strpos( $this->file_content, $sql ) + strlen( $sql ) + 1 );
119 $rows ++;
120
121 // Write file content to array for security check (150 characters is sufficient to check DML and table name).
122 $dml_check = explode( ' ', substr( trim( $sql ), 0, 150 ) );//phpcs:ignore - 8.1 proof
123
124 if ( ! isset( $dml_check[0] ) || ! isset( $dml_check[1] ) ) {
125 // No content.
126 $rows_failed ++;
127 } else {
128 // Check first two words (must be insert into, no other statements allowed).
129 if ( strtolower( $dml_check[0] . $dml_check[1] ) !== 'insertinto' ) {
130 // Only insert into is allowed.
131 $rows_failed ++;
132 } else {
133 // Check table name (using stristr should cover backticks and schema_names as well).
134 if ( ! stristr( $dml_check[2], $table_name ) ) {
135 $rows_failed ++;
136 } else {
137 // Insert row.
138 if ( false === $wpdadb->query( $sql ) ) {
139 $rows_failed ++;
140 }
141 }
142 }
143 }
144
145 // Find next SQL statement.
146 $sql_end_unix = strpos( $this->file_content, ";\n" );
147 $sql_end_windows = strpos( $this->file_content, ";\r\n" );
148 }
149 }
150 }
151
152 $wpdadb->suppress_errors( $suppress );
153
154 $msg = 'Imported ' . ( $rows - $rows_failed ) . ' rows';
155 if ( $rows_failed > 0 ) {
156 $msg .= " ($rows_failed failed).";
157 } else {
158 $msg .= '.';
159 }
160 $msg = new WPDA_Message_Box(
161 array(
162 'message_text' => $msg,
163 )
164 );
165 $msg->box();
166
167 }
168
169 }
170
171 }
172