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,43 @@
<?php namespace FluentMail\App\Services\DB;
use FluentMail\App\Services\DB\QueryBuilder\QueryBuilderHandler;
/**
* This class gives the ability to access non-static methods statically
*
* Class AliasFacade
*
* @package FluentAuthDb
*/
class AliasFacade
{
/**
* @var QueryBuilderHandler
*/
protected static $queryBuilderInstance;
/**
* @param $method
* @param $args
*
* @return mixed
*/
public static function __callStatic($method, $args)
{
if (!static::$queryBuilderInstance) {
static::$queryBuilderInstance = new QueryBuilderHandler();
}
// Call the non-static method from the class instance
return call_user_func_array(array(static::$queryBuilderInstance, $method), $args);
}
/**
* @param QueryBuilderHandler $queryBuilderInstance
*/
public static function setQueryBuilderInstance($queryBuilderInstance)
{
static::$queryBuilderInstance = $queryBuilderInstance;
}
}

View File

@@ -0,0 +1,187 @@
<?php
namespace FluentMail\App\Services\DB;
use FluentMail\App\Services\DB\Viocon\Container;
class Connection
{
/**
* @var Container
*/
protected $container;
/**
* @var string
*/
protected $adapter;
/**
* @var array
*/
protected $adapterConfig;
/**
* @var \wpdb $wpdb
*/
protected $dbInstance;
/**
* @var \wpdb $wpdb
*/
protected $wpdb;
/**
* @var Connection
*/
protected static $storedConnection;
/**
* @var EventHandler
*/
protected $eventHandler;
/**
* @param $wpdb
* @param array $adapterConfig
* @param null|string $alias
* @param null|Container $container
*/
public function __construct($wpdb, array $config = array(), $alias = null, ?Container $container = null)
{
$container = $container ? : new Container();
$this->container = $container;
$this->wpdb = $wpdb;
$this->setAdapter()->setAdapterConfig($config)->connect();
// Create event dependency
$this->eventHandler = $this->container->build('\\FluentMail\\App\\Services\\DB\\EventHandler');
if ($alias) {
$this->createAlias($alias);
}
}
/**
* Create an easily accessible query builder alias
*
* @param $alias
*/
public function createAlias($alias)
{
class_alias('FluentMail\\App\\Services\\DB\\AliasFacade', $alias);
$builder = $this->container->build('\\FluentMail\\App\\Services\\DB\\QueryBuilder\\QueryBuilderHandler', array($this));
AliasFacade::setQueryBuilderInstance($builder);
}
/**
* Returns an instance of Query Builder
*/
public function getQueryBuilder()
{
return $this->container->build('\\FluentMail\\App\\Services\\DB\\QueryBuilder\\QueryBuilderHandler', array($this));
}
/**
* Create the connection adapter
*/
protected function connect()
{
$this->setDbInstance($this->wpdb);
// Preserve the first database connection with a static property
if (! static::$storedConnection) {
static::$storedConnection = $this;
}
}
/**
* @param $db
*
* @return $this
*/
public function setDbInstance($db)
{
$this->dbInstance = $db;
return $this;
}
/**
* @return \wpdb
*/
public function getDbInstance()
{
return $this->dbInstance;
}
/**
* @param $adapter
*
* @return $this
*/
public function setAdapter($adapter = 'mysql')
{
$this->adapter = $adapter;
return $this;
}
/**
* @return string
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* @param array $adapterConfig
*
* @return $this
*/
public function setAdapterConfig(array $adapterConfig)
{
$this->adapterConfig = $adapterConfig;
return $this;
}
/**
* @return array
*/
public function getAdapterConfig()
{
return $this->adapterConfig;
}
/**
* @return \FluentMail\App\Services\DB\Viocon\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* @return EventHandler
*/
public function getEventHandler()
{
return $this->eventHandler;
}
/**
* @return Connection
*/
public static function getStoredConnection()
{
return static::$storedConnection;
}
}

View File

@@ -0,0 +1,99 @@
<?php namespace FluentMail\App\Services\DB;
use FluentMail\App\Services\DB\QueryBuilder\QueryBuilderHandler;
use FluentMail\App\Services\DB\QueryBuilder\Raw;
class EventHandler
{
/**
* @var array
*/
protected $events = array();
/**
* @var array
*/
protected $firedEvents = array();
/**
* @return array
*/
public function getEvents()
{
return $this->events;
}
/**
* @param $event
* @param $table
*
* @return callable|null
*/
public function getEvent($event, $table = ':any')
{
if ($table instanceof Raw) {
return null;
}
return isset($this->events[$table][$event]) ? $this->events[$table][$event] : null;
}
/**
* @param $event
* @param string $table
* @param callable $action
*
* @return void
*/
public function registerEvent($event, $table, \Closure $action)
{
$table = $table ?: ':any';
$this->events[$table][$event] = $action;
}
/**
* @param $event
* @param string $table
*
* @return void
*/
public function removeEvent($event, $table = ':any')
{
unset($this->events[$table][$event]);
}
/**
* @param \FluentMail\App\Services\DB\src\QueryBuilder\QueryBuilderHandler $queryBuilder
* @param $event
* @return mixed
*/
public function fireEvents($queryBuilder, $event)
{
$originalArgs = func_get_args();
$statements = $queryBuilder->getStatements();
$tables = isset($statements['tables']) ? $statements['tables'] : array();
// Events added with :any will be fired in case of any table,
// we are adding :any as a fake table at the beginning.
array_unshift($tables, ':any');
// Fire all events
foreach ($tables as $table) {
// Fire before events for :any table
if ($action = $this->getEvent($event, $table)) {
// Make an event id, with event type and table
$eventId = $event . $table;
// Fire event
$handlerParams = $originalArgs;
unset($handlerParams[1]); // we do not need $event
// Add to fired list
$this->firedEvents[] = $eventId;
$result = call_user_func_array($action, $handlerParams);
if (!is_null($result)) {
return $result;
};
}
}
}
}

