Current Path :
/
home
/
develito
/
httpdocs
/
libraries
/
sobi
/
Database
/
Or
Select Your Path :
Upload File :
New :
File
Dir
/home/develito/httpdocs/libraries/sobi/Database/MySQLi.php
<?php /** * @package: Sobi Framework * * @author * Name: Sigrid Suski & Radek Suski, Sigsiu.NET GmbH * Email: sobi[at]sigsiu.net * Url: https://www.Sigsiu.NET * * @copyright Copyright (C) 2006 - 2020 Sigsiu.NET GmbH (https://www.sigsiu.net). All rights reserved. * @license GNU/LGPL Version 3 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation, and under the additional terms according section 7 of GPL v3. * See https://www.gnu.org/licenses/lgpl.html and https://www.sigsiu.net/licenses. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * @created Wed, Nov 30, 2016 by Radek Suski * @modified 20 May 2020 by Sigrid Suski */ namespace Sobi\Database; defined( 'SOBI' ) || exit( 'Restricted access' ); use Sobi\C; use Sobi\Framework; use Sobi\Error\Exception; use Sobi\Utils\Serialiser; use Sobi\Utils\StringUtils; /** * Class MySQLi * @package Sobi\Database */ class MySQLi { /*** Joomla Database object @var \JDatabaseDriverMysqli */ protected $db = null; /*** @var string */ protected $prefix = '#__'; /*** @var int */ protected $count = 0; /** * @return \Sobi\Database\MySQLi */ public function __construct() { $this->db = \JFactory::getDBO(); return $this; } /** * @return \Sobi\Database\MySQLi */ public static function & getInstance() { static $db = null; if ( !$db || !( $db instanceof self ) ) { $db = new self(); } return $db; } /** * Returns the error number. * * @return int * @deprecated */ public function getErrorNum() { return $this->db->getErrorNum(); } /** * Returns the error message. * * @return string * @deprecated */ public function getErrorMsg() { return $this->db->getErrorMsg(); } /** * Proxy pattern. * * @param string $method * @param array $args * * @return mixed * @throws Exception */ public function __call( $method, $args ) { if ( $this->db && method_exists( $this->db, $method ) ) { $Args = []; // http://www.php.net/manual/en/function.call-user-func-array.php#91503 foreach ( $args as $k => &$arg ) { $Args[ $k ] = &$arg; } return call_user_func_array( [ $this->db, $method ], $Args ); } else { throw new Exception( Framework::Txt( 'CALL_TO_UNDEFINED_CLASS_METHOD', get_class( $this->_type ), $method ) ); } } /** * Returns a database escaped string * * @param string $text string to be escaped * @param bool $esc extra escaping * * @return string */ public function getEscaped( $text, $esc = false ) { return $this->db->getEscaped( StringUtils::Clean( $text ), $esc ); } /** * Returns a database escaped string * * @param string $text string to be escaped * @param bool $esc extra escaping * * @return string */ public function escape( $text, $esc = false ) { return $this->db->escape( $text, $esc ); } /** * Returns database null date format * * @return string Quoted null date string */ public function getNullDate() { return $this->db->getNullDate(); } /** * Sets the SQL query string for later execution. * * @param string $sql * * @return MySQLi */ public function & setQuery( $sql ) { $sql = str_replace( 'spdb', $this->prefix . 'sobipro', $sql ); $sql = str_replace( 'NOW()', '\'' . gmdate( 'Y-m-d H:i:s' ) . '\'', $sql ); $this->db->setQuery( $sql ); return $this; } /* (non-PHPdoc) * @see Site/lib/base/SPDatabase#loadFile($file) */ /** * @param $file * * @return array * @throws Exception */ public function loadFile( $file ) { $sql = file_get_contents( $file ); $sql = explode( "\n", $sql ); $log = []; if ( is_array( $sql ) && count( $sql ) ) { foreach ( $sql as $query ) { if ( strlen( $query ) ) { $this->exec( str_replace( 'spdb_', $this->prefix . 'sobipro_', $query ) ); $log[] = $query; } } } return $log; } /** * Alias for select where $distinct is true * * @param string | array $toSelect * @param string | array $tables * @param string | array $where * @param string $order * @param int $limit * @param int $limitStart * @param null $group * * @return \Sobi\Database\MySQLi */ public function dselect( $toSelect, $tables, $where = null, $order = null, $limit = 0, $limitStart = 0, $group = null ) { return $this->select( $toSelect, $tables, $where, $order, $limit, $limitStart, true, $group ); } /** * Creates a "select" SQL query. * * @param string | array $toSelect - table rows to select * @param string $tables - from which table(s) * @param string | array $where - SQL select condition * @param null $order * @param int $limit - maximal number of rows * @param int $limitStart - start position * @param bool $distinct - clear?? * @param string $groupBy - column to group by * * @return \Sobi\Database\MySQLi */ public function & select( $toSelect, $tables, $where = null, $order = null, $limit = 0, $limitStart = 0, $distinct = false, $groupBy = null ) { $limits = null; $ordering = null; $where = $this->where( $where ); $where = $where ? "WHERE {$where}" : null; $distinct = $distinct ? ' DISTINCT ' : null; $tables = is_array( $tables ) ? implode( ', ', $tables ) : $tables; $groupBy = $groupBy ? "GROUP BY {$groupBy}" : null; $limitStart = $limitStart < 0 ? 0 : $limitStart; if ( $limit ) { $limits = "LIMIT {$limitStart}, {$limit}"; } if ( is_array( $toSelect ) ) { $toSelect = implode( ',', $toSelect ); } if ( $order ) { $n = false; if ( strstr( $order, '.num' ) ) { $order = str_replace( '.num', null, $order ); $n = true; } if ( strstr( $order, ',' ) ) { $o = explode( ',', $order ); $order = []; foreach ( $o as $p ) { if ( strstr( $p, '.' ) ) { $p = explode( '.', $p ); $order[] = $p[ 0 ] . ' ' . strtoupper( $p[ 1 ] ); } else { $order[] = $p; } } $order = implode( ', ', $order ); } else { if ( strstr( $order, '.' ) && ( stristr( $order, 'asc' ) || stristr( $order, 'desc' ) ) ) { $order = explode( '.', $order ); $ext = array_pop( $order ); if ( $n ) { $order = implode( '.', $order ) . '+0 ' . $ext; } else { $order = implode( '.', $order ) . ' ' . $ext; } } else { if ( $n ) { $order .= '+0'; } } } $ordering = "ORDER BY {$order}"; } $this->setQuery( "SELECT {$distinct}{$toSelect} FROM {$tables} {$where} {$groupBy} {$ordering} {$limits}" ); return $this; } /** * Creates a "delete" SQL query. * * @param string $table - in which table * @param string | array $where - SQL delete condition * @param int $limit - maximal number of rows to delete * * @return \Sobi\Database\MySQLi * @throws Exception */ public function & delete( $table, $where, $limit = 0 ) { $where = $this->where( $where ); $limit = $limit ? "LIMIT $limit" : null; try { $this->exec( "DELETE FROM {$table} WHERE {$where} {$limit}" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $this; } /** * Creates a "drop table" SQL query. * * @param string $table - in which table * @param bool|string $ifExists * * @return \Sobi\Database\MySQLi * @throws Exception */ public function & drop( $table, $ifExists = true ) { $ifExists = $ifExists ? 'IF EXISTS' : null; try { $this->exec( "DROP TABLE {$ifExists} {$table}" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $this; } /** * Creates a "truncate table" SQL query. * * @param string $table - in which table * * @return \Sobi\Database\MySQLi * @throws Exception */ public function & truncate( $table ) { try { $this->exec( "TRUNCATE TABLE {$table}" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $this; } /** * Creates where condition from a given array. * * @param array $where - array with values. array( 'id' => 5, 'published' => 1 ) OR array( 'id' => array( 5, 3, 4 ), 'published' => 1 ) * @param string $andor - join conditions through AND or OR * * @return string */ public function where( $where, $andor = 'AND' ) { if ( is_array( $where ) ) { $w = []; foreach ( $where as $col => $val ) { $equal = '='; $not = false; // sort of workaround for incompatibility between RC3 and RC4 if ( $col == 'language' && !( count( (array) $val ) ) ) { $val = 'en-GB'; } /* like: * array( '!key' => 'value' ) * produces sql query with * key NOT 'value' */ if ( strpos( $col, '!' ) !== false && strpos( $col, '!' ) == 0 ) { $col = trim( str_replace( '!', null, $col ) ); $not = true; } /* current means get previous query */ if ( is_string( $val ) && ( string ) $val == '@CURRENT' ) { $n = $not ? 'NOT' : null; $val = $this->db->getQuery(); $w[] = " ( {$col} {$n} IN ( {$val} ) ) "; } /* see SPDb#valid() */ else { if ( $col == '@VALID' ) { $w[] = $val; } else { if ( is_numeric( $col ) ) { $w[] = $this->escape( $val ); } /* like: * array( 'key' => array( 'from' => 1, 'to' => 10 ) ) * produces sql query with * key BETWEEN 1 AND 10 */ else { if ( is_array( $val ) && ( isset( $val[ 'from' ] ) || isset( $val[ 'to' ] ) ) ) { if ( ( isset( $val[ 'from' ] ) && isset( $val[ 'to' ] ) ) && $val[ 'from' ] != C::NO_VALUE && $val[ 'to' ] != C::NO_VALUE ) { $val[ 'to' ] = $this->escape( $val[ 'to' ] ); $val[ 'from' ] = $this->escape( $val[ 'from' ] ); $w[] = " ( {$col} * 1.0 BETWEEN {$val['from']} AND {$val['to']} ) "; } else { if ( $val[ 'from' ] != C::NO_VALUE && $val[ 'to' ] == C::NO_VALUE ) { $val[ 'from' ] = $this->escape( $val[ 'from' ] ); $w[] = " ( {$col} * 1.0 > {$val['from']} ) "; } else { if ( $val[ 'from' ] == C::NO_VALUE && $val[ 'to' ] != C::NO_VALUE ) { $val[ 'to' ] = $this->escape( $val[ 'to' ] ); $w[] = " ( {$col} * 1.0 < {$val['to']} ) "; } } } } /* like: * array( 'key' => array( 1,2,3,4 ) ) * produces sql query with * key IN ( 1,2,3,4 ) */ else { if ( is_array( $val ) ) { $v = []; foreach ( $val as $k ) { if ( strlen( $k ) || $k == C::NO_VALUE ) { $k = $k == C::NO_VALUE ? null : $k; $k = $this->escape( $k ); $v[] = "'{$k}'"; } } $val = implode( ',', $v ); $n = $not ? 'NOT' : null; $w[] = " ( {$col} {$n} IN ( {$val} ) ) "; } else { /* changes the equal sign */ $n = $not ? '!' : null; /* is lower */ if ( strpos( $col, '<' ) ) { $equal = '<'; $col = trim( str_replace( '<', null, $col ) ); } /* is greater */ else { if ( strpos( $col, '>' ) ) { $equal = '>'; $col = trim( str_replace( '>', null, $col ) ); } /* is like */ else { if ( strpos( $val, '%' ) !== false ) { if ( $n == '!' ) { $n = null; $equal = 'NOT LIKE'; } else { $equal = 'LIKE'; } } /* regular expressions handling * array( 'key' => 'REGEXP:^search$' ) */ else { if ( strpos( $val, 'REGEXP:' ) !== false ) { $equal = 'REGEXP'; $val = str_replace( 'REGEXP:', null, $val ); } else { if ( strpos( $val, 'RLIKE:' ) !== false ) { $equal = 'RLIKE'; $val = str_replace( 'RLIKE:', null, $val ); } } } } } /* ^^ regular expressions handling ^^ */ /* SQL functions within the query * array( 'created' => 'FUNCTION:NOW()' ) */ if ( strstr( $val, 'FUNCTION:' ) ) { $val = str_replace( 'FUNCTION:', null, $val ); } else { $val = $this->escape( $val ); $val = "'{$val}'"; } $w[] = " ( {$col} {$n}{$equal}{$val} ) "; } } } } } } $where = implode( " {$andor} ", $w ); } return $where; } /** * Sample usage * $fields = array( * 'url' => 'VARCHAR(255) NOT NULL', * 'crid' => 'INT(11) NOT NULL AUTO_INCREMENT', * 'state' => 'TINYINT(1) NOT NULL' * ); * $keys = array( * 'crid' => 'primary', * 'url' => 'unique' * ); * SPFactory::db()->createTable( 'crawler', $fields, $keys, true, 'MyISAM' ); * * Would create query like: * * CREATE TABLE IF NOT EXISTS `#__sobipro_crawler` ( * `url` VARCHAR(255) NOT NULL, * `crid` INT(11) NOT NULL AUTO_INCREMENT, * `state` TINYINT(1) NOT NULL, * PRIMARY KEY (`crid`), * UNIQUE KEY `url` (`url`) * ) ENGINE = MyISAM DEFAULT CHARSET = utf8; * * * @param string $name - table name without any prefix * @param array $fields - array with fields definition like: $fields[ 'url' ] = 'VARCHAR(255) NOT NULL'; * @param array $keys - optional array with keys defined like: $keys[ 'url' ] = 'unique'; || $keys[ 'url, crid' ] = 'primary'; * @param bool $notExists - adds "CREATE TABLE IF NOT EXISTS" * @param string $engine - optional engine type * @param string $charset * * @return $this * @throws Exception */ public function & createTable( $name, $fields, $keys = [], $notExists = false, $engine = null, $charset = 'utf8' ) { $name = "#__sobipro_{$name}"; $query = $notExists ? "CREATE TABLE IF NOT EXISTS `{$name}` " : "CREATE TABLE `{$name}` "; $subQuery = null; $count = count( $fields ); $i = 0; foreach ( $fields as $name => $definition ) { $i++; $subQuery .= "`{$name}` {$definition}"; if ( $i < $count || count( $keys ) ) { $subQuery .= ', '; } else { $subQuery .= ' '; } } if ( count( $keys ) ) { $count = count( $keys ); $i = 0; foreach ( $keys as $key => $type ) { $type = strtoupper( $type ); if ( strstr( $key, ',' ) ) { $_keys = explode( ',', $key ); $key = null; foreach ( $_keys as $i => $subkey ) { $_keys[ $i ] = "`{$subkey}`"; } $key = implode( ',', $_keys ); } else { $key = "`{$key}`"; } $subQuery = "{$type} KEY ( {$key} )"; if ( $i < $count ) { $subQuery .= ', '; } else { $subQuery .= ' '; } } } $query .= "( {$subQuery} ) "; if ( $engine ) { $query .= " ENGINE = {$engine} "; } $query .= "DEFAULT CHARSET = {$charset};"; $this->exec( $query ); return $this; } /* Arguments and or or * (non-PHPdoc) * @see Site/lib/base/SPDatabase#argsOr($val) */ /** * @param $val * * @return string */ public function argsOr( $val ) { $cond = []; foreach ( $val as $i => $k ) { $equal = ' = '; if ( strpos( $i, '<' ) ) { $equal = '<'; $i = trim( str_replace( '<', null, $i ) ); } /* is greater */ else { if ( strpos( $i, '>' ) ) { $equal = '>'; $i = trim( str_replace( '>', null, $i ) ); } } if ( $i == '@VALID' ) { $cond[] .= $k; } else { $cond[] .= $i . $equal . $k; } } $cond = implode( ' OR ', $cond ); return '( ' . $cond . ' )'; } /** * Creates a "update" SQL query * * @param string $table - table to update * @param array $set - two-dimensional array with table row name to update => new value * @param array|string $where - SQL update condition * @param int $limit * * @throws Exception */ public function update( $table, $set, $where, $limit = 0 ) { $change = []; $where = $this->where( $where ); foreach ( $set as $var => $state ) { if ( is_array( $state ) || is_object( $state ) ) { $state = Serialiser::serialise( $state ); } $var = $this->escape( $var ); $state = $this->escape( $state ); if ( strstr( $state, 'FUNCTION:' ) ) { $state = str_replace( 'FUNCTION:', null, $state ); } else { if ( strlen( $state ) == 2 && $state == '++' ) { $state = "{$var} + 1"; } else { $state = "'{$state}'"; } } $change[] = "{$var} = {$state}"; } $change = implode( ',', $change ); $l = $limit ? " LIMIT {$limit} " : null; $this->exec( "UPDATE {$table} SET {$change} WHERE {$where}{$l}" ); } /** * Creates a "replace" SQL query * * @param string $table - table name * @param array $values - two-dimensional array with table row name => value * * @throws Exception */ public function replace( $table, $values ) { $v = []; foreach ( $values as $var => $val ) { if ( is_array( $val ) || is_object( $val ) ) { $val = Serialiser::serialise( $val ); } $val = $this->escape( $val ); if ( strstr( $val, 'FUNCTION:' ) ) { $v[] = str_replace( 'FUNCTION:', null, $val ); } else { $v[] = "'{$val}'"; } } $v = implode( ',', $v ); try { $this->exec( "REPLACE INTO {$table} VALUES ({$v})" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } } /** * Creates a "insert" SQL query * * @param string $table - table name * @param array $values - two-dimensional array with table row name => value * @param bool $ignore - adds "IGNORE" after "INSERT" command * @param bool $normalize - if the $values is a two-dimensional, array and it's not complete - fit to the columns * * @return \Sobi\Database\MySQLi * @throws Exception */ public function & insert( $table, $values, $ignore = false, $normalize = false ) { $ignore = $ignore ? 'IGNORE ' : null; $v = []; if ( $normalize ) { $this->normalize( $table, $values ); } foreach ( $values as $val ) { if ( is_array( $val ) || is_object( $val ) ) { $val = Serialiser::serialise( $val ); } $val = $this->escape( $val ); if ( strstr( $val, 'FUNCTION:' ) ) { $v[] = str_replace( 'FUNCTION:', null, $val ); } else { $v[] = "'{$val}'"; } } $v = implode( ',', $v ); try { $this->exec( "INSERT {$ignore} INTO {$table} VALUES ({$v})" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $this; } /** * Fits a two dimensional array to the necessary columns of the given table * * @param string $table - table name * @param array $values * * @throws Exception */ public function normalize( $table, &$values ) { $normalised = []; $cols = $this->getColumns( $table ); /* sort the properties in the same order */ foreach ( $cols as $col ) { $normalised[ $col ] = isset( $values[ $col ] ) ? $values[ $col ] : ''; } $values = $normalised; } /** * Creates a "insert" SQL query with multiple values * * @param string $table - table name * @param array $values - one-dimensional array with two-dimensional array with table row name => value * @param bool $update - update existing row if cannot insert it because of duplicate primary key * @param bool $ignore - adds "IGNORE" after "INSERT" command * * @return \Sobi\Database\MySQLi * @throws Exception */ public function & insertArray( $table, $values, $update = false, $ignore = false ) { $ignore = $ignore ? 'IGNORE ' : null; $rows = []; foreach ( $values as $arr ) { $v = []; $vars = []; $k = []; foreach ( $arr as $var => $val ) { if ( is_array( $val ) || is_object( $val ) ) { $val = Serialiser::serialise( $val ); } $vars[] = "{$var} = VALUES( {$var} )"; $k[] = $var; $val = $this->escape( $val ); if ( strstr( $val, 'FUNCTION:' ) ) { $v[] = str_replace( 'FUNCTION:', null, $val ); } else { $v[] = "'{$val}'"; } } $rows[] = implode( ',', $v ); } $vars = implode( ', ', $vars ); $rows = implode( " ), \n ( ", $rows ); $k = implode( '`,`', $k ); $update = $update ? "ON DUPLICATE KEY UPDATE {$vars}" : null; try { $this->exec( "INSERT {$ignore} INTO {$table} ( `{$k}` ) VALUES ({$rows}) {$update}" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $this; } /** * Creates a "insert" SQL query with update if cannot insert it because of duplicate primary key * * @param string $table - table name * @param array $values - two-dimensional array with table row name => value * * @return \Sobi\Database\MySQLi * @throws Exception */ public function & insertUpdate( $table, $values ) { $v = []; $c = []; $k = []; foreach ( $values as $var => $val ) { if ( is_array( $val ) || is_object( $val ) ) { $val = Serialiser::serialise( $val ); } $val = $this->escape( $val ); if ( strstr( $val, 'FUNCTION:' ) ) { $f = str_replace( 'FUNCTION:', null, $val ); $v[] = $f; $c[] = "{$var} = {$f}"; } else { $v[] = "'{$val}'"; $c[] = "{$var} = '{$val}'"; } $k[] = "`{$var}`"; } $v = implode( ',', $v ); $c = implode( ',', $c ); $k = implode( ',', $k ); try { $this->exec( "INSERT INTO {$table} ({$k}) VALUES ({$v}) ON DUPLICATE KEY UPDATE {$c}" ); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $this; } /** * Returns current query * * @return string */ public function getQuery() { return str_replace( $this->prefix, $this->db->getPrefix(), $this->db->getQuery() ); } /** * Returns queries counter * * @return int */ public function getCount() { return $this->count; } /** * Execute the query * * @return mixed database resource or <var>false</var>. */ public function query() { $this->count++; return $this->db->execute(); } /** * Loads the first field of the first row returned by the query. * * @return string * @throws Exception */ public function loadResult() { try { $r = $this->db->loadResult(); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Load an array of single field results into an array * * @return array * @throws Exception */ public function loadResultArray() { try { $r = $this->db->loadColumn(); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Load a assoc list of database rows * * @param string $key field name of a primary key * * @return array If <var>key</var> is empty as sequential list of returned records. * @throws Exception */ public function loadAssocList( $key = null ) { try { $r = $this->db->loadAssocList( $key ); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Loads the first row of a query into an object * * @return stdObject * @throws Exception */ public function loadObject() { try { $r = $this->db->loadObject(); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } if ( $r && is_object( $r ) ) { $attr = get_object_vars( $r ); foreach ( $attr as $property => $value ) { if ( is_string( $value ) && strstr( $value, '"' ) ) { $r->$property = StringUtils::Clean( $value ); } } } return $r; } /** * Load a list of database objects * * @param string $key * * @return array If <var>key</var> is empty as sequential list of returned records. * @throws Exception */ public function loadObjectList( $key = null ) { try { $r = $this->db->loadObjectList( $key ); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Load the first row of the query. * * @return array * @throws Exception */ public function loadRow() { try { $r = $this->db->loadRow(); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Load a list of database rows (numeric column indexing) * * @param string $key field name of a primary key * * @return array If <var>key</var> is empty as sequential list of returned records. * @throws Exception */ public function loadRowList( $key = null ) { try { $r = $this->db->loadRowList( $key ); $this->count++; } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Returns an error statement * @return string * @deprecated */ public function stderr() { return $this->db->stderr(); } /** * Returns the ID generated from the previous insert operation * * @return int */ public function insertid() { return $this->db->insertid(); } /** * executing query (update/insert etc) * * @param string $query - query to execute * * @return mixed * @throws Exception */ public function exec( $query ) { $this->setQuery( $query ); try { $r = $this->query(); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } return $r; } /** * Returns all rows of given table * * @param string $table * * @return array * @throws Exception */ public function getColumns( $table ) { static $cache = []; if ( !( isset( $cache[ $table ] ) ) ) { $this->setQuery( "SHOW COLUMNS FROM {$table}" ); try { $cache[ $table ] = $this->loadResultArray(); } catch ( \Exception $e ) { throw new Exception( $e->getMessage() ); } } return $cache[ $table ]; } /** * Rolls back the current transaction, canceling its changes. * * @return bool * @throws Exception */ public function rollback() { return $this->exec( 'ROLLBACK;' ) !== false ? true : false; } /** * Begins a new transaction. * * @return bool * @throws Exception */ public function transaction() { return $this->exec( 'START TRANSACTION;' ) !== false ? true : false; } /** * Commits the current transaction, making its changes permanent. * * @return bool * @throws Exception */ public function commit() { return $this->exec( 'COMMIT;' ) !== false ? true : false; } /** * Returns current datetime in database acceptable format. * * @return string */ public function now() { return date( 'Y-m-d H:i:s' ); } /** * Creates syntax for join two tables. * * @param array $params - two cells array with table name <var>table</var>, alias name <var>as</var> and common key <var>key</var> * @param string $through - join direction (left/right) * * @return string */ public function join( $params, $through = 'left' ) { $through = strtoupper( $through ); $join = null; if ( count( $params ) > 2 ) { $joins = []; $c = 0; foreach ( $params as $table ) { if ( isset( $table[ 'table' ] ) ) { $join = "\n {$table['table']} AS {$table['as']} "; if ( $c > 0 ) { if ( isset( $table[ 'key' ] ) ) { if ( is_array( $table[ 'key' ] ) ) { $join .= " ON {$table['key'][0]} = {$table['key'][1]} "; } else { $join .= " ON {$params[0]['as']}.{$table['key']} = {$table['as']}.{$table['key']} "; } } } $joins[] = $join; } $c++; } $join = implode( " {$through} JOIN ", $joins ); } else { if ( ( isset( $params[ 0 ][ 'table' ] ) && isset( $params[ 0 ][ 'as' ] ) && isset( $params[ 0 ][ 'key' ] ) ) && ( isset( $params[ 1 ][ 'table' ] ) && isset( $params[ 1 ][ 'as' ] ) && isset( $params[ 1 ][ 'key' ] ) ) ) { $join = " {$params[0]['table']} AS {$params[0]['as']} {$through} JOIN {$params[1]['table']} AS {$params[1]['as']} ON {$params[0]['as']}.{$params[0]['key']} = {$params[1]['as']}.{$params[1]['key']}"; } } return $join; } /** * Creates syntax to check the expiration date, state, and start publishing date off an row * * @param string $until - row name where the expiration date is stored * @param string $since - row name where the start date is stored * @param string $pub - row name where the state is stored (e.g. 'published') * @param array $exception * * @return string */ public function valid( $until, $since = null, $pub = null, $exception = null ) { $null = $this->getNullDate(); $pub = $pub ? " AND {$pub} = 1 " : null; $stamp = date( 'Y-m-d H:i:s', 0 ); if ( $since ) { // $since = "AND ( {$since} < '{$now}' OR {$since} IN( '{$null}', '{$stamp}' ) ) "; $since = "AND ( {$since} < NOW() OR {$since} IN( '{$null}', '{$stamp}' ) ) "; } if ( $exception && is_array( $exception ) ) { $ex = []; foreach ( $exception as $subject => $value ) { $ex[] = "{$subject} = '{$value}'"; } $exception = implode( 'OR', $ex ); $exception = 'OR ' . $exception; } // return " ( ( {$until} > '{$now}' OR {$until} IN ( '{$null}', '{$stamp}' ) ) {$since} {$pub} ) "; return "( ( {$until} > NOW() OR {$until} IN ( '{$null}', '{$stamp}' ) ) {$since} {$pub} ) {$exception} "; } }