Current File : /home/pacjaorg/www/nsa/administrator/components/com_sppagebuilder/helpers/maintenance.php |
<?php
/**
* @package SP Page Builder
* @author JoomShaper http://www.joomshaper.com
* @copyright Copyright (c) 2010 - 2021 JoomShaper
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 or later
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;
require_once __DIR__ . '/traits/AuditTablesTrait.php';
require_once __DIR__ . '/traits/AuditTableFieldsTrait.php';
require_once __DIR__ . '/traits/AuditTableFieldTypesTrait.php';
require_once __DIR__ . '/traits/AuditTableFieldNullableTrait.php';
require_once __DIR__ . '/traits/AuditTableFieldDefaultTrait.php';
/**
* SP Page Builder Maintenance script
*
* @since 3.7.5
*/
class Maintenance
{
/**
* HTML contents to render
*
* @var array $html The HTML contents to render
* * @since 3.7.5
*/
private $html = [];
/**
* Missing message HTML Buffer
*
* @var array
* * @since 3.7.5
*/
private $missingBuffer = [];
/**
* Fixed message HTML Buffer
*
* @var array
* * @since 3.7.5
*/
private $fixedBuffer = [];
/**
* Errors array
*
* @var array $errors The errors while performing sql operations
* * @since 3.7.5
*/
private $errors = [];
/**
* Tables structures
*
* @var array $tables The tables structure array
* * @since 3.7.5
*/
private $tables = [];
/**
* Installed table description
*
* @var array $installedTables Installed table description
* * @since 3.7.5
*/
private $installedTables = [];
/**
* Tables fields
*
* @var array $fields The fields of a table
* * @since 3.7.5
*/
private $fields = [];
/**
* Table field types
*
* @var array $types The tables field types
* * @since 3.7.5
*/
private $types = [];
/**
* Table field's default values
*
* @var array $defaults The table field's default values
* * @since 3.7.5
*/
private $defaults = [];
/**
* Nullable fields
*
* @var array $nullables The nullable fields
* * @since 3.7.5
*/
private $nullables = [];
/**
* Database Name
*
* @var string $db The database name.
* * @since 3.7.5
*/
private $db = null;
/**
* Database Prefix
*
* @var string $prefix The database prefix.
* * @since 3.7.5
*/
private $prefix = null;
use AuditTablesTrait;
use AuditTableFieldsTrait;
use AuditTableFieldTypesTrait;
use AuditTableFieldNullableTrait;
use AuditTableFieldDefaultTrait;
/**
* Constructor.
*
* @param object &$subject The object to observe.
* @param array $config An optional associative array of configuration settings.
*
* @since 3.9.0
*/
public function __construct()
{
$this->html = [];
$this->missingBuffer = [];
$this->fixedBuffer = [];
$conf = Factory::getConfig();
$this->db = $conf->get('db', '');
$this->prefix = $conf->get('dbprefix', '');
$this->setSqlModes();
$this->extractSQL();
}
public function run()
{
$app = Factory::getApplication();
$input = $app->input;
$this->auditTables();
$this->generateInstalledTablesDescriptions();
$this->auditMissingFields();
$this->auditRemovedFields();
//$this->auditFieldTypesMismatches();
//$this->auditNullTypeMismatches();
//$this->auditDefaultValueMismatches();
}
public function fix()
{
$this->auditAndFixTables();
$this->generateInstalledTablesDescriptions();
$this->auditAndFixTableFields();
//$this->auditAndFixFieldTypeMismatches();
//$this->auditAndFixNullTypeMismatches();
//$this->auditAndFixDefaultValueMismatches();
}
public function getHtml()
{
return $this->html;
}
public function getErrors()
{
return $this->errors;
}
public function getBuffer($type = 'missing')
{
return $type === 'missing' ? $this->missingBuffer : $this->fixedBuffer;
}
private function setSqlModes()
{
try
{
$db = Factory::getDbo();
$query = "SET GLOBAL SQL_MODE='ALLOW_INVALID_DATES,ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
$db->setQuery($query);
$db->execute();
}
catch (Exception $e)
{
//$this->errors[] = $e->getMessage();
// echo $e->getMessage();
}
}
private function getInstallationFile()
{
$input = Factory::getApplication()->input;
$component = $input->get('option');
if (empty($component))
{
throw new Exception(sprintf('No Component Found!'));
}
$sqlPath = JPATH_ADMINISTRATOR . '/components/' . $component . '/sql/install/mysql/install.mysql.utf8.sql';
if(file_exists($sqlPath))
{
return $sqlPath;
}
return false;
}
private function lines()
{
$sqlFile = $this->getInstallationFile();
if (empty($sqlFile))
{
throw new \Exception('No sql file found!');
}
$file = fopen($sqlFile, 'r');
$lineNumber = 0;
while (($line = fgets($file)) !== false)
{
$lineNumber++;
yield $lineNumber => $line;
}
fclose($file);
}
private function extractSQL()
{
$lastTableEncountered = '';
foreach ($this->lines() as $lineNo => $line)
{
$line = trim($line);
if (preg_match("@^--.*@", $line))
{
continue;
}
if (preg_match("@(?<=\s)`(#__.+)`(?=\s)@", $line, $matches))
{
$lastTableEncountered = $matches[1];
$this->tables[$lastTableEncountered] = [];
}
if (!empty($lastTableEncountered))
{
if (preg_match("@[^\s]+@", $line))
{
$this->tables[$lastTableEncountered][] = $line;
}
}
if (preg_match("@^`(.+)`@", $line, $matches))
{
$this->fields[$lastTableEncountered][$matches[1]] = preg_replace("@,$@", "", $line);
}
if (preg_match("@^`(.+)`\s+((.+(\([\d,\s]+\))|([a-z]+))(\s+unsigned)?)@i", $line, $matches))
{
$this->types[$lastTableEncountered][$matches[1]] = strtolower($matches[2]);
}
if (preg_match("@^`(.+)`(.+(not\s+null))?@i", $line, $matches))
{
$isNull = !empty($matches[3]) ? 'no' : 'yes';
if (preg_match("@default\s+null@i", $line))
{
$isNull = 'yes';
}
$this->nullables[$lastTableEncountered][$matches[1]] = $isNull;
}
if (preg_match("@^`(.+)`.*(?<=default\s)([\'\"])?(?(2)([a-z\d\-_\:\s\*\&\$\?\<\>\!\^\#\%\(\)\{\}\[\]\.]+)|(\b\w+\b))?@i", $line, $matches))
{
if (isset($matches[4]))
{
$value = $matches[4];
}
elseif (isset($matches[3]))
{
$value = $matches[3];
}
else
{
$value = '';
}
$value = strtolower($value) === 'null' ? null : $value;
$this->defaults[$lastTableEncountered][$matches[1]] = $value;
}
}
}
private function generateInstalledTablesDescriptions()
{
if (!empty($this->tables))
{
foreach ($this->tables as $table => $structure)
{
$tableStructure = [];
try
{
$tableStructure = $this->getTableDescription($table);
}
catch (Exception $e)
{
// echo $e->getMessage();
//$this->errors[] = $e->getMessage();
}
if (!empty($tableStructure))
{
$this->installedTables[$table] = $tableStructure;
}
}
}
}
private function getRealTableName($table)
{
return preg_replace("@^#__@", $this->prefix, $table);
}
private function getAllTheInstalledTables()
{
try
{
$db = Factory::getDbo();
$query = $db->getQuery(true);
$query->select('table_name as table_name')
->from($db->quoteName('information_schema.tables'))
->where($db->quoteName('table_schema') . ' = ' . $db->quote($this->db));
$db->setQuery($query);
$tables = $db->loadObjectList();
$output = [];
if (!empty($tables))
{
foreach ($tables as $table)
{
$output[] = $table->table_name;
}
}
return $output;
}
catch (Exception $e)
{
//$this->errors[] = $e->getMessage();
return $e->getMessage();
}
}
private function getTableNames()
{
return array_keys($this->tables);
}
private function getTableColumns($tableName)
{
$columns = [];
try
{
$db = Factory::getDbo();
$columns = $db->getTableColumns($tableName);
}
catch (Exception $e)
{
// echo $e->getMessage();
//$this->errors[] = $e->getMessage();
}
return array_keys($columns);
}
private function getTableDescription($table)
{
$description = [];
try
{
$db = Factory::getDbo();
$sql = "DESCRIBE " . $db->quoteName($table);
$db->setQuery($sql);
$description = $db->loadObjectList();
}
catch (Exception $e)
{
// echo $e->getMessage();
//$this->errors[] = $e->getMessage();
}
return $description;
}
private function getTableInformation($table, $prop)
{
$prop = ucfirst($prop);
$data = !empty($this->installedTables[$table]) ? $this->installedTables[$table] : [];
$information = [];
if (!empty($data))
{
foreach ($data as $row)
{
switch ($prop)
{
case 'Type':
case 'Null':
case 'Key':
$value = strtolower($row->$prop);
break;
default:
$value = $row->$prop;
break;
}
$information[$row->Field] = $value;
}
}
return $information;
}
}