View File

@@ -0,0 +1,6 @@
<?php namespace FluentMail\App\Services\DB;
class Exception extends \Exception
{
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Muhammad Usman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

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;
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace FluentMail\App\Services\DB\QueryBuilder\Adapters;
class Mysql extends BaseAdapter
{
/**
* @var string
*/
protected $sanitizer = '`';
}

View File

@@ -0,0 +1,45 @@
<?php namespace FluentMail\App\Services\DB\QueryBuilder;
class JoinBuilder extends QueryBuilderHandler
{
/**
* @param $key
* @param $operator
* @param $value
*
* @return $this
*/
public function on($key, $operator, $value)
{
return $this->joinHandler($key, $operator, $value, 'AND');
}
/**
* @param $key
* @param $operator
* @param $value
*
* @return $this
*/
public function orOn($key, $operator, $value)
{
return $this->joinHandler($key, $operator, $value, 'OR');
}
/**
* @param $key
* @param null $operator
* @param null $value
* @param string $joiner
*
* @return $this
*/
protected function joinHandler($key, $operator = null, $value = null, $joiner = 'AND')
{
$key = $this->addTablePrefix($key);
$value = $this->addTablePrefix($value);
$this->statements['criteria'][] = compact('key', 'operator', 'value', 'joiner');
return $this;
}
}

View File

@@ -0,0 +1,20 @@
<?php namespace FluentMail\App\Services\DB\QueryBuilder;
class NestedCriteria extends QueryBuilderHandler
{
/**
* @param $key
* @param null $operator
* @param null $value
* @param string $joiner
*
* @return $this
*/
protected function whereHandler($key, $operator = null, $value = null, $joiner = 'AND')
{
$key = $this->addTablePrefix($key);
$this->statements['criteria'][] = compact('key', 'operator', 'value', 'joiner');
return $this;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
<?php
namespace FluentMail\App\Services\DB\QueryBuilder;
class QueryObject
{
/**
* @var string
*/
protected $sql;
/**
* @var \wpdb
*/
protected $db;
/**
* @var array
*/
protected $bindings = array();
public function __construct($sql, array $bindings)
{
$this->sql = (string) $sql;
$this->bindings = $bindings;
global $wpdb;
$this->db = $wpdb;
}
/**
* @return string
*/
public function getSql()
{
return $this->sql;
}
/**
* @return array
*/
public function getBindings()
{
return $this->bindings;
}
/**
* Get the raw/bound sql
*
* @return string
*/
public function getRawSql()
{
return $this->interpolateQuery($this->sql, $this->bindings);
}
/**
* Replaces any parameter placeholders in a query with the value of that
* parameter. Useful for debugging. Assumes anonymous parameters from
* $params are are in the same order as specified in $query
*
* Reference: http://stackoverflow.com/a/1376838/656489
*
* @param string $query The sql query with parameter placeholders
* @param array $params The array of substitution parameters
*
* @return string The interpolated query
*/
protected function interpolateQuery($query, $params)
{
$keys = $placeHolders = [];
foreach ($params as $key => $value) {
if (is_string($key)) {
$keys[] = '/:' . $key . '/';
} else {
$keys[] = '/[?]/';
}
$placeHolders[] = $this->getPlaceHolder($value);
}
$query = preg_replace($keys, $placeHolders, $query, 1, $count);
return $params ? $this->db->prepare($query, $params) : $query;
}
private function getPlaceHolder($value)
{
$placeHolder = '%s';
if (is_int($value)) {
$placeHolder = '%d';
} elseif (is_float($value)) {
$placeHolder = '%f';
}
return $placeHolder;
}
}

View File

@@ -0,0 +1,34 @@
<?php namespace FluentMail\App\Services\DB\QueryBuilder;
class Raw
{
/**
* @var string
*/
protected $value;
/**
* @var array
*/
protected $bindings;
public function __construct($value, $bindings = array())
{
$this->value = (string)$value;
$this->bindings = (array)$bindings;
}
public function getBindings()
{
return $this->bindings;
}
/**
* @return string
*/
public function __toString()
{
return (string) $this->value;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace FluentMail\App\Services\DB\QueryBuilder;
class Transaction extends QueryBuilderHandler
{
/**
* Commit the database changes
*/
public function commit()
{
$this->db->query('COMMIT');
throw new TransactionHaltException();
}
/**
* Rollback the database changes
*/
public function rollback()
{
$this->db->query('ROLLBACK');
throw new TransactionHaltException();
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace FluentMail\App\Services\DB\QueryBuilder;
class TransactionHaltException extends \Exception
{
}

View File

@@ -0,0 +1,48 @@
<?php
namespace FluentMail\App\Services\DB\Viocon;
/**
* This class gives the ability to access non-static methods statically
*
* Class AliasFacade
*
* @package Viocon
*/
class AliasFacade {
/**
* @var Container
*/
protected static $vioconInstance;
/**
* @param $method
* @param $args
*
* @return mixed
*/
public static function __callStatic($method, $args)
{
if(!static::$vioconInstance) {
static::$vioconInstance = new Container();
}
return call_user_func_array(array(static::$vioconInstance, $method), $args);
}
/**
* @param Container $instance
*/
public static function setVioconInstance(Container $instance)
{
static::$vioconInstance = $instance;
}
/**
* @return \FluentMail\App\Services\DB\Viocon\Container $instance
*/
public static function getVioconInstance()
{
return static::$vioconInstance;
}
}

View File

@@ -0,0 +1,140 @@
<?php namespace FluentMail\App\Services\DB\Viocon;
class Container
{
/**
* @var array
*/
public $registry = array();
/**
* Singleton instances
*
* @var array
*/
public $singletons = array();
public function __construct($alias = null)
{
if ($alias) {
AliasFacade::setVioconInstance($this);
class_alias('\\FluentMail\\App\\Services\\DB\\Viocon\\AliasFacade', $alias);
}
}
/**
* Register an object with a key
*
* @param string $key
* @param mixed $object
* @param bool $singleton
*
* @return void
*/
public function set($key, $object, $singleton = false)
{
$this->registry[$key] = compact('object', 'singleton');
}
/**
* If we have a registry for the given key
*
* @param string $key
*
* @return bool
*/
public function has($key)
{
return array_key_exists($key, $this->registry);
}
/**
* Register as singleton.
*
* @param string $key
* @param mixed $object
*
* @return void
*/
public function singleton($key, $object)
{
$this->set($key, $object, true);
}
/**
* Register or replace an instance as a singleton.
* Useful for replacing with Mocked instance
*
* @param string $key
* @param mixed $instance
*
* @return void
*/
public function setInstance($key, $instance)
{
$this->singletons[$key] = $instance;
}
/**
* Build from the given key.
* If there is a class registered with Container::set() then it's instance
* will be returned. If a closure is registered, a closure's return value
* will be returned. If nothing is registered then it will try to build an
* instance with new $key(...).
*
* $parameters will be passed to closure or class constructor.
*
*
* @param string $key
* @param array $parameters
*
* @return mixed
*/
public function build($key, $parameters = array())
{
// If we have a singleton instance registered the just return it
if (array_key_exists($key, $this->singletons)) {
return $this->singletons[$key];
}
// If we don't have a registered object with the key then assume user
// is trying to build a class with the given key/name
if (!array_key_exists($key, $this->registry)) {
$object = $key;
} else {
$object = $this->registry[$key]['object'];
}
$instance = $this->instanciate($object, $parameters);
// If the key is registered as a singleton, we can save the instance as singleton
// for later use
if (isset($this->registry[$key]['singleton']) && $this->registry[$key]['singleton'] === true) {
$this->singletons[$key] = $instance;
}
return $instance;
}
/**
* Instantiate an instance of the given type.
*
* @param string $key
* @param array $parameters
*
* @throws \Exception
* @return mixed
*/
protected function instanciate($key, $parameters = null)
{
if ($key instanceof \Closure) {
return call_user_func_array($key, $parameters);
}
$reflection = new \ReflectionClass($key);
return $reflection->newInstanceArgs($parameters);
}
}

View File

@@ -0,0 +1,7 @@
<?php namespace FluentMail\App\Services\DB\Viocon;
class VioconException extends \Exception
{
}

View File

@@ -0,0 +1,22 @@
<?php defined('ABSPATH') or die;
if (! function_exists('FluentSmtpDb')) {
/**
* @return \FluentMail\App\Services\DB\QueryBuilder\QueryBuilderHandler
*/
function FluentSmtpDb()
{
static $FluentSmtpDb;
if (! $FluentSmtpDb) {
global $wpdb;
$connection = new \FluentMail\App\Services\DB\Connection($wpdb, ['prefix' => $wpdb->prefix]);
$FluentSmtpDb = new \FluentMail\App\Services\DB\QueryBuilder\QueryBuilderHandler($connection);
}
return $FluentSmtpDb;
}
}