Файловый менеджер - Редактировать - /home/lexlmvtu/public_html/wp-content/plugins/backup-backup/includes/database/smart-sort.php
Назад
<?php /** * Author: Mikołaj `iClyde` Chodorowski * Contact: kontakt@iclyde.pl * Package: Backup Migration – WP Plugin * Version: 2.0 */ // Namespace namespace BMI\Plugin\Database; // Use use BMI\Plugin\BMI_Logger AS Logger; use BMI\Plugin\Progress\BMI_ZipProgress AS Progress; // // Exit on direct access if (!defined('ABSPATH')) exit; /** * Database sort method * Usage: Create new object and use "sortUnsorted" function */ class BMI_Database_Sorting { /** * Path to database files made with V2 engine */ private $db_files_root; private $output_file_stream; private $name_of_finished_tables_dir = 'bmi_converted_completed_tables'; private $progress; private $isCLI; private $unwantedTables = [ 'wfblockediplog', 'wfblocks7', 'wfcrawlers', 'wffilechanges', 'wffilemods', 'wfhits', 'wfhoover', 'wfissues', 'wfknownfilelist', 'wflivetraffichuman', 'wflocs', 'wflogins', 'wfnotifications', 'wfpendingissues', 'wfreversecache', 'wfsnipcache', 'wfstatus', 'wftrafficrate', 'actionscheduler_logs', 'slim_stats', 'woocommerce_sessions', 'yoast_indexable', 'slim_events', 'cerber_files', 'cerber_traffic', 'cerber_log', 'cerber_countries', 'cerber_blocks', 'cerber_acl' ]; /** * __construct - description * * @param {string} $db_root Path to database files * @return void */ function __construct($db_root, &$progress, $isCLI) { /** * Set path to the root directory */ $this->db_files_root = $db_root; $this->progress = $progress; $this->isCLI = $isCLI; } /** * sortUnsorted - Main function which dynamically sorts the tables (main function) * * @param {array} $processData = [] Data of process to be continued or empty array to start * Requires keys [ 'index', 'insert', 'file', 'table_name', 'dir', 'unique', 'destinationFile' ] * Optional key: convertionFinished * * @return array of [ 'index', 'insert', 'file', 'table_name', 'dir', 'unique', 'destinationFile' ] */ public function sortUnsorted($processData = []) { // Sort the SQL files into directories $this->putDatabaseFilesInDirectories(); // Split files into partial files (query per batch) $process = $this->splitFilesInSeparateDirectories($processData); // Check if all tables finished and move them outside completed directory if ($this->doesTablesFinished()) { // Move them outside $this->moveAllConvertedTables(); // Check if process finished if ($this->isCLI || (is_array($process) && array_key_exists('completed', $process) && $process['completed'] == 'yes')) { $process['convertionFinished'] = 'yes'; } } // Return process for that return $process; } /** * doesTablesFinished - Checks if there is any table that didn't finish * * @return {bool} true or false */ private function doesTablesFinished() { // Scan all files in root $allFiles = scandir($this->db_files_root); $files = array_diff($allFiles, array('.', '..', $this->name_of_finished_tables_dir)); // If no other directories here that means nothing to convert left if (sizeof($files) <= 0) { // Return true for that return true; } else { // Otherwise it's false return false; } } /** * putDatabaseFilesInDirectories - It puts all SQL files into table directories * Does nothing if the root directory does not contain any SQL files * * @return void */ private function putDatabaseFilesInDirectories() { // Scan all files in root $allFiles = scandir($this->db_files_root); $files = array_diff($allFiles, array('.', '..')); // For each found file make sure it's SQL and run merge function foreach ($files as $index => $filename) { // Exclude non .sql files if (substr($filename, -4) != '.sql') continue; // It may be directory with .sql ending, make sure it's not $pathToFile = $this->db_files_root . DIRECTORY_SEPARATOR . $filename; if (is_dir($pathToFile)) continue; // Merge the file $this->mergeFileWithDirectory($filename); } } /** * mergeFileWithDirectory - Merges the file into proper directory * * @param {string} $filename File name which is located in root * @return bool true on success false on failed file move */ private function mergeFileWithDirectory($filename) { // Suffix size which stands for ending ".sql" $suffix_size = 4; // Match output for table name with different name than just table // It may happen when our support used their tools for optimization $match_output = []; preg_match('/_(\d+)\_of\_(\d+)/', $filename, $match_output); // If that's the case, add suffix size as we don't need that info here if (sizeof($match_output) > 0) { $suffix_size += strlen($match_output[0]); } // If we know the suffix size, get table name $table_name = substr($filename, 0, -$suffix_size); // Prepare future paths of the file $dest_dir = $this->db_files_root . DIRECTORY_SEPARATOR . $table_name; $source_path = $this->db_files_root . DIRECTORY_SEPARATOR . $filename; $dest_path = $dest_dir . DIRECTORY_SEPARATOR . $filename; // Check if the directory exists and if it's not make new one if (!file_exists($dest_dir) && !is_dir($dest_dir)) { @mkdir($dest_dir, 0755, true); } // Check if the files is not an duplicate and make sure both will be merged $tries = 2; while (file_exists($dest_path)) { // If file exists already add number at the suffix and try again until unique name $dest_path = substr($dest_path, 0, -4) . '_' . $tries . '.sql'; $tries++; } // If we're sure move the file to correct directory if (rename($source_path, $dest_path)) { // Return true on success return true; } else { // Return false on fail return false; } } /** * countAllFilesAndQueries - Counts all files inside directory and returns all query count * * @return {array} of total_queries, total_size, all_tables and all_files */ public function countAllFilesAndQueries() { // Scan all files in root $allFiles = scandir($this->db_files_root); $folders = array_diff($allFiles, array('.', '..', $this->name_of_finished_tables_dir)); // Tables $tables = []; // Files $files = []; // Total size $total_size = 0; // For each found file make sure it's SQL and run merge function foreach ($folders as $index => $filename) { // Path to that file/directory $pathToFile = $this->db_files_root . DIRECTORY_SEPARATOR . $filename; // Hanlde only dirs if (is_dir($pathToFile)) { // Add table information $tables[$filename] = 0; // Scan SQL files $allSQLFiles = scandir($pathToFile); $allSQLFilesParsed = array_diff($allSQLFiles, array('.', '..')); // Go throught these files foreach ($allSQLFilesParsed as $indexSQL => $filenameSQL) { // Exclude non .sql files if (substr($filenameSQL, -4) != '.sql') continue; // Get size of that file $size = filesize($pathToFile . DIRECTORY_SEPARATOR . $filenameSQL); // Add size in total and table $tables[$filename] += $size; $total_size += $size; // Add that file to all files $files[] = $filenameSQL; } } } // Prepare stats variable $stats = [ 'total_queries' => (sizeof($files) * 5), 'total_size' => $total_size, 'all_tables' => $tables, 'all_files' => $files ]; return $stats; } /** * countTablesDuringProcess - Counts tables even during process * * @return array $done, $progress, $total */ private function countTablesDuringProcess() { $theFinalCount = 0; $progressCount = 0; $doneCount = 0; // Scan all files in root (now everything should be directory) $allFiles = scandir($this->db_files_root); $files = array_diff($allFiles, array('.', '..', $this->name_of_finished_tables_dir)); foreach ($files as $index => $filename) { if (is_dir($this->db_files_root . DIRECTORY_SEPARATOR . $filename)) { $theFinalCount++; $progressCount++; } } $doneDir = $this->db_files_root . DIRECTORY_SEPARATOR . $this->name_of_finished_tables_dir; if (file_exists($doneDir) && is_dir($doneDir)) { $allDoneFiles = scandir($doneDir); $doneFiles = array_diff($allDoneFiles, array('.', '..')); foreach ($doneFiles as $index => $filename) { if (is_dir($doneDir . DIRECTORY_SEPARATOR . $filename)) { $theFinalCount++; $doneCount++; } } } return [ 'done' => $doneCount, 'in_progress' => $progressCount, 'total' => $theFinalCount ]; } /** * logFinished - Shows progress of the process in the log file * * @return void */ private function logFinished($dir, $filename) { $counts = $this->countTablesDuringProcess(); $progress = ($counts['done'] + 1) . '/' . $counts['total'] . ' (' . number_format((($counts['done'] + 1) / $counts['total']) * 100, 2) . '%)'; $translated = __('Finished %progress%: %filename% table, total of %parts% parts.', 'backup-backup'); // Get part amount $partsAll = scandir($dir); $parts = sizeof(array_diff($partsAll, array('.', '..', $this->name_of_finished_tables_dir))); $theLog = str_replace('%progress%', $progress, $translated); $theLog = str_replace('%filename%', $filename, $theLog); $theLog = str_replace('%parts%', $parts, $theLog); $this->progress->log($theLog, 'SUCCESS'); $percentage = number_format((($counts['done'] + 1) / $counts['total']) * 100, 2); $this->progress->progress((50 + ($percentage / 4)), 'INFO'); } /** * splitInDirectories - Splits file into parts inside proper directory * @param {array} $processData Process data to be continued * * @return void */ private function splitFilesInSeparateDirectories($processData = []) { // Local process variable $process = []; // Scan all files in root (now everything should be directory) $allFiles = scandir($this->db_files_root); $files = array_diff($allFiles, array('.', '..', $this->name_of_finished_tables_dir)); // Loop all tables and split them one by one foreach ($files as $index => $filename) { // Prepate path to the SQL file which should be converted $dir = $this->db_files_root . DIRECTORY_SEPARATOR . $filename; // Always double check if it's directory otherwise we may get some unexpected errors if (!is_dir($dir)) continue; // Log the new file which will be processed $destinationFile = $this->makeDestinationFilename($dir, $filename); $destinationIndex = $destinationFile['index']; // Log only if it's first batch if ($destinationIndex == 1) { $this->progress->log(str_replace('%s', $filename, __('Starting conversion of: %s table.', 'backup-backup')), 'INFO'); } // Dynamically find file to shrink and split it $process = $this->splitFileInTableDirectory($dir, $filename, $processData); // If it's not CLI use batching if (!$this->isCLI) { // If process finished if (is_array($process) && array_key_exists('completed', $process) && $process['completed'] == 'yes') { // Show in the log file the progress $this->logFinished($dir, $filename); // Check if directory for completed tables exist and make it if it is not $doneDirectory = $this->db_files_root . DIRECTORY_SEPARATOR . $this->name_of_finished_tables_dir; if (!file_exists($doneDirectory) && !is_dir($doneDirectory)) { @mkdir($doneDirectory, 0755, true); } // Move the table into completed directory rename($dir, $doneDirectory . DIRECTORY_SEPARATOR . $filename); // Return process even empty return $process; } else { // If didn't finished that table return process data for next batch to finish return $process; } } else { // Show in the log file the progress $this->logFinished($dir, $filename); // Check if directory for completed tables exist and make it if it is not $doneDirectory = $this->db_files_root . DIRECTORY_SEPARATOR . $this->name_of_finished_tables_dir; if (!file_exists($doneDirectory) && !is_dir($doneDirectory)) { @mkdir($doneDirectory, 0755, true); } // Move the table into completed directory rename($dir, $doneDirectory . DIRECTORY_SEPARATOR . $filename); } } } /** * splitFileInTableDirectory - Splits file into parts for easier progress read and performance * * @param {string} $dir Path to parent directory of table SQL files * @param {string} $table_name Table name (current directory name) * @param {array} $processData Process data to be continued * @return void */ private function splitFileInTableDirectory($dir, $table_name, $processData = []) { // Prepare local var for process data $process = []; // Get all database files inside that directory (it can contain multiple files alrady) $allFiles = scandir($dir); $files = array_diff($allFiles, array('.', '..')); // Loop throught all of them and apply splitting foreach ($files as $index => $filename) { // Just to triple check that parent is a valid directory if (!is_dir($dir)) continue; // Prepare exact path to the SQL file $file = $dir . DIRECTORY_SEPARATOR . $filename; // Run splitting function for that file $process = $this->splitDatabaseFile($file, $dir, $table_name, $processData); // Break each query if not CLI if (!$this->isCLI) { break; } } // If CLI only rename files without return if ($this->isCLI) { // Rename splited files $this->renameSplitedFiles($dir); } else { // Check if process for that table completed and rename if so if (is_array($process) && array_key_exists('completed', $process) && $process['completed'] == 'yes') { // Rename splited files $this->renameSplitedFiles($dir); // Return empty process data as we will iterate new file in next batch return [ 'index' => 0, 'insert' => 'no', 'completed' => 'yes' ]; } else { // Or just return process data for future use (next batch) return $process; } } } /** * logPartial - Logs partial progress to the output log * * @param {string} $dir Directory of the table * @param {string} $table_name Name of the table * @return void */ private function logPartial($dir, $table_name) { // Get part amount $partsAll = scandir($dir); $parts = sizeof(array_diff($partsAll, array('.', '..', $this->name_of_finished_tables_dir))); $parts = $parts - 1; // Prepare log string $logString = __('Finished part %part% of %table% table.', 'backup-backup'); $logString = str_replace('%table%', $table_name, $logString); $logString = str_replace('%part%', $parts, $logString); // Log the string to output $this->progress->log($logString, 'INFO'); } /** * splitDatabaseFile - Splits a SQL file into parts * * @param {string} $file Name of the SQL File * @param {string} $dir Full path to the SQL file * @param {string} $table_name Name of the table to which SQL file belong * @param {array} $processData Process data to be continued * @return void */ private function splitDatabaseFile($file, $dir, $table_name, $processData = []) { // Make destionation file and prepare output file stream $destinationFile = $this->makeDestinationFilename($dir, $table_name); $destinationFile = $destinationFile['file']; // Local variables required for the process $table_unique = 0; $is_converted = false; $query_started = false; $custom_vars_started = false; $values_started = false; $insert_next = false; $last_seek = 0; // Resolve not finished process if (!$this->isCLI && is_array($processData) && !empty($processData)) { // Should be file path $file_path & $file (check if the file exist) if (array_key_exists('file', $processData) && file_exists($processData['file'])) { // Set existing file path $file = $processData['file']; // Should be int<make sure> of $last_seek if (array_key_exists('index', $processData)) { $last_seek = intval($processData['index']) + 1; } // Yes | No values {string} of $insert_next if (array_key_exists('insert', $processData)) { $ins = $processData['insert']; if ($ins == 'yes') $insert_next = true; else $insert_next = false; } // Table name of $table_name if (array_key_exists('table_name', $processData)) { $table_name = $processData['table_name']; } // Directory of that table $dir if (array_key_exists('dir', $processData)) { $dir = $processData['dir']; } // Unique for that table $table_unique if (array_key_exists('unique', $processData)) { $table_unique = $processData['unique']; } // Destination File (output) of $destinationFile if (array_key_exists('destinationFile', $processData)) { $destinationFile = $processData['destinationFile']; } } } // Open stream for output file $this->output_file_stream = fopen($destinationFile, 'a+'); // Keep original filename $file_path = $file; // Open SplObject for seek-based reading $file = new \SplFileObject($file); // Go to last line to check how many lines are there $file->seek($file->getSize()); // Calculate total lines in that file $total_lines = $file->key() + 1; for ($i = $last_seek; $i < $total_lines; ++$i) { // Start seek frrom the loop index $file->seek($i); // Get line into string and trim it (it contains new line at the end) $line = trim($file->current()); // Variable for that line, if it's a comment or not $hasComment = false; // Check this only if the size of line is below 24 // Otherwise it's not a comment line and we can ignore that check for better performance if (strlen($line) < 24) { // List of all our comments $c_fs = "/* CONVERTED DB FILE */"; $q_s = "/* QUERY START */"; $q_e = "/* QUERY END */"; $cq_s = "/* CUSTOM VARS START */"; $cq_e = "/* CUSTOM VARS END */"; $v_s = "/* VALUES START */"; $v_e = "/* VALUES END */"; // If it's converted already ignore the file if ($line === $c_fs) { // Mark as converted (it output file be removed by this) $is_converted = true; // And break the loop, no need to continue break; } // Check if it's a query start comment and adjust local variables for that for future know if ($line === $q_s) { $query_started = true; $hasComment = true; } // Check if it's a custom variable section start comment and adjust local variables for that for future know if ($line === $cq_s) { $custom_vars_started = true; $hasComment = true; } // Check if it's a values section start comment and adjust local variables for that for future know if ($line === $v_s) { $values_started = true; $hasComment = true; } // If we are behind a heading insert this line into new output file if ($insert_next && $hasComment) { // Add new line as we trimed it before $line .= "\n"; // Push this to output file $this->insertIntoOutputFile($line, $table_name); // If we already added this line continue to new line continue; } // Handle query ending comment if ($line === $q_e) { // Adjust local variable for that file $query_started = false; // If it's below heading, add new output and generate new heading for output file if ($insert_next) { // Add double ending – it looks much better for our eyes :) $line .= "\n\n"; // Add this line $this->insertIntoOutputFile($line, $table_name); // Close the file as we split per query, we will need new one for new query if (is_resource($this->output_file_stream) || get_resource_type($this->output_file_stream) === 'file') { fclose($this->output_file_stream); } // Check if it's end of the file add 4 lines offset for empty lines // If it's not the end make new heading, otherwise remove new output file if (($i + 4) < $total_lines) { // Make new destination file $destinationFile = $this->makeDestinationFilename($dir, $table_name); $destinationFile = $destinationFile['file']; // Check if we really need that table contents if ($this->checkIfContainName($table_name, $this->unwantedTables)) { $this->progress->log(str_replace('%s', $table_name, __('Cleaning up contents of %s table.', 'backup-backup')), 'INFO'); $insert_next = false; if (!$this->isCLI) { $file = null; if (is_resource($this->output_file_stream) || get_resource_type($this->output_file_stream) === 'file') { fclose($this->output_file_stream); } if (file_exists($destinationFile)) { @unlink($destinationFile); } if (file_exists($file_path)) { @unlink($file_path); } // Return empty for new file return [ 'index' => 0, 'insert' => 'no', 'completed' => 'yes' ]; } } else { // Log partial progress $this->logPartial($dir, $table_name); // Open new stream for new output file $this->output_file_stream = fopen($destinationFile, 'a+'); // Generate new heading $heading = $this->generateNewHeading($table_unique, $table_name); // Put the heading into new file $this->insertIntoOutputFile($heading, $table_name); // Technically only few bytes but with 200 tables it may be few MBs :) // Always unset variables if you don't need them anymore unset($heading); } if (!$this->isCLI) { // Check if the output file is open and close it if it is $file = null; if (is_resource($this->output_file_stream) || get_resource_type($this->output_file_stream) === 'file') { fclose($this->output_file_stream); } // Return latest insert query return [ 'index' => $i, 'insert' => ($insert_next == true ? 'yes' : 'no'), 'file' => $file_path, 'table_name' => $table_name, 'dir' => $dir, 'unique' => $table_unique, 'destinationFile' => $destinationFile ]; } } else { // Log partial progress $this->logPartial($dir, $table_name); } // Continue to new line as we handled this one already continue; } } // Handle Custom Variables ending comment if ($line === $cq_e) { // Adjust local variables for next loops $custom_vars_started = false; } // Handle values ending if ($line === $v_e) { // Adjust local variables for next loops $values_started = false; // If it's after heading add this line into new output file if ($insert_next) { // Add new line as we trimed it before $line .= "\n"; // Insert that line into new file $this->insertIntoOutputFile($line, $table_name); // As we added the line continue to new one continue; } } } // Check if the line is not a comment if (!$hasComment) { // If the line should be a part of query handle that case if ($query_started === true) { // If it's after heading allow to add this line to new output file if ($insert_next) { // Add new line as we trimed it earlier $line .= "\n"; // Insert the line into new file $this->insertIntoOutputFile($line, $table_name); // As we added that line continue to new one continue; } } // Handle custom variables if ($custom_vars_started === true) { // We are interested only into PRE TABLE NAME which contains unique timestamp if (strpos($line, 'PRE_TABLE_NAME')) { // Prepare variable for preg match output $output = []; // Run the preg match function to find the preg_match('/\`(.*)\`/', $line, $output); // Get the unique value from regex output $unique = substr($output[1], 0, 10); // Set the local variable to found unique for future use in the heading $table_unique = $unique; // As we went throught old heading let the script know that it can insert new lines in next loops $insert_next = true; // Prepare new heading for file which will be used in next loops $heading = $this->generateNewHeading($unique, $table_name); // Insert that heading $this->insertIntoOutputFile($heading, $table_name); } } // Handle casual variable line if ($values_started === true) { // If it can insert new output handle it if ($insert_next) { // Insert that line into new file $this->insertIntoOutputFile($line, $table_name); // Free up the memory as this line may be actually above few MBs. unset($line); // Continue to new line as we inserted this one already continue; } } } // Free up the memory as this line may be actually above few MBs. unset($line); } // $total_lines // File size: $file->getSize() / 1024 / 1024 // Check if the output file is open and close it if it is if (is_resource($this->output_file_stream) || get_resource_type($this->output_file_stream) === 'file') { fclose($this->output_file_stream); } // If the file was already converted if ($is_converted === false) { // Empty the SplFileObject stream $file = null; // Remove new output file as there's nothing to do with it @unlink($file_path); } else { // If the convert finished, remove source file as we now have splited files @unlink($destinationFile); } // Empty SplFileObject stream $file = null; // Only if not CLI if (!$this->isCLI) { // Return empty process data as we will iterate new file in next batch return [ 'index' => 0, 'insert' => 'no', 'completed' => 'yes' ]; } } /** * makeHeading - Generates new heading (converted) for output file * * @param {string/int} $unique Unique timestamp generated during backup (all tables have to be part of it) * @param {string} $table_name Table name of current file, required to generate the heading * @return {string} New heading */ private function generateNewHeading($unique, $table_name) { $heading = ''; $heading .= "/* CONVERTED DB FILE */\n\n"; $heading .= "/* QUERY START */\n"; $heading .= "SET foreign_key_checks = 0;\n"; $heading .= "/* QUERY END */\n"; $heading .= "\n"; $heading .= "/* QUERY START */\n"; $heading .= "SET SQL_MODE = '';\n"; $heading .= "/* QUERY END */\n"; $heading .= "\n"; $heading .= "/* QUERY START */\n"; $heading .= "SET time_zone = '+00:00';\n"; $heading .= "/* QUERY END */\n"; $heading .= "\n"; $heading .= "/* QUERY START */\n"; $heading .= "SET NAMES 'utf8';\n"; $heading .= "/* QUERY END */\n"; $heading .= "\n"; $heading .= "/* CUSTOM VARS START */\n"; $heading .= "/* REAL_TABLE_NAME: `" . $table_name . "`; */\n"; $heading .= "/* PRE_TABLE_NAME: `" . $unique . "_" . $table_name . "`; */\n"; $heading .= "/* CUSTOM VARS END */\n"; $heading .= "\n"; return $heading; } /** * insertIntoOutputFile - Puts and output data into new (current) file * * @param {string} &$line Pointer to line, to save the memory * @param {string} $table_name Table name, may be useful for future use * @return void */ private function insertIntoOutputFile(&$line, $table_name) { if (is_resource($this->output_file_stream) || get_resource_type($this->output_file_stream) === 'file') { fwrite($this->output_file_stream, $line); } } /** * destinationFile - Makes unique destionation file name * * @param {string} $dir Full path to the SQL file * @param {string} $table_name Name of the table to which SQL file belong * @return {string} name of the destionation SQL file */ private function makeDestinationFilename($dir, $table_name) { // Start from file number one $i = 1; // Make an assumption that it will be the first file $file = $table_name . '_' . $i . '.sql'; // Loop until it find unqiue name while (file_exists($dir . DIRECTORY_SEPARATOR . $file)) { // Increment each iteration for new filename $i++; // Set new name to check $file = $table_name . '_' . $i . '.sql'; } // Return final file name return ['file' => $dir . DIRECTORY_SEPARATOR . $file, 'index' => $i]; } /** * * renameSplitedFiles - Renames all files after splitting into sorted SQL files * It also gives better progress experience for the user * * @param {string} $directory Path to directory where the rename function should run * @return void */ private function renameSplitedFiles($directory) { // Scan all files after splitting $allFiles = scandir($directory); $files = array_diff($allFiles, array('.', '..')); // Loop throught them and add proper number for each foreach ($files as $index => $filename) { // Make new destination name $newName = substr($filename, 0, -4) . '_of_' . sizeof($files) . '.sql'; // Current file path $file = $directory . DIRECTORY_SEPARATOR . $filename; // Final path (after rename) $finalPathWithName = $directory . DIRECTORY_SEPARATOR . $newName; // Finally rename the file rename($file, $finalPathWithName); } } /** * checkIfContainName - Checks if A (string) is part of B array * * @return bool */ private function checkIfContainName($tableName, $unwantedTables) { $found = false; $tableName = str_replace('-', '', $tableName); $tableName = str_replace('_', '', $tableName); $tableName = strtolower($tableName); for ($i = 0; $i < sizeof($unwantedTables); ++$i) { $name = $unwantedTables[$i]; $name = str_replace('-', '', $name); $name = str_replace('_', '', $name); $name = strtolower($name); if (strpos($tableName, $name) !== false) { $found = true; break; } } return $found; } /** * moveAllConvertedTables - Moves all completed tables outside * * @return void */ private function moveAllConvertedTables() { // Finished directory path $finishedDBDir = $this->db_files_root . DIRECTORY_SEPARATOR . $this->name_of_finished_tables_dir; // Check if it exists if (!file_exists($finishedDBDir) || !is_dir($finishedDBDir)) { return; } // Scan all tables in finished directory $allFiles = scandir($finishedDBDir); $files = array_diff($allFiles, array('.', '..')); // Loop throught them and move outside foreach ($files as $index => $filename) { // Old path $old = $this->db_files_root . DIRECTORY_SEPARATOR . $this->name_of_finished_tables_dir . DIRECTORY_SEPARATOR . $filename; // New path $new = $this->db_files_root . DIRECTORY_SEPARATOR . $filename; // Move that directory to parent rename($old, $new); } // Unlink directory that won't be used as it's (and it should) be empty. if (file_exists($finishedDBDir) && is_dir($finishedDBDir)) { @rmdir($finishedDBDir); } // Return void return; } }
| ver. 1.4 |
Github
|
.
| PHP 7.2.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка