File "Blueprint.php"
Full Path: /home/warrior1/public_html/wp-content/plugins/file-manager/vendor/bitapps/wp-database/src/Blueprint.php
File size: 21.08 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace BitApps\WPDatabase;
if (!\defined('ABSPATH')) {
exit;
}
use Closure;
use Exception;
use RuntimeException;
/**
* Class for schema blueprint.
*
* @method Blueprint char($name, $length = null)
* @method Blueprint varchar($name, $length = null)
* @method Blueprint binary($name, $length = null)
* @method Blueprint json($name, $length = null)
* @method Blueprint varbinary($name, $length = null)
* @method Blueprint tinyblob($name, $length = null)
* @method Blueprint tinytext($name, $length = null)
* @method Blueprint text($name, $length = null)
* @method Blueprint blob($name, $length = null)
* @method Blueprint mediumtext($name, $length = null)
* @method Blueprint mediumblob($name, $length = null)
* @method Blueprint longtext($name, $length = null)
* @method Blueprint longblob($name, $length = null)
* @method Blueprint enum($name, array $enum)
* @method Blueprint set($name, array $set)
* @method Blueprint bit($name, $length = null)
* @method Blueprint tinyint($name, $length = null)
* @method Blueprint bool($name)
* @method Blueprint boolean($name)
* @method Blueprint smallint($name, $length = null)
* @method Blueprint mediumint($name, $length = null)
* @method Blueprint int($name, $length = null)
* @method Blueprint integer($name, $length = null)
* @method Blueprint bigint($name, $length = null)
* @method Blueprint float($name, $length = null)
* @method Blueprint float($name, $length = null)
* @method Blueprint double($name, $length = null)
* @method Blueprint double_precision($name, $length = null)
* @method Blueprint decimal($name, $length = null)
* @method Blueprint dec($name, $length = null)
* @method Blueprint date($name)
* @method Blueprint datetime($name)
* @method Blueprint timestamp($name)
* @method Blueprint time($name)
* @method Blueprint year($name)
*/
class Blueprint
{
public $charset;
public $collation;
public $after;
protected $table;
protected $primaryKey = [];
protected $uniqueIndex = [];
protected $indexColumns = [];
protected $foreignKeys = [];
protected $columns = [];
protected $columnIndex = 0;
protected $columnsToDrop = [];
protected $columnsToRename = [];
protected $method;
private $fkID = '';
private $_sql = '';
private $_rawSql = false;
private $_prefix = '';
private $_edit = [];
private $_newName = '';
/**
* Create a new schema blueprint.
*
* @param string $table Table name
* @param string $method Schema method
* @param string $prefix Table prefix
* @param null|Closure $callback Closure to build the blueprint
*/
public function __construct($table, $method, $prefix = '', Closure $callback = null)
{
$this->_prefix = $prefix;
$this->table = "{$prefix}{$table}";
$this->method = $method;
$this->collation = $this->getCollation();
if ($callback instanceof Closure) {
$callback($this);
}
Connection::suppressError();
}
public function __call($method, $parameters)
{
$formattedMethodName = strtoupper(str_replace('_', ' ', $method));
if ($this->isValidType($formattedMethodName)) {
if (\count($parameters) > 2) {
throw new Exception('Too many parameters');
}
$columnName = $parameters[0];
array_shift($parameters);
return $this->addColumn($columnName, $formattedMethodName, ...$parameters);
}
throw new RuntimeException("Undefined method [ {$method} ] called on Blueprint");
}
public function withPrefix($prefix)
{
$this->table = "{$prefix}{$this->table}";
return $this;
}
public function build()
{
return $this->toSql();
}
public function toSql()
{
switch ($this->method) {
case 'create':
$this->create(true);
break;
case 'drop':
$this->drop();
break;
default:
$this->_rawSql = true;
break;
}
return $this->execute();
}
public function execute()
{
if (\is_null($this->_sql)) {
return false;
}
Connection::query($this->_sql);
$hasError = Connection::prop('last_error');
Connection::restoreErrorState();
if ($hasError) {
throw new RuntimeException($hasError);
}
return true;
}
public function create($isSql = false)
{
if ($isSql) {
if (empty($this->columns)) {
return false;
}
$queryToAdd[] = $this->addColumnQuery();
$queryToAdd[] = $this->addPrimaryKeyQuery();
$queryToAdd[] = $this->addUniqueIndexQuery();
$queryToAdd[] = $this->addIndexQuery();
$queryToAdd[] = $this->addForeignKeyQuery();
$this->_sql = "CREATE TABLE IF NOT EXISTS {$this->table} (
{$this->processQueryArr($queryToAdd)}
) {$this->collation}";
}
return $this;
}
public function edit()
{
$queryToAdd[] = $this->addColumnQuery();
$queryToAdd[] = $this->dropColumnQuery();
$queryToAdd = $queryToAdd + $this->_edit;
$queryToAdd[] = $this->addPrimaryKeyQuery();
$queryToAdd[] = $this->addUniqueIndexQuery();
$queryToAdd[] = $this->addIndexQuery();
$queryToAdd[] = $this->addForeignKeyQuery();
$query = $this->processQueryArr($queryToAdd);
$this->_sql = "ALTER TABLE {$this->table}";
$this->_sql .= " {$query}";
return $this;
}
public function drop()
{
if ($this->method === 'drop') {
$this->_sql = "DROP TABLE IF EXISTS {$this->table}";
}
return $this;
}
public function rename($newName)
{
if ($this->method === 'rename') {
$this->_sql = "ALTER TABLE {$this->table} RENAME TO {$this->_prefix}{$newName}";
} else {
$this->_newName = $newName;
}
return $this;
}
public function addColumn($name, $type, $length = null)
{
if ($this->method === 'addColumn') {
$this->_sql = "ALTER TABLE {$this->table} ADD {$name} {$type}";
if ($length) {
$this->_sql .= "({$length})";
}
} else {
$this->columnIndex = \count($this->columns);
$this->columns[] = [
'name' => $name,
'type' => $type,
];
if (!\is_null($length)) {
$this->length($length);
}
}
return $this;
}
public function dropColumn($column)
{
if ($this->method === 'dropColumn') {
$this->_sql = "ALTER TABLE {$this->table} DROP {$column}";
} else {
$this->columnsToDrop[] = $column;
}
return $this;
}
public function renameColumn($column, $newName)
{
if ($this->method === 'renameColumn') {
$this->_sql = "ALTER TABLE {$this->table} CHANGE {$column} {$newName}";
} else {
$this->columnsToRename[] = [
'column' => $column,
'new_name' => $newName,
];
}
return $this;
}
public function renameColumnQuery()
{
$query = '';
if (\is_array($this->columnsToRename)) {
foreach ($this->columnsToRename as $id => $column) {
if ($id > 0) {
$query .= "\n, ";
}
$query .= "CHANGE {$column['column']} {$column['new_name']}";
}
}
return $query;
}
public function change()
{
$this->columns[$this->columnIndex]['change'] = true;
return $this;
}
public function increments($column = null)
{
if (!\is_null($column)) {
$this->columnIndex = \count($this->columns);
$this->columns[] = [
'type' => 'BIGINT',
'name' => "{$column}",
];
}
$this->columns[$this->columnIndex]['props'][] = 'AUTO_INCREMENT';
return $this;
}
public function id()
{
$this->columnIndex = \count($this->columns);
$this->columns[] = [
'type' => 'BIGINT',
'name' => 'id',
'unsigned' => 'UNSIGNED',
];
$this->increments();
$this->primary();
return $this;
}
public function string($name)
{
$this->columnIndex = \count($this->columns);
$this->columns[] = [
'type' => 'VARCHAR',
'name' => $name,
];
$this->length('255');
return $this;
}
public function timestamps()
{
$this->columnIndex = \count($this->columns);
$this->columns[] = [
'type' => 'timestamp',
'name' => 'created_at',
];
$this->nullable()->defaultValue('NULL');
++$this->columnIndex;
$this->columns[] = [
'type' => 'timestamp',
'name' => 'updated_at',
];
$this->nullable()->defaultValue('NULL');
return $this;
}
public function softDeletes()
{
$this->columnIndex = \count($this->columns);
$this->columns[] = [
'type' => 'timestamp',
'name' => 'deleted_at',
];
$this->nullable()->defaultValue('NULL');
return $this;
}
public function nullable()
{
$this->columns[$this->columnIndex]['nullable'] = true;
return $this;
}
public function defaultValue($value)
{
$this->columns[$this->columnIndex]['default'] = $value;
return $this;
}
public function unsigned()
{
$this->columns[$this->columnIndex]['unsigned'] = 'UNSIGNED';
return $this;
}
public function zeroFill()
{
$this->columns[$this->columnIndex]['props'][] = 'ZEROFILL';
return $this;
}
public function binary()
{
$this->columns[$this->columnIndex]['props'][] = 'BINARY';
return $this;
}
public function primary()
{
$this->primaryKey[] = $this->columns[$this->columnIndex]['name'];
$this->columns[$this->columnIndex]['nullable'] = false;
return $this;
}
public function index($type = null)
{
$indexColumns = [
'name' => $this->columns[$this->columnIndex]['name'],
];
if (!\is_null($type)) {
$indexColumns['type'] = $type;
}
$this->indexColumns[] = $indexColumns;
return $this;
}
public function unique()
{
$this->uniqueIndex[] = $this->columns[$this->columnIndex]['name'];
return $this;
}
public function foreign($ref, $refCol)
{
$this->fkID = \count($this->foreignKeys);
$this->foreignKeys[] = [
'column' => $this->columns[$this->columnIndex]['name'],
'ref' => $this->_prefix . $ref,
'ref_col' => $refCol,
];
return $this;
}
public function onDelete()
{
$this->foreignKeys[$this->fkID]['method'] = 'onDelete';
return $this;
}
public function onUpdate()
{
$this->foreignKeys[$this->fkID]['method'] = 'onUpdate';
return $this;
}
public function restrict()
{
if (\array_key_exists('method', $this->foreignKeys[$this->fkID])) {
$this->foreignKeys[$this->fkID][$this->foreignKeys[$this->fkID]['method']] = 'RESTRICT';
} else {
$this->foreignKeys[$this->fkID]['both'] = 'RESTRICT';
}
return $this;
}
public function setNull()
{
if (\array_key_exists('method', $this->foreignKeys[$this->fkID])) {
$this->foreignKeys[$this->fkID][$this->foreignKeys[$this->fkID]['method']] = 'SET NULL';
} else {
$this->foreignKeys[$this->fkID]['both'] = 'SET NULL';
}
return $this;
}
public function cascade()
{
if (\array_key_exists('method', $this->foreignKeys[$this->fkID])) {
$this->foreignKeys[$this->fkID][$this->foreignKeys[$this->fkID]['method']] = 'CASCADE';
} else {
$this->foreignKeys[$this->fkID]['both'] = 'CASCADE';
}
return $this;
}
public function dropForeign($keys)
{
if ($this->method === 'dropForeign') {
$this->_sql = "ALTER TABLE `{$this->table}`";
} else {
$sql = '';
$idCount = \count($keys) - 1;
$i = 0;
if (\is_array($keys)) {
foreach ($keys as $key) {
if ($i == $idCount) {
$sql .= " DROP FOREIGN KEY `{$key}`";
} else {
$sql .= " DROP FOREIGN KEY `{$key}`,";
}
$i++;
}
} else {
$sql .= " DROP FOREIGN KEY `{$keys}`";
}
$this->_edit['dropForeign'] = $sql;
}
return $this;
}
public function dropIndex($indexes)
{
if ($this->method === 'dropIndex') {
$this->_sql = "ALTER TABLE `{$this->table}`";
} else {
$sql = '';
$idCount = \count($indexes) - 1;
$i = 0;
if (\is_array($indexes)) {
foreach ($indexes as $index) {
if ($i == $idCount) {
$sql .= " DROP INDEX `{$index}`";
} else {
$sql .= " DROP INDEX `{$index}`,";
}
$i++;
}
} else {
$sql .= " DROP INDEX `{$indexes}`";
}
$this->_edit['dropIndex'] = $sql;
}
return $this;
}
public function dropPrimary()
{
if ($this->method === 'dropPrimary') {
$this->_sql = "ALTER TABLE `{$this->table}`";
} else {
$this->_edit['dropPrimary'] = ' DROP PRIMARY KEY';
}
return $this;
}
public function dropUnique($indexes)
{
return $this->dropIndex($indexes);
}
public function dropTimestamps()
{
if ($this->method === 'dropTimestamps') {
$this->_sql = "ALTER TABLE `{$this->table}`";
} else {
$this->_edit['dropTimestamps'] = ' DROP COLUMN created_at, DROP COLUMN updated_at';
}
return $this;
}
public function length($length)
{
if (\is_array($length)) {
$l = '';
foreach ($length as $e) {
$l .= "'{$e}',";
}
$length = rtrim($l, ',');
}
$this->columns[$this->columnIndex]['length'] = $length;
return $this;
}
private function getCollation()
{
$collate = null;
if (Connection::has_cap('collation')) {
if (!empty(Connection::prop('charset'))) {
$collate .= 'DEFAULT CHARACTER SET ' . Connection::prop('charset');
}
if (!empty(Connection::prop('collate'))) {
$collate .= ' COLLATE ' . Connection::prop('collate');
}
}
return $collate;
}
private function processQueryArr($queriesToAdd)
{
$query = '';
foreach ($queriesToAdd as $key => $queryToAdd) {
if (empty($queryToAdd)) {
continue;
}
$query .= empty($query) || $query[\strlen($query) - 1] === ',' ? '' : ',';
$query .= $queryToAdd;
}
return $query;
}
private function addColumnQuery()
{
if (!\is_array($this->columns)) {
return '';
}
$query = '';
foreach ($this->columns as $id => $column) {
if ($id > 0) {
$query .= "\n, ";
}
if ($this->method === 'edit') {
$query .= 'ADD COLUMN ';
}
if (isset($column['change'])) {
$query .= 'CHANGE COLUMN ';
}
$query .= $column['name'] . ' ' . $column['type'];
if (!empty($column['length'])) {
$query .= '(' . $column['length'] . ')';
} elseif (!empty($column['precision']) && !empty($column['scale'])) {
$query .= '(' . $column['precision'] . ', ' . $column['scale'] . ')';
} else {
$query .= ' ';
}
if (!empty($column['unsigned'])) {
$query .= " {$column['unsigned']}";
}
if (!empty($column['nullable'])) {
$query .= ' NULL';
} else {
$query .= ' NOT NULL';
}
if (\array_key_exists('default', $column)) {
if (!\in_array($column['default'], ['CURRENT_TIMESTAMP', 'NULL']) && !\is_int($column['default'])) {
$column['default'] = "'{$column['default']}'";
}
$query .= ' DEFAULT ' . $column['default'];
}
if (!empty($column['props'])) {
$query .= ' ' . implode(' ', $column['props']);
}
}
return $query;
}
private function dropColumnQuery()
{
if (!\is_array($this->columnsToDrop)) {
return '';
}
$query = '';
foreach ($this->columnsToDrop as $id => $column) {
if ($id > 0) {
$query .= "\n, ";
}
$query .= "DROP {$column}";
}
return $query;
}
private function addPrimaryKeyQuery()
{
if (!\is_array($this->primaryKey) || \count($this->primaryKey) === 0) {
return '';
}
$query = "\n";
if ($this->method === 'edit') {
$query .= ' ADD ';
}
$query .= "PRIMARY KEY (\n";
$query .= implode(', ', $this->primaryKey);
$query .= "\n)";
return $query;
}
private function addIndexQuery()
{
if (!\is_array($this->indexColumns) || \count($this->indexColumns) === 0) {
return '';
}
$query = '';
foreach ($this->indexColumns as $key => $indexColumn) {
if ($key > 0) {
$query .= "\n, ";
}
if ($this->method === 'edit') {
$query .= ' ADD ';
}
$query .= (
isset($indexColumn['type']) ? $indexColumn['type'] : null
) . "INDEX {$indexColumn['name']}_INDEX ({$indexColumn['name']} ASC)";
}
return $query;
}
private function addUniqueIndexQuery()
{
if (!\is_array($this->uniqueIndex) || \count($this->uniqueIndex) === 0) {
return '';
}
$query = '';
foreach ($this->uniqueIndex as $key => $uniqueColumn) {
$query .= "\nUNIQUE INDEX {$uniqueColumn}_UNIQUE ({$uniqueColumn} ASC),";
}
return $query;
}
private function addForeignKeyQuery()
{
if (!\is_array($this->foreignKeys) || \count($this->foreignKeys) === 0) {
return '';
}
$query = '';
foreach ($this->foreignKeys as $fkId => $foreignKey) {
/* $query .= "\nCONSTRAINT f_c_{$this->table}_{$fkId} "
." FOREIGN KEY f_key_{$this->table}_{$fkId} ({$foreignKey['column']})"
." REFERENCES {$foreignKey['ref']} ({$foreignKey['ref_col']})"
. (isset($foreignKey['onUpdate']) ? " ON DELETE {$foreignKey['onUpdate']}" : null)
. (isset($foreignKey['onUpdate']) ? " ON UPDATE {$foreignKey['onUpdate']}" : null)
. (isset($foreignKey['both']) ? " ON DELETE {$foreignKey['both']} ON UPDATE {$foreignKey['both']}" : null)
. ","; */
$query .= " FOREIGN KEY ({$foreignKey['column']}) REFERENCES {$foreignKey['ref']} ";
$query .= "({$foreignKey['ref_col']})";
$query .= (isset($foreignKey['onDelete']) ? " ON DELETE {$foreignKey['onDelete']}" : null);
$query .= (isset($foreignKey['onUpdate']) ? " ON UPDATE {$foreignKey['onUpdate']}" : null);
$query .= (isset($foreignKey['both']) ? " ON DELETE {$foreignKey['both']} ON UPDATE {$foreignKey['both']}" : null);
$query .= ',';
}
return rtrim($query, ',');
}
private function isValidType($type)
{
// phpcs:disable Squiz.Arrays.ArrayDeclaration.ValueNoNewline
return \in_array(
$type,
[
'CHAR', 'VARCHAR', 'BINARY', 'JSON',
'VARBINARY', 'TINYBLOB', 'TINYTEXT', 'TEXT', 'BLOB',
'MEDIUMTEXT', 'MEDIUMBLOB', 'LONGTEXT', 'LONGBLOB',
'ENUM', 'SET', 'BIT', 'TINYINT', 'BOOL', 'BOOLEAN', 'SMALLINT',
'MEDIUMINT', 'INT', 'INTEGER', 'BIGINT', 'FLOAT',
'FLOAT', 'DOUBLE', 'DOUBLE PRECISION', 'DECIMAL', 'DEC', 'DATE', 'DATETIME', 'TIMESTAMP', 'TIME', 'YEAR',
]
);
}
}