| 1 |
<?php |
| 2 |
|
| 3 |
namespace WPSynchro\API; |
| 4 |
|
| 5 |
use WPSynchro\Utilities\CommonFunctions; |
| 6 |
use WPSynchro\Database\DatabaseSync; |
| 7 |
use WPSynchro\Database\Table; |
| 8 |
use WPSynchro\Database\TableColumns; |
| 9 |
use WPSynchro\Transport\ReturnResult; |
| 10 |
use WPSynchro\Utilities\DebugInformation; |
| 11 |
|
| 12 |
/** |
| 13 |
* Class for handling service "masterdata" |
| 14 |
* Call should already be verified by permissions callback |
| 15 |
* |
| 16 |
*/ |
| 17 |
class MasterData extends WPSynchroService |
| 18 |
{ |
| 19 |
// Column types - in how they are inserted into database |
| 20 |
public $string_columns_types = ["decimal", "dec", "fixed", "numeric", "json", "date", "datetime", "timestamp", "time", "year", "char", "varchar", "tinytext", "text", "mediumtext", "longtext", "enum", "set"]; |
| 21 |
public $numeric_column_types = ["tinyint", "smallint", "mediumint", "int", "bigint", "float", "double", "real"]; |
| 22 |
public $bit_column_types = ["bit"]; |
| 23 |
public $binary_column_types = ["blob", "tinyblob", "mediumblob", "longblob", "binary", "varbinary", "point", "geometry", "linestring", "polygon", "multipoint", "multilinestring", "multipolygon", "geometrycollection"]; |
| 24 |
// Tables to exclude |
| 25 |
public $tables_to_exclude = ["wpsynchro_sync_list", "wpsynchro_file_population_list"]; |
| 26 |
|
| 27 |
public function service() |
| 28 |
{ |
| 29 |
$result = new \stdClass(); |
| 30 |
|
| 31 |
// Check php/mysql/wp requirements |
| 32 |
$commonfunctions = new CommonFunctions(); |
| 33 |
$compat_errors = $commonfunctions->checkEnvCompatability(); |
| 34 |
|
| 35 |
if (count($compat_errors) > 0) { |
| 36 |
// @codeCoverageIgnoreStart |
| 37 |
foreach ($compat_errors as &$error) { |
| 38 |
$error = __("Error from remote server:", "wpsynchro") . " " . $error; |
| 39 |
} |
| 40 |
$result->errors = $compat_errors; |
| 41 |
|
| 42 |
$returnresult = new ReturnResult(); |
| 43 |
$returnresult->init(); |
| 44 |
$returnresult->setDataObject($result); |
| 45 |
$returnresult->setHTTPStatus(500); |
| 46 |
return $returnresult->echoDataFromServiceAndExit(); |
| 47 |
// @codeCoverageIgnoreEnd |
| 48 |
} |
| 49 |
|
| 50 |
if (isset($_REQUEST['type'])) { |
| 51 |
$type = $_REQUEST['type']; |
| 52 |
} else { |
| 53 |
$type = []; |
| 54 |
} |
| 55 |
|
| 56 |
/** |
| 57 |
* Insert standard information on site |
| 58 |
*/ |
| 59 |
$result->base = $this->getBaseSiteData(); |
| 60 |
|
| 61 |
/** |
| 62 |
* Multisite data |
| 63 |
*/ |
| 64 |
$result->multisite = $this->getMultisiteData(); |
| 65 |
|
| 66 |
/** |
| 67 |
* Get tables in database |
| 68 |
*/ |
| 69 |
if (in_array('dbtables', $type)) { |
| 70 |
$result->dbtables = $this->getBasicDatabaseData(); |
| 71 |
} |
| 72 |
|
| 73 |
/** |
| 74 |
* Get detailed listing of database tables and sizes |
| 75 |
*/ |
| 76 |
if (in_array('dbdetails', $type)) { |
| 77 |
$dbdetails = $this->getDetailsDatabaseData(); |
| 78 |
$result->dbdetails = $dbdetails->dbdetails; |
| 79 |
$result->tmptables_dbdetails = $dbdetails->tmptables_dbdetails; |
| 80 |
} |
| 81 |
|
| 82 |
/** |
| 83 |
* Get information needed for files |
| 84 |
*/ |
| 85 |
if (in_array('filedetails', $type)) { |
| 86 |
$result->files = $this->getFileDetailsData(); |
| 87 |
} |
| 88 |
|
| 89 |
/** |
| 90 |
* Include debug data for log |
| 91 |
*/ |
| 92 |
$debuginformation = new DebugInformation(); |
| 93 |
$result->debug = $debuginformation->getAllDebugInformation(); |
| 94 |
|
| 95 |
// Return |
| 96 |
$return_result = new ReturnResult(); |
| 97 |
$return_result->init(); |
| 98 |
$return_result->setDataObject($result); |
| 99 |
return $return_result->echoDataFromServiceAndExit(); |
| 100 |
} |
| 101 |
|
| 102 |
/** |
| 103 |
* Get base data for site |
| 104 |
*/ |
| 105 |
public function getBaseSiteData() |
| 106 |
{ |
| 107 |
global $wpdb; |
| 108 |
$commonfunctions = new CommonFunctions(); |
| 109 |
|
| 110 |
$result = new \stdClass(); |
| 111 |
|
| 112 |
$result->client_home_url = home_url('/'); |
| 113 |
$result->wpdb_prefix = $wpdb->prefix; |
| 114 |
$result->wp_options_table = $wpdb->options; |
| 115 |
$result->wp_users_table = $wpdb->users; |
| 116 |
$result->wp_usermeta_table = $wpdb->usermeta; |
| 117 |
|
| 118 |
$home_url_from_db = $wpdb->get_var("select option_value from " . $wpdb->options . " where option_name='home'"); |
| 119 |
if (!$home_url_from_db) { |
| 120 |
$home_url_from_db = ""; |
| 121 |
} |
| 122 |
|
| 123 |
$result->home_url_db = trim($home_url_from_db, "/"); |
| 124 |
$result->home_url_constant = trim((defined('WP_HOME') ? WP_HOME : ""), "/"); |
| 125 |
|
| 126 |
// Get max allowed packet size from sql |
| 127 |
$result->max_allowed_packet_size = (int) $wpdb->get_row("SHOW VARIABLES LIKE 'max_allowed_packet'")->Value; |
| 128 |
// Get max post size |
| 129 |
$result->max_post_size = $commonfunctions->convertPHPSizeToBytes(ini_get('post_max_size')); |
| 130 |
if ($result->max_post_size < 1) { |
| 131 |
// If set to 0, which mean unlimited, we just set it to 100mb |
| 132 |
$result->max_post_size = 104857600; |
| 133 |
} |
| 134 |
// Get memory limit |
| 135 |
$result->memory_limit = $commonfunctions->convertPHPSizeToBytes(ini_get('memory_limit')); |
| 136 |
// If set to -1, which mean unlimited, we just set it to 512mb |
| 137 |
if ($result->memory_limit < 1) { |
| 138 |
$result->memory_limit = 536870912; |
| 139 |
} |
| 140 |
// MySQL version |
| 141 |
$result->sql_version = $wpdb->get_var("select VERSION()"); |
| 142 |
// WP Synchro plugin version |
| 143 |
$result->plugin_version = WPSYNCHRO_VERSION . " " . (\WPSynchro\Utilities\CommonFunctions::isPremiumVersion() ? 'PRO' : 'FREE'); |
| 144 |
// WP version |
| 145 |
include ABSPATH . WPINC . '/version.php'; |
| 146 |
$result->wp_version = $wp_version; |
| 147 |
// Get whether the MU plugin is enabled |
| 148 |
$result->mu_plugin_enabled = defined('WPSYNCHRO_MU_COMPATIBILITY_VERSION'); |
| 149 |
|
| 150 |
// Add whether database contains tables with different prefix |
| 151 |
$database_helper_functions = new \WPSynchro\Database\DatabaseHelperFunctions(); |
| 152 |
$result->database_contains_tables_with_different_prefix = $database_helper_functions->databaseContainsTablesWithDifferentPrefix(); |
| 153 |
|
| 154 |
return $result; |
| 155 |
} |
| 156 |
|
| 157 |
/** |
| 158 |
* Get data on multisite, if it is multisite, ofc... |
| 159 |
*/ |
| 160 |
public function getMultisiteData() |
| 161 |
{ |
| 162 |
$multisite = new \stdClass(); |
| 163 |
$is_multisite = false; |
| 164 |
if (is_multisite()) { |
| 165 |
$is_multisite = true; |
| 166 |
$multisite->is_multisite = true; |
| 167 |
|
| 168 |
// Detect the "main" site blog id |
| 169 |
$multisite->main_blog_id = get_network()->site_id; |
| 170 |
$multisite->current_blog_id = get_current_blog_id(); |
| 171 |
$multisite->is_main_site = ($multisite->main_blog_id === $multisite->current_blog_id); |
| 172 |
|
| 173 |
// Add list of other blogs |
| 174 |
$sitelist = get_sites(); |
| 175 |
$multisite->blogs = []; |
| 176 |
foreach ($sitelist as $site) { |
| 177 |
$blog = new \stdClass(); |
| 178 |
$blog->id = $site->blog_id; |
| 179 |
$blog->domain = $site->domain; |
| 180 |
$blog->path = $site->path; |
| 181 |
$multisite->blogs[] = $blog; |
| 182 |
} |
| 183 |
|
| 184 |
// Get the first super admin, to have a user_id to assign content to |
| 185 |
$super_admin = get_super_admins(); |
| 186 |
if (count($super_admin) > 0) { |
| 187 |
$multisite->default_super_admin_id = username_exists($super_admin[0]); |
| 188 |
$multisite->default_super_admin_username = $super_admin[0]; |
| 189 |
} else { |
| 190 |
$multisite->default_super_admin_id = 0; |
| 191 |
$multisite->default_super_admin_username = ""; |
| 192 |
} |
| 193 |
} else { |
| 194 |
$multisite->is_multisite = false; |
| 195 |
$multisite->is_main_site = false; |
| 196 |
} |
| 197 |
$multisite->defined_uploads_location = defined("UPLOADS") ? UPLOADS : ""; |
| 198 |
|
| 199 |
return $multisite; |
| 200 |
} |
| 201 |
|
| 202 |
/** |
| 203 |
* Get basic data on database |
| 204 |
*/ |
| 205 |
public function getBasicDatabaseData() |
| 206 |
{ |
| 207 |
global $wpdb; |
| 208 |
|
| 209 |
$tables_sql = $wpdb->get_col('SHOW TABLES'); |
| 210 |
|
| 211 |
$tables = []; |
| 212 |
foreach ($tables_sql as $tablename) { |
| 213 |
// If temp table, just skip it |
| 214 |
if (strpos($tablename, DatabaseSync::TMP_TABLE_PREFIX) === 0) { |
| 215 |
continue; |
| 216 |
} |
| 217 |
// Check if table should be excluded, such as WP Synchro tables |
| 218 |
if ($this->shouldTableBeExcluded($tablename)) { |
| 219 |
continue; |
| 220 |
} |
| 221 |
$tables[] = $tablename; |
| 222 |
} |
| 223 |
return $tables; |
| 224 |
} |
| 225 |
|
| 226 |
/** |
| 227 |
* Get details on database |
| 228 |
*/ |
| 229 |
public function getDetailsDatabaseData() |
| 230 |
{ |
| 231 |
global $wpdb; |
| 232 |
$result = new \stdClass(); |
| 233 |
$tables_sql = $wpdb->get_results('SHOW TABLE STATUS'); |
| 234 |
$tables_details = []; |
| 235 |
$table_tmptables_details = []; |
| 236 |
foreach ($tables_sql as $tb) { |
| 237 |
// Check if table should be excluded, such as WP Synchro tables |
| 238 |
if ($this->shouldTableBeExcluded($tb->Name)) { |
| 239 |
continue; |
| 240 |
} |
| 241 |
|
| 242 |
// Get the actual count on rows, because show table status is not precise |
| 243 |
$exactrows = $wpdb->get_var("SELECT COUNT(*) FROM `" . $tb->Name . "`"); |
| 244 |
$new_table = new Table(); |
| 245 |
$new_table->name = $tb->Name; |
| 246 |
$new_table->rows = intval($exactrows); |
| 247 |
$new_table->completed_rows = 0; |
| 248 |
$new_table->row_avg_bytes = $tb->Avg_row_length; |
| 249 |
$new_table->data_total_bytes = $tb->Data_length; |
| 250 |
|
| 251 |
// Fix some cases, where row_avg_bytes are reported to be 0, even if there is some rows |
| 252 |
if ($new_table->rows > 0 && $new_table->row_avg_bytes == 0) { |
| 253 |
$new_table->row_avg_bytes = 8192; |
| 254 |
} |
| 255 |
|
| 256 |
// If temp table, add to seperate array (mostly used in finalize) |
| 257 |
if (strpos($new_table->name, DatabaseSync::TMP_TABLE_PREFIX) === 0) { |
| 258 |
$table_tmptables_details[] = $new_table; |
| 259 |
} else { |
| 260 |
$tables_details[] = $new_table; |
| 261 |
} |
| 262 |
} |
| 263 |
|
| 264 |
// Show create table |
| 265 |
foreach ($tables_details as &$tb) { |
| 266 |
$createsql = $wpdb->get_row('show create table `' . $tb->name . '`', ARRAY_N); |
| 267 |
$createsql[1] = mb_convert_encoding($createsql[1], 'UTF-8', 'UTF-8'); |
| 268 |
$tb->create_table = $createsql[1]; |
| 269 |
|
| 270 |
// If it is a view, make sure we mark it as one and clean it up a bit |
| 271 |
if (preg_match('#\CREATE[^\]]+\VIEW `#', $tb->create_table)) { |
| 272 |
$cleaned_view_create = preg_replace('#\CREATE[^\]]+\VIEW `#', '', $tb->create_table); |
| 273 |
$tb->create_table = "CREATE VIEW `" . $cleaned_view_create; |
| 274 |
$tb->is_view = true; |
| 275 |
} |
| 276 |
|
| 277 |
// Clean up CREATE statement |
| 278 |
$tb->create_table = $this->cleanUpCreateStatement($tb->create_table); |
| 279 |
} |
| 280 |
|
| 281 |
// Get primary key (for faster data fetch) |
| 282 |
foreach ($tables_details as &$tb) { |
| 283 |
$primarysql_key = $wpdb->get_results('SHOW KEYS FROM `' . $tb->name . '` WHERE Key_name = "PRIMARY"', ARRAY_N); |
| 284 |
// Check if composite key |
| 285 |
if ($primarysql_key && count($primarysql_key) > 1) { |
| 286 |
// Primary key is composite, so we dont use it |
| 287 |
$tb->primary_key_column = ""; |
| 288 |
} elseif (isset($primarysql_key[0][4])) { |
| 289 |
$tb->primary_key_column = $primarysql_key[0][4]; |
| 290 |
if (!$this->isPrimaryIndexNumeric($tb->create_table, $tb->primary_key_column)) { |
| 291 |
$tb->primary_key_column = ""; |
| 292 |
} |
| 293 |
} else { |
| 294 |
$tb->primary_key_column = ""; |
| 295 |
} |
| 296 |
} |
| 297 |
|
| 298 |
// Check for speciel columns, ex blob's |
| 299 |
foreach ($tables_details as &$tb) { |
| 300 |
$tb->column_types = $this->extractColumnsTypeFromSQLCreate($tb->create_table); |
| 301 |
} |
| 302 |
|
| 303 |
$result->dbdetails = $tables_details; |
| 304 |
$result->tmptables_dbdetails = $table_tmptables_details; |
| 305 |
|
| 306 |
return $result; |
| 307 |
} |
| 308 |
|
| 309 |
/** |
| 310 |
* Clean up create statement |
| 311 |
*/ |
| 312 |
public function cleanUpCreateStatement($create_statement) |
| 313 |
{ |
| 314 |
// Change any fields enclosed with " to backticks ` (looking at you MySQL 8...) |
| 315 |
$backtick_matches = []; |
| 316 |
preg_match_all('/\s+"(\S+)"\s/', $create_statement, $backtick_matches); |
| 317 |
if (isset($backtick_matches[1])) { |
| 318 |
foreach ($backtick_matches[1] as $match) { |
| 319 |
$create_statement = str_replace('"' . $match . '"', '`' . $match . '`', $create_statement); |
| 320 |
} |
| 321 |
} |
| 322 |
|
| 323 |
return $create_statement; |
| 324 |
} |
| 325 |
|
| 326 |
|
| 327 |
/** |
| 328 |
* Get file details data |
| 329 |
*/ |
| 330 |
public function getFileDetailsData() |
| 331 |
{ |
| 332 |
$commonfunctions = new CommonFunctions(); |
| 333 |
|
| 334 |
$result = new \stdClass(); |
| 335 |
|
| 336 |
// Web root |
| 337 |
$documentroot = untrailingslashit($commonfunctions->fixPath(realpath($_SERVER['DOCUMENT_ROOT']))); |
| 338 |
if (is_multisite()) { |
| 339 |
$homeurl = parse_url(network_site_url('/')); |
| 340 |
} else { |
| 341 |
$homeurl = parse_url(home_url('/')); |
| 342 |
} |
| 343 |
$pathcomponent = $commonfunctions->fixPath($homeurl['path']); |
| 344 |
$home_dir = untrailingslashit($documentroot . $pathcomponent); |
| 345 |
|
| 346 |
$result->files_home_dir_readwrite = static::checkReadWriteOnDir($home_dir); |
| 347 |
$result->files_home_dir = $home_dir; |
| 348 |
|
| 349 |
// One dir above webroot |
| 350 |
$files_above_webroot_dir = untrailingslashit(dirname($result->files_home_dir)); |
| 351 |
$result->files_above_webroot_dir_readwrite = static::checkReadWriteOnDir($files_above_webroot_dir); |
| 352 |
$result->files_above_webroot_dir = $commonfunctions->fixPath($files_above_webroot_dir); |
| 353 |
|
| 354 |
// Absolut directory of WordPress root folder |
| 355 |
$result->files_wp_dir = untrailingslashit($commonfunctions->fixPath(ABSPATH)); |
| 356 |
$result->files_wp_dir_readwrite = static::checkReadWriteOnDir($result->files_wp_dir); |
| 357 |
|
| 358 |
// Absolut directory of WP_CONTENT folder, or whatever it is called |
| 359 |
$result->files_wp_content_dir = untrailingslashit($commonfunctions->fixPath(WP_CONTENT_DIR)); |
| 360 |
$result->files_wp_content_dir_readwrite = static::checkReadWriteOnDir($result->files_wp_content_dir); |
| 361 |
|
| 362 |
// Plugins dir |
| 363 |
$result->files_plugins_dir = untrailingslashit($commonfunctions->fixPath(WP_PLUGIN_DIR)); |
| 364 |
$result->files_plugins_dir_readwrite = static::checkReadWriteOnDir($result->files_plugins_dir); |
| 365 |
|
| 366 |
// Themes dir |
| 367 |
$result->files_themes_dir = untrailingslashit($commonfunctions->fixPath(get_theme_root())); |
| 368 |
$result->files_themes_dir_readwrite = static::checkReadWriteOnDir($result->files_themes_dir); |
| 369 |
|
| 370 |
// Uploads dir |
| 371 |
$upload_dir_obj = wp_upload_dir(); |
| 372 |
$result->files_uploads_dir = untrailingslashit($commonfunctions->fixPath($upload_dir_obj['basedir'])); |
| 373 |
$result->files_uploads_dir_readwrite = static::checkReadWriteOnDir($result->files_uploads_dir); |
| 374 |
|
| 375 |
// Get plugin list |
| 376 |
$result->files_plugin_list = []; |
| 377 |
if (!function_exists('get_plugins')) { |
| 378 |
require_once(ABSPATH . '/wp-admin/includes/plugin.php'); |
| 379 |
} |
| 380 |
$all_pluginlist = \get_plugins(); |
| 381 |
foreach ($all_pluginlist as $pluginslug => $plugindata) { |
| 382 |
$tmp_arr = []; |
| 383 |
$tmp_arr['slug'] = $pluginslug; |
| 384 |
$tmp_arr['name'] = $plugindata['Name']; |
| 385 |
|
| 386 |
$result->files_plugin_list[] = $tmp_arr; |
| 387 |
} |
| 388 |
// Get theme list |
| 389 |
$result->files_theme_list = []; |
| 390 |
$all_themeslist = \wp_get_themes(); |
| 391 |
foreach ($all_themeslist as $themeslug => $wp_theme) { |
| 392 |
$tmp_arr = []; |
| 393 |
$tmp_arr['slug'] = $themeslug; |
| 394 |
$tmp_arr['name'] = $wp_theme->get("Name"); |
| 395 |
|
| 396 |
$result->files_theme_list[] = $tmp_arr; |
| 397 |
} |
| 398 |
return $result; |
| 399 |
} |
| 400 |
|
| 401 |
/** |
| 402 |
* Check if table should be excluded |
| 403 |
*/ |
| 404 |
public function shouldTableBeExcluded($tablename) |
| 405 |
{ |
| 406 |
$exclude_this_table = false; |
| 407 |
|
| 408 |
if (strpos($tablename, DatabaseSync::TMP_TABLE_PREFIX) === 0) { |
| 409 |
return false; |
| 410 |
} |
| 411 |
|
| 412 |
foreach ($this->tables_to_exclude as $excludedtable) { |
| 413 |
if (stripos($tablename, $excludedtable) !== false) { |
| 414 |
$exclude_this_table = true; |
| 415 |
break; |
| 416 |
} |
| 417 |
} |
| 418 |
if ($exclude_this_table) { |
| 419 |
return true; |
| 420 |
} |
| 421 |
|
| 422 |
// If it is multisite and mainsite, show all. If subsite, only show global users and usermeta and the subsite tables |
| 423 |
if (is_multisite() && get_current_blog_id() != get_network()->site_id) { |
| 424 |
global $wpdb; |
| 425 |
$currentblog_id = get_current_blog_id(); |
| 426 |
// Get global prefix |
| 427 |
switch_to_blog(get_network()->site_id); |
| 428 |
$global_tables = [$wpdb->prefix . "users", $wpdb->prefix . "usermeta"]; |
| 429 |
restore_current_blog(); |
| 430 |
if (strpos($tablename, $wpdb->prefix) !== 0) { |
| 431 |
$exclude_this_table = true; |
| 432 |
} |
| 433 |
if (in_array($tablename, $global_tables)) { |
| 434 |
$exclude_this_table = false; |
| 435 |
} |
| 436 |
} |
| 437 |
|
| 438 |
return $exclude_this_table; |
| 439 |
} |
| 440 |
|
| 441 |
/** |
| 442 |
* Function to extract the columns "super"-type |
| 443 |
*/ |
| 444 |
public function extractColumnsTypeFromSQLCreate($sqlcreate) |
| 445 |
{ |
| 446 |
$columns = new TableColumns(); |
| 447 |
|
| 448 |
$lines = explode("\n", $sqlcreate); |
| 449 |
foreach ($lines as $line) { |
| 450 |
if (strpos(trim($line), "`") != 0) { |
| 451 |
continue; |
| 452 |
} |
| 453 |
|
| 454 |
$parts = explode("`", $line); |
| 455 |
if (isset($parts[1]) && isset($parts[2])) { |
| 456 |
// Search the column type for types we know to be |
| 457 |
$splitted = preg_split("/[\s,(]+/", trim($parts[2])); |
| 458 |
$columntype = strtolower($splitted[0]); |
| 459 |
|
| 460 |
$found = false; |
| 461 |
$colname = trim($parts[1]); |
| 462 |
|
| 463 |
// Check if we have a generated column |
| 464 |
if (strpos($line, ' GENERATED ') !== false) { |
| 465 |
$columns->generated[$colname] = $colname; |
| 466 |
} |
| 467 |
|
| 468 |
// Check if string type insert |
| 469 |
foreach ($this->string_columns_types as $search) { |
| 470 |
if ($columntype == $search) { |
| 471 |
$found = true; |
| 472 |
$columns->string[$colname] = $colname; |
| 473 |
$columns->addColumnTypeUsed($columntype); |
| 474 |
break; |
| 475 |
} |
| 476 |
} |
| 477 |
|
| 478 |
if ($found) { |
| 479 |
continue; |
| 480 |
} |
| 481 |
|
| 482 |
// Check if numeric type insert |
| 483 |
foreach ($this->numeric_column_types as $search) { |
| 484 |
if ($columntype == $search) { |
| 485 |
$found = true; |
| 486 |
$columns->numeric[$colname] = $colname; |
| 487 |
$columns->addColumnTypeUsed($columntype); |
| 488 |
break; |
| 489 |
} |
| 490 |
} |
| 491 |
|
| 492 |
if ($found) { |
| 493 |
continue; |
| 494 |
} |
| 495 |
|
| 496 |
// Check if numeric type insert |
| 497 |
foreach ($this->binary_column_types as $search) { |
| 498 |
if ($columntype == $search) { |
| 499 |
$found = true; |
| 500 |
$columns->binary[$colname] = $colname; |
| 501 |
$columns->addColumnTypeUsed($columntype); |
| 502 |
break; |
| 503 |
} |
| 504 |
} |
| 505 |
|
| 506 |
if ($found) { |
| 507 |
continue; |
| 508 |
} |
| 509 |
|
| 510 |
// Check if numeric type insert |
| 511 |
foreach ($this->bit_column_types as $search) { |
| 512 |
if ($columntype == $search) { |
| 513 |
$found = true; |
| 514 |
$columns->bit[$colname] = $colname; |
| 515 |
$columns->addColumnTypeUsed($columntype); |
| 516 |
break; |
| 517 |
} |
| 518 |
} |
| 519 |
|
| 520 |
if (!$found) { |
| 521 |
$columns->unknown[$colname] = $colname; |
| 522 |
} |
| 523 |
} |
| 524 |
} |
| 525 |
|
| 526 |
return $columns; |
| 527 |
} |
| 528 |
|
| 529 |
/** |
| 530 |
* Function to determine if primary index is numeric |
| 531 |
*/ |
| 532 |
public function isPrimaryIndexNumeric($sqlcreate, $column) |
| 533 |
{ |
| 534 |
if ($column == "") { |
| 535 |
return false; |
| 536 |
} |
| 537 |
|
| 538 |
$lines = explode("\n", $sqlcreate); |
| 539 |
$column = '`' . $column . '`'; |
| 540 |
foreach ($lines as $line) { |
| 541 |
if (strpos($line, $column) > -1) { |
| 542 |
$parts = explode("`", $line); |
| 543 |
$col_part = trim($parts[2]); |
| 544 |
$col_parts = explode(" ", $col_part); |
| 545 |
|
| 546 |
foreach ($this->numeric_column_types as $num_col_type) { |
| 547 |
if (strpos($col_parts[0], $num_col_type) > -1) { |
| 548 |
return true; |
| 549 |
} |
| 550 |
} |
| 551 |
} |
| 552 |
} |
| 553 |
return false; |
| 554 |
} |
| 555 |
|
| 556 |
/** |
| 557 |
* Function to check if dir can be read/written to |
| 558 |
*/ |
| 559 |
public static function checkReadWriteOnDir($dir) |
| 560 |
{ |
| 561 |
// Default error handler is required |
| 562 |
set_error_handler(null); |
| 563 |
@trigger_error('__clean_error_info'); |
| 564 |
|
| 565 |
// Testing... |
| 566 |
@is_writable($dir); |
| 567 |
@is_readable($dir); |
| 568 |
|
| 569 |
// Restore previous error handler |
| 570 |
restore_error_handler(); |
| 571 |
|
| 572 |
$error = error_get_last(); |
| 573 |
return $error['message'] === '__clean_error_info'; |
| 574 |
} |
| 575 |
} |
| 576 |
|