Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,545 @@
<?php namespace FluentMail\App\Services\DB\QueryBuilder\Adapters;
use FluentMail\App\Services\DB\Connection;
use FluentMail\App\Services\DB\Exception;
use FluentMail\App\Services\DB\QueryBuilder\Raw;
abstract class BaseAdapter
{
/**
* @var \FluentMail\App\Services\DB\Connection
*/
protected $connection;
/**
* @var \FluentMail\App\Services\DB\Viocon\Container
*/
protected $container;
public function __construct(Connection $connection)
{
$this->connection = $connection;
$this->container = $this->connection->getContainer();
}
/**
* Build select query string and bindings
*
* @param $statements
*
* @return array
* @throws \FluentMail\App\Services\DB\Exception
*/
public function select($statements)
{
if (! array_key_exists('tables', $statements)) {
throw new Exception('No table specified.', 3);
} elseif (! array_key_exists('selects', $statements)) {
$statements['selects'][] = '*';
}
// From
$tables = $this->arrayStr($statements['tables'], ', ');
// Select
$selects = $this->arrayStr($statements['selects'], ', ');
// Wheres
list($whereCriteria, $whereBindings) = $this->buildCriteriaWithType($statements, 'wheres', 'WHERE');
// Group bys
$groupBys = '';
if (isset($statements['groupBys']) && $groupBys = $this->arrayStr($statements['groupBys'], ', ')) {
$groupBys = 'GROUP BY ' . $groupBys;
}
// Order bys
$orderBys = '';
if (isset($statements['orderBys']) && is_array($statements['orderBys'])) {
foreach ($statements['orderBys'] as $orderBy) {
$orderBys .= $this->wrapSanitizer($orderBy['field']) . ' ' . $orderBy['type'] . ', ';
}
if ($orderBys = trim($orderBys, ', ')) {
$orderBys = 'ORDER BY ' . $orderBys;
}
}
// Limit and offset
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
$offset = isset($statements['offset']) ? 'OFFSET ' . $statements['offset'] : '';
// Having
list($havingCriteria, $havingBindings) = $this->buildCriteriaWithType($statements, 'havings', 'HAVING');
// Joins
$joinString = $this->buildJoin($statements);
$sqlArray = array(
'SELECT' . (isset($statements['distinct']) ? ' DISTINCT' : ''),
$selects,
'FROM',
$tables,
$joinString,
$whereCriteria,
$groupBys,
$havingCriteria,
$orderBys,
$limit,
$offset
);
$sql = $this->concatenateQuery($sqlArray);
$bindings = array_merge(
$whereBindings,
$havingBindings
);
return compact('sql', 'bindings');
}
/**
* Build just criteria part of the query
*
* @param $statements
* @param bool $bindValues
*
* @return array
*/
public function criteriaOnly($statements, $bindValues = true)
{
$sql = $bindings = array();
if (! isset($statements['criteria'])) {
return compact('sql', 'bindings');
}
list($sql, $bindings) = $this->buildCriteria($statements['criteria'], $bindValues);
return compact('sql', 'bindings');
}
/**
* Build a generic insert/ignore/replace query
*
* @param $statements
* @param array $data
*
* @return array
* @throws \FluentMail\App\Services\DB\Exception
*/
private function doInsert($statements, array $data, $type)
{
if (! isset($statements['tables'])) {
throw new Exception('No table specified', 3);
}
$table = end($statements['tables']);
$bindings = $keys = $values = array();
foreach ($data as $key => $value) {
$keys[] = $key;
if ($value instanceof Raw) {
$values[] = (string) $value;
} else {
$values[] = '?';
$bindings[] = $value;
}
}
$sqlArray = array(
$type . ' INTO',
$this->wrapSanitizer($table),
'(' . $this->arrayStr($keys, ',') . ')',
'VALUES',
'(' . $this->arrayStr($values, ',', false) . ')',
);
if (isset($statements['onduplicate'])) {
if (count($statements['onduplicate']) < 1) {
throw new Exception('No data given.', 4);
}
list($updateStatement, $updateBindings) = $this->getUpdateStatement($statements['onduplicate']);
$sqlArray[] = 'ON DUPLICATE KEY UPDATE ' . $updateStatement;
$bindings = array_merge($bindings, $updateBindings);
}
$sql = $this->concatenateQuery($sqlArray);
return compact('sql', 'bindings');
}
/**
* Build Insert query
*
* @param $statements
* @param array $data
*
* @return array
* @throws \FluentMail\App\Services\DB\Exception
*/
public function insert($statements, array $data)
{
return $this->doInsert($statements, $data, 'INSERT');
}
/**
* Build Insert Ignore query
*
* @param $statements
* @param array $data
*
* @return array
* @throws \FluentMail\App\Services\DB\Exception
*/
public function insertIgnore($statements, array $data)
{
return $this->doInsert($statements, $data, 'INSERT IGNORE');
}
/**
* Build Insert Ignore query
*
* @param $statements
* @param array $data
*
* @return array
* @throws \FluentMail\App\Services\DB\Exception
*/
public function replace($statements, array $data)
{
return $this->doInsert($statements, $data, 'REPLACE');
}
/**
* Build fields assignment part of SET ... or ON DUBLICATE KEY UPDATE ... statements
*
* @param array $data
*
* @return array
*/
private function getUpdateStatement($data)
{
$bindings = array();
$statement = '';
foreach ($data as $key => $value) {
if ($value instanceof Raw) {
$statement .= $this->wrapSanitizer($key) . '=' . $value . ',';
} else {
$statement .= $this->wrapSanitizer($key) . '=?,';
$bindings[] = $value;
}
}
$statement = trim($statement, ',');
return array($statement, $bindings);
}
/**
* Build update query
*
* @param $statements
* @param array $data
*
* @return array
* @throws \FluentMail\App\Services\DB\Exception
*/
public function update($statements, array $data)
{
if (! isset($statements['tables'])) {
throw new Exception('No table specified', 3);
} elseif (count($data) < 1) {
throw new Exception('No data given.', 4);
}
$table = end($statements['tables']);
// Update statement
list($updateStatement, $bindings) = $this->getUpdateStatement($data);
// Wheres
list($whereCriteria, $whereBindings) = $this->buildCriteriaWithType($statements, 'wheres', 'WHERE');
// Limit
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
$sqlArray = array(
'UPDATE',
$this->wrapSanitizer($table),
'SET ' . $updateStatement,
$whereCriteria,
$limit
);
$sql = $this->concatenateQuery($sqlArray);
$bindings = array_merge($bindings, $whereBindings);
return compact('sql', 'bindings');
}
/**
* Build delete query
*
* @param $statements
*
* @return array
* @throws \FluentMail\App\Services\DB\src\Exception
*/
public function delete($statements)
{
if (! isset($statements['tables'])) {
throw new Exception('No table specified', 3);
}
$table = end($statements['tables']);
// Wheres
list($whereCriteria, $whereBindings) = $this->buildCriteriaWithType($statements, 'wheres', 'WHERE');
// Limit
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
$sqlArray = array('DELETE FROM', $this->wrapSanitizer($table), $whereCriteria);
$sql = $this->concatenateQuery($sqlArray);
$bindings = $whereBindings;
return compact('sql', 'bindings');
}
/**
* Array concatenating method, like implode.
* But it does wrap sanitizer and trims last glue
*
* @param array $pieces
* @param $glue
* @param bool $wrapSanitizer
*
* @return string
*/
protected function arrayStr(array $pieces, $glue, $wrapSanitizer = true)
{
$str = '';
foreach ($pieces as $key => $piece) {
if ($wrapSanitizer) {
$piece = $this->wrapSanitizer($piece);
}
if (! is_int($key)) {
$piece = ($wrapSanitizer ? $this->wrapSanitizer($key) : $key) . ' AS ' . $piece;
}
$str .= $piece . $glue;
}
return trim($str, $glue);
}
/**
* Join different part of queries with a space.
*
* @param array $pieces
*
* @return string
*/
protected function concatenateQuery(array $pieces)
{
$str = '';
foreach ($pieces as $piece) {
$str = trim($str) . ' ' . trim($piece);
}
return trim($str);
}
/**
* Build generic criteria string and bindings from statements, like "a = b and c = ?"
*
* @param $statements
* @param bool $bindValues
*
* @return array
*/
protected function buildCriteria($statements, $bindValues = true)
{
$criteria = '';
$bindings = array();
foreach ($statements as $statement) {
$key = $this->wrapSanitizer($statement['key']);
$value = $statement['value'];
if (is_null($value) && $key instanceof \Closure) {
// We have a closure, a nested criteria
// Build a new NestedCriteria class, keep it by reference so any changes made
// in the closure should reflect here
$nestedCriteria = $this->container->build(
'\\FluentMail\\App\\Services\\DB\\QueryBuilder\\NestedCriteria',
array($this->connection)
);
$nestedCriteria = & $nestedCriteria;
// Call the closure with our new nestedCriteria object
$key($nestedCriteria);
// Get the criteria only query from the nestedCriteria object
$queryObject = $nestedCriteria->getQuery('criteriaOnly', true);
// Merge the bindings we get from nestedCriteria object
$bindings = array_merge($bindings, $queryObject->getBindings());
// Append the sql we get from the nestedCriteria object
$criteria .= $statement['joiner'] . ' (' . $queryObject->getSql() . ') ';
} elseif (is_array($value)) {
// where_in or between like query
$criteria .= $statement['joiner'] . ' ' . $key . ' ' . $statement['operator'];
switch ($statement['operator']) {
case 'BETWEEN':
$bindings = array_merge($bindings, $statement['value']);
$criteria .= ' ? AND ? ';
break;
default:
$valuePlaceholder = '';
foreach ($statement['value'] as $subValue) {
$valuePlaceholder .= '?, ';
$bindings[] = $subValue;
}
$valuePlaceholder = trim($valuePlaceholder, ', ');
$criteria .= ' (' . $valuePlaceholder . ') ';
break;
}
} elseif ($value instanceof Raw) {
$criteria .= "{$statement['joiner']} {$key} {$statement['operator']} $value ";
} else {
// Usual where like criteria
if (! $bindValues) {
// Specially for joins
// We are not binding values, lets sanitize then
$value = $this->wrapSanitizer($value);
$criteria .= $statement['joiner'] . ' ' . $key . ' ' . $statement['operator'] . ' ' . $value . ' ';
} elseif ($statement['key'] instanceof Raw) {
$criteria .= $statement['joiner'] . ' ' . $key . ' ';
$bindings = array_merge($bindings, $statement['key']->getBindings());
} else {
// For wheres
$valuePlaceholder = '?';
$bindings[] = $value;
$criteria .= $statement['joiner'] . ' ' . $key . ' ' . $statement['operator'] . ' '
. $valuePlaceholder . ' ';
}
}
}
// Clear all white spaces, and, or from beginning and white spaces from ending
$criteria = preg_replace('/^(\s?AND ?|\s?OR ?)|\s$/i', '', $criteria);
return array($criteria, $bindings);
}
/**
* Wrap values with adapter's sanitizer like, '`'
*
* @param $value
*
* @return string
*/
public function wrapSanitizer($value)
{
// Its a raw query, just cast as string, object has __toString()
if ($value instanceof Raw) {
return (string) $value;
} elseif ($value instanceof \Closure) {
return $value;
}
// Separate our table and fields which are joined with a ".",
// like my_table.id
$valueArr = explode('.', $value, 2);
foreach ($valueArr as $key => $subValue) {
// Don't wrap if we have *, which is not a usual field
$valueArr[$key] = trim($subValue) == '*' ? $subValue : $this->sanitizer . $subValue . $this->sanitizer;
}
// Join these back with "." and return
return implode('.', $valueArr);
}
/**
* Build criteria string and binding with various types added, like WHERE and Having
*
* @param $statements
* @param $key
* @param $type
* @param bool $bindValues
*
* @return array
*/
protected function buildCriteriaWithType($statements, $key, $type, $bindValues = true)
{
$criteria = '';
$bindings = array();
if (isset($statements[$key])) {
// Get the generic/adapter agnostic criteria string from parent
list($criteria, $bindings) = $this->buildCriteria($statements[$key], $bindValues);
if ($criteria) {
$criteria = $type . ' ' . $criteria;
}
}
return array($criteria, $bindings);
}
/**
* Build join string
*
* @param $statements
*
* @return array|string
*/
protected function buildJoin($statements)
{
$sql = '';
if (! array_key_exists('joins', $statements) || ! is_array($statements['joins'])) {
return $sql;
}
foreach ($statements['joins'] as $joinArr) {
if (is_array($joinArr['table'])) {
$mainTable = $joinArr['table'][0];
$aliasTable = $joinArr['table'][1];
$table = $this->wrapSanitizer($mainTable) . ' AS ' . $this->wrapSanitizer($aliasTable);
} else {
$table = $joinArr['table'] instanceof Raw ?
(string) $joinArr['table'] :
$this->wrapSanitizer($joinArr['table']);
}
$joinBuilder = $joinArr['joinBuilder'];
$sqlArr = array(
$sql,
strtoupper($joinArr['type']),
'JOIN',
$table,
'ON',
$joinBuilder->getQuery('criteriaOnly', false)->getSql()
);
$sql = $this->concatenateQuery($sqlArr);
}
return $sql;
}
}