File Manager

Current Directory: /home/astoriaah/www/administrator/components/com_sh404sef/vendor/weeblr/wblib/v2/packages/db
Viewing File: /home/astoriaah/www/administrator/components/com_sh404sef/vendor/weeblr/wblib/v2/packages/db/db.php
<?php /** * Project: sh404SEF - SEO extension for Joomla! * * @package sh404SEF * @copyright (c) Yannick Gaultier - Weeblr llc - 2022 * @author Yannick Gaultier * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL * @version 4.24.1.4308 * @date 2022-05-31 */ namespace Weeblr\Wblib\V_SH4_4308\Db; use Weeblr\Wblib\V_SH4_4308\Wb; // Security check to ensure this file is being included by a parent file. defined('_JEXEC') || defined('WBLIB_V_SH4_4308_ROOT_PATH') || die; class Db { private $sql = ''; private $db = null; /** * Get a hold on the platform database object. * * @param Platformdbconnectioninterface $db */ public function __construct($db) { $this->db = $db; } /** * Get the null date value for the database driver. */ public function getNullDate() { return $this->db->getNullDate(); } /** * Quote the name of a table, replacing the prefix placeholder * by its actual value * * @param string $tableName * @param string $prefix * * @return string */ public function quoteTable($tableName, $prefix = '#__') { return $this->db->quoteName(str_replace($prefix, $this->db->getPrefix(), $tableName)); } /** * Quote a column name (mysql) * * @param $name * * @return string */ public function quotename($name) { return $this->db->quoteName($name); } /** * Quote and by default also escape * a value (mysql) * * @param string|array $value * @param bool $escape * * @return string */ public function quote($value, $escape = true) { return $this->db->quote($value, $escape); } /** * Escape a value, using database connection * * @param string | array $text * @param bool $extra * * @return array|string */ public function escape($text, $extra = false) { $result = $this->db->escape($text, $extra); if ($extra) { $result = addcslashes($result, '%_'); } return $result; } /** * Stores a (valid and complete) sql query, to * be executed later * * @param $query */ public function setQuery($query) { $this->sql = $query; $this->db->setQuery($query); } /** * Execute a query stored with setQuery() */ public function execute() { if (empty($this->sql)) { Wb\throwException(new \InvalidArgumentException('wbLib: trying to execute an empty query')); } return $this->db->execute($this->sql); } /** * * Prepare a query, quoting or name quoting some * of its constituents * ?? will be replaced with name quoted data from the $nameQuoted parameter * ? will be replaced with quoted data from the $quoted parameter * * Example: * $query = 'select ?? from ?? where ?? <> ?' * with * $nameQuoted = array( 'id', '#__table', 'counter') * $quoted = array( 'test') * * will return * * select `id` from `#__table` where `counter` <> 'test' * * * @param string $query * @param array $nameQuoted * @param array $quoted * @param string $namePlaceHolder * @param string $dataPlaceHolder */ public function quoteQuery($query, $nameQuoted = array(), $quoted = array(), $namePlaceHolder = '??', $dataPlaceHolder = '?') { $newQuery = ''; // name quoting if (!empty($nameQuoted)) { // find placeholders $sqlBits = explode($namePlaceHolder, $query); $i = 0; // replace each place holder by the matching value foreach ($nameQuoted as $data) { $newQuery .= $sqlBits[$i]; $newQuery .= $this->quoteName($data); $i += 1; } if (isset($sqlBits[$i])) { $newQuery .= $sqlBits[$i]; } } if (strpos($newQuery, $namePlaceHolder) !== false) { Wb\throwException(new \RuntimeException(__METHOD__ . ':' . __LINE__ . ': ' . 'Invalid db query sent to queryQuote helper: ' . $query . '. Maybe missing some data.')); } // name quoting if (!empty($quoted)) { // find placeholders $sqlBits = explode($dataPlaceHolder, $newQuery); $newQuery = ''; $i = 0; // replace each place holder by the matching value foreach ($quoted as $data) { $newQuery .= $sqlBits[$i]; $newQuery .= $this->_prepareData($data); $i += 1; } if (isset($sqlBits[$i])) { $newQuery .= $sqlBits[$i]; } } return $newQuery; } /** * Prepare and set a query against the db object * * @param String $table The table name * @param Array $aData An array of field to be inserted in the db ('columnName' => 'columnValue') * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * * @return Db */ public function setInsertUpdateQuery($table, $aData, $mWhere = '', $aWhereData = array()) { if ($this->isRecord($table, $mWhere, $aWhereData)) { // update it $this->setUpdateQuery($table, $aData, $mWhere, $aWhereData); } else { // or insert it $this->setInsertQuery($table, $aData); } return $this; } /** * Prepare and set a SELECT query against the db * * @param String $table The table name * @param string[] $aColList array of strings of columns to be fetched * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * @param array $orderBy , a list of columns to order the results * @param Integer $offset , first line of result set to select * @param Integer $lines , max number of lines to select * * @return Db */ public function setSelectQuery($table, $aColList = array('*'), $mWhere = '', $aWhereData = array(), $orderBy = array(), $offset = 0, $lines = 0) { // sanitize $aColList = empty($aColList) ? array('*') : $aColList; $aColList = is_string($aColList) ? array($aColList) : $aColList; // which columns to fetch ? $quotedColList = array(); foreach ($aColList as $columnName) { $quotedColList[] = $columnName == '*' ? '*' : $this->quoteName($columnName); } $columns = implode(', ', $quotedColList); // where to look for $where = $this->buildWhereClause($mWhere, $aWhereData); // order by clause $orderByClause = $this->buildOrderByClause($orderBy); // lines limit clause $limitClause = $this->buildLimitClause($offset, $lines); // set up the query $this->setQuery('SELECT ' . $columns . ' FROM ' . $this->quoteTable($table) . $where . $orderByClause . $limitClause . ';'); return $this; } // end of setSelectQuery /** * Prepare and set a select/count query against the db * * @param String $table The table name * @param String $column an optional column to be counter * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * * @return Db * @throws \Exception */ public function setCountQuery($table, $column = '*', $mWhere = '', $aWhereData = array()) { // sanitize $column = empty($column) || $column == '*' ? '*' : $this->quoteName($column); // where to look for $where = $this->buildWhereClause($mWhere, $aWhereData); // set up the query $this->setQuery('SELECT count(' . $column . ') FROM ' . $this->quoteTable($table) . $where . ';'); return $this; } // end of setSelectQuery /** * Prepare and set an UPDATE query against the db * * @param String $table The table name * @param Array $aData array of values pairs ( ie 'columnName' => 'columnValue') * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * * @return bool|Db */ public function setUpdateQuery($table, $aData, $mWhere = '', $aWhereData = array()) { // which columns to set ? $set = ''; if (!empty($aData)) { foreach ($aData as $columnName => $columnValue) { $set .= ', ' . $this->quoteName($columnName) . '=' . $this->_prepareData($columnValue); } // remove leading ', ' $set = substr($set, 2); } // check result if (empty($set)) { return false; } // where to look for $where = $this->buildWhereClause($mWhere, $aWhereData); // set up the query $this->setQuery('UPDATE ' . $this->quoteTable($table) . ' SET ' . $set . $where . ';'); return $this; } /** * Prepare and set an INSERT query against the db * * @param String $table The table name * @param Array $aData array of values pairs ( ie 'columnName' => 'columnValue') */ public function setInsertQuery($table, $aData) { // which columns to set ? $columns = ''; $values = ''; if (!empty($aData)) { foreach ($aData as $columnName => $columnValue) { $columns .= ', ' . $this->quoteName($columnName); $values .= ', ' . $this->_prepareData($columnValue); } // remove leading ', ' $columns = substr($columns, 2); $values = substr($values, 2); } // set up the query $this->setQuery('INSERT INTO ' . $this->quoteTable($table) . ' (' . $columns . ') VALUES (' . $values . ');'); return $this; } /** * Prepare and set a DELETE query against the db * * @param String $table The table name * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * * @return Db */ public function setDeleteQuery($table, $mWhere = '', $aWhereData = array()) { // where to look for $where = $this->buildWhereClause($mWhere, $aWhereData); // set up the query $this->setQuery('DELETE FROM ' . $this->quoteTable($table) . $where . ';'); return $this; } /** * Returns true if a record exists matching 'where' condition * * @param String $table , the table to look into * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * * @return bool */ public function isRecord($table, $mWhere = '', $aWhereData = array()) { // where to look for $where = $this->buildWhereClause($mWhere, $aWhereData); if (empty($where)) { return false; } // set up the query and load result $this->setQuery('SELECT count(*) FROM ' . $this->quoteTable($table) . $where . ';'); $result = $this->loadResult(); return !empty($result); } /** * Returns true if a record exists with a given Id * * @param String $table , the table to look into * @param Integer $id , the id to look for * @param String $idName , default to 'id', the columns to look into, if not 'id' */ public function isRecordById($table, $id, $idName = 'id') { $id = (int) $id; if (empty($id)) { return false; } // get db and look up record $this->setSelectQuery($table, array($idName), array($id)); $result = $this->loadResult(); return !empty($result); } /** * Method to get the first row of the result set from the database query as an associative array * of ['field_name' => 'row_value']. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadAssoc() { return $this->db->loadAssoc(); } /** * Method to get an array of the result set rows from the database query where each row is an associative array * of ['field_name' => 'row_value']. The array of rows can optionally be keyed by a field name, but defaults to * a sequential numeric array. * * NOTE: Chosing to key the result array by a non-unique field name can result in unwanted * behavior and should be avoided. * * @param string $key The name of a field on which to key the result array. * @param string $column An optional column name. Instead of the whole row, only this column value will be in * the result array. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadAssocList($key = null, $column = null) { return $this->db->loadAssocList($key, $column); } /** * Method to get an array of values from the <var>$offset</var> field in each row of the result set from * the database query. * * @param integer $offset The row offset to use to build the result array. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadColumn($offset = 0) { return $this->db->loadColumn($offset); } /** * Method to get the first row of the result set from the database query as an object. * * @param string $class The class name to use for the returned row object. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadObject() { return $this->db->loadObject(); } /** * Method to get an array of the result set rows from the database query where each row is an object. The array * of objects can optionally be keyed by a field name, but defaults to a sequential numeric array. * * NOTE: Choosing to key the result array by a non-unique field name can result in unwanted * behavior and should be avoided. * * @param string $key The name of a field on which to key the result array. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadObjectList($key = '') { return $this->db->loadObjectList($key); } /** * Method to get the first field of the first row of the result set from the database query. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadResult() { return $this->db->loadResult(); } /** * Method to get the first row of the result set from the database query as an array. Columns are indexed * numerically so the first column in the result set would be accessible via <var>$row[0]</var>, etc. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadRow() { return $this->db->loadRow(); } /** * Method to get an array of the result set rows from the database query where each row is an array. The array * of objects can optionally be keyed by a field offset, but defaults to a sequential numeric array. * * NOTE: Choosing to key the result array by a non-unique field can result in unwanted * behavior and should be avoided. * * @param string $key The name of a field on which to key the result array. * * @return mixed The return value or null if the query failed. * * @throws RuntimeException */ public function loadRowList($key = null) { return $this->db->loadRowList($key); } /** * Returns the last insert id. * * @return int */ public function insertId() { return $this->db->getInsertId(); } /** * Start a transation. * * @return mixed */ public function transactionStart() { return $this->db->transactionStart(); } /** * Commit queries in transaction. * * @return mixed */ public function transactionCommit() { return $this->db->transactionCommit(); } /** * Rollback queries from transaction. * * @return mixed */ public function transactionRollback() { return $this->db->transactionRollback(); } /** * Prepare data to be inserted in an sql statement * * @param mixed $data */ private function _prepareData($data) { // from Ron Baldwin <ron.baldwin#sourceprose.com> // Only quote string types $type = gettype($data); if ($type == 'string') { $ret = $this->quote($data); } else if ($type == 'double') { $ret = str_replace(',', '.', $data); // locales fix so 1.1 does not get converted to 1,1 } else if ($type == 'boolean') { $ret = $data ? '1' : '0'; } else if ($type == 'object') { if (method_exists($data, '__toString')) { $ret = $this->quote($data->__toString()); } else { $ret = $this->quote((string) $data); } } else if ($data === null) { $ret = 'NULL'; } else { $ret = $data; } return $ret; } /** * Build a where clause * * @param string $mWhere ( ie 'columnName' => 'columnValue') : a where clause is created like so : WHERE * `columnName` = 'columnValue'. columnValue is escaped before being used * @param array $aWhereData Used only if $aWhere is a string. In such case, '?' place holders will be replaced by * this array values, escaped * * @return string * @throws \Exception */ public function buildWhereClause($mWhere = '', $aWhereData = array()) { // where clause if (is_string($mWhere)) { // litteral clause, find ? place holders if (!is_array($aWhereData)) { $aWhereData = array($aWhereData); } $holderCount = substr_count($mWhere, '?'); if ($holderCount > 0 && !empty($aWhereData) && $holderCount != count($aWhereData)) { // the number of ? placehlders does not match the data array passed Wb\throwException( new \RuntimeException( __METHOD__ . ':' . __LINE__ . ': ' . 'Internal error: trying to build invalid db query where clause [ ' . json_encode($mWhere) . ' ] [ ' . json_encode($aWhereData) . ' ]', 500 ) ); } else { // we have ? placeholders and their number equals that of data passed $where = ''; // find placeholders if (empty($aWhereData)) { $where = $mWhere; } else { $sqlBits = explode('?', $mWhere); $i = 0; // replace each place holder by the matching value foreach ($aWhereData as $data) { $where .= $sqlBits[$i]; $where .= $this->_prepareData($data); $i += 1; } if (isset($sqlBits[$i])) { $where .= $sqlBits[$i]; } } } } elseif (is_array($mWhere)) { // an array of columns/values, we must turn into a where clause // 2021-01-07: alternate syntax: $value can be an array. If so, it's similar to [$column, $op, $value] $where = ''; foreach ($mWhere as $column => $value) { if (is_array($value)) { if (count($value) !== 3) { Wb\throwException( new \RuntimeException( __METHOD__ . ':' . __LINE__ . ': ' . 'Internal error: trying to build invalid db query where clause [ ' . json_encode($mWhere) . ' ] [ ' . json_encode($aWhereData) . ' ]', 500 ) ); } $where .= ' AND ' . $this->quoteName($value[0]) . ' ' . $value[1] . ' ' . $this->_prepareData($value[2]); } else { $where .= ' AND ' . $this->quoteName($column) . '=' . $this->_prepareData($value); } } // remove initial AND $where = substr($where, 5); } else { $where = ''; } return empty($where) ? '' : ' WHERE ' . $where; } /** * Builds an ORDER BY sql statement * * $orderBy = 'title'; * $orderBy = array( 'extension' => '', 'title' => 'desc'); * $orderBy = array( 'extension', 'title'); * * @param Array $orderBy a list of key => values, where key is a column name, and value is either '', 'asc' or * 'desc' * * @return string */ public function buildOrderByClause($orderBy) { if (empty($orderBy)) { return ''; } $clause = ''; // 1: $orderBy is a string if (is_string($orderBy)) { $clause = $this->quoteName($orderBy); } else if (is_array($orderBy)) { foreach ($orderBy as $key => $value) { if (is_int($key)) { // 2 : $orderBy is an array of strings // use directly, always with no direction $clause .= ', ' . $this->quoteName((string) $value); } else { // 3 : $orderBy is an array of column names with direction $clause .= ', ' . $this->quoteName($key) . (empty($value) ? '' : $this->escape($value)); } } $clause = empty($clause) ? '' : substr($clause, 2); } // put everything together $clause = empty($clause) ? '' : ' ORDER BY ' . $clause; return $clause; } /** * Builds a LIMIT sql statement * * @param Integer $offset , the line in result set to start with * @param Integer $lines , the max number of lines in result set to return * * @return string */ public function buildLimitClause($offset, $lines) { if (empty($offset) && empty($lines)) { return ''; } $clause = ' LIMIT '; if (!empty($offset)) { $clause .= $this->_prepareData($offset); } if (!empty($lines)) { $clause .= (empty($offset) ? '' : ', ') . $this->_prepareData($lines); } return $clause; } }