File: /var/www/gosurya-id/wp-content/plugins/akeebabackupwp/app/Awf/Database/Restore/Mysqli.php
<?php
/**
* @package awf
* @copyright Copyright (c)2014-2021 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU GPL version 3 or later
*/
namespace Awf\Database\Restore;
use Awf\Container\Container;
use Awf\Database;
class Mysqli extends Database\Restore
{
/**
* Overloaded constructor, allows us to set up error codes and connect to
* the database.
*
* @param Container $container The container we are attached to
*/
public function __construct(Container $container)
{
parent::__construct($container);
// Set up allowed error codes
$this->allowedErrorCodes = array(
1262,
1263,
1264,
1265, // "Data truncated" warning
1266,
1287,
1299
// , 1406 // "Data too long" error
);
// Set up allowed comment delimiters
$this->comment = array(
'#',
'\'-- ',
'---',
'/*!',
);
// Connect to the database
$this->getDatabase();
// Suppress foreign key checks
if ($this->getParam('foreignkey', 1))
{
$this->db->setQuery('SET FOREIGN_KEY_CHECKS = 0');
try
{
$this->db->execute();
}
catch (\Exception $exc)
{
// Do nothing if that fails. Maybe we can continue with the restoration.
}
}
}
/**
* Overloaded method which will create the database (if it doesn't exist).
*
* @return Database\Driver
*/
protected function getDatabase()
{
// Do I have all I need?
if(!isset($this->container['dbrestore']['dbname']) || !isset($this->container['dbrestore']['dbuser']))
{
throw new \RuntimeException('AWF_RESTORE_ERROR_MISSINGDBDETAILS', 500);
}
if (!is_object($this->db))
{
$db = parent::getDatabase();
try
{
$db->select($this->container['dbrestore']['dbname']);
}
catch (\Exception $exc)
{
// We couldn't connect to the database. Maybe we have to create
// it first. Let's see...
$options = (object)array(
'db_name' => $this->container['dbrestore']['dbname'],
'db_user' => $this->container['dbrestore']['dbuser'],
);
$db->createDatabase($options, true);
$db->select($this->container['dbrestore']['dbname']);
}
// Try to change the database collation, if requested
if ($this->getParam('utf8db', 0))
{
try
{
$db->alterDbCharacterSet($this->container['dbrestore']['dbname']);
}
catch (\Exception $exc)
{
// Ignore any errors
}
}
}
return $this->db;
}
/**
* Processes and runs the query
*
* @param string $query The query to process
*
* @return boolean True on success
*/
protected function processQueryLine($query)
{
$db = $this->getDatabase();
$prefix = $this->getParam('prefix', 'awf_');
$existing = $this->getParam('existing', 'drop');
$forceutf8 = $this->getParam('utf8tables', 0);
$replacesql = $this->getParam('replace', 0);
$changeEncoding = false;
$useDelimiter = false;
// CREATE TABLE query pre-processing
// If the table has a prefix, back it up (if requested). In any case, drop
// the table. before attempting to create it.
if (substr($query, 0, 12) == 'CREATE TABLE')
{
// Yes, try to get the table name
$restOfQuery = trim(substr($query, 12, strlen($query) - 12)); // Rest of query, after CREATE TABLE
// Is there a backtick?
if (substr($restOfQuery, 0, 1) == '`')
{
// There is... Good, we'll just find the matching backtick
$pos = strpos($restOfQuery, '`', 1);
$tableName = substr($restOfQuery, 1, $pos - 1);
}
else
{
// Nope, let's assume the table name ends in the next blank character
$pos = strpos($restOfQuery, ' ', 1);
$tableName = substr($restOfQuery, 1, $pos - 1);
}
unset($restOfQuery);
// Should I back the table up?
if (($prefix != '') && ($existing == 'backup') && (strpos($tableName, '#__') == 0))
{
// It's a table with a prefix, a prefix IS specified and we are asked to back it up.
// Start by dropping any existing backup tables
$backupTable = str_replace('#__', 'bak_', $tableName);
try
{
$db->dropTable($backupTable);
$db->renameTable($tableName, $backupTable);
}
catch (\Exception $exc)
{
// We can't rename the table. Try deleting it.
$db->dropTable($tableName);
}
}
else
{
// Try to drop the table anyway
$db->dropTable($tableName);
}
$changeEncoding = $forceutf8;
}
// CREATE VIEW query pre-processing
// In any case, drop the view before attempting to create it. (Views can't be renamed)
elseif ((substr($query, 0, 7) == 'CREATE ') && (strpos($query, ' VIEW ') !== false))
{
// Yes, try to get the view name
$view_pos = strpos($query, ' VIEW ');
$restOfQuery = trim(substr($query, $view_pos + 6)); // Rest of query, after VIEW string
// Is there a backtick?
if (substr($restOfQuery, 0, 1) == '`')
{
// There is... Good, we'll just find the matching backtick
$pos = strpos($restOfQuery, '`', 1);
$tableName = substr($restOfQuery, 1, $pos - 1);
}
else
{
// Nope, let's assume the table name ends in the next blank character
$pos = strpos($restOfQuery, ' ', 1);
$tableName = substr($restOfQuery, 1, $pos - 1);
}
unset($restOfQuery);
// Try to drop the view anyway
$dropQuery = 'DROP VIEW IF EXISTS `' . $tableName . '`;';
$db->setQuery(trim($dropQuery));
$db->execute();
}
// CREATE PROCEDURE pre-processing
elseif ((substr($query, 0, 7) == 'CREATE ') && (strpos($query, 'PROCEDURE ') !== false))
{
// Try to get the procedure name
$entity_keyword = ' PROCEDURE ';
$entity_pos = strpos($query, $entity_keyword);
$restOfQuery = trim(substr($query, $entity_pos + strlen($entity_keyword))); // Rest of query, after entity key string
// Is there a backtick?
if (substr($restOfQuery, 0, 1) == '`')
{
// There is... Good, we'll just find the matching backtick
$pos = strpos($restOfQuery, '`', 1);
$entity_name = substr($restOfQuery, 1, $pos - 1);
}
else
{
// Nope, let's assume the entity name ends in the next blank character
$pos = strpos($restOfQuery, ' ', 1);
$entity_name = substr($restOfQuery, 1, $pos - 1);
}
unset($restOfQuery);
// Try to drop the entity anyway
$dropQuery = 'DROP' . $entity_keyword . 'IF EXISTS `' . $entity_name . '`;';
$db->setQuery(trim($dropQuery));
$db->execute();
$useDelimiter = true; // Instruct the engine to change the delimiter for this query to //
}
// CREATE FUNCTION pre-processing
elseif ((substr($query, 0, 7) == 'CREATE ') && (strpos($query, 'FUNCTION ') !== false))
{
// Try to get the procedure name
$entity_keyword = ' FUNCTION ';
$entity_pos = strpos($query, $entity_keyword);
$restOfQuery = trim(substr($query, $entity_pos + strlen($entity_keyword))); // Rest of query, after entity key string
// Is there a backtick?
if (substr($restOfQuery, 0, 1) == '`')
{
// There is... Good, we'll just find the matching backtick
$pos = strpos($restOfQuery, '`', 1);
$entity_name = substr($restOfQuery, 1, $pos - 1);
}
else
{
// Nope, let's assume the entity name ends in the next blank character
$pos = strpos($restOfQuery, ' ', 1);
$entity_name = substr($restOfQuery, 1, $pos - 1);
}
unset($restOfQuery);
// Try to drop the entity anyway
$dropQuery = 'DROP' . $entity_keyword . 'IF EXISTS `' . $entity_name . '`;';
$db->setQuery(trim($dropQuery));
$db->execute();
$useDelimiter = true; // Instruct the engine to change the delimiter for this query to //
}
// CREATE TRIGGER pre-processing
elseif ((substr($query, 0, 7) == 'CREATE ') && (strpos($query, 'TRIGGER ') !== false))
{
// Try to get the procedure name
$entity_keyword = ' TRIGGER ';
$entity_pos = strpos($query, $entity_keyword);
$restOfQuery = trim(substr($query, $entity_pos + strlen($entity_keyword))); // Rest of query, after entity key string
// Is there a backtick?
if (substr($restOfQuery, 0, 1) == '`')
{
// There is... Good, we'll just find the matching backtick
$pos = strpos($restOfQuery, '`', 1);
$entity_name = substr($restOfQuery, 1, $pos - 1);
}
else
{
// Nope, let's assume the entity name ends in the next blank character
$pos = strpos($restOfQuery, ' ', 1);
$entity_name = substr($restOfQuery, 1, $pos - 1);
}
unset($restOfQuery);
// Try to drop the entity anyway
$dropQuery = 'DROP' . $entity_keyword . 'IF EXISTS `' . $entity_name . '`;';
$db->setQuery(trim($dropQuery));
$db->execute();
$useDelimiter = true; // Instruct the engine to change the delimiter for this query to //
}
elseif (substr($query, 0, 6) == 'INSERT')
{
if ($replacesql)
{
// Use REPLACE instead of INSERT selected
$query = 'REPLACE ' . substr($query, 7);
}
}
if (!empty($query))
{
if ($useDelimiter)
{
// This doesn't work from PHP
//$this->execute('DELIMITER //');
}
$this->execute($query);
if ($useDelimiter)
{
// This doesn't work from PHP
//$this->execute('DELIMITER ;');
}
// Do we have to force UTF8 encoding?
if ($changeEncoding && isset($tableName))
{
// Get a list of columns
$columns = $db->getTableColumns($tableName);
$mods = array(); // array to hold individual MODIFY COLUMN commands
if (is_array($columns))
{
foreach ($columns as $field => $column)
{
// Make sure we are redefining only columns which do support a collation
$col = (object)$column;
if (empty($col->Collation))
{
continue;
}
$null = $col->Null == 'YES' ? 'NULL' : 'NOT NULL';
$default = is_null($col->Default) ? '' : "DEFAULT '" . $db->escape($col->Default) . "'";
$mods[] = "MODIFY COLUMN `$field` {$col->Type} $null $default COLLATE utf8_general_ci";
}
}
// Begin the modification statement
$sql = "ALTER TABLE `$tableName` ";
// Add commands to modify columns
if (!empty($mods))
{
$sql .= implode(', ', $mods) . ', ';
}
// Add commands to modify the table collation
$sql .= 'DEFAULT CHARACTER SET UTF8 COLLATE utf8_general_ci;';
$db->setQuery($sql);
try
{
$db->execute();
}
catch (\Exception $exc)
{
// Don't fail if the collation could not be changed
}
}
}
return true;
}
}