diff --git a/do.php b/do.php index fef97ff..f946914 100755 --- a/do.php +++ b/do.php @@ -320,7 +320,7 @@ elseif (ig('down') || ig('downf') || $is_live = in_array($t, $livexts) ? true : false; - $SQL->free($result); + $SQL->freeresult($result); //fix bug where a user can override files wait counter if (! $is_image && (ig('img') || ig('thmb'))) diff --git a/includes/adm/d_img_ctrl.php b/includes/adm/d_img_ctrl.php index f385c0e..28402b0 100755 --- a/includes/adm/d_img_ctrl.php +++ b/includes/adm/d_img_ctrl.php @@ -69,11 +69,11 @@ if (ip('submit')) @kleeja_unlink(PATH . $row['folder'] . '/thumbs/' . $row['name']); } $ids[] = $row['id']; - $num++; + $num++; $sizes += $row['size']; } - $SQL->free($result); + $SQL->freeresult($result); } @@ -105,9 +105,9 @@ if (ip('submit')) } } - //after submit + //after submit $text = ($affected ? $lang['FILES_UPDATED'] : $lang['NO_UP_CHANGE_S']) . - '' . "\n"; $stylee = 'admin_info'; @@ -231,8 +231,8 @@ else 'thumb_link' => $url_thumb ]; - //fix ... - $tdnum = $tdnum == 4 ? 0 : $tdnum+1; + //fix ... + $tdnum = $tdnum == 4 ? 0 : $tdnum+1; $del[$row['id']] = p('del_' . $row['id']); @@ -260,7 +260,7 @@ else } //pages - $total_pages = $Pager->getTotalPages(); + $total_pages = $Pager->getTotalPages(); $page_nums = $Pager->print_nums(basename(ADMIN_PATH) . '?cp=' . basename(__file__, '.php') . (ig('last_visit') ? '&last_vists=' . g('last_visit', 'int') : '') . (ig('smt') ? '&smt=' . g('smt') : ''), 'onclick="javascript:get_kleeja_link($(this).attr(\'href\'), \'#content\'); return false;"'); diff --git a/includes/adm/g_users.php b/includes/adm/g_users.php index caab7d7..a9bc6e2 100755 --- a/includes/adm/g_users.php +++ b/includes/adm/g_users.php @@ -460,7 +460,7 @@ if (ip('newgroup')) ]; $SQL->build($insert_query); } - $SQL->free($result); + $SQL->freeresult($result); //copy configs from the other group to this group $query = [ @@ -480,7 +480,7 @@ if (ip('newgroup')) ]; $SQL->build($insert_query); } - $SQL->free($result); + $SQL->freeresult($result); //copy exts from the other group to this group $query = [ @@ -500,7 +500,7 @@ if (ip('newgroup')) ]; $SQL->build($insert_query); } - $SQL->free($result); + $SQL->freeresult($result); //show group-is-added message delete_cache('data_groups'); @@ -934,50 +934,6 @@ case 'group_exts': $d_groups[$req_group]['data']['group_name']); - //check if there is klj_exts which means this is an upgraded website ! - if (empty($config['exts_upraded1_5'])) - { - $ex_exts = $SQL->query("SHOW TABLES LIKE '{$dbprefix}exts';"); - - if ($SQL->num_rows($ex_exts)) - { - $xquery = [ - 'SELECT' => 'ext, gust_size, user_size, gust_allow, user_allow', - 'FROM' => "{$dbprefix}exts", - 'WHERE' => 'gust_allow=1 OR user_allow=1', - ]; - - $xresult = $SQL->build($xquery); - - $xexts = ''; - while ($row=$SQL->fetch_array($xresult)) - { - if ($row['gust_allow']) - { - $xexts .= ($xexts == '' ? '' : ',') . "('" . $SQL->escape($row['ext']) . "', 2, " . $row['gust_size'] . ')'; - } - - if ($row['user_allow']) - { - $xexts .= ($xexts == '' ? '' : ',') . "('" . $SQL->escape($row['ext']) . "', 3, " . $row['user_size'] . ')'; - } - } - - $SQL->freeresult($result); - - //delete prev exts before adding - $query_del = [ - 'DELETE' => "{$dbprefix}groups_exts", - 'WHERE' => 'group_id=2 OR group_id=3' - ]; - - $SQL->build($query_del); - - $SQL->query("INSERT INTO {$dbprefix}groups_exts (ext, group_id, size) VALUES " . $xexts . ';'); - - add_config('exts_upraded1_5', 'done'); - } - } //delete ext? $DELETED_EXT = $GE_INFO = false; diff --git a/includes/adm/h_search.php b/includes/adm/h_search.php index 4839990..ae6186b 100755 --- a/includes/adm/h_search.php +++ b/includes/adm/h_search.php @@ -66,7 +66,7 @@ if (ip('search_file')) $ids[] = $row['filter_id']; } - $SQL->free($result); + $SQL->freeresult($result); if ($ids != '') { @@ -128,7 +128,7 @@ if (ip('search_user')) { $ids[] = $row['filter_id']; } - $SQL->free($result); + $SQL->freeresult($result); if ($ids != '') { diff --git a/includes/adm/j_plugins.php b/includes/adm/j_plugins.php index f45ab58..33c0959 100755 --- a/includes/adm/j_plugins.php +++ b/includes/adm/j_plugins.php @@ -117,7 +117,7 @@ switch ($case): } } } - $SQL->free($result); + $SQL->freeresult($result); //get available plugins $dh = opendir(PATH . KLEEJA_PLUGINS_FOLDER); @@ -332,9 +332,9 @@ switch ($case): $kleeja_plugin = []; //don't show mysql errors - if (! defined('MYSQL_NO_ERRORS')) + if (! defined('SQL_NO_ERRORS')) { - define('MYSQL_NO_ERRORS', true); + define('SQL_NO_ERRORS', true); } @include PATH . KLEEJA_PLUGINS_FOLDER . '/' . $plg_name . '/init.php'; diff --git a/includes/adm/start.php b/includes/adm/start.php index 793dc04..06b83e7 100755 --- a/includes/adm/start.php +++ b/includes/adm/start.php @@ -29,7 +29,7 @@ $files_sizes = readable_size($stat_sizes); $users_number = $stat_users; $last_del_fles = (int) $config['del_f_day'] <= 0 ? $lang['CLOSED_FEATURE'] : kleeja_date($stat_last_f_del); $php_version = isset($NO_PHPINFO) || ! function_exists('phpinfo') ? phpversion() : 'PHP ' . phpversion(); -$mysql_version = 'MySQL ' . $SQL->mysql_version(); +$mysql_version = $SQL->server_info(); $max_execution_time = function_exists('ini_get') ? @ini_get('max_execution_time') : @get_cfg_var('max_execution_time'); $upload_max_filesize = function_exists('ini_get') ? @ini_get('upload_max_filesize') : @get_cfg_var('upload_max_filesize'); $post_max_size = function_exists('ini_get') ? @ini_get('post_max_size') : @get_cfg_var('post_max_size'); diff --git a/includes/common.php b/includes/common.php index 38f26a6..1acd09f 100755 --- a/includes/common.php +++ b/includes/common.php @@ -142,7 +142,16 @@ define('K_DIR_CHMOD', defined('HAS_SUEXEC') ? (0755 & ~umask()) : 0755); include PATH . 'includes/functions_alternative.php'; include PATH . 'includes/version.php'; -include PATH . 'includes/mysqli.php'; + +if (isset($dbtype) && $dbtype == 'sqlite') +{ + include PATH . 'includes/sqlite.php'; +} +else +{ + include PATH . 'includes/mysqli.php'; +} + include PATH . 'includes/style.php'; include PATH . 'includes/usr.php'; include PATH . 'includes/pager.php'; @@ -383,11 +392,13 @@ if (defined('STOP_CAPTCHA')) is_array($plugin_run_result = Plugins::getInstance()->run('end_common', get_defined_vars())) ? extract($plugin_run_result) : null; //run hook -if (function_exists('session_register_shutdown')) -{ - session_register_shutdown(); -} -else -{ - register_shutdown_function('session_write_close'); -} + +register_shutdown_function(function() { + session_write_close(); + + $err = error_get_last(); + if(is_array($err) && ! empty($err['type']) && in_array($err['type'], [E_ERROR, E_PARSE])) + { + kleeja_log('[FATAL] ' . basename($err['file']) . ':' . $err['line'] . ' ' . $err['message']); + } +}); diff --git a/includes/functions.php b/includes/functions.php index 04f5d0f..f1b9161 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -1281,7 +1281,7 @@ function kleeja_log($text) } file_put_contents( - PATH . 'cache/kleeja_log.log', + __DIR__ . '/../cache/kleeja_log.log', date_format(date_create(), 'Y-m-d h:i:s.ua') . ' | INFO | ' . $text . PHP_EOL, FILE_APPEND | LOCK_EX ); diff --git a/includes/functions_adm.php b/includes/functions_adm.php index 9c11cfb..298485a 100755 --- a/includes/functions_adm.php +++ b/includes/functions_adm.php @@ -189,7 +189,7 @@ function get_filter($item, $filter_type = false, $just_value = false, $get_by = $result = $SQL->build($query); $v = $SQL->fetch($result); - $SQL->free($result); + $SQL->freeresult($result); if ($just_value) { diff --git a/includes/functions_display.php b/includes/functions_display.php index b6aedb2..f56ad61 100755 --- a/includes/functions_display.php +++ b/includes/functions_display.php @@ -847,6 +847,11 @@ function kleeja_date($time, $human_time = true, $format = false) if (! empty($config['time_zone']) && strpos($config['time_zone'], '/') !== false) { + if(strpos($config['time_zone'], 'Buraydah') !== false) + { + $config['time_zone'] = 'Asia/Riyadh'; + } + $timezone_offset = timezone_offset_get(new DateTimeZone($config['time_zone']), new DateTime); } else diff --git a/includes/mysqli.php b/includes/mysqli.php index bcc00ab..695f30a 100755 --- a/includes/mysqli.php +++ b/includes/mysqli.php @@ -20,7 +20,9 @@ define('SQL_LAYER', 'mysqli'); class KleejaDatabase { + /** @var mysqli */ private $connect_id = null; + /** @var mysqli_result */ private $result = null; public $dbprefix = ''; private $dbname = ''; @@ -30,10 +32,15 @@ class KleejaDatabase private $show_errors = true; - /* - * initiate the class - * with basic data - */ + /** + * connect + * + * @param string $host + * @param string $db_username + * @param string $db_password + * @param string $db_name + * @param string $dbprefix + */ public function __construct($host, $db_username, $db_password, $db_name, $dbprefix) { $port = 3306; @@ -50,7 +57,7 @@ class KleejaDatabase $this->connect_id = @mysqli_connect($host, $db_username, $db_password, $db_name, $port); //no error - if (defined('MYSQL_NO_ERRORS')) + if (defined('SQL_NO_ERRORS') || defined('MYSQL_NO_ERRORS')) { $this->show_errors = false; } @@ -79,36 +86,39 @@ class KleejaDatabase return $this->connect_id; } + public function __destruct() + { + $this->close(); + } + public function is_connected() { - return ! (is_null($this->connect_id) || empty($this->connect_id)); + return ! (is_resource($this->connect_id) || empty($this->connect_id)); } // close the connection public function close() { - if ($this->connect_id) + if (! $this->is_connected()) { - // Commit any remaining transactions - if ($this->in_transaction) - { - mysqli_commit($this->connect_id); - } - - //loggin -> close connection - kleeja_log('[Closing connection] : ' . kleeja_get_page()); - - if(! is_resource($this->connect_id)) - { - return true; - } - - return @mysqli_close($this->connect_id); + return true; } - else + + // Commit any remaining transactions + if ($this->in_transaction) { - return false; + mysqli_commit($this->connect_id); } + + //loggin -> close connection + kleeja_log('[Closing connection] : ' . kleeja_get_page()); + + if(! is_resource($this->connect_id)) + { + return true; + } + + return @mysqli_close($this->connect_id); } // encoding functions @@ -127,7 +137,7 @@ class KleejaDatabase return mysqli_character_set_name($this->connect_id); } - public function mysql_version() + public function version() { $vr = $this->query('SELECT VERSION() AS v'); $vs = $this->fetch_array($vr); @@ -135,14 +145,18 @@ class KleejaDatabase return preg_replace('/^([^-]+).*$/', '\\1', $vs); } - /* - * the query func . its so important to do - * the quries and give results + + /** + * execute a query + * + * @param string $query + * @param boolean $transaction + * @return bool */ public function query($query, $transaction = false) { //no connection - if (! $this->connect_id) + if (! $this->is_connected()) { return false; } @@ -158,7 +172,7 @@ class KleejaDatabase $srartum_sql = get_microtime(); //////////////// - if ($transaction == 1 && ! $this->in_transaction) + if ($transaction && ! $this->in_transaction) { if (! mysqli_autocommit($this->connect_id, false)) { @@ -186,7 +200,7 @@ class KleejaDatabase } else { - if ($transaction == 2 && $this->in_transaction) + if ($this->in_transaction) { $this->result = mysqli_commit($this->connect_id); } @@ -195,7 +209,7 @@ class KleejaDatabase //is there any result if ($this->result) { - if ($transaction == 2 && $this->in_transaction) + if ($this->in_transaction) { $this->in_transaction = false; @@ -220,7 +234,12 @@ class KleejaDatabase } } - // query build + /** + * build structured query ['SELECT' => ..., 'FROM' => ..., ...] + * + * @param array $query + * @return string + */ public function build($query) { $sql = ''; @@ -311,12 +330,12 @@ class KleejaDatabase return $this->query($sql); } - // free the memmory from the last results - public function free($query_id = 0) - { - return $this->freeresult($query_id); - } - + /** + * free the memmory from the last results + * + * @param integer $query_id optional + * @return bool + */ public function freeresult($query_id = 0) { if (! $query_id) @@ -335,15 +354,24 @@ class KleejaDatabase } } - /* - * if the result is an arry , - * this func is so important to order them as a array + + /** + * fetch results (alias of fetch_array) + * + * @param mysqli_result $query_id + * @return array */ public function fetch($query_id = 0) { return $this->fetch_array($query_id); } + /** + * fetch results + * + * @param mysqli_result $query_id + * @return array + */ public function fetch_array($query_id = 0) { if (! $query_id) @@ -351,12 +379,14 @@ class KleejaDatabase $query_id = $this->result; } - return $query_id ? mysqli_fetch_array($query_id, MYSQLI_ASSOC) : false; + return $query_id ? mysqli_fetch_array($query_id, MYSQLI_ASSOC) : false; } - /* - * if we have a result and we have to know - * the number of it , this is a func .. + /** + * return number of rows of result (not efficient) + * + * @param mysqli_result $query_id + * @return int */ public function num_rows($query_id = 0) { @@ -369,13 +399,22 @@ class KleejaDatabase } - // last id inserted in sql + /** + * return the id of latest inserted record + * + * @return int + */ public function insert_id() { - return $this->connect_id ? mysqli_insert_id($this->connect_id) : false; + return $this->is_connected() ? mysqli_insert_id($this->connect_id) : false; } - // clean the qurery before insert it + /** + * extra escape + * + * @param string $msg + * @return string + */ public function escape($msg) { $msg = htmlspecialchars($msg, ENT_QUOTES); @@ -384,42 +423,48 @@ class KleejaDatabase return $msg; } - // real escape .. /** - * @param string|array $msg + * escape + * @param string $msg * @return int|string */ public function real_escape($msg) { - if (is_array($msg) && ! $this->connect_id) + if (! $this->is_connected()) { - return $msg; + return false; } - if (! $this->connect_id) - { - return 0; - } - - //escaping _ made alot of problems - //return addcslashes(mysqli_real_escape_string($this->connect_id, $msg), '%_'); return mysqli_real_escape_string($this->connect_id, $msg); } - // get affected records + /** + * number of affected rows by latest action + * + * @return int + */ public function affected() { - return $this->connect_id ? mysqli_affected_rows($this->connect_id) : false; + return $this->is_connected() ? mysqli_affected_rows($this->connect_id) : false; } - // get the information of mysql server + /** + * information + * + * @return string + */ public function server_info() { - return 'MySQLi ' . $this->mysql_version; + return 'MySQLi ' . $this->version(); } - // error message func - public function error_msg($msg) + /** + * present error messages + * + * @param string $msg + * @return void + */ + private function error_msg($msg) { if (! $this->show_errors) { @@ -427,8 +472,7 @@ class KleejaDatabase return false; } - $error_no = $this->connect_id ? @mysqli_errno($this->connect_id) : @mysqli_connect_errno(); - $error_msg = $this->connect_id ? @mysqli_error($this->connect_id) : @mysqli_connect_error(); + [$error_no, $error_msg] = $this->get_error(); $error_sql = @current($this->debugr[$this->query_num+1]); //some ppl want hide their table names @@ -496,10 +540,14 @@ class KleejaDatabase exit(); } - // return last error + /** + * return last error as [code, message] + * + * @return array + */ public function get_error() { - if ($this->connect_id) + if ($this->is_connected()) { return [@mysqli_errno($this->connect_id), @mysqli_error($this->connect_id)]; } @@ -508,6 +556,6 @@ class KleejaDatabase return [@mysqli_connect_errno(), @mysqli_connect_error()]; } } -}//end of class +} endif; diff --git a/includes/plugins.php b/includes/plugins.php index 34e6684..84e0e4b 100755 --- a/includes/plugins.php +++ b/includes/plugins.php @@ -75,7 +75,7 @@ class Plugins { $this->installed_plugins[$row['plg_name']] = $row['plg_ver']; } - $SQL->free($result); + $SQL->freeresult($result); $this->load_enabled_plugins(); diff --git a/includes/sqlite.php b/includes/sqlite.php new file mode 100755 index 0000000..751bddf --- /dev/null +++ b/includes/sqlite.php @@ -0,0 +1,554 @@ +connect_id = new SQLite3(PATH . $db_name, SQLITE3_OPEN_READWRITE); + + $this->dbprefix = $dbprefix; + $this->dbname = $db_name; + + //no error + if (defined('SQL_NO_ERRORS')) + { + $this->show_errors = false; + } + + if (! $this->connect_id) + { + //loggin -> no database -> close connection + $this->close(); + $this->error_msg('We can not connect to the sqlite database, check location or existence of the SQLite dirver ...'); + return false; + } + + //connecting + kleeja_log('[Connected] : ' . kleeja_get_page()); + + + return $this->connect_id; + } + + public function __destruct() + { + $this->close(); + } + + public function is_connected() + { + return ! (is_null($this->connect_id) || empty($this->connect_id)); + } + + // close the connection + public function close() + { + if (! $this->is_connected()) + { + return true; + } + + // Commit any remaining transactions + if ($this->in_transaction) + { + $this->query('COMMIT;'); + } + + //loggin -> close connection + kleeja_log('[Closing connection] : ' . kleeja_get_page()); + + if (! is_resource($this->connect_id)) + { + return true; + } + + return @mysqli_close($this->connect_id); + } + + // encoding functions + public function set_utf8() + { + //$this->set_names('utf8'); + } + + public function set_names($charset) + { + } + + public function client_encoding() + { + } + + public function version() + { + return SQLite3::version(); + } + + /** + * execute a query + * + * @param string $query + * @param boolean $transaction + * @return bool + */ + public function query($query, $transaction = false) + { + //no connection + if (! $this->is_connected()) + { + return false; + } + + // + // Remove any pre-existing queries + // + unset($this->result); + + if(strpos($query, 'CREATE TABLE') !== false || strpos($query, 'ALTER DATABASE') !== false) + { + $sqlite_types = [ + '/AUTO_INCREMENT/i' => '', + '/VARCHAR\s?(\\([0-9]+\\))?/i' => 'TEXT', + '/COLLATE\s+([a-z0-9_]+)/i' => '', + '/(TINY|SMALL|MEDIUM|BIG)?INT\s?(\([0-9]+\))?\s?(UNSIGNED)?/i' => 'INTEGER ', + '/(TINY|MEDIUM|LONG)?TEXT/i' => 'TEXT', + '/KEY\s`?([a-z0-9_]+)`?\s\(`?([a-z0-9_]+)`?(\([0-9]+\))?\)\s?,?/i' => '', + '/\)(\s{0,4}ENGINE=([a-z0-9_]+))?(\s{0,4}DEFAULT)?(\s{0,4}CHARSET=([a-z0-9_]+))?(\s{0,4}COLLATE=([a-z0-9_]+))?(\s{0,4}AUTOINCREMENT)?(\s{0,4}=\s?1)?(\s{0,4};)?/i' => ')', + '/,\s+\)/' => ')', + '/INTEGER\s{0,4}NOT\s{0,4}NULL/i' => 'INTEGER', + ]; + + //todo extract keys and add as CREATE INDEX index_name ON table (column); + + foreach($sqlite_types as $old_type => $new_type) + { + $query = preg_replace($old_type, $new_type, $query); + } + } + + if (! empty($query)) + { + //debug + $srartum_sql = get_microtime(); + + if ($transaction && ! $this->in_transaction) + { + $this->query('BEGIN;'); + $this->in_transaction = true; + } + + $this->result = @$this->connect_id->query($query); + + //debug .. ////////////// + $this->debugr[$this->query_num+1] = [$query, sprintf('%.5f', get_microtime() - $srartum_sql)]; + //////////////// + + if (! $this->result) + { + $this->error_msg('Error In query'); + } + else + { + //let's debug it + kleeja_log('[Query] : --> ' . $query); + } + } + else + { + if ($this->in_transaction) + { + $this->result = $this->connect_id->query('COMMIT;'); + } + } + + //is there any result + if ($this->result) + { + if ($this->in_transaction) + { + $this->in_transaction = false; + + if (! $this->connect_id->query('COMMIT;')) + { + $this->connect_id->query('ROLLBACK;'); + return false; + } + } + + $this->query_num++; + return $this->result; + } + else + { + if ($this->in_transaction) + { + $this->connect_id->query('ROLLBACK;'); + $this->in_transaction = false; + } + return false; + } + } + + /** + * build structured query ['SELECT' => ..., 'FROM' => ..., ...] + * + * @param array $query + * @return string + */ + public function build($query) + { + $sql = ''; + + if (isset($query['SELECT']) && isset($query['FROM'])) + { + $sql = 'SELECT ' . $query['SELECT'] . ' FROM ' . $query['FROM']; + + if (isset($query['JOINS'])) + { + foreach ($query['JOINS'] as $cur_join) + { + $sql .= ' ' . key($cur_join) . ' ' . current($cur_join) . ' ON ' . $cur_join['ON']; + } + } + + if (! empty($query['WHERE'])) + { + $sql .= ' WHERE ' . $query['WHERE']; + } + + if (! empty($query['GROUP BY'])) + { + $sql .= ' GROUP BY ' . $query['GROUP BY']; + } + + if (! empty($query['HAVING'])) + { + $sql .= ' HAVING ' . $query['HAVING']; + } + + if (! empty($query['ORDER BY'])) + { + $sql .= ' ORDER BY ' . $query['ORDER BY']; + } + + if (! empty($query['LIMIT'])) + { + $sql .= ' LIMIT ' . $query['LIMIT']; + } + } + elseif (isset($query['INSERT'])) + { + $sql = 'INSERT INTO ' . $query['INTO']; + + if (! empty($query['INSERT'])) + { + $sql .= ' (' . $query['INSERT'] . ')'; + } + + $sql .= ' VALUES(' . $query['VALUES'] . ')'; + } + elseif (isset($query['UPDATE'])) + { + $sql = 'UPDATE ' . $query['UPDATE'] . ' SET ' . $query['SET']; + + if (! empty($query['WHERE'])) + { + $sql .= ' WHERE ' . $query['WHERE']; + } + } + elseif (isset($query['DELETE'])) + { + $sql = 'DELETE FROM ' . $query['DELETE']; + + if (! empty($query['WHERE'])) + { + $sql .= ' WHERE ' . $query['WHERE']; + } + } + elseif (isset($query['REPLACE'])) + { + $sql = 'REPLACE INTO ' . $query['INTO']; + + if (! empty($query['REPLACE'])) + { + $sql .= ' (' . $query['REPLACE'] . ')'; + } + + $sql .= ' VALUES(' . $query['VALUES'] . ')'; + } + + return $this->query($sql); + } + + /** + * free the memmory from the last results + * + * @param SQLite3Result $query_id optional + * @return bool + */ + public function freeresult($query_id = 0) + { + if (! $query_id) + { + $query_id = $this->result; + } + + if ($query_id) + { + $query_id->finalize(); + return true; + } + else + { + return false; + } + } + + /** + * fetch results (alias of fetch_array) + * + * @param SQLite3Result $query_id + * @return array + */ + public function fetch($query_id = 0) + { + return $this->fetch_array($query_id); + } + + /** + * fetch results + * + * @param SQLite3Result $query_id + * @return array + */ + public function fetch_array($query_id = 0) + { + if (! $query_id) + { + $query_id = $this->result; + } + + if ($query_id && $query_id->numColumns() > 0) + { + return $query_id->fetchArray(SQLITE3_ASSOC); + } + + return false; + } + + /** + * return number of rows of result (not efficient) + * + * @param SQLite3Result $query_id + * @return int + */ + public function num_rows($query_id = 0) + { + if (! $query_id) + { + $query_id = $this->result; + } + + if ($results = $query_id->numColumns()) + { + return $results; + } + + return false; + } + + /** + * return the id of latest inserted record + * + * @return int + */ + public function insert_id() + { + return $this->is_connected() ? $this->connect_id->lastInsertRowID() : false; + } + + /** + * extra escape + * + * @param string $msg + * @return string + */ + public function escape($msg) + { + $msg = htmlspecialchars($msg, ENT_QUOTES); + $msg = $this->real_escape($msg); + return $msg; + } + + /** + * escape + * @param string $msg + * @return int|string + */ + + public function real_escape($msg) + { + return SQLite3::escapeString($msg); + } + + /** + * number of affected rows by latest action + * + * @return int + */ + public function affected() + { + return $this->is_connected() ? $this->connect_id->changes() : false; + } + + /** + * information + * + * @return string + */ + public function server_info() + { + return 'SQLite3 ' . $this->version(); + } + + /** + * present error messages + * + * @param string $msg + * @return void + */ + private function error_msg($msg) + { + if (! $this->show_errors) + { + kleeja_log('SQLite3: ' . $msg); + return false; + } + + [$error_no, $error_msg] = $this->get_error(); + $error_sql = @current($this->debugr[$this->query_num+1]); + + //some ppl want hide their table names + if (! defined('DEV_STAGE')) + { + $error_sql = preg_replace_callback("#\s{1,3}`*{$this->dbprefix}([a-z0-9]+)`*\s{1,3}#", function($m) { + return ' ' . substr($m[1], 0, 1) . ' '; + }, $error_sql); + $error_msg = preg_replace_callback("#{$this->dbname}.{$this->dbprefix}([a-z0-9]+)#", function($m) { + return ' ' . substr($m[1], 0, 1) . ' '; + }, $error_msg); + $error_sql = preg_replace_callback("#\s{1,3}(from|update|into)\s{1,3}([a-z0-9]+)\s{1,3}#i", function($m) { + return $m[1] . ' ' . substr($m[2], 0, 1) . ' '; + }, $error_sql); + $error_msg = preg_replace_callback("#\s{1,3}(from|update|into)\s{1,3}([a-z0-9]+)\s{1,3}#i", function($m) { + return $m[1] . ' ' . substr($m[2], 0, 1) . ' '; + }, $error_msg); + $error_msg = preg_replace_callback("#\s'([^']+)'@'([^']+)'#i", function($m) { + return ' hidden@' . $m[2] . ' '; + }, $error_msg); + $error_sql = preg_replace("#password\s*=\s*'[^']+'#i", "password='hidden'", $error_sql); + } + + //is this error related to updating? + $updating_related = false; + + if (strpos($error_msg, 'Unknown column') !== false || strpos($error_msg, 'no such table') !== false) + { + $updating_related = true; + } + + header('HTTP/1.1 500 Internal Server Error'); + $error_message = '