2012-06-04 14:58:40 +00:00
<? php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Mark J Crane <markjcrane@fusionpbx.com>
2022-01-24 15:33:34 -07:00
Copyright (C) 2010 - 2022
2012-06-04 14:58:40 +00:00
All Rights Reserved.
Contributor(s):
Mark J Crane <markjcrane@fusionpbx.com>
2014-06-21 04:59:25 +00:00
Luis Daniel Lucio Quiroz <dlucio@okay.com.mx>
2012-06-04 14:58:40 +00:00
*/
//define the database class
if ( ! class_exists ( 'database' )) {
class database {
2019-11-23 15:30:29 -07:00
2022-09-17 17:44:21 -04:00
const TABLE_PREFIX = "v_" ;
/**
* Database connection
* @access private
* @var PDO object
*/
2023-05-09 08:39:42 -06:00
public $db ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Driver to use.
* @access private
* @var string Can be pgsql, mysql, sqlite, odbc
*/
private $driver ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Alias of driver.
* @access private
* @var string Can be pgsql, mysql, sqlite, odbc
* @see $driver
*/
private $type ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Host for database connection
* @access private
* @var string host name or IP address.
*/
private $host ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Port number
* @access private
* @var int 1025 - 65534
*/
private $port ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Database name
* @access private
* @var string
*/
private $db_name ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Database security
* @access private
* @var boolean
*/
private $db_secure ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Specifies the file name of the client SSL certificate
* @access private
* @var string full path
*/
private $db_cert_authority ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Username used to connect
* @access private
* @var string
*/
private $username ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Password used to connect
* @access private
* @var string
*/
private $password ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Full path to file name.
* @access private
* @var string full path to file name
*/
private $path ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Table name.
* @access private
* @var string sanitized
*/
private $table ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Where clause(s) of an SQL statement.
* <p>Array of arrays must be passed with each having the
* following keys:
* <ol><li>'name' - Any valid column name.</li>
* <li>'operator' - Must be <b>one</b> of the following values: =, >, <, >=, <=, <>, !=</li>
* <li>'value' - Value being matched</li></ol></p>
* <p>Example Usage:</p>
* <p><code>$db->where['SearchTerm'] = ['name'=>'MyColumn','operator'=>'=','value'=>'MySearchTerm'</code></p>
* <p><code>$db->where['NextSearchTerm'] = ['name'=>'MyColumn','operator'=>'=','value'=>'MyOtherSearchTerm'</code></p>
* <p>Below is equivalent to the above.</p>
* <p><code>$db->where[0] = ['name'=>'MyColumn','operator'=>'=','value'=>'MyValue'</code></p>
* <p><code>$db->where[1] = ['name'=>'MyColumn','operator'=>'=>','value'=>'MyValue'</code></p>
* @access private
* @var array Two dimensional array of key value pairs
* @see $order_by
*/
2022-12-14 09:58:27 -07:00
public $where ; //array
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Order By clause(s) of an SQL statement.
* <p>Array of arrays must be passed with each having the
* following keys:
* <ol><li>'name' - Any valid column name.</li>
* <li>'operator' - Must be <b>one</b> of the following values: =, >, <, >=, <=, <>, !=</li>
* <li>'value' - Value being matched</li></ol></p>
* <p>Example Usage:</p>
* <p><code>$db->where['SearchTerm'] = ['name'=>'MyColumn','operator'=>'=','value'=>'MySearchTerm'</code></p>
* <p><code>$db->where['NextSearchTerm'] = ['name'=>'MyColumn','operator'=>'=','value'=>'MyOtherSearchTerm'</code></p>
* <p>Below is equivalent to the above.</p>
* <p><code>$db->where[0] = ['name'=>'MyColumn','operator'=>'=','value'=>'MyValue'</code></p>
* <p><code>$db->where[1] = ['name'=>'MyColumn','operator'=>'=>','value'=>'MyValue'</code></p>
* @access private
* @var array Two dimensional array of key value pairs
* @see $where
*/
2022-12-14 09:58:27 -07:00
public $order_by ; //array
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Ascending or Descending order.
* @var string
* @access private
*/
private $order_type ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Numerical value to limit returned results.
* @var int Used for 'LIMIT' in SQL statement.
* @access private
*/
private $limit ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Numerical value to offset returned results.
* @var int Used for 'OFFSET' in SQL statement.
* @access private
*/
private $offset ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* <p>Array of fields.</p>
* <p>Fields are specified in 'name'=>'value' format.
* <p>Used by {@link database::add() } and {@link database::update() }</p>
* @access private
* @var array Array of columns
* @see database::add()
* @see database::update()
*/
private $fields ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Unknown property
* @var unknown
* @access private
*/
private $count ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Unknown property
* @var unknown
* @access private
*/
private $sql ;
2022-09-18 02:13:33 -06:00
2019-11-23 15:30:29 -07:00
/**
2022-09-17 17:44:21 -04:00
* <p>Stores the result from the most recent query. The type will be based on what was requested.</p>
* <p><b>NOTE:</b> If an error occurred on the last query the result is set to an empty string.</p>
* @var mixed
2019-11-23 15:30:29 -07:00
*/
2022-09-17 17:44:21 -04:00
private $result ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Stores the application name making the request.
* @var string App name making database request.
* @see $app_uuid
2022-12-22 13:04:24 -07:00
* @access public
2022-09-17 17:44:21 -04:00
*/
2022-12-22 13:04:24 -07:00
public $app_name ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* Stores the application UUID making the request.
* @var string
* @see $app_name
2022-12-22 13:04:24 -07:00
* @access public
2022-09-17 17:44:21 -04:00
*/
2022-12-22 13:04:24 -07:00
public $app_uuid ;
2022-09-18 02:13:33 -06:00
2022-09-17 17:44:21 -04:00
/**
* <p>Stores the domain UUID making the request.</p>
* <p>This is defaulted to the Session domain UUID.</p>
* @access private
* @uses $_SESSION['domain_uuid'] <br>Default value upon object creation
* @var string Domain UUID making request.
*/
private $domain_uuid ;
/**
* <p>Message for the query results.</p>
* @var array Contains the message array after a query
* @access private
*/
private $message ;
2017-09-11 01:21:36 -05:00
/**
* Called when the object is created
*/
public function __construct () {
2022-12-22 13:04:24 -07:00
if ( ! isset ( $this -> domain_uuid ) && isset ( $_SESSION [ 'domain_uuid' ])) {
2017-09-11 01:21:36 -05:00
$this -> domain_uuid = $_SESSION [ 'domain_uuid' ];
}
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
/**
* <p>Magic function called whenever a property is attempted to be set.</p>
* <p>This is used to protect the values stored in the object properties.</p>
* @param mixed $name Name of object property
* @param mixed $value Value of property
*/
public function __set ( $name , $value ) {
switch ( $name ) {
case 'name' :
case 'app_name' :
$this -> app_name = self :: sanitize ( $value );
break ;
case 'message' :
2022-09-18 02:59:58 -06:00
if ( is_array ( $value )) {
2022-09-17 17:44:21 -04:00
$this -> message = $value ;
} else {
trigger_error ( 'Message property must be set to array type' , E_USER_ERROR );
}
break ;
case 'table' :
$this -> table = self :: sanitize ( $value );
break ;
case 'db_name' :
$this -> db_name = self :: sanitize ( $value );
break ;
case 'db' :
2022-09-18 02:59:58 -06:00
if ( $name instanceof PDO ) {
2022-09-17 17:44:21 -04:00
$this -> db = $value ;
} else {
trigger_error ( 'db property must be a PDO object!' , E_USER_ERROR );
}
break ;
case 'count' :
break ;
case 'path' :
$value = realpath ( $value );
2022-09-18 02:59:58 -06:00
if ( file_exists ( $value )) {
2022-09-17 17:44:21 -04:00
$this -> path = $value ;
} else {
trigger_error ( 'Unable to find database path file!' , E_USER_ERROR );
}
break ;
case 'db_cert_authority' :
2022-09-18 02:59:58 -06:00
if ( ! file_exists ( $value )) {
2022-09-17 17:44:21 -04:00
trigger_error ( 'db cert authority not found!' , E_USER_WARNING );
}
$this -> db_cert_authority = $value ;
break ;
case 'port' :
$value = ( int ) $value ; // force cast to int
2022-09-18 02:59:58 -06:00
if ( $value > 1023 && $value < 65536 ) { $this -> port = $value ; } //valid values are 1024...65535
2022-09-17 17:44:21 -04:00
else { trigger_error ( 'Port not a valid range' , E_USER_ERROR ); }
break ;
case 'app_uuid' :
case 'domain_uuid' :
2022-09-18 02:59:58 -06:00
if ( is_uuid ( $value )) { $this -> domain_uuid = $value ; }
2022-09-17 17:44:21 -04:00
break ;
case 'type' :
case 'driver' :
switch ( $value ) {
case 'pgsql' :
case 'mysql' :
case 'sqlite' :
case 'odbc' :
$this -> type = $value ;
$this -> driver = $value ;
break ;
default :
trigger_error ( "Type/Driver must be set to pgsql,mysql,sqlite,odbc" , E_USER_ERROR );
break ;
}
case 'offset' :
case 'limit' :
2022-09-18 02:59:58 -06:00
if ( is_int ( $value )) {
2022-09-17 17:44:21 -04:00
$this -> $name = $value ;
} else {
trigger_error ( 'Offset or Limit not set to valid integer. Resetting to zero!' , E_USER_WARNING );
}
break ;
case '' :
trigger_error ( 'Database property must not be empty' , E_USER_ERROR );
break ;
case 'null' :
case null :
trigger_error ( 'Database property must not be null' , E_USER_ERROR );
break ;
case 'debug' :
$this -> debug = $value ;
}
}
/**
* Magic function called whenever a property is requested.
* <p>If any case statement is removed then access to the variable will be removed.</p>
* @param mixed $name object property
* @return mixed
*/
public function __get ( $name ) {
//remove any case statement below to remove access to the variable
switch ( $name ) {
case 'name' :
return $this -> app_name ;
case 'app_name' :
case 'app_uuid' :
case 'db' :
case 'db_cert_authority' :
case 'db_name' :
case 'db_secure' :
case 'domain_uuid' :
case 'driver' :
case 'fields' :
case 'host' :
case 'limit' :
case 'message' :
case 'offset' :
case 'order_by' :
case 'order_type' :
case 'password' :
case 'path' :
case 'port' :
case 'result' :
case 'sql' :
case 'table' :
case 'type' :
case 'username' :
case 'where' :
case 'debug' :
case 'count' :
return $this -> count ();
default :
trigger_error ( 'Object property not available' , E_USER_ERROR );
}
}
2017-09-11 01:21:36 -05:00
/**
2022-09-17 17:44:21 -04:00
* <p>Connect to the database.</p>
* <p>Database driver must be set before calling connect.</p>
* <p>For types other than sqlite. Execution will stop on failure.</p>
* @depends database::driver Alias of database::type.
*
2017-09-11 01:21:36 -05:00
*/
2012-06-04 14:58:40 +00:00
public function connect () {
2022-10-10 19:43:07 -06:00
//set the include path
$conf = glob ( "{/usr/local/etc,/etc}/fusionpbx/config.conf" , GLOB_BRACE );
set_include_path ( parse_ini_file ( $conf [ 0 ])[ 'document.root' ]);
2022-11-01 15:52:56 -06:00
2022-10-10 19:43:07 -06:00
//parset the config.conf file
$conf = parse_ini_file ( $conf [ 0 ]);
//get the database connection settings
$db_type = $conf [ 'database.0.type' ];
$db_host = $conf [ 'database.0.host' ];
$db_port = $conf [ 'database.0.port' ];
$db_name = $conf [ 'database.0.name' ];
$db_username = $conf [ 'database.0.username' ];
$db_password = $conf [ 'database.0.password' ];
//debug info
//echo "db type:".$db_type."\n";
//echo "db host:".$db_host."\n";
//echo "db port:".$db_port."\n";
//echo "db name:".$db_name."\n";
//echo "db username:".$db_username."\n";
//echo "db password:".$db_password."\n";
//echo "db path:".$db_path."\n";
//echo "</pre>\n";
//set defaults
if ( ! isset ( $this -> driver ) && isset ( $db_type )) { $this -> driver = $db_type ; }
if ( ! isset ( $this -> type ) && isset ( $db_type )) { $this -> type = $db_type ; }
if ( ! isset ( $this -> host ) && isset ( $db_host )) { $this -> host = $db_host ; }
if ( ! isset ( $this -> port ) && isset ( $db_port )) { $this -> port = $db_port ; }
if ( ! isset ( $this -> db_name ) && isset ( $db_name )) { $this -> db_name = $db_name ; }
if ( ! isset ( $this -> db_secure ) && isset ( $db_secure )) {
$this -> db_secure = $db_secure ;
}
else {
$this -> db_secure = false ;
}
if ( ! isset ( $this -> username ) && isset ( $db_username )) { $this -> username = $db_username ; }
if ( ! isset ( $this -> password ) && isset ( $db_password )) { $this -> password = $db_password ; }
if ( ! isset ( $this -> path ) && isset ( $db_path )) { $this -> path = $db_path ; }
2017-07-15 17:09:01 -06:00
2012-07-23 23:31:02 +00:00
if ( $this -> driver == "sqlite" ) {
2023-05-05 13:46:37 -03:00
if ( empty ( $this -> db_name )) {
2012-06-04 14:58:40 +00:00
$server_name = $_SERVER [ "SERVER_NAME" ];
$server_name = str_replace ( "www." , "" , $server_name );
$db_name_short = $server_name ;
2014-01-19 13:06:27 +00:00
$this -> db_name = $server_name . '.db' ;
2012-06-04 14:58:40 +00:00
}
else {
2014-01-19 13:06:27 +00:00
$db_name_short = $this -> db_name ;
2012-06-04 14:58:40 +00:00
}
2012-07-23 23:31:02 +00:00
$this -> path = realpath ( $this -> path );
2014-01-19 13:06:27 +00:00
if ( file_exists ( $this -> path . '/' . $this -> db_name )) {
2016-10-20 15:03:52 -06:00
//connect to the database
$this -> db = new PDO ( 'sqlite:' . $this -> path . '/' . $this -> db_name ); //sqlite 3
2018-05-19 15:48:02 -06:00
//PRAGMA commands
2016-10-20 15:03:52 -06:00
$this -> db -> query ( 'PRAGMA foreign_keys = ON;' );
2018-05-19 15:48:02 -06:00
$this -> db -> query ( 'PRAGMA journal_mode = wal;' );
2016-10-20 15:03:52 -06:00
//add additional functions to SQLite so that they are accessible inside SQL
//bool PDO::sqliteCreateFunction ( string function_name, callback callback [, int num_args] )
$this -> db -> sqliteCreateFunction ( 'md5' , 'php_md5' , 1 );
$this -> db -> sqliteCreateFunction ( 'unix_timestamp' , 'php_unix_timestamp' , 1 );
$this -> db -> sqliteCreateFunction ( 'now' , 'php_now' , 0 );
$this -> db -> sqliteCreateFunction ( 'sqlitedatatype' , 'php_sqlite_data_type' , 2 );
$this -> db -> sqliteCreateFunction ( 'strleft' , 'php_left' , 2 );
$this -> db -> sqliteCreateFunction ( 'strright' , 'php_right' , 2 );
2012-06-04 14:58:40 +00:00
}
2013-06-08 05:58:07 +00:00
else {
echo "not found" ;
2012-06-04 14:58:40 +00:00
}
}
2012-07-23 23:31:02 +00:00
if ( $this -> driver == "mysql" ) {
2012-06-04 14:58:40 +00:00
try {
//mysql pdo connection
2023-05-05 13:46:37 -03:00
if ( strlen ( $this -> host ) == 0 && empty ( $this -> port )) {
2012-06-04 14:58:40 +00:00
//if both host and port are empty use the unix socket
2014-01-19 13:06:27 +00:00
$this -> db = new PDO ( "mysql:host= $this->host ;unix_socket=/var/run/mysqld/mysqld.sock;dbname= $this->db_name " , $this -> username , $this -> password );
2012-06-04 14:58:40 +00:00
}
else {
2023-05-05 13:46:37 -03:00
if ( empty ( $this -> port )) {
2012-06-04 14:58:40 +00:00
//leave out port if it is empty
2014-01-19 13:06:27 +00:00
$this -> db = new PDO ( "mysql:host= $this->host ;dbname= $this->db_name ;" , $this -> username , $this -> password , array (
2012-06-04 14:58:40 +00:00
PDO :: ATTR_ERRMODE ,
PDO :: ERRMODE_EXCEPTION
));
}
else {
2014-01-19 13:06:27 +00:00
$this -> db = new PDO ( "mysql:host= $this->host ;port= $this->port ;dbname= $this->db_name ;" , $this -> username , $this -> password , array (
2012-06-04 14:58:40 +00:00
PDO :: ATTR_ERRMODE ,
PDO :: ERRMODE_EXCEPTION
));
}
}
}
catch ( PDOException $error ) {
print "error: " . $error -> getMessage () . "<br/>" ;
die ();
}
}
2012-07-23 23:31:02 +00:00
if ( $this -> driver == "pgsql" ) {
2012-06-04 14:58:40 +00:00
//database connection
try {
2023-05-05 13:46:37 -03:00
if ( ! empty ( $this -> host )) {
if ( empty ( $this -> port )) { $this -> port = "5432" ; }
2022-09-17 17:44:21 -04:00
if ( $this -> db_secure === true ) {
2019-06-05 22:10:58 -05:00
$this -> db = new PDO ( "pgsql:host= $this->host port= $this->port dbname= $this->db_name user= $this->username password= $this->password sslmode=verify-ca sslrootcert= $this->db_cert_authority " );
}
else {
$this -> db = new PDO ( "pgsql:host= $this->host port= $this->port dbname= $this->db_name user= $this->username password= $this->password " );
}
2012-06-04 14:58:40 +00:00
}
else {
2014-01-19 13:06:27 +00:00
$this -> db = new PDO ( "pgsql:dbname= $this->db_name user= $this->username password= $this->password " );
2012-06-04 14:58:40 +00:00
}
}
catch ( PDOException $error ) {
print "error: " . $error -> getMessage () . "<br/>" ;
die ();
}
}
2012-07-23 23:31:02 +00:00
if ( $this -> driver == "odbc" ) {
//database connection
try {
2014-01-19 13:06:27 +00:00
$this -> db = new PDO ( "odbc:" . $this -> db_name , $this -> username , $this -> password );
2012-07-23 23:31:02 +00:00
}
catch ( PDOException $e ) {
echo 'Connection failed: ' . $e -> getMessage ();
}
}
2012-06-04 14:58:40 +00:00
}
2022-09-17 17:44:21 -04:00
/**
* Returns the table names from the database.
* @return array tables
* @depends connect()
*/
2022-11-01 15:52:56 -06:00
public function tables () {
2022-09-17 17:44:21 -04:00
$result = [];
2012-07-22 05:37:30 +00:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
if ( $this -> type == "sqlite" ) {
$sql = "SELECT name FROM sqlite_master " ;
$sql .= "WHERE type='table' " ;
$sql .= "order by name;" ;
}
if ( $this -> type == "pgsql" ) {
$sql = "select table_name as name " ;
$sql .= "from information_schema.tables " ;
$sql .= "where table_schema='public' " ;
$sql .= "and table_type='BASE TABLE' " ;
$sql .= "order by table_name " ;
}
if ( $this -> type == "mysql" ) {
$sql = "show tables" ;
}
2012-07-23 23:31:02 +00:00
if ( $this -> type == "mssql" ) {
2012-07-28 21:32:44 +00:00
$sql = "SELECT * FROM sys.Tables order by name asc" ;
2012-07-23 23:31:02 +00:00
}
2012-07-22 05:37:30 +00:00
$prep_statement = $this -> db -> prepare ( check_sql ( $sql ));
$prep_statement -> execute ();
$tmp = $prep_statement -> fetchAll ( PDO :: FETCH_NAMED );
2012-07-23 23:31:02 +00:00
if ( $this -> type == "pgsql" || $this -> type == "sqlite" || $this -> type == "mssql" ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $tmp )) {
foreach ( $tmp as & $row ) {
$result [][ 'name' ] = $row [ 'name' ];
}
2012-07-22 06:35:00 +00:00
}
}
if ( $this -> type == "mysql" ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $tmp )) {
foreach ( $tmp as & $row ) {
$table_array = array_values ( $row );
$result [][ 'name' ] = $table_array [ 0 ];
}
2012-07-22 06:35:00 +00:00
}
2012-07-22 05:37:30 +00:00
}
return $result ;
}
2022-09-17 17:44:21 -04:00
/**
* Returns table information from the database.
* @return array table info
* @depends connect()
*/
2022-11-01 15:52:56 -06:00
public function table_info () {
2012-07-22 05:37:30 +00:00
//public $db;
//public $type;
//public $table;
//public $name;
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2022-09-17 17:44:21 -04:00
2012-07-22 05:37:30 +00:00
//get the table info
2023-05-05 13:46:37 -03:00
if ( empty ( $this -> table )) { return false ; }
2012-07-22 05:37:30 +00:00
if ( $this -> type == "sqlite" ) {
$sql = "PRAGMA table_info(" . $this -> table . ");" ;
}
if ( $this -> type == "pgsql" ) {
$sql = "SELECT ordinal_position, " ;
$sql .= "column_name, " ;
$sql .= "data_type, " ;
$sql .= "column_default, " ;
$sql .= "is_nullable, " ;
$sql .= "character_maximum_length, " ;
$sql .= "numeric_precision " ;
$sql .= "FROM information_schema.columns " ;
$sql .= "WHERE table_name = '" . $this -> table . "' " ;
2014-01-19 13:06:27 +00:00
$sql .= "and table_catalog = '" . $this -> db_name . "' " ;
2012-07-22 05:37:30 +00:00
$sql .= "ORDER BY ordinal_position; " ;
}
if ( $this -> type == "mysql" ) {
2012-07-23 23:31:02 +00:00
$sql = "DESCRIBE " . $this -> table . ";" ;
}
if ( $this -> type == "mssql" ) {
$sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" . $this -> table . "'" ;
2012-07-22 05:37:30 +00:00
}
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ();
2022-09-18 02:13:33 -06:00
2012-07-22 05:37:30 +00:00
//set the result array
return $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
}
2022-09-17 17:44:21 -04:00
/**
* Checks if the table exists in the database.
* <p><b>Note:</b><br>
* Table name must be sanitized. Otherwise, a warning will be
* emitted and false will be returned.</p>
* @param type $table_name Sanitized name of the table to search for.
* @return boolean Returns <i>true</i> if the table exists and <i>false</i> if it does not.
* @depends connect()
*/
2022-11-01 15:52:56 -06:00
public function table_exists ( $table_name ) {
2022-09-18 02:59:58 -06:00
if ( self :: sanitize ( $table_name ) != $table_name ) {
2022-09-17 17:44:21 -04:00
trigger_error ( 'Table Name must be sanitized' , E_USER_WARNING );
return false ;
}
2022-09-18 02:13:33 -06:00
2021-08-10 07:54:08 -06:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
//query table store to see if the table exists
$sql = "" ;
2022-09-17 17:44:21 -04:00
if ( $this -> type == "sqlite" ) {
2021-08-10 07:54:08 -06:00
$sql .= "SELECT * FROM sqlite_master WHERE type='table' and name=' $table_name ' " ;
}
2022-09-17 17:44:21 -04:00
if ( $this -> type == "pgsql" ) {
2021-08-10 07:54:08 -06:00
$sql .= "select * from pg_tables where schemaname='public' and tablename = ' $table_name ' " ;
}
2022-09-17 17:44:21 -04:00
if ( $this -> type == "mysql" ) {
2021-08-10 07:54:08 -06:00
$sql .= "SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = ' $db_name ' and TABLE_NAME = ' $table_name ' " ;
}
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ();
$result = $prep_statement -> fetchAll ( PDO :: FETCH_NAMED );
if ( count ( $result ) > 0 ) {
return true ; //table exists
}
else {
return false ; //table doesn't exist
}
}
2022-09-17 17:44:21 -04:00
/**
* Queries {@link database::table_info()} to return the fields.
* @access public
* @return array Two dimensional array
* @depends table_info()
*/
2022-11-01 15:52:56 -06:00
public function fields () {
2012-07-22 05:37:30 +00:00
//public $db;
//public $type;
//public $table;
//public $name;
2023-05-09 11:14:41 -06:00
2022-09-18 02:13:33 -06:00
//initialize the array
2022-09-17 17:44:21 -04:00
$result = [];
2022-09-18 02:13:33 -06:00
2012-07-22 05:37:30 +00:00
//get the table info
$table_info = $this -> table_info ();
2012-07-22 06:35:00 +00:00
2012-07-22 05:37:30 +00:00
//set the list of fields
if ( $this -> type == "sqlite" ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $table_info )) {
foreach ( $table_info as $row ) {
$result [][ 'name' ] = $row [ 'name' ];
}
2012-07-22 05:37:30 +00:00
}
}
if ( $this -> type == "pgsql" ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $table_info )) {
foreach ( $table_info as $row ) {
$result [][ 'name' ] = $row [ 'column_name' ];
}
2012-07-22 05:37:30 +00:00
}
}
if ( $this -> type == "mysql" ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $table_info )) {
foreach ( $table_info as $row ) {
$result [][ 'name' ] = $row [ 'Field' ];
}
2012-07-22 05:37:30 +00:00
}
}
2012-07-23 23:31:02 +00:00
if ( $this -> type == "mssql" ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $table_info )) {
foreach ( $table_info as $row ) {
$result [][ 'name' ] = $row [ 'COLUMN_NAME' ];
}
2012-07-23 23:31:02 +00:00
}
}
2012-07-22 06:35:00 +00:00
2012-07-22 05:37:30 +00:00
//return the result array
return $result ;
}
2022-09-17 17:44:21 -04:00
/**
* Searches database using the following object properties:
* <ol>
* <li>table - sanitized name of the table {@see database::table}</li>
* <li>where - where clause {@see database::where}</li>
* <li>order_by - order_by clause {@see database::order_by}</li>
* <li>limit - limit clause {@see database::limit}</li>
* <li>offset - offset clause {@see database::offset}</li>
* </ol>
* @return boolean
* @depends connect()
*/
2012-06-04 14:58:40 +00:00
public function find () {
//connect;
//table;
//where;
//order_by;
//limit;
//offset;
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2022-09-17 17:44:21 -04:00
2012-06-04 14:58:40 +00:00
//get data from the database
2012-06-14 17:32:41 +00:00
$sql = "select * from " . $this -> table . " " ;
2012-06-04 14:58:40 +00:00
if ( $this -> where ) {
$i = 0 ;
2016-11-27 00:16:18 -07:00
if ( is_array ( $this -> where )) {
foreach ( $this -> where as $row ) {
2017-07-15 17:09:01 -06:00
//sanitize the name
2022-09-17 17:44:21 -04:00
$array [ 'name' ] = self :: sanitize ( $array [ 'name' ]);
2017-07-15 17:09:01 -06:00
//validate the operator
switch ( $row [ 'operator' ]) {
case "<" : break ;
case ">" : break ;
case "<=" : break ;
case ">=" : break ;
case "=" : break ;
case "<>" : break ;
case "!=" : break ;
default :
//invalid operator
return false ;
}
//build the sql
2016-11-27 00:16:18 -07:00
if ( $i == 0 ) {
2017-07-15 17:09:01 -06:00
//$sql .= 'where '.$row['name']." ".$row['operator']." '".$row['value']."' ";
$sql .= 'where ' . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'name' ] . " " ;
2016-11-27 00:16:18 -07:00
}
else {
2017-07-15 17:09:01 -06:00
//$sql .= "and ".$row['name']." ".$row['operator']." '".$row['value']."' ";
$sql .= "and " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'name' ] . " " ;
2016-11-27 00:16:18 -07:00
}
2017-07-15 17:09:01 -06:00
//add the name and value to the params array
$params [ $row [ 'name' ]] = $row [ 'value' ];
//increment $i
2016-11-27 00:16:18 -07:00
$i ++ ;
2012-06-04 14:58:40 +00:00
}
}
}
2017-07-15 17:09:01 -06:00
if ( is_array ( $this -> order_by )) {
2012-06-04 14:58:40 +00:00
$sql .= "order by " ;
$i = 1 ;
2016-11-27 00:16:18 -07:00
if ( is_array ( $this -> order_by )) {
foreach ( $this -> order_by as $row ) {
2017-07-15 17:09:01 -06:00
//sanitize the name
2022-09-17 17:44:21 -04:00
$row [ 'name' ] = self :: sanitize ( $row [ 'name' ]);
2017-07-15 17:09:01 -06:00
//sanitize the order
switch ( $row [ 'order' ]) {
case "asc" :
break ;
case "desc" :
break ;
default :
$row [ 'order' ] = '' ;
}
//build the sql
2016-11-27 00:16:18 -07:00
if ( count ( $this -> order_by ) == $i ) {
$sql .= $row [ 'name' ] . " " . $row [ 'order' ] . " " ;
}
else {
$sql .= $row [ 'name' ] . " " . $row [ 'order' ] . ", " ;
}
2017-07-15 17:09:01 -06:00
//increment $i
2016-11-27 00:16:18 -07:00
$i ++ ;
2012-06-04 14:58:40 +00:00
}
}
}
2017-07-15 17:09:01 -06:00
//limit
if ( isset ( $this -> limit ) && is_numeric ( $this -> limit )) {
$sql .= "limit " . $this -> limit . " " ;
}
//offset
if ( isset ( $this -> offset ) && is_numeric ( $this -> offset )) {
$sql .= "offset " . $this -> offset . " " ;
2012-06-04 14:58:40 +00:00
}
2017-07-15 17:09:01 -06:00
2012-06-04 14:58:40 +00:00
$prep_statement = $this -> db -> prepare ( $sql );
if ( $prep_statement ) {
2017-07-15 17:09:01 -06:00
$prep_statement -> execute ( $params );
$array = $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
unset ( $prep_statement );
return $array ;
2012-06-04 14:58:40 +00:00
}
else {
return false ;
}
}
2014-06-21 04:59:25 +00:00
// Use this function to execute complex queries
2019-05-27 19:56:32 -06:00
public function execute ( $sql , $parameters = null , $return_type = 'all' ) {
2016-11-19 11:57:36 -07:00
2014-06-21 05:22:45 +00:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2016-11-19 11:57:36 -07:00
2019-04-23 09:28:49 -06:00
//set the error mode
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//execute the query, and return the results
try {
$prep_statement = $this -> db -> prepare ( $sql );
if ( is_array ( $parameters )) {
$prep_statement -> execute ( $parameters );
}
else {
$prep_statement -> execute ();
}
$message [ "message" ] = "OK" ;
$message [ "code" ] = "200" ;
$message [ "sql" ] = $sql ;
if ( is_array ( $parameters )) {
$message [ "parameters" ] = $parameters ;
}
$this -> message = $message ;
2019-05-27 19:56:32 -06:00
//return the results
switch ( $return_type ) {
case 'all' :
return $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
case 'row' :
return $prep_statement -> fetch ( PDO :: FETCH_ASSOC );
case 'column' ;
return $prep_statement -> fetchColumn ();
default :
return $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
}
2014-06-21 04:59:25 +00:00
}
2019-04-23 09:28:49 -06:00
catch ( PDOException $e ) {
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
$message [ "error" ][ "message" ] = $e -> getMessage ();
2023-05-08 22:30:39 -06:00
$message [ "sql" ] = $sql ;
2019-04-23 09:28:49 -06:00
if ( is_array ( $parameters )) {
$message [ "parameters" ] = $parameters ;
}
$this -> message = $message ;
2014-06-21 04:59:25 +00:00
return false ;
}
}
2017-07-15 20:20:51 -06:00
public function add () {
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2022-09-18 02:13:33 -06:00
2017-07-15 23:06:22 -06:00
//sanitize the table name
2022-09-17 17:44:21 -04:00
//$this->table = self::sanitize($this->table); // no longer needed
2022-09-18 02:13:33 -06:00
2017-07-15 20:38:56 -06:00
//count the fields
$field_count = count ( $this -> fields );
2022-09-18 02:13:33 -06:00
2017-07-15 20:20:51 -06:00
//add data to the database
$sql = "insert into " . $this -> table ;
$sql .= " (" ;
$i = 1 ;
if ( is_array ( $this -> fields )) {
foreach ( $this -> fields as $name => $value ) {
2022-09-17 17:44:21 -04:00
$name = self :: sanitize ( $name );
2017-07-15 20:20:51 -06:00
if ( count ( $this -> fields ) == $i ) {
2017-07-15 20:38:56 -06:00
$sql .= $name . " \n " ;
2017-07-15 20:20:51 -06:00
}
else {
2017-07-15 20:38:56 -06:00
$sql .= $name . ", \n " ;
2017-07-15 20:20:51 -06:00
}
$i ++ ;
}
}
2017-07-15 20:38:56 -06:00
$sql .= ") \n " ;
$sql .= "values \n " ;
$sql .= "( \n " ;
2017-07-15 20:20:51 -06:00
$i = 1 ;
if ( is_array ( $this -> fields )) {
foreach ( $this -> fields as $name => $value ) {
2022-09-17 17:44:21 -04:00
$name = self :: sanitize ( $name );
2017-07-15 20:38:56 -06:00
if ( $field_count == $i ) {
2023-05-09 11:14:41 -06:00
if ( strlen ( $value ) > 0 ) {
2017-07-15 20:20:51 -06:00
//$sql .= "'".$value."' ";
2017-07-15 20:38:56 -06:00
$sql .= ":" . $name . " \n " ;
2019-11-20 10:14:01 -07:00
$params [ $name ] = trim ( $value );
2017-07-15 20:20:51 -06:00
}
else {
2017-07-15 20:38:56 -06:00
$sql .= "null \n " ;
2017-07-15 20:20:51 -06:00
}
}
else {
2023-05-09 11:14:41 -06:00
if ( strlen ( $value ) > 0 ) {
2017-07-15 20:20:51 -06:00
//$sql .= "'".$value."', ";
2017-07-15 20:38:56 -06:00
$sql .= ":" . $name . ", \n " ;
2019-11-20 10:14:01 -07:00
$params [ $name ] = trim ( $value );
2017-07-15 20:20:51 -06:00
}
else {
2017-07-15 20:38:56 -06:00
$sql .= "null, \n " ;
2017-07-15 20:20:51 -06:00
}
}
$i ++ ;
}
}
2017-07-15 20:38:56 -06:00
$sql .= ") \n " ;
2017-07-15 20:20:51 -06:00
//execute the query, show exceptions
2022-08-18 17:53:33 -06:00
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//reduce prepared statement latency
if ( defined ( 'PDO::PGSQL_ATTR_DISABLE_PREPARES' )) {
2022-08-24 16:09:33 -04:00
$this -> db -> setAttribute ( PDO :: PGSQL_ATTR_DISABLE_PREPARES , true );
2022-08-18 17:53:33 -06:00
}
//prepare the sql and parameters and then execute the query
2017-07-15 20:20:51 -06:00
try {
//$this->sql = $sql;
//$this->db->exec($sql);
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
}
catch ( PDOException $e ) {
echo "<b>Error:</b><br /> \n " ;
echo "<table> \n " ;
echo "<tr> \n " ;
echo "<td> \n " ;
echo $e -> getMessage ();
echo "</td> \n " ;
echo "</tr> \n " ;
echo "</table> \n " ;
}
unset ( $sql , $prep_statement , $this -> fields );
}
2017-07-15 22:26:01 -06:00
public function update () {
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2022-09-18 02:13:33 -06:00
2017-07-15 23:06:22 -06:00
//sanitize the table name
2022-09-17 17:44:21 -04:00
//$this->table = self::sanitize($this->table); // no longer needed
2022-09-18 02:13:33 -06:00
2017-07-15 22:26:01 -06:00
//udate the database
$sql = "update " . $this -> table . " set " ;
$i = 1 ;
if ( is_array ( $this -> fields )) {
foreach ( $this -> fields as $name => $value ) {
2022-09-17 17:44:21 -04:00
$name = self :: sanitize ( $name );
2017-07-15 22:26:01 -06:00
if ( count ( $this -> fields ) == $i ) {
2023-05-09 11:14:41 -06:00
if ( strlen ( $name ) > 0 && $value == null ) {
2017-07-15 22:26:01 -06:00
$sql .= $name . " = null " ;
}
else {
2017-07-15 23:06:22 -06:00
//$sql .= $name." = '".$value."' ";
$sql .= $name . " = :" . $name . " " ;
2019-11-20 10:14:01 -07:00
$params [ $name ] = trim ( $value );
2017-07-15 22:26:01 -06:00
}
}
else {
2023-05-09 11:14:41 -06:00
if ( strlen ( $name ) > 0 && $value == null ) {
2017-07-15 22:26:01 -06:00
$sql .= $name . " = null, " ;
}
else {
2017-07-15 23:06:22 -06:00
//$sql .= $name." = '".$value."', ";
$sql .= $name . " = :" . $name . ", " ;
2019-11-20 10:14:01 -07:00
$params [ $name ] = trim ( $value );
2017-07-15 22:26:01 -06:00
}
}
$i ++ ;
}
}
$i = 0 ;
if ( is_array ( $this -> where )) {
foreach ( $this -> where as $row ) {
2017-07-15 23:06:22 -06:00
//sanitize the name
2022-09-17 17:44:21 -04:00
$row [ 'name' ] = self :: sanitize ( $row [ 'name' ]);
2017-07-15 23:06:22 -06:00
//validate the operator
switch ( $row [ 'operator' ]) {
case "<" : break ;
case ">" : break ;
case "<=" : break ;
case ">=" : break ;
case "=" : break ;
case "<>" : break ;
case "!=" : break ;
default :
//invalid operator
return false ;
}
//build the sql
2017-07-15 22:26:01 -06:00
if ( $i == 0 ) {
2017-07-15 23:06:22 -06:00
//$sql .= $row['name']." ".$row['operator']." '".$row['value']."' ";
$sql .= "where " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'name' ] . " " ;
2017-07-15 22:26:01 -06:00
}
else {
2017-07-15 23:06:22 -06:00
//$sql .= $row['name']." ".$row['operator']." '".$row['value']."' ";
$sql .= "and " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'name' ] . " " ;
2017-07-15 22:26:01 -06:00
}
2017-07-15 23:06:22 -06:00
//add the name and value to the params array
$params [ $row [ 'name' ]] = $row [ 'value' ];
//increment $i
2017-07-15 22:26:01 -06:00
$i ++ ;
}
}
2017-07-15 23:06:22 -06:00
//$this->db->exec(check_sql($sql));
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
unset ( $prep_statement );
2017-07-15 22:26:01 -06:00
unset ( $this -> fields );
unset ( $this -> where );
unset ( $sql );
}
2022-09-17 17:44:21 -04:00
public function delete ( array $array ) {
2022-09-18 02:13:33 -06:00
//set the default value
2022-09-17 17:44:21 -04:00
$retval = true ;
2022-09-18 02:13:33 -06:00
2020-07-09 02:57:28 -06:00
//return the array
2022-09-17 17:44:21 -04:00
if ( ! is_array ( $array )) { return false ; }
2019-11-22 23:34:03 -07:00
2012-06-04 14:58:40 +00:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2016-11-19 11:49:38 -07:00
2016-11-19 14:10:06 -07:00
//set the message id
$m = 0 ;
//debug sql
2022-09-19 09:30:20 -06:00
//$this->debug["sql"] = true;
2016-11-19 14:10:06 -07:00
2020-07-09 02:57:28 -06:00
//set the message id
$m = 0 ;
//loop through the array
$checked = false ;
2022-09-17 17:44:21 -04:00
$x = 0 ;
foreach ( $array as $parent_name => $tables ) {
if ( is_array ( $tables )) {
foreach ( $tables as $id => $row ) {
//prepare the variables
$parent_name = self :: sanitize ( $parent_name );
$parent_key_name = self :: singular ( $parent_name ) . "_uuid" ;
//build the delete array
if ( $row [ 'checked' ] == 'true' ) {
//set checked to true
$checked = true ;
//delete the child data
if ( isset ( $row [ $parent_key_name ])) {
$new_array [ $parent_name ][ $x ][ $parent_key_name ] = $row [ $parent_key_name ];
2020-07-09 02:57:28 -06:00
}
2022-09-17 17:44:21 -04:00
//remove the row from the main array
unset ( $array [ $parent_name ][ $x ]);
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//loop through the fields
foreach ( $row as $field_name => $field_value ) {
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//find the child tables
$y = 0 ;
if ( is_array ( $field_value )) {
//prepare the variables
$child_name = self :: sanitize ( $field_name );
$child_key_name = self :: singular ( $child_name ) . "_uuid" ;
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//loop through the child rows
foreach ( $field_value as $sub_row ) {
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//build the delete array
if ( $row [ 'checked' ] == 'true' ) {
//set checked to true
$checked = true ;
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//delete the child data
$new_array [ $child_name ][][ $child_key_name ] = $sub_row [ $child_key_name ];
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//remove the row from the main array
unset ( $array [ $parent_name ][ $x ][ $child_name ][ $y ]);
2020-07-09 02:57:28 -06:00
}
2022-09-17 17:44:21 -04:00
//increment the value
$y ++ ;
2020-07-09 02:57:28 -06:00
}
}
2022-09-17 17:44:21 -04:00
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//increment the value
$x ++ ;
2020-07-09 02:57:28 -06:00
}
}
}
//if not checked then copy the array to delete array
if ( ! $checked ) {
$new_array = $array ;
}
2019-05-05 19:30:05 -06:00
//get the current data
2022-09-17 17:44:21 -04:00
if ( count ( $new_array ) > 0 ) {
2020-07-09 02:57:28 -06:00
//build an array of tables, fields, and values
foreach ( $new_array as $table_name => $rows ) {
2020-02-08 15:53:32 -07:00
foreach ( $rows as $row ) {
2020-07-09 02:57:28 -06:00
foreach ( $row as $field_name => $field_value ) {
$keys [ $table_name ][ $field_name ][] = $field_value ;
}
}
}
//use the array to get a copy of the parent data before deleting it
foreach ( $new_array as $table_name => $rows ) {
foreach ( $rows as $row ) {
2022-09-17 17:44:21 -04:00
$table_name = self :: sanitize ( $table_name );
$sql = "select * from " . self :: TABLE_PREFIX . $table_name . " " ;
2020-07-09 02:57:28 -06:00
$i = 0 ;
2020-02-08 15:53:32 -07:00
foreach ( $row as $field_name => $field_value ) {
if ( $i == 0 ) { $sql .= "where " ; } else { $sql .= "and " ; }
2020-07-09 02:57:28 -06:00
$sql .= $field_name . " in ( " ;
$i = 0 ;
foreach ( $keys [ $table_name ][ $field_name ] as $field_value ) {
2022-09-17 17:44:21 -04:00
$field_name = self :: sanitize ( $field_name );
2020-07-09 02:57:28 -06:00
if ( $i > 0 ) { $sql .= " ," ; }
$sql .= " :" . $field_name . "_" . $i . " " ;
$i ++ ;
}
$sql .= ") " ;
$i = 0 ;
foreach ( $keys [ $table_name ][ $field_name ] as $field_value ) {
$parameters [ $field_name . '_' . $i ] = $field_value ;
$i ++ ;
2020-02-08 15:53:32 -07:00
}
2019-11-22 23:34:03 -07:00
}
2020-07-09 02:57:28 -06:00
}
2023-05-09 11:14:41 -06:00
if ( strlen ( $field_value ) > 0 ) {
2020-07-09 02:57:28 -06:00
$results = $this -> execute ( $sql , $parameters , 'all' );
2020-02-08 15:53:32 -07:00
unset ( $parameters );
2020-07-09 02:57:28 -06:00
if ( is_array ( $results )) {
$old_array [ $table_name ] = $results ;
}
2019-11-22 23:34:03 -07:00
}
2016-11-23 13:39:20 -07:00
}
2016-11-27 00:16:18 -07:00
2020-07-17 21:43:34 -06:00
//get relations array
2022-09-17 17:44:21 -04:00
$relations = self :: get_relations ( $parent_name );
2020-07-17 21:43:34 -06:00
2020-07-09 02:57:28 -06:00
//add child data to the old array
foreach ( $old_array as $parent_name => $rows ) {
//get relations array
2022-09-17 17:44:21 -04:00
$relations = self :: get_relations ( $parent_name );
2020-07-09 02:57:28 -06:00
//loop through the rows
$x = 0 ;
foreach ( $rows as $row ) {
if ( is_array ( $relations )) {
foreach ( $relations as $relation ) {
2020-07-17 21:43:34 -06:00
if ( $relation [ 'key' ][ 'action' ][ 'delete' ] == 'cascade' ) {
//set the child table
$child_table = $relation [ 'table' ];
2020-07-09 02:57:28 -06:00
2020-07-17 21:43:34 -06:00
//remove the v_ prefix
2022-09-17 17:44:21 -04:00
if ( substr ( $child_table , 0 , strlen ( self :: TABLE_PREFIX )) == self :: TABLE_PREFIX ) {
$child_table = substr ( $child_table , strlen ( self :: TABLE_PREFIX ));
2020-07-17 21:43:34 -06:00
}
2020-07-09 02:57:28 -06:00
2020-07-17 21:43:34 -06:00
//get the child data
2022-09-17 17:44:21 -04:00
$sql = "select * from " . self :: TABLE_PREFIX . $child_table . " " ;
2020-07-17 21:43:34 -06:00
$sql .= "where " . $relation [ 'field' ] . " = :" . $relation [ 'field' ];
$parameters [ $relation [ 'field' ]] = $row [ $relation [ 'field' ]];
$results = $this -> execute ( $sql , $parameters , 'all' );
unset ( $parameters );
if ( is_array ( $results ) && $parent_name !== $child_table ) {
$old_array [ $parent_name ][ $x ][ $child_table ] = $results ;
}
//delete the child data
2023-05-05 13:46:37 -03:00
if ( isset ( $row [ $relation [ 'field' ]]) && ! empty ( $row [ $relation [ 'field' ]])) {
2022-09-17 17:44:21 -04:00
$sql = "delete from " . self :: TABLE_PREFIX . $child_table . " " ;
2020-07-17 21:43:34 -06:00
$sql .= "where " . $relation [ 'field' ] . " = :" . $relation [ 'field' ];
$parameters [ $relation [ 'field' ]] = $row [ $relation [ 'field' ]];
// $this->execute($sql, $parameters);
}
unset ( $parameters );
}
2020-07-09 02:57:28 -06:00
}
}
$x ++ ;
}
}
}
2019-11-22 23:34:03 -07:00
2019-05-05 19:30:05 -06:00
//start the atomic transaction
$this -> db -> beginTransaction ();
//delete the current data
2022-09-17 17:44:21 -04:00
foreach ( $new_array as $table_name => $rows ) {
//echo "table: ".$table_name."\n";
foreach ( $rows as $row ) {
if ( permission_exists ( self :: singular ( $table_name ) . '_delete' )) {
$sql = "delete from " . self :: TABLE_PREFIX . $table_name . " " ;
$i = 0 ;
foreach ( $row as $field_name => $field_value ) {
//echo "field: ".$field_name." = ".$field_value."\n";
if ( $i == 0 ) { $sql .= "where " ; } else { $sql .= "and " ; }
$sql .= $field_name . " = :" . $field_name . " " ;
$parameters [ $field_name ] = $field_value ;
$i ++ ;
}
try {
$this -> execute ( $sql , $parameters );
$message [ "message" ] = "OK" ;
$message [ "code" ] = "200" ;
$message [ "uuid" ] = $id ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = "OK" ;
$message [ "details" ][ $m ][ "code" ] = "200" ;
//$message["details"][$m]["uuid"] = $parent_key_value;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
2022-09-17 17:44:21 -04:00
$this -> message = $message ;
$m ++ ;
unset ( $sql );
unset ( $statement );
}
catch ( PDOException $e ) {
$retval = false ;
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = $e -> getMessage ();
$message [ "details" ][ $m ][ "code" ] = "400" ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
2022-09-17 17:44:21 -04:00
$this -> message = $message ;
$m ++ ;
}
unset ( $parameters );
} //if permission
} //foreach rows
} //foreach $array
2016-11-19 14:10:06 -07:00
//commit the atomic transaction
2019-05-05 19:30:05 -06:00
$this -> db -> commit ();
2016-11-19 14:10:06 -07:00
2018-02-12 08:40:23 -07:00
//set the action if not set
2019-03-23 17:27:58 -06:00
$transaction_type = 'delete' ;
2018-02-12 08:40:23 -07:00
2017-06-11 08:48:18 -06:00
//get the UUIDs
$user_uuid = $_SESSION [ 'user_uuid' ];
2016-11-19 14:10:06 -07:00
//log the transaction results
if ( file_exists ( $_SERVER [ "PROJECT_ROOT" ] . "/app/database_transactions/app_config.php" )) {
2022-09-17 17:44:21 -04:00
$sql = "insert into " . self :: TABLE_PREFIX . "database_transactions " ;
2016-11-19 14:10:06 -07:00
$sql .= "(" ;
$sql .= "database_transaction_uuid, " ;
2019-12-16 12:39:54 -07:00
if ( isset ( $this -> domain_uuid ) && is_uuid ( $this -> domain_uuid )) {
$sql .= "domain_uuid, " ;
}
2019-08-20 12:40:51 -06:00
if ( isset ( $user_uuid ) && is_uuid ( $user_uuid )) {
2017-06-11 08:48:18 -06:00
$sql .= "user_uuid, " ;
}
2019-08-20 12:40:51 -06:00
if ( isset ( $this -> app_uuid ) && is_uuid ( $this -> app_uuid )) {
2016-11-19 14:10:06 -07:00
$sql .= "app_uuid, " ;
}
2023-05-05 13:46:37 -03:00
if ( isset ( $this -> app_name ) && ! empty ( $this -> app_name )) {
2019-03-23 17:27:58 -06:00
$sql .= "app_name, " ;
}
2016-11-19 14:10:06 -07:00
$sql .= "transaction_code, " ;
$sql .= "transaction_address, " ;
2018-02-12 08:40:23 -07:00
$sql .= "transaction_type, " ;
2016-11-19 14:10:06 -07:00
$sql .= "transaction_date, " ;
$sql .= "transaction_old, " ;
$sql .= "transaction_new, " ;
$sql .= "transaction_result " ;
$sql .= ")" ;
$sql .= "values " ;
$sql .= "(" ;
$sql .= "'" . uuid () . "', " ;
2019-12-16 12:39:54 -07:00
if ( isset ( $this -> domain_uuid ) && is_uuid ( $this -> domain_uuid )) {
$sql .= "'" . $this -> domain_uuid . "', " ;
}
2019-08-20 12:40:51 -06:00
if ( isset ( $user_uuid ) && is_uuid ( $user_uuid )) {
2019-03-23 17:27:58 -06:00
$sql .= ":user_uuid, " ;
2017-06-11 08:48:18 -06:00
}
2019-08-20 12:40:51 -06:00
if ( isset ( $this -> app_uuid ) && is_uuid ( $this -> app_uuid )) {
2019-03-23 17:27:58 -06:00
$sql .= ":app_uuid, " ;
}
2023-05-05 13:46:37 -03:00
if ( isset ( $this -> app_name ) && ! empty ( $this -> app_name )) {
2019-05-05 19:30:05 -06:00
$sql .= ":app_name, " ;
2016-11-19 14:10:06 -07:00
}
$sql .= "'" . $message [ "code" ] . "', " ;
2019-03-23 17:27:58 -06:00
$sql .= ":remote_address, " ;
2018-02-12 08:40:23 -07:00
$sql .= "'" . $transaction_type . "', " ;
2016-11-19 14:10:06 -07:00
$sql .= "now(), " ;
2018-02-12 08:40:23 -07:00
if ( is_array ( $old_array )) {
2019-03-23 17:27:58 -06:00
$sql .= ":transaction_old, " ;
2018-02-12 08:40:23 -07:00
}
else {
$sql .= "null, " ;
}
if ( is_array ( $new_array )) {
2019-03-23 17:27:58 -06:00
$sql .= ":transaction_new, " ;
2018-02-12 08:40:23 -07:00
}
else {
$sql .= "null, " ;
}
2019-03-23 17:27:58 -06:00
$sql .= ":transaction_result " ;
2016-11-19 14:10:06 -07:00
$sql .= ")" ;
2019-03-23 17:27:58 -06:00
$statement = $this -> db -> prepare ( $sql );
2019-08-20 12:40:51 -06:00
if ( isset ( $user_uuid ) && is_uuid ( $user_uuid )) {
2019-03-23 17:27:58 -06:00
$statement -> bindParam ( ':user_uuid' , $user_uuid );
}
2019-08-20 12:40:51 -06:00
if ( isset ( $this -> app_uuid ) && is_uuid ( $this -> app_uuid )) {
2019-03-23 17:27:58 -06:00
$statement -> bindParam ( ':app_uuid' , $this -> app_uuid );
}
2023-05-05 13:46:37 -03:00
if ( isset ( $this -> app_name ) && ! empty ( $this -> app_name )) {
2019-03-23 17:27:58 -06:00
$statement -> bindParam ( ':app_name' , $this -> app_name );
}
$statement -> bindParam ( ':remote_address' , $_SERVER [ 'REMOTE_ADDR' ]);
2019-03-25 09:32:00 -06:00
if ( is_array ( $old_array )) {
2022-01-24 15:33:34 -07:00
$old_json = json_encode ( $old_array , JSON_PRETTY_PRINT );
$statement -> bindParam ( ':transaction_old' , $old_json );
2019-03-25 09:32:00 -06:00
}
if ( is_array ( $new_array )) {
2022-01-24 15:33:34 -07:00
$new_json = json_encode ( $new_array , JSON_PRETTY_PRINT );
$statement -> bindParam ( ':transaction_new' , $new_json );
2019-03-25 09:32:00 -06:00
}
2022-01-24 15:33:34 -07:00
$result = json_encode ( $this -> message , JSON_PRETTY_PRINT );
$statement -> bindParam ( ':transaction_result' , $result );
2019-03-23 17:27:58 -06:00
$statement -> execute ();
2016-11-19 14:10:06 -07:00
unset ( $sql );
}
2022-09-17 17:44:21 -04:00
return $retval ;
2016-11-23 13:39:20 -07:00
} //delete
2012-06-04 14:58:40 +00:00
2022-09-17 17:44:21 -04:00
/**
* Counts the number of rows.
* @return int Represents the number of counted rows or -1 if failed.
*/
2022-11-01 15:52:56 -06:00
public function count () {
2017-07-15 17:09:01 -06:00
2012-06-04 14:58:40 +00:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2022-09-18 02:13:33 -06:00
2023-05-08 22:30:39 -06:00
//return if the table name is not set
if ( empty ( $this -> table )) {
return ;
}
2017-07-15 17:09:01 -06:00
//sanitize the table name
2022-09-17 17:44:21 -04:00
//$this->table = self::sanitize($this->table); // no longer needed
2017-07-15 17:09:01 -06:00
2012-06-04 14:58:40 +00:00
//get the number of rows
2012-06-14 17:32:41 +00:00
$sql = "select count(*) as num_rows from " . $this -> table . " " ;
2023-05-08 22:30:39 -06:00
$i = 0 ;
if ( is_array ( $this -> where )) {
foreach ( $this -> where as $row ) {
//sanitize the name
$row [ 'name' ] = self :: sanitize ( $row [ 'name' ]);
2017-07-15 17:09:01 -06:00
2023-05-08 22:30:39 -06:00
//validate the operator
switch ( $row [ 'operator' ]) {
case "<" : break ;
case ">" : break ;
case "<=" : break ;
case ">=" : break ;
case "=" : break ;
case "<>" : break ;
case "!=" : break ;
default :
//invalid operator
return - 1 ;
}
2017-07-15 17:09:01 -06:00
2023-05-08 22:30:39 -06:00
//build the sql
if ( $i == 0 ) {
$sql .= "where " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'name' ] . " " ;
}
else {
$sql .= "and " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'name' ] . " " ;
}
2017-07-15 17:09:01 -06:00
2023-05-08 22:30:39 -06:00
//add the name and value to the params array
$params [ $row [ 'name' ]] = $row [ 'value' ];
2017-07-15 17:09:01 -06:00
2023-05-08 22:30:39 -06:00
//increment $i
$i ++ ;
2012-06-04 14:58:40 +00:00
}
}
2023-05-08 22:30:39 -06:00
2022-09-17 17:44:21 -04:00
//unset($this->where); //should not be objects resposibility
2017-07-15 17:09:01 -06:00
$prep_statement = $this -> db -> prepare ( $sql );
2012-06-04 14:58:40 +00:00
if ( $prep_statement ) {
2023-05-08 22:30:39 -06:00
if ( ! isset ( $params )) { $params = null ; }
2017-07-15 17:09:01 -06:00
$prep_statement -> execute ( $params );
2012-06-04 14:58:40 +00:00
$row = $prep_statement -> fetch ( PDO :: FETCH_ASSOC );
if ( $row [ 'num_rows' ] > 0 ) {
2015-03-22 07:54:35 +00:00
return $row [ 'num_rows' ];
2012-06-04 14:58:40 +00:00
}
else {
2015-03-22 07:54:35 +00:00
return 0 ;
2012-06-04 14:58:40 +00:00
}
}
unset ( $prep_statement );
2017-07-15 17:09:01 -06:00
2016-10-16 10:45:04 -06:00
} //count
2022-09-17 17:44:21 -04:00
/**
* Performs a select query on database using the <b>$sql</b> statement supplied.
* @param type $sql Valid SQL statement.
* @param type $parameters Value can be <i>array</i>, empty string, or <i>null</i>.
* @param type $return_type Values can be set to <i>all</i>, <i>row</i>, or <i>column</i>.
* @return mixed Returned values can be array, string, boolean, int, or false. This is dependent on <i>$return_type</i>.
*/
2019-05-27 19:56:32 -06:00
public function select ( $sql , $parameters = '' , $return_type = 'all' ) {
2019-04-23 09:28:49 -06:00
2016-11-02 12:31:59 -06:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
2019-04-23 09:28:49 -06:00
//set the error mode
2022-08-18 17:37:43 -06:00
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//reduce prepared statement latency
2022-08-18 17:39:51 -06:00
if ( defined ( 'PDO::PGSQL_ATTR_DISABLE_PREPARES' )) {
2022-08-24 16:09:33 -04:00
$this -> db -> setAttribute ( PDO :: PGSQL_ATTR_DISABLE_PREPARES , true );
2022-08-18 17:37:43 -06:00
}
2019-04-23 09:28:49 -06:00
2022-08-18 17:53:33 -06:00
//execute the query and return the results
2016-11-02 12:31:59 -06:00
try {
2019-04-23 09:28:49 -06:00
$prep_statement = $this -> db -> prepare ( $sql );
if ( is_array ( $parameters )) {
$prep_statement -> execute ( $parameters );
}
else {
$prep_statement -> execute ();
}
2016-11-02 12:31:59 -06:00
$message [ "message" ] = "OK" ;
$message [ "code" ] = "200" ;
2019-04-23 09:28:49 -06:00
$message [ "sql" ] = $sql ;
if ( is_array ( $parameters )) {
$message [ "parameters" ] = $parameters ;
2016-11-02 12:31:59 -06:00
}
$this -> message = $message ;
2019-05-27 19:56:32 -06:00
//return the results
switch ( $return_type ) {
case 'all' :
return $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
case 'row' :
return $prep_statement -> fetch ( PDO :: FETCH_ASSOC );
2019-07-01 13:26:26 -06:00
case 'column' :
2019-05-27 19:56:32 -06:00
return $prep_statement -> fetchColumn ();
default :
return $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
}
2016-11-02 12:31:59 -06:00
}
catch ( PDOException $e ) {
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
2019-04-23 09:28:49 -06:00
$message [ "error" ][ "message" ] = $e -> getMessage ();
2023-05-08 22:30:39 -06:00
$message [ "sql" ] = $sql ;
2019-04-23 09:28:49 -06:00
if ( is_array ( $parameters )) {
$message [ "parameters" ] = $parameters ;
2016-11-02 12:31:59 -06:00
}
$this -> message = $message ;
2019-04-23 09:28:49 -06:00
return false ;
2016-11-02 12:31:59 -06:00
}
} //select
2022-09-17 17:44:21 -04:00
/**
* Sets the object <i>$result</i> to sql array
* @param array $array Array containing the table name, uuid, SQL and where clause.
* @return database Returns the database object or null.
*/
2022-11-01 15:52:56 -06:00
public function find_new ( array $array ) {
2016-10-16 10:45:04 -06:00
//connect to the database if needed
2022-09-17 17:44:21 -04:00
if ( ! $this -> db ) {
$this -> connect ();
}
2022-09-18 02:13:33 -06:00
2016-10-16 10:45:04 -06:00
//set the name
2022-09-17 17:44:21 -04:00
if ( isset ( $array [ 'name' ])) {
$this -> name = $array [ 'name' ];
}
2022-09-18 02:13:33 -06:00
2016-10-16 10:45:04 -06:00
//set the uuid
2022-09-17 17:44:21 -04:00
if ( isset ( $array [ 'uuid' ])) {
$this -> uuid = $array [ 'uuid' ];
}
2022-09-18 02:13:33 -06:00
2016-10-16 10:45:04 -06:00
//build the query
2022-09-17 17:44:21 -04:00
$sql = "SELECT * FROM " . self :: TABLE_PREFIX . $this -> name . " " ;
if ( isset ( $this -> uuid )) {
//get the specific uuid
$sql .= "WHERE " . self :: singular ( $this -> name ) . "_uuid = '" . $this -> uuid . "' " ;
} else {
//where
$i = 0 ;
if ( isset ( $array [ 'where' ])) {
foreach ( $array [ 'where' ] as $row ) {
if ( isset ( $row [ 'operator' ])) {
//validate the operator
switch ( $row [ 'operator' ]) {
case "<" : break ;
case ">" : break ;
case "<=" : break ;
case ">=" : break ;
case "=" : break ;
case "<>" : break ;
case "!=" : break ;
default :
//invalid operator
return null ;
}
2017-07-15 17:09:01 -06:00
2022-09-17 17:44:21 -04:00
//build the sql
if ( $i == 0 ) {
$sql .= "WHERE " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'value' ] . " " ;
} else {
$sql .= "AND " . $row [ 'name' ] . " " . $row [ 'operator' ] . " :" . $row [ 'value' ] . " " ;
2016-10-16 10:45:04 -06:00
}
}
2022-09-17 17:44:21 -04:00
//add the name and value to the params array
$params [ $row [ 'name' ]] = $row [ 'value' ];
//increment $i
$i ++ ;
2016-10-16 10:45:04 -06:00
}
}
2022-09-17 17:44:21 -04:00
//order by
if ( isset ( $array [ 'order_by' ])) {
$array [ 'order_by' ] = self :: sanitize ( $array [ 'order_by' ]);
$sql .= "ORDER BY " . $array [ 'order_by' ] . " " ;
2016-10-16 10:45:04 -06:00
}
2022-09-17 17:44:21 -04:00
//limit
if ( isset ( $array [ 'limit' ]) && is_numeric ( $array [ 'limit' ])) {
$sql .= "LIMIT " . $array [ 'limit' ] . " " ;
2016-10-16 10:45:04 -06:00
}
2022-09-17 17:44:21 -04:00
//offset
if ( isset ( $array [ 'offset' ]) && is_numeric ( $array [ 'offset' ])) {
$sql .= "OFFSET " . $array [ 'offset' ] . " " ;
}
}
//execute the query, and return the results
try {
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
$message [ "message" ] = "OK" ;
$message [ "code" ] = "200" ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = "OK" ;
$message [ "details" ][ $m ][ "code" ] = "200" ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
2022-09-17 17:44:21 -04:00
$this -> message = $message ;
$this -> result = $prep_statement -> fetchAll ( PDO :: FETCH_NAMED );
unset ( $prep_statement );
$m ++ ;
} catch ( PDOException $e ) {
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = $e -> getMessage ();
$message [ "details" ][ $m ][ "code" ] = "400" ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
2022-09-17 17:44:21 -04:00
$this -> message = $message ;
$this -> result = '' ;
$m ++ ;
}
return $this ;
2016-10-16 10:45:04 -06:00
}
2022-09-17 17:44:21 -04:00
/**
* Stores the passed UUID in the object
* @param string $uuid A valid UUID must be passed
* @return database Returns this object
*/
2022-11-01 15:52:56 -06:00
public function uuid ( string $uuid ) {
2016-10-16 10:45:04 -06:00
$this -> uuid = $uuid ;
return $this ;
}
2022-09-17 17:44:21 -04:00
/**
* Copies records and appends <i>suffix</i> to the column <i>description</i> data
* @param array $array Three dimensional Array. The first dimension is the table name without the prefix 'v_'. Second dimension in the row value as int. Third dimension is the column name.
* @return bool Returns <b>true</b> on success and <b>false</b> on failure.
*/
2022-11-01 15:52:56 -06:00
public function copy ( array $array , $suffix = '(Copy)' ) {
2022-09-17 17:44:21 -04:00
//set default return value
2022-09-18 04:47:17 -06:00
$retval = false ;
2020-07-09 02:57:28 -06:00
//return the array
2022-09-17 17:44:21 -04:00
if ( ! is_array ( $array )) { return $retval ; }
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//initialize array
2022-09-18 04:47:17 -06:00
$copy_array = [];
2020-07-09 02:57:28 -06:00
//set the message id
$m = 0 ;
//loop through the array
2022-09-17 17:44:21 -04:00
$x = 0 ;
foreach ( $array as $parent_name => $tables ) {
if ( is_array ( $tables )) {
foreach ( $tables as $id => $row ) {
//prepare the variables
$parent_name = self :: sanitize ( $parent_name );
$parent_key_name = self :: singular ( $parent_name ) . "_uuid" ;
//build the copy array
if ( $row [ 'checked' ] == 'true' ) {
//set checked to true
$checked = true ;
//copy the child data
if ( is_uuid ( $row [ $parent_key_name ])) {
$copy_array [ $parent_name ][ $x ][ $parent_key_name ] = $row [ $parent_key_name ];
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//remove the row from the main array
unset ( $array [ $parent_name ][ $x ]);
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//loop through the fields
foreach ( $row as $field_name => $field_value ) {
//find the child tables
if ( is_array ( $field_value )) {
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//prepare the variables
$child_name = self :: sanitize ( $field_name );
$child_key_name = self :: singular ( $child_name ) . "_uuid" ;
2020-07-24 10:15:30 -06:00
2022-09-17 17:44:21 -04:00
//loop through the child rows
$y = 0 ;
foreach ( $field_value as $sub_row ) {
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//delete the child data
$copy_array [ $child_name ][][ $child_key_name ] = $sub_row [ $child_key_name ];
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//remove the row from the main array
unset ( $array [ $parent_name ][ $x ][ $child_name ][ $y ]);
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//increment the value
$y ++ ;
2020-07-09 02:57:28 -06:00
}
}
}
2022-09-17 17:44:21 -04:00
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//increment the value
$x ++ ;
2020-07-09 02:57:28 -06:00
}
}
}
//get the current data
2022-09-17 17:44:21 -04:00
if ( count ( $copy_array ) > 0 ) {
2020-07-24 10:15:30 -06:00
2020-07-09 02:57:28 -06:00
//build an array of tables, fields, and values
foreach ( $copy_array as $table_name => $rows ) {
foreach ( $rows as $row ) {
foreach ( $row as $field_name => $field_value ) {
$keys [ $table_name ][ $field_name ][] = $field_value ;
}
}
}
//unset the array
unset ( $array );
//use the array to get a copy of the paent data before deleting it
foreach ( $copy_array as $table_name => $rows ) {
foreach ( $rows as $row ) {
2022-09-17 17:44:21 -04:00
$table_name = self :: sanitize ( $table_name );
$sql = "select * from " . self :: TABLE_PREFIX . $table_name . " " ;
2020-07-09 02:57:28 -06:00
$i = 0 ;
foreach ( $row as $field_name => $field_value ) {
if ( $i == 0 ) { $sql .= "where " ; } else { $sql .= "and " ; }
$sql .= $field_name . " in ( " ;
$i = 0 ;
foreach ( $keys [ $table_name ][ $field_name ] as $field_value ) {
2022-09-17 17:44:21 -04:00
$field_name = self :: sanitize ( $field_name );
2020-07-09 02:57:28 -06:00
if ( $i > 0 ) { $sql .= " ," ; }
$sql .= " :" . $field_name . "_" . $i . " " ;
$i ++ ;
}
$sql .= ") " ;
$i = 0 ;
foreach ( $keys [ $table_name ][ $field_name ] as $field_value ) {
$parameters [ $field_name . '_' . $i ] = $field_value ;
$i ++ ;
}
}
}
$results = $this -> execute ( $sql , $parameters , 'all' );
unset ( $parameters );
if ( is_array ( $results )) {
$array [ $table_name ] = $results ;
}
}
//add child data to the old array
foreach ( $copy_array as $parent_name => $rows ) {
//get relations array
2022-09-17 17:44:21 -04:00
$relations = self :: get_relations ( $parent_name );
2020-07-09 02:57:28 -06:00
//loop through the rows
$x = 0 ;
foreach ( $rows as $row ) {
if ( is_array ( $relations )) {
foreach ( $relations as $relation ) {
//set the child table
$child_table = $relation [ 'table' ];
//remove the v_ prefix
2022-09-17 17:44:21 -04:00
if ( substr ( $child_table , 0 , strlen ( self :: TABLE_PREFIX )) == self :: TABLE_PREFIX ) {
$child_table = substr ( $child_table , strlen ( self :: TABLE_PREFIX ));
2020-07-09 02:57:28 -06:00
}
//get the child data
2022-09-17 17:44:21 -04:00
$sql = "select * from " . self :: TABLE_PREFIX . $child_table . " " ;
2020-07-09 02:57:28 -06:00
$sql .= "where " . $relation [ 'field' ] . " = :" . $relation [ 'field' ];
$parameters [ $relation [ 'field' ]] = $row [ $relation [ 'field' ]];
$results = $this -> execute ( $sql , $parameters , 'all' );
unset ( $parameters );
if ( is_array ( $results )) {
$array [ $parent_name ][ $x ][ $child_table ] = $results ;
}
}
}
$x ++ ;
}
}
}
//update the parent and child keys
$checked = false ;
2022-09-17 17:44:21 -04:00
$x = 0 ;
foreach ( $array as $parent_name => $tables ) {
if ( is_array ( $tables )) {
foreach ( $tables as $id => $row ) {
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//prepare the variables
$parent_name = self :: sanitize ( $parent_name );
$parent_key_name = self :: singular ( $parent_name ) . "_uuid" ;
$parent_key_value = uuid ();
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//update the parent key id
$array [ $parent_name ][ $x ][ $parent_key_name ] = $parent_key_value ;
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//add copy to the description
if ( isset ( $array [ $parent_name ][ $x ][ self :: singular ( $parent_name ) . '_description' ])) {
$array [ $parent_name ][ $x ][ self :: singular ( $parent_name ) . '_description' ] = $suffix . $array [ $parent_name ][ $x ][ self :: singular ( $parent_name ) . '_description' ];
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//loop through the fields
foreach ( $row as $field_name => $field_value ) {
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//find the child tables
$y = 0 ;
if ( is_array ( $field_value )) {
//prepare the variables
$child_name = self :: sanitize ( $field_name );
$child_key_name = self :: singular ( $child_name ) . "_uuid" ;
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//loop through the child rows
foreach ( $field_value as $sub_row ) {
//update the parent key id
$array [ $parent_name ][ $x ][ $child_name ][ $y ][ $parent_key_name ] = $parent_key_value ;
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//udpate the child key id
$array [ $parent_name ][ $x ][ $child_name ][ $y ][ $child_key_name ] = uuid ();
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//increment the value
$y ++ ;
2020-07-09 02:57:28 -06:00
}
}
2022-09-17 17:44:21 -04:00
}
2020-07-09 02:57:28 -06:00
2022-09-17 17:44:21 -04:00
//increment the value
$x ++ ;
2020-07-09 02:57:28 -06:00
}
}
}
//save the copy of the data
if ( is_array ( $array ) && count ( $array ) > 0 ) {
2022-09-17 17:44:21 -04:00
$retval = $this -> save ( $array );
2020-07-09 02:57:28 -06:00
unset ( $array );
}
2022-09-17 17:44:21 -04:00
return $retval ;
2020-07-09 02:57:28 -06:00
} //end function copy
2022-09-17 17:44:21 -04:00
/**
* Toggles fields on a table using the <i>toggle_field</i> array values within the app object.
* @param array $array Three dimensional Array. The first dimension is the table name without the prefix 'v_'. Second dimension in the row value as int. Third dimension is the column name.
* @return bool Returns <b>true</b> on success and <b>false</b> on failure.
* @depends database::save()
* @depends database::get_apps()
*/
2022-11-01 15:52:56 -06:00
public function toggle ( array $array ) {
2020-07-09 02:57:28 -06:00
//return the array
2022-09-17 17:44:21 -04:00
if ( ! is_array ( $array )) { return false ; }
2020-07-09 02:57:28 -06:00
//set the message id
$m = 0 ;
//loop through the array
if ( is_array ( $array )) {
$x = 0 ;
foreach ( $array as $parent_name => $tables ) {
if ( is_array ( $tables )) {
foreach ( $tables as $id => $row ) {
//prepare the variables
2022-09-17 17:44:21 -04:00
$parent_name = self :: sanitize ( $parent_name );
$parent_key_name = self :: singular ( $parent_name ) . "_uuid" ;
2020-07-09 02:57:28 -06:00
//build the toggle array
if ( $row [ 'checked' ] == 'true' ) {
//toggle the field value
//$toggle_array[$parent_name][$x][$parent_key_name] = $row[$parent_key_name];
$toggle_array [ $parent_name ][ $x ] = $row ;
//remove the row from the main array
unset ( $array [ $parent_name ][ $x ]);
}
//loop through the fields
foreach ( $row as $field_name => $field_value ) {
//find the child tables
$y = 0 ;
if ( is_array ( $field_value )) {
//prepare the variables
2022-09-17 17:44:21 -04:00
$child_name = self :: sanitize ( $field_name );
$child_key_name = self :: singular ( $child_name ) . "_uuid" ;
2020-07-09 02:57:28 -06:00
//loop through the child rows
foreach ( $field_value as $sub_row ) {
//build the delete array
if ( $action == 'delete' && $sub_row [ 'checked' ] == 'true' ) {
//delete the child data
$delete_array [ $child_name ][ $y ][ $child_key_name ] = $sub_row [ $child_key_name ];
//remove the row from the main array
unset ( $array [ $parent_name ][ $x ][ $child_name ][ $y ]);
}
//increment the value
$y ++ ;
}
}
}
//increment the value
$x ++ ;
}
}
}
}
//unset the original array
unset ( $array );
//get the $apps array from the installed apps from the core and mod directories
if ( ! is_array ( $_SESSION [ 'apps' ])) {
2022-09-17 17:44:21 -04:00
self :: get_apps ();
2020-07-09 02:57:28 -06:00
}
//search through all fields to see if toggle field exists
if ( is_array ( $_SESSION [ 'apps' ])) {
foreach ( $_SESSION [ 'apps' ] as $x => $app ) {
if ( is_array ( $app [ 'db' ])) {
foreach ( $app [ 'db' ] as $y => $row ) {
if ( is_array ( $row [ 'table' ][ 'name' ])) {
$table_name = $row [ 'table' ][ 'name' ][ 'text' ];
}
else {
$table_name = $row [ 'table' ][ 'name' ];
}
2022-09-17 17:44:21 -04:00
if ( $table_name === self :: TABLE_PREFIX . $parent_name ) {
2020-07-09 02:57:28 -06:00
if ( is_array ( $row [ 'fields' ])) {
foreach ( $row [ 'fields' ] as $field ) {
if ( isset ( $field [ 'toggle' ])) {
$toggle_field = $field [ 'name' ];
$toggle_values = $field [ 'toggle' ];
}
}
}
}
}
}
}
}
//get the current values from the database
foreach ( $toggle_array as $table_name => $table ) {
$x = 0 ;
foreach ( $table as $row ) {
2022-09-17 17:44:21 -04:00
$child_name = self :: sanitize ( $table_name );
$child_key_name = self :: singular ( $child_name ) . "_uuid" ;
2020-07-09 02:57:28 -06:00
$array [ $table_name ][ $x ][ $child_key_name ] = $row [ $child_key_name ];
$array [ $table_name ][ $x ][ $toggle_field ] = ( $row [ $toggle_field ] === $toggle_values [ 0 ]) ? $toggle_values [ 1 ] : $toggle_values [ 0 ];
$x ++ ;
}
}
unset ( $toggle_array );
//save the array
2022-09-17 17:44:21 -04:00
return $this -> save ( $array );
2020-07-09 02:57:28 -06:00
} //end function toggle
2022-09-17 17:44:21 -04:00
/**
* <p>Save an array to the database.</p>
* <p>Usage Example:<br><code>$database = new database();<br>$database->app_name = "MyApp";<br>$database->app_uuid = "12345678-1234-1234-1234-123456789abc";<br>$row = 0;<br>$array['mytable'][$row]['mycolumn'] = "myvalue";<br>if ($database->save($array)) { <br> echo "Saved Successfully.";<br> } else {<br> echo "Save Failed.";<br>}</code></p>
* @param array $array Three dimensional Array. The first dimension is the table name without the prefix 'v_'. Second dimension in the row value as int. Third dimension is the column name.
* @param bool $transaction_save
* @return boolean Returns <b>true</b> on success and <b>false</b> on failure of one or more failed write attempts.
*/
2022-11-01 15:52:56 -06:00
public function save ( array & $array , bool $transaction_save = true ) {
2022-09-18 04:47:17 -06:00
//set default return value
$retval = true ;
2016-10-16 10:45:04 -06:00
//return the array
2022-09-17 17:44:21 -04:00
if ( ! is_array ( $array )) { return false ; }
2016-10-16 10:45:04 -06:00
//set the message id
$m = 0 ;
2022-12-29 23:55:11 -07:00
//build the json string from the array
$new_json = json_encode ( $array , JSON_PRETTY_PRINT );
2020-07-09 02:57:28 -06:00
//debug sql
2022-09-19 09:30:20 -06:00
//$this->debug["sql"] = true;
2016-10-16 10:45:04 -06:00
//connect to the database if needed
if ( ! $this -> db ) {
$this -> connect ();
}
//start the atomic transaction
2017-07-14 20:44:45 -06:00
$this -> db -> beginTransaction ();
2016-10-16 10:45:04 -06:00
//loop through the array
2022-09-17 17:44:21 -04:00
if ( is_array ( $array )) foreach ( $array as $schema_name => $schema_array ) {
2016-10-16 10:45:04 -06:00
2022-09-17 17:44:21 -04:00
$this -> name = $schema_name ;
2016-11-27 00:16:18 -07:00
if ( is_array ( $schema_array )) foreach ( $schema_array as $schema_id => $array ) {
2016-10-16 10:45:04 -06:00
//set the variables
2022-09-17 17:44:21 -04:00
$table_name = self :: TABLE_PREFIX . $this -> name ;
$parent_key_name = self :: singular ( $this -> name ) . "_uuid" ;
$parent_key_name = self :: sanitize ( $parent_key_name );
2016-10-16 10:45:04 -06:00
2023-05-09 11:14:41 -06:00
//if the uuid is set then set parent key exists and value
2016-10-16 10:45:04 -06:00
//determine if the parent_key_exists
$parent_key_exists = false ;
if ( isset ( $array [ $parent_key_name ])) {
2017-05-28 17:18:07 +01:00
$parent_key_value = $array [ $parent_key_name ];
2016-10-16 10:45:04 -06:00
$parent_key_exists = true ;
}
else {
if ( isset ( $this -> uuid )) {
$parent_key_exists = true ;
$parent_key_value = $this -> uuid ;
}
else {
$parent_key_value = uuid ();
}
}
2017-07-11 00:13:54 -06:00
//allow characters found in the uuid only.
2022-09-17 17:44:21 -04:00
$parent_key_value = self :: sanitize ( $parent_key_value );
2017-07-11 00:13:54 -06:00
2016-10-16 10:45:04 -06:00
//get the parent field names
$parent_field_names = array ();
2019-08-03 16:16:30 -06:00
if ( is_array ( $array )) {
foreach ( $array as $key => $value ) {
if ( ! is_array ( $value )) {
2022-09-17 17:44:21 -04:00
$parent_field_names [] = self :: sanitize ( $key );
2019-08-03 16:16:30 -06:00
}
2016-10-16 10:45:04 -06:00
}
}
//determine action update or delete and get the original data
if ( $parent_key_exists ) {
$sql = "SELECT " . implode ( ", " , $parent_field_names ) . " FROM " . $table_name . " " ;
2022-09-30 12:46:44 -06:00
$sql .= "WHERE " . $parent_key_name . " = '" . $parent_key_value . "'; " ;
2016-10-16 10:45:04 -06:00
$prep_statement = $this -> db -> prepare ( $sql );
if ( $prep_statement ) {
//get the data
try {
$prep_statement -> execute ();
$result = $prep_statement -> fetchAll ( PDO :: FETCH_ASSOC );
}
catch ( PDOException $e ) {
2022-09-30 12:46:44 -06:00
echo $sql . "<br /> \n " ;
2022-09-20 13:56:54 -06:00
echo 'Caught exception: ' . $e -> getMessage () . "<br /><br /> \n " ;
echo $sql . "<br /><br /> \n " ;
2016-10-16 10:45:04 -06:00
exit ;
}
//set the action
if ( count ( $result ) > 0 ) {
$action = "update" ;
$old_array [ $schema_name ] = $result ;
}
else {
$action = "add" ;
}
}
2022-09-30 12:46:44 -06:00
unset ( $prep_statement , $result );
2016-10-16 10:45:04 -06:00
}
else {
$action = "add" ;
}
//add a record
if ( $action == "add" ) {
2022-09-17 17:44:21 -04:00
if ( permission_exists ( self :: singular ( $this -> name ) . '_add' )) {
2016-10-16 10:45:04 -06:00
2017-07-14 20:41:23 -06:00
$params = array ();
2022-09-17 17:44:21 -04:00
$sql = "INSERT INTO " . self :: TABLE_PREFIX . $this -> name . " " ;
2016-10-16 10:45:04 -06:00
$sql .= "(" ;
if ( ! $parent_key_exists ) {
$sql .= $parent_key_name . ", " ;
}
2019-08-03 16:16:30 -06:00
if ( is_array ( $array )) {
foreach ( $array as $array_key => $array_value ) {
if ( ! is_array ( $array_value )) {
2022-09-17 17:44:21 -04:00
$array_key = self :: sanitize ( $array_key );
2022-09-20 13:56:54 -06:00
if ( $array_key != 'insert_user' &&
$array_key != 'insert_date' &&
2023-05-09 11:14:41 -06:00
$array_key != 'update_user' &&
2022-09-20 13:56:54 -06:00
$array_key != 'update_date' ) {
$sql .= $array_key . ", " ;
}
2019-08-03 16:16:30 -06:00
}
2016-10-16 10:45:04 -06:00
}
}
2022-09-18 02:57:43 -06:00
$sql .= "insert_date, " ;
$sql .= "insert_user " ;
2016-10-16 10:45:04 -06:00
$sql .= ") " ;
$sql .= "VALUES " ;
$sql .= "(" ;
if ( ! $parent_key_exists ) {
$sql .= "'" . $parent_key_value . "', " ;
}
2019-08-03 16:16:30 -06:00
if ( is_array ( $array )) {
foreach ( $array as $array_key => $array_value ) {
if ( ! is_array ( $array_value )) {
2022-09-20 13:56:54 -06:00
if ( $array_key != 'insert_user' &&
$array_key != 'insert_date' &&
2023-05-09 11:14:41 -06:00
$array_key != 'update_user' &&
2022-09-20 13:56:54 -06:00
$array_key != 'update_date' ) {
2023-05-09 11:14:41 -06:00
if ( strlen ( $array_value ) == 0 ) {
2022-09-20 13:56:54 -06:00
$sql .= "null, " ;
}
elseif ( $array_value === "now()" ) {
$sql .= "now(), " ;
}
elseif ( $array_value === "user_uuid()" ) {
$sql .= ':' . $array_key . ", " ;
$params [ $array_key ] = $_SESSION [ 'user_uuid' ];
}
elseif ( $array_value === "remote_address()" ) {
$sql .= ':' . $array_key . ", " ;
$params [ $array_key ] = $_SERVER [ 'REMOTE_ADDR' ];
}
else {
$sql .= ':' . $array_key . ", " ;
$params [ $array_key ] = trim ( $array_value );
}
2019-08-03 16:16:30 -06:00
}
2016-10-16 10:45:04 -06:00
}
}
}
2022-09-18 02:57:43 -06:00
$sql .= "now(), " ;
$sql .= ":insert_user " ;
2016-10-16 10:45:04 -06:00
$sql .= ");" ;
2022-09-18 02:57:43 -06:00
//add insert user parameter
$params [ 'insert_user' ] = $_SESSION [ 'user_uuid' ];
2017-07-11 12:48:20 -06:00
2022-08-18 17:53:33 -06:00
//set the error mode
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
2017-07-11 12:48:20 -06:00
2022-08-18 17:53:33 -06:00
//reduce prepared statement latency
if ( defined ( 'PDO::PGSQL_ATTR_DISABLE_PREPARES' )) {
2022-08-24 16:09:33 -04:00
$this -> db -> setAttribute ( PDO :: PGSQL_ATTR_DISABLE_PREPARES , true );
2022-08-18 17:53:33 -06:00
}
//execute the query and return the results
2016-10-16 10:45:04 -06:00
try {
2017-07-14 10:52:30 -06:00
//$this->db->query(check_sql($sql));
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
unset ( $prep_statement );
2016-10-16 10:45:04 -06:00
$message [ "message" ] = "OK" ;
$message [ "code" ] = "200" ;
$message [ "uuid" ] = $parent_key_value ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = "OK" ;
$message [ "details" ][ $m ][ "code" ] = "200" ;
$message [ "details" ][ $m ][ "uuid" ] = $parent_key_value ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2016-10-16 10:45:04 -06:00
}
2017-07-14 20:41:23 -06:00
unset ( $params );
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
$m ++ ;
}
catch ( PDOException $e ) {
2022-09-17 17:44:21 -04:00
$retval = false ;
2016-10-16 10:45:04 -06:00
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = $e -> getMessage ();
$message [ "details" ][ $m ][ "code" ] = "400" ;
2017-07-14 10:52:30 -06:00
$message [ "details" ][ $m ][ "array" ] = $array ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2016-10-16 10:45:04 -06:00
}
2017-07-14 20:41:23 -06:00
unset ( $params );
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
$m ++ ;
}
unset ( $sql );
}
else {
2022-09-17 17:44:21 -04:00
$retval = false ;
2016-10-16 10:45:04 -06:00
$message [ "name" ] = $this -> name ;
2022-09-17 17:44:21 -04:00
$message [ "message" ] = "Forbidden, does not have '" . self :: singular ( $this -> name ) . "_add'" ;
2016-10-16 10:45:04 -06:00
$message [ "code" ] = "403" ;
$message [ "line" ] = __line__ ;
$this -> message [] = $message ;
$m ++ ;
}
}
//edit a specific uuid
if ( $action == "update" ) {
2022-09-17 17:44:21 -04:00
if ( permission_exists ( self :: singular ( $this -> name ) . '_edit' )) {
2016-10-16 10:45:04 -06:00
//parent data
2017-07-14 20:41:23 -06:00
$params = array ();
2022-09-17 17:44:21 -04:00
$sql = "UPDATE " . self :: TABLE_PREFIX . $this -> name . " SET " ;
2016-11-27 00:16:18 -07:00
if ( is_array ( $array )) {
foreach ( $array as $array_key => $array_value ) {
if ( ! is_array ( $array_value ) && $array_key != $parent_key_name ) {
2022-09-17 17:44:21 -04:00
$array_key = self :: sanitize ( $array_key );
2023-05-09 11:14:41 -06:00
if ( strlen ( $array_value ) == 0 ) {
2017-07-11 11:30:22 -06:00
$sql .= $array_key . " = null, " ;
2016-11-27 00:16:18 -07:00
}
2017-07-08 01:10:28 -06:00
elseif ( $array_value === "now()" ) {
2017-07-11 11:30:22 -06:00
$sql .= $array_key . " = now(), " ;
2017-07-04 09:48:52 -06:00
}
2020-04-24 17:14:41 -06:00
elseif ( $array_value === "user_uuid()" ) {
$sql .= $array_key . " = :" . $array_key . ", " ;
2020-04-24 17:36:14 -06:00
$params [ $array_key ] = $_SESSION [ 'user_uuid' ];
2020-04-24 17:14:41 -06:00
}
elseif ( $array_value === "remote_address()" ) {
$sql .= $array_key . " = :" . $array_key . ", " ;
$params [ $array_key ] = $_SERVER [ 'REMOTE_ADDR' ];
}
2016-11-27 00:16:18 -07:00
else {
2017-07-14 10:52:30 -06:00
$sql .= $array_key . " = :" . $array_key . ", " ;
2019-11-20 10:14:01 -07:00
$params [ $array_key ] = trim ( $array_value );
2016-11-27 00:16:18 -07:00
}
2016-10-16 10:45:04 -06:00
}
}
}
2022-09-18 02:57:43 -06:00
//add the modified date and user
$sql .= "update_date = now(), " ;
$sql .= "update_user = :update_user " ;
$params [ 'update_user' ] = $_SESSION [ 'user_uuid' ];
//add the where with the parent name and value
2022-09-30 12:46:44 -06:00
$sql .= "WHERE " . $parent_key_name . " = '" . $parent_key_value . "'; " ;
2016-10-16 10:45:04 -06:00
$sql = str_replace ( ", WHERE" , " WHERE" , $sql );
2022-08-18 17:53:33 -06:00
2022-09-18 02:57:43 -06:00
//add update user parameter
$params [ 'update_user' ] = $_SESSION [ 'user_uuid' ];
2022-08-18 17:53:33 -06:00
//set the error mode
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//reduce prepared statement latency
if ( defined ( 'PDO::PGSQL_ATTR_DISABLE_PREPARES' )) {
2022-08-24 16:09:33 -04:00
$this -> db -> setAttribute ( PDO :: PGSQL_ATTR_DISABLE_PREPARES , true );
2022-08-18 17:53:33 -06:00
}
//execute the query and return the results
2016-10-16 10:45:04 -06:00
try {
2017-07-14 10:52:30 -06:00
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
//$this->db->query(check_sql($sql));
2016-10-16 10:45:04 -06:00
$message [ "message" ] = "OK" ;
$message [ "code" ] = "200" ;
$message [ "uuid" ] = $parent_key_value ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = "OK" ;
$message [ "details" ][ $m ][ "code" ] = "200" ;
$message [ "details" ][ $m ][ "uuid" ] = $parent_key_value ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2016-10-16 10:45:04 -06:00
}
2017-07-14 20:41:23 -06:00
unset ( $params );
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
$m ++ ;
unset ( $sql );
}
catch ( PDOException $e ) {
2022-09-17 17:44:21 -04:00
$retval = false ;
2016-10-16 10:45:04 -06:00
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
$message [ "details" ][ $m ][ "name" ] = $this -> name ;
$message [ "details" ][ $m ][ "message" ] = $e -> getMessage ();
$message [ "details" ][ $m ][ "code" ] = "400" ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2016-10-16 10:45:04 -06:00
}
2017-07-14 20:41:23 -06:00
unset ( $params );
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
$m ++ ;
}
}
else {
2022-09-17 17:44:21 -04:00
$retval = false ;
$message [ "message" ] = "Forbidden, does not have '" . self :: singular ( $this -> name ) . "_edit'" ;
2016-10-16 10:45:04 -06:00
$message [ "code" ] = "403" ;
$message [ "line" ] = __line__ ;
$this -> message = $message ;
$m ++ ;
}
}
//unset the variables
unset ( $sql , $action );
//child data
2019-08-03 16:16:30 -06:00
if ( is_array ( $array )) {
foreach ( $array as $key => $value ) {
if ( is_array ( $value )) {
2022-09-18 04:47:17 -06:00
$child_table_name = self :: TABLE_PREFIX . $key ;
$child_table_name = self :: sanitize ( $child_table_name );
2019-08-03 16:16:30 -06:00
foreach ( $value as $id => $row ) {
//prepare the variables
2022-09-17 17:44:21 -04:00
$child_name = self :: singular ( $key );
$child_name = self :: sanitize ( $child_name );
2019-08-03 16:16:30 -06:00
$child_key_name = $child_name . "_uuid" ;
//determine if the parent key exists in the child array
$parent_key_exists = false ;
if ( ! isset ( $array [ $parent_key_name ])) {
$parent_key_exists = true ;
}
2016-10-16 10:45:04 -06:00
2019-08-03 16:16:30 -06:00
//determine if the uuid exists
$uuid_exists = false ;
if ( is_array ( $row )) foreach ( $row as $k => $v ) {
if ( $child_key_name == $k ) {
2023-05-09 11:14:41 -06:00
if ( strlen ( $v ) > 0 ) {
2019-11-20 10:14:01 -07:00
$child_key_value = trim ( $v );
2019-08-03 16:16:30 -06:00
$uuid_exists = true ;
break ;
}
}
else {
$uuid_exists = false ;
2016-10-16 10:45:04 -06:00
}
}
2022-09-18 04:47:17 -06:00
//allow characters found in the uuid only
if ( isset ( $child_key_value )) {
$child_key_value = self :: sanitize ( $child_key_value );
}
2017-07-11 00:13:54 -06:00
2019-08-03 16:16:30 -06:00
//get the child field names
$child_field_names = array ();
if ( is_array ( $row )) {
foreach ( $row as $k => $v ) {
2020-07-09 02:57:28 -06:00
if ( ! is_array ( $v ) && $k !== 'checked' ) {
2022-09-17 17:44:21 -04:00
$child_field_names [] = self :: sanitize ( $k );
2019-08-03 16:16:30 -06:00
}
}
2016-10-16 10:45:04 -06:00
}
2019-08-03 16:16:30 -06:00
//determine sql update or delete and get the original data
if ( $uuid_exists ) {
2022-09-18 04:47:17 -06:00
$sql = "SELECT " . implode ( ", " , $child_field_names ) . " FROM " . $child_table_name . " " ;
2022-09-30 12:46:44 -06:00
$sql .= "WHERE " . $child_key_name . " = '" . $child_key_value . "'; " ;
try {
$prep_statement = $this -> db -> prepare ( $sql );
if ( $prep_statement ) {
//get the data
$prep_statement -> execute ();
$child_array = $prep_statement -> fetch ( PDO :: FETCH_ASSOC );
//set the action
if ( is_array ( $child_array )) {
$action = "update" ;
}
else {
$action = "add" ;
}
2020-07-09 02:57:28 -06:00
2022-09-30 12:46:44 -06:00
//add to the parent array
if ( is_array ( $child_array )) {
$old_array [ $schema_name ][ $schema_id ][ $key ][] = $child_array ;
}
}
unset ( $prep_statement );
}
catch ( PDOException $e ) {
echo $sql . "<br /> \n " ;
echo 'Caught exception: ' . $e -> getMessage () . "<br /><br /> \n " ;
echo $sql . "<br /><br /> \n " ;
exit ;
2019-08-03 16:16:30 -06:00
}
2022-09-30 12:46:44 -06:00
2019-08-03 16:16:30 -06:00
}
else {
$action = "add" ;
}
//update the child data
if ( $action == "update" ) {
if ( permission_exists ( $child_name . '_edit' )) {
2022-09-18 04:47:17 -06:00
$sql = "UPDATE " . $child_table_name . " SET " ;
2019-08-03 16:16:30 -06:00
if ( is_array ( $row )) {
foreach ( $row as $k => $v ) {
if ( ! is_array ( $v ) && ( $k != $parent_key_name || $k != $child_key_name )) {
2022-09-17 17:44:21 -04:00
$k = self :: sanitize ( $k );
2023-05-09 11:14:41 -06:00
if ( strlen ( $v ) == 0 ) {
2019-08-03 16:16:30 -06:00
$sql .= $k . " = null, " ;
}
elseif ( $v === "now()" ) {
$sql .= $k . " = now(), " ;
}
2020-04-24 17:14:41 -06:00
elseif ( $v === "user_uuid()" ) {
$sql .= $k . " = :" . $k . ", " ;
2020-04-24 17:36:14 -06:00
$params [ $k ] = $_SESSION [ 'user_uuid' ];
2020-04-24 17:14:41 -06:00
}
elseif ( $v === "remote_address()" ) {
$sql .= $k . " = :" . $k . ", " ;
$params [ $k ] = $_SERVER [ 'REMOTE_ADDR' ];
}
2019-08-03 16:16:30 -06:00
else {
$sql .= $k . " = :" . $k . ", " ;
2019-11-20 10:14:01 -07:00
$params [ $k ] = trim ( $v );
2019-08-03 16:16:30 -06:00
}
}
}
2016-10-16 10:45:04 -06:00
}
2022-09-18 02:57:43 -06:00
//add the modified date and user
$sql .= "update_date = now(), " ;
$sql .= "update_user = :update_user " ;
$params [ 'update_user' ] = $_SESSION [ 'user_uuid' ];
//add the where with the parent name and value
2019-08-03 16:16:30 -06:00
$sql .= "WHERE " . $parent_key_name . " = '" . $parent_key_value . "' " ;
2022-09-30 12:46:44 -06:00
$sql .= "AND " . $child_key_name . " = '" . $child_key_value . "'; " ;
2019-08-03 16:16:30 -06:00
$sql = str_replace ( ", WHERE" , " WHERE" , $sql );
2022-08-18 17:53:33 -06:00
//set the error mode
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//reduce prepared statement latency
if ( defined ( 'PDO::PGSQL_ATTR_DISABLE_PREPARES' )) {
2022-08-24 16:09:33 -04:00
$this -> db -> setAttribute ( PDO :: PGSQL_ATTR_DISABLE_PREPARES , true );
2022-08-18 17:53:33 -06:00
}
2019-08-03 16:16:30 -06:00
//$prep_statement->bindParam(':domain_uuid', $this->domain_uuid );
try {
//$this->db->query(check_sql($sql));
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
unset ( $prep_statement );
$message [ "details" ][ $m ][ "name" ] = $key ;
$message [ "details" ][ $m ][ "message" ] = "OK" ;
$message [ "details" ][ $m ][ "code" ] = "200" ;
$message [ "details" ][ $m ][ "uuid" ] = $child_key_value ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2019-08-03 16:16:30 -06:00
}
2022-09-19 09:30:20 -06:00
unset ( $params );
2019-08-03 16:16:30 -06:00
$this -> message = $message ;
$m ++ ;
2016-10-16 10:45:04 -06:00
}
2019-08-03 16:16:30 -06:00
catch ( PDOException $e ) {
2022-09-17 17:44:21 -04:00
$retval = false ;
2019-08-03 16:16:30 -06:00
if ( $message [ "code" ] = "200" ) {
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
}
$message [ "details" ][ $m ][ "name" ] = $key ;
$message [ "details" ][ $m ][ "message" ] = $e -> getMessage ();
$message [ "details" ][ $m ][ "code" ] = "400" ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2019-08-03 16:16:30 -06:00
}
2022-09-19 09:30:20 -06:00
unset ( $params );
2019-08-03 16:16:30 -06:00
$this -> message = $message ;
$m ++ ;
2016-10-16 10:45:04 -06:00
}
2019-08-03 16:16:30 -06:00
}
else {
2022-09-17 17:44:21 -04:00
$retval = false ;
2019-08-03 16:16:30 -06:00
$message [ "name" ] = $child_name ;
2023-05-09 11:14:41 -06:00
$message [ "message" ] = "Forbidden, does not have '" . $child_name . "_edit'" ;
2019-08-03 16:16:30 -06:00
$message [ "code" ] = "403" ;
$message [ "line" ] = __line__ ;
$this -> message = $message ;
$m ++ ;
}
} //action update
//add the child data
if ( $action == "add" ) {
if ( permission_exists ( $child_name . '_add' )) {
//determine if child or parent key exists
$child_key_name = $child_name . '_uuid' ;
$parent_key_exists = false ;
$child_key_exists = false ;
2016-11-27 00:16:18 -07:00
if ( is_array ( $row )) {
foreach ( $row as $k => $v ) {
2019-08-03 16:16:30 -06:00
if ( $k == $parent_key_name ) {
2023-05-09 11:14:41 -06:00
$parent_key_exists = true ;
2019-08-03 16:16:30 -06:00
}
if ( $k == $child_key_name ) {
$child_key_exists = true ;
2019-11-20 10:14:01 -07:00
$child_key_value = trim ( $v );
2019-08-03 16:16:30 -06:00
}
}
}
if ( ! $child_key_value ) {
$child_key_value = uuid ();
}
//build the insert
2022-09-18 04:47:17 -06:00
$sql = "INSERT INTO " . $child_table_name . " " ;
2019-08-03 16:16:30 -06:00
$sql .= "(" ;
if ( ! $parent_key_exists ) {
2022-09-17 17:44:21 -04:00
$sql .= self :: singular ( $parent_key_name ) . ", " ;
2019-08-03 16:16:30 -06:00
}
if ( ! $child_key_exists ) {
2022-09-17 17:44:21 -04:00
$sql .= self :: singular ( $child_key_name ) . ", " ;
2019-08-03 16:16:30 -06:00
}
if ( is_array ( $row )) {
foreach ( $row as $k => $v ) {
if ( ! is_array ( $v )) {
2022-09-17 17:44:21 -04:00
$k = self :: sanitize ( $k );
2022-09-30 12:46:44 -06:00
if ( $k != 'insert_user' &&
$k != 'insert_date' &&
2023-05-09 11:14:41 -06:00
$k != 'update_user' &&
2022-09-30 12:46:44 -06:00
$k != 'update_date' ) {
$sql .= $k . ", " ;
}
2019-08-03 16:16:30 -06:00
}
}
}
2022-09-30 12:46:44 -06:00
$sql .= "insert_date, " ;
$sql .= "insert_user " ;
2019-08-03 16:16:30 -06:00
$sql .= ") " ;
$sql .= "VALUES " ;
$sql .= "(" ;
if ( ! $parent_key_exists ) {
$sql .= "'" . $parent_key_value . "', " ;
}
if ( ! $child_key_exists ) {
$sql .= "'" . $child_key_value . "', " ;
}
if ( is_array ( $row )) {
foreach ( $row as $k => $v ) {
if ( ! is_array ( $v )) {
2022-10-18 13:04:16 -06:00
if ( $k != 'insert_user' &&
2022-09-30 12:46:44 -06:00
$k != 'insert_date' &&
2023-05-09 11:14:41 -06:00
$k != 'update_user' &&
2022-09-30 12:46:44 -06:00
$k != 'update_date' ) {
2023-05-09 11:14:41 -06:00
if ( strlen ( $v ) == 0 ) {
2022-10-18 13:04:16 -06:00
$sql .= "null, " ;
}
elseif ( $v === "now()" ) {
$sql .= "now(), " ;
}
elseif ( $v === "user_uuid()" ) {
2022-09-30 12:46:44 -06:00
$sql .= ':' . $k . ", " ;
2022-10-18 13:04:16 -06:00
$params [ $k ] = $_SESSION [ 'user_uuid' ];
}
elseif ( $v === "remote_address()" ) {
$sql .= ':' . $k . ", " ;
$params [ $k ] = $_SERVER [ 'REMOTE_ADDR' ];
}
else {
$k = self :: sanitize ( $k );
if ( $k != 'insert_user' &&
$k != 'insert_date' &&
2023-05-09 11:14:41 -06:00
$k != 'update_user' &&
2022-10-18 13:04:16 -06:00
$k != 'update_date' ) {
$sql .= ':' . $k . ", " ;
$params [ $k ] = trim ( $v );
}
2022-09-30 12:46:44 -06:00
}
2016-11-27 00:16:18 -07:00
}
2016-10-16 10:45:04 -06:00
}
}
}
2022-09-30 12:46:44 -06:00
$sql .= "now(), " ;
$sql .= ":insert_user " ;
2019-08-03 16:16:30 -06:00
$sql .= ");" ;
2022-09-18 02:57:43 -06:00
//add insert user parameter
$params [ 'insert_user' ] = $_SESSION [ 'user_uuid' ];
2022-08-18 17:53:33 -06:00
//set the error mode
$this -> db -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
//reduce prepared statement latency
if ( defined ( 'PDO::PGSQL_ATTR_DISABLE_PREPARES' )) {
2022-08-24 16:09:33 -04:00
$this -> db -> setAttribute ( PDO :: PGSQL_ATTR_DISABLE_PREPARES , true );
2022-08-18 17:53:33 -06:00
}
//execute the query and return the results
2016-10-16 10:45:04 -06:00
try {
2017-07-14 10:52:30 -06:00
$prep_statement = $this -> db -> prepare ( $sql );
$prep_statement -> execute ( $params );
2017-07-14 20:41:23 -06:00
unset ( $prep_statement );
2016-10-16 10:45:04 -06:00
$message [ "details" ][ $m ][ "name" ] = $key ;
$message [ "details" ][ $m ][ "message" ] = "OK" ;
$message [ "details" ][ $m ][ "code" ] = "200" ;
$message [ "details" ][ $m ][ "uuid" ] = $child_key_value ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2016-10-16 10:45:04 -06:00
}
2022-09-19 09:30:20 -06:00
unset ( $params );
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
$m ++ ;
}
catch ( PDOException $e ) {
2022-09-17 17:44:21 -04:00
$retval = false ;
2016-10-16 10:45:04 -06:00
if ( $message [ "code" ] = "200" ) {
$message [ "message" ] = "Bad Request" ;
$message [ "code" ] = "400" ;
}
$message [ "details" ][ $m ][ "name" ] = $key ;
$message [ "details" ][ $m ][ "message" ] = $e -> getMessage ();
$message [ "details" ][ $m ][ "code" ] = "400" ;
2023-05-08 22:30:39 -06:00
$message [ "details" ][ $m ][ "sql" ] = $sql ;
if ( is_array ( $params )) {
$message [ "details" ][ $m ][ "params" ] = $params ;
2016-10-16 10:45:04 -06:00
}
2022-09-19 09:30:20 -06:00
unset ( $params );
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
$m ++ ;
}
}
else {
2022-09-17 17:44:21 -04:00
$retval = false ;
2016-10-16 10:45:04 -06:00
$message [ "name" ] = $child_name ;
2023-05-09 11:14:41 -06:00
$message [ "message" ] = "Forbidden, does not have '" . $child_name . "_add'" ;
2016-10-16 10:45:04 -06:00
$message [ "code" ] = "403" ;
$message [ "line" ] = __line__ ;
$this -> message = $message ;
$m ++ ;
}
2019-08-03 16:16:30 -06:00
} //action add
2016-10-16 10:45:04 -06:00
2019-08-03 16:16:30 -06:00
//unset the variables
unset ( $sql , $action , $child_key_name , $child_key_value );
} // foreach value
2016-10-16 10:45:04 -06:00
2019-08-03 16:16:30 -06:00
} //is array
} //foreach array
}
2016-10-16 10:45:04 -06:00
} // foreach schema_array
2022-09-18 04:47:17 -06:00
} // foreach main array
2016-10-16 10:45:04 -06:00
$this -> message = $message ;
//commit the atomic transaction
2017-07-14 20:44:45 -06:00
$this -> db -> commit ();
2016-10-16 10:45:04 -06:00
2018-02-12 08:40:23 -07:00
//set the action if not set
2023-05-05 13:46:37 -03:00
if ( strlen ( $action ?? '' ) === 0 ) {
2018-02-12 08:40:23 -07:00
if ( is_array ( $old_array )) {
$transaction_type = 'update' ;
}
else {
$transaction_type = 'add' ;
}
}
else {
$transaction_type = $action ;
}
2017-06-11 08:48:18 -06:00
//get the UUIDs
$user_uuid = $_SESSION [ 'user_uuid' ];
2016-10-16 10:45:04 -06:00
//log the transaction results
2020-12-10 19:52:03 -07:00
if ( $transaction_save && file_exists ( $_SERVER [ "PROJECT_ROOT" ] . "/app/database_transactions/app_config.php" )) {
2019-03-23 17:27:58 -06:00
try {
2022-09-17 17:44:21 -04:00
$sql = "insert into " . self :: TABLE_PREFIX . "database_transactions " ;
2019-03-23 17:27:58 -06:00
$sql .= "(" ;
$sql .= "database_transaction_uuid, " ;
$sql .= "domain_uuid, " ;
2019-08-20 13:05:27 -06:00
if ( isset ( $user_uuid ) && is_uuid ( $user_uuid )) {
2019-03-23 17:27:58 -06:00
$sql .= "user_uuid, " ;
}
2019-08-20 13:05:27 -06:00
if ( isset ( $this -> app_uuid ) && is_uuid ( $this -> app_uuid )) {
2019-03-23 17:27:58 -06:00
$sql .= "app_uuid, " ;
}
2023-05-05 13:46:37 -03:00
if ( isset ( $this -> app_name ) && ! empty ( $this -> app_name )) {
2019-03-23 17:27:58 -06:00
$sql .= "app_name, " ;
}
$sql .= "transaction_code, " ;
$sql .= "transaction_address, " ;
$sql .= "transaction_type, " ;
$sql .= "transaction_date, " ;
$sql .= "transaction_old, " ;
$sql .= "transaction_new, " ;
$sql .= "transaction_result " ;
$sql .= ")" ;
$sql .= "values " ;
$sql .= "(" ;
$sql .= "'" . uuid () . "', " ;
if ( is_null ( $this -> domain_uuid )) {
$sql .= "null, " ;
}
else {
$sql .= "'" . $this -> domain_uuid . "', " ;
}
2019-08-20 13:05:27 -06:00
if ( isset ( $user_uuid ) && is_uuid ( $user_uuid )) {
2019-03-23 17:27:58 -06:00
$sql .= ":user_uuid, " ;
}
2019-08-20 13:05:27 -06:00
if ( isset ( $this -> app_uuid ) && is_uuid ( $this -> app_uuid )) {
2019-03-23 17:27:58 -06:00
$sql .= ":app_uuid, " ;
}
2023-05-05 13:46:37 -03:00
if ( isset ( $this -> app_name ) && ! empty ( $this -> app_name )) {
2019-03-23 17:27:58 -06:00
$sql .= ":app_name, " ;
}
$sql .= "'" . $message [ "code" ] . "', " ;
$sql .= ":remote_address, " ;
$sql .= "'" . $transaction_type . "', " ;
$sql .= "now(), " ;
if ( is_array ( $old_array )) {
$sql .= ":transaction_old, " ;
}
else {
$sql .= "null, " ;
}
2022-09-17 17:44:21 -04:00
if ( is_array ( $array )) {
2019-03-23 17:27:58 -06:00
$sql .= ":transaction_new, " ;
}
else {
$sql .= "null, " ;
}
$sql .= ":transaction_result " ;
$sql .= ")" ;
$statement = $this -> db -> prepare ( $sql );
2019-08-20 13:05:27 -06:00
if ( isset ( $user_uuid ) && is_uuid ( $user_uuid )) {
2019-03-23 17:27:58 -06:00
$statement -> bindParam ( ':user_uuid' , $user_uuid );
}
2019-08-20 13:05:27 -06:00
if ( isset ( $this -> app_uuid ) && is_uuid ( $this -> app_uuid )) {
2019-03-23 17:27:58 -06:00
$statement -> bindParam ( ':app_uuid' , $this -> app_uuid );
}
2023-05-05 13:46:37 -03:00
if ( isset ( $this -> app_name ) && ! empty ( $this -> app_name )) {
2019-03-23 17:27:58 -06:00
$statement -> bindParam ( ':app_name' , $this -> app_name );
}
$statement -> bindParam ( ':remote_address' , $_SERVER [ 'REMOTE_ADDR' ]);
2019-03-25 09:32:00 -06:00
if ( is_array ( $old_array )) {
2019-04-09 10:49:51 -06:00
$old_json = json_encode ( $old_array , JSON_PRETTY_PRINT );
$statement -> bindParam ( ':transaction_old' , $old_json );
2019-03-25 09:32:00 -06:00
}
2022-12-29 23:55:11 -07:00
if ( isset ( $new_json )) {
2019-04-09 10:49:51 -06:00
$statement -> bindParam ( ':transaction_new' , $new_json );
2019-03-25 09:32:00 -06:00
}
2019-04-09 10:49:51 -06:00
$message = json_encode ( $this -> message , JSON_PRETTY_PRINT );
$statement -> bindParam ( ':transaction_result' , $message );
2019-03-23 17:27:58 -06:00
$statement -> execute ();
unset ( $sql );
2018-02-12 08:40:23 -07:00
}
2019-03-23 17:27:58 -06:00
catch ( PDOException $e ) {
echo $e -> getMessage ();
exit ;
2018-02-12 08:40:23 -07:00
}
2016-10-16 10:45:04 -06:00
}
2022-09-17 17:44:21 -04:00
return $retval ;
2016-10-16 10:45:04 -06:00
} //save method
2022-09-17 17:44:21 -04:00
/**
* Converts a plural English word to singular.
* @param string $word English word
* @return string Singular version of English word
* @internal Moved to class to conserve resources.
*/
2022-11-01 15:52:56 -06:00
public static function singular ( string $word ) {
2016-10-16 10:45:04 -06:00
//"-es" is used for words that end in "-x", "-s", "-z", "-sh", "-ch" in which case you add
if ( substr ( $word , - 2 ) == "es" ) {
2019-07-27 09:02:47 -06:00
if ( substr ( $word , - 4 ) == "sses" ) { // eg. 'addresses' to 'address'
return substr ( $word , 0 , - 2 );
}
elseif ( substr ( $word , - 3 ) == "ses" ) { // eg. 'databases' to 'database' (necessary!)
return substr ( $word , 0 , - 1 );
2019-07-09 20:06:17 -06:00
}
2019-07-27 09:02:47 -06:00
elseif ( substr ( $word , - 3 ) == "ies" ) { // eg. 'countries' to 'country'
2019-06-30 17:11:15 -04:00
return substr ( $word , 0 , - 3 ) . "y" ;
}
2019-07-27 09:02:47 -06:00
elseif ( substr ( $word , - 3 , 1 ) == "x" ) {
2016-10-16 10:45:04 -06:00
return substr ( $word , 0 , - 2 );
}
2019-07-27 09:02:47 -06:00
elseif ( substr ( $word , - 3 , 1 ) == "s" ) {
2016-10-16 10:45:04 -06:00
return substr ( $word , 0 , - 2 );
}
elseif ( substr ( $word , - 3 , 1 ) == "z" ) {
return substr ( $word , 0 , - 2 );
}
elseif ( substr ( $word , - 4 , 2 ) == "sh" ) {
return substr ( $word , 0 , - 2 );
}
elseif ( substr ( $word , - 4 , 2 ) == "ch" ) {
return substr ( $word , 0 , - 2 );
}
else {
return rtrim ( $word , "s" );
}
}
else {
return rtrim ( $word , "s" );
}
}
2022-09-17 17:44:21 -04:00
/**
* Gets the $apps array from the installed apps from the core and mod directories and writes it to $_SESSION['apps'] overwriting previous values.
* @uses $_SERVER['DOCUMENT_ROOT'] Global variable
* @uses PROJECT_PATH Global variable
* @return null Does not return any values
* @internal Moved to class to conserve resources.
*/
public static function get_apps () {
2016-10-16 10:45:04 -06:00
//get the $apps array from the installed apps from the core and mod directories
$config_list = glob ( $_SERVER [ "DOCUMENT_ROOT" ] . PROJECT_PATH . "/*/*/app_config.php" );
$x = 0 ;
2016-11-27 00:16:18 -07:00
if ( is_array ( $config_list )) {
foreach ( $config_list as & $config_path ) {
include ( $config_path );
$x ++ ;
}
2016-10-16 10:45:04 -06:00
}
$_SESSION [ 'apps' ] = $apps ;
}
2022-09-17 17:44:21 -04:00
/**
* Returns the depth of an array
* @param array $array Reference to array
* @return int Depth of array
* @internal Moved to class to conserve resources.
*/
2022-11-01 15:52:56 -06:00
public static function array_depth ( array & $array ) {
2022-09-17 17:44:21 -04:00
$depth = 0 ;
2016-10-16 10:45:04 -06:00
if ( is_array ( $array )) {
2022-09-17 17:44:21 -04:00
$depth ++ ;
2016-10-16 10:45:04 -06:00
foreach ( $array as $value ) {
if ( is_array ( $value )) {
2022-09-17 17:44:21 -04:00
$depth = self :: array_depth ( $value ) + 1 ;
2016-10-16 10:45:04 -06:00
}
}
}
return $depth ;
}
2022-09-17 17:44:21 -04:00
/**
* Searches through all fields to see if domain_uuid exists
* @param string $name
* @uses $_SESSION['apps'] directly
* @return boolean <b>true</b> on success and <b>false</b> on failure
* @see database::get_apps()
*/
public static function domain_uuid_exists ( $name ) {
2016-10-16 10:45:04 -06:00
//get the $apps array from the installed apps from the core and mod directories
if ( ! is_array ( $_SESSION [ 'apps' ])) {
2022-09-17 17:44:21 -04:00
self :: get_apps ();
2016-10-16 10:45:04 -06:00
}
2020-07-09 02:57:28 -06:00
2016-10-16 10:45:04 -06:00
//search through all fields to see if domain_uuid exists
2016-11-27 00:16:18 -07:00
$apps = $_SESSION [ 'apps' ];
if ( is_array ( $apps )) {
foreach ( $apps as $x => & $app ) {
if ( is_array ( $app [ 'db' ])) {
foreach ( $app [ 'db' ] as $y => & $row ) {
2020-07-09 02:57:28 -06:00
if ( is_array ( $row [ 'table' ][ 'name' ])) {
$table_name = $row [ 'table' ][ 'name' ][ 'text' ];
}
else {
$table_name = $row [ 'table' ][ 'name' ];
}
2022-09-17 17:44:21 -04:00
if ( $table_name === self :: TABLE_PREFIX . $name ) {
2016-11-27 00:16:18 -07:00
if ( is_array ( $row [ 'fields' ])) {
2020-07-09 02:57:28 -06:00
foreach ( $row [ 'fields' ] as $field ) {
2016-11-27 00:16:18 -07:00
if ( $field [ 'name' ] == "domain_uuid" ) {
return true ;
}
} //foreach
} //is array
2016-10-16 10:45:04 -06:00
}
2016-11-27 00:16:18 -07:00
} //foreach
} //is array
} //foreach
} //is array
2020-07-09 02:57:28 -06:00
2016-10-16 10:45:04 -06:00
//not found
return false ;
}
2022-09-17 17:44:21 -04:00
/**
* Get Relations searches through all fields to find relations
* @param string $schema Table name
* @return array Returns array or false
* @internal Moved to class to conserve resources.
*/
public static function get_relations ( $schema ) {
2020-07-09 02:57:28 -06:00
//remove the v_ prefix
2022-09-17 17:44:21 -04:00
if ( substr ( $schema , 0 , strlen ( self :: TABLE_PREFIX )) == self :: TABLE_PREFIX ) {
$schema = substr ( $schema , strlen ( self :: TABLE_PREFIX ));
2020-07-09 02:57:28 -06:00
}
//sanitize the values
2022-09-17 17:44:21 -04:00
$schema = self :: sanitize ( $schema );
2020-07-09 02:57:28 -06:00
//get the apps array
2022-09-17 17:44:21 -04:00
$config_list = glob ( $_SERVER [ "DOCUMENT_ROOT" ] . PROJECT_PATH . "/{core,app}/{" . $schema . "," . self :: singular ( $schema ) . "}/app_config.php" , GLOB_BRACE );
2020-07-09 02:57:28 -06:00
foreach ( $config_list as & $config_path ) {
include ( $config_path );
}
//search through all fields to find relations
if ( is_array ( $apps )) {
foreach ( $apps as $x => & $app ) {
foreach ( $app [ 'db' ] as $y => & $row ) {
foreach ( $row [ 'fields' ] as $z => $field ) {
if ( $field [ 'deprecated' ] != "true" ) {
if ( $field [ 'key' ][ 'type' ] == "foreign" ) {
2022-09-17 17:44:21 -04:00
if ( $row [ 'table' ][ 'name' ] == self :: TABLE_PREFIX . $schema || $field [ 'key' ][ 'reference' ][ 'table' ] == self :: TABLE_PREFIX . $schema ) {
2020-07-09 02:57:28 -06:00
//get the field name
if ( is_array ( $field [ 'name' ])) {
$field_name = trim ( $field [ 'name' ][ 'text' ]);
}
else {
$field_name = trim ( $field [ 'name' ]);
}
//build the array
2022-12-29 23:55:11 -07:00
$relations [ $i ][ 'table' ] = $row [ 'table' ][ 'name' ];
$relations [ $i ][ 'field' ] = $field_name ;
$relations [ $i ][ 'key' ][ 'type' ] = $field [ 'key' ][ 'type' ];
$relations [ $i ][ 'key' ][ 'table' ] = $field [ 'key' ][ 'reference' ][ 'table' ];
$relations [ $i ][ 'key' ][ 'field' ] = $field [ 'key' ][ 'reference' ][ 'field' ];
2020-07-17 21:43:34 -06:00
if ( isset ( $field [ 'key' ][ 'reference' ][ 'action' ])) {
2022-12-29 23:55:11 -07:00
$relations [ $i ][ 'key' ][ 'action' ] = $field [ 'key' ][ 'reference' ][ 'action' ];
2020-07-17 21:43:34 -06:00
}
2020-07-09 02:57:28 -06:00
//increment the value
$i ++ ;
}
}
}
unset ( $field_name );
}
}
}
}
//return the array
2022-12-29 23:55:11 -07:00
if ( is_array ( $relations )) {
return $relations ;
2020-07-09 02:57:28 -06:00
} else {
return false ;
}
}
2022-09-17 17:44:21 -04:00
/**
* Returns a sanitized string value safe for database or table name.
* @param string $value To be sanitized
* @return string Sanitized using preg_replace('#[^a-zA-Z0-9_\-]#', '')
* @see preg_replace()
*/
2022-11-01 15:52:56 -06:00
public static function sanitize ( string $value ) {
2022-09-17 17:44:21 -04:00
return preg_replace ( '#[^a-zA-Z0-9_\-]#' , '' , $value );
}
/**
* Returns a new connected database object.<br>
* <p>This allows a shortcut for a common syntax. For more information
* on how the connection happens see {@link database::__construct()} and
* {@link database::connect()}</p>
* <p><b>Usage:</b><br>
* <code> $database_object = database::new();</code></p>
2023-02-21 12:39:15 -04:00
* @return database new instance of database object already connected
2022-09-17 17:44:21 -04:00
* @see database::__construct()
* @see database::connect()
*/
2023-02-21 12:39:15 -04:00
public static function new () {
2022-09-17 17:44:21 -04:00
$db = new database ();
$db -> connect ();
return $db ;
}
2016-10-16 10:45:04 -06:00
} //class database
} //!class_exists
2012-06-04 14:58:40 +00:00
2016-10-20 15:03:52 -06:00
//addtitional functions for sqlite
if ( ! function_exists ( 'php_md5' )) {
function php_md5 ( $string ) {
return md5 ( $string );
}
2012-06-04 14:58:40 +00:00
}
2016-10-20 15:03:52 -06:00
if ( ! function_exists ( 'php_unix_time_stamp' )) {
function php_unix_time_stamp ( $string ) {
return strtotime ( $string );
}
2012-06-04 14:58:40 +00:00
}
2016-10-20 15:03:52 -06:00
if ( ! function_exists ( 'php_now' )) {
function php_now () {
return date ( "Y-m-d H:i:s" );
}
2012-06-04 14:58:40 +00:00
}
2016-10-20 15:03:52 -06:00
if ( ! function_exists ( 'php_left' )) {
function php_left ( $string , $num ) {
return substr ( $string , 0 , $num );
}
2012-06-04 14:58:40 +00:00
}
2016-10-20 15:03:52 -06:00
if ( ! function_exists ( 'php_right' )) {
function php_right ( $string , $num ) {
return substr ( $string , ( strlen ( $string ) - $num ), strlen ( $string ));
}
2012-06-04 14:58:40 +00:00
}
/*
2016-10-20 15:03:52 -06:00
//example usage
//find
require_once "resources/classes/database.php";
$database = new database;
$database->domain_uuid = $_SESSION["domain_uuid"];
$database->type = $db_type;
$database->table = "v_extensions";
$where[0]['name'] = 'domain_uuid';
$where[0]['value'] = $_SESSION["domain_uuid"];
$where[0]['operator'] = '=';
$database->where = $where;
$order_by[0]['name'] = 'extension';
$database->order_by = $order_by;
$database->order_type = 'desc';
$database->limit = '2';
$database->offset = '0';
$database->find();
print_r($database->result);
//insert
require_once "resources/classes/database.php";
$database = new database;
$database->domain_uuid = $_SESSION["domain_uuid"];
$database->table = "v_ivr_menus";
$fields[0]['name'] = 'domain_uuid';
$fields[0]['value'] = $_SESSION["domain_uuid"];
2017-07-15 17:09:01 -06:00
echo $database->count();
2017-07-15 17:20:21 -06:00
*/
2018-02-12 08:40:23 -07:00
2016-10-16 10:45:04 -06:00
?>