From 61e6960b404b7032653b41ef623ac31c4a10869d Mon Sep 17 00:00:00 2001 From: kjmtsh Date: Mon, 14 Jul 2014 08:46:32 +0000 Subject: [PATCH] change the algorithm for manipulating multiple meta query git-svn-id: https://plugins.svn.wordpress.org/sqlite-integration/trunk@948014 b8457f37-d9ea-0310-8a92-e5e31aec5664 --- db.php | 63 +- functions-5-2.php | 1212 ++++++++-------- functions.php | 1108 +++++++------- install.php | 110 +- js/sqlite.js | 16 +- pdodb.class.php | 570 ++++---- pdoengine.class.php | 2180 ++++++++++++++-------------- query.class.php | 812 ++++++----- query_alter.class.php | 1096 +++++++------- query_create.class.php | 264 ++-- schema.php | 128 +- sqlite-integration.php | 467 +++--- utilities/database_maintenance.php | 642 ++++---- utilities/documentation.php | 268 ++-- utilities/patch.php | 818 +++++------ utilities/utility.php | 1966 ++++++++++++------------- 16 files changed, 5853 insertions(+), 5867 deletions(-) diff --git a/db.php b/db.php index 4c665c2..26169f4 100644 --- a/db.php +++ b/db.php @@ -1,10 +1,10 @@ * define('USE_MYSQL', true); * - * + * * If you want to use SQLite, the line below will do. Or simply removing the line will * be enough. - * + * * * define('USE_MYSQL', false); * @@ -34,13 +34,12 @@ if (!defined('ABSPATH')) { // Oh, you are not WordPress! if (defined('USE_MYSQL') && USE_MYSQL) return; function pdo_log_error($message, $data = null) { - - if (strpos($_SERVER['SCRIPT_NAME'], 'wp-admin') !== false) { - $admin_dir = ''; - } else { - $admin_dir = 'wp-admin/'; - } - die(<< @@ -84,47 +83,47 @@ if (!extension_loaded('pdo_sqlite')) { * PDODIR is SQLite Integration installed directory. */ if (defined('WP_PLUGIN_DIR')) { - define('PDODIR', WP_PLUGIN_DIR . '/sqlite-integration/'); + define('PDODIR', WP_PLUGIN_DIR . '/sqlite-integration/'); } else { - if (defined('WP_CONTENT_DIR')) { - define('PDODIR', WP_CONTENT_DIR . '/plugins/sqlite-integration/'); - } else { - define('PDODIR', ABSPATH . 'wp-content/plugins/sqlite-integration/'); - } + if (defined('WP_CONTENT_DIR')) { + define('PDODIR', WP_CONTENT_DIR . '/plugins/sqlite-integration/'); + } else { + define('PDODIR', ABSPATH . 'wp-content/plugins/sqlite-integration/'); + } } /* * FQDBDIR is a directory where the sqlite database file is placed. * If DB_DIR is defined, it is used as FQDBDIR. */ if (defined('DB_DIR')) { - if (substr(DB_DIR, -1, 1) != '/') { - define('FQDBDIR', DB_DIR . '/'); - } else { - define('FQDBDIR', DB_DIR); - } + if (substr(DB_DIR, -1, 1) != '/') { + define('FQDBDIR', DB_DIR . '/'); + } else { + define('FQDBDIR', DB_DIR); + } } else { - if (defined('WP_CONTENT_DIR')) { - define('FQDBDIR', WP_CONTENT_DIR . '/database/'); - } else { - define('FQDBDIR', ABSPATH . 'wp-content/database/'); - } + if (defined('WP_CONTENT_DIR')) { + define('FQDBDIR', WP_CONTENT_DIR . '/database/'); + } else { + define('FQDBDIR', ABSPATH . 'wp-content/database/'); + } } /* * FQDB is a database file name. If DB_FILE is defined, it is used * as FQDB. */ if ( defined('DB_FILE' )) { - define('FQDB', FQDBDIR . DB_FILE); + define('FQDB', FQDBDIR . DB_FILE); } else { - define('FQDB', FQDBDIR . '.ht.sqlite'); + define('FQDB', FQDBDIR . '.ht.sqlite'); } /* * UDF_FILE is a file that contains user defined functions. */ if (version_compare(PHP_VERSION, '5.3', '<')) { - define('UDF_FILE', PDODIR . 'functions-5-2.php'); + define('UDF_FILE', PDODIR . 'functions-5-2.php'); } elseif (version_compare(PHP_VERSION, '5.3', '>=')) { - define('UDF_FILE', PDODIR . 'functions.php'); + define('UDF_FILE', PDODIR . 'functions.php'); } require_once PDODIR . 'pdodb.class.php'; diff --git a/functions-5-2.php b/functions-5-2.php index 8d5f2a5..f30fcb3 100644 --- a/functions-5-2.php +++ b/functions-5-2.php @@ -1,11 +1,11 @@ * new PDOSQLiteUDFS(ref_to_pdo_obj); * - * + * * This automatically enables ref_to_pdo_obj to replace the function in the SQL statement * to the ones defined here. */ class PDOSQLiteUDFS { /** * Constructor - * + * * Initialize the user defined functions to the PDO object with PDO::sqliteCreateFunction(). - * + * * @param reference to PDO object $pdo */ - public function __construct(&$pdo){ - foreach ($this->functions as $f=>$t) { - $pdo->sqliteCreateFunction($f, array($this, $t)); - } - } + public function __construct(&$pdo){ + foreach ($this->functions as $f=>$t) { + $pdo->sqliteCreateFunction($f, array($this, $t)); + } + } /** * Array to associate MySQL function to the substituted one. - * + * * @var associative array */ - private $functions = array( - 'month' => 'month', - 'year' => 'year', - 'day' => 'day', - 'unix_timestamp' => 'unix_timestamp', - 'now' => 'now', - 'char_length' => 'char_length', - 'md5' => 'md5', - 'curdate' => 'curdate', - 'rand' => 'rand', - 'substring' => 'substring', - 'dayofmonth' => 'day', - 'second' => 'second', - 'minute' => 'minute', - 'hour' => 'hour', - 'date_format' => 'dateformat', - 'from_unixtime' => 'from_unixtime', - 'date_add' => 'date_add', - 'date_sub' => 'date_sub', - 'adddate' => 'date_add', - 'subdate' => 'date_sub', - 'localtime' => 'now', - 'localtimestamp' => 'now', - 'isnull' => 'isnull', - 'if' => '_if', - 'regexpp' => 'regexp', - 'concat' => 'concat', - 'field' => 'field', - 'log' => 'log', - 'least' => 'least', - 'greatest' => 'greatest', - 'get_lock' => 'get_lock', - 'release_lock' => 'release_lock', - 'ucase' => 'ucase', - 'lcase' => 'lcase', - 'inet_ntoa' => 'inet_ntoa', - 'inet_aton' => 'inet_aton', - 'datediff' => 'datediff', - 'locate' => 'locate', - 'utc_date' => 'utc_date', - 'utc_time' => 'utc_time', - 'utc_timestamp' => 'utc_timestamp', - 'version' => 'version' - ); - /** - * Method to extract the month value from the date. - * - * @param string representing the date formated as 0000-00-00. - * @return string representing the number of the month between 1 and 12. - */ - public function month($field){ - $t = strtotime($field); - return date('n', $t); - } - /** - * Method to extract the year value from the date. - * - * @param string representing the date formated as 0000-00-00. - * @return string representing the number of the year. - */ - public function year($field){ - $t = strtotime($field); - return date('Y', $t); - } + private $functions = array( + 'month' => 'month', + 'year' => 'year', + 'day' => 'day', + 'unix_timestamp' => 'unix_timestamp', + 'now' => 'now', + 'char_length' => 'char_length', + 'md5' => 'md5', + 'curdate' => 'curdate', + 'rand' => 'rand', + 'substring' => 'substring', + 'dayofmonth' => 'day', + 'second' => 'second', + 'minute' => 'minute', + 'hour' => 'hour', + 'date_format' => 'dateformat', + 'from_unixtime' => 'from_unixtime', + 'date_add' => 'date_add', + 'date_sub' => 'date_sub', + 'adddate' => 'date_add', + 'subdate' => 'date_sub', + 'localtime' => 'now', + 'localtimestamp' => 'now', + 'isnull' => 'isnull', + 'if' => '_if', + 'regexpp' => 'regexp', + 'concat' => 'concat', + 'field' => 'field', + 'log' => 'log', + 'least' => 'least', + 'greatest' => 'greatest', + 'get_lock' => 'get_lock', + 'release_lock' => 'release_lock', + 'ucase' => 'ucase', + 'lcase' => 'lcase', + 'inet_ntoa' => 'inet_ntoa', + 'inet_aton' => 'inet_aton', + 'datediff' => 'datediff', + 'locate' => 'locate', + 'utc_date' => 'utc_date', + 'utc_time' => 'utc_time', + 'utc_timestamp' => 'utc_timestamp', + 'version' => 'version' + ); + /** + * Method to extract the month value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the month between 1 and 12. + */ + public function month($field){ + $t = strtotime($field); + return date('n', $t); + } + /** + * Method to extract the year value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the year. + */ + public function year($field){ + $t = strtotime($field); + return date('Y', $t); + } /** * Method to extract the day value from the date. - * + * * @param string representing the date formated as 0000-00-00. * @return string representing the number of the day of the month from 1 and 31. */ - public function day($field){ - $t = strtotime($field); - return date('j', $t); - } - /** - * Method to return the unix timestamp. - * - * Used without an argument, it returns PHP time() function (total seconds passed - * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value - * to the timestamp. - * - * @param string representing the date formated as '0000-00-00 00:00:00'. - * @return number of unsigned integer - */ - public function unix_timestamp($field = null){ - return is_null($field) ? time() : strtotime($field); - } - /** - * Method to emulate MySQL SECOND() function. - * - * @param string representing the time formated as '00:00:00'. - * @return number of unsigned integer - */ - public function second($field){ - $t = strtotime($field); - return intval( date("s", $t) ); - } - /** - * Method to emulate MySQL MINUTE() function. - * - * @param string representing the time formated as '00:00:00'. - * @return number of unsigned integer - */ - public function minute($field){ - $t = strtotime($field); - return intval(date("i", $t)); - } - /** - * Method to emulate MySQL HOUR() function. - * - * @param string representing the time formated as '00:00:00'. - * @return number - */ - public function hour($time){ - list($hours, $minutes, $seconds) = explode(":", $time); - return intval($hours); - } - /** - * Method to emulate MySQL FROM_UNIXTIME() function. - * - * @param integer of unix timestamp - * @param string to indicate the way of formatting(optional) - * @return string formatted as '0000-00-00 00:00:00'. - */ - public function from_unixtime($field, $format=null){ - // $field is a timestamp - //convert to ISO time - $date = date("Y-m-d H:i:s", $field); - //now submit to dateformat - - return is_null($format) ? $date : $self->dateformat($date, $format); - } - /** - * Method to emulate MySQL NOW() function. - * - * @return string representing current time formatted as '0000-00-00 00:00:00'. - */ - public function now(){ - return date("Y-m-d H:i:s"); - } - /** - * Method to emulate MySQL CURDATE() function. - * - * @return string representing current time formatted as '0000-00-00'. - */ - public function curdate() { - return date("Y-m-d"); - } - /** - * Method to emulate MySQL CHAR_LENGTH() function. - * - * @param string - * @return unsigned integer for the length of the argument. - */ - public function char_length($field){ - return strlen($field); - } - /** - * Method to emulate MySQL MD5() function. - * - * @param string - * @return string of the md5 hash value of the argument. - */ - public function md5($field){ - return md5($field); - } - /** - * Method to emulate MySQL RAND() function. - * - * SQLite does have a random generator, but it is called RANDOM() and returns random - * number between -9223372036854775808 and +9223372036854775807. So we substitute it - * with PHP random generator. - * - * This function uses mt_rand() which is four times faster than rand() and returns - * the random number between 0 and 1. - * - * @return unsigned integer - */ - public function rand(){ - return mt_rand(0,1); - } - /** - * Method to emulate MySQL SUBSTRING() function. - * - * This function rewrites the function name to SQLite compatible substr(), - * which can manipulate UTF-8 characters. - * - * @param string $text - * @param integer $pos representing the start point. - * @param integer $len representing the length of the substring(optional). - * @return string - */ - public function substring($text, $pos, $len=null){ - return "substr($text, $pos, $len)"; - } - /** - * Method to emulate MySQL DATEFORMAT() function. - * - * @param string date formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. - * @param string $format - * @return string formatted according to $format - */ - public function dateformat($date, $format){ - $mysql_php_dateformats = array ( '%a' => 'D', '%b' => 'M', '%c' => 'n', '%D' => 'jS', '%d' => 'd', '%e' => 'j', '%H' => 'H', '%h' => 'h', '%I' => 'h', '%i' => 'i', '%j' => 'z', '%k' => 'G', '%l' => 'g', '%M' => 'F', '%m' => 'm', '%p' => 'A', '%r' => 'h:i:s A', '%S' => 's', '%s' => 's', '%T' => 'H:i:s', '%U' => 'W', '%u' => 'W', '%V' => 'W', '%v' => 'W', '%W' => 'l', '%w' => 'w', '%X' => 'Y', '%x' => 'o', '%Y' => 'Y', '%y' => 'y', ); - $t = strtotime($date); - $format = strtr($format, $mysql_php_dateformats); - $output = date($format, $t); - return $output; - } - /** - * Method to emulate MySQL DATE_ADD() function. - * - * This function adds the time value of $interval expression to $date. - * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). - * It is calculated in the private function deriveInterval(). - * - * @param string $date representing the start date. - * @param string $interval representing the expression of the time to add. - * @return string date formated as '0000-00-00 00:00:00'. - */ - public function date_add($date, $interval) { - $interval = $this->deriveInterval($interval); - switch (strtolower($date)) { - case "curdate()": - $objDate = new Datetime($this->curdate()); - $objDate->add(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d"); - break; - case "now()": - $objDate = new Datetime($this->now()); - $objDate->add(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - break; - default: - $objDate = new Datetime($date); - $objDate->add(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - } - return $returnval; - } - /** - * Method to emulate MySQL DATE_SUB() function. - * - * This function substracts the time value of $interval expression from $date. - * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). - * It is calculated in the private function deriveInterval(). - * - * @param string $date representing the start date. - * @param string $interval representing the expression of the time to substract. - * @return string date formated as '0000-00-00 00:00:00'. - */ - public function date_sub($date, $interval) { - $interval = $this->deriveInterval($interval); - switch (strtolower($date)) { - case "curdate()": - $objDate = new Datetime($this->curdate()); - $objDate->sub(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d"); - break; - case "now()": - $objDate = new Datetime($this->now()); - $objDate->sub(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - break; - default: - $objDate = new Datetime($date); - $objDate->sub(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - } - return $returnval; - } - /** - * Method to calculate the interval time between two dates value. - * - * @access private - * @param string $interval white space separated expression. - * @return string representing the time to add or substract. - */ + public function day($field){ + $t = strtotime($field); + return date('j', $t); + } + /** + * Method to return the unix timestamp. + * + * Used without an argument, it returns PHP time() function (total seconds passed + * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value + * to the timestamp. + * + * @param string representing the date formated as '0000-00-00 00:00:00'. + * @return number of unsigned integer + */ + public function unix_timestamp($field = null){ + return is_null($field) ? time() : strtotime($field); + } + /** + * Method to emulate MySQL SECOND() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ + public function second($field){ + $t = strtotime($field); + return intval( date("s", $t) ); + } + /** + * Method to emulate MySQL MINUTE() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ + public function minute($field){ + $t = strtotime($field); + return intval(date("i", $t)); + } + /** + * Method to emulate MySQL HOUR() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number + */ + public function hour($time){ + list($hours, $minutes, $seconds) = explode(":", $time); + return intval($hours); + } + /** + * Method to emulate MySQL FROM_UNIXTIME() function. + * + * @param integer of unix timestamp + * @param string to indicate the way of formatting(optional) + * @return string formatted as '0000-00-00 00:00:00'. + */ + public function from_unixtime($field, $format=null){ + // $field is a timestamp + //convert to ISO time + $date = date("Y-m-d H:i:s", $field); + //now submit to dateformat + return is_null($format) ? $date : $self->dateformat($date, $format); + } + /** + * Method to emulate MySQL NOW() function. + * + * @return string representing current time formatted as '0000-00-00 00:00:00'. + */ + public function now(){ + return date("Y-m-d H:i:s"); + } + /** + * Method to emulate MySQL CURDATE() function. + * + * @return string representing current time formatted as '0000-00-00'. + */ + public function curdate() { + return date("Y-m-d"); + } + /** + * Method to emulate MySQL CHAR_LENGTH() function. + * + * @param string + * @return unsigned integer for the length of the argument. + */ + public function char_length($field){ + return strlen($field); + } + /** + * Method to emulate MySQL MD5() function. + * + * @param string + * @return string of the md5 hash value of the argument. + */ + public function md5($field){ + return md5($field); + } + /** + * Method to emulate MySQL RAND() function. + * + * SQLite does have a random generator, but it is called RANDOM() and returns random + * number between -9223372036854775808 and +9223372036854775807. So we substitute it + * with PHP random generator. + * + * This function uses mt_rand() which is four times faster than rand() and returns + * the random number between 0 and 1. + * + * @return unsigned integer + */ + public function rand(){ + return mt_rand(0,1); + } + /** + * Method to emulate MySQL SUBSTRING() function. + * + * This function rewrites the function name to SQLite compatible substr(), + * which can manipulate UTF-8 characters. + * + * @param string $text + * @param integer $pos representing the start point. + * @param integer $len representing the length of the substring(optional). + * @return string + */ + public function substring($text, $pos, $len=null){ + return "substr($text, $pos, $len)"; + } + /** + * Method to emulate MySQL DATEFORMAT() function. + * + * @param string date formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. + * @param string $format + * @return string formatted according to $format + */ + public function dateformat($date, $format){ + $mysql_php_dateformats = array ( '%a' => 'D', '%b' => 'M', '%c' => 'n', '%D' => 'jS', '%d' => 'd', '%e' => 'j', '%H' => 'H', '%h' => 'h', '%I' => 'h', '%i' => 'i', '%j' => 'z', '%k' => 'G', '%l' => 'g', '%M' => 'F', '%m' => 'm', '%p' => 'A', '%r' => 'h:i:s A', '%S' => 's', '%s' => 's', '%T' => 'H:i:s', '%U' => 'W', '%u' => 'W', '%V' => 'W', '%v' => 'W', '%W' => 'l', '%w' => 'w', '%X' => 'Y', '%x' => 'o', '%Y' => 'Y', '%y' => 'y', ); + $t = strtotime($date); + $format = strtr($format, $mysql_php_dateformats); + $output = date($format, $t); + return $output; + } + /** + * Method to emulate MySQL DATE_ADD() function. + * + * This function adds the time value of $interval expression to $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to add. + * @return string date formated as '0000-00-00 00:00:00'. + */ + public function date_add($date, $interval) { + $interval = $this->deriveInterval($interval); + switch (strtolower($date)) { + case "curdate()": + $objDate = new Datetime($this->curdate()); + $objDate->add(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d"); + break; + case "now()": + $objDate = new Datetime($this->now()); + $objDate->add(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + break; + default: + $objDate = new Datetime($date); + $objDate->add(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + } + return $returnval; + } + /** + * Method to emulate MySQL DATE_SUB() function. + * + * This function substracts the time value of $interval expression from $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to substract. + * @return string date formated as '0000-00-00 00:00:00'. + */ + public function date_sub($date, $interval) { + $interval = $this->deriveInterval($interval); + switch (strtolower($date)) { + case "curdate()": + $objDate = new Datetime($this->curdate()); + $objDate->sub(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d"); + break; + case "now()": + $objDate = new Datetime($this->now()); + $objDate->sub(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + break; + default: + $objDate = new Datetime($date); + $objDate->sub(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + } + return $returnval; + } + /** + * Method to calculate the interval time between two dates value. + * + * @access private + * @param string $interval white space separated expression. + * @return string representing the time to add or substract. + */ private function deriveInterval($interval){ $interval = trim(substr(trim($interval), 8)); $parts = explode(' ', $interval); @@ -338,77 +337,68 @@ class PDOSQLiteUDFS { case "week": case "month": case "year": - if (intval($_parts[0]) > 1){ - $type .= 's'; - } - return "$_parts[0] $_parts[1]"; - break; + if (intval($_parts[0]) > 1){ + $type .= 's'; + } + return "$_parts[0] $_parts[1]"; case "minute_second": - list($minutes, $seconds) = explode (':', $_parts[0]); - $minutes = intval($minutes); - $seconds = intval($seconds); - $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; - $seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second"; - return "$minutes $seconds"; - break; - + list($minutes, $seconds) = explode (':', $_parts[0]); + $minutes = intval($minutes); + $seconds = intval($seconds); + $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; + $seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second"; + return "$minutes $seconds"; case "hour_second": - list($hours, $minutes, $seconds) = explode (':', $_parts[0]); - $hours = intval($hours); - $minutes = intval($minutes); - $seconds = intval($seconds); - $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; - $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; - $seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second"; - return "$hours $minutes $seconds"; - break; + list($hours, $minutes, $seconds) = explode (':', $_parts[0]); + $hours = intval($hours); + $minutes = intval($minutes); + $seconds = intval($seconds); + $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; + $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; + $seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second"; + return "$hours $minutes $seconds"; case "hour_minute": - list($hours, $minutes) = explode (':', $_parts[0]); - $hours = intval($hours); - $minutes = intval($minutes); - $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; - $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; - return "$hours $minutes"; - break; + list($hours, $minutes) = explode (':', $_parts[0]); + $hours = intval($hours); + $minutes = intval($minutes); + $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; + $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; + return "$hours $minutes"; case "day_second": - $days = intval($_parts[0]); - list($hours, $minutes, $seconds) = explode (':', $_parts[1]); - $hours = intval($hours); - $minutes = intval($minutes); - $seconds = intval($seconds); - $days = $days > 1 ? "$days days" : "$days day"; - $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; - $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; - $seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second"; - return "$days $hours $minutes $seconds"; - break; + $days = intval($_parts[0]); + list($hours, $minutes, $seconds) = explode (':', $_parts[1]); + $hours = intval($hours); + $minutes = intval($minutes); + $seconds = intval($seconds); + $days = $days > 1 ? "$days days" : "$days day"; + $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; + $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; + $seconds = ($seconds > 1) ? "$seconds seconds" : "$seconds second"; + return "$days $hours $minutes $seconds"; case "day_minute": - $days = intval($_parts[0]); - list($hours, $minutes) = explode (':', $_parts[1]); - $hours = intval($hours); - $minutes = intval($minutes); - $days = $days > 1 ? "$days days" : "$days day"; - $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; - $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; - return "$days $hours $minutes"; - break; + $days = intval($_parts[0]); + list($hours, $minutes) = explode (':', $_parts[1]); + $hours = intval($hours); + $minutes = intval($minutes); + $days = $days > 1 ? "$days days" : "$days day"; + $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; + $minutes = ($minutes > 1) ? "$minutes minutes" : "$minutes minute"; + return "$days $hours $minutes"; case "day_hour": - $days = intval($_parts[0]); - $hours = intval($_parts[1]); - $days = $days > 1 ? "$days days" : "$days day"; - $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; - return "$days $hours"; - break; + $days = intval($_parts[0]); + $hours = intval($_parts[1]); + $days = $days > 1 ? "$days days" : "$days day"; + $hours = ($hours > 1) ? "$hours hours" : "$hours hour"; + return "$days $hours"; case "year_month": - list($years, $months) = explode ('-', $_parts[0]); - $years = intval($years); - $months = intval($months); - $years = ($years > 1) ? "$years years" : "$years year"; - $months = ($months > 1) ? "$months months": "$months month"; - return "$years $months"; - break; - default: - return false; + list($years, $months) = explode ('-', $_parts[0]); + $years = intval($years); + $months = intval($months); + $years = ($years > 1) ? "$years years" : "$years year"; + $months = ($months > 1) ? "$months months": "$months month"; + return "$years $months"; + default: + return false; } } /** @@ -417,262 +407,262 @@ class PDOSQLiteUDFS { * @param string $date formatted as unix time. * @return string formatted as '0000-00-00'. */ - public function date($date){ - return date("Y-m-d", strtotime($date)); - } - /** - * Method to emulate MySQL ISNULL() function. - * - * This function returns true if the argument is null, and true if not. - * - * @param various types $field - * @return boolean - */ - public function isnull($field){ - return is_null($field); - } - /** - * Method to emulate MySQL IF() function. - * - * As 'IF' is a reserved word for PHP, function name must be changed. - * - * @param unknonw $expression the statement to be evaluated as true or false. - * @param unknown $true statement or value returned if $expression is true. - * @param unknown $false statement or value returned if $expression is false. - * @return unknown - */ - public function _if($expression, $true, $false){ - return ($expression == true) ? $true : $false; - } - /** - * Method to emulate MySQL REGEXP() function. - * - * @param string $field haystack - * @param string $pattern: regular expression to match. - * @return integer 1 if matched, 0 if not matched. - */ - public function regexp($field, $pattern){ - $pattern = str_replace('/', '\/', $pattern); - $pattern = "/" . $pattern ."/i"; - return preg_match ($pattern, $field); - } - /** - * Method to emulate MySQL CONCAT() function. - * - * SQLite does have CONCAT() function, but it has a different syntax from MySQL. - * So this function must be manipulated here. - * - * @param string - * @return NULL if the argument is null | string conatenated if the argument is given. - */ - public function concat() { - $returnValue = ""; - $argsNum = func_num_args(); - $argsList = func_get_args(); - for ($i = 0; $i < $argsNum; $i++) { - if (is_null($argsList[$i])) { - return null; - } - $returnValue .= $argsList[$i]; - } - return $returnValue; - } - /** - * Method to emulate MySQL FIELD() function. - * - * This function gets the list argument and compares the first item to all the others. - * If the same value is found, it returns the position of that value. If not, it - * returns 0. - * - * @param variable number of string, integer or double - * @return unsigned integer - */ - public function field() { - $numArgs = func_num_args(); - if ($numArgs < 2 or is_null(func_get_arg(0))) { - return 0; - } - $arr = func_get_args(); - $searchString = strtolower(array_shift($arr)); - for ($i = 0; $i < $numArgs-1; $i++) { - if ($searchString === strtolower($arr[$i])) return $i + 1; - } - return 0; - } - /** - * Method to emulate MySQL LOG() function. - * - * Used with one argument, it returns the natural logarithm of X. - * - * LOG(X) - * - * Used with two arguments, it returns the natural logarithm of X base B. - * - * LOG(B, X) - * - * In this case, it returns the value of log(X) / log(B). - * - * Used without an argument, it returns false. This returned value will be - * rewritten to 0, because SQLite doesn't understand true/false value. - * - * @param integer representing the base of the logarithm, which is optional. - * @param double value to turn into logarithm. - * @return double | NULL - */ - public function log() { - $numArgs = func_num_args(); - if ($numArgs == 1) { - $arg1 = func_get_arg(0); - return log($arg1); - } else if ($numArgs == 2) { - $arg1 = func_get_arg(0); - $arg2 = func_get_arg(1); - return log($arg1)/log($arg2); - } else { - return null; - } - } - /** - * Method to emulate MySQL LEAST() function. - * - * This function rewrites the function name to SQLite compatible function name. - * - * @return mixed - */ - public function least() { - $arg_list = func_get_args(); - return "min($arg_list)"; - } - /** - * Method to emulate MySQL GREATEST() function. - * - * This function rewrites the function name to SQLite compatible function name. - * - * @return mixed - */ - public function greatest() { - $arg_list = func_get_args(); - return "max($arg_list)"; - } - /** - * Method to dummy out MySQL GET_LOCK() function. - * - * This function is meaningless in SQLite, so we do nothing. - * - * @param string $name - * @param integer $timeout - * @return string - */ - public function get_lock($name, $timeout) { - return '1=1'; - } - /** - * Method to dummy out MySQL RELEASE_LOCK() function. - * - * This function is meaningless in SQLite, so we do nothing. - * - * @param string $name - * @return string - */ - public function release_lock($name) { - return '1=1'; - } - /** - * Method to emulate MySQL UCASE() function. - * - * This is MySQL alias for upper() function. This function rewrites it - * to SQLite compatible name upper(). - * - * @param string - * @return string SQLite compatible function name. - */ - public function ucase($string) { - return "upper($string)"; - } - /** - * Method to emulate MySQL LCASE() function. - * - * This is MySQL alias for lower() function. This function rewrites it - * to SQLite compatible name lower(). - * - * @param string - * @return string SQLite compatible function name. - */ - public function lcase($string) { - return "lower($string)"; - } - /** - * Method to emulate MySQL INET_NTOA() function. - * - * This function gets 4 or 8 bytes integer and turn it into the network address. - * - * @param unsigned long integer - * @return string - */ - public function inet_ntoa($num) { - return long2ip($num); - } - /** - * Method to emulate MySQL INET_ATON() function. - * - * This function gets the network address and turns it into integer. - * - * @param string - * @return unsigned long integer - */ - public function inet_aton($addr) { - $int_data = ip2long($addr); - $unsigned_int_data = sprintf('%u', $address); - return $unsigned_int_data; - } - /** - * Method to emulate MySQL DATEDIFF() function. - * - * This function compares two dates value and returns the difference. - * - * PHP 5.3.2 has a serious bug in DateTime::diff(). So if users' PHP is that version, - * we don't use that function. See https://bugs.php.net/bug.php?id=51184. - * - * @param string start - * @param string end - * @return string - */ - public function datediff($start, $end) { - $start_date = strtotime($start); - $end_date = strtotime($end); - $interval = floor(($end_date - $start_date)/(3600*24)); - return $interval; - } - /** - * Method to emulate MySQL LOCATE() function. - * - * This function returns the position if $substr is found in $str. If not, - * it returns 0. If mbstring extension is loaded, mb_strpos() function is - * used. - * - * @param string needle - * @param string haystack - * @param integer position - * @return integer - */ - public function locate($substr, $str, $pos = 0) { - if (!extension_loaded('mbstring')) { - if (($val = stros($str, $substr, $pos)) !== false) { - return $val + 1; - } else { - return 0; - } - } else { - if (($val = mb_strpos($str, $substr, $pos)) !== false) { - return $val + 1; - } else { - return 0; - } - } - } + public function date($date){ + return date("Y-m-d", strtotime($date)); + } + /** + * Method to emulate MySQL ISNULL() function. + * + * This function returns true if the argument is null, and true if not. + * + * @param various types $field + * @return boolean + */ + public function isnull($field){ + return is_null($field); + } + /** + * Method to emulate MySQL IF() function. + * + * As 'IF' is a reserved word for PHP, function name must be changed. + * + * @param unknonw $expression the statement to be evaluated as true or false. + * @param unknown $true statement or value returned if $expression is true. + * @param unknown $false statement or value returned if $expression is false. + * @return unknown + */ + public function _if($expression, $true, $false){ + return ($expression == true) ? $true : $false; + } + /** + * Method to emulate MySQL REGEXP() function. + * + * @param string $field haystack + * @param string $pattern: regular expression to match. + * @return integer 1 if matched, 0 if not matched. + */ + public function regexp($field, $pattern){ + $pattern = str_replace('/', '\/', $pattern); + $pattern = "/" . $pattern ."/i"; + return preg_match ($pattern, $field); + } + /** + * Method to emulate MySQL CONCAT() function. + * + * SQLite does have CONCAT() function, but it has a different syntax from MySQL. + * So this function must be manipulated here. + * + * @param string + * @return NULL if the argument is null | string conatenated if the argument is given. + */ + public function concat() { + $returnValue = ""; + $argsNum = func_num_args(); + $argsList = func_get_args(); + for ($i = 0; $i < $argsNum; $i++) { + if (is_null($argsList[$i])) { + return null; + } + $returnValue .= $argsList[$i]; + } + return $returnValue; + } + /** + * Method to emulate MySQL FIELD() function. + * + * This function gets the list argument and compares the first item to all the others. + * If the same value is found, it returns the position of that value. If not, it + * returns 0. + * + * @param variable number of string, integer or double + * @return unsigned integer + */ + public function field() { + $numArgs = func_num_args(); + if ($numArgs < 2 or is_null(func_get_arg(0))) { + return 0; + } + $arr = func_get_args(); + $searchString = strtolower(array_shift($arr)); + for ($i = 0; $i < $numArgs-1; $i++) { + if ($searchString === strtolower($arr[$i])) return $i + 1; + } + return 0; + } + /** + * Method to emulate MySQL LOG() function. + * + * Used with one argument, it returns the natural logarithm of X. + * + * LOG(X) + * + * Used with two arguments, it returns the natural logarithm of X base B. + * + * LOG(B, X) + * + * In this case, it returns the value of log(X) / log(B). + * + * Used without an argument, it returns false. This returned value will be + * rewritten to 0, because SQLite doesn't understand true/false value. + * + * @param integer representing the base of the logarithm, which is optional. + * @param double value to turn into logarithm. + * @return double | NULL + */ + public function log() { + $numArgs = func_num_args(); + if ($numArgs == 1) { + $arg1 = func_get_arg(0); + return log($arg1); + } else if ($numArgs == 2) { + $arg1 = func_get_arg(0); + $arg2 = func_get_arg(1); + return log($arg1)/log($arg2); + } else { + return null; + } + } + /** + * Method to emulate MySQL LEAST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ + public function least() { + $arg_list = func_get_args(); + return "min($arg_list)"; + } + /** + * Method to emulate MySQL GREATEST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ + public function greatest() { + $arg_list = func_get_args(); + return "max($arg_list)"; + } + /** + * Method to dummy out MySQL GET_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * + * @param string $name + * @param integer $timeout + * @return string + */ + public function get_lock($name, $timeout) { + return '1=1'; + } + /** + * Method to dummy out MySQL RELEASE_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * + * @param string $name + * @return string + */ + public function release_lock($name) { + return '1=1'; + } + /** + * Method to emulate MySQL UCASE() function. + * + * This is MySQL alias for upper() function. This function rewrites it + * to SQLite compatible name upper(). + * + * @param string + * @return string SQLite compatible function name. + */ + public function ucase($string) { + return "upper($string)"; + } + /** + * Method to emulate MySQL LCASE() function. + * + * This is MySQL alias for lower() function. This function rewrites it + * to SQLite compatible name lower(). + * + * @param string + * @return string SQLite compatible function name. + */ + public function lcase($string) { + return "lower($string)"; + } + /** + * Method to emulate MySQL INET_NTOA() function. + * + * This function gets 4 or 8 bytes integer and turn it into the network address. + * + * @param unsigned long integer + * @return string + */ + public function inet_ntoa($num) { + return long2ip($num); + } + /** + * Method to emulate MySQL INET_ATON() function. + * + * This function gets the network address and turns it into integer. + * + * @param string + * @return unsigned long integer + */ + public function inet_aton($addr) { + $int_data = ip2long($addr); + $unsigned_int_data = sprintf('%u', $address); + return $unsigned_int_data; + } + /** + * Method to emulate MySQL DATEDIFF() function. + * + * This function compares two dates value and returns the difference. + * + * PHP 5.3.2 has a serious bug in DateTime::diff(). So if users' PHP is that version, + * we don't use that function. See https://bugs.php.net/bug.php?id=51184. + * + * @param string start + * @param string end + * @return string + */ + public function datediff($start, $end) { + $start_date = strtotime($start); + $end_date = strtotime($end); + $interval = floor(($end_date - $start_date)/(3600*24)); + return $interval; + } + /** + * Method to emulate MySQL LOCATE() function. + * + * This function returns the position if $substr is found in $str. If not, + * it returns 0. If mbstring extension is loaded, mb_strpos() function is + * used. + * + * @param string needle + * @param string haystack + * @param integer position + * @return integer + */ + public function locate($substr, $str, $pos = 0) { + if (!extension_loaded('mbstring')) { + if (($val = stros($str, $substr, $pos)) !== false) { + return $val + 1; + } else { + return 0; + } + } else { + if (($val = mb_strpos($str, $substr, $pos)) !== false) { + return $val + 1; + } else { + return 0; + } + } + } /** * Method to return GMT date in the string format. - * + * * @param none * @return string formatted GMT date 'dddd-mm-dd' */ @@ -681,7 +671,7 @@ class PDOSQLiteUDFS { } /** * Method to return GMT time in the string format. - * + * * @param none * @return string formatted GMT time '00:00:00' */ @@ -690,7 +680,7 @@ class PDOSQLiteUDFS { } /** * Method to return GMT time stamp in the string format. - * + * * @param none * @return string formatted GMT timestamp 'yyyy-mm-dd 00:00:00' */ @@ -699,16 +689,16 @@ class PDOSQLiteUDFS { } /** * Method to return MySQL version. - * + * * This function only returns the current newest version number of MySQL, * because it is meaningless for SQLite database. - * + * * @param none * @return string representing the version number: major_version.minor_version */ public function version() { -// global $required_mysql_version; -// return $required_mysql_version; + //global $required_mysql_version; + //return $required_mysql_version; return '5.5'; } } diff --git a/functions.php b/functions.php index 7dd6247..f9f3b28 100644 --- a/functions.php +++ b/functions.php @@ -1,11 +1,11 @@ * new PDOSQLiteUDFS(ref_to_pdo_obj); * - * + * * This automatically enables ref_to_pdo_obj to replace the function in the SQL statement * to the ones defined here. */ class PDOSQLiteUDFS { /** * The class constructor - * + * * Initializes the use defined functions to PDO object with PDO::sqliteCreateFunction(). - * + * * @param reference to PDO object $pdo */ - public function __construct(&$pdo){ - foreach ($this->functions as $f=>$t) { - $pdo->sqliteCreateFunction($f, array($this, $t)); - } - } + public function __construct(&$pdo){ + foreach ($this->functions as $f=>$t) { + $pdo->sqliteCreateFunction($f, array($this, $t)); + } + } /** * array to define MySQL function => function defined with PHP. - * + * * Replaced functions must be public. - * + * * @var associative array */ - private $functions = array( - 'month' => 'month', - 'year' => 'year', - 'day' => 'day', - 'unix_timestamp' => 'unix_timestamp', - 'now' => 'now', - 'char_length' => 'char_length', - 'md5' => 'md5', - 'curdate' => 'curdate', - 'rand' => 'rand', - 'substring' => 'substring', - 'dayofmonth' => 'day', - 'second' => 'second', - 'minute' => 'minute', - 'hour' => 'hour', - 'date_format' => 'dateformat', - 'from_unixtime' => 'from_unixtime', - 'date_add' => 'date_add', - 'date_sub' => 'date_sub', - 'adddate' => 'date_add', - 'subdate' => 'date_sub', - 'localtime' => 'now', - 'localtimestamp' => 'now', - 'isnull' => 'isnull', - 'if' => '_if', - 'regexpp' => 'regexp', - 'concat' => 'concat', - 'field' => 'field', - 'log' => 'log', - 'least' => 'least', - 'greatest' => 'greatest', - 'get_lock' => 'get_lock', - 'release_lock' => 'release_lock', - 'ucase' => 'ucase', - 'lcase' => 'lcase', - 'inet_ntoa' => 'inet_ntoa', - 'inet_aton' => 'inet_aton', - 'datediff' => 'datediff', - 'locate' => 'locate', - 'utc_date' => 'utc_date', - 'utc_time' => 'utc_time', - 'utc_timestamp' => 'utc_timestamp', - 'version' => 'version' - ); - /** - * Method to extract the month value from the date. - * - * @param string representing the date formated as 0000-00-00. - * @return string representing the number of the month between 1 and 12. - */ - public function month($field){ - $t = strtotime($field); - return date('n', $t); - } - /** - * Method to extract the year value from the date. - * - * @param string representing the date formated as 0000-00-00. - * @return string representing the number of the year. - */ - public function year($field){ - $t = strtotime($field); - return date('Y', $t); - } - /** - * Method to extract the day value from the date. - * - * @param string representing the date formated as 0000-00-00. - * @return string representing the number of the day of the month from 1 and 31. - */ - public function day($field){ - $t = strtotime($field); - return date('j', $t); - } - /** - * Method to return the unix timestamp. - * - * Used without an argument, it returns PHP time() function (total seconds passed - * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value - * to the timestamp. - * - * @param string representing the date formated as '0000-00-00 00:00:00'. - * @return number of unsigned integer - */ - public function unix_timestamp($field = null){ - return is_null($field) ? time() : strtotime($field); - } - /** - * Method to emulate MySQL SECOND() function. - * - * @param string representing the time formated as '00:00:00'. - * @return number of unsigned integer - */ - public function second($field){ - $t = strtotime($field); - return intval( date("s", $t) ); - } - /** - * Method to emulate MySQL MINUTE() function. - * - * @param string representing the time formated as '00:00:00'. - * @return number of unsigned integer - */ - public function minute($field){ - $t = strtotime($field); - return intval(date("i", $t)); - } - /** - * Method to emulate MySQL HOUR() function. - * - * @param string representing the time formated as '00:00:00'. - * @return number - */ - public function hour($time){ - list($hours, $minutes, $seconds) = explode(":", $time); - return intval($hours); - } - /** - * Method to emulate MySQL FROM_UNIXTIME() function. - * - * @param integer of unix timestamp - * @param string to indicate the way of formatting(optional) - * @return string formatted as '0000-00-00 00:00:00'. - */ - public function from_unixtime($field, $format=null){ - // $field is a timestamp - //convert to ISO time - $date = date("Y-m-d H:i:s", $field); - //now submit to dateformat - return is_null($format) ? $date : $self->dateformat($date, $format); - } - /** - * Method to emulate MySQL NOW() function. - * - * @return string representing current time formatted as '0000-00-00 00:00:00'. - */ - public function now(){ - return date("Y-m-d H:i:s"); - } - /** - * Method to emulate MySQL CURDATE() function. - * - * @return string representing current time formatted as '0000-00-00'. - */ - public function curdate() { - return date("Y-m-d"); - } - /** - * Method to emulate MySQL CHAR_LENGTH() function. - * - * @param string - * @return unsigned integer for the length of the argument. - */ - public function char_length($field){ - return strlen($field); - } - /** - * Method to emulate MySQL MD5() function. - * - * @param string - * @return string of the md5 hash value of the argument. - */ - public function md5($field){ - return md5($field); - } - /** - * Method to emulate MySQL RAND() function. - * - * SQLite does have a random generator, but it is called RANDOM() and returns random - * number between -9223372036854775808 and +9223372036854775807. So we substitute it - * with PHP random generator. - * - * This function uses mt_rand() which is four times faster than rand() and returns - * the random number between 0 and 1. - * - * @return unsigned integer - */ - public function rand(){ - return mt_rand(0, 1); - } - /** - * Method to emulate MySQL SUBSTRING() function. - * - * This function rewrites the function name to SQLite compatible substr(), - * which can manipulate UTF-8 characters. - * - * @param string $text - * @param integer $pos representing the start point. - * @param integer $len representing the length of the substring(optional). - * @return string - */ - public function substring($text, $pos, $len=null){ - return "substr($text, $pos, $len)"; - } - /** - * Method to emulate MySQL DATEFORMAT() function. - * - * @param string date formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. - * @param string $format - * @return string formatted according to $format - */ - public function dateformat($date, $format){ - $mysql_php_dateformats = array ( '%a' => 'D', '%b' => 'M', '%c' => 'n', '%D' => 'jS', '%d' => 'd', '%e' => 'j', '%H' => 'H', '%h' => 'h', '%I' => 'h', '%i' => 'i', '%j' => 'z', '%k' => 'G', '%l' => 'g', '%M' => 'F', '%m' => 'm', '%p' => 'A', '%r' => 'h:i:s A', '%S' => 's', '%s' => 's', '%T' => 'H:i:s', '%U' => 'W', '%u' => 'W', '%V' => 'W', '%v' => 'W', '%W' => 'l', '%w' => 'w', '%X' => 'Y', '%x' => 'o', '%Y' => 'Y', '%y' => 'y', ); - $t = strtotime($date); - $format = strtr($format, $mysql_php_dateformats); - $output = date($format, $t); - return $output; - } - /** - * Method to emulate MySQL DATE_ADD() function. - * - * This function adds the time value of $interval expression to $date. - * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). - * It is calculated in the private function deriveInterval(). - * - * @param string $date representing the start date. - * @param string $interval representing the expression of the time to add. - * @return string date formated as '0000-00-00 00:00:00'. - */ - public function date_add($date, $interval) { - $interval = $this->deriveInterval($interval); - switch (strtolower($date)) { - case "curdate()": - $objDate = new Datetime($this->curdate()); - $objDate->add(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d"); - break; - case "now()": - $objDate = new Datetime($this->now()); - $objDate->add(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - break; - default: - $objDate = new Datetime($date); - $objDate->add(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - } - return $returnval; - } - /** - * Method to emulate MySQL DATE_SUB() function. - * - * This function substracts the time value of $interval expression from $date. - * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). - * It is calculated in the private function deriveInterval(). - * - * @param string $date representing the start date. - * @param string $interval representing the expression of the time to substract. - * @return string date formated as '0000-00-00 00:00:00'. - */ - public function date_sub($date, $interval) { - $interval = $this->deriveInterval($interval); - switch (strtolower($date)) { - case "curdate()": - $objDate = new Datetime($this->curdate()); - $objDate->sub(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d"); - break; - case "now()": - $objDate = new Datetime($this->now()); - $objDate->sub(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - break; - default: - $objDate = new Datetime($date); - $objDate->sub(new DateInterval($interval)); - $returnval = $objDate->format("Y-m-d H:i:s"); - } - return $returnval; - } - /** - * Method to calculate the interval time between two dates value. - * - * @access private - * @param string $interval white space separated expression. - * @return string representing the time to add or substract. - */ - private function deriveInterval($interval) { - $interval = trim(substr(trim($interval), 8)); - $parts = explode(' ', $interval); - foreach ($parts as $part) { - if (!empty($part)) { - $_parts[] = $part; - } - } - $type = strtolower(end($_parts)); - switch ($type) { - case "second": $unit = 'S'; return 'PT' . $_parts[0] . $unit; break; - case "minute": $unit = 'M'; return 'PT' . $_parts[0] . $unit; break; - case "hour": $unit = 'H'; return 'PT' . $_parts[0] . $unit; break; - case "day": $unit = 'D'; return 'P' . $_parts[0] . $unit; break; - case "week": $unit = 'W'; return 'P' . $_parts[0] . $unit; break; - case "month": $unit = 'M'; return 'P' . $_parts[0] . $unit; break; - case "year": $unit = 'Y'; return 'P' . $_parts[0] . $unit; break; - case "minute_second": - list($minutes, $seconds) = explode(':', $_parts[0]); - return 'PT' . $minutes . 'M' . $seconds . 'S'; - break; - case "hour_second": - list($hours, $minutes, $seconds) = explode (':', $_parts[0]); - return 'PT' . $hours . 'H' . $minutes . 'M' . $seconds . 'S'; - break; - case "hour_minute": - list($hours, $minutes) = explode (':', $_parts[0]); - return 'PT' . $hours . 'H' . $minutes . 'M'; - break; - case "day_second": - $days = intval($_parts[0]); - list($hours, $minutes, $seconds) = explode (':', $_parts[1]); - return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M' . $seconds . 'S'; - break; - case "day_minute": - $days = intval($_parts[0]); - list($hours, $minutes) = explode(':', $parts[1]); - return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M'; - break; - case "day_hour": - $days = intval($_parts[0]); - $hours = intval($_parts[1]); - return 'P' . $days . 'D' . 'T' . $hours . 'H'; - break; - case "year_month": - list($years, $months) = explode ('-', $_parts[0]); - return 'P' . $years . 'Y' . $months . 'M'; - break; - } - } + private $functions = array( + 'month' => 'month', + 'year' => 'year', + 'day' => 'day', + 'unix_timestamp' => 'unix_timestamp', + 'now' => 'now', + 'char_length' => 'char_length', + 'md5' => 'md5', + 'curdate' => 'curdate', + 'rand' => 'rand', + 'substring' => 'substring', + 'dayofmonth' => 'day', + 'second' => 'second', + 'minute' => 'minute', + 'hour' => 'hour', + 'date_format' => 'dateformat', + 'from_unixtime' => 'from_unixtime', + 'date_add' => 'date_add', + 'date_sub' => 'date_sub', + 'adddate' => 'date_add', + 'subdate' => 'date_sub', + 'localtime' => 'now', + 'localtimestamp' => 'now', + 'isnull' => 'isnull', + 'if' => '_if', + 'regexpp' => 'regexp', + 'concat' => 'concat', + 'field' => 'field', + 'log' => 'log', + 'least' => 'least', + 'greatest' => 'greatest', + 'get_lock' => 'get_lock', + 'release_lock' => 'release_lock', + 'ucase' => 'ucase', + 'lcase' => 'lcase', + 'inet_ntoa' => 'inet_ntoa', + 'inet_aton' => 'inet_aton', + 'datediff' => 'datediff', + 'locate' => 'locate', + 'utc_date' => 'utc_date', + 'utc_time' => 'utc_time', + 'utc_timestamp' => 'utc_timestamp', + 'version' => 'version' + ); + /** + * Method to extract the month value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the month between 1 and 12. + */ + public function month($field){ + $t = strtotime($field); + return date('n', $t); + } + /** + * Method to extract the year value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the year. + */ + public function year($field){ + $t = strtotime($field); + return date('Y', $t); + } + /** + * Method to extract the day value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the day of the month from 1 and 31. + */ + public function day($field){ + $t = strtotime($field); + return date('j', $t); + } + /** + * Method to return the unix timestamp. + * + * Used without an argument, it returns PHP time() function (total seconds passed + * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value + * to the timestamp. + * + * @param string representing the date formated as '0000-00-00 00:00:00'. + * @return number of unsigned integer + */ + public function unix_timestamp($field = null){ + return is_null($field) ? time() : strtotime($field); + } + /** + * Method to emulate MySQL SECOND() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ + public function second($field){ + $t = strtotime($field); + return intval( date("s", $t) ); + } + /** + * Method to emulate MySQL MINUTE() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ + public function minute($field){ + $t = strtotime($field); + return intval(date("i", $t)); + } + /** + * Method to emulate MySQL HOUR() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number + */ + public function hour($time){ + list($hours, $minutes, $seconds) = explode(":", $time); + return intval($hours); + } + /** + * Method to emulate MySQL FROM_UNIXTIME() function. + * + * @param integer of unix timestamp + * @param string to indicate the way of formatting(optional) + * @return string formatted as '0000-00-00 00:00:00'. + */ + public function from_unixtime($field, $format=null){ + // $field is a timestamp + //convert to ISO time + $date = date("Y-m-d H:i:s", $field); + //now submit to dateformat + return is_null($format) ? $date : $self->dateformat($date, $format); + } + /** + * Method to emulate MySQL NOW() function. + * + * @return string representing current time formatted as '0000-00-00 00:00:00'. + */ + public function now(){ + return date("Y-m-d H:i:s"); + } + /** + * Method to emulate MySQL CURDATE() function. + * + * @return string representing current time formatted as '0000-00-00'. + */ + public function curdate() { + return date("Y-m-d"); + } + /** + * Method to emulate MySQL CHAR_LENGTH() function. + * + * @param string + * @return unsigned integer for the length of the argument. + */ + public function char_length($field){ + return strlen($field); + } + /** + * Method to emulate MySQL MD5() function. + * + * @param string + * @return string of the md5 hash value of the argument. + */ + public function md5($field){ + return md5($field); + } + /** + * Method to emulate MySQL RAND() function. + * + * SQLite does have a random generator, but it is called RANDOM() and returns random + * number between -9223372036854775808 and +9223372036854775807. So we substitute it + * with PHP random generator. + * + * This function uses mt_rand() which is four times faster than rand() and returns + * the random number between 0 and 1. + * + * @return unsigned integer + */ + public function rand(){ + return mt_rand(0, 1); + } + /** + * Method to emulate MySQL SUBSTRING() function. + * + * This function rewrites the function name to SQLite compatible substr(), + * which can manipulate UTF-8 characters. + * + * @param string $text + * @param integer $pos representing the start point. + * @param integer $len representing the length of the substring(optional). + * @return string + */ + public function substring($text, $pos, $len=null){ + return "substr($text, $pos, $len)"; + } + /** + * Method to emulate MySQL DATEFORMAT() function. + * + * @param string date formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. + * @param string $format + * @return string formatted according to $format + */ + public function dateformat($date, $format){ + $mysql_php_dateformats = array ( '%a' => 'D', '%b' => 'M', '%c' => 'n', '%D' => 'jS', '%d' => 'd', '%e' => 'j', '%H' => 'H', '%h' => 'h', '%I' => 'h', '%i' => 'i', '%j' => 'z', '%k' => 'G', '%l' => 'g', '%M' => 'F', '%m' => 'm', '%p' => 'A', '%r' => 'h:i:s A', '%S' => 's', '%s' => 's', '%T' => 'H:i:s', '%U' => 'W', '%u' => 'W', '%V' => 'W', '%v' => 'W', '%W' => 'l', '%w' => 'w', '%X' => 'Y', '%x' => 'o', '%Y' => 'Y', '%y' => 'y', ); + $t = strtotime($date); + $format = strtr($format, $mysql_php_dateformats); + $output = date($format, $t); + return $output; + } + /** + * Method to emulate MySQL DATE_ADD() function. + * + * This function adds the time value of $interval expression to $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to add. + * @return string date formated as '0000-00-00 00:00:00'. + */ + public function date_add($date, $interval) { + $interval = $this->deriveInterval($interval); + switch (strtolower($date)) { + case "curdate()": + $objDate = new Datetime($this->curdate()); + $objDate->add(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d"); + break; + case "now()": + $objDate = new Datetime($this->now()); + $objDate->add(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + break; + default: + $objDate = new Datetime($date); + $objDate->add(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + } + return $returnval; + } + /** + * Method to emulate MySQL DATE_SUB() function. + * + * This function substracts the time value of $interval expression from $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to substract. + * @return string date formated as '0000-00-00 00:00:00'. + */ + public function date_sub($date, $interval) { + $interval = $this->deriveInterval($interval); + switch (strtolower($date)) { + case "curdate()": + $objDate = new Datetime($this->curdate()); + $objDate->sub(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d"); + break; + case "now()": + $objDate = new Datetime($this->now()); + $objDate->sub(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + break; + default: + $objDate = new Datetime($date); + $objDate->sub(new DateInterval($interval)); + $returnval = $objDate->format("Y-m-d H:i:s"); + } + return $returnval; + } + /** + * Method to calculate the interval time between two dates value. + * + * @access private + * @param string $interval white space separated expression. + * @return string representing the time to add or substract. + */ + private function deriveInterval($interval) { + $interval = trim(substr(trim($interval), 8)); + $parts = explode(' ', $interval); + foreach ($parts as $part) { + if (!empty($part)) { + $_parts[] = $part; + } + } + $type = strtolower(end($_parts)); + switch ($type) { + case "second": $unit = 'S'; return 'PT' . $_parts[0] . $unit; break; + case "minute": $unit = 'M'; return 'PT' . $_parts[0] . $unit; break; + case "hour": $unit = 'H'; return 'PT' . $_parts[0] . $unit; break; + case "day": $unit = 'D'; return 'P' . $_parts[0] . $unit; break; + case "week": $unit = 'W'; return 'P' . $_parts[0] . $unit; break; + case "month": $unit = 'M'; return 'P' . $_parts[0] . $unit; break; + case "year": $unit = 'Y'; return 'P' . $_parts[0] . $unit; break; + case "minute_second": + list($minutes, $seconds) = explode(':', $_parts[0]); + return 'PT' . $minutes . 'M' . $seconds . 'S'; + case "hour_second": + list($hours, $minutes, $seconds) = explode (':', $_parts[0]); + return 'PT' . $hours . 'H' . $minutes . 'M' . $seconds . 'S'; + case "hour_minute": + list($hours, $minutes) = explode (':', $_parts[0]); + return 'PT' . $hours . 'H' . $minutes . 'M'; + case "day_second": + $days = intval($_parts[0]); + list($hours, $minutes, $seconds) = explode (':', $_parts[1]); + return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M' . $seconds . 'S'; + case "day_minute": + $days = intval($_parts[0]); + list($hours, $minutes) = explode(':', $parts[1]); + return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M'; + case "day_hour": + $days = intval($_parts[0]); + $hours = intval($_parts[1]); + return 'P' . $days . 'D' . 'T' . $hours . 'H'; + case "year_month": + list($years, $months) = explode ('-', $_parts[0]); + return 'P' . $years . 'Y' . $months . 'M'; + } + } /** * Method to emulate MySQL DATE() function. - * + * * @param string $date formatted as unix time. * @return string formatted as '0000-00-00'. */ - public function date($date){ - return date("Y-m-d", strtotime($date)); - } + public function date($date){ + return date("Y-m-d", strtotime($date)); + } /** * Method to emulate MySQL ISNULL() function. - * + * * This function returns true if the argument is null, and true if not. - * + * * @param various types $field * @return boolean */ - public function isnull($field){ - return is_null($field); - } + public function isnull($field){ + return is_null($field); + } /** * Method to emulate MySQL IF() function. - * + * * As 'IF' is a reserved word for PHP, function name must be changed. - * + * * @param unknonw $expression the statement to be evaluated as true or false. * @param unknown $true statement or value returned if $expression is true. * @param unknown $false statement or value returned if $expression is false. * @return unknown */ - public function _if($expression, $true, $false){ - return ($expression == true) ? $true : $false; - } + public function _if($expression, $true, $false){ + return ($expression == true) ? $true : $false; + } /** * Method to emulate MySQL REGEXP() function. - * + * * @param string $field haystack * @param string $pattern: regular expression to match. * @return integer 1 if matched, 0 if not matched. */ - public function regexp($field, $pattern){ - $pattern = str_replace('/', '\/', $pattern); - $pattern = "/" . $pattern ."/i"; - return preg_match ($pattern, $field); - } + public function regexp($field, $pattern){ + $pattern = str_replace('/', '\/', $pattern); + $pattern = "/" . $pattern ."/i"; + return preg_match ($pattern, $field); + } /** * Method to emulate MySQL CONCAT() function. - * + * * SQLite does have CONCAT() function, but it has a different syntax from MySQL. * So this function must be manipulated here. - * + * * @param string * @return NULL if the argument is null | string conatenated if the argument is given. */ - public function concat() { - $returnValue = ""; - $argsNum = func_num_args(); - $argsList = func_get_args(); - for ($i = 0; $i < $argsNum; $i++) { - if (is_null($argsList[$i])) { - return null; - } - $returnValue .= $argsList[$i]; - } - return $returnValue; - } + public function concat() { + $returnValue = ""; + $argsNum = func_num_args(); + $argsList = func_get_args(); + for ($i = 0; $i < $argsNum; $i++) { + if (is_null($argsList[$i])) { + return null; + } + $returnValue .= $argsList[$i]; + } + return $returnValue; + } /** * Method to emulate MySQL FIELD() function. - * + * * This function gets the list argument and compares the first item to all the others. * If the same value is found, it returns the position of that value. If not, it * returns 0. - * + * * @param variable number of string, integer or double * @return unsigned integer */ - public function field() { - $numArgs = func_num_args(); - if ($numArgs < 2 or is_null(func_get_arg(0))) { - return 0; - } else { - $arg_list = func_get_args(); - } - $searchString = array_shift($arg_list); - for ($i = 0; $i < $numArgs-1; $i++) { - if ($searchString === strtolower($arg_list[$i])) { - return $i + 1; - } - } - return 0; - } + public function field() { + $numArgs = func_num_args(); + if ($numArgs < 2 or is_null(func_get_arg(0))) { + return 0; + } else { + $arg_list = func_get_args(); + } + $searchString = array_shift($arg_list); + for ($i = 0; $i < $numArgs-1; $i++) { + if ($searchString === strtolower($arg_list[$i])) { + return $i + 1; + } + } + return 0; + } /** * Method to emulate MySQL LOG() function. - * + * * Used with one argument, it returns the natural logarithm of X. * * LOG(X) @@ -475,177 +468,176 @@ class PDOSQLiteUDFS { * LOG(B, X) * * In this case, it returns the value of log(X) / log(B). - * + * * Used without an argument, it returns false. This returned value will be * rewritten to 0, because SQLite doesn't understand true/false value. - * + * * @param integer representing the base of the logarithm, which is optional. * @param double value to turn into logarithm. * @return double | NULL */ - public function log() { - $numArgs = func_num_args(); - if ($numArgs == 1) { - $arg1 = func_get_arg(0); - return log($arg1); - } else if ($numArgs == 2) { - $arg1 = func_get_arg(0); - $arg2 = func_get_arg(1); - return log($arg1)/log($arg2); - } else { - return null; - } - } + public function log() { + $numArgs = func_num_args(); + if ($numArgs == 1) { + $arg1 = func_get_arg(0); + return log($arg1); + } else if ($numArgs == 2) { + $arg1 = func_get_arg(0); + $arg2 = func_get_arg(1); + return log($arg1)/log($arg2); + } else { + return null; + } + } /** * Method to emulate MySQL LEAST() function. - * + * * This function rewrites the function name to SQLite compatible function name. - * + * * @return mixed */ - public function least() { - $arg_list = func_get_args(); - return "min($arg_list)"; - } - /** - * Method to emulate MySQL GREATEST() function. - * - * This function rewrites the function name to SQLite compatible function name. - * - * @return mixed - */ - public function greatest() { - $arg_list = func_get_args(); - return "max($arg_list)"; - } - /** - * Method to dummy out MySQL GET_LOCK() function. - * - * This function is meaningless in SQLite, so we do nothing. - * - * @param string $name - * @param integer $timeout - * @return string - */ - public function get_lock($name, $timeout) { - return '1=1'; - } - /** - * Method to dummy out MySQL RELEASE_LOCK() function. - * - * This function is meaningless in SQLite, so we do nothing. - * - * @param string $name - * @return string - */ - public function release_lock($name) { - return '1=1'; - } - /** - * Method to emulate MySQL UCASE() function. - * - * This is MySQL alias for upper() function. This function rewrites it - * to SQLite compatible name upper(). - * - * @param string - * @return string SQLite compatible function name. - */ - public function ucase($string) { - return "upper($string)"; - } - /** - * Method to emulate MySQL LCASE() function. - * - * - * This is MySQL alias for lower() function. This function rewrites it - * to SQLite compatible name lower(). - * - * @param string - * @return string SQLite compatible function name. - */ - public function lcase($string) { - return "lower($string)"; - } - /** - * Method to emulate MySQL INET_NTOA() function. - * - * This function gets 4 or 8 bytes integer and turn it into the network address. - * - * @param unsigned long integer - * @return string - */ - public function inet_ntoa($num) { - return long2ip($num); - } - /** - * Method to emulate MySQL INET_ATON() function. - * - * This function gets the network address and turns it into integer. - * - * @param string - * @return unsigned long integer - */ - public function inet_aton($addr) { - $int_data = ip2long($addr); - $unsigned_int_data = sprintf('%u', $address); - return $unsigned_int_data; - } - - /** - * Method to emulate MySQL DATEDIFF() function. - * - * This function compares two dates value and returns the difference. - * - * PHP 5.3.2 has a serious bug in DateTime::diff(). So if users' PHP is that version, - * we don't use that function. See https://bugs.php.net/bug.php?id=51184. - * - * @param string start - * @param string end - * @return string - */ - public function datediff($start, $end) { - if (version_compare(PHP_VERSION, '5.3.2', '==')) { - $start_date = strtotime($start); - $end_date = strtotime($end); - $interval = floor(($start_date - $end_date)/(3600*24)); - return $interval; - } else { - $start_date = new DateTime($start); - $end_date = new DateTime($end); - $interval = $end_date->diff($start_date, false); - return $interval->format('%r%a'); - } - } - /** - * Method to emulate MySQL LOCATE() function. - * - * This function returns the position if $substr is found in $str. If not, - * it returns 0. If mbstring extension is loaded, mb_strpos() function is - * used. - * - * @param string needle - * @param string haystack - * @param integer position - * @return integer - */ - public function locate($substr, $str, $pos = 0) { - if (!extension_loaded('mbstring')) { - if (($val = stros($str, $substr, $pos)) !== false) { - return $val + 1; - } else { - return 0; - } - } else { - if (($val = mb_strpos($str, $substr, $pos)) !== false) { - return $val + 1; - } else { - return 0; - } - } - } + public function least() { + $arg_list = func_get_args(); + return "min($arg_list)"; + } + /** + * Method to emulate MySQL GREATEST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ + public function greatest() { + $arg_list = func_get_args(); + return "max($arg_list)"; + } + /** + * Method to dummy out MySQL GET_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * + * @param string $name + * @param integer $timeout + * @return string + */ + public function get_lock($name, $timeout) { + return '1=1'; + } + /** + * Method to dummy out MySQL RELEASE_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * + * @param string $name + * @return string + */ + public function release_lock($name) { + return '1=1'; + } + /** + * Method to emulate MySQL UCASE() function. + * + * This is MySQL alias for upper() function. This function rewrites it + * to SQLite compatible name upper(). + * + * @param string + * @return string SQLite compatible function name. + */ + public function ucase($string) { + return "upper($string)"; + } + /** + * Method to emulate MySQL LCASE() function. + * + * + * This is MySQL alias for lower() function. This function rewrites it + * to SQLite compatible name lower(). + * + * @param string + * @return string SQLite compatible function name. + */ + public function lcase($string) { + return "lower($string)"; + } + /** + * Method to emulate MySQL INET_NTOA() function. + * + * This function gets 4 or 8 bytes integer and turn it into the network address. + * + * @param unsigned long integer + * @return string + */ + public function inet_ntoa($num) { + return long2ip($num); + } + /** + * Method to emulate MySQL INET_ATON() function. + * + * This function gets the network address and turns it into integer. + * + * @param string + * @return unsigned long integer + */ + public function inet_aton($addr) { + $int_data = ip2long($addr); + $unsigned_int_data = sprintf('%u', $address); + return $unsigned_int_data; + } + /** + * Method to emulate MySQL DATEDIFF() function. + * + * This function compares two dates value and returns the difference. + * + * PHP 5.3.2 has a serious bug in DateTime::diff(). So if users' PHP is that version, + * we don't use that function. See https://bugs.php.net/bug.php?id=51184. + * + * @param string start + * @param string end + * @return string + */ + public function datediff($start, $end) { + if (version_compare(PHP_VERSION, '5.3.2', '==')) { + $start_date = strtotime($start); + $end_date = strtotime($end); + $interval = floor(($start_date - $end_date)/(3600*24)); + return $interval; + } else { + $start_date = new DateTime($start); + $end_date = new DateTime($end); + $interval = $end_date->diff($start_date, false); + return $interval->format('%r%a'); + } + } + /** + * Method to emulate MySQL LOCATE() function. + * + * This function returns the position if $substr is found in $str. If not, + * it returns 0. If mbstring extension is loaded, mb_strpos() function is + * used. + * + * @param string needle + * @param string haystack + * @param integer position + * @return integer + */ + public function locate($substr, $str, $pos = 0) { + if (!extension_loaded('mbstring')) { + if (($val = stros($str, $substr, $pos)) !== false) { + return $val + 1; + } else { + return 0; + } + } else { + if (($val = mb_strpos($str, $substr, $pos)) !== false) { + return $val + 1; + } else { + return 0; + } + } + } /** * Method to return GMT date in the string format. - * + * * @param none * @return string formatted GMT date 'dddd-mm-dd' */ @@ -654,7 +646,7 @@ class PDOSQLiteUDFS { } /** * Method to return GMT time in the string format. - * + * * @param none * @return string formatted GMT time '00:00:00' */ @@ -663,7 +655,7 @@ class PDOSQLiteUDFS { } /** * Method to return GMT time stamp in the string format. - * + * * @param none * @return string formatted GMT timestamp 'yyyy-mm-dd 00:00:00' */ @@ -672,16 +664,16 @@ class PDOSQLiteUDFS { } /** * Method to return MySQL version. - * + * * This function only returns the current newest version number of MySQL, * because it is meaningless for SQLite database. - * + * * @param none * @return string representing the version number: major_version.minor_version */ public function version() { -// global $required_mysql_version; -// return $required_mysql_version; + //global $required_mysql_version; + //return $required_mysql_version; return '5.5'; } } diff --git a/install.php b/install.php index 4648d02..56efbdb 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ Note that password carefully! It is a random password that was generated just for you.'); - $user_id = wp_create_user($user_name, $user_password, $user_email); - update_user_option($user_id, 'default_password_nag', true, true); - $email_password = true; - } else if (!$user_id) { - $message = ''.__('Your chosen password.').''; - $user_id = wp_create_user($user_name, $user_password, $user_email); - } - - $user = new WP_User($user_id); - $user->set_role('administrator'); - - wp_install_defaults($user_id); - - flush_rewrite_rules(); - - wp_new_blog_notification($blog_title, $guessurl, $user_id, ($email_password ? $user_password : __('The password you chose during the install.'))); - - wp_cache_flush(); + update_option('blogname', $blog_title); + update_option('admin_email', $user_email); + update_option('blog_public', $public); - if (isset($_SERVER['SERVER_SOFTWARE']) && stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false || isset($_SERVER['SERVER_SIGNATURE']) && stripos($_SERVER['SERVER_SIGNATURE'], 'apache') !== false) { - ;// Your server is Apache. Nothing to do more. - } else { - $server_message = sprintf('Your webserver doesn\'t seem to be Apache. So the database directory access restriction by the .htaccess file may not function. We strongly recommend that you should restrict the access to the directory %s in some other way.', FQDBDIR); - echo '

'; - echo $server_message; - echo '

'; - } + $guessurl = wp_guess_url(); - return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message); + update_option('siteurl', $guessurl); + + if (!$public) + update_option('default_pingback_flag', 0); + + $user_id = username_exists($user_name); + $user_password = trim($user_password); + $email_password = false; + if (!$user_id && empty($user_password)) { + $user_password = wp_generate_password(12, false); + $message = __('Note that password carefully! It is a random password that was generated just for you.'); + $user_id = wp_create_user($user_name, $user_password, $user_email); + update_user_option($user_id, 'default_password_nag', true, true); + $email_password = true; + } else if (!$user_id) { + $message = ''.__('Your chosen password.').''; + $user_id = wp_create_user($user_name, $user_password, $user_email); + } + + $user = new WP_User($user_id); + $user->set_role('administrator'); + + wp_install_defaults($user_id); + + flush_rewrite_rules(); + + wp_new_blog_notification($blog_title, $guessurl, $user_id, ($email_password ? $user_password : __('The password you chose during the install.'))); + + wp_cache_flush(); + + if (isset($_SERVER['SERVER_SOFTWARE']) && stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false || isset($_SERVER['SERVER_SIGNATURE']) && stripos($_SERVER['SERVER_SIGNATURE'], 'apache') !== false) { + ;// Your server is Apache. Nothing to do more. + } else { + $server_message = sprintf('Your webserver doesn\'t seem to be Apache. So the database directory access restriction by the .htaccess file may not function. We strongly recommend that you should restrict the access to the directory %s in some other way.', FQDBDIR); + echo '

'; + echo $server_message; + echo '

'; + } + + return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message); } ?> \ No newline at end of file diff --git a/js/sqlite.js b/js/sqlite.js index 40dc4ce..ea09473 100644 --- a/js/sqlite.js +++ b/js/sqlite.js @@ -23,14 +23,14 @@ jQuery(document).ready(function($) { $headers = $table.find('thead th').slice(1); } $headers - .wrapInner('') - .addClass('sort'); + .wrapInner('') + .addClass('sort'); var rows = $table.find('tbody > tr').get(); $headers.bind('click', function(event) { event.preventDefault(); var $header = $(this), - sortKey = $header.data('sort').key, - sortDirection = 1; + sortKey = $header.data('sort').key, + sortDirection = 1; if ($header.hasClass('sorted-asc')) { sortDirection = -1; } @@ -70,14 +70,14 @@ jQuery(document).ready(function($) { var $table = $('#plugins-info'); var $headers = $table.find('thead th').slice(0); $headers - .wrapInner('') - .addClass('sort'); + .wrapInner('') + .addClass('sort'); var rows = $table.find('tbody > tr').get(); $headers.bind('click', function(event) { event.preventDefault(); var $header = $(this), - sortKey = $header.data('sort').key, - sortDirection = 1; + sortKey = $header.data('sort').key, + sortDirection = 1; if ($header.hasClass('sorted-asc')) { sortDirection = -1; } diff --git a/pdodb.class.php b/pdodb.class.php index b7df54c..ad1e269 100644 --- a/pdodb.class.php +++ b/pdodb.class.php @@ -2,7 +2,7 @@ /** * This file defines PDODB class, which inherits wpdb class and replaces it * global $wpdb variable. - * + * * @package SQLite Integration * @author Kojima Toshiyasu * @@ -18,315 +18,315 @@ if (!defined('SAVEQUERIES')){ define ('SAVEQUERIES', false); } if(!defined('PDO_DEBUG')){ - define('PDO_DEBUG', false); + define('PDO_DEBUG', false); } /** * This class extends wpdb and replaces it. - * + * * It also rewrites some methods that use mysql specific functions. - * + * */ class PDODB extends wpdb { /** - * + * * @var reference to the object of PDOEngine class. * @access protected */ - protected $dbh = null; - - /** - * Constructor - * - * This overrides wpdb::__construct() which has database server, username and - * password as arguments. This class doesn't use them. - * - * @see wpdb::__construct() - */ - function __construct() { - register_shutdown_function(array($this, '__destruct')); + protected $dbh = null; - if (WP_DEBUG) - $this->show_errors(); - - $this->init_charset(); + /** + * Constructor + * + * This overrides wpdb::__construct() which has database server, username and + * password as arguments. This class doesn't use them. + * + * @see wpdb::__construct() + */ + function __construct() { + register_shutdown_function(array($this, '__destruct')); + + if (WP_DEBUG) + $this->show_errors(); + + $this->init_charset(); + + $this->db_connect(); + } + /** + * Desctructor + * + * This overrides wpdb::__destruct(), but does nothing but return true. + * + * @see wpdb::__destruct() + */ + function __destruct() { + return true; + } + + /** + * Method to set character set for the database. + * + * This overrides wpdb::set_charset(), only to dummy out the MySQL function. + * + * @see wpdb::set_charset() + */ + function set_charset($dbh, $charset = null, $collate = null) { + if ( ! isset( $charset ) ) + $charset = $this->charset; + if ( ! isset( $collate ) ) + $collate = $this->collate; + } + /** + * Method to dummy out wpdb::set_sql_mode() + * + * @see wpdb::set_sql_mode() + */ + function set_sql_mode($modes = array()) { + unset($modes); + return; + } + /** + * Method to select the database connection. + * + * This overrides wpdb::select(), only to dummy out the MySQL function. + * + * @see wpdb::select() + */ + function select($db, $dbh = null) { + if (is_null($dbh)) + $dbh = $this->dbh; + $this->ready = true; + return; + } + /** + * Method to dummy out wpdb::_weak_escape() + * + */ + function _weak_escape($string) { + return addslashes($string); + } + /** + * Method to escape characters. + * + * This overrides wpdb::_real_escape() to avoid using mysql_real_escape_string(). + * + * @see wpdb::_real_escape() + */ + function _real_escape($string) { + return addslashes($string); + } + + /** + * Method to put out the error message. + * + * This overrides wpdb::print_error(), for we can't use the parent class method. + * + * @see wpdb::print_error() + */ + function print_error($str = '') { + global $EZSQL_ERROR; + + if (!$str) { + $err = $this->dbh->get_error_message() ? $this->dbh->get_error_message() : ''; + if (!empty($err)) $str = $err[2]; else $str = ''; + } + $EZSQL_ERROR[] = array('query' => $this->last_query, 'error_str' => $str); + + if ($this->suppress_errors) + return false; + + wp_load_translations_early(); + + if ($caller = $this->get_caller()) + $error_str = sprintf(__('WordPress database error %1$s for query %2$s made by %3$s'), $str, $this->last_query, $caller); + else + $error_str = sprintf(__('WordPress database error %1$s for query %2$s'), $str, $this->last_query); + + error_log($error_str); + + if (!$this->show_errors) + return false; + + if (is_multisite()) { + $msg = "WordPress database error: [$str]\n{$this->last_query}\n"; + if (defined('ERRORLOGFILE')) + error_log($msg, 3, ERRORLOGFILE); + if (defined('DIEONDBERROR')) + wp_die($msg); + } else { + $str = htmlspecialchars($str, ENT_QUOTES); + $query = htmlspecialchars($this->last_query, ENT_QUOTES); - $this->db_connect(); - } - /** - * Desctructor - * - * This overrides wpdb::__destruct(), but does nothing but return true. - * - * @see wpdb::__destruct() - */ - function __destruct() { - return true; - } - - /** - * Method to set character set for the database. - * - * This overrides wpdb::set_charset(), only to dummy out the MySQL function. - * - * @see wpdb::set_charset() - */ - function set_charset($dbh, $charset = null, $collate = null) { - if ( ! isset( $charset ) ) - $charset = $this->charset; - if ( ! isset( $collate ) ) - $collate = $this->collate; - } - /** - * Method to dummy out wpdb::set_sql_mode() - * - * @see wpdb::set_sql_mode() - */ - function set_sql_mode($modes = array()) { - unset($modes); - return; - } - /** - * Method to select the database connection. - * - * This overrides wpdb::select(), only to dummy out the MySQL function. - * - * @see wpdb::select() - */ - function select($db, $dbh = null) { - if (is_null($dbh)) - $dbh = $this->dbh; - $this->ready = true; - return; - } - /** - * Method to dummy out wpdb::_weak_escape() - * - */ - function _weak_escape($string) { - return addslashes($string); - } - /** - * Method to escape characters. - * - * This overrides wpdb::_real_escape() to avoid using mysql_real_escape_string(). - * - * @see wpdb::_real_escape() - */ - function _real_escape($string) { - return addslashes($string); - } - - /** - * Method to put out the error message. - * - * This overrides wpdb::print_error(), for we can't use the parent class method. - * - * @see wpdb::print_error() - */ - function print_error($str = '') { - global $EZSQL_ERROR; - - if (!$str) { - $err = $this->dbh->get_error_message() ? $this->dbh->get_error_message() : ''; - if (!empty($err)) $str = $err[2]; else $str = ''; - } - $EZSQL_ERROR[] = array('query' => $this->last_query, 'error_str' => $str); - - if ($this->suppress_errors) - return false; - - wp_load_translations_early(); - - if ($caller = $this->get_caller()) - $error_str = sprintf(__('WordPress database error %1$s for query %2$s made by %3$s'), $str, $this->last_query, $caller); - else - $error_str = sprintf(__('WordPress database error %1$s for query %2$s'), $str, $this->last_query); - - error_log($error_str); - - if (!$this->show_errors) - return false; - - if (is_multisite()) { - $msg = "WordPress database error: [$str]\n{$this->last_query}\n"; - if (defined('ERRORLOGFILE')) - error_log($msg, 3, ERRORLOGFILE); - if (defined('DIEONDBERROR')) - wp_die($msg); - } else { - $str = htmlspecialchars($str, ENT_QUOTES); - $query = htmlspecialchars($this->last_query, ENT_QUOTES); - print "

WordPress database error: [$str]
$query

"; - } - } + } + } /** * Method to flush cached data. - * + * * This overrides wpdb::flush(). This is not necessarily overridden, because * $result will never be resource. - * + * * @see wpdb::flush */ - function flush() { - $this->last_result = array(); - $this->col_info = null; - $this->last_query = null; - $this->rows_affected = $this->num_rows = 0; - $this->last_error = ''; + function flush() { + $this->last_result = array(); + $this->col_info = null; + $this->last_query = null; + $this->rows_affected = $this->num_rows = 0; + $this->last_error = ''; $this->result = null; - } - /** - * Method to do the database connection. - * - * This overrides wpdb::db_connect() to avoid using MySQL function. - * - * @see wpdb::db_connect() - */ - function db_connect($allow_bail=true) { - if (WP_DEBUG) { - $this->dbh = new PDOEngine(); - } else { - // WP_DEBUG or not, we don't use @ which causes the slow execution - // PDOEngine class will take the Exception handling. - $this->dbh = new PDOEngine(); - } - if (!$this->dbh) { - wp_load_translations_early();//probably there's no translations - $this->bail(sprintf(__("

Error establlishing a database connection

We have been unable to connect to the specified database.
The error message received was %s"), $this->dbh->errorInfo())); - return; - } - $is_enabled_foreign_keys = @$this->get_var('PRAGMA foreign_keys'); - if ($is_enabled_foreign_keys == '0') @$this->query('PRAGMA foreign_keys = ON'); - $this->ready = true; - } - /** - * Method to dummy out wpdb::check_connection() - * - */ - function check_connection($allow_bail=true) { - return true; - } - /** - * Method to execute the query. - * - * This overrides wpdb::query(). In fact, this method does all the database - * access jobs. - * - * @see wpdb::query() - */ - function query($query) { - if (!$this->ready) - return false; - - $query = apply_filters('query', $query); - - $return_val = 0; - $this->flush(); - - $this->func_call = "\$db->query(\"$query\")"; - - $this->last_query = $query; - - if (defined('SAVEQUERIES') && SAVEQUERIES) - $this->timer_start(); - - $this->result = $this->dbh->query($query); - $this->num_queries++; - - if (defined('SAVEQUERIES') && SAVEQUERIES) - $this->queries[] = array($query, $this->timer_stop(), $this->get_caller()); - - if ($this->last_error = $this->dbh->get_error_message()) { - if (defined('WP_INSTALLING') && WP_INSTALLING) { - //$this->suppress_errors(); - } else { - $this->print_error($this->last_error); - return false; - } - } - - if (preg_match('/^\\s*(create|alter|truncate|drop|optimize)\\s*/i', $query)) { -// $return_val = $this->result; - $return_val = $this->dbh->get_return_value(); - } elseif (preg_match('/^\\s*(insert|delete|update|replace)\s/i', $query)) { - $this->rows_affected = $this->dbh->get_affected_rows(); - if (preg_match('/^\s*(insert|replace)\s/i', $query)) { - $this->insert_id = $this->dbh->get_insert_id(); - } - $return_val = $this->rows_affected; - } else { - $this->last_result = $this->dbh->get_query_results(); - $this->num_rows = $this->dbh->get_num_rows(); - $return_val = $this->num_rows; - } - return $return_val; - } - /** - * - */ - private function _do_query($query) { - if (defined('SAVEQUERIES') && SAVEQUERIES) { - $this->timer_start(); - } - $this->result = $this->dbh->query($query); - $this->num_queries++; - if (defined('SAVEQUERIES') && SAVEQUERIES) { - $this->queries[] = array($query, $this->timer_stop(), $this->get_caller()); - } - } - /** - * Method to set the class variable $col_info. - * - * This overrides wpdb::load_col_info(), which uses a mysql function. - * - * @see wpdb::load_col_info() - * @access protected - */ - protected function load_col_info() { - if ($this->col_info) - return; - $this->col_info = $this->dbh->get_columns(); - } - - /** - * Method to return what the database can do. - * - * This overrides wpdb::has_cap() to avoid using MySQL functions. - * SQLite supports subqueries, but not support collation, group_concat and set_charset. - * - * @see wpdb::has_cap() - */ - function has_cap($db_cap) { - switch(strtolower($db_cap)) { - case 'collation': - case 'group_concat': - case 'set_charset': - return false; - case 'subqueries': - return true; - default: - return false; - } - } - /** - * Method to return database version number. - * - * This overrides wpdb::db_version() to avoid using MySQL function. - * It returns mysql version number, but it means nothing for SQLite. - * So it return the newest mysql version. - * - * @see wpdb::db_version() - */ - function db_version() { -// global $required_mysql_version; -// return $required_mysql_version; + } + /** + * Method to do the database connection. + * + * This overrides wpdb::db_connect() to avoid using MySQL function. + * + * @see wpdb::db_connect() + */ + function db_connect($allow_bail=true) { + if (WP_DEBUG) { + $this->dbh = new PDOEngine(); + } else { + // WP_DEBUG or not, we don't use @ which causes the slow execution + // PDOEngine class will take the Exception handling. + $this->dbh = new PDOEngine(); + } + if (!$this->dbh) { + wp_load_translations_early();//probably there's no translations + $this->bail(sprintf(__("

Error establlishing a database connection

We have been unable to connect to the specified database.
The error message received was %s"), $this->dbh->errorInfo())); + return; + } + $is_enabled_foreign_keys = @$this->get_var('PRAGMA foreign_keys'); + if ($is_enabled_foreign_keys == '0') @$this->query('PRAGMA foreign_keys = ON'); + $this->ready = true; + } + /** + * Method to dummy out wpdb::check_connection() + * + */ + function check_connection($allow_bail=true) { + return true; + } + /** + * Method to execute the query. + * + * This overrides wpdb::query(). In fact, this method does all the database + * access jobs. + * + * @see wpdb::query() + */ + function query($query) { + if (!$this->ready) + return false; + + $query = apply_filters('query', $query); + + $return_val = 0; + $this->flush(); + + $this->func_call = "\$db->query(\"$query\")"; + + $this->last_query = $query; + + if (defined('SAVEQUERIES') && SAVEQUERIES) + $this->timer_start(); + + $this->result = $this->dbh->query($query); + $this->num_queries++; + + if (defined('SAVEQUERIES') && SAVEQUERIES) + $this->queries[] = array($query, $this->timer_stop(), $this->get_caller()); + + if ($this->last_error = $this->dbh->get_error_message()) { + if (defined('WP_INSTALLING') && WP_INSTALLING) { + //$this->suppress_errors(); + } else { + $this->print_error($this->last_error); + return false; + } + } + + if (preg_match('/^\\s*(create|alter|truncate|drop|optimize)\\s*/i', $query)) { + //$return_val = $this->result; + $return_val = $this->dbh->get_return_value(); + } elseif (preg_match('/^\\s*(insert|delete|update|replace)\s/i', $query)) { + $this->rows_affected = $this->dbh->get_affected_rows(); + if (preg_match('/^\s*(insert|replace)\s/i', $query)) { + $this->insert_id = $this->dbh->get_insert_id(); + } + $return_val = $this->rows_affected; + } else { + $this->last_result = $this->dbh->get_query_results(); + $this->num_rows = $this->dbh->get_num_rows(); + $return_val = $this->num_rows; + } + return $return_val; + } + /** + * + */ + private function _do_query($query) { + if (defined('SAVEQUERIES') && SAVEQUERIES) { + $this->timer_start(); + } + $this->result = $this->dbh->query($query); + $this->num_queries++; + if (defined('SAVEQUERIES') && SAVEQUERIES) { + $this->queries[] = array($query, $this->timer_stop(), $this->get_caller()); + } + } + /** + * Method to set the class variable $col_info. + * + * This overrides wpdb::load_col_info(), which uses a mysql function. + * + * @see wpdb::load_col_info() + * @access protected + */ + protected function load_col_info() { + if ($this->col_info) + return; + $this->col_info = $this->dbh->get_columns(); + } + + /** + * Method to return what the database can do. + * + * This overrides wpdb::has_cap() to avoid using MySQL functions. + * SQLite supports subqueries, but not support collation, group_concat and set_charset. + * + * @see wpdb::has_cap() + */ + function has_cap($db_cap) { + switch(strtolower($db_cap)) { + case 'collation': + case 'group_concat': + case 'set_charset': + return false; + case 'subqueries': + return true; + default: + return false; + } + } + /** + * Method to return database version number. + * + * This overrides wpdb::db_version() to avoid using MySQL function. + * It returns mysql version number, but it means nothing for SQLite. + * So it return the newest mysql version. + * + * @see wpdb::db_version() + */ + function db_version() { + //global $required_mysql_version; + //return $required_mysql_version; return '5.5'; - } + } } /* diff --git a/pdoengine.class.php b/pdoengine.class.php index 5caa6da..ac284b0 100644 --- a/pdoengine.class.php +++ b/pdoengine.class.php @@ -1,7 +1,7 @@ init(); - } - /** - * Destructor - * - * @return boolean - */ - function __destruct() { - $this->pdo = null; - return true; - } - - /** - * Method to initialize database, executed in the contructor. - * - * It checks if there's a database directory and database file, creates the tables, - * and binds the user defined function to the pdo object. - * - * @return boolean - */ - private function init() { - $dsn = 'sqlite:' . FQDB; - $result = $this->prepare_directory(); - if (!$result) return false; - if (is_file(FQDB)) { - $locked = false; - do { - try { - if ($locked) $locked = false; - $this->pdo = new PDO( - $dsn, // data source name - null, // user name - null, // user password - array( // PDO options - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION - )); - $statement = $this->pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type='table'"); - $number_of_tables = $statement->fetchColumn(0); - $statement = null; - if ($number_of_tables == 0) { - $this->make_sqlite_tables(); - } - } catch (PDOException $err) { - $status = $err->getCode(); - // code 5 => The database file is locked - // code 6 => A table in the database is locked - if ($status == 5 || $status == 6) { - $locked = true; - } else { - $message = 'Database connection error!
'; - $message .= sprintf("Error message is: %s", $err->getMessage()); - $this->set_error(__LINE__, __FUNCTION__, $message); - return false; - } - } - } while ($locked); - require_once UDF_FILE; - new PDOSQLiteUDFS($this->pdo); - if (version_compare($this->get_sqlite_version(), '3.7.11', '>=')) { - $this->can_insert_multiple_rows = true; - } - } else { // database file is not found, so we make it and create tables... - try { - $this->pdo = new PDO($dsn, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); - } catch (PDOException $err) { - $message = 'Database initialization error!
'; - $message .= sprintf("Error message is: %s", $err->getMessage()); - $this->set_error(__LINE__, __FUNCTION__, $message); - return false; - } - $this->make_sqlite_tables(); - } - } + /** + * Constructor + * + * @param none + */ + function __construct() { + $this->init(); + } + /** + * Destructor + * + * @return boolean + */ + function __destruct() { + $this->pdo = null; + return true; + } - /** - * This method makes database direcotry and .htaccess file. - * - * It is executed only once when the installation begins. - */ - private function prepare_directory() { - global $wpdb; - $u = umask(0000); - if (!is_dir(FQDBDIR)) { - if (!@mkdir(FQDBDIR, 0707, true)) { - umask($u); - $message = 'Unable to create the required directory! Please check your server settings.'; - wp_die($message, 'Error!'); - } - } - if (!is_writable(FQDBDIR)) { - umask($u); - $message = 'Unable to create a file in the directory! Please check your server settings.'; - wp_die($message, 'Error!'); - } - if (!is_file(FQDBDIR . '.htaccess')) { - $fh = fopen(FQDBDIR . '.htaccess', "w"); - if (!$fh) { - umask($u); - $message = 'Unable to create a file in the directory! Please check your server settings.'; - echo $message; - return false; - } - fwrite($fh, 'DENY FROM ALL'); - fclose($fh); - } - if (!is_file(FQDBDIR . 'index.php')) { - $fh = fopen(FQDBDIR . 'index.php', "w"); - if (!$fh) { - umask($u); - $message = 'Unable to create a file in the directory! Please check your server settings.'; - echo $message; - return false; - } - fwrite($fh, ''); - fclose($fh); - } - umask($u); - return true; - } - /** - * Method to call install() function which overrides WordPress install(). - * - * This function is executed only once during the installation process. - */ - private function make_sqlite_tables() { - require_once PDODIR . 'install.php'; - } - /** - * Method to execute query(). - * - * Divide the query types into seven different ones. That is to say: - * - * 1. SELECT SQL_CALC_FOUND_ROWS - * 2. INSERT - * 3. CREATE TABLE(INDEX) - * 4. ALTER TABLE - * 5. SHOW VARIABLES - * 6. DROP INDEX - * 7. THE OTHERS - * - * #1 is just a tricky play. See the private function handle_sql_count() in query.class.php. - * From #2 through #5 call different functions respectively. - * #6 call the ALTER TABLE query. - * #7 is a normal process: sequentially call prepare_query() and execute_query(). - * - * #1 process has been changed since version 1.5.1. - * - * @param $query full SQL statement string - * @return mixed according to the query type - * @see PDO::query() - */ - public function query($query) { - $this->flush(); - - $this->queries[] = "Raw query:\n$query"; - $res = $this->determine_query_type($query); - if (!$res && defined(PDO_DEBUG) && PDO_DEBUG) { - $bailoutString = sprintf(__("

Unknown query type

Sorry, we cannot determine the type of query that is requested.

The query is %s

", 'sqlite-integration'), $query); - $this->set_error(__LINE__, __FUNCTION__, $bailoutString); - } - switch (strtolower($this->query_type)) { - case 'set': - $this->return_value = false; - break; - case 'foundrows': + /** + * Method to initialize database, executed in the contructor. + * + * It checks if there's a database directory and database file, creates the tables, + * and binds the user defined function to the pdo object. + * + * @return boolean + */ + private function init() { + $dsn = 'sqlite:' . FQDB; + $result = $this->prepare_directory(); + if (!$result) return false; + if (is_file(FQDB)) { + $locked = false; + do { + try { + if ($locked) $locked = false; + $this->pdo = new PDO( + $dsn, // data source name + null, // user name + null, // user password + array( // PDO options + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION + )); + $statement = $this->pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type='table'"); + $number_of_tables = $statement->fetchColumn(0); + $statement = null; + if ($number_of_tables == 0) { + $this->make_sqlite_tables(); + } + } catch (PDOException $err) { + $status = $err->getCode(); + // code 5 => The database file is locked + // code 6 => A table in the database is locked + if ($status == 5 || $status == 6) { + $locked = true; + } else { + $message = 'Database connection error!
'; + $message .= sprintf("Error message is: %s", $err->getMessage()); + $this->set_error(__LINE__, __FUNCTION__, $message); + return false; + } + } + } while ($locked); + require_once UDF_FILE; + new PDOSQLiteUDFS($this->pdo); + if (version_compare($this->get_sqlite_version(), '3.7.11', '>=')) { + $this->can_insert_multiple_rows = true; + } + } else { // database file is not found, so we make it and create tables... + try { + $this->pdo = new PDO($dsn, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); + } catch (PDOException $err) { + $message = 'Database initialization error!
'; + $message .= sprintf("Error message is: %s", $err->getMessage()); + $this->set_error(__LINE__, __FUNCTION__, $message); + return false; + } + $this->make_sqlite_tables(); + } + } + + /** + * This method makes database direcotry and .htaccess file. + * + * It is executed only once when the installation begins. + */ + private function prepare_directory() { + global $wpdb; + $u = umask(0000); + if (!is_dir(FQDBDIR)) { + if (!@mkdir(FQDBDIR, 0707, true)) { + umask($u); + $message = 'Unable to create the required directory! Please check your server settings.'; + wp_die($message, 'Error!'); + } + } + if (!is_writable(FQDBDIR)) { + umask($u); + $message = 'Unable to create a file in the directory! Please check your server settings.'; + wp_die($message, 'Error!'); + } + if (!is_file(FQDBDIR . '.htaccess')) { + $fh = fopen(FQDBDIR . '.htaccess', "w"); + if (!$fh) { + umask($u); + $message = 'Unable to create a file in the directory! Please check your server settings.'; + echo $message; + return false; + } + fwrite($fh, 'DENY FROM ALL'); + fclose($fh); + } + if (!is_file(FQDBDIR . 'index.php')) { + $fh = fopen(FQDBDIR . 'index.php', "w"); + if (!$fh) { + umask($u); + $message = 'Unable to create a file in the directory! Please check your server settings.'; + echo $message; + return false; + } + fwrite($fh, ''); + fclose($fh); + } + umask($u); + return true; + } + /** + * Method to call install() function which overrides WordPress install(). + * + * This function is executed only once during the installation process. + */ + private function make_sqlite_tables() { + require_once PDODIR . 'install.php'; + } + /** + * Method to execute query(). + * + * Divide the query types into seven different ones. That is to say: + * + * 1. SELECT SQL_CALC_FOUND_ROWS + * 2. INSERT + * 3. CREATE TABLE(INDEX) + * 4. ALTER TABLE + * 5. SHOW VARIABLES + * 6. DROP INDEX + * 7. THE OTHERS + * + * #1 is just a tricky play. See the private function handle_sql_count() in query.class.php. + * From #2 through #5 call different functions respectively. + * #6 call the ALTER TABLE query. + * #7 is a normal process: sequentially call prepare_query() and execute_query(). + * + * #1 process has been changed since version 1.5.1. + * + * @param $query full SQL statement string + * @return mixed according to the query type + * @see PDO::query() + */ + public function query($query) { + $this->flush(); + + $this->queries[] = "Raw query:\n$query"; + $res = $this->determine_query_type($query); + if (!$res && defined(PDO_DEBUG) && PDO_DEBUG) { + $bailoutString = sprintf(__("

Unknown query type

Sorry, we cannot determine the type of query that is requested.

The query is %s

", 'sqlite-integration'), $query); + $this->set_error(__LINE__, __FUNCTION__, $bailoutString); + } + switch (strtolower($this->query_type)) { + case 'set': + $this->return_value = false; + break; + case 'foundrows': $_column = array('FOUND_ROWS()' => ''); $column = array(); if (!is_null($this->found_rows_result)) { $this->num_rows = $this->found_rows_result; $_column['FOUND_ROWS()'] = $this->num_rows; -// foreach ($this->found_rows_result[0] as $key => $value) { -// $_column['FOUND_ROWS()'] = $value; -// } + //foreach ($this->found_rows_result[0] as $key => $value) { + //$_column['FOUND_ROWS()'] = $value; + //} $column[] = new ObjectArray($_column); $this->results = $column; $this->found_rows_result = null; } - break; - case 'insert': - if ($this->can_insert_multiple_rows) { - $this->execute_insert_query_new($query); - } else { - $this->execute_insert_query($query); - } - break; - case 'create': - $result = $this->execute_create_query($query); - $this->return_value = $result; - break; - case 'alter': - $result = $this->execute_alter_query($query); - $this->return_value = $result; - break; - case 'show_variables': - $result = $this->show_variables_workaround($query); - break; - case 'showstatus': - $result = $this->show_status_workaround($query); - break; - case 'drop_index': - $pattern = '/^\\s*(DROP\\s*INDEX\\s*.*?)\\s*ON\\s*(.*)/im'; - if (preg_match($pattern, $query, $match)) { - $drop_query = 'ALTER TABLE ' . trim($match[2]) . ' ' . trim($match[1]); - $this->query_type = 'alter'; - $result = $this->execute_alter_query($drop_query); - $this->return_value = $result; - } else { - $this->return_value = false; - } - break; - default: - $engine = $this->prepare_engine($this->query_type); - $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); - $this->queries[] = "Rewritten:\n$this->rewritten_query"; - $this->extract_variables(); - $statement = $this->prepare_query(); - $this->execute_query($statement); - if (!$this->is_error) { - $this->process_results($engine); - } else {// Error - ; - } - break; - } - if (defined('PDO_DEBUG') && PDO_DEBUG === true) { - file_put_contents(FQDBDIR . 'debug.txt', $this->get_debug_info(), FILE_APPEND); - } - return $this->return_value; - } + break; + case 'insert': + if ($this->can_insert_multiple_rows) { + $this->execute_insert_query_new($query); + } else { + $this->execute_insert_query($query); + } + break; + case 'create': + $result = $this->execute_create_query($query); + $this->return_value = $result; + break; + case 'alter': + $result = $this->execute_alter_query($query); + $this->return_value = $result; + break; + case 'show_variables': + $result = $this->show_variables_workaround($query); + break; + case 'showstatus': + $result = $this->show_status_workaround($query); + break; + case 'drop_index': + $pattern = '/^\\s*(DROP\\s*INDEX\\s*.*?)\\s*ON\\s*(.*)/im'; + if (preg_match($pattern, $query, $match)) { + $drop_query = 'ALTER TABLE ' . trim($match[2]) . ' ' . trim($match[1]); + $this->query_type = 'alter'; + $result = $this->execute_alter_query($drop_query); + $this->return_value = $result; + } else { + $this->return_value = false; + } + break; + default: + $engine = $this->prepare_engine($this->query_type); + $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); + $this->queries[] = "Rewritten:\n$this->rewritten_query"; + $this->extract_variables(); + $statement = $this->prepare_query(); + $this->execute_query($statement); + if (!$this->is_error) { + $this->process_results($engine); + } else {// Error + ; + } + break; + } + if (defined('PDO_DEBUG') && PDO_DEBUG === true) { + file_put_contents(FQDBDIR . 'debug.txt', $this->get_debug_info(), FILE_APPEND); + } + return $this->return_value; + } /** * Method to return inserted row id. - * + * * @return unsigned integer */ - public function get_insert_id() { - return $this->last_insert_id; - } - /** - * Method to return the number of rows affected. - * - * @return unsigned integer - */ - public function get_affected_rows() { - return $this->affected_rows; - } - /** - * Method to return the queried column names. - * - * These data are meaningless for SQLite. So they are dummy emulating - * MySQL columns data. - * - * @return array of the object - */ - public function get_columns() { - if (!empty($this->results)) { - $primary_key = array( - 'meta_id', 'comment_ID', 'link_ID', 'option_id', - 'blog_id', 'option_name', 'ID', 'term_id', 'object_id', - 'term_taxonomy_id', 'umeta_id', 'id'); - $unique_key = array('term_id', 'taxonomy', 'slug'); - $data = array( - 'name' => '', // column name - 'table' => '', // table name - 'max_length' => 0, // max length of the column - 'not_null' => 1, // 1 if not null - 'primary_key' => 0, // 1 if column has primary key - 'unique_key' => 0, // 1 if column has unique key - 'multiple_key' => 0, // 1 if column doesn't have unique key - 'numeric' => 0, // 1 if column has numeric value - 'blob' => 0, // 1 if column is blob - 'type' => '', // type of the column - 'unsigned' => 0, // 1 if column is unsigned integer - 'zerofill' => 0 // 1 if column is zero-filled - ); - if (preg_match("/\s*FROM\s*(.*)?\s*/i", $this->rewritten_query, $match)) { - $table_name = trim($match[1]); - } else { - $table_name = ''; - } - foreach ($this->results[0] as $key => $value) { - $data['name'] = $key; - $data['table'] = $table_name; - if (in_array($key, $primary_key)) { - $data['primary_key'] = 1; - } elseif (in_array($key, $unique_key)) { - $data['unique_key'] = 1; - } else { - $data['multiple_key'] = 1; - } - $this->column_data[] = new ObjectArray($data); - $data['name'] = ''; - $data['table'] = ''; - $data['primary_key'] = 0; - $data['unique_key'] = 0; - $data['multiple_key'] = 0; - } - return $this->column_data; - } else { - return null; - } - } - /** - * Method to return the queried result data. - * - * @return mixed - */ - public function get_query_results() { - return $this->results; - } - /** - * Method to return the number of rows from the queried result. - * - * @return unsigned integer - */ - public function get_num_rows() { - return $this->num_rows; - } - /** - * Method to return the queried results according to the query types. - * - * @return mixed - */ - public function get_return_value() { - return $this->return_value; - } + public function get_insert_id() { + return $this->last_insert_id; + } + /** + * Method to return the number of rows affected. + * + * @return unsigned integer + */ + public function get_affected_rows() { + return $this->affected_rows; + } + /** + * Method to return the queried column names. + * + * These data are meaningless for SQLite. So they are dummy emulating + * MySQL columns data. + * + * @return array of the object + */ + public function get_columns() { + if (!empty($this->results)) { + $primary_key = array( + 'meta_id', 'comment_ID', 'link_ID', 'option_id', + 'blog_id', 'option_name', 'ID', 'term_id', 'object_id', + 'term_taxonomy_id', 'umeta_id', 'id'); + $unique_key = array('term_id', 'taxonomy', 'slug'); + $data = array( + 'name' => '', // column name + 'table' => '', // table name + 'max_length' => 0, // max length of the column + 'not_null' => 1, // 1 if not null + 'primary_key' => 0, // 1 if column has primary key + 'unique_key' => 0, // 1 if column has unique key + 'multiple_key' => 0, // 1 if column doesn't have unique key + 'numeric' => 0, // 1 if column has numeric value + 'blob' => 0, // 1 if column is blob + 'type' => '', // type of the column + 'unsigned' => 0, // 1 if column is unsigned integer + 'zerofill' => 0 // 1 if column is zero-filled + ); + if (preg_match("/\s*FROM\s*(.*)?\s*/i", $this->rewritten_query, $match)) { + $table_name = trim($match[1]); + } else { + $table_name = ''; + } + foreach ($this->results[0] as $key => $value) { + $data['name'] = $key; + $data['table'] = $table_name; + if (in_array($key, $primary_key)) { + $data['primary_key'] = 1; + } elseif (in_array($key, $unique_key)) { + $data['unique_key'] = 1; + } else { + $data['multiple_key'] = 1; + } + $this->column_data[] = new ObjectArray($data); + $data['name'] = ''; + $data['table'] = ''; + $data['primary_key'] = 0; + $data['unique_key'] = 0; + $data['multiple_key'] = 0; + } + return $this->column_data; + } else { + return null; + } + } + /** + * Method to return the queried result data. + * + * @return mixed + */ + public function get_query_results() { + return $this->results; + } + /** + * Method to return the number of rows from the queried result. + * + * @return unsigned integer + */ + public function get_num_rows() { + return $this->num_rows; + } + /** + * Method to return the queried results according to the query types. + * + * @return mixed + */ + public function get_return_value() { + return $this->return_value; + } /** * Method to return error messages. - * + * * @return string */ public function get_error_message(){ @@ -495,8 +495,8 @@ class PDOEngine extends PDO { } $output = '
 
'; if ($this->is_error === false){ -// return $output; - return ''; + //return $output; + return ''; } $output .= "
Queries made or created this session were
\r\n\t
    \r\n"; foreach ($this->queries as $q){ @@ -506,99 +506,99 @@ class PDOEngine extends PDO { foreach ($this->error_messages as $num=>$m){ $output .= "
    Error occurred at line {$this->errors[$num]['line']} in Function {$this->errors[$num]['function']}.
    Error message was: $m
    "; } - + ob_start(); debug_print_backtrace(); $output .= '
    ' . ob_get_contents() . '
    '; ob_end_clean(); return $output; - + } /** * Method to return information about query string for debugging. - * + * * @return string */ private function get_debug_info(){ - $output = ''; - foreach ($this->queries as $q){ - $output .= $q ."\n"; - } - return $output; + $output = ''; + foreach ($this->queries as $q){ + $output .= $q ."\n"; + } + return $output; } /** * Method to clear previous data. */ private function flush(){ - $this->rewritten_query = ''; - $this->query_type = ''; - $this->results = null; - $this->_results = null; - $this->last_insert_id = null; - $this->affected_rows = null; - $this->column_data = array(); - $this->num_rows = null; - $this->return_value = null; - $this->extracted_variables = array(); - $this->error_messages = array(); - $this->is_error = false; - $this->queries = array(); - $this->param_num = 0; + $this->rewritten_query = ''; + $this->query_type = ''; + $this->results = null; + $this->_results = null; + $this->last_insert_id = null; + $this->affected_rows = null; + $this->column_data = array(); + $this->num_rows = null; + $this->return_value = null; + $this->extracted_variables = array(); + $this->error_messages = array(); + $this->is_error = false; + $this->queries = array(); + $this->param_num = 0; } /** * Method to include the apropreate class files. - * + * * It is not a good habit to change the include files programatically. * Needs to be fixed some other way. - * + * * @param string $query_type * @return object reference to apropreate driver */ private function prepare_engine($query_type = null) { - if (stripos($query_type, 'create') !== false) { - require_once PDODIR . 'query_create.class.php'; - $engine = new CreateQuery(); - } elseif (stripos($query_type, 'alter') !== false) { - require_once PDODIR . 'query_alter.class.php'; - $engine = new AlterQuery(); - } else { - require_once PDODIR . 'query.class.php'; - $engine = new PDOSQLiteDriver(); - } - return $engine; + if (stripos($query_type, 'create') !== false) { + require_once PDODIR . 'query_create.class.php'; + $engine = new CreateQuery(); + } elseif (stripos($query_type, 'alter') !== false) { + require_once PDODIR . 'query_alter.class.php'; + $engine = new AlterQuery(); + } else { + require_once PDODIR . 'query.class.php'; + $engine = new PDOSQLiteDriver(); + } + return $engine; } /** * Method to create a PDO statement object from the query string. - * + * * @return PDOStatement */ - private function prepare_query(){ + private function prepare_query(){ $this->queries[] = "Prepare:\n" . $this->prepared_query; $reason = 0; $message = ''; $statement = null; do { - try { - $statement = $this->pdo->prepare($this->prepared_query); - } catch (PDOException $err) { - $reason = $err->getCode(); - $message = $err->getMessage(); - } + try { + $statement = $this->pdo->prepare($this->prepared_query); + } catch (PDOException $err) { + $reason = $err->getCode(); + $message = $err->getMessage(); + } } while (5 == $reason || 6 == $reason); - + if ($reason > 0){ $err_message = sprintf("Problem preparing the PDO SQL Statement. Error was: %s", $message); - $this->set_error(__LINE__, __FUNCTION__, $err_message); + $this->set_error(__LINE__, __FUNCTION__, $err_message); } return $statement; } /** * Method to execute PDO statement object. - * + * * This function executes query and sets the variables to give back to WordPress. * The variables are class fields. So if success, no return value. If failure, it * returns void and stops. - * + * * @param object $statement of PDO statement * @return boolean */ @@ -621,35 +621,35 @@ class PDOEngine extends PDO { $this->rollBack(); } } else { - try { - $statement->execute($this->extracted_variables); - } catch (PDOException $err) { - $reason = $err->getCode(); - $message = $err->getMessage(); - } + try { + $statement->execute($this->extracted_variables); + } catch (PDOException $err) { + $reason = $err->getCode(); + $message = $err->getMessage(); + } } } while (5 == $reason || 6 == $reason); } else { $this->queries[] = 'Executing: (no parameters)'; do{ - if ($this->query_type == 'update' || $this->query_type == 'replace') { - try { - $this->beginTransaction(); - $statement->execute(); - $this->commit(); - } catch (PDOException $err) { - $reason = $err->getCode(); - $message = $err->getMessage(); - $this->rollBack(); - } - } else { + if ($this->query_type == 'update' || $this->query_type == 'replace') { try { - $statement->execute(); - } catch (PDOException $err) { - $reason = $err->getCode(); - $message = $err->getMessage(); - } - } + $this->beginTransaction(); + $statement->execute(); + $this->commit(); + } catch (PDOException $err) { + $reason = $err->getCode(); + $message = $err->getMessage(); + $this->rollBack(); + } + } else { + try { + $statement->execute(); + } catch (PDOException $err) { + $reason = $err->getCode(); + $message = $err->getMessage(); + } + } } while (5 == $reason || 6 == $reason); } if ($reason > 0) { @@ -673,17 +673,17 @@ class PDOEngine extends PDO { case 'showcolumns': case 'showindex': case 'describe': - case 'desc': - case 'check': - case 'analyze': -// case "foundrows": + case 'desc': + case 'check': + case 'analyze': + //case "foundrows": $this->num_rows = count($this->_results); $this->return_value = $this->num_rows; - break; + break; case 'delete': $this->affected_rows = $statement->rowCount(); $this->return_value = $this->affected_rows; - break; + break; case 'alter': case 'drop': case 'create': @@ -699,10 +699,10 @@ class PDOEngine extends PDO { } /** * Method to extract field data to an array and prepare the query statement. - * + * * If original SQL statement is CREATE query, this function do nothing and return * true. This returned value is not used. - * + * * @return boolean */ private function extract_variables() { @@ -710,7 +710,7 @@ class PDOEngine extends PDO { $this->prepared_query = $this->rewritten_query; return true; } - + //long queries can really kill this $pattern = '/(?rewritten_query); + $query = preg_replace_callback($pattern, array($this,'replace_variables_with_placeholders'), $this->rewritten_query); } $limit = $limit * 10; } while (empty($query)); - + //reset the pcre.backtrack_limist ini_set('pcre.backtrack_limit', $_limit); $this->queries[] = "With Placeholders:\n" . $query; @@ -733,17 +733,17 @@ class PDOEngine extends PDO { } /** * Call back function to replace field data with PDO parameter. - * + * * @param string $matches * @return string */ private function replace_variables_with_placeholders($matches) { //remove the wordpress escaping mechanism $param = stripslashes($matches[0]); - + //remove trailing spaces - $param = trim($param); - + $param = trim($param); + //remove the quotes at the end and the beginning if (in_array($param{strlen($param)-1}, array("'",'"'))) { $param = substr($param,0,-1) ;//end @@ -761,581 +761,581 @@ class PDOEngine extends PDO { /** * Method to determine which query type the argument is. - * - * It takes the query string ,determines the type and returns the type string. - * If the query is the type that SQLite Integration can't executes, returns false. - * - * @param string $query - * @return boolean|string - */ - private function determine_query_type($query) { - $result = preg_match('/^\\s*(SET|EXPLAIN|PRAGMA|SELECT\\s*FOUND_ROWS|SELECT|INSERT|UPDATE|REPLACE|DELETE|ALTER|CREATE|DROP\\s*INDEX|DROP|SHOW\\s*\\w+\\s*\\w+\\s*|DESCRIBE|DESC|TRUNCATE|OPTIMIZE|CHECK|ANALYZE)/i', $query, $match); - - if (!$result) { - return false; - } - $this->query_type = strtolower($match[1]); - if (stripos($this->query_type, 'found') !== false) { - $this->query_type = 'foundrows'; - } - if (stripos($this->query_type, 'show') !== false) { - if (stripos($this->query_type, 'show table status') !== false) { - $this->query_type = 'showstatus'; - } elseif (stripos($this->query_type, 'show tables') !== false || stripos($this->query_type, 'show full tables') !== false) { - $this->query_type = 'show'; - } elseif (stripos($this->query_type, 'show columns') !== false || stripos($this->query_type, 'show fields') !== false || stripos($this->query_type, 'show full columns') !== false) { - $this->query_type = 'showcolumns'; - } elseif (stripos($this->query_type, 'show index') !== false || stripos($this->query_type, 'show indexes') !== false || stripos($this->query_type, 'show keys') !== false) { - $this->query_type = 'showindex'; - } elseif (stripos($this->query_type, 'show variables') !== false || stripos($this->query_type, 'show global variables') !== false || stripos($this->query_type, 'show session variables') !== false) { - $this->query_type = 'show_variables'; - } else { - return false; - } - } - if (stripos($this->query_type, 'drop index') !== false) { - $this->query_type = 'drop_index'; - } - return true; - } + * + * It takes the query string ,determines the type and returns the type string. + * If the query is the type that SQLite Integration can't executes, returns false. + * + * @param string $query + * @return boolean|string + */ + private function determine_query_type($query) { + $result = preg_match('/^\\s*(SET|EXPLAIN|PRAGMA|SELECT\\s*FOUND_ROWS|SELECT|INSERT|UPDATE|REPLACE|DELETE|ALTER|CREATE|DROP\\s*INDEX|DROP|SHOW\\s*\\w+\\s*\\w+\\s*|DESCRIBE|DESC|TRUNCATE|OPTIMIZE|CHECK|ANALYZE)/i', $query, $match); - /** - * Method to execute INSERT query for SQLite version 3.7.11 or later. - * - * SQLite version 3.7.11 began to support multiple rows insert with values - * clause. This is for that version or later. - * - * @param string $query - */ - private function execute_insert_query_new($query) { - $engine = $this->prepare_engine($this->query_type); - $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); - $this->queries[] = "Rewritten:\n" . $this->rewritten_query; - $this->extract_variables(); - $statement = $this->prepare_query(); - $this->execute_query($statement); - } - /** - * Method to execute INSERT query for SQLite version 3.7.10 or lesser. - * - * It executes the INSERT query for SQLite version 3.7.10 or lesser. It is - * necessary to rewrite multiple row values. - * - * @param string $query - */ - private function execute_insert_query($query) { - global $wpdb; - $multi_insert = false; - $statement = null; - $engine = $this->prepare_engine($this->query_type); - if (preg_match('/(INSERT.*?VALUES\\s*)(\(.*\))/imsx', $query, $matched)) { - $query_prefix = $matched[1]; - $values_data = $matched[2]; - if (stripos($values_data, 'ON DUPLICATE KEY') !== false) { - $exploded_parts = $values_data; - } elseif (stripos($query_prefix, "INSERT INTO $wpdb->comments") !== false) { - $exploded_parts = $values_data; - } else { - $exploded_parts = $this->parse_multiple_inserts($values_data); - } - $count = count($exploded_parts); - if ($count > 1) { - $multi_insert = true; - } - } - if ($multi_insert) { - $first = true; - foreach ($exploded_parts as $value) { - if (substr($value, -1, 1) === ')') { - $suffix = ''; - } else { - $suffix = ')'; - } - $query_string = $query_prefix . ' ' . $value . $suffix; - $this->rewritten_query = $engine->rewrite_query($query_string, $this->query_type); - $this->queries[] = "Rewritten:\n" . $this->rewritten_query; - $this->extracted_variables = array(); - $this->extract_variables(); - if ($first) { - $statement = $this->prepare_query(); - $this->execute_query($statement); - $first = false; - } else { - $this->execute_query($statement); - } - } - } else { - $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); - $this->queries[] = "Rewritten:\n" . $this->rewritten_query; - $this->extract_variables(); - $statement = $this->prepare_query(); - $this->execute_query($statement); - } - } + if (!$result) { + return false; + } + $this->query_type = strtolower($match[1]); + if (stripos($this->query_type, 'found') !== false) { + $this->query_type = 'foundrows'; + } + if (stripos($this->query_type, 'show') !== false) { + if (stripos($this->query_type, 'show table status') !== false) { + $this->query_type = 'showstatus'; + } elseif (stripos($this->query_type, 'show tables') !== false || stripos($this->query_type, 'show full tables') !== false) { + $this->query_type = 'show'; + } elseif (stripos($this->query_type, 'show columns') !== false || stripos($this->query_type, 'show fields') !== false || stripos($this->query_type, 'show full columns') !== false) { + $this->query_type = 'showcolumns'; + } elseif (stripos($this->query_type, 'show index') !== false || stripos($this->query_type, 'show indexes') !== false || stripos($this->query_type, 'show keys') !== false) { + $this->query_type = 'showindex'; + } elseif (stripos($this->query_type, 'show variables') !== false || stripos($this->query_type, 'show global variables') !== false || stripos($this->query_type, 'show session variables') !== false) { + $this->query_type = 'show_variables'; + } else { + return false; + } + } + if (stripos($this->query_type, 'drop index') !== false) { + $this->query_type = 'drop_index'; + } + return true; + } - /** - * Method to help rewriting multiple row values insert query. - * - * It splits the values clause into an array to execute separately. - * - * @param string $values - * @return array - */ - private function parse_multiple_inserts($values) { - $tokens = preg_split("/(''|(?prepare_engine($this->query_type); - $rewritten_query = $engine->rewrite_query($query); - $reason = 0; - $message = ''; -// $queries = explode(";", $this->rewritten_query); - try { - $this->beginTransaction(); - foreach ($rewritten_query as $single_query) { - $this->queries[] = "Executing:\n" . $single_query; - $single_query = trim($single_query); - if (empty($single_query)) continue; - $this->pdo->exec($single_query); - } - $this->commit(); - } catch (PDOException $err) { - $reason = $err->getCode(); - $message = $err->getMessage(); - if (5 == $reason || 6 == $reason) { - $this->commit(); - } else { - $this->rollBack(); - } - } - if ($reason > 0) { - $err_message = sprintf("Problem in creating table or index. Error was: %s", $message); - $this->set_error(__LINE__, __FUNCTION__, $err_message); - return false; - } - return true; - } - /** - * Method to execute ALTER TABLE query. - * - * @param string - * @return boolean - */ - private function execute_alter_query($query) { - $engine = $this->prepare_engine($this->query_type); - $reason = 0; - $message = ''; - $re_query = ''; - $rewritten_query = $engine->rewrite_query($query, $this->query_type); - if (is_array($rewritten_query) && array_key_exists('recursion', $rewritten_query)) { - $re_query = $rewritten_query['recursion']; - unset($rewritten_query['recursion']); - } - try { - $this->beginTransaction(); - if (is_array($rewritten_query)) { - foreach ($rewritten_query as $single_query) { - $this->queries[] = "Executing:\n" . $single_query; - $single_query = trim($single_query); - if (empty($single_query)) continue; - $this->pdo->exec($single_query); - } - } else { - $this->queries[] = "Executing:\n" . $rewritten_query; - $rewritten_query = trim($rewritten_query); - $this->pdo->exec($rewritten_query); - } - $this->commit(); - } catch (PDOException $err) { - $reason = $err->getCode(); - $message = $err->getMessage(); - if (5 == $reason || 6 == $reason) { - $this->commit(); - usleep(10000); - } else { - $this->rollBack(); - } - } - if ($re_query != '') { - $this->query($re_query); - } - if ($reason > 0) { - $err_message = sprintf("Problem in executing alter query. Error was: %s", $message); - $this->set_error(__LINE__, __FUNCTION__, $err_message); - return false; - } - return true; - } - - /** - * Method to execute SHOW VARIABLES query - * - * This query is meaningless for SQLite. This function returns null data with some - * exceptions and only avoids the error message. - * - * @param string - * @return ObjectArray - */ - private function show_variables_workaround($query) { - $dummy_data = array('Variable_name' => '', 'Value' => null); - $pattern = '/SHOW\\s*VARIABLES\\s*LIKE\\s*(.*)?$/im'; - if (preg_match($pattern, $query, $match)) { - $value = str_replace("'", '', $match[1]); - $dummy_data['Variable_name'] = trim($value); - // this is set for Wordfence Security Plugin - if ($value == 'max_allowed_packet') { + /** + * Method to execute INSERT query for SQLite version 3.7.11 or later. + * + * SQLite version 3.7.11 began to support multiple rows insert with values + * clause. This is for that version or later. + * + * @param string $query + */ + private function execute_insert_query_new($query) { + $engine = $this->prepare_engine($this->query_type); + $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); + $this->queries[] = "Rewritten:\n" . $this->rewritten_query; + $this->extract_variables(); + $statement = $this->prepare_query(); + $this->execute_query($statement); + } + /** + * Method to execute INSERT query for SQLite version 3.7.10 or lesser. + * + * It executes the INSERT query for SQLite version 3.7.10 or lesser. It is + * necessary to rewrite multiple row values. + * + * @param string $query + */ + private function execute_insert_query($query) { + global $wpdb; + $multi_insert = false; + $statement = null; + $engine = $this->prepare_engine($this->query_type); + if (preg_match('/(INSERT.*?VALUES\\s*)(\(.*\))/imsx', $query, $matched)) { + $query_prefix = $matched[1]; + $values_data = $matched[2]; + if (stripos($values_data, 'ON DUPLICATE KEY') !== false) { + $exploded_parts = $values_data; + } elseif (stripos($query_prefix, "INSERT INTO $wpdb->comments") !== false) { + $exploded_parts = $values_data; + } else { + $exploded_parts = $this->parse_multiple_inserts($values_data); + } + $count = count($exploded_parts); + if ($count > 1) { + $multi_insert = true; + } + } + if ($multi_insert) { + $first = true; + foreach ($exploded_parts as $value) { + if (substr($value, -1, 1) === ')') { + $suffix = ''; + } else { + $suffix = ')'; + } + $query_string = $query_prefix . ' ' . $value . $suffix; + $this->rewritten_query = $engine->rewrite_query($query_string, $this->query_type); + $this->queries[] = "Rewritten:\n" . $this->rewritten_query; + $this->extracted_variables = array(); + $this->extract_variables(); + if ($first) { + $statement = $this->prepare_query(); + $this->execute_query($statement); + $first = false; + } else { + $this->execute_query($statement); + } + } + } else { + $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); + $this->queries[] = "Rewritten:\n" . $this->rewritten_query; + $this->extract_variables(); + $statement = $this->prepare_query(); + $this->execute_query($statement); + } + } + + /** + * Method to help rewriting multiple row values insert query. + * + * It splits the values clause into an array to execute separately. + * + * @param string $values + * @return array + */ + private function parse_multiple_inserts($values) { + $tokens = preg_split("/(''|(?prepare_engine($this->query_type); + $rewritten_query = $engine->rewrite_query($query); + $reason = 0; + $message = ''; + //$queries = explode(";", $this->rewritten_query); + try { + $this->beginTransaction(); + foreach ($rewritten_query as $single_query) { + $this->queries[] = "Executing:\n" . $single_query; + $single_query = trim($single_query); + if (empty($single_query)) continue; + $this->pdo->exec($single_query); + } + $this->commit(); + } catch (PDOException $err) { + $reason = $err->getCode(); + $message = $err->getMessage(); + if (5 == $reason || 6 == $reason) { + $this->commit(); + } else { + $this->rollBack(); + } + } + if ($reason > 0) { + $err_message = sprintf("Problem in creating table or index. Error was: %s", $message); + $this->set_error(__LINE__, __FUNCTION__, $err_message); + return false; + } + return true; + } + /** + * Method to execute ALTER TABLE query. + * + * @param string + * @return boolean + */ + private function execute_alter_query($query) { + $engine = $this->prepare_engine($this->query_type); + $reason = 0; + $message = ''; + $re_query = ''; + $rewritten_query = $engine->rewrite_query($query, $this->query_type); + if (is_array($rewritten_query) && array_key_exists('recursion', $rewritten_query)) { + $re_query = $rewritten_query['recursion']; + unset($rewritten_query['recursion']); + } + try { + $this->beginTransaction(); + if (is_array($rewritten_query)) { + foreach ($rewritten_query as $single_query) { + $this->queries[] = "Executing:\n" . $single_query; + $single_query = trim($single_query); + if (empty($single_query)) continue; + $this->pdo->exec($single_query); + } + } else { + $this->queries[] = "Executing:\n" . $rewritten_query; + $rewritten_query = trim($rewritten_query); + $this->pdo->exec($rewritten_query); + } + $this->commit(); + } catch (PDOException $err) { + $reason = $err->getCode(); + $message = $err->getMessage(); + if (5 == $reason || 6 == $reason) { + $this->commit(); + usleep(10000); + } else { + $this->rollBack(); + } + } + if ($re_query != '') { + $this->query($re_query); + } + if ($reason > 0) { + $err_message = sprintf("Problem in executing alter query. Error was: %s", $message); + $this->set_error(__LINE__, __FUNCTION__, $err_message); + return false; + } + return true; + } + + /** + * Method to execute SHOW VARIABLES query + * + * This query is meaningless for SQLite. This function returns null data with some + * exceptions and only avoids the error message. + * + * @param string + * @return ObjectArray + */ + private function show_variables_workaround($query) { + $dummy_data = array('Variable_name' => '', 'Value' => null); + $pattern = '/SHOW\\s*VARIABLES\\s*LIKE\\s*(.*)?$/im'; + if (preg_match($pattern, $query, $match)) { + $value = str_replace("'", '', $match[1]); + $dummy_data['Variable_name'] = trim($value); + // this is set for Wordfence Security Plugin + if ($value == 'max_allowed_packet') { $dummy_data['Value'] = 1047552; } else { $dummy_data['Value'] = ''; } - } - $_results[] = new ObjectArray($dummy_data); - $this->results = $_results; - $this->num_rows = count($this->results); - $this->return_value = $this->num_rows; - return true; - } - /** - * Method to execute SHOW TABLE STATUS query. - * - * This query is meaningless for SQLite. This function return dummy data. - * - * @param string - * @return ObjectArray - */ - private function show_status_workaround($query) { - $pattern = '/^SHOW\\s*TABLE\\s*STATUS\\s*LIKE\\s*(.*?)$/im'; - if (preg_match($pattern, $query, $match)) { - $table_name = str_replace("'", '', $match[1]); - } else { - $table_name = ''; - } - $dummy_data = array( - 'Name' => $table_name, 'Engine' => '', 'Version' => '', - 'Row_format' => '', 'Rows' => 0, 'Avg_row_length' => 0, - 'Data_length' => 0, 'Max_data_length' => 0, 'Index_length' => 0, - 'Data_free' => 0, 'Auto_increment' => 0, 'Create_time' => '', - 'Update_time' => '', 'Check_time' => '', 'Collation' => '', - 'Checksum' => '', 'Create_options' => '', 'Comment' => '' - ); - $_results[] = new ObjectArray($dummy_data); - $this->results = $_results; - $this->num_rows = count($this->results); - $this->return_value = $this->num_rows; - return true; - } - /** - * Method to format the queried data to that of MySQL. - * - * @param string $engine - */ - private function process_results($engine) { - if (in_array($this->query_type, array('describe', 'desc', 'showcolumns'))) { - $this->convert_to_columns_object(); - } elseif ('showindex' === $this->query_type){ - $this->convert_to_index_object(); - } elseif (in_array($this->query_type, array('check', 'analyze'))) { - $this->convert_result_check_or_analyze(); - } else { - $this->results = $this->_results; - } - } + } + $_results[] = new ObjectArray($dummy_data); + $this->results = $_results; + $this->num_rows = count($this->results); + $this->return_value = $this->num_rows; + return true; + } + /** + * Method to execute SHOW TABLE STATUS query. + * + * This query is meaningless for SQLite. This function return dummy data. + * + * @param string + * @return ObjectArray + */ + private function show_status_workaround($query) { + $pattern = '/^SHOW\\s*TABLE\\s*STATUS\\s*LIKE\\s*(.*?)$/im'; + if (preg_match($pattern, $query, $match)) { + $table_name = str_replace("'", '', $match[1]); + } else { + $table_name = ''; + } + $dummy_data = array( + 'Name' => $table_name, 'Engine' => '', 'Version' => '', + 'Row_format' => '', 'Rows' => 0, 'Avg_row_length' => 0, + 'Data_length' => 0, 'Max_data_length' => 0, 'Index_length' => 0, + 'Data_free' => 0, 'Auto_increment' => 0, 'Create_time' => '', + 'Update_time' => '', 'Check_time' => '', 'Collation' => '', + 'Checksum' => '', 'Create_options' => '', 'Comment' => '' + ); + $_results[] = new ObjectArray($dummy_data); + $this->results = $_results; + $this->num_rows = count($this->results); + $this->return_value = $this->num_rows; + return true; + } + /** + * Method to format the queried data to that of MySQL. + * + * @param string $engine + */ + private function process_results($engine) { + if (in_array($this->query_type, array('describe', 'desc', 'showcolumns'))) { + $this->convert_to_columns_object(); + } elseif ('showindex' === $this->query_type){ + $this->convert_to_index_object(); + } elseif (in_array($this->query_type, array('check', 'analyze'))) { + $this->convert_result_check_or_analyze(); + } else { + $this->results = $this->_results; + } + } /** * Method to format the error messages and put out to the file. - * + * * When $wpdb::suppress_errors is set to true or $wpdb::show_errors is set to false, * the error messages are ignored. - * + * * @param string $line where the error occurred. * @param string $function to indicate the function name where the error occurred. * @param string $message * @return boolean */ - private function set_error ($line, $function, $message){ - global $wpdb; - $this->errors[] = array("line"=>$line, "function"=>$function); - $this->error_messages[] = $message; - $this->is_error = true; - if ($wpdb->suppress_errors) return false; - if (!$wpdb->show_errors) return false; - file_put_contents (FQDBDIR .'debug.txt', "Line $line, Function: $function, Message: $message \n", FILE_APPEND); - } - /** - * Method to change the queried data to PHP object format. - * - * It takes the associative array of query results and creates a numeric - * array of anonymous objects - * - * @access private - */ - private function convert_to_object(){ - $_results = array(); - if (count ($this->results) === 0){ - echo $this->get_error_message(); - } else { - foreach($this->results as $row){ - $_results[] = new ObjectArray($row); - } - } - $this->results = $_results; - } - /** - * Method to convert the SHOW COLUMNS query data to an object. - * - * It rewrites pragma results to mysql compatible array - * when query_type is describe, we use sqlite pragma function. - * - * @access private - */ - private function convert_to_columns_object() { - $_results = array(); - $_columns = array( //Field names MySQL SHOW COLUMNS returns - 'Field' => "", - 'Type' => "", - 'Null' => "", - 'Key' => "", - 'Default' => "", - 'Extra' => "" - ); - if (count($this->_results) === 0) { - echo $this->get_error_message(); - } else { - foreach ($this->_results as $row) { - $_columns['Field'] = $row->name; - $_columns['Type'] = $row->type; - $_columns['Null'] = $row->notnull ? "NO" : "YES"; - $_columns['Key'] = $row->pk ? "PRI" : ""; - $_columns['Default'] = $row->dflt_value; - $_results[] = new ObjectArray($_columns); - } - } - $this->results = $_results; - } - /** - * Method to convert SHOW INDEX query data to PHP object. - * - * It rewrites the result of SHOW INDEX to the Object compatible with MySQL - * added the WHERE clause manipulation (ver 1.3.1) - * - * @access private - */ - private function convert_to_index_object() { - $_results = array(); - $_columns = array( - 'Table' => "", - 'Non_unique' => "",// unique -> 0, not unique -> 1 - 'Key_name' => "",// the name of the index - 'Seq_in_index' => "",// column sequence number in the index. begins at 1 - 'Column_name' => "", - 'Collation' => "",//A(scend) or NULL - 'Cardinality' => "", - 'Sub_part' => "",// set to NULL - 'Packed' => "",// How to pack key or else NULL - 'Null' => "",// If column contains null, YES. If not, NO. - 'Index_type' => "",// BTREE, FULLTEXT, HASH, RTREE - 'Comment' => "" - ); - if (count($this->_results) == 0) { - echo $this->get_error_message(); - } else { - foreach ($this->_results as $row) { - if ($row->type == 'table' && !stripos($row->sql, 'primary')) - continue; - if ($row->type == 'index' && stripos($row->name, 'sqlite_autoindex') !== false) - continue; - switch ($row->type) { - case 'table': - $pattern1 = '/^\\s*PRIMARY.*\((.*)\)/im'; - $pattern2 = '/^\\s*(\\w+)?\\s*.*PRIMARY.*(?!\()/im'; - if (preg_match($pattern1, $row->sql, $match)) { - $col_name = trim($match[1]); - $_columns['Key_name'] = 'PRIMARY'; - $_columns['Non_unique'] = 0; - $_columns['Column_name'] = $col_name; - } elseif (preg_match($pattern2, $row->sql, $match)) { - $col_name = trim($match[1]); - $_columns['Key_name'] = 'PRIMARY'; - $_columns['Non_unique'] = 0; - $_columns['Column_name'] = $col_name; - } - break; - case 'index': - if (stripos($row->sql, 'unique') !== false) { - $_columns['Non_unique'] = 0; - } else { - $_columns['Non_unique'] = 1; - } - if (preg_match('/^.*\((.*)\)/i', $row->sql, $match)) { - $col_name = str_replace("'", '', $match[1]); - $_columns['Column_name'] = trim($col_name); - } - $_columns['Key_name'] = $row->name; - break; - default: - break; - } - $_columns['Table'] = $row->tbl_name; - $_columns['Collation'] = NULL; - $_columns['Cardinality'] = 0; - $_columns['Sub_part'] = NULL; - $_columns['Packed'] = NULL; - $_columns['Null'] = 'NO'; - $_columns['Index_type'] = 'BTREE'; - $_columns['Comment'] = ''; - $_results[] = new ObjectArray($_columns); - } - if (stripos($this->queries[0], 'WHERE') !== false) { - preg_match('/WHERE\\s*(.*)$/im', $this->queries[0], $match); - list($key, $value) = explode('=', $match[1]); - $key = trim($key); - $value = preg_replace("/[\';]/", '', $value); - $value = trim($value); - foreach ($_results as $result) { - if (stripos($value, $result->$key) !== false) { - unset($_results); - $_results[] = $result; - break; - } - } - } - } - $this->results = $_results; - } + private function set_error ($line, $function, $message){ + global $wpdb; + $this->errors[] = array("line"=>$line, "function"=>$function); + $this->error_messages[] = $message; + $this->is_error = true; + if ($wpdb->suppress_errors) return false; + if (!$wpdb->show_errors) return false; + file_put_contents (FQDBDIR .'debug.txt', "Line $line, Function: $function, Message: $message \n", FILE_APPEND); + } /** - * Method to the CHECK query data to an object. - * + * Method to change the queried data to PHP object format. + * + * It takes the associative array of query results and creates a numeric + * array of anonymous objects + * * @access private */ - private function convert_result_check_or_analyze() { - $results = array(); - if ($this->query_type == 'check') { - $_columns = array( - 'Table' => '', - 'Op' => 'check', - 'Msg_type' => 'status', - 'Msg_text' => 'OK' - ); - } else { - $_columns = array( - 'Table' => '', - 'Op' => 'analyze', - 'Msg_type' => 'status', - 'Msg_text' => 'Table is already up to date' - ); - } - $_results[] = new ObjectArray($_columns); - $this->results = $_results; - } - /** - * Method to check SQLite library version. - * - * This is used for checking if SQLite can execute multiple rows insert. - * - * @return version number string or 0 - * @access private - */ - private function get_sqlite_version() { - try { - $statement = $this->pdo->prepare('SELECT sqlite_version()'); - $statement->execute(); - $result = $statement->fetch(PDO::FETCH_NUM); - return $result[0]; - } catch (PDOException $err) { - return '0'; - } - } - /** - * Method to call PDO::beginTransaction(). - * - * @see PDO::beginTransaction() - * @return boolean - */ - public function beginTransaction() { - if ($this->has_active_transaction) { - return false; - } else { - $this->has_active_transaction = $this->pdo->beginTransaction(); - return $this->has_active_transaction; - } - } - /** - * Method to call PDO::commit(). - * - * @see PDO::commit() - */ - public function commit() { - $this->pdo->commit(); - $this->has_active_transaction = false; - } - /** - * Method to call PDO::rollBack(). - * - * @see PDO::rollBack() - */ - public function rollBack() { - $this->pdo->rollBack(); - $this->has_active_transaction = false; - } + private function convert_to_object(){ + $_results = array(); + if (count ($this->results) === 0){ + echo $this->get_error_message(); + } else { + foreach($this->results as $row){ + $_results[] = new ObjectArray($row); + } + } + $this->results = $_results; + } + /** + * Method to convert the SHOW COLUMNS query data to an object. + * + * It rewrites pragma results to mysql compatible array + * when query_type is describe, we use sqlite pragma function. + * + * @access private + */ + private function convert_to_columns_object() { + $_results = array(); + $_columns = array( //Field names MySQL SHOW COLUMNS returns + 'Field' => "", + 'Type' => "", + 'Null' => "", + 'Key' => "", + 'Default' => "", + 'Extra' => "" + ); + if (count($this->_results) === 0) { + echo $this->get_error_message(); + } else { + foreach ($this->_results as $row) { + $_columns['Field'] = $row->name; + $_columns['Type'] = $row->type; + $_columns['Null'] = $row->notnull ? "NO" : "YES"; + $_columns['Key'] = $row->pk ? "PRI" : ""; + $_columns['Default'] = $row->dflt_value; + $_results[] = new ObjectArray($_columns); + } + } + $this->results = $_results; + } + /** + * Method to convert SHOW INDEX query data to PHP object. + * + * It rewrites the result of SHOW INDEX to the Object compatible with MySQL + * added the WHERE clause manipulation (ver 1.3.1) + * + * @access private + */ + private function convert_to_index_object() { + $_results = array(); + $_columns = array( + 'Table' => "", + 'Non_unique' => "",// unique -> 0, not unique -> 1 + 'Key_name' => "",// the name of the index + 'Seq_in_index' => "",// column sequence number in the index. begins at 1 + 'Column_name' => "", + 'Collation' => "",//A(scend) or NULL + 'Cardinality' => "", + 'Sub_part' => "",// set to NULL + 'Packed' => "",// How to pack key or else NULL + 'Null' => "",// If column contains null, YES. If not, NO. + 'Index_type' => "",// BTREE, FULLTEXT, HASH, RTREE + 'Comment' => "" + ); + if (count($this->_results) == 0) { + echo $this->get_error_message(); + } else { + foreach ($this->_results as $row) { + if ($row->type == 'table' && !stripos($row->sql, 'primary')) + continue; + if ($row->type == 'index' && stripos($row->name, 'sqlite_autoindex') !== false) + continue; + switch ($row->type) { + case 'table': + $pattern1 = '/^\\s*PRIMARY.*\((.*)\)/im'; + $pattern2 = '/^\\s*(\\w+)?\\s*.*PRIMARY.*(?!\()/im'; + if (preg_match($pattern1, $row->sql, $match)) { + $col_name = trim($match[1]); + $_columns['Key_name'] = 'PRIMARY'; + $_columns['Non_unique'] = 0; + $_columns['Column_name'] = $col_name; + } elseif (preg_match($pattern2, $row->sql, $match)) { + $col_name = trim($match[1]); + $_columns['Key_name'] = 'PRIMARY'; + $_columns['Non_unique'] = 0; + $_columns['Column_name'] = $col_name; + } + break; + case 'index': + if (stripos($row->sql, 'unique') !== false) { + $_columns['Non_unique'] = 0; + } else { + $_columns['Non_unique'] = 1; + } + if (preg_match('/^.*\((.*)\)/i', $row->sql, $match)) { + $col_name = str_replace("'", '', $match[1]); + $_columns['Column_name'] = trim($col_name); + } + $_columns['Key_name'] = $row->name; + break; + default: + break; + } + $_columns['Table'] = $row->tbl_name; + $_columns['Collation'] = NULL; + $_columns['Cardinality'] = 0; + $_columns['Sub_part'] = NULL; + $_columns['Packed'] = NULL; + $_columns['Null'] = 'NO'; + $_columns['Index_type'] = 'BTREE'; + $_columns['Comment'] = ''; + $_results[] = new ObjectArray($_columns); + } + if (stripos($this->queries[0], 'WHERE') !== false) { + preg_match('/WHERE\\s*(.*)$/im', $this->queries[0], $match); + list($key, $value) = explode('=', $match[1]); + $key = trim($key); + $value = preg_replace("/[\';]/", '', $value); + $value = trim($value); + foreach ($_results as $result) { + if (stripos($value, $result->$key) !== false) { + unset($_results); + $_results[] = $result; + break; + } + } + } + } + $this->results = $_results; + } + /** + * Method to the CHECK query data to an object. + * + * @access private + */ + private function convert_result_check_or_analyze() { + $results = array(); + if ($this->query_type == 'check') { + $_columns = array( + 'Table' => '', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'OK' + ); + } else { + $_columns = array( + 'Table' => '', + 'Op' => 'analyze', + 'Msg_type' => 'status', + 'Msg_text' => 'Table is already up to date' + ); + } + $_results[] = new ObjectArray($_columns); + $this->results = $_results; + } + /** + * Method to check SQLite library version. + * + * This is used for checking if SQLite can execute multiple rows insert. + * + * @return version number string or 0 + * @access private + */ + private function get_sqlite_version() { + try { + $statement = $this->pdo->prepare('SELECT sqlite_version()'); + $statement->execute(); + $result = $statement->fetch(PDO::FETCH_NUM); + return $result[0]; + } catch (PDOException $err) { + return '0'; + } + } + /** + * Method to call PDO::beginTransaction(). + * + * @see PDO::beginTransaction() + * @return boolean + */ + public function beginTransaction() { + if ($this->has_active_transaction) { + return false; + } else { + $this->has_active_transaction = $this->pdo->beginTransaction(); + return $this->has_active_transaction; + } + } + /** + * Method to call PDO::commit(). + * + * @see PDO::commit() + */ + public function commit() { + $this->pdo->commit(); + $this->has_active_transaction = false; + } + /** + * Method to call PDO::rollBack(). + * + * @see PDO::rollBack() + */ + public function rollBack() { + $this->pdo->rollBack(); + $this->has_active_transaction = false; + } } /** * Class to change queried data to PHP object. - * + * * @author kjm */ class ObjectArray { - function __construct($data = null,&$node= null) { - foreach ($data as $key => $value) { - if ( is_array($value) ) { - if (!$node) { - $node =& $this; - } - $node->$key = new stdClass(); - self::__construct($value,$node->$key); - } else { - if (!$node) { - $node =& $this; - } - $node->$key = $value; - } - } - } + function __construct($data = null,&$node= null) { + foreach ($data as $key => $value) { + if ( is_array($value) ) { + if (!$node) { + $node =& $this; + } + $node->$key = new stdClass(); + self::__construct($value,$node->$key); + } else { + if (!$node) { + $node =& $this; + } + $node->$key = $value; + } + } + } } ?> \ No newline at end of file diff --git a/query.class.php b/query.class.php index 44c5165..f23feba 100644 --- a/query.class.php +++ b/query.class.php @@ -1,148 +1,154 @@ query_type = $query_type; - $this->_query = $query; - $this->parse_query(); + $this->_query = $query; + $this->parse_query(); switch ($this->query_type) { - case 'truncate': - $this->handle_truncate_query(); - break; - case 'alter': - $this->handle_alter_query(); - break; - case 'create': - $this->handle_create_query(); - break; - case 'describe': - case 'desc': - $this->handle_describe_query(); - break; - case 'show': - $this->handle_show_query(); - break; - case 'showcolumns': - $this->handle_show_columns_query(); - break; - case 'showindex': - $this->handle_show_index(); - break; - case 'select': - //$this->strip_backticks(); - $this->handle_sql_count(); - $this->rewrite_date_sub(); - $this->delete_index_hints(); - $this->rewrite_regexp(); - //$this->rewrite_boolean(); - $this->fix_date_quoting(); - $this->rewrite_between(); - break; - case 'insert': - //$this->safe_strip_backticks(); - $this->execute_duplicate_key_update(); - $this->rewrite_insert_ignore(); - $this->rewrite_regexp(); - $this->fix_date_quoting(); - break; - case 'update': - //$this->safe_strip_backticks(); - $this->rewrite_update_ignore(); -// $this->_rewrite_date_sub(); - $this->rewrite_limit_usage(); - $this->rewrite_order_by_usage(); - $this->rewrite_regexp(); - $this->rewrite_between(); - break; - case 'delete': - //$this->strip_backticks(); - $this->rewrite_limit_usage(); - $this->rewrite_order_by_usage(); - $this->rewrite_date_sub(); - $this->rewrite_regexp(); - $this->delete_workaround(); - break; - case 'replace': - //$this->safe_strip_backticks(); - $this->rewrite_date_sub(); - $this->rewrite_regexp(); - break; - case 'optimize': - $this->rewrite_optimize(); - break; - case 'pragma': - break; - default: - if (defined(WP_DEBUG) && WP_DEBUG) { - break; - } else { - $this->return_true(); - break; - } + case 'truncate': + $this->handle_truncate_query(); + break; + case 'alter': + $this->handle_alter_query(); + break; + case 'create': + $this->handle_create_query(); + break; + case 'describe': + case 'desc': + $this->handle_describe_query(); + break; + case 'show': + $this->handle_show_query(); + break; + case 'showcolumns': + $this->handle_show_columns_query(); + break; + case 'showindex': + $this->handle_show_index(); + break; + case 'select': + //$this->strip_backticks(); + $this->handle_sql_count(); + $this->rewrite_date_sub(); + $this->delete_index_hints(); + $this->rewrite_regexp(); + //$this->rewrite_boolean(); + $this->fix_date_quoting(); + $this->rewrite_between(); + break; + case 'insert': + //$this->safe_strip_backticks(); + $this->execute_duplicate_key_update(); + $this->rewrite_insert_ignore(); + $this->rewrite_regexp(); + $this->fix_date_quoting(); + break; + case 'update': + //$this->safe_strip_backticks(); + $this->rewrite_update_ignore(); + //$this->_rewrite_date_sub(); + $this->rewrite_limit_usage(); + $this->rewrite_order_by_usage(); + $this->rewrite_regexp(); + $this->rewrite_between(); + break; + case 'delete': + //$this->strip_backticks(); + $this->rewrite_limit_usage(); + $this->rewrite_order_by_usage(); + $this->rewrite_date_sub(); + $this->rewrite_regexp(); + $this->delete_workaround(); + break; + case 'replace': + //$this->safe_strip_backticks(); + $this->rewrite_date_sub(); + $this->rewrite_regexp(); + break; + case 'optimize': + $this->rewrite_optimize(); + break; + case 'pragma': + break; + default: + if (defined(WP_DEBUG) && WP_DEBUG) { + break; + } else { + $this->return_true(); + break; + } } return $this->_query; } /** * Method to parse query string and determine which operation is needed. - * + * * Remove backticks and change true/false values into 1/0. And determines * if rewriting CALC_FOUND_ROWS or ON DUPLICATE KEY UPDATE etc is needed. - * + * * @access private */ private function parse_query() { @@ -161,29 +167,30 @@ class PDOSQLiteDriver { if (strpos($token, '`') !== false) { $token = str_replace('`', '', $token); } - if (preg_match('/\\bTRUE\\b/i', $token)) { - $token = str_ireplace('TRUE', '1', $token); - } - if (preg_match('/\\bFALSE\\b/i', $token)) { - $token = str_ireplace('FALSE', '0', $token); - } - if (stripos($token, 'SQL_CALC_FOUND_ROWS') !== false) { + if (preg_match('/\\bTRUE\\b/i', $token)) { + $token = str_ireplace('TRUE', '1', $token); + } + if (preg_match('/\\bFALSE\\b/i', $token)) { + $token = str_ireplace('FALSE', '0', $token); + } + if (stripos($token, 'SQL_CALC_FOUND_ROWS') !== false) { $this->rewrite_calc_found = true; } - if (stripos($token, 'ON DUPLICATE KEY UPDATE') !== false) { + if (stripos($token, 'ON DUPLICATE KEY UPDATE') !== false) { $this->rewrite_duplicate_key = true; } - if (stripos($token, 'USE INDEX') !== false) { + if (stripos($token, 'USE INDEX') !== false) { $this->rewrite_index_hint = true; } - if (stripos($token, 'IGNORE INDEX') !== false) { + if (stripos($token, 'IGNORE INDEX') !== false) { $this->rewrite_index_hint = true; } - if (stripos($token, 'FORCE INDEX') !== false) { + if (stripos($token, 'FORCE INDEX') !== false) { $this->rewrite_index_hint = true; } - if (stripos($token, 'BETWEEN') !== false) { + if (stripos($token, 'BETWEEN') !== false) { $this->rewrite_between = true; + $this->num_of_rewrite_between++; } } } @@ -193,18 +200,18 @@ class PDOSQLiteDriver { } /** * method to handle SHOW TABLES query. - * + * * @access private */ private function handle_show_query(){ - $this->_query = str_ireplace(' FULL', '', $this->_query); - $table_name = ''; + $this->_query = str_ireplace(' FULL', '', $this->_query); + $table_name = ''; $pattern = '/^\\s*SHOW\\s*TABLES\\s*.*?(LIKE\\s*(.*))$/im'; if (preg_match($pattern, $this->_query, $matches)) { - $table_name = str_replace(array("'", ';'), '', $matches[2]); + $table_name = str_replace(array("'", ';'), '', $matches[2]); } if (!empty($table_name)) { - $suffix = ' AND name LIKE '. "'" . $table_name . "'"; + $suffix = ' AND name LIKE '. "'" . $table_name . "'"; } else { $suffix = ''; } @@ -212,12 +219,12 @@ class PDOSQLiteDriver { } /** * Method to strip all column qualifiers (backticks) from a query. - * + * * All the back quotes in the query string are removed automatically. * So it must not be used when INSERT, UPDATE or REPLACE query is executed. - * + * * Obsolite since 1.5.1 - * + * * @access private */ private function strip_backticks(){ @@ -225,12 +232,12 @@ class PDOSQLiteDriver { } /** * Method to strip all column qualifiers (backticks) from a query except post data. - * + * * All the back quotes execpt user data to be inserted are revomved automatically. * This method must be used when INSERT, UPDATE or REPLACE query is executed. - * + * * Obsolite since 1.5.1 - * + * * @access private */ private function safe_strip_backticks() { @@ -261,12 +268,12 @@ class PDOSQLiteDriver { * 1. remove SQL_CALC_FOUND_ROWS option, and give it to the pdo engine * 2. make another $wpdb instance, and execute the rewritten query * 3. give the returned value (integer: number of the rows) to the original instance variable without LIMIT - * + * * We no longer use SELECT COUNT query, because it returns the inexact values when used with WP_Meta_Query(). - * + * * This kind of statement is required for WordPress to calculate the paging information. * see also WP_Query class in wp-includes/query.php - * + * * @access private */ private function handle_sql_count(){ @@ -276,8 +283,8 @@ class PDOSQLiteDriver { $this->_query = str_ireplace('SQL_CALC_FOUND_ROWS', '', $this->_query); // we make the data for next SELECE FOUND_ROWS() statement $unlimited_query = preg_replace('/\\bLIMIT\\s*.*/imsx', '', $this->_query); - //$unlimited_query = preg_replace('/\\bGROUP\\s*BY\\s*.*/imsx', '', $unlimited_query); - // we no longer use SELECT COUNT query + //$unlimited_query = preg_replace('/\\bGROUP\\s*BY\\s*.*/imsx', '', $unlimited_query); + // we no longer use SELECT COUNT query //$unlimited_query = $this->_transform_to_count($unlimited_query); $_wpdb = new PDODB(); $result = $_wpdb->query($unlimited_query); @@ -286,7 +293,7 @@ class PDOSQLiteDriver { } /** * Call back method to change SELECT query to SELECT COUNT(). - * + * * obsolite since version 1.5.1 * * @param string $query the query to be transformed @@ -300,58 +307,58 @@ class PDOSQLiteDriver { } /** * Method to rewrite INSERT IGNORE to INSERT OR IGNORE. - * + * * @access private */ private function rewrite_insert_ignore(){ - $this->_query = str_ireplace('INSERT IGNORE', 'INSERT OR IGNORE ', $this->_query); + $this->_query = str_ireplace('INSERT IGNORE', 'INSERT OR IGNORE ', $this->_query); } /** * Method to rewrite UPDATE IGNORE to UPDATE OR IGNORE. - * + * * @access private */ private function rewrite_update_ignore(){ - $this->_query = str_ireplace('UPDATE IGNORE', 'UPDATE OR IGNORE ', $this->_query); + $this->_query = str_ireplace('UPDATE IGNORE', 'UPDATE OR IGNORE ', $this->_query); } /** * Method to rewrite DATE_ADD() function. - * + * * DATE_ADD has a parameter PHP function can't parse, so we quote the list and * pass it to the user defined function. - * + * * @access private */ private function rewrite_date_add(){ //(date,interval expression unit) $pattern = '/\\s*date_add\\s*\(([^,]*),([^\)]*)\)/imsx'; - if (preg_match($pattern, $this->_query, $matches)) { - $expression = "'".trim($matches[2])."'"; - $this->_query = preg_replace($pattern, " date_add($matches[1], $expression) ", $this->_query); - } + if (preg_match($pattern, $this->_query, $matches)) { + $expression = "'".trim($matches[2])."'"; + $this->_query = preg_replace($pattern, " date_add($matches[1], $expression) ", $this->_query); + } } /** * Method to rewrite DATE_SUB() function. - * + * * DATE_SUB has a parameter PHP function can't parse, so we quote the list and * pass it to the user defined function. - * + * * @access private */ private function rewrite_date_sub(){ //(date,interval expression unit) $pattern = '/\\s*date_sub\\s*\(([^,]*),([^\)]*)\)/imsx'; - if (preg_match($pattern, $this->_query, $matches)) { - $expression = "'".trim($matches[2])."'"; - $this->_query = preg_replace($pattern, " date_sub($matches[1], $expression) ", $this->_query); - } + if (preg_match($pattern, $this->_query, $matches)) { + $expression = "'".trim($matches[2])."'"; + $this->_query = preg_replace($pattern, " date_sub($matches[1], $expression) ", $this->_query); + } } /** * Method to handle CREATE query. - * + * * If the query is CREATE query, it will be passed to the query_create.class.php. * So this method can't be used. It's here for safety. - * + * * @access private */ private function handle_create_query(){ @@ -360,47 +367,46 @@ class PDOSQLiteDriver { $this->_query = $engine->rewrite_query($this->_query); $engine = null; } - + /** * Method to handle ALTER query. - * + * * If the query is ALTER query, it will be passed ot the query_alter.class.php. * So this method can't be used. It is here for safety. - * + * * @access private */ private function handle_alter_query(){ - require_once PDODIR . 'query_alter.class.php'; - $engine = new AlterQuery(); - $this->_query = $engine->rewrite_query($this->_query, 'alter'); - $engine = null; + require_once PDODIR . 'query_alter.class.php'; + $engine = new AlterQuery(); + $this->_query = $engine->rewrite_query($this->_query, 'alter'); + $engine = null; } - + /** * Method to handle DESCRIBE or DESC query. - * + * * DESCRIBE is required for WordPress installation process. DESC is * an alias for DESCRIBE, but it is not used in core WordPress. - * + * * @access private */ private function handle_describe_query(){ - // $this->_query = "select 1=1"; $pattern = '/^\\s*(DESCRIBE|DESC)\\s*(.*)/i'; if (preg_match($pattern, $this->_query, $match)) { - $tablename = preg_replace('/[\';]/', '', $match[2]); - $this->_query = "PRAGMA table_info($tablename)"; + $tablename = preg_replace('/[\';]/', '', $match[2]); + $this->_query = "PRAGMA table_info($tablename)"; } } /** * Method to remove LIMIT clause from DELETE or UPDATE query. - * + * * The author of the original 'PDO for WordPress' says update method of wpdb * insists on adding LIMIT. But the newest version of WordPress doesn't do that. * Nevertheless some plugins use DELETE with LIMIT, UPDATE with LIMIT. * We need to exclude sub query's LIMIT. And if SQLite is compiled with * ENABLE_UPDATE_DELETE_LIMIT option, we don't remove it. - * + * * @access private */ private function rewrite_limit_usage(){ @@ -409,17 +415,17 @@ class PDOSQLiteDriver { foreach ($options as $opt) { if (stripos($opt->compile_option, 'ENABLE_UPDATE_DELETE_LIMIT') !== false) return; } - if (stripos($this->_query, '(select') === false) { - $this->_query = preg_replace('/\\s*LIMIT\\s*[0-9]$/i', '', $this->_query); - } + if (stripos($this->_query, '(select') === false) { + $this->_query = preg_replace('/\\s*LIMIT\\s*[0-9]$/i', '', $this->_query); + } } /** * Method to remove ORDER BY clause from DELETE or UPDATE query. - * + * * SQLite compiled without SQLITE_ENABLE_UPDATE_DELETE_LIMIT option can't * execute UPDATE with ORDER BY, DELETE with GROUP BY. * We need to exclude sub query's GROUP BY. - * + * * @access private */ private function rewrite_order_by_usage() { @@ -428,13 +434,13 @@ class PDOSQLiteDriver { foreach ($options as $opt) { if (stripos($opt->compile_option, 'ENABLE_UPDATE_DELETE_LIMIT') !== false) return; } - if (stripos($this->_query, '(select') === false) { - $this->_query = preg_replace('/\\s*ORDER\\s*BY\\s*.*$/i', '', $this->_query); - } + if (stripos($this->_query, '(select') === false) { + $this->_query = preg_replace('/\\s+ORDER\\s+BY\\s*.*$/i', '', $this->_query); + } } /** * Method to handle TRUNCATE query. - * + * * @access private */ private function handle_truncate_query(){ @@ -443,10 +449,10 @@ class PDOSQLiteDriver { } /** * Method to handle OPTIMIZE query. - * + * * Original query has the table names, but they are simply ignored. * Table names are meaningless in SQLite. - * + * * @access private */ private function rewrite_optimize(){ @@ -454,13 +460,13 @@ class PDOSQLiteDriver { } /** * Method to rewrite day. - * + * * Jusitn Adie says: some wp UI interfaces (notably the post interface) * badly composes the day part of the date leading to problems in sqlite * sort ordering etc. - * + * * I don't understand that... - * + * * @return void * @access private */ @@ -470,7 +476,7 @@ class PDOSQLiteDriver { } /** * Method to remove INDEX HINT. - * + * * @return void * @access private */ @@ -480,15 +486,15 @@ class PDOSQLiteDriver { } /** * Method to fix the date string and quoting. - * + * * This is required for the calendar widget. - * + * * WHERE month(fieldname)=08 is converted to month(fieldname)='8' * WHERE month(fieldname)='08' is converted to month(fieldname)='8' - * + * * I use preg_replace_callback instead of 'e' option because of security reason. * cf. PHP manual (regular expression) - * + * * @return void * @access private */ @@ -498,7 +504,7 @@ class PDOSQLiteDriver { } /** * Call back method to rewrite date string. - * + * * @param string $match * @return string * @access private @@ -509,10 +515,10 @@ class PDOSQLiteDriver { } /** * Method to rewrite REGEXP() function. - * + * * This method changes function name to regexpp() and pass it to the user defined * function. - * + * * @access private */ private function rewrite_regexp(){ @@ -521,249 +527,249 @@ class PDOSQLiteDriver { } /** * Method to rewrite boolean to number. - * + * * SQLite doesn't support true/false type, so we need to convert them to 1/0. - * + * * Obsolite since 1.5.1 - * + * * @access private */ private function rewrite_boolean() { - $query = str_ireplace('TRUE', "1", $this->_query); - $query = str_ireplace('FALSE', "0", $query); - $this->_query = $query; + $query = str_ireplace('TRUE', "1", $this->_query); + $query = str_ireplace('FALSE', "0", $query); + $this->_query = $query; } /** * Method to handl SHOW COLUMN query. - * + * * @access private */ - private function handle_show_columns_query() { - $this->_query = str_ireplace(' FULL', '', $this->_query); - $pattern_like = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?\\s*LIKE\\s*(.*)?/i'; - $pattern = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?/i'; - if (preg_match($pattern_like, $this->_query, $matches)) { - $table_name = str_replace("'", "", trim($matches[2])); - $column_name = str_replace("'", "", trim($matches[3])); - $query_string = "SELECT sql FROM sqlite_master WHERE tbl_name='$table_name' AND sql LIKE '%$column_name%'"; - $this->_query = $query_string; - } elseif (preg_match($pattern, $this->_query, $matches)) { - $table_name = $matches[2]; - $query_string = preg_replace($pattern, "PRAGMA table_info($table_name)", $this->_query); - $this->_query = $query_string; - } - } - /** - * Method to handle SHOW INDEX query. - * - * Moved the WHERE clause manipulation to pdoengin.class.php (ver 1.3.1) - * - * @access private - */ - private function handle_show_index() { - $pattern = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im'; - if (preg_match($pattern, $this->_query, $match)) { - $table_name = preg_replace("/[\';]/", '', $match[1]); - $table_name = trim($table_name); - $this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name'"; - } - } - /** - * Method to handle ON DUPLICATE KEY UPDATE statement. - * - * First we use SELECT query and check if INSERT is allowed or not. - * Rewriting procedure looks like a detour, but I've got no other ways. - * - * Added the literal check since the version 1.5.1. - * - * @return void - * @access private - */ - private function execute_duplicate_key_update() { - if (!$this->rewrite_duplicate_key) return; - $unique_keys_for_cond = array(); - $unique_keys_for_check = array(); - $pattern = '/^\\s*INSERT\\s*INTO\\s*(\\w+)?\\s*(.*)\\s*ON\\s*DUPLICATE\\s*KEY\\s*UPDATE\\s*(.*)$/ims'; - if (preg_match($pattern, $this->_query, $match_0)) { - $table_name = trim($match_0[1]); - $insert_data = trim($match_0[2]); - $update_data = trim($match_0[3]); - // prepare two unique key data for the table - // 1. array('col1', 'col2, col3', etc) 2. array('col1', 'col2', 'col3', etc) - $_wpdb = new PDODB(); - $indexes = $_wpdb->get_results("SHOW INDEX FROM {$table_name}"); - if (!empty($indexes)) { - foreach ($indexes as $index) { - if ($index->Non_unique == 0) { - $unique_keys_for_cond[] = $index->Column_name; - if (strpos($index->Column_name, ',') !== false) { - $unique_keys_for_check = array_merge($unique_keys_for_check, explode(',', $index->Column_name)); - } else { - $unique_keys_for_check[] = $index->Column_name; - } - } - } - $unique_keys_for_check = array_map('trim', $unique_keys_for_check); - } else { - // Without unique key or primary key, UPDATE statement will affect all the rows! - $query = 'INSERT INTO '.$table_name.' '.$insert_data; - $this->_query = $query; - $_wpdb = null; - return; - } - // data check - if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/ims', $insert_data, $match_1)) { - $col_array = explode(',', $match_1[1]); - $ins_data_array = explode(',', $match_1[2]); - foreach ($col_array as $col) { - $val = trim(array_shift($ins_data_array)); - $ins_data_assoc[trim($col)] = $val; - } -// $ins_data_assoc = array_combine($col_array, $ins_array); - $condition = ''; - foreach ($unique_keys_for_cond as $unique_key) { - if (strpos($unique_key, ',') !== false) { - $unique_key_array = explode(',', $unique_key); - $counter = count($unique_key_array); - for ($i = 0; $i < $counter; ++$i) { - $col = trim($unique_key_array[$i]); - if (isset($ins_data_assoc[$col]) && $i == $counter - 1) { - $condition .= $col . '=' . $ins_data_assoc[$col] . ' OR '; - } elseif (isset($ins_data_assoc[$col])) { - $condition .= $col . '=' . $ins_data_assoc[$col] . ' AND '; - } else { - continue; - } - } -// $condition = rtrim($condition, ' AND '); - } else { - $col = trim($unique_key); - if (isset($ins_data_assoc[$col])) { - $condition .= $col . '=' . $ins_data_assoc[$col] . ' OR '; - } else { - continue; - } - } - } - $condition = rtrim($condition, ' OR '); - $test_query = "SELECT * FROM {$table_name} WHERE {$condition}"; - $results = $_wpdb->query($test_query); - $_wpdb = null; - if ($results == 0) { - $this->_query = 'INSERT INTO '.$table_name.' '.$insert_data; - return; - } else { - // change (col, col...) values (data, data...) to array(col=>data, col=>data...) - if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_2)) { - $col_array = explode(',', $match_2[1]); - $ins_array = explode(',', $match_2[2]); - $count = count($col_array); - for ($i = 0; $i < $count; $i++) { - $col = trim($col_array[$i]); - $val = trim($ins_array[$i]); - $ins_array_assoc[$col] = $val; - } - } - // change col = data, col = data to array(col=>data, col=>data) - // some plugins have semi-colon at the end of the query - $update_data = rtrim($update_data, ';'); - $tmp_array = explode(',', $update_data); - foreach ($tmp_array as $pair) { - list($col, $value) = explode('=', $pair); - $col = trim($col); - $value = trim($value); - $update_array_assoc[$col] = $value; - } - // change array(col=>values(col)) to array(col=>data) - foreach ($update_array_assoc as $key => &$value) { - if (preg_match('/^VALUES\\s*\((.*)\)$/im', $value, $match_3)) { - $col = trim($match_3[1]); - $value = $ins_array_assoc[$col]; - } - } - foreach ($ins_array_assoc as $key => $val) { - if (in_array($key, $unique_keys_for_check)) { - $where_array[] = $key . '=' . $val; - } - } - $update_strings = ''; - foreach ($update_array_assoc as $key => $val) { - if (in_array($key, $unique_keys_for_check)) { - $where_array[] = $key . '=' . $val; - } else { - $update_strings .= $key . '=' . $val . ','; - } - } - $update_strings = rtrim($update_strings, ','); - $unique_where = array_unique($where_array, SORT_REGULAR); - $where_string = ' WHERE ' . implode(' AND ', $unique_where); - // $where_string = ' WHERE ' . rtrim($where_string, ','); - $update_query = 'UPDATE ' . $table_name . ' SET ' . $update_strings . $where_string; - $this->_query = $update_query; - } - } - } -// else { -// $pattern = '/ ON DUPLICATE KEY UPDATE.*$/im'; -// $replace_query = preg_replace($pattern, '', $this->_query); -// $replace_query = str_ireplace('INSERT ', 'INSERT OR REPLACE ', $replace_query); -// $this->_query = $replace_query; -// } - } - /** - * Method to rewrite BETWEEN A AND B clause. - * - * This clause is the same form as natural language, so we have to check if it is - * in the data or SQL statement. - * - * @access private - */ - private function rewrite_between() { - if (!$this->rewrite_between) return; - $pattern = '/\\s*(CAST\([^\)]+?\)|[^\\s\(]*)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s\)]*)?\\s*/ims'; - if (preg_match($pattern, $this->_query, $match)) { - $column_name = trim($match[1]); - $min_value = trim($match[2]); - $max_value = trim($match[3]); - $max_value = rtrim($max_value); - $replacement = " $column_name >= $min_value AND $column_name <= $max_value"; - $this->_query = str_ireplace($match[0], $replacement, $this->_query); - $this->rewrite_between = false; - } - $this->parse_query(); - $this->rewrite_between(); - } - /** - * Method to avoid DELETE with JOIN statement. - * - * wp-admin/includes/upgrade.php contains 'DELETE ... JOIN' statement. - * This query can't be replaced with regular expression or udf, so we - * replace all the statement with another. But this query was used in - * the very old version of WordPress when it was upgraded. So we won't - * have no chance that this method should be used. - * - * @access private - */ - private function delete_workaround() { - global $wpdb; -// $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (option_name) WHERE o2.option_id > o1.option_id"; + private function handle_show_columns_query() { + $this->_query = str_ireplace(' FULL', '', $this->_query); + $pattern_like = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?\\s*LIKE\\s*(.*)?/i'; + $pattern = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?/i'; + if (preg_match($pattern_like, $this->_query, $matches)) { + $table_name = str_replace("'", "", trim($matches[2])); + $column_name = str_replace("'", "", trim($matches[3])); + $query_string = "SELECT sql FROM sqlite_master WHERE tbl_name='$table_name' AND sql LIKE '%$column_name%'"; + $this->_query = $query_string; + } elseif (preg_match($pattern, $this->_query, $matches)) { + $table_name = $matches[2]; + $query_string = preg_replace($pattern, "PRAGMA table_info($table_name)", $this->_query); + $this->_query = $query_string; + } + } + /** + * Method to handle SHOW INDEX query. + * + * Moved the WHERE clause manipulation to pdoengin.class.php (ver 1.3.1) + * + * @access private + */ + private function handle_show_index() { + $pattern = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im'; + if (preg_match($pattern, $this->_query, $match)) { + $table_name = preg_replace("/[\';]/", '', $match[1]); + $table_name = trim($table_name); + $this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name'"; + } + } + /** + * Method to handle ON DUPLICATE KEY UPDATE statement. + * + * First we use SELECT query and check if INSERT is allowed or not. + * Rewriting procedure looks like a detour, but I've got no other ways. + * + * Added the literal check since the version 1.5.1. + * + * @return void + * @access private + */ + private function execute_duplicate_key_update() { + if (!$this->rewrite_duplicate_key) return; + $unique_keys_for_cond = array(); + $unique_keys_for_check = array(); + $pattern = '/^\\s*INSERT\\s*INTO\\s*(\\w+)?\\s*(.*)\\s*ON\\s*DUPLICATE\\s*KEY\\s*UPDATE\\s*(.*)$/ims'; + if (preg_match($pattern, $this->_query, $match_0)) { + $table_name = trim($match_0[1]); + $insert_data = trim($match_0[2]); + $update_data = trim($match_0[3]); + // prepare two unique key data for the table + // 1. array('col1', 'col2, col3', etc) 2. array('col1', 'col2', 'col3', etc) + $_wpdb = new PDODB(); + $indexes = $_wpdb->get_results("SHOW INDEX FROM {$table_name}"); + if (!empty($indexes)) { + foreach ($indexes as $index) { + if ($index->Non_unique == 0) { + $unique_keys_for_cond[] = $index->Column_name; + if (strpos($index->Column_name, ',') !== false) { + $unique_keys_for_check = array_merge($unique_keys_for_check, explode(',', $index->Column_name)); + } else { + $unique_keys_for_check[] = $index->Column_name; + } + } + } + $unique_keys_for_check = array_map('trim', $unique_keys_for_check); + } else { + // Without unique key or primary key, UPDATE statement will affect all the rows! + $query = 'INSERT INTO '.$table_name.' '.$insert_data; + $this->_query = $query; + $_wpdb = null; + return; + } + // data check + if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/ims', $insert_data, $match_1)) { + $col_array = explode(',', $match_1[1]); + $ins_data_array = explode(',', $match_1[2]); + foreach ($col_array as $col) { + $val = trim(array_shift($ins_data_array)); + $ins_data_assoc[trim($col)] = $val; + } + $ins_data_assoc = array_combine($col_array, $ins_array); + $condition = ''; + foreach ($unique_keys_for_cond as $unique_key) { + if (strpos($unique_key, ',') !== false) { + $unique_key_array = explode(',', $unique_key); + $counter = count($unique_key_array); + for ($i = 0; $i < $counter; ++$i) { + $col = trim($unique_key_array[$i]); + if (isset($ins_data_assoc[$col]) && $i == $counter - 1) { + $condition .= $col . '=' . $ins_data_assoc[$col] . ' OR '; + } elseif (isset($ins_data_assoc[$col])) { + $condition .= $col . '=' . $ins_data_assoc[$col] . ' AND '; + } else { + continue; + } + } + $condition = rtrim($condition, ' AND '); + } else { + $col = trim($unique_key); + if (isset($ins_data_assoc[$col])) { + $condition .= $col . '=' . $ins_data_assoc[$col] . ' OR '; + } else { + continue; + } + } + } + $condition = rtrim($condition, ' OR '); + $test_query = "SELECT * FROM {$table_name} WHERE {$condition}"; + $results = $_wpdb->query($test_query); + $_wpdb = null; + if ($results == 0) { + $this->_query = 'INSERT INTO '.$table_name.' '.$insert_data; + return; + } else { + if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_2)) { + $col_array = explode(',', $match_2[1]); + $ins_array = explode(',', $match_2[2]); + $count = count($col_array); + for ($i = 0; $i < $count; $i++) { + $col = trim($col_array[$i]); + $val = trim($ins_array[$i]); + $ins_array_assoc[$col] = $val; + } + } + $update_data = rtrim($update_data, ';'); + $tmp_array = explode(',', $update_data); + foreach ($tmp_array as $pair) { + list($col, $value) = explode('=', $pair); + $col = trim($col); + $value = trim($value); + $update_array_assoc[$col] = $value; + } + foreach ($update_array_assoc as $key => &$value) { + if (preg_match('/^VALUES\\s*\((.*)\)$/im', $value, $match_3)) { + $col = trim($match_3[1]); + $value = $ins_array_assoc[$col]; + } + } + foreach ($ins_array_assoc as $key => $val) { + if (in_array($key, $unique_keys_for_check)) { + $where_array[] = $key . '=' . $val; + } + } + $update_strings = ''; + foreach ($update_array_assoc as $key => $val) { + if (in_array($key, $unique_keys_for_check)) { + $where_array[] = $key . '=' . $val; + } else { + $update_strings .= $key . '=' . $val . ','; + } + } + $update_strings = rtrim($update_strings, ','); + $unique_where = array_unique($where_array, SORT_REGULAR); + $where_string = ' WHERE ' . implode(' AND ', $unique_where); + $update_query = 'UPDATE ' . $table_name . ' SET ' . $update_strings . $where_string; + $this->_query = $update_query; + } + } + } + } + /** + * Method to rewrite BETWEEN A AND B clause. + * + * This clause is the same form as natural language, so we have to check if it is + * in the data or SQL statement. + * + * @access private + */ + private function rewrite_between() { + if (!$this->rewrite_between) return; + $pattern = '/\\s*(CAST\([^\)]+?\)|[^\\s\(]*)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s\)]*)?\\s*/ims'; + do { + if (preg_match($pattern, $this->_query, $match)) { + $column_name = trim($match[1]); + $min_value = trim($match[2]); + $max_value = trim($match[3]); + $max_value = rtrim($max_value); + $replacement = " ($column_name >= $min_value AND $column_name <= $max_value)"; + $this->_query = str_ireplace($match[0], $replacement, $this->_query); + } + $this->num_of_rewrite_between--; + } while ($this->num_of_rewrite_between > 0); + } + /** + * Method to avoid DELETE with JOIN statement. + * + * wp-admin/includes/upgrade.php contains 'DELETE ... JOIN' statement. + * This query can't be replaced with regular expression or udf, so we + * replace all the statement with another. But this query was used in + * the very old version of WordPress when it was upgraded. So we won't + * have no chance that this method should be used. + * + * @access private + */ + private function delete_workaround() { + global $wpdb; $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2"; - $rewritten = "DELETE FROM $wpdb->options WHERE option_id IN (SELECT MIN(option_id) FROM $wpdb->options GROUP BY option_name HAVING COUNT(*) > 1)"; - if (stripos($this->_query, $pattern) !== false) { - $this->_query = $rewritten; - } - } - /** - * Method to suppress errors. - * - * When the query string is the one that this class can't manipulate, - * the query string is replaced with the one that always returns true - * and does nothing. - * - * @access private - */ - private function return_true() { - $this->_query = 'SELECT 1=1'; - } + $pattern2 = "DELETE a, b FROM $wpdb->sitemeta AS a, $wpdb->sitemeta AS b"; + $rewritten = "DELETE FROM $wpdb->options WHERE option_id IN (SELECT MIN(option_id) FROM $wpdb->options GROUP BY option_name HAVING COUNT(*) > 1)"; + if (stripos($this->_query, $pattern) !== false) { + $this->_query = $rewritten; + } else if (stripos($this->_query, $pattern2) !== false) { + $time = time(); + $prep_query = "SELECT a.meta_id AS aid, b.meta_id AS bid FROM $wpdb->sitemeta AS a INNER JOIN $wpdb->sitemeta AS b ON a.meta_key='_site_transient_timeout_'||substr(b.meta_key, 17) WHERE b.meta_key='_site_transient_'||substr(a.meta_key, 25) AND a.meta_value < $time"; + $_wpdb = new PDODB(); + $ids = $_wpdb->get_results($prep_query); + foreach ($ids as $id) { + $ids_to_delete[] = $id->aid; + $ids_to_delete[] = $id->bid; + } + $rewritten = "DELETE FROM $wpdb->sitemeta WHERE meta_id IN (".implode(',', $ids_to_delete).")"; + $this->_query = $rewritten; + } + } + /** + * Method to suppress errors. + * + * When the query string is the one that this class can't manipulate, + * the query string is replaced with the one that always returns true + * and does nothing. + * + * @access private + */ + private function return_true() { + $this->_query = 'SELECT 1=1'; + } } ?> \ No newline at end of file diff --git a/query_alter.class.php b/query_alter.class.php index 933183c..488ffd9 100644 --- a/query_alter.class.php +++ b/query_alter.class.php @@ -1,9 +1,9 @@ split_multiple($command); + public $_query = null; + + /** + * Function to split the query string to the tokens and call apropreate functions. + * + * @param string @query + * @parm string $query_type + * @return boolean | stirng + */ + public function rewrite_query($query, $query_type) { + if (stripos($query, $query_type) === false) { + return false; + } + $query = str_replace('`', '', $query); + if (preg_match('/^\\s*(ALTER\\s*TABLE)\\s*(\\w+)?\\s*/ims', $query, $match)) { + $tmp_query = array(); + $tokens = array(); + $re_command = ''; + $command = str_ireplace($match[0], '', $query); + $tmp_tokens['query_type'] = trim($match[1]); + $tmp_tokens['table_name'] = trim($match[2]); + //$command_array = $this->split_multiple($command); $command_array = explode(',', $command); - + $single_command = array_shift($command_array); if (!empty($command_array)) { $re_command = 'ALTER TABLE ' . $tmp_tokens['table_name'] . ' '; $re_command .= implode(',', $command_array); } - $command_tokens = $this->command_tokenizer($single_command); - if (!empty($command_tokens)) { - $tokens = array_merge($tmp_tokens, $command_tokens); - } else { - $this->_query = 'SELECT 1=1'; - return $this->_query; - } -// foreach ($tokens as $token) { - $command_name = strtolower($tokens['command']); - switch ($command_name) { - case 'add column': case 'rename to': case 'add index': case 'drop index': - $tmp_query = $this->handle_single_command($tokens); - break; - case 'add primary key': - $tmp_query = $this->handle_add_primary_key($tokens); - break; - case 'drop primary key': - $tmp_query = $this->handle_drop_primary_key($tokens); - break; - case 'modify column': - $tmp_query = $this->handle_modify_command($tokens); - break; - case 'change column': - $tmp_query = $this->handle_change_command($tokens); - break; - case 'alter column': - $tmp_query = $this->handle_alter_command($tokens); - break; - default: - break; - } -// } - if (!is_array($tmp_query)) { - $this->_query[] = $tmp_query; - } else { - $this->_query = $tmp_query; - } - if ($re_command != '') { - $this->_query = array_merge($this->_query, array('recursion' => $re_command)); - } - } else { - $this->_query = 'SELECT 1=1'; - } - return $this->_query; - } + $command_tokens = $this->command_tokenizer($single_command); + if (!empty($command_tokens)) { + $tokens = array_merge($tmp_tokens, $command_tokens); + } else { + $this->_query = 'SELECT 1=1'; + return $this->_query; + } + $command_name = strtolower($tokens['command']); + switch ($command_name) { + case 'add column': case 'rename to': case 'add index': case 'drop index': + $tmp_query = $this->handle_single_command($tokens); + break; + case 'add primary key': + $tmp_query = $this->handle_add_primary_key($tokens); + break; + case 'drop primary key': + $tmp_query = $this->handle_drop_primary_key($tokens); + break; + case 'modify column': + $tmp_query = $this->handle_modify_command($tokens); + break; + case 'change column': + $tmp_query = $this->handle_change_command($tokens); + break; + case 'alter column': + $tmp_query = $this->handle_alter_command($tokens); + break; + default: + break; + } + if (!is_array($tmp_query)) { + $this->_query[] = $tmp_query; + } else { + $this->_query = $tmp_query; + } + if ($re_command != '') { + $this->_query = array_merge($this->_query, array('recursion' => $re_command)); + } + } else { + $this->_query = 'SELECT 1=1'; + } + return $this->_query; + } /** * Function to analyze ALTER TABLE command and sets the data to an array. - * + * * @param string $command * @return boolean|array * @access private */ - private function command_tokenizer($command) { - $tokens = array(); - if (preg_match('/^(ADD|DROP|RENAME|MODIFY|CHANGE|ALTER)\\s*(\\w+)?\\s*(\\w+(\(.+\)|))?\\s*/ims', $command, $match)) { - $the_rest = str_ireplace($match[0], '', $command); - $match_1 = trim($match[1]); - $match_2 = trim($match[2]); - $match_3 = isset($match[3]) ? trim($match[3]) : ''; - switch (strtolower($match_1)) { - case 'add': - if (in_array(strtolower($match_2), array('fulltext', 'constraint', 'foreign'))) { - break; - } elseif (stripos('column', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['column_name'] = $match_3; - $tokens['column_def'] = trim($the_rest); - } elseif (stripos('primary', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; - $tokens['column_name'] = $the_rest; - } elseif (stripos('unique', $match_2) !== false) { - list($index_name, $col_name) = preg_split('/[\(\)]/s', trim($the_rest), -1, PREG_SPLIT_DELIM_CAPTURE); - $tokens['unique'] = true; - $tokens['command'] = $match_1.' '.$match_3; - $tokens['index_name'] = trim($index_name); - $tokens['column_name'] = '('.trim($col_name).')'; - } elseif (in_array(strtolower($match_2), array('index', 'key'))) { - $tokens['command'] = $match_1.' '.$match_2; - if ($match_3 == '') { - $tokens['index_name'] = str_replace(array('(', ')'), '', $the_rest); - } else { - $tokens['index_name'] = $match_3; - } - $tokens['column_name'] = trim($the_rest); - } else { - $tokens['command'] = $match_1.' COLUMN'; - $tokens['column_name'] = $match_2; - $tokens['column_def'] = $match_3.' '.$the_rest; - } - break; - case 'drop': - if (stripos('column', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['column_name'] = trim($match_3); - } elseif (stripos('primary', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; - } elseif (in_array(strtolower($match_2), array('index', 'key'))) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['index_name'] = $match_3; - } elseif (stripos('primary', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; - } else { - $tokens['command'] = $match_1.' COLUMN'; - $tokens['column_name'] = $match_2; - } - break; - case 'rename': - if (stripos('to', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['column_name'] = $match_3; - } else { - $tokens['command'] = $match_1.' TO'; - $tokens['column_name'] = $match_2; - } - break; - case 'modify': - if (stripos('column', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['column_name'] = $match_3; - $tokens['column_def'] = trim($the_rest); - } else { - $tokens['command'] = $match_1.' COLUMN'; - $tokens['column_name'] = $match_2; - $tokens['column_def'] = $match_3.' '.trim($the_rest); - } - break; - case 'change': - $the_rest = trim($the_rest); - if (stripos('column', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['old_column'] = $match_3; - list($new_col) = explode(' ', $the_rest); - $tmp_col = preg_replace('/\(.+?\)/im', '', $new_col); - if (array_key_exists(strtolower($tmp_col), $this->array_types)) { - $tokens['column_def'] = $the_rest; - } else { - $tokens['new_column'] = $new_col; - $col_def = str_replace($new_col, '', $the_rest); - $tokens['column_def'] = trim($col_def); - } - } else { - $tokens['command'] = $match_1.' column'; - $tokens['old_column'] = $match_2; - $tmp_col = preg_replace('/\(.+?\)/im', '', $match_3); - if (array_key_exists(strtolower($tmp_col), $this->array_types)) { - $tokens['column_def'] = $match_3 . ' ' . $the_rest; - } else { - $tokens['new_column'] = $match_3; - $tokens['column_def'] = $the_rest; - } - } - break; - case 'alter': - if (stripos('column', $match_2) !== false) { - $tokens['command'] = $match_1.' '.$match_2; - $tokens['column_name'] = $match_3; - list($set_or_drop) = explode(' ', $the_rest); - if (stripos('set', $set_or_drop) !== false) { - $tokens['default_command'] = 'SET DEFAULT'; - $default_value = str_ireplace('set default', '', $the_rest); - $tokens['default_value'] = trim($default_value); - } else { - $tokens['default_command'] = 'DROP DEFAULT'; - } - } else { - $tokens['command'] = $match_1.' COLUMN'; - $tokens['column_name'] = $match_2; - if (stripos('set', $match_3) !== false) { - $tokens['default_command'] = 'SET DEFAULT'; - $default_value = str_ireplace('default', '', $the_rest); - $tokens['default_value'] = trim($default_value); - } else { - $tokens['default_command'] = 'DROP DEFAULT'; - } - } - break; - default: - break; - } - return $tokens; - } - } - /** - * Function to split multiple commands into an array and return it. - * - * This function is deprecated. - * - * @access private - * @param unknown $command - * @return multitype:string unknown Ambigous - */ - private function split_multiple($command) { - $out = true; - $command_array = array(); - $command_string = ''; - $tokens = preg_split('/\b/s', $command, -1, PREG_SPLIT_DELIM_CAPTURE); - foreach ($tokens as $token) { - switch (trim($token)) { - case ';': - break; - case '(': - $command_string .= $token; - $out = false; - break; - case ')': - $command_string .= $token; - $out = true; - break; - case '),': - $command_array[] = $command_string; - $command_string = ''; - $out = true; - break; - case ',': - if ($out) { - $command_array[] = $command_string; - $command_string = ''; - } else { - $command_string .= $token; - } - break; - default: - $command_string .= $token; - break; - } - } - if (!empty($command_string)) { - $command_array[] = $command_string; - } - return $command_array; - } - /** - * Function to handle single command. - * - * @access private - * @param array of string $queries - * @return string - */ - private function handle_single_command($queries) { - $tokenized_query = $queries; - if (stripos($tokenized_query['command'], 'add column') !== false) { - $column_def = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['column_def']); - $query = "ALTER TABLE {$tokenized_query['table_name']} ADD COLUMN {$tokenized_query['column_name']} $column_def"; - } elseif (stripos($tokenized_query['command'], 'rename') !== false) { - $query = "ALTER TABLE {$tokenized_query['table_name']} RENAME TO {$tokenized_query['column_name']}"; - } elseif (stripos($tokenized_query['command'], 'add index') !== false) { - $unique = isset($tokenized_query['unique']) ? 'UNIQUE' : ''; - $query = "CREATE $unique INDEX IF NOT EXISTS {$tokenized_query['index_name']} ON {$tokenized_query['table_name']} {$tokenized_query['column_name']}"; - } elseif (stripos($tokenized_query['command'], 'drop index') !== false) { - $query = "DROP INDEX IF EXISTS {$tokenized_query['index_name']}"; - } else { - $query = 'SELECT 1=1'; - } - return $query; - } + private function command_tokenizer($command) { + $tokens = array(); + if (preg_match('/^(ADD|DROP|RENAME|MODIFY|CHANGE|ALTER)\\s*(\\w+)?\\s*(\\w+(\(.+\)|))?\\s*/ims', $command, $match)) { + $the_rest = str_ireplace($match[0], '', $command); + $match_1 = trim($match[1]); + $match_2 = trim($match[2]); + $match_3 = isset($match[3]) ? trim($match[3]) : ''; + switch (strtolower($match_1)) { + case 'add': + if (in_array(strtolower($match_2), array('fulltext', 'constraint', 'foreign'))) { + break; + } elseif (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['column_name'] = $match_3; + $tokens['column_def'] = trim($the_rest); + } elseif (stripos('primary', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; + $tokens['column_name'] = $the_rest; + } elseif (stripos('unique', $match_2) !== false) { + list($index_name, $col_name) = preg_split('/[\(\)]/s', trim($the_rest), -1, PREG_SPLIT_DELIM_CAPTURE); + $tokens['unique'] = true; + $tokens['command'] = $match_1.' '.$match_3; + $tokens['index_name'] = trim($index_name); + $tokens['column_name'] = '('.trim($col_name).')'; + } elseif (in_array(strtolower($match_2), array('index', 'key'))) { + $tokens['command'] = $match_1.' '.$match_2; + if ($match_3 == '') { + $tokens['index_name'] = str_replace(array('(', ')'), '', $the_rest); + } else { + $tokens['index_name'] = $match_3; + } + $tokens['column_name'] = trim($the_rest); + } else { + $tokens['command'] = $match_1.' COLUMN'; + $tokens['column_name'] = $match_2; + $tokens['column_def'] = $match_3.' '.$the_rest; + } + break; + case 'drop': + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['column_name'] = trim($match_3); + } elseif (stripos('primary', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; + } elseif (in_array(strtolower($match_2), array('index', 'key'))) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['index_name'] = $match_3; + } elseif (stripos('primary', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; + } else { + $tokens['command'] = $match_1.' COLUMN'; + $tokens['column_name'] = $match_2; + } + break; + case 'rename': + if (stripos('to', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['column_name'] = $match_3; + } else { + $tokens['command'] = $match_1.' TO'; + $tokens['column_name'] = $match_2; + } + break; + case 'modify': + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['column_name'] = $match_3; + $tokens['column_def'] = trim($the_rest); + } else { + $tokens['command'] = $match_1.' COLUMN'; + $tokens['column_name'] = $match_2; + $tokens['column_def'] = $match_3.' '.trim($the_rest); + } + break; + case 'change': + $the_rest = trim($the_rest); + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['old_column'] = $match_3; + list($new_col) = explode(' ', $the_rest); + $tmp_col = preg_replace('/\(.+?\)/im', '', $new_col); + if (array_key_exists(strtolower($tmp_col), $this->array_types)) { + $tokens['column_def'] = $the_rest; + } else { + $tokens['new_column'] = $new_col; + $col_def = str_replace($new_col, '', $the_rest); + $tokens['column_def'] = trim($col_def); + } + } else { + $tokens['command'] = $match_1.' column'; + $tokens['old_column'] = $match_2; + $tmp_col = preg_replace('/\(.+?\)/im', '', $match_3); + if (array_key_exists(strtolower($tmp_col), $this->array_types)) { + $tokens['column_def'] = $match_3 . ' ' . $the_rest; + } else { + $tokens['new_column'] = $match_3; + $tokens['column_def'] = $the_rest; + } + } + break; + case 'alter': + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; + $tokens['column_name'] = $match_3; + list($set_or_drop) = explode(' ', $the_rest); + if (stripos('set', $set_or_drop) !== false) { + $tokens['default_command'] = 'SET DEFAULT'; + $default_value = str_ireplace('set default', '', $the_rest); + $tokens['default_value'] = trim($default_value); + } else { + $tokens['default_command'] = 'DROP DEFAULT'; + } + } else { + $tokens['command'] = $match_1.' COLUMN'; + $tokens['column_name'] = $match_2; + if (stripos('set', $match_3) !== false) { + $tokens['default_command'] = 'SET DEFAULT'; + $default_value = str_ireplace('default', '', $the_rest); + $tokens['default_value'] = trim($default_value); + } else { + $tokens['default_command'] = 'DROP DEFAULT'; + } + } + break; + default: + break; + } + return $tokens; + } + } + /** + * Function to split multiple commands into an array and return it. + * + * This function is deprecated. + * + * @access private + * @param unknown $command + * @return multitype:string unknown Ambigous + */ + private function split_multiple($command) { + $out = true; + $command_array = array(); + $command_string = ''; + $tokens = preg_split('/\b/s', $command, -1, PREG_SPLIT_DELIM_CAPTURE); + foreach ($tokens as $token) { + switch (trim($token)) { + case ';': + break; + case '(': + $command_string .= $token; + $out = false; + break; + case ')': + $command_string .= $token; + $out = true; + break; + case '),': + $command_array[] = $command_string; + $command_string = ''; + $out = true; + break; + case ',': + if ($out) { + $command_array[] = $command_string; + $command_string = ''; + } else { + $command_string .= $token; + } + break; + default: + $command_string .= $token; + break; + } + } + if (!empty($command_string)) { + $command_array[] = $command_string; + } + return $command_array; + } + /** + * Function to handle single command. + * + * @access private + * @param array of string $queries + * @return string + */ + private function handle_single_command($queries) { + $tokenized_query = $queries; + if (stripos($tokenized_query['command'], 'add column') !== false) { + $column_def = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['column_def']); + $query = "ALTER TABLE {$tokenized_query['table_name']} ADD COLUMN {$tokenized_query['column_name']} $column_def"; + } elseif (stripos($tokenized_query['command'], 'rename') !== false) { + $query = "ALTER TABLE {$tokenized_query['table_name']} RENAME TO {$tokenized_query['column_name']}"; + } elseif (stripos($tokenized_query['command'], 'add index') !== false) { + $unique = isset($tokenized_query['unique']) ? 'UNIQUE' : ''; + $query = "CREATE $unique INDEX IF NOT EXISTS {$tokenized_query['index_name']} ON {$tokenized_query['table_name']} {$tokenized_query['column_name']}"; + } elseif (stripos($tokenized_query['command'], 'drop index') !== false) { + $query = "DROP INDEX IF EXISTS {$tokenized_query['index_name']}"; + } else { + $query = 'SELECT 1=1'; + } + return $query; + } /** * Function to handle ADD PRIMARY KEY. - * + * * @access private * @param array of string $queries * @return array of string */ - private function handle_add_primary_key($queries) { - $tokenized_query = $queries; - $tbl_name = $tokenized_query['table_name']; - $temp_table = 'temp_'.$tokenized_query['table_name']; - $_wpdb = new PDODB(); - $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='$tbl_name'"); - $_wpdb = null; - for ($i = 0; $i < count($query_obj); $i++) { - $index_queries[$i] = $query_obj[$i]->sql; - } - $table_query = array_shift($index_queries); - $table_query = str_replace($tokenized_query['table_name'], $temp_table, $table_query); - $table_query = rtrim($table_query, ')'); - $table_query = ", PRIMARY KEY {$tokenized_query['column_name']}"; - $query[] = $table_query; - $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; - $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; - $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; - foreach ($index_queries as $index) { - $query[] = $index; - } - return $query; - } - /** - * Function to handle DROP PRIMARY KEY. - * - * @access private - * @param array of string $queries - * @return array of string - */ - private function handle_drop_primary_key($queries) { - $tokenized_query = $queries; - $temp_table = 'temp_'.$tokenized_query['table_name']; - $_wpdb = new PDODB(); - $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); - $_wpdb = null; - for ($i = 0; $i < count($query_obj); $i++) { - $index_queries[$i] = $query_obj[$i]->sql; - } - $table_query = array_shift($index_queries); - $pattern1 = '/^\\s*PRIMARY\\s*KEY\\s*\(.*\)/im'; - $pattern2 = '/^\\s*.*(PRIMARY\\s*KEY\\s*(:?AUTOINCREMENT|))\\s*(?!\()/im'; - if (preg_match($pattern1, $table_query, $match)) { - $table_query = str_replace($match[0], '', $table_query); - } elseif (preg_match($pattern2, $table_query, $match)) { - $table_query = str_replace($match[1], '', $table_query); - } - $table_query = str_replace($tokenized_query['table_name'], $temp_table, $table_query); - $query[] = $table_query; - $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; - $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; - $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; - foreach ($index_queries as $index) { - $query[] = $index; - } - return $query; - } - /** - * Function to handle MODIFY COLUMN. - * - * @access private - * @param array of string $queries - * @return string|array of string - */ - private function handle_modify_command($queries) { - $tokenized_query = $queries; - $temp_table = 'temp_'.$tokenized_query['table_name']; - $column_def = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['column_def']); - $_wpdb = new PDODB(); - $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); - $_wpdb = null; - for ($i =0; $i < count($query_obj); $i++) { - $index_queries[$i] = $query_obj[$i]->sql; - } - $create_query = array_shift($index_queries); - if (stripos($create_query, $tokenized_query['column_name']) === false) { - return 'SELECT 1=1'; - } elseif (preg_match("/{$tokenized_query['column_name']}\\s*{$column_def}\\s*[,)]/i", $create_query)) { - return 'SELECT 1=1'; - } - $create_query = preg_replace("/{$tokenized_query['table_name']}/i", $temp_table, $create_query); - if (preg_match("/\\b{$tokenized_query['column_name']}\\s*.*(?=,)/ims", $create_query)) { - $create_query = preg_replace("/\\b{$tokenized_query['column_name']}\\s*.*(?=,)/ims", "{$tokenized_query['column_name']} {$column_def}", $create_query); - } elseif (preg_match("/\\b{$tokenized_query['column_name']}\\s*.*(?=\))/ims", $create_query)) { - $create_query = preg_replace("/\\b{$tokenized_query['column_name']}\\s*.*(?=\))/ims", "{$tokenized_query['column_name']} {$column_def}", $create_query); - } - $query[] = $create_query; - $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; - $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; - $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; - foreach ($index_queries as $index) { - $query[] = $index; - } - return $query; - } - /** - * Function to handle CHANGE COLUMN. - * - * @access private - * @param array of string $queries - * @return string|array of string - */ - private function handle_change_command($queries) { - $col_check = false; - $old_fields = ''; - $new_fields = ''; - $tokenized_query = $queries; - $temp_table = 'temp_'.$tokenized_query['table_name']; - if (isset($tokenized_query['new_column'])) { - $column_name = $tokenized_query['new_column']; - } else { - $column_name = $tokenized_query['old_column']; - } - $column_def = $this->convert_field_types($column_name, $tokenized_query['column_def']); - $_wpdb = new PDODB(); - $col_obj = $_wpdb->get_results("SHOW COLUMNS FROM {$tokenized_query['table_name']}"); - foreach ($col_obj as $col) { - if (stripos($col->Field, $tokenized_query['old_column']) !== false) $col_check = true; - $old_fields .= $col->Field . ','; - } - if ($col_check == false) { - $_wpdb = null; - return 'SELECT 1=1'; - } - $old_fields = rtrim($old_fields, ','); - $new_fields = str_ireplace($tokenized_query['old_column'], $column_name, $old_fields); - $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); - $_wpdb = null; - for ($i = 0; $i < count($query_obj); $i++) { - $index_queries[$i] = $query_obj[$i]->sql; - } - $create_query = array_shift($index_queries); - $create_query = preg_replace("/{$tokenized_query['table_name']}/i", $temp_table, $create_query); - if (preg_match("/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=,)/ims", $create_query, $match)) { - if (stripos(trim($match[1]), $column_def) !== false) { - return 'SELECT 1=1'; - } else { - $create_query = preg_replace("/\\b{$tokenized_query['old_column']}\\s*.+?(?=,)/ims", "{$column_name} {$column_def}", $create_query, 1); - } - } elseif (preg_match("/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=\))/ims", $create_query, $match)) { - if (stripos(trim($match[1]), $column_def) !== false) { - return 'SELECT 1=1'; - } else { - $create_query = preg_replace("/\\b{$tokenized_query['old_column']}\\s*.*(?=\))/ims", "{$column_name} {$column_def}", $create_query, 1); - } - } - $query[] = $create_query; - $query[] = "INSERT INTO $temp_table ($new_fields) SELECT $old_fields FROM {$tokenized_query['table_name']}"; - $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; - $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; - foreach ($index_queries as $index) { - $query[] = $index; - } - return $query; - } - /** - * Function to handle ALTER COLUMN. - * - * @access private - * @param array of string $queries - * @return string|array of string - */ - private function handle_alter_command($queries) { - $tokenized_query = $queries; - $temp_table = 'temp_'.$tokenized_query['table_name']; - if (isset($tokenized_query['default_value'])) { - $def_value = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['default_value']); - $def_value = 'DEFAULT '.$def_value; - } else { - $def_value = null; - } - $_wpdb = new PDODB(); - $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); - $_wpdb = null; - for ($i =0; $i < count($query_obj); $i++) { - $index_queries[$i] = $query_obj[$i]->sql; - } - $create_query = array_shift($index_queries); - if (stripos($create_query, $tokenized_query['column_name']) === false) { - return 'SELECT 1=1'; - } - if (preg_match("/\\s*({$tokenized_query['column_name']})\\s*(.*)?(DEFAULT\\s*.*)[,)]/im", $create_query, $match)) { - $col_name = trim($match[1]); - $col_def = trim($match[2]); - $col_def_esc = str_replace(array('(', ')'), array('\(', '\)'), $col_def); - $checked_col_def = $this->convert_field_types($col_name, $col_def); - $old_default = trim($match[3]); - $pattern = "/$col_name\\s*$col_def_esc\\s*$old_default/im"; - if (is_null($def_value)) { - $replacement = $col_name . ' ' . $checked_col_def; - } else { - $replacement = $col_name . ' ' . $checked_col_def . ' ' . $def_value; - } - $create_query = preg_replace($pattern, $replacement, $create_query); - $create_query = str_ireplace($tokenized_query['table_name'], $temp_table, $create_query); - } elseif (preg_match("/\\s*({$tokenized_query['column_name']})\\s*(.*)?[,)]/im", $create_query, $match)) { - $col_name = trim($match[1]); - $col_def = trim($match[2]); - $col_def_esc = str_replace(array('(', ')'), array('\(', '\)'), $col_def); - $checked_col_def = $this->convert_field_types($col_name, $col_def); - $pattern = "/$col_name\\s*$col_def_esc/im"; - if (is_null($def_value)) { - $replacement = $col_name . ' ' . $checked_col_def; - } else { - $replacement = $col_name . ' ' . $checked_col_def . ' ' . $def_value; - } - $create_query = preg_replace($pattern, $replacement, $create_query); - $create_query = str_ireplace($tokenized_query['table_name'], $temp_table, $create_query); - } else { - return 'SELECT 1=1'; - } - $query[] = $create_query; - $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; - $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; - $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; - foreach ($index_queries as $index) { - $query[] = $index; - } - return $query; - } - /** - * Function to change the field definition to SQLite compatible data type. - * - * @access private - * @param string $col_name - * @param string $col_def - * @return string - */ - private function convert_field_types($col_name, $col_def){ - $array_curtime = array('current_timestamp', 'current_time', 'current_date'); - $array_reptime = array("'0000-00-00 00:00:00'", "'0000-00-00 00:00:00'", "'0000-00-00'"); - $def_string = str_replace('`', '', $col_def); - foreach ($this->array_types as $o=>$r){ - $pattern = "/\\b$o\\s*(\([^\)]*\)*)?\\s*/ims"; - if (preg_match($pattern, $def_string)) { - $def_string = preg_replace($pattern, "$r ", $def_string); - break; - } - } - $def_string = preg_replace('/unsigned/im', '', $def_string); - $def_string = preg_replace('/auto_increment/im', 'PRIMARY KEY AUTOINCREMENT', $def_string); - // when you use ALTER TABLE ADD, you can't use current_*. so we replace - $def_string = str_ireplace($array_curtime, $array_reptime, $def_string); - // colDef is enum - $pattern_enum = '/enum\((.*?)\)([^,\)]*)/ims'; - if (preg_match($pattern_enum, $col_def, $matches)) { - $def_string = 'TEXT' . $matches[2] . ' CHECK (' . $col_name . ' IN (' . $matches[1] . '))'; - } - return $def_string; - } - /** - * Variable to store the data definition table. - * - * @access private - * @var associative array - */ - private $array_types = array( - 'bit' => 'INTEGER', 'bool' => 'INTEGER', - 'boolean' => 'INTEGER', 'tinyint' => 'INTEGER', - 'smallint' => 'INTEGER', 'mediumint' => 'INTEGER', - 'bigint' => 'INTEGER', 'integer' => 'INTEGER', - 'int' => 'INTEGER', 'float' => 'REAL', - 'double' => 'REAL', 'decimal' => 'REAL', - 'dec' => 'REAL', 'numeric' => 'REAL', - 'fixed' => 'REAL', 'datetime' => 'TEXT', - 'date' => 'TEXT', 'timestamp' => 'TEXT', - 'time' => 'TEXT', 'year' => 'TEXT', - 'varchar' => 'TEXT', 'char' => 'TEXT', - 'varbinary' => 'BLOB', 'binary' => 'BLOB', - 'tinyblob' => 'BLOB', 'mediumblob' => 'BLOB', - 'longblob' => 'BLOB', 'blob' => 'BLOB', - 'tinytext' => 'TEXT', 'mediumtext' => 'TEXT', - 'longtext' => 'TEXT', 'text' => 'TEXT' - ); + private function handle_add_primary_key($queries) { + $tokenized_query = $queries; + $tbl_name = $tokenized_query['table_name']; + $temp_table = 'temp_'.$tokenized_query['table_name']; + $_wpdb = new PDODB(); + $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='$tbl_name'"); + $_wpdb = null; + for ($i = 0; $i < count($query_obj); $i++) { + $index_queries[$i] = $query_obj[$i]->sql; + } + $table_query = array_shift($index_queries); + $table_query = str_replace($tokenized_query['table_name'], $temp_table, $table_query); + $table_query = rtrim($table_query, ')'); + $table_query = ", PRIMARY KEY {$tokenized_query['column_name']}"; + $query[] = $table_query; + $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; + $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; + $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; + foreach ($index_queries as $index) { + $query[] = $index; + } + return $query; + } + /** + * Function to handle DROP PRIMARY KEY. + * + * @access private + * @param array of string $queries + * @return array of string + */ + private function handle_drop_primary_key($queries) { + $tokenized_query = $queries; + $temp_table = 'temp_'.$tokenized_query['table_name']; + $_wpdb = new PDODB(); + $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); + $_wpdb = null; + for ($i = 0; $i < count($query_obj); $i++) { + $index_queries[$i] = $query_obj[$i]->sql; + } + $table_query = array_shift($index_queries); + $pattern1 = '/^\\s*PRIMARY\\s*KEY\\s*\(.*\)/im'; + $pattern2 = '/^\\s*.*(PRIMARY\\s*KEY\\s*(:?AUTOINCREMENT|))\\s*(?!\()/im'; + if (preg_match($pattern1, $table_query, $match)) { + $table_query = str_replace($match[0], '', $table_query); + } elseif (preg_match($pattern2, $table_query, $match)) { + $table_query = str_replace($match[1], '', $table_query); + } + $table_query = str_replace($tokenized_query['table_name'], $temp_table, $table_query); + $query[] = $table_query; + $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; + $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; + $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; + foreach ($index_queries as $index) { + $query[] = $index; + } + return $query; + } + /** + * Function to handle MODIFY COLUMN. + * + * @access private + * @param array of string $queries + * @return string|array of string + */ + private function handle_modify_command($queries) { + $tokenized_query = $queries; + $temp_table = 'temp_'.$tokenized_query['table_name']; + $column_def = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['column_def']); + $_wpdb = new PDODB(); + $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); + $_wpdb = null; + for ($i =0; $i < count($query_obj); $i++) { + $index_queries[$i] = $query_obj[$i]->sql; + } + $create_query = array_shift($index_queries); + if (stripos($create_query, $tokenized_query['column_name']) === false) { + return 'SELECT 1=1'; + } elseif (preg_match("/{$tokenized_query['column_name']}\\s*{$column_def}\\s*[,)]/i", $create_query)) { + return 'SELECT 1=1'; + } + $create_query = preg_replace("/{$tokenized_query['table_name']}/i", $temp_table, $create_query); + if (preg_match("/\\b{$tokenized_query['column_name']}\\s*.*(?=,)/ims", $create_query)) { + $create_query = preg_replace("/\\b{$tokenized_query['column_name']}\\s*.*(?=,)/ims", "{$tokenized_query['column_name']} {$column_def}", $create_query); + } elseif (preg_match("/\\b{$tokenized_query['column_name']}\\s*.*(?=\))/ims", $create_query)) { + $create_query = preg_replace("/\\b{$tokenized_query['column_name']}\\s*.*(?=\))/ims", "{$tokenized_query['column_name']} {$column_def}", $create_query); + } + $query[] = $create_query; + $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; + $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; + $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; + foreach ($index_queries as $index) { + $query[] = $index; + } + return $query; + } + /** + * Function to handle CHANGE COLUMN. + * + * @access private + * @param array of string $queries + * @return string|array of string + */ + private function handle_change_command($queries) { + $col_check = false; + $old_fields = ''; + $new_fields = ''; + $tokenized_query = $queries; + $temp_table = 'temp_'.$tokenized_query['table_name']; + if (isset($tokenized_query['new_column'])) { + $column_name = $tokenized_query['new_column']; + } else { + $column_name = $tokenized_query['old_column']; + } + $column_def = $this->convert_field_types($column_name, $tokenized_query['column_def']); + $_wpdb = new PDODB(); + $col_obj = $_wpdb->get_results("SHOW COLUMNS FROM {$tokenized_query['table_name']}"); + foreach ($col_obj as $col) { + if (stripos($col->Field, $tokenized_query['old_column']) !== false) $col_check = true; + $old_fields .= $col->Field . ','; + } + if ($col_check == false) { + $_wpdb = null; + return 'SELECT 1=1'; + } + $old_fields = rtrim($old_fields, ','); + $new_fields = str_ireplace($tokenized_query['old_column'], $column_name, $old_fields); + $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); + $_wpdb = null; + for ($i = 0; $i < count($query_obj); $i++) { + $index_queries[$i] = $query_obj[$i]->sql; + } + $create_query = array_shift($index_queries); + $create_query = preg_replace("/{$tokenized_query['table_name']}/i", $temp_table, $create_query); + if (preg_match("/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=,)/ims", $create_query, $match)) { + if (stripos(trim($match[1]), $column_def) !== false) { + return 'SELECT 1=1'; + } else { + $create_query = preg_replace("/\\b{$tokenized_query['old_column']}\\s*.+?(?=,)/ims", "{$column_name} {$column_def}", $create_query, 1); + } + } elseif (preg_match("/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=\))/ims", $create_query, $match)) { + if (stripos(trim($match[1]), $column_def) !== false) { + return 'SELECT 1=1'; + } else { + $create_query = preg_replace("/\\b{$tokenized_query['old_column']}\\s*.*(?=\))/ims", "{$column_name} {$column_def}", $create_query, 1); + } + } + $query[] = $create_query; + $query[] = "INSERT INTO $temp_table ($new_fields) SELECT $old_fields FROM {$tokenized_query['table_name']}"; + $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; + $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; + foreach ($index_queries as $index) { + $query[] = $index; + } + return $query; + } + /** + * Function to handle ALTER COLUMN. + * + * @access private + * @param array of string $queries + * @return string|array of string + */ + private function handle_alter_command($queries) { + $tokenized_query = $queries; + $temp_table = 'temp_'.$tokenized_query['table_name']; + if (isset($tokenized_query['default_value'])) { + $def_value = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['default_value']); + $def_value = 'DEFAULT '.$def_value; + } else { + $def_value = null; + } + $_wpdb = new PDODB(); + $query_obj = $_wpdb->get_results("SELECT sql FROM sqlite_master WHERE tbl_name='{$tokenized_query['table_name']}'"); + $_wpdb = null; + for ($i =0; $i < count($query_obj); $i++) { + $index_queries[$i] = $query_obj[$i]->sql; + } + $create_query = array_shift($index_queries); + if (stripos($create_query, $tokenized_query['column_name']) === false) { + return 'SELECT 1=1'; + } + if (preg_match("/\\s*({$tokenized_query['column_name']})\\s*(.*)?(DEFAULT\\s*.*)[,)]/im", $create_query, $match)) { + $col_name = trim($match[1]); + $col_def = trim($match[2]); + $col_def_esc = str_replace(array('(', ')'), array('\(', '\)'), $col_def); + $checked_col_def = $this->convert_field_types($col_name, $col_def); + $old_default = trim($match[3]); + $pattern = "/$col_name\\s*$col_def_esc\\s*$old_default/im"; + if (is_null($def_value)) { + $replacement = $col_name . ' ' . $checked_col_def; + } else { + $replacement = $col_name . ' ' . $checked_col_def . ' ' . $def_value; + } + $create_query = preg_replace($pattern, $replacement, $create_query); + $create_query = str_ireplace($tokenized_query['table_name'], $temp_table, $create_query); + } elseif (preg_match("/\\s*({$tokenized_query['column_name']})\\s*(.*)?[,)]/im", $create_query, $match)) { + $col_name = trim($match[1]); + $col_def = trim($match[2]); + $col_def_esc = str_replace(array('(', ')'), array('\(', '\)'), $col_def); + $checked_col_def = $this->convert_field_types($col_name, $col_def); + $pattern = "/$col_name\\s*$col_def_esc/im"; + if (is_null($def_value)) { + $replacement = $col_name . ' ' . $checked_col_def; + } else { + $replacement = $col_name . ' ' . $checked_col_def . ' ' . $def_value; + } + $create_query = preg_replace($pattern, $replacement, $create_query); + $create_query = str_ireplace($tokenized_query['table_name'], $temp_table, $create_query); + } else { + return 'SELECT 1=1'; + } + $query[] = $create_query; + $query[] = "INSERT INTO $temp_table SELECT * FROM {$tokenized_query['table_name']}"; + $query[] = "DROP TABLE IF EXISTS {$tokenized_query['table_name']}"; + $query[] = "ALTER TABLE $temp_table RENAME TO {$tokenized_query['table_name']}"; + foreach ($index_queries as $index) { + $query[] = $index; + } + return $query; + } + /** + * Function to change the field definition to SQLite compatible data type. + * + * @access private + * @param string $col_name + * @param string $col_def + * @return string + */ + private function convert_field_types($col_name, $col_def){ + $array_curtime = array('current_timestamp', 'current_time', 'current_date'); + $array_reptime = array("'0000-00-00 00:00:00'", "'0000-00-00 00:00:00'", "'0000-00-00'"); + $def_string = str_replace('`', '', $col_def); + foreach ($this->array_types as $o=>$r){ + $pattern = "/\\b$o\\s*(\([^\)]*\)*)?\\s*/ims"; + if (preg_match($pattern, $def_string)) { + $def_string = preg_replace($pattern, "$r ", $def_string); + break; + } + } + $def_string = preg_replace('/unsigned/im', '', $def_string); + $def_string = preg_replace('/auto_increment/im', 'PRIMARY KEY AUTOINCREMENT', $def_string); + // when you use ALTER TABLE ADD, you can't use current_*. so we replace + $def_string = str_ireplace($array_curtime, $array_reptime, $def_string); + // colDef is enum + $pattern_enum = '/enum\((.*?)\)([^,\)]*)/ims'; + if (preg_match($pattern_enum, $col_def, $matches)) { + $def_string = 'TEXT' . $matches[2] . ' CHECK (' . $col_name . ' IN (' . $matches[1] . '))'; + } + return $def_string; + } + /** + * Variable to store the data definition table. + * + * @access private + * @var associative array + */ + private $array_types = array( + 'bit' => 'INTEGER', 'bool' => 'INTEGER', + 'boolean' => 'INTEGER', 'tinyint' => 'INTEGER', + 'smallint' => 'INTEGER', 'mediumint' => 'INTEGER', + 'bigint' => 'INTEGER', 'integer' => 'INTEGER', + 'int' => 'INTEGER', 'float' => 'REAL', + 'double' => 'REAL', 'decimal' => 'REAL', + 'dec' => 'REAL', 'numeric' => 'REAL', + 'fixed' => 'REAL', 'datetime' => 'TEXT', + 'date' => 'TEXT', 'timestamp' => 'TEXT', + 'time' => 'TEXT', 'year' => 'TEXT', + 'varchar' => 'TEXT', 'char' => 'TEXT', + 'varbinary' => 'BLOB', 'binary' => 'BLOB', + 'tinyblob' => 'BLOB', 'mediumblob' => 'BLOB', + 'longblob' => 'BLOB', 'blob' => 'BLOB', + 'tinytext' => 'TEXT', 'mediumtext' => 'TEXT', + 'longtext' => 'TEXT', 'text' => 'TEXT' + ); } ?> \ No newline at end of file diff --git a/query_create.class.php b/query_create.class.php index 2a37ad5..e8ff1b0 100644 --- a/query_create.class.php +++ b/query_create.class.php @@ -1,56 +1,56 @@ rewrite_set(); $this->rewrite_key(); $this->add_if_not_exists(); - + return $this->post_process(); } /** * Method to get table name from the query string. - * + * * 'IF NOT EXISTS' clause is removed for the easy regular expression usage. * It will be added at the end of the process. - * + * * @access private */ private function get_table_name(){ // $pattern = '/^\\s*CREATE\\s*(TEMP|TEMPORARY)?\\s*TABLE\\s*(IF NOT EXISTS)?\\s*([^\(]*)/imsx'; - $pattern = '/^\\s*CREATE\\s*(?:TEMP|TEMPORARY)?\\s*TABLE\\s*(?:IF\\s*NOT\\s*EXISTS)?\\s*([^\(]*)/imsx'; + $pattern = '/^\\s*CREATE\\s*(?:TEMP|TEMPORARY)?\\s*TABLE\\s*(?:IF\\s*NOT\\s*EXISTS)?\\s*([^\(]*)/imsx'; if (preg_match($pattern, $this->_query, $matches)) { - $this->table_name = trim($matches[1]); - } + $this->table_name = trim($matches[1]); + } } /** * Method to change the MySQL field types to SQLite compatible types. - * + * * Order of the key value is important. Don't change it. - * + * * @access private */ private function rewrite_field_types(){ $array_types = array ( - 'bit' => 'integer', 'bool' => 'integer', - 'boolean' => 'integer', 'tinyint' => 'integer', - 'smallint' => 'integer', 'mediumint' => 'integer', - 'int' => 'integer', 'integer' => 'integer', - 'bigint' => 'integer', 'float' => 'real', - 'double' => 'real', 'decimal' => 'real', - 'dec' => 'real', 'numeric' => 'real', - 'fixed' => 'real', 'date' => 'text', - 'datetime' => 'text', 'timestamp' => 'text', - 'time' => 'text', 'year' => 'text', - 'char' => 'text', 'varchar' => 'text', - 'binary' => 'integer', 'varbinary' => 'blob', - 'tinyblob' => 'blob', 'tinytext' => 'text', - 'blob' => 'blob', 'text' => 'text', - 'mediumblob' => 'blob', 'mediumtext' => 'text', - 'longblob' => 'blob', 'longtext' => 'text' - ); + 'bit' => 'integer', 'bool' => 'integer', + 'boolean' => 'integer', 'tinyint' => 'integer', + 'smallint' => 'integer', 'mediumint' => 'integer', + 'int' => 'integer', 'integer' => 'integer', + 'bigint' => 'integer', 'float' => 'real', + 'double' => 'real', 'decimal' => 'real', + 'dec' => 'real', 'numeric' => 'real', + 'fixed' => 'real', 'date' => 'text', + 'datetime' => 'text', 'timestamp' => 'text', + 'time' => 'text', 'year' => 'text', + 'char' => 'text', 'varchar' => 'text', + 'binary' => 'integer', 'varbinary' => 'blob', + 'tinyblob' => 'blob', 'tinytext' => 'text', + 'blob' => 'blob', 'text' => 'text', + 'mediumblob' => 'blob', 'mediumtext' => 'text', + 'longblob' => 'blob', 'longtext' => 'text' + ); foreach ($array_types as $o=>$r){ $pattern = "/\\b(?_query)) { @@ -140,43 +140,43 @@ class CreateQuery{ } /** * Method for stripping the comments from the SQL statement. - * + * * @access private - */ + */ private function rewrite_comments(){ $this->_query = preg_replace("/# --------------------------------------------------------/","-- ******************************************************",$this->_query); $this->_query = preg_replace("/#/","--",$this->_query); } /** * Method for stripping the engine and other stuffs. - * + * * TYPE, ENGINE and AUTO_INCREMENT are removed here. * @access private - */ + */ private function rewrite_engine_info(){ $this->_query = preg_replace("/\\s*(TYPE|ENGINE)\\s*=\\s*.*(?_query); $this->_query = preg_replace("/ AUTO_INCREMENT\\s*=\\s*[0-9]*/ims",'',$this->_query); } /** * Method for stripping unsigned. - * + * * SQLite doesn't have unsigned int data type. So UNSIGNED INT(EGER) is converted * to INTEGER here. - * + * * @access private - */ + */ private function rewrite_unsigned(){ $this->_query = preg_replace('/\\bunsigned\\b/ims', ' ', $this->_query); } /** * Method for rewriting primary key auto_increment. - * + * * If the field type is 'INTEGER PRIMARY KEY', it is automatically autoincremented * by SQLite. There's a little difference between PRIMARY KEY and AUTOINCREMENT, so * we may well convert to PRIMARY KEY only. - * + * * @access private - */ + */ private function rewrite_autoincrement(){ $this->_query = preg_replace('/\\bauto_increment\\s*primary\\s*key\\s*(,)?/ims', ' PRIMARY KEY AUTOINCREMENT \\1', $this->_query, -1, $count); $this->_query = preg_replace('/\\bauto_increment\\b\\s*(,)?/ims', ' PRIMARY KEY AUTOINCREMENT $1', $this->_query, -1, $count); @@ -186,72 +186,72 @@ class CreateQuery{ } /** * Method for rewriting primary key. - * + * * @access private - */ + */ private function rewrite_primary_key(){ if ($this->has_primary_key) { $this->_query = preg_replace('/\\s*primary key\\s*.*?\([^\)]*\)\\s*(,|)/i', ' ', $this->_query); } else { - // If primary key has an index name, we remove that name. - $this->_query = preg_replace('/\\bprimary\\s*key\\s*.*?\\s*(\(.*?\))/im', 'PRIMARY KEY \\1', $this->_query); + // If primary key has an index name, we remove that name. + $this->_query = preg_replace('/\\bprimary\\s*key\\s*.*?\\s*(\(.*?\))/im', 'PRIMARY KEY \\1', $this->_query); + } + } + /** + * Method for rewriting foreign key. + * + * @access private + */ + private function rewrite_foreign_key() { + $pattern = '/\\s*foreign\\s*key\\s*(|.*?)\([^\)]+?\)\\s*references\\s*.*/i'; + if (preg_match_all($pattern, $this->_query, $match)) { + if (isset($match[1])) { + $this->_query = str_ireplace($match[1], '', $this->_query); + } } } - /** - * Method for rewriting foreign key. - * - * @access private - */ - private function rewrite_foreign_key() { - $pattern = '/\\s*foreign\\s*key\\s*(|.*?)\([^\)]+?\)\\s*references\\s*.*/i'; - if (preg_match_all($pattern, $this->_query, $match)) { - if (isset($match[1])) { - $this->_query = str_ireplace($match[1], '', $this->_query); - } - } - } /** * Method for rewriting unique key. - * + * * @access private - */ + */ private function rewrite_unique_key(){ $this->_query = preg_replace_callback('/\\bunique key\\b([^\(]*)(\(.*\))/im', array($this, '_rewrite_unique_key'), $this->_query); } /** * Callback method for rewrite_unique_key. - * + * * @param array $matches an array of matches from the Regex * @access private */ private function _rewrite_unique_key($matches){ - $index_name = trim($matches[1]); - $col_name = trim($matches[2]); - $tbl_name = $this->table_name; - if (preg_match('/\(\\d+?\)/', $col_name)) { - $col_name = preg_replace('/\(\\d+?\)/', '', $col_name); - } - $_wpdb = new PDODB(); - $results = $_wpdb->get_results("SELECT name FROM sqlite_master WHERE type='index'"); - $_wpdb = null; - if ($results) { - foreach ($results as $result) { - if ($result->name == $index_name) { - $r = rand(0, 50); - $index_name = $index_name . "_$r"; - break; - } - } - } + $index_name = trim($matches[1]); + $col_name = trim($matches[2]); + $tbl_name = $this->table_name; + if (preg_match('/\(\\d+?\)/', $col_name)) { + $col_name = preg_replace('/\(\\d+?\)/', '', $col_name); + } + $_wpdb = new PDODB(); + $results = $_wpdb->get_results("SELECT name FROM sqlite_master WHERE type='index'"); + $_wpdb = null; + if ($results) { + foreach ($results as $result) { + if ($result->name == $index_name) { + $r = rand(0, 50); + $index_name = $index_name . "_$r"; + break; + } + } + } $index_name = str_replace(' ', '', $index_name); $this->index_queries[] = "CREATE UNIQUE INDEX $index_name ON " . $tbl_name .$col_name; return ''; } /** * Method for handling ENUM fields. - * + * * SQLite doesn't support enum, so we change it to check constraint. - * + * * @access private */ private function rewrite_enum(){ @@ -260,7 +260,7 @@ class CreateQuery{ } /** * Call back method for rewrite_enum() and rewrite_set(). - * + * * @access private */ private function _rewrite_enum($matches){ @@ -269,9 +269,9 @@ class CreateQuery{ } /** * Method for rewriting usage of set. - * + * * It is similar but not identical to enum. SQLite does not support either. - * + * * @access private */ private function rewrite_set(){ @@ -280,10 +280,10 @@ class CreateQuery{ } /** * Method for rewriting usage of key to create an index. - * + * * SQLite cannot create non-unique indices as part of the create query, * so we need to create an index by hand and append it to the create query. - * + * * @access private */ private function rewrite_key(){ @@ -291,72 +291,72 @@ class CreateQuery{ } /** * Callback method for rewrite_key. - * + * * @param array $matches an array of matches from the Regex * @access private - */ + */ private function _rewrite_key($matches){ - $index_name = trim($matches[2]); - $col_name = trim($matches[3]); - if (preg_match('/\([0-9]+?\)/', $col_name, $match)) { - $col_name = preg_replace_callback('/\([0-9]+?\)/', array($this, '_remove_length'), $col_name); - } - $tbl_name = $this->table_name; - $_wpdb = new PDODB(); - $results = $_wpdb->get_results("SELECT name FROM sqlite_master WHERE type='index'"); - $_wpdb = null; - if ($results) { - foreach ($results as $result) { - if ($result->name == $index_name) { - $r = rand(0, 50); - $index_name = $index_name . "_$r"; - break; - } - } - } + $index_name = trim($matches[2]); + $col_name = trim($matches[3]); + if (preg_match('/\([0-9]+?\)/', $col_name, $match)) { + $col_name = preg_replace_callback('/\([0-9]+?\)/', array($this, '_remove_length'), $col_name); + } + $tbl_name = $this->table_name; + $_wpdb = new PDODB(); + $results = $_wpdb->get_results("SELECT name FROM sqlite_master WHERE type='index'"); + $_wpdb = null; + if ($results) { + foreach ($results as $result) { + if ($result->name == $index_name) { + $r = rand(0, 50); + $index_name = $index_name . "_$r"; + break; + } + } + } $this->index_queries[] = 'CREATE INDEX '. $index_name . ' ON ' . $tbl_name . $col_name ; return ''; } /** * Call back method to remove unnecessary string. - * + * * This method is deprecated. - * + * * @param string $match * @return string whose length is zero * @access private */ private function _remove_length($match) { - return ''; + return ''; } /** * Method to assemble the main query and index queries into an array. - * + * * It return the array of the queries to be executed separately. - * + * * @return array * @access private */ - private function post_process(){ + private function post_process() { $mainquery = $this->_query; do{ $count = 0; $mainquery = preg_replace('/,\\s*\)/imsx',')', $mainquery, -1, $count); } while ($count > 0); do { - $count = 0; - $mainquery = preg_replace('/\(\\s*?,/imsx', '(', $mainquery, -1, $count); + $count = 0; + $mainquery = preg_replace('/\(\\s*?,/imsx', '(', $mainquery, -1, $count); } while ($count > 0); $return_val[] = $mainquery; $return_val = array_merge($return_val, $this->index_queries); - return $return_val; + return $return_val; } /** * Method to add IF NOT EXISTS to query string. - * + * * This adds IF NOT EXISTS to every query string, which prevent the exception * from being thrown. - * + * * @access private */ private function add_if_not_exists(){ @@ -364,33 +364,33 @@ class CreateQuery{ $this->_query = preg_replace($pattern_table, 'CREATE $1 TABLE IF NOT EXISTS ', $this->_query); $pattern_index = '/^\\s*CREATE\\s*(UNIQUE)?\\s*INDEX\\s*(IF NOT EXISTS)?\\s*/ims'; for ($i = 0; $i < count($this->index_queries); $i++) { - $this->index_queries[$i] = preg_replace($pattern_index, 'CREATE $1 INDEX IF NOT EXISTS ', $this->index_queries[$i]); + $this->index_queries[$i] = preg_replace($pattern_index, 'CREATE $1 INDEX IF NOT EXISTS ', $this->index_queries[$i]); } } /** * Method to strip back quotes. - * + * * @access private - */ + */ private function strip_backticks(){ $this->_query = str_replace('`', '', $this->_query); - foreach ($this->index_queries as &$query) { - $query = str_replace('`', '', $query); - } + foreach ($this->index_queries as &$query) { + $query = str_replace('`', '', $query); + } } /** * Method to remove the character set information from within mysql queries. - * + * * This removes DEFAULT CHAR(ACTER) SET and COLLATE, which is meaningless for * SQLite. - * + * * @access private - */ + */ private function rewrite_character_set(){ $pattern_charset = '/\\b(default\\s*character\\s*set|default\\s*charset|character\\s*set)\\s*(?_query = preg_replace($patterns, '', $this->_query); } } diff --git a/schema.php b/schema.php index 5100ed1..c1342be 100644 --- a/schema.php +++ b/schema.php @@ -1,7 +1,7 @@ PDO::ERRMODE_EXCEPTION)); + $pdo = new PDO('sqlite:'.FQDB, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); } catch (PDOException $err) { - $err_data = $err->errorInfo; - $message = 'Database connection error!
    '; - $message .= sprintf("Error message is: %s", $err_data[2]); - wp_die($message, 'Database Error!'); + $err_data = $err->errorInfo; + $message = 'Database connection error!
    '; + $message .= sprintf("Error message is: %s", $err_data[2]); + wp_die($message, 'Database Error!'); } try { - $pdo->beginTransaction(); - foreach ($queries as $query) { - $query = trim($query); - if (empty($query)) - continue; - $rewritten_query = $query_parser->rewrite_query($query); - if (is_array($rewritten_query)) { - $table_query = array_shift($rewritten_query); - $index_queries = $rewritten_query; - $table_query = trim($table_query); - $pdo->exec($table_query); -// foreach($rewritten_query as $single_query) { -// $single_query = trim($single_query); -// $pdo->exec($single_query); -// } - } else { - $rewritten_query = trim($rewritten_query); - $pdo->exec($rewritten_query); - } - } - $pdo->commit(); - if ($index_queries) { - // $query_parser rewrites KEY to INDEX, so we don't need KEY pattern - $pattern = '/CREATE\\s*(UNIQUE\\s*INDEX|INDEX)\\s*IF\\s*NOT\\s*EXISTS\\s*(\\w+)?\\s*.*/im'; - $pdo->beginTransaction(); - foreach ($index_queries as $index_query) { - preg_match($pattern, $index_query, $match); - $index_name = trim($match[2]); - if (in_array($index_name, $index_array)) { - $r = rand(0, 50); - $replacement = $index_name . "_$r"; - $index_query = str_ireplace('EXISTS '.$index_name, 'EXISTS '.$replacement, $index_query); - } else { - $index_array[] = $index_name; - } - $pdo->exec($index_query); - } - $pdo->commit(); - } + $pdo->beginTransaction(); + foreach ($queries as $query) { + $query = trim($query); + if (empty($query)) + continue; + $rewritten_query = $query_parser->rewrite_query($query); + if (is_array($rewritten_query)) { + $table_query = array_shift($rewritten_query); + $index_queries = $rewritten_query; + $table_query = trim($table_query); + $pdo->exec($table_query); + //foreach($rewritten_query as $single_query) { + // $single_query = trim($single_query); + // $pdo->exec($single_query); + //} + } else { + $rewritten_query = trim($rewritten_query); + $pdo->exec($rewritten_query); + } + } + $pdo->commit(); + if ($index_queries) { + // $query_parser rewrites KEY to INDEX, so we don't need KEY pattern + $pattern = '/CREATE\\s*(UNIQUE\\s*INDEX|INDEX)\\s*IF\\s*NOT\\s*EXISTS\\s*(\\w+)?\\s*.*/im'; + $pdo->beginTransaction(); + foreach ($index_queries as $index_query) { + preg_match($pattern, $index_query, $match); + $index_name = trim($match[2]); + if (in_array($index_name, $index_array)) { + $r = rand(0, 50); + $replacement = $index_name . "_$r"; + $index_query = str_ireplace('EXISTS '.$index_name, 'EXISTS '.$replacement, $index_query); + } else { + $index_array[] = $index_name; + } + $pdo->exec($index_query); + } + $pdo->commit(); + } } catch (PDOException $err) { - $err_data = $err->errorInfo; - $err_code = $err_data[1]; - if (5 == $err_code || 6 == $err_code) { - // if the database is locked, commit again - $pdo->commit(); - } else { - $pdo->rollBack(); - $message = sprintf("Error occured while creating tables or indexes...
    Query was: %s
    ", var_export($rewritten_query, true)); - $message .= sprintf("Error message is: %s", $err_data[2]); - wp_die($message, 'Database Error!'); - } + $err_data = $err->errorInfo; + $err_code = $err_data[1]; + if (5 == $err_code || 6 == $err_code) { + // if the database is locked, commit again + $pdo->commit(); + } else { + $pdo->rollBack(); + $message = sprintf("Error occured while creating tables or indexes...
    Query was: %s
    ", var_export($rewritten_query, true)); + $message .= sprintf("Error message is: %s", $err_data[2]); + wp_die($message, 'Database Error!'); + } } $query_parser = null; diff --git a/sqlite-integration.php b/sqlite-integration.php index 4b8b171..2fa1c2b 100644 --- a/sqlite-integration.php +++ b/sqlite-integration.php @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /** * This file defines global constants and defines SQLiteIntegration class. - * + * * @package SQLite Integration * @author Kojima Toshiyasu */ @@ -57,13 +57,13 @@ if (defined('WP_PLUGIN_URL')) { * Defines patch file upload directory. */ if (defined('UPLOADS')) { - define('SQLitePatchDir', UPLOADS . '/patches'); + define('SQLitePatchDir', UPLOADS . '/patches'); } else { - if (defined('WP_CONTENT_DIR')) { - define('SQLitePatchDir', WP_CONTENT_DIR . '/uploads/patches'); - } else { - define('SQLitePatchDir', ABSPATH . 'wp-content/uploads/patches'); - } + if (defined('WP_CONTENT_DIR')) { + define('SQLitePatchDir', WP_CONTENT_DIR . '/uploads/patches'); + } else { + define('SQLitePatchDir', ABSPATH . 'wp-content/uploads/patches'); + } } /* * Plugin compatibility file in json format. @@ -73,16 +73,16 @@ define('SQLiteListFile', SQLiteFilePath . '/utilities/plugin_lists.json'); * Instantiates utility classes. */ if (!class_exists('SQLiteIntegrationUtils')) { - require_once SQLiteFilePath . '/utilities/utility.php'; - $utils = new SQLiteIntegrationUtils(); + require_once SQLiteFilePath . '/utilities/utility.php'; + $utils = new SQLiteIntegrationUtils(); } if (!class_exists('SQLiteIntegrationDocument')) { - require_once SQLiteFilePath . '/utilities/documentation.php'; - $doc = new SQLiteIntegrationDocument(); + require_once SQLiteFilePath . '/utilities/documentation.php'; + $doc = new SQLiteIntegrationDocument(); } if (!class_exists('PatchUtils')) { - require_once SQLiteFilePath . '/utilities/patch.php'; - $patch_utils = new PatchUtils(); + require_once SQLiteFilePath . '/utilities/patch.php'; + $patch_utils = new PatchUtils(); } if (!class_exists('DatabaseMaintenance')) { require_once SQLiteFilePath . '/utilities/database_maintenance.php'; @@ -91,232 +91,233 @@ if (!class_exists('DatabaseMaintenance')) { /** * This class is for WordPress Administration Panel. - * + * * This class and other utility classes don't affect the base functionality * of the plugin. - * + * */ class SQLiteIntegration { - /** - * Constructor. - * - * This constructor does everything needed for the administration panel. - * - * @param no parameter is provided. - */ - function __construct() { - if (function_exists('register_activation_hook')) { - register_activation_hook(__FILE__, array($this, 'install')); - } - if (function_exists('register_deactivation_hook')) { - } - if (function_exists('register_uninstall_hook')) { - register_uninstall_hook(__FILE__, array('SQLiteIntegration', 'uninstall')); - } - if (function_exists('is_multisite') && is_multisite()) { - add_action('network_admin_menu', array($this, 'add_network_pages')); - add_action('network_admin_notices', array('SQLiteIntegrationUtils', 'show_admin_notice')); - } else { - add_action('admin_menu', array($this, 'add_pages')); - add_action('admin_notices', array('SQLiteIntegrationUtils', 'show_admin_notice')); - } - // See the docstring for download_backup_db() in utilities/utility.php - // We need this registration process. - add_action('admin_init', array('SQLiteIntegrationUtils', 'download_backup_db')); - add_action('plugins_loaded', array($this, 'textdomain_init')); - } + /** + * Constructor. + * + * This constructor does everything needed for the administration panel. + * + * @param no parameter is provided. + */ + function __construct() { + if (function_exists('register_activation_hook')) { + register_activation_hook(__FILE__, array($this, 'install')); + } + if (function_exists('register_deactivation_hook')) { + ; + } + if (function_exists('register_uninstall_hook')) { + register_uninstall_hook(__FILE__, array('SQLiteIntegration', 'uninstall')); + } + if (function_exists('is_multisite') && is_multisite()) { + add_action('network_admin_menu', array($this, 'add_network_pages')); + add_action('network_admin_notices', array('SQLiteIntegrationUtils', 'show_admin_notice')); + } else { + add_action('admin_menu', array($this, 'add_pages')); + add_action('admin_notices', array('SQLiteIntegrationUtils', 'show_admin_notice')); + } + // See the docstring for download_backup_db() in utilities/utility.php + // We need this registration process. + add_action('admin_init', array('SQLiteIntegrationUtils', 'download_backup_db')); + add_action('plugins_loaded', array($this, 'textdomain_init')); + } - /** - * Method to install on multisite or single site. - * - * There really is nothing to install for now. It is for future use... - * - * @param no parameter is provided. - * @return returns null. - */ - function install() { - global $wpdb; - if (function_exists('is_multisite') && is_multisite()) { - $old_blog = $wpdb->blogid; - $blog_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); - foreach ($blog_ids as $blog_id) { - switch_to_blog($blog_id); - $this->_install(); - } - switch_to_blog($old_blog); - return; - } else { - $this->_install(); - return; - } - } - - /** - * Method to install something. - * - * We have nothing to do for now. - * We show menu and documents only to the network administrator. - * - * @param no parameter is provided. - * @return no return values. - */ - function _install() { - } - - /** - * Method to uninstall plugin. - * - * This will remove wp-content/db.php and wp-content/patches direcotry. - * If you migrate the site to the sever with MySQL, you have only to - * migrate the data in the database. - * - * @param no parameter is provided. - * @return no return values. - */ - function uninstall() { - // remove patch files and patch directory - if (file_exists(SQLitePatchDir) && is_dir(SQLitePatchDir)) { - $dir_handle = opendir(SQLitePatchDir); - while (($file_name = readdir($dir_handle)) !== false) { - if ($file_name != '.' && $file_name != '..') { - unlink(SQLitePatchDir.'/'.$file_name); - } - } - rmdir(SQLitePatchDir); - } - // remove wp-content/db.php - if (defined('WP_CONTENT_DIR')) { - $target = WP_CONTENT_DIR . 'db.php'; - } else { - $target = ABSPATH . 'wp-content/db.php'; - } - if (file_exists($target)) { - unlink($target); - } - } - - /** - * Method to manipulate the admin panel, stylesheet and JavaScript. - * - * We use class method to show pages and want to load style files and script - * files only in our plugin documents, so we need add_submenu_page with parent - * slug set to null. This means that menu items are added but hidden from the - * users. - * - * @param no parameter is provided. - * @return no return values. - */ - function add_pages() { - global $utils, $doc, $patch_utils, $maintenance; - if (function_exists('add_options_page')) { - $welcome_page = add_options_page(__('SQLite Integration'), __('SQLite Integration'), 'manage_options', 'sqlite-integration', array($utils, 'welcome')); - $util_page = add_submenu_page(null, 'System Info', 'System Info', 'manage_options', 'sys-info', array($utils, 'show_utils')); - $edit_db = add_submenu_page(null, 'Setting File', 'Setting File', 'manage_options', 'setting-file', array($utils, 'edit_db_file')); - $doc_page = add_submenu_page(null, 'Documentation', 'Documentation', 'manage_options', 'doc', array($doc, 'show_doc')); - $patch_page = add_submenu_page(null, 'Patch Utility', 'Patch Utility', 'manage_options', 'patch', array($patch_utils, 'show_patch_page')); - $maintenance_page = add_submenu_page(null, 'DB Maintenance', 'DB Maintenance', 'manage_options', 'maintenance', array($maintenance, 'show_maintenance_page')); - add_action('admin_print_styles-'.$welcome_page, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$util_page, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$edit_db, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$doc_page, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$patch_page, array($this, 'add_style_sheet')); - add_action('admin_print_scripts-'.$util_page, array($this, 'add_sqlite_script')); - add_action('admin_print_scripts-'.$doc_page, array($this, 'add_sqlite_script')); - add_action('admin_print_scripts-'.$patch_page, array($this, 'add_sqlite_script')); - add_action('admin_print_scripts-'.$edit_db, array($this, 'add_sqlite_script')); - add_action('admin_print_styles-'.$maintenance_page, array($this, 'add_style_sheet')); - } - } - - /** - * Method to manipulate network admin panel. - * - * Capability is set to manage_network_options. - * - * @param no parameter is provided. - * @return no return values. - */ - function add_network_pages() { - global $utils, $doc, $patch_utils, $maintenance; - if (function_exists('add_options_page')) { - $welcome_page = add_submenu_page('settings.php', __('SQLite Integration'), __('SQLite Integration'), 'manage_network_options', 'sqlite-integration', array($utils, 'welcome')); - $util_page = add_submenu_page(null, 'System Info', 'System Info', 'manage_network_options', 'sys-info', array($utils, 'show_utils')); - $edit_db = add_submenu_page(null, 'Setting File', 'Setting File', 'manage_network_options', 'setting-file', array($utils, 'edit_db_file')); - $doc_page = add_submenu_page(null, 'Documentation', 'Documentation', 'manage_network_options', 'doc', array($doc, 'show_doc')); - $patch_page = add_submenu_page(null, 'Patch Utility', 'Patch Utility', 'manage_network_options', 'patch', array($patch_utils, 'show_patch_page')); - $maintenance_page = add_submenu_page(null, 'DB Maintenance', 'DB Maintenance', 'manage_network_options', 'maintenance', array($maintenance, 'show_maintenance_page')); - add_action('admin_print_styles-'.$welcome_page, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$util_page, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$edit_db, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$doc_page, array($this, 'add_style_sheet')); - add_action('admin_print_styles-'.$patch_page, array($this, 'add_style_sheet')); - add_action('admin_print_scripts-'.$util_page, array($this, 'add_sqlite_script')); - add_action('admin_print_scripts-'.$doc_page, array($this, 'add_sqlite_script')); - add_action('admin_print_scripts-'.$patch_page, array($this, 'add_sqlite_script')); - add_action('admin_print_scripts-'.$edit_db, array($this, 'add_sqlite_script')); - add_action('admin_print_styles-'.$maintenance_page, array($this, 'add_style_sheet')); - } - } - - /** - * Method to initialize textdomain. - * - * Japanese catalog is only available. - * - * @param no parameter is provided. - * @return no return values. - */ - function textdomain_init() { - global $utils; -// $current_locale = get_locale(); -// if (!empty($current_locale)) { -// $moFile = dirname(__FILE__) . "/languages/sqlite-wordpress-" . $current_locale . ".mo"; -// if(@file_exists($moFile) && is_readable($moFile)) load_textdomain('sqlite-wordpress', $moFile); -// } - load_plugin_textdomain($utils->text_domain, false, SQLiteDir.'/languages/'); - } + /** + * Method to install on multisite or single site. + * + * There really is nothing to install for now. It is for future use... + * + * @param no parameter is provided. + * @return returns null. + */ + function install() { + global $wpdb; + if (function_exists('is_multisite') && is_multisite()) { + $old_blog = $wpdb->blogid; + $blog_ids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs"); + foreach ($blog_ids as $blog_id) { + switch_to_blog($blog_id); + $this->_install(); + } + switch_to_blog($old_blog); + return; + } else { + $this->_install(); + return; + } + } - /** - * Method to initialize stylesheet on the admin panel. - * - * This determines which stylesheet to use depending on the users' choice - * of admin_color. Each stylesheet imports style.css and change the color - * of the admin dashboard. - * - * @param no parameter is provided. - * @return no return values. - */ - function add_style_sheet() { - global $current_user; - get_currentuserinfo(); - $admin_color = get_user_meta($current_user->ID, 'admin_color', true); - if ($admin_color == 'fresh') { - $stylesheet_file = 'style.min.css'; - } else { - $stylesheet_file = $admin_color . '.min.css'; - } - $style_url = SQLiteUrl . '/styles/' . $stylesheet_file; - $style_file = SQLiteFilePath . '/styles/' . $stylesheet_file; - if (file_exists($style_file)) { - wp_enqueue_style('sqlite_integration_stylesheet', $style_url); - } - } - /** - * Method to register the JavaScript file. - * - * To register the JavaScript file. It's only for the admin dashboard. - * It won't included in web pages. - * - * @param no parameter is provided. - * @return no return value. - */ - function add_sqlite_script() { - $script_url = SQLiteUrl . '/js/sqlite.min.js'; - $script_file = SQLiteFilePath . '/js/sqlite.min.js'; - if (file_exists($script_file)) { - wp_enqueue_script('sqlite-integration', $script_url, 'jquery'); - } - } + /** + * Method to install something. + * + * We have nothing to do for now. + * We show menu and documents only to the network administrator. + * + * @param no parameter is provided. + * @return no return values. + */ + function _install() { + } + + /** + * Method to uninstall plugin. + * + * This will remove wp-content/db.php and wp-content/patches direcotry. + * If you migrate the site to the sever with MySQL, you have only to + * migrate the data in the database. + * + * @param no parameter is provided. + * @return no return values. + */ + function uninstall() { + // remove patch files and patch directory + if (file_exists(SQLitePatchDir) && is_dir(SQLitePatchDir)) { + $dir_handle = opendir(SQLitePatchDir); + while (($file_name = readdir($dir_handle)) !== false) { + if ($file_name != '.' && $file_name != '..') { + unlink(SQLitePatchDir.'/'.$file_name); + } + } + rmdir(SQLitePatchDir); + } + // remove wp-content/db.php + if (defined('WP_CONTENT_DIR')) { + $target = WP_CONTENT_DIR . 'db.php'; + } else { + $target = ABSPATH . 'wp-content/db.php'; + } + if (file_exists($target)) { + unlink($target); + } + } + + /** + * Method to manipulate the admin panel, stylesheet and JavaScript. + * + * We use class method to show pages and want to load style files and script + * files only in our plugin documents, so we need add_submenu_page with parent + * slug set to null. This means that menu items are added but hidden from the + * users. + * + * @param no parameter is provided. + * @return no return values. + */ + function add_pages() { + global $utils, $doc, $patch_utils, $maintenance; + if (function_exists('add_options_page')) { + $welcome_page = add_options_page(__('SQLite Integration'), __('SQLite Integration'), 'manage_options', 'sqlite-integration', array($utils, 'welcome')); + $util_page = add_submenu_page(null, 'System Info', 'System Info', 'manage_options', 'sys-info', array($utils, 'show_utils')); + $edit_db = add_submenu_page(null, 'Setting File', 'Setting File', 'manage_options', 'setting-file', array($utils, 'edit_db_file')); + $doc_page = add_submenu_page(null, 'Documentation', 'Documentation', 'manage_options', 'doc', array($doc, 'show_doc')); + $patch_page = add_submenu_page(null, 'Patch Utility', 'Patch Utility', 'manage_options', 'patch', array($patch_utils, 'show_patch_page')); + $maintenance_page = add_submenu_page(null, 'DB Maintenance', 'DB Maintenance', 'manage_options', 'maintenance', array($maintenance, 'show_maintenance_page')); + add_action('admin_print_styles-'.$welcome_page, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$util_page, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$edit_db, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$doc_page, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$patch_page, array($this, 'add_style_sheet')); + add_action('admin_print_scripts-'.$util_page, array($this, 'add_sqlite_script')); + add_action('admin_print_scripts-'.$doc_page, array($this, 'add_sqlite_script')); + add_action('admin_print_scripts-'.$patch_page, array($this, 'add_sqlite_script')); + add_action('admin_print_scripts-'.$edit_db, array($this, 'add_sqlite_script')); + add_action('admin_print_styles-'.$maintenance_page, array($this, 'add_style_sheet')); + } + } + + /** + * Method to manipulate network admin panel. + * + * Capability is set to manage_network_options. + * + * @param no parameter is provided. + * @return no return values. + */ + function add_network_pages() { + global $utils, $doc, $patch_utils, $maintenance; + if (function_exists('add_options_page')) { + $welcome_page = add_submenu_page('settings.php', __('SQLite Integration'), __('SQLite Integration'), 'manage_network_options', 'sqlite-integration', array($utils, 'welcome')); + $util_page = add_submenu_page(null, 'System Info', 'System Info', 'manage_network_options', 'sys-info', array($utils, 'show_utils')); + $edit_db = add_submenu_page(null, 'Setting File', 'Setting File', 'manage_network_options', 'setting-file', array($utils, 'edit_db_file')); + $doc_page = add_submenu_page(null, 'Documentation', 'Documentation', 'manage_network_options', 'doc', array($doc, 'show_doc')); + $patch_page = add_submenu_page(null, 'Patch Utility', 'Patch Utility', 'manage_network_options', 'patch', array($patch_utils, 'show_patch_page')); + $maintenance_page = add_submenu_page(null, 'DB Maintenance', 'DB Maintenance', 'manage_network_options', 'maintenance', array($maintenance, 'show_maintenance_page')); + add_action('admin_print_styles-'.$welcome_page, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$util_page, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$edit_db, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$doc_page, array($this, 'add_style_sheet')); + add_action('admin_print_styles-'.$patch_page, array($this, 'add_style_sheet')); + add_action('admin_print_scripts-'.$util_page, array($this, 'add_sqlite_script')); + add_action('admin_print_scripts-'.$doc_page, array($this, 'add_sqlite_script')); + add_action('admin_print_scripts-'.$patch_page, array($this, 'add_sqlite_script')); + add_action('admin_print_scripts-'.$edit_db, array($this, 'add_sqlite_script')); + add_action('admin_print_styles-'.$maintenance_page, array($this, 'add_style_sheet')); + } + } + + /** + * Method to initialize textdomain. + * + * Japanese catalog is only available. + * + * @param no parameter is provided. + * @return no return values. + */ + function textdomain_init() { + global $utils; + //$current_locale = get_locale(); + //if (!empty($current_locale)) { + // $moFile = dirname(__FILE__) . "/languages/sqlite-wordpress-" . $current_locale . ".mo"; + // if(@file_exists($moFile) && is_readable($moFile)) load_textdomain('sqlite-wordpress', $moFile); + //} + load_plugin_textdomain($utils->text_domain, false, SQLiteDir.'/languages/'); + } + + /** + * Method to initialize stylesheet on the admin panel. + * + * This determines which stylesheet to use depending on the users' choice + * of admin_color. Each stylesheet imports style.css and change the color + * of the admin dashboard. + * + * @param no parameter is provided. + * @return no return values. + */ + function add_style_sheet() { + global $current_user; + get_currentuserinfo(); + $admin_color = get_user_meta($current_user->ID, 'admin_color', true); + if ($admin_color == 'fresh') { + $stylesheet_file = 'style.min.css'; + } else { + $stylesheet_file = $admin_color . '.min.css'; + } + $style_url = SQLiteUrl . '/styles/' . $stylesheet_file; + $style_file = SQLiteFilePath . '/styles/' . $stylesheet_file; + if (file_exists($style_file)) { + wp_enqueue_style('sqlite_integration_stylesheet', $style_url); + } + } + /** + * Method to register the JavaScript file. + * + * To register the JavaScript file. It's only for the admin dashboard. + * It won't included in web pages. + * + * @param no parameter is provided. + * @return no return value. + */ + function add_sqlite_script() { + $script_url = SQLiteUrl . '/js/sqlite.min.js'; + $script_file = SQLiteFilePath . '/js/sqlite.min.js'; + if (file_exists($script_file)) { + wp_enqueue_script('sqlite-integration', $script_url, 'jquery'); + } + } } /* this is enough for initialization */ diff --git a/utilities/database_maintenance.php b/utilities/database_maintenance.php index ea2e313..8575341 100644 --- a/utilities/database_maintenance.php +++ b/utilities/database_maintenance.php @@ -1,29 +1,29 @@ prefix.'commentmeta' => array( - 'comment_id' => '\'0\'', - 'meta_key' => 'NULL' + 'comment_id' => '\'0\'', + 'meta_key' => 'NULL' ), $wpdb->prefix.'comments' => array( - 'comment_post_ID' => '\'0\'', - 'comment_author_email' => '\'\'', - 'comment_author_url' => '\'\'', - 'comment_author_IP' => '\'\'', - 'comment_date_gmt' => '\'0000-00-00 00:00:00\'', - 'comment_date' => '\'0000-00-00 00:00:00\'', - 'comment_karma' => '\'0\'', - 'comment_approved' => '\'1\'', - 'comment_agent' => '\'\'', - 'comment_type' => '\'\'', - 'comment_parent' => '\'0\'', - 'user_id' => '\'0\'' + 'comment_post_ID' => '\'0\'', + 'comment_author_email' => '\'\'', + 'comment_author_url' => '\'\'', + 'comment_author_IP' => '\'\'', + 'comment_date_gmt' => '\'0000-00-00 00:00:00\'', + 'comment_date' => '\'0000-00-00 00:00:00\'', + 'comment_karma' => '\'0\'', + 'comment_approved' => '\'1\'', + 'comment_agent' => '\'\'', + 'comment_type' => '\'\'', + 'comment_parent' => '\'0\'', + 'user_id' => '\'0\'' ), $wpdb->prefix.'links' => array( - 'link_url' => '\'\'', - 'link_name' => '\'\'', - 'link_image' => '\'\'', - 'link_target' => '\'\'', - 'link_description' => '\'\'', - 'link_visible' => '\'Y\'', - 'link_owner' => '\'1\'', - 'link_rating' => '\'0\'', - 'link_updated' => '\'0000-00-00 00:00:00\'', - 'link_rel' => '\'\'', - 'link_rss' => '\'\'' + 'link_url' => '\'\'', + 'link_name' => '\'\'', + 'link_image' => '\'\'', + 'link_target' => '\'\'', + 'link_description' => '\'\'', + 'link_visible' => '\'Y\'', + 'link_owner' => '\'1\'', + 'link_rating' => '\'0\'', + 'link_updated' => '\'0000-00-00 00:00:00\'', + 'link_rel' => '\'\'', + 'link_rss' => '\'\'' ), $wpdb->prefix.'options' => array( - 'option_name' => '\'\'', - 'autoload' => '\'yes\'' + 'option_name' => '\'\'', + 'autoload' => '\'yes\'' ), $wpdb->prefix.'postmeta' => array( - 'post_id' => '\'0\'', - 'meta_key' => 'NULL' + 'post_id' => '\'0\'', + 'meta_key' => 'NULL' ), $wpdb->prefix.'posts' => array( - 'post_author' => '\'0\'', - 'post_date_gmt' => '\'0000-00-00 00:00:00\'', - 'post_date' => '\'0000-00-00 00:00:00\'', - 'post_status' => '\'publish\'', - 'comment_status' => '\'open\'', - 'ping_status' => '\'open\'', - 'post_password' => '\'\'', - 'post_name' => '\'\'', - 'post_modified_gmt' => '\'0000-00-00 00:00:00\'', - 'post_modified' => '\'0000-00-00 00:00:00\'', - 'post_parent' => '\'0\'', - 'guid' => '\'\'', - 'menu_order' => '\'0\'', - 'post_type' => '\'post\'', - 'post_mime_type' => '\'\'', - 'comment_count' => '\'0\'' + 'post_author' => '\'0\'', + 'post_date_gmt' => '\'0000-00-00 00:00:00\'', + 'post_date' => '\'0000-00-00 00:00:00\'', + 'post_status' => '\'publish\'', + 'comment_status' => '\'open\'', + 'ping_status' => '\'open\'', + 'post_password' => '\'\'', + 'post_name' => '\'\'', + 'post_modified_gmt' => '\'0000-00-00 00:00:00\'', + 'post_modified' => '\'0000-00-00 00:00:00\'', + 'post_parent' => '\'0\'', + 'guid' => '\'\'', + 'menu_order' => '\'0\'', + 'post_type' => '\'post\'', + 'post_mime_type' => '\'\'', + 'comment_count' => '\'0\'' ), $wpdb->prefix.'term_relationships' => array( - 'term_order' => '0' + 'term_order' => '0' ), $wpdb->prefix.'term_taxonomy' => array( - 'taxonomy' => '\'\'', - 'parent' => '0', - 'count' => '0' + 'taxonomy' => '\'\'', + 'parent' => '0', + 'count' => '0' ), $wpdb->prefix.'terms' => array( - 'name' => '\'\'', - 'slug' => '\'\'', - 'term_group' => '0' + 'name' => '\'\'', + 'slug' => '\'\'', + 'term_group' => '0' ), $wpdb->prefix.'users' => array( - 'user_login' => '\'\'', - 'user_pass' => '\'\'', - 'user_nicename' => '\'\'', - 'user_email' => '\'\'', - 'user_url' => '\'\'', - 'user_registered' => '\'0000-00-00 00:00:00\'', - 'user_activation_key' => '\'\'', - 'user_status' => '\'0\'', - 'display_name' => '\'\'', - // for network install - 'spam' => '\'0\'', - 'deleted' => '\'0\'' + 'user_login' => '\'\'', + 'user_pass' => '\'\'', + 'user_nicename' => '\'\'', + 'user_email' => '\'\'', + 'user_url' => '\'\'', + 'user_registered' => '\'0000-00-00 00:00:00\'', + 'user_activation_key' => '\'\'', + 'user_status' => '\'0\'', + 'display_name' => '\'\'', + // for network install + 'spam' => '\'0\'', + 'deleted' => '\'0\'' ), $wpdb->prefix.'usermeta' => array( - 'user_id' => '\'0\'', - 'meta_key' => 'NULL', + 'user_id' => '\'0\'', + 'meta_key' => 'NULL', ), // for network install $wpdb->prefix.'blog_versions' => array( - 'blog_id' => '\'0\'', - 'db_version' => '\'\'', - 'last_updated' => '\'0000-00-00 00:00:00\'' + 'blog_id' => '\'0\'', + 'db_version' => '\'\'', + 'last_updated' => '\'0000-00-00 00:00:00\'' ), $wpdb->prefix.'blogs' => array( - 'site_id' => '\'0\'', - 'domain' => '\'\'', - 'path' => '\'\'', - 'registered' => '\'0000-00-00 00:00:00\'', - 'last_updated' => '\'0000-00-00 00:00:00\'', - 'public' => '\'1\'', - 'mature' => '\'0\'', - 'spam' => '\'0\'', - 'deleted' => '\'0\'', - 'lang_id' => '\'0\'' + 'site_id' => '\'0\'', + 'domain' => '\'\'', + 'path' => '\'\'', + 'registered' => '\'0000-00-00 00:00:00\'', + 'last_updated' => '\'0000-00-00 00:00:00\'', + 'public' => '\'1\'', + 'mature' => '\'0\'', + 'spam' => '\'0\'', + 'deleted' => '\'0\'', + 'lang_id' => '\'0\'' ), $wpdb->prefix.'registration_log' => array( - 'email' => '\'\'', - 'IP' => '\'\'', - 'blog_id' => '\'0\'', - 'date_registered' => '\'0000-00-00 00:00:00\'' + 'email' => '\'\'', + 'IP' => '\'\'', + 'blog_id' => '\'0\'', + 'date_registered' => '\'0000-00-00 00:00:00\'' ), $wpdb->prefix.'signups' => array( - 'domain' => '\'\'', - 'path' => '\'\'', - 'user_login' => '\'\'', - 'user_email' => '\'\'', - 'registered' => '\'0000-00-00 00:00:00\'', - 'activated' => '\'0000-00-00 00:00:00\'', - 'active' => '\'0\'', - 'activation_key' => '\'\'', + 'domain' => '\'\'', + 'path' => '\'\'', + 'user_login' => '\'\'', + 'user_email' => '\'\'', + 'registered' => '\'0000-00-00 00:00:00\'', + 'activated' => '\'0000-00-00 00:00:00\'', + 'active' => '\'0\'', + 'activation_key' => '\'\'', ), $wpdb->prefix.'site' => array( - 'domain' => '\'\'', - 'path' => '\'\'' + 'domain' => '\'\'', + 'path' => '\'\'' ), $wpdb->prefix.'sitemeta' => array( - 'site_id' => '\'0\'', - 'meta_key' => 'NULL', + 'site_id' => '\'0\'', + 'meta_key' => 'NULL', ) ); $tables = $wpdb->tables('all'); @@ -180,10 +180,10 @@ class DatabaseMaintenance { } /** * Method to do the fixing job to the broken tables. - * + * * If the job succeeded, it returns string of success message. * If failed, it returns the array of the failed query for debugging. - * + * * @return string|array of string * @access private */ @@ -191,148 +191,148 @@ class DatabaseMaintenance { global $wpdb, $wp_version, $utils; $global_schema_to_change = array( $wpdb->prefix.'commentmeta' => array( - "comment_id bigint(20) unsigned NOT NULL default '0'", - "meta_key varchar(255) default NULL", - "meta_value longtext" + "comment_id bigint(20) unsigned NOT NULL default '0'", + "meta_key varchar(255) default NULL", + "meta_value longtext" ), $wpdb->prefix.'comments' => array( - "comment_post_ID bigint(20) unsigned NOT NULL default '0'", - "comment_author_email varchar(100) NOT NULL default ''", - "comment_author_url varchar(200) NOT NULL default ''", - "comment_author_IP varchar(100) NOT NULL default ''", - "comment_date datetime NOT NULL default '0000-00-00 00:00:00'", - "comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00'", - "comment_karma int(11) NOT NULL default '0'", - "comment_approved varchar(20) NOT NULL default '1'", - "comment_agent varchar(255) NOT NULL default ''", - "comment_type varchar(20) NOT NULL default ''", - "comment_parent bigint(20) unsigned NOT NULL default '0'", - "user_id bigint(20) unsigned NOT NULL default '0'" + "comment_post_ID bigint(20) unsigned NOT NULL default '0'", + "comment_author_email varchar(100) NOT NULL default ''", + "comment_author_url varchar(200) NOT NULL default ''", + "comment_author_IP varchar(100) NOT NULL default ''", + "comment_date datetime NOT NULL default '0000-00-00 00:00:00'", + "comment_date_gmt datetime NOT NULL default '0000-00-00 00:00:00'", + "comment_karma int(11) NOT NULL default '0'", + "comment_approved varchar(20) NOT NULL default '1'", + "comment_agent varchar(255) NOT NULL default ''", + "comment_type varchar(20) NOT NULL default ''", + "comment_parent bigint(20) unsigned NOT NULL default '0'", + "user_id bigint(20) unsigned NOT NULL default '0'" ), $wpdb->prefix.'links' => array( - "link_url varchar(255) NOT NULL default ''", - "link_name varchar(255) NOT NULL default ''", - "link_image varchar(255) NOT NULL default ''", - "link_target varchar(25) NOT NULL default ''", - "link_description varchar(255) NOT NULL default ''", - "link_visible varchar(20) NOT NULL default 'Y'", - "link_owner bigint(20) unsigned NOT NULL default '1'", - "link_rating int(11) NOT NULL default '0'", - "link_updated datetime NOT NULL default '0000-00-00 00:00:00'", - "link_rel varchar(255) NOT NULL default ''", - "link_notes mediumtext NOT NULL", - "link_rss varchar(255) NOT NULL default ''" + "link_url varchar(255) NOT NULL default ''", + "link_name varchar(255) NOT NULL default ''", + "link_image varchar(255) NOT NULL default ''", + "link_target varchar(25) NOT NULL default ''", + "link_description varchar(255) NOT NULL default ''", + "link_visible varchar(20) NOT NULL default 'Y'", + "link_owner bigint(20) unsigned NOT NULL default '1'", + "link_rating int(11) NOT NULL default '0'", + "link_updated datetime NOT NULL default '0000-00-00 00:00:00'", + "link_rel varchar(255) NOT NULL default ''", + "link_notes mediumtext NOT NULL", + "link_rss varchar(255) NOT NULL default ''" ), $wpdb->prefix.'options' => array( - "option_name varchar(64) NOT NULL default ''", - "option_value longtext NOT NULL", - "autoload varchar(20) NOT NULL default 'yes'" + "option_name varchar(64) NOT NULL default ''", + "option_value longtext NOT NULL", + "autoload varchar(20) NOT NULL default 'yes'" ), $wpdb->prefix.'postmeta' => array( - "post_id bigint(20) unsigned NOT NULL default '0'", - "meta_key varchar(255) default NULL", - "meta_value longtext" + "post_id bigint(20) unsigned NOT NULL default '0'", + "meta_key varchar(255) default NULL", + "meta_value longtext" ), $wpdb->prefix.'posts' => array( - "post_author bigint(20) unsigned NOT NULL default '0'", - "post_date datetime NOT NULL default '0000-00-00 00:00:00'", - "post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00'", - "post_status varchar(20) NOT NULL default 'publish'", - "comment_status varchar(20) NOT NULL default 'open'", - "ping_status varchar(20) NOT NULL default 'open'", - "post_password varchar(20) NOT NULL default ''", - "post_name varchar(200) NOT NULL default ''", - "post_modified datetime NOT NULL default '0000-00-00 00:00:00'", - "post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00'", - "post_content_filtered longtext NOT NULL", - "post_parent bigint(20) unsigned NOT NULL default '0'", - "guid varchar(255) NOT NULL default ''", - "menu_order int(11) NOT NULL default '0'", - "post_type varchar(20) NOT NULL default 'post'", - "post_mime_type varchar(100) NOT NULL default ''", - "comment_count bigint(20) NOT NULL default '0'" + "post_author bigint(20) unsigned NOT NULL default '0'", + "post_date datetime NOT NULL default '0000-00-00 00:00:00'", + "post_date_gmt datetime NOT NULL default '0000-00-00 00:00:00'", + "post_status varchar(20) NOT NULL default 'publish'", + "comment_status varchar(20) NOT NULL default 'open'", + "ping_status varchar(20) NOT NULL default 'open'", + "post_password varchar(20) NOT NULL default ''", + "post_name varchar(200) NOT NULL default ''", + "post_modified datetime NOT NULL default '0000-00-00 00:00:00'", + "post_modified_gmt datetime NOT NULL default '0000-00-00 00:00:00'", + "post_content_filtered longtext NOT NULL", + "post_parent bigint(20) unsigned NOT NULL default '0'", + "guid varchar(255) NOT NULL default ''", + "menu_order int(11) NOT NULL default '0'", + "post_type varchar(20) NOT NULL default 'post'", + "post_mime_type varchar(100) NOT NULL default ''", + "comment_count bigint(20) NOT NULL default '0'" ), $wpdb->prefix.'term_relationships' => array( - "term_order int(11) NOT NULL default 0" + "term_order int(11) NOT NULL default 0" ), $wpdb->prefix.'term_taxonomy' => array( - "taxonomy varchar(32) NOT NULL default ''", - "description longtext NOT NULL", - "parent bigint(20) unsigned NOT NULL default 0", - "count bigint(20) NOT NULL default 0" + "taxonomy varchar(32) NOT NULL default ''", + "description longtext NOT NULL", + "parent bigint(20) unsigned NOT NULL default 0", + "count bigint(20) NOT NULL default 0" ), $wpdb->prefix.'terms' => array( - "name varchar(200) NOT NULL default ''", - "slug varchar(200) NOT NULL default ''", - "term_group bigint(10) NOT NULL default 0" + "name varchar(200) NOT NULL default ''", + "slug varchar(200) NOT NULL default ''", + "term_group bigint(10) NOT NULL default 0" ), $wpdb->prefix.'users' => array( - "user_login varchar(60) NOT NULL default ''", - "user_pass varchar(64) NOT NULL default ''", - "user_nicename varchar(50) NOT NULL default ''", - "user_email varchar(100) NOT NULL default ''", - "user_url varchar(100) NOT NULL default ''", - "user_registered datetime NOT NULL default '0000-00-00 00:00:00'", - "user_activation_key varchar(60) NOT NULL default ''", - "user_status int(11) NOT NULL default '0'", - "display_name varchar(250) NOT NULL default ''" + "user_login varchar(60) NOT NULL default ''", + "user_pass varchar(64) NOT NULL default ''", + "user_nicename varchar(50) NOT NULL default ''", + "user_email varchar(100) NOT NULL default ''", + "user_url varchar(100) NOT NULL default ''", + "user_registered datetime NOT NULL default '0000-00-00 00:00:00'", + "user_activation_key varchar(60) NOT NULL default ''", + "user_status int(11) NOT NULL default '0'", + "display_name varchar(250) NOT NULL default ''" ), $wpdb->prefix.'usermeta' => array( - "user_id bigint(20) unsigned NOT NULL default '0'", - "meta_key varchar(255) default NULL", - "meta_value longtext" + "user_id bigint(20) unsigned NOT NULL default '0'", + "meta_key varchar(255) default NULL", + "meta_value longtext" ) ); $network_schema_to_change = array( $wpdb->prefix.'blog_versions' => array( - "blog_id bigint(20) NOT NULL default '0'", - "db_version varchar(20) NOT NULL default ''", - "last_updated datetime NOT NULL default '0000-00-00 00:00:00'" + "blog_id bigint(20) NOT NULL default '0'", + "db_version varchar(20) NOT NULL default ''", + "last_updated datetime NOT NULL default '0000-00-00 00:00:00'" ), $wpdb->prefix.'blogs' => array( - "site_id bigint(20) NOT NULL default '0'", - "domain varchar(200) NOT NULL default ''", - "path varchar(100) NOT NULL default ''", - "registered datetime NOT NULL default '0000-00-00 00:00:00'", - "last_updated datetime NOT NULL default '0000-00-00 00:00:00'", - "public tinyint(2) NOT NULL default '1'", - "mature tinyint(2) NOT NULL default '0'", - "spam tinyint(2) NOT NULL default '0'", - "deleted tinyint(2) NOT NULL default '0'", - "lang_id int(11) NOT NULL default '0'" + "site_id bigint(20) NOT NULL default '0'", + "domain varchar(200) NOT NULL default ''", + "path varchar(100) NOT NULL default ''", + "registered datetime NOT NULL default '0000-00-00 00:00:00'", + "last_updated datetime NOT NULL default '0000-00-00 00:00:00'", + "public tinyint(2) NOT NULL default '1'", + "mature tinyint(2) NOT NULL default '0'", + "spam tinyint(2) NOT NULL default '0'", + "deleted tinyint(2) NOT NULL default '0'", + "lang_id int(11) NOT NULL default '0'" ), $wpdb->prefix.'registration_log' => array( - "email varchar(255) NOT NULL default ''", - "IP varchar(30) NOT NULL default ''", - "blog_id bigint(20) NOT NULL default '0'", - "date_registered datetime NOT NULL default '0000-00-00 00:00:00'" + "email varchar(255) NOT NULL default ''", + "IP varchar(30) NOT NULL default ''", + "blog_id bigint(20) NOT NULL default '0'", + "date_registered datetime NOT NULL default '0000-00-00 00:00:00'" ), $wpdb->prefix.'signups' => array( - "domain varchar(200) NOT NULL default ''", - "path varchar(100) NOT NULL default ''", - "title longtext NOT NULL", - "user_login varchar(60) NOT NULL default ''", - "user_email varchar(100) NOT NULL default ''", - "registered datetime NOT NULL default '0000-00-00 00:00:00'", - "activated datetime NOT NULL default '0000-00-00 00:00:00'", - "active tinyint(1) NOT NULL default '0'", - "activation_key varchar(50) NOT NULL default ''", - "meta longtext" + "domain varchar(200) NOT NULL default ''", + "path varchar(100) NOT NULL default ''", + "title longtext NOT NULL", + "user_login varchar(60) NOT NULL default ''", + "user_email varchar(100) NOT NULL default ''", + "registered datetime NOT NULL default '0000-00-00 00:00:00'", + "activated datetime NOT NULL default '0000-00-00 00:00:00'", + "active tinyint(1) NOT NULL default '0'", + "activation_key varchar(50) NOT NULL default ''", + "meta longtext" ), $wpdb->prefix.'site' => array( - "domain varchar(200) NOT NULL default ''", - "path varchar(100) NOT NULL default ''" + "domain varchar(200) NOT NULL default ''", + "path varchar(100) NOT NULL default ''" ), $wpdb->prefix.'sitemeta' => array( - "site_id bigint(20) NOT NULL default '0'", - "meta_key varchar(255) default NULL", - "meta_value longtext" + "site_id bigint(20) NOT NULL default '0'", + "meta_key varchar(255) default NULL", + "meta_value longtext" ), $wpdb->prefix.'users' => array( - "user_login varchar(60) NOT NULL default ''", - "spam tinyint(2) NOT NULL default '0'", - "deleted tinyint(2) NOT NULL default '0'" + "user_login varchar(60) NOT NULL default ''", + "spam tinyint(2) NOT NULL default '0'", + "deleted tinyint(2) NOT NULL default '0'" ) ); if (version_compare($wp_version, '3.6', '<')) return false; @@ -377,10 +377,10 @@ class DatabaseMaintenance { } /** * Method to return the result of SHOW COLUMNS query. - * + * * It returns the result of SHOW COLUMNS query as an object if the table exists. * It returns the error message if the table doesn't exist. - * + * * @return string|object */ private function show_columns() { @@ -401,9 +401,9 @@ class DatabaseMaintenance { } /** * Method to create a back up file of the database. - * + * * It returns true if success, false if failure. - * + * * @return boolean */ private function maintenance_backup() { @@ -437,7 +437,7 @@ class DatabaseMaintenance { } /** * Method to display the maintenance page on the admin panel. - * + * */ function show_maintenance_page() { global $utils, $wpdb; @@ -447,133 +447,133 @@ class DatabaseMaintenance { } elseif (!current_user_can('manage_options')) { die(__('You are not allowed to access this page!', $domain)); } - if (isset($_GET['page']) && $_GET['page'] == 'maintenance') : ?> - -
    -

    -

    -

    - - -

    -

    - -

    -

    - -

    -

    - -

    - -
    - - - -
    - - -

    -

    - -

    + if (isset($_GET['page']) && $_GET['page'] == 'maintenance') : ?> + +
    +

    +

    +

    + + +

    +

    + +

    +

    + +

    +

    + +

    + +
    + + + +
    + + +

    +

    + +

    tables('all'); ?> -
    - - - - -
    - - -
    - do_fix_database(); - if (is_array($fix_results)) { +
    + + + + +
    + + +
    + do_fix_database(); + if (is_array($fix_results)) { $title = '

    '. __('Results', $domain) . '

    '; echo '
    '; echo $title; echo '
      '; - foreach ($fix_results as $result) { - echo '
    • ' . $result . '
    • '; - } - echo '
    '; - echo '
    '; - } else { + foreach ($fix_results as $result) { + echo '
  1. ' . $result . '
  2. '; + } + echo ''; + echo '
'; + } else { $title = '

'. __('Results', $domain) . '

'; echo '
'; echo $title; echo '

'.$fix_results.'

'; echo '
'; } - } - if (isset($_POST['sanity-check'])) { - check_admin_referer('sqliteintegration-database-manip-stats'); - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } - $check_results = $this->sanity_check(); - if ($check_results !== true) { + } + if (isset($_POST['sanity-check'])) { + check_admin_referer('sqliteintegration-database-manip-stats'); + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } + $check_results = $this->sanity_check(); + if ($check_results !== true) { $title = '

'. __('Checked Results', $domain) . '

'; echo '
'; echo $title; echo ''; - echo '
'; - } else { + foreach ($check_results as $table => $damaged) { + $message = __(' needs restoring.', $domain); + echo '
  • ' . $table . '' . $message . '
  • '; + } + echo ''; + echo ''; + } else { $title = '

    '. __('Checked Results', $domain) . '

    '; - $message = __('Your database is OK. You don\'t have to restore it.', $domain); + $message = __('Your database is OK. You don\'t have to restore it.', $domain); echo '
    '; - echo $title; + echo $title; echo '

    '.$message.'

    '; - echo '
    '; - } - } - if (isset($_POST['show-columns'])) { + echo ''; + } + } + if (isset($_POST['show-columns'])) { check_admin_referer('sqliteintegration-database-manip-stats'); - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } - $results = $this->show_columns(); - if (is_array($results)) { + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } + $results = $this->show_columns(); + if (is_array($results)) { $title = '

    '. sprintf(__('Columns In %s', $domain), $_POST['table']) . '

    '; $column_header = __('Column', $domain); $type_header = __('Type', $domain); diff --git a/utilities/documentation.php b/utilities/documentation.php index 18343da..56ede19 100644 --- a/utilities/documentation.php +++ b/utilities/documentation.php @@ -1,151 +1,151 @@ text_domain; - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to access this page!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to access this page!', $domain)); - } - if (isset($_GET['page']) && $_GET['page'] == 'doc') :?> - -
    -

    -

    - SQLite Integration page.', $domain);?> -

    -

    - -

    - -

    -

    - PDO for WordPress, which enabled WordPress to use SQLite for its database. But PDO for WordPress doesn\'t seem to be maintained any more only to be outdated. SQLite Integration makes use of the basic ideas and framework of PDO for WordPress, adds some new features and updates it to be able to work with the newest version of WordPress(3.8.1).', $domain); ?> -

    -

    - SQLite Web Page says — SQLite is a "software library that implements selfcontained, serverless, zero-configuration, transactional SQL database engine". It is "a good choice for small to medium size websites". It\'s small and portable, and you don\'t need any database server system.', $domain); ?> -

    -

    - -

    -

    - -

    -
      -
    1. -
    2. -
    3. -
    4. -
    5. -
    6. -
    -

    - -

    - -

    -

    - -

    -
      -
    1. ', $domain);?> -
    2. -
    3. ', $domain);?> - Patch Utility. See also the SQLite Integration Page for more details.', $domain), $utils->show_parent());?>
    4. -
    -

    - Support Forum.', $domain);?> -

    -

    -

    - -

    -

    - -

    - -

    -

    - -

    - -

    - -

    -
    + function show_doc() { + // textdomain is defined in the utils class + global $utils; + $domain = $utils->text_domain; + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to access this page!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to access this page!', $domain)); + } + if (isset($_GET['page']) && $_GET['page'] == 'doc') :?> + +
    +

    +

    + SQLite Integration page.', $domain);?> +

    +

    + +

    - -
    -

    -

    - -

    -

    - System Info page. To see more details, please visit the Plugin Page.', $domain), $utils->show_parent());?> -

    - - - - - - - - - - - - - compat, array('No', 'Probably No', 'Needs Patch'))) :?> - - - compat, 'patch') !== false) :?> - - compat, 'probably no')) :?> - - - - - - - - - - -
    name;?>reason;?>
    -
    - +

    + PDO for WordPress, which enabled WordPress to use SQLite for its database. But PDO for WordPress doesn\'t seem to be maintained any more only to be outdated. SQLite Integration makes use of the basic ideas and framework of PDO for WordPress, adds some new features and updates it to be able to work with the newest version of WordPress(3.8.1).', $domain); ?> +

    +

    + SQLite Web Page says — SQLite is a "software library that implements selfcontained, serverless, zero-configuration, transactional SQL database engine". It is "a good choice for small to medium size websites". It\'s small and portable, and you don\'t need any database server system.', $domain); ?> +

    +

    + +

    +

    + +

    +
      +
    1. +
    2. +
    3. +
    4. +
    5. +
    6. +
    +

    + +

    + +

    +

    + +

    +
      +
    1. ', $domain);?> +
    2. +
    3. ', $domain);?> + Patch Utility. See also the SQLite Integration Page for more details.', $domain), $utils->show_parent());?>
    4. +
    +

    + Support Forum.', $domain);?> +

    +

    +

    + +

    +

    + +

    + +

    +

    + +

    + +

    + +

    +
    + + +
    +

    +

    + +

    +

    + System Info page. To see more details, please visit the Plugin Page.', $domain), $utils->show_parent());?> +

    + + + + + + + + + + + + + compat, array('No', 'Probably No', 'Needs Patch'))) :?> + + + compat, 'patch') !== false) :?> + + compat, 'probably no')) :?> + + + + + + + + + + +
    name;?>reason;?>
    +
    + \ No newline at end of file diff --git a/utilities/patch.php b/utilities/patch.php index a5482b4..c244f92 100644 --- a/utilities/patch.php +++ b/utilities/patch.php @@ -1,421 +1,421 @@ text_domain; - $installed_plugins = array(); - $file_names = array(); - $output = array(); - $retval = 0; - $patch_results = array(); - $message = ''; - if (isset($_POST['plugin_checked'])) { - $file_names = $_POST['plugin_checked']; - } else { - return false; - } - if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { - exec('where patch 2>&1', $out, $val); - } else { - exec('which patch 2>&1', $out, $val); - } - if ($val != 0) { - $patch_results['error'] = __('Patch command is not found', $domain); - return $patch_results; - } elseif (!is_executable(trim($out[0]))) { - $patch_results['error'] = __('Patch command is not executable', $domain); - return $patch_results; - } else { - $patch_command = trim($out[0]) . ' -s -N -p1'; - } - $installed_plugins = get_plugins(); - foreach ($file_names as $file) { - if (preg_match('/_(.*)\.patch/i', $file, $match)) { - $plugin_version = trim($match[1]); - $plugin_basename = preg_replace('/_.*\.patch$/i', '', $file); - foreach (array_keys($installed_plugins) as $key) { - if (stripos($key, $plugin_basename) !== false) { - $installed_plugin_version = $installed_plugins[$key]['Version']; - break; - } - } - } else { - $patch_results['error'] = __('Patch file name is invalid', $domain); - break; - } - if (version_compare($installed_plugin_version, $plugin_version, '!=')) { - $patch_results['error'] = __('Patch file version does not match with that of your plugin.', $domain); - break; - } - $plugin_dir = WP_PLUGIN_DIR.'/'.$plugin_basename; - $patch_file = SQLitePatchDir.'/'.$file; - $command = $patch_command.' <'.$patch_file.' 2>&1'; - if (chdir($plugin_dir)) { - exec("$command", $output, $retval); - } else { - $patch_results[$file] = __('Error! Plugin directory is not accessible.', $domain); - } - if ($retval == 0) { - $patch_results[$file] = __('is patched successfully.', $domain); - } else { - foreach ($output as $val) { - $message .= $val.'
    '; - } - $patch_results[$file] = sprintf(__('Error! Messages: %s', $domain), $message); - } - } - return $patch_results; - } - /** - * Method to remove patch file(s) from the server. - * - * It deletes uploaded patch file(s). - * If patch file(s) is not selected, returns false. - * Or else returns array contains messages. - * - * @return boolean|array - * @access private - */ - private function delete_patch_files() { - global $utils; - $domain = $utils->text_domain; - $file_names = array(); - $rm_results = array(); - if (isset($_POST['plugin_checked'])) { - $file_names = $_POST['plugin_checked']; - } else { - return false; - } - if (chdir(SQLitePatchDir)) { - foreach ($file_names as $file) { - if (unlink($file)) { - $rm_results[$file] = sprintf(__('File %s is deleted.', $domain), $file); - } else { - $rm_results[$file] = sprintf(__('Error! File %s is not deleted.', $domain), $file); - } - } - } else { - $rm_results[$file] = __('Error!: patches directory is not accessible.', $domain); - } - return $rm_results; - } - /** - * Method to upload patch file(s) to the server. - * - * It uploads a patch file to the server. You must have the permission to write to the - * temporary directory. If there isn't SQLitePatchDir, this method will create it and - * set the permission to 0707. - * - * No return values. - * - * @return boolean - * @access private - */ - private function upload_file() { - global $utils; - $domain = $utils->text_domain; - if (!file_exists(SQLitePatchDir) || !is_dir(SQLitePatchDir)) { - if (!mkdir(SQLitePatchDir, 0707, true)) { - $message = __('Unable to create a patch directory.', $domain); - echo '
    '.$message.'
    '; - return false; - } - } - if (!is_file(SQLitePatchDir . '/.htaccess')) { - $fp = fopen(SQLitePatchDir . '/.htaccess', 'w'); - if (!$fp) { - $message = __('Unable to create a .htaccess file.', $domain); - echo '
    '.$message.'
    '; - return false; - } - fwrite($fp, 'DENY FROM ALL'); - fclose($fp); - } - if (!isset($_FILES['upfile']['error']) || !is_int($_FILES['upfile']['error'])) { - $message = __('Invalid operation.', $domain); - echo '
    '.$message.'
    '; - return false; - } elseif ($_FILES['upfile']['error'] != UPLOAD_ERR_OK) { - switch ($_FILES['upfile']['error']) { - case UPLOAD_ERR_FORM_SIZE: - $message = __('File is too large to upload.', $domain); - echo '
    '.$message.'
    '; - break; - case UPLOAD_ERR_PARTIAL: - $message = __('File upload is not complete.', $domain); - echo '
    '.$message.'
    '; - break; - case UPLOAD_ERR_NO_FILE: - $message = __('File is not uploaded.', $domain); - echo '
    '.$message.'
    '; - break; - case UPLOAD_ERR_NO_TMP_DIR: - $message = __('Temporary directory is not writable.', $domain); - echo '
    '.$message.'
    '; - break; - case UPLOAD_ERR_CANT_WRITE: - $message = __('File cannot be written on the disk.', $domain); - echo '
    '.$message.'
    '; - break; - default: - $message = __('Unknown error.', $domain); - break; - } - return false; - } - if (is_uploaded_file($_FILES['upfile']['tmp_name'])) { - $file_full_path = SQLitePatchDir . '/' . $_FILES['upfile']['name']; - if (move_uploaded_file($_FILES['upfile']['tmp_name'], $file_full_path)) { - $message = __('File is successfully uploaded.', $domain); - echo '
    '.$message.'
    '; - chmod(SQLitePatchDir.'/'.$_FILES['upfile']['name'], 0606); - } else { - $message = __('File upload failed. Possible file upload attack.', $domain); - echo '
    '.$message.'
    '; - return false; - } - } else { - $message = __('File is not selected', $domain); - echo '
    '.$message.'
    '; - return false; - } - return true; - } - /** - * Method to display the patch utility page on the admin panel. - * - */ - function show_patch_page() { - global $utils; - $domain = $utils->text_domain; - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to access this page!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to access this page!', $domain)); - } - if (isset($_POST['apply_patch'])) { - check_admin_referer('sqlitewordpress-plugin-manip-stats'); - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } - $result = $this->apply_patches(); - if ($result === false) { - $message = __('Please select patch file(s)', $domain); - echo '
    '.$message.'
    '; - } elseif (is_array($result) && count($result) > 0) { - echo '
    '; - foreach ($result as $key => $val) { - echo $key.' => '.$val.'
    '; - } - echo '
    '; - } else { - $message = __('None of the patches is applied!'); - echo '
    '.$message.'
    '; - } - } - if (isset($_POST['patch_file_delete'])) { - check_admin_referer('sqlitewordpress-plugin-manip-stats'); - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } - $result = $this->delete_patch_files(); - if ($result === false) { - $message = __('Please select patch file(s)', $domain); - echo '
    '.$message.'
    '; - } elseif (is_array($result) && count($result) > 0) { - echo '
    '; - foreach ($result as $key => $val) { - echo $key.' => '.$val.'
    '; - } - echo '
    '; - } else { - $message = __('Error! Please remove files manually', $domain); - echo '
    '.$message.'
    '; - } - } - if (isset($_POST['upload'])) { - check_admin_referer('sqlitewordpress-plugin-patch-file-stats'); - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to do this operation!', $domain)); - } - $result = $this->upload_file(); - } - if (isset($_GET['page']) && $_GET['page'] == 'patch') : ?> - -
    -

    -

    -

    - Plugin Page about how to apply a patch file to the plugin. But the command line interface sometimes embarrasses some people, especially newbies.', $domain);?> -

    -

    - -

    -
      -
    1. Plugin Directory for the substitutes?', $domain)?>
    2. -
    3. -
    4. -
    5. -
    -

    - -

    -

    - -

    -
      -
    1. -
    2. -
    3. -
    4. -
    -

    - -

    - -

    -
      -
    1. -
    2. -
    3. -
    -

    -

    - -

    -
      -
    1. -
    2. -
    3. -
    4. -
    -

    -

    - - - - - - - - - - - -
    -
    - - -
    - - -
    -
    -
    - - - - - - - - - - - get_patch_files(); - if (!empty($files)) : ?> - - - - - - - - -
    -

    - - -

    -
    -
    -
    - -
    -
    - -
    -
    -

    - -

    -
    -
    - text_domain; + $installed_plugins = array(); + $file_names = array(); + $output = array(); + $retval = 0; + $patch_results = array(); + $message = ''; + if (isset($_POST['plugin_checked'])) { + $file_names = $_POST['plugin_checked']; + } else { + return false; + } + if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { + exec('where patch 2>&1', $out, $val); + } else { + exec('which patch 2>&1', $out, $val); + } + if ($val != 0) { + $patch_results['error'] = __('Patch command is not found', $domain); + return $patch_results; + } elseif (!is_executable(trim($out[0]))) { + $patch_results['error'] = __('Patch command is not executable', $domain); + return $patch_results; + } else { + $patch_command = trim($out[0]) . ' -s -N -p1'; + } + $installed_plugins = get_plugins(); + foreach ($file_names as $file) { + if (preg_match('/_(.*)\.patch/i', $file, $match)) { + $plugin_version = trim($match[1]); + $plugin_basename = preg_replace('/_.*\.patch$/i', '', $file); + foreach (array_keys($installed_plugins) as $key) { + if (stripos($key, $plugin_basename) !== false) { + $installed_plugin_version = $installed_plugins[$key]['Version']; + break; + } + } + } else { + $patch_results['error'] = __('Patch file name is invalid', $domain); + break; + } + if (version_compare($installed_plugin_version, $plugin_version, '!=')) { + $patch_results['error'] = __('Patch file version does not match with that of your plugin.', $domain); + break; + } + $plugin_dir = WP_PLUGIN_DIR.'/'.$plugin_basename; + $patch_file = SQLitePatchDir.'/'.$file; + $command = $patch_command.' <'.$patch_file.' 2>&1'; + if (chdir($plugin_dir)) { + exec("$command", $output, $retval); + } else { + $patch_results[$file] = __('Error! Plugin directory is not accessible.', $domain); + } + if ($retval == 0) { + $patch_results[$file] = __('is patched successfully.', $domain); + } else { + foreach ($output as $val) { + $message .= $val.'
    '; + } + $patch_results[$file] = sprintf(__('Error! Messages: %s', $domain), $message); + } + } + return $patch_results; + } + /** + * Method to remove patch file(s) from the server. + * + * It deletes uploaded patch file(s). + * If patch file(s) is not selected, returns false. + * Or else returns array contains messages. + * + * @return boolean|array + * @access private + */ + private function delete_patch_files() { + global $utils; + $domain = $utils->text_domain; + $file_names = array(); + $rm_results = array(); + if (isset($_POST['plugin_checked'])) { + $file_names = $_POST['plugin_checked']; + } else { + return false; + } + if (chdir(SQLitePatchDir)) { + foreach ($file_names as $file) { + if (unlink($file)) { + $rm_results[$file] = sprintf(__('File %s is deleted.', $domain), $file); + } else { + $rm_results[$file] = sprintf(__('Error! File %s is not deleted.', $domain), $file); + } + } + } else { + $rm_results[$file] = __('Error!: patches directory is not accessible.', $domain); + } + return $rm_results; + } + /** + * Method to upload patch file(s) to the server. + * + * It uploads a patch file to the server. You must have the permission to write to the + * temporary directory. If there isn't SQLitePatchDir, this method will create it and + * set the permission to 0707. + * + * No return values. + * + * @return boolean + * @access private + */ + private function upload_file() { + global $utils; + $domain = $utils->text_domain; + if (!file_exists(SQLitePatchDir) || !is_dir(SQLitePatchDir)) { + if (!mkdir(SQLitePatchDir, 0707, true)) { + $message = __('Unable to create a patch directory.', $domain); + echo '
    '.$message.'
    '; + return false; + } + } + if (!is_file(SQLitePatchDir . '/.htaccess')) { + $fp = fopen(SQLitePatchDir . '/.htaccess', 'w'); + if (!$fp) { + $message = __('Unable to create a .htaccess file.', $domain); + echo '
    '.$message.'
    '; + return false; + } + fwrite($fp, 'DENY FROM ALL'); + fclose($fp); + } + if (!isset($_FILES['upfile']['error']) || !is_int($_FILES['upfile']['error'])) { + $message = __('Invalid operation.', $domain); + echo '
    '.$message.'
    '; + return false; + } elseif ($_FILES['upfile']['error'] != UPLOAD_ERR_OK) { + switch ($_FILES['upfile']['error']) { + case UPLOAD_ERR_FORM_SIZE: + $message = __('File is too large to upload.', $domain); + echo '
    '.$message.'
    '; + break; + case UPLOAD_ERR_PARTIAL: + $message = __('File upload is not complete.', $domain); + echo '
    '.$message.'
    '; + break; + case UPLOAD_ERR_NO_FILE: + $message = __('File is not uploaded.', $domain); + echo '
    '.$message.'
    '; + break; + case UPLOAD_ERR_NO_TMP_DIR: + $message = __('Temporary directory is not writable.', $domain); + echo '
    '.$message.'
    '; + break; + case UPLOAD_ERR_CANT_WRITE: + $message = __('File cannot be written on the disk.', $domain); + echo '
    '.$message.'
    '; + break; + default: + $message = __('Unknown error.', $domain); + break; + } + return false; + } + if (is_uploaded_file($_FILES['upfile']['tmp_name'])) { + $file_full_path = SQLitePatchDir . '/' . $_FILES['upfile']['name']; + if (move_uploaded_file($_FILES['upfile']['tmp_name'], $file_full_path)) { + $message = __('File is successfully uploaded.', $domain); + echo '
    '.$message.'
    '; + chmod(SQLitePatchDir.'/'.$_FILES['upfile']['name'], 0606); + } else { + $message = __('File upload failed. Possible file upload attack.', $domain); + echo '
    '.$message.'
    '; + return false; + } + } else { + $message = __('File is not selected', $domain); + echo '
    '.$message.'
    '; + return false; + } + return true; + } + /** + * Method to display the patch utility page on the admin panel. + * + */ + function show_patch_page() { + global $utils; + $domain = $utils->text_domain; + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to access this page!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to access this page!', $domain)); + } + if (isset($_POST['apply_patch'])) { + check_admin_referer('sqlitewordpress-plugin-manip-stats'); + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } + $result = $this->apply_patches(); + if ($result === false) { + $message = __('Please select patch file(s)', $domain); + echo '
    '.$message.'
    '; + } elseif (is_array($result) && count($result) > 0) { + echo '
    '; + foreach ($result as $key => $val) { + echo $key.' => '.$val.'
    '; + } + echo '
    '; + } else { + $message = __('None of the patches is applied!'); + echo '
    '.$message.'
    '; + } + } + if (isset($_POST['patch_file_delete'])) { + check_admin_referer('sqlitewordpress-plugin-manip-stats'); + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } + $result = $this->delete_patch_files(); + if ($result === false) { + $message = __('Please select patch file(s)', $domain); + echo '
    '.$message.'
    '; + } elseif (is_array($result) && count($result) > 0) { + echo '
    '; + foreach ($result as $key => $val) { + echo $key.' => '.$val.'
    '; + } + echo '
    '; + } else { + $message = __('Error! Please remove files manually', $domain); + echo '
    '.$message.'
    '; + } + } + if (isset($_POST['upload'])) { + check_admin_referer('sqlitewordpress-plugin-patch-file-stats'); + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to do this operation!', $domain)); + } + $result = $this->upload_file(); + } + if (isset($_GET['page']) && $_GET['page'] == 'patch') : ?> + +
    +

    +

    +

    + Plugin Page about how to apply a patch file to the plugin. But the command line interface sometimes embarrasses some people, especially newbies.', $domain);?> +

    +

    + +

    +
      +
    1. Plugin Directory for the substitutes?', $domain)?>
    2. +
    3. +
    4. +
    5. +
    +

    + +

    +

    + +

    +
      +
    1. +
    2. +
    3. +
    4. +
    +

    + +

    + +

    +
      +
    1. +
    2. +
    3. +
    +

    +

    + +

    +
      +
    1. +
    2. +
    3. +
    4. +
    +

    +

    + + + + + + + + + + + +
    +
    + + +
    + + +
    +
    +
    + + + + + + + + + + + get_patch_files(); + if (!empty($files)) : ?> + + + + + + + + +
    +

    + + +

    +
    +
    +
    + +
    +
    + +
    +
    +

    + +

    +
    +
    + \ No newline at end of file diff --git a/utilities/utility.php b/utilities/utility.php index dd08322..cd08306 100644 --- a/utilities/utility.php +++ b/utilities/utility.php @@ -1,887 +1,887 @@ > SQLite Integration >> Miscellaneous, and click the button "update" at the bottom of the page. Or else replace wp-content/db.php with the one in sqlite-integration directory manually.', 'sqlite-integration'); - $current_version = defined('SQLITE_INTEGRATION_VERSION') ? SQLITE_INTEGRATION_VERSION : ''; - if (version_compare($current_version, '1.6.2', '=')) return; - $version = ''; - if (defined('WP_CONTENT_DIR')) { - $path = WP_CONTENT_DIR . '/db.php'; - } else { - $path = ABSPATH . 'wp-content/db.php'; - } - if (!$file_handle = @fopen($path, 'r')) return; - while (($buffer = fgets($file_handle)) !== false) { - if (stripos($buffer, '@version') !== false) { - $version = str_ireplace('*@version ', '', $buffer); - $version = trim($version); - break; - } - } - fclose($file_handle); - if (empty($version) || version_compare($version, $current_version, '<')) { - echo '
    '.$notice_string.'
    '; - } - } - /** - * Method to read a error log file and returns its contents. - * - * 'FQDBDIR/debug.txt' is the log file name. - * If this file is not existent, returns false. - * - * @return string|boolean - * @access private - */ - private function show_error_log() { - $file = FQDBDIR . 'debug.txt'; - if (file_exists($file)) { - $contents = file_get_contents($file); - return $contents; - } else { - return false; - } - } - /** - * Method to clear the contents of the error log file. - * - * @return boolean - * @access private - */ - private function clear_log_file() { - $result = false; - $file = FQDBDIR . 'debug.txt'; - $fh = fopen($file, "w+"); - if ($fh) { - if (flock($fh, LOCK_EX)) { - if (ftruncate($fh, 0) === false) { - return false; - } - flock($fh, LOCK_UN); - } else { - return false; - } - } - fclose($fh); - return true; - } - - /** - * Method to get system information from the server and returns its data. - * - * Returned value is an associative array of system informations. - * - * sys_info['WordPress'] => WordPress Version - * sys_info['PHP'] => PHP Version - * - * - * @return array - * @access private - */ - private function get_system_info() { - global $wp_version; - $sys_info = array(); - $sys_info['WordPress'] = $wp_version; - $sys_info['PHP'] = PHP_VERSION; - return $sys_info; - } - /** - * Method to get database information from the database and returns its data. - * - * Returned value is an associative array. - * - * @return array - * @access private - */ - private function get_database_status() { - global $wpdb; - $status = array(); - $db_size = $this->get_database_size(); - $encoding = $wpdb->get_var("PRAGMA encoding"); - $integrity = $wpdb->get_var("PRAGMA integrity_check"); - $page_size = $wpdb->get_var("PRAGMA page_size"); - $page_count = $wpdb->get_var("PRAGMA page_count"); - $unused_page = $wpdb->get_var("PRAGMA freelist_count"); - $collation_list = $wpdb->get_results("PRAGMA collation_list"); - $compile_options = $wpdb->get_results("PRAGMA compile_options"); - foreach ($collation_list as $col) { - $collations[] = $col->name; - } - foreach ($compile_options as $opt) { - $options[] = $opt->compile_option; - } - $status['size'] = $db_size; - $status['integrity'] = $integrity; - $status['pagesize'] = $page_size; - $status['page'] = $page_count; - $status['unused'] = $unused_page; - $status['encoding'] = $encoding; - $status['collations'] = $collations; - $status['options'] = $options; - return $status; - } - /** - * Method to get table information and returns its data. - * - * Returned value is an associative array like: - * - * array( table name => array( index name ( column name ))) - * - * for each table in the database - * - * @return array - * @access private - */ - private function get_tables_info() { - global $wpdb; - $table_info = array(); - $tables = $wpdb->get_col("SHOW TABLES"); - foreach ($tables as $table) { - $index_object = $wpdb->get_results("SHOW INDEX FROM $table"); - if (empty($index_object)) { - $table_info[$table][] = 'no index'; - } else { - foreach ($index_object as $index) { - $table_info[$table][] = $index->Key_name . ' ( ' . $index->Column_name . ' )'; - } - } - } - $table_info = array_reverse($table_info); - return $table_info; - } - /** - * Method to get the autoincremented values of each table and returns it. - * - * The data is from sqlite_sequence table. - * - * @return assoc array name => sequence, or false - * @access private - */ - private function get_sequence() { - global $wpdb; - $sequence_info = array(); - $results = $wpdb->get_results("SELECT name, seq FROM sqlite_sequence"); - if (is_null($results) || empty($results)) { - return false; - } else { - foreach ($results as $result) { - $sequence_info[$result->name] = $result->seq; - } - return $sequence_info; - } - } - /** - * Method to show the contents of 'wp-content/db.php' file. - * - * If this file is not existent, shows message and returns false. - * - * @return string - * @access private - */ - private function show_db_php() { - if (defined('WP_CONTENT_DIR')) { - $file = WP_CONTENT_DIR . '/db.php'; - } else { - $file = ABSPATH . 'wp-content/db.php'; - } - if (file_exists($file)) { - if (is_readable($file)) { - $contents = file_get_contents($file); - return $contents; - } else { - $contents = 'file is not readable'; - } - } else { - $contents = 'file doesn\'t exist'; - } - return $contents; - } - /** - * Method to get the textarea content and write it to db.php file. - * - * @param string $contents - * @return boolean - * @access private - */ - private function save_db_php($contents) { - if (defined('WP_CONTENT_DIR')) { - $file = WP_CONTENT_DIR . '/db.php'; - } else { - $file = ABSPATH . 'wp-content/db.php'; - } - $fh = fopen($file, "w+"); - if ($fh) { - if (flock($fh, LOCK_EX)) { - if (fwrite($fh, $contents) === false) { - return false; - } - flock($fh, LOCK_UN); - } else { - return false; - } - } - fclose($fh); - return true; - } - /** - * Method to replace the old db.php with the new one. - * - * @return boolean - * @access private - */ - private function update_db_file() { - $new_file = PDODIR . 'db.php'; - if (file_exists($new_file) && is_readable($new_file)) { - $contents = file_get_contents($new_file); - } else { - return false; - } - if (defined('WP_CONTENT_DIR')) { - $path = WP_CONTENT_DIR . '/db.php'; - } else { - $path = ABSPATH . 'wp-content/db.php'; - } - if (($handle = @fopen($path, 'w+')) && flock($handle, LOCK_EX)) { - if (fwrite($handle, $contents) == false) { - flock($handle, LOCK_UN); - fclose($handle); - return false; - } - flock($handle, LOCK_UN); - fclose($handle); - } else { - return false; - } - return true; - } - /** - * Method to optimize SQLite database. - * - * This only gives VACUUM command to SQLite database. This query is rewritten in - * the query.class.php file. - * - * @return boolean - * @access private - */ - private function optimize_db() { - global $wpdb; - $result = $wpdb->query("OPTIMIZE"); - return $result; - } - /** - * Method to get SQLite database file size. - * - * @return string - * @access private - */ - private function get_database_size() { - $db_file = FQDB; - if (file_exists($db_file)) { - $size = filesize($db_file); - clearstatcache(true, $db_file); - return $this->convert_to_formatted_number($size); - } - } - /** - * Method to format the file size number to the unit byte. - * - * @param integer $size - * @return string - * @access private - */ - private function convert_to_formatted_number($size) { - $unim = array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); - $count = 0; - while ($size >= 1024) { - $count++; - $size = $size / 1024; - } - return number_format($size, ($count ? 2 : 0), '.', ',') . ' ' . $unim[$count]; - } - - /** - * Method to echo plugins info table component. - * - * @return nothing returned. - * @access private - */ - private function show_plugins_info() { - $domain = $this->text_domain; - if (file_exists(SQLiteListFile)) { - $contents = file_get_contents(SQLiteListFile); - $plugin_info_list = json_decode($contents); - $plugins = get_plugins(); - foreach ($plugins as $key => $data) { - $name = ''.$data['Name'].''; - foreach ($plugin_info_list as $plugin_info) { - if ($data['Name'] == $plugin_info->name) { - $class = 'class="'.$plugin_info->class.'"'; - // for Internationalization... it's a redundant codes, mm... - // I might have made a mistake to store data in json format... - switch ($plugin_info->compat) { - case 'Needs Patch': - if (!empty($plugin_info->patch_url)) { - $compat = ''.__('Needs Patch', $domain).''; - } else { - $compat = __('Needs Patch', $domain); - } - break; - case 'Probably No': - $compat = __('Probably No', $domain); - break; - case 'Probably Yes': - $compat = __('Probably Yes', $domain); - break; - case 'No': - $compat = __('No', $domain); - break; - case 'Checked': - if (!empty($plugin_info->informed) && stripos($plugin_info->informed, 'Users\' Information') !== false) { - $compat = __('Checked*', $domain); - } else { - $compat = __('Checked', $domain); - } - break; - default: - $compat = __('Not Checked', $domain); - break; - } - break; - } else { - $class = 'class="compatible"'; - $compat = __('Not Checked', $domain); - } - } - if (is_plugin_active_for_network($key)) { - echo '"; - echo sprintf('%1$s%2$s%3$s', $name, __('Sitewide Active', $domain), $compat); - } elseif (is_plugin_active($key)) { - echo '"; - echo sprintf('%1$s%2$s%3$s', $name, __('Active', $domain), $compat); - } else { - echo '"; - echo sprintf('%1$s%2$s%3$s', $name, __('Inactive', $domain), $compat); - } - echo ''; - } - } - } + /** + * Method to display update notice on the admin dashboard. + * + * Check if db.php file is replaced with the apropriate version, + * and if not, display notice. + * + * This is not required for now. So this method only returns and + * do nothing. + * + */ + public static function show_admin_notice() { + return; + $notice_string = __('Upgrading Notice: To finish upgrading, please activate SQLite Integration and go Setting >> SQLite Integration >> Miscellaneous, and click the button "update" at the bottom of the page. Or else replace wp-content/db.php with the one in sqlite-integration directory manually.', 'sqlite-integration'); + $current_version = defined('SQLITE_INTEGRATION_VERSION') ? SQLITE_INTEGRATION_VERSION : ''; + if (version_compare($current_version, '1.6.2', '=')) return; + $version = ''; + if (defined('WP_CONTENT_DIR')) { + $path = WP_CONTENT_DIR . '/db.php'; + } else { + $path = ABSPATH . 'wp-content/db.php'; + } + if (!$file_handle = @fopen($path, 'r')) return; + while (($buffer = fgets($file_handle)) !== false) { + if (stripos($buffer, '@version') !== false) { + $version = str_ireplace('*@version ', '', $buffer); + $version = trim($version); + break; + } + } + fclose($file_handle); + if (empty($version) || version_compare($version, $current_version, '<')) { + echo '
    '.$notice_string.'
    '; + } + } + /** + * Method to read a error log file and returns its contents. + * + * 'FQDBDIR/debug.txt' is the log file name. + * If this file is not existent, returns false. + * + * @return string|boolean + * @access private + */ + private function show_error_log() { + $file = FQDBDIR . 'debug.txt'; + if (file_exists($file)) { + $contents = file_get_contents($file); + return $contents; + } else { + return false; + } + } + /** + * Method to clear the contents of the error log file. + * + * @return boolean + * @access private + */ + private function clear_log_file() { + $result = false; + $file = FQDBDIR . 'debug.txt'; + $fh = fopen($file, "w+"); + if ($fh) { + if (flock($fh, LOCK_EX)) { + if (ftruncate($fh, 0) === false) { + return false; + } + flock($fh, LOCK_UN); + } else { + return false; + } + } + fclose($fh); + return true; + } - /** - * Method to return output of phpinfo() as an array. - * - * @See PHP Manual - * @return array - * @access private - */ - private function parse_php_modules() { - ob_start(); - phpinfo(INFO_MODULES); - $infos = ob_get_contents(); - ob_end_clean(); - - $infos = strip_tags($infos, '

    '); - $infos = preg_replace('/]*>([^<]+)<\/th>/', "\\1", $infos); - $infos = preg_replace('/]*>([^<]+)<\/td>/', "\\1", $infos); - $info_array = preg_split('/(

    [^<]+?<\/h2>)/', $infos, -1, PREG_SPLIT_DELIM_CAPTURE); - $modules = array(); - for ($i = 1; $i < count($info_array); $i++) { - if (preg_match('/

    ([^<]+)<\/h2>/', $info_array[$i], $match)) { - $name = trim($match[1]); - $info_array2 = explode("\n", $info_array[$i+1]); - foreach ($info_array2 as $info) { - $pattern = '([^<]+)<\/info>'; - $pattern3 = "/$pattern\\s*$pattern\\s*$pattern/"; - $pattern2 = "/$pattern\\s*$pattern/"; - if (preg_match($pattern3, $info, $match)) { - $modules[$name][trim($match[1])] = array(trim($match[2]), trim($match[3])); - } elseif (preg_match($pattern2, $info, $match)) { - $modules[$name][trim($match[1])] = trim($match[2]); - } - } - } - } - return $modules; - } - /** - * Method to echo PHP module info. - * - * @param string $module_name - * @param string $setting_name - * @access private - */ - private function get_module_setting($module_name, $setting_name) { - $module_info = $this->parse_php_modules(); - echo $module_info[$module_name][$setting_name]; - } - function show_parent() { - if (function_exists('is_multisite') && is_multisite()) { - return 'settings.php'; - } else { - return 'options-general.php'; - } - } + /** + * Method to get system information from the server and returns its data. + * + * Returned value is an associative array of system informations. + * + * sys_info['WordPress'] => WordPress Version + * sys_info['PHP'] => PHP Version + * + * + * @return array + * @access private + */ + private function get_system_info() { + global $wp_version; + $sys_info = array(); + $sys_info['WordPress'] = $wp_version; + $sys_info['PHP'] = PHP_VERSION; + return $sys_info; + } + /** + * Method to get database information from the database and returns its data. + * + * Returned value is an associative array. + * + * @return array + * @access private + */ + private function get_database_status() { + global $wpdb; + $status = array(); + $db_size = $this->get_database_size(); + $encoding = $wpdb->get_var("PRAGMA encoding"); + $integrity = $wpdb->get_var("PRAGMA integrity_check"); + $page_size = $wpdb->get_var("PRAGMA page_size"); + $page_count = $wpdb->get_var("PRAGMA page_count"); + $unused_page = $wpdb->get_var("PRAGMA freelist_count"); + $collation_list = $wpdb->get_results("PRAGMA collation_list"); + $compile_options = $wpdb->get_results("PRAGMA compile_options"); + foreach ($collation_list as $col) { + $collations[] = $col->name; + } + foreach ($compile_options as $opt) { + $options[] = $opt->compile_option; + } + $status['size'] = $db_size; + $status['integrity'] = $integrity; + $status['pagesize'] = $page_size; + $status['page'] = $page_count; + $status['unused'] = $unused_page; + $status['encoding'] = $encoding; + $status['collations'] = $collations; + $status['options'] = $options; + return $status; + } + /** + * Method to get table information and returns its data. + * + * Returned value is an associative array like: + * + * array( table name => array( index name ( column name ))) + * + * for each table in the database + * + * @return array + * @access private + */ + private function get_tables_info() { + global $wpdb; + $table_info = array(); + $tables = $wpdb->get_col("SHOW TABLES"); + foreach ($tables as $table) { + $index_object = $wpdb->get_results("SHOW INDEX FROM $table"); + if (empty($index_object)) { + $table_info[$table][] = 'no index'; + } else { + foreach ($index_object as $index) { + $table_info[$table][] = $index->Key_name . ' ( ' . $index->Column_name . ' )'; + } + } + } + $table_info = array_reverse($table_info); + return $table_info; + } + /** + * Method to get the autoincremented values of each table and returns it. + * + * The data is from sqlite_sequence table. + * + * @return assoc array name => sequence, or false + * @access private + */ + private function get_sequence() { + global $wpdb; + $sequence_info = array(); + $results = $wpdb->get_results("SELECT name, seq FROM sqlite_sequence"); + if (is_null($results) || empty($results)) { + return false; + } else { + foreach ($results as $result) { + $sequence_info[$result->name] = $result->seq; + } + return $sequence_info; + } + } + /** + * Method to show the contents of 'wp-content/db.php' file. + * + * If this file is not existent, shows message and returns false. + * + * @return string + * @access private + */ + private function show_db_php() { + if (defined('WP_CONTENT_DIR')) { + $file = WP_CONTENT_DIR . '/db.php'; + } else { + $file = ABSPATH . 'wp-content/db.php'; + } + if (file_exists($file)) { + if (is_readable($file)) { + $contents = file_get_contents($file); + return $contents; + } else { + $contents = 'file is not readable'; + } + } else { + $contents = 'file doesn\'t exist'; + } + return $contents; + } + /** + * Method to get the textarea content and write it to db.php file. + * + * @param string $contents + * @return boolean + * @access private + */ + private function save_db_php($contents) { + if (defined('WP_CONTENT_DIR')) { + $file = WP_CONTENT_DIR . '/db.php'; + } else { + $file = ABSPATH . 'wp-content/db.php'; + } + $fh = fopen($file, "w+"); + if ($fh) { + if (flock($fh, LOCK_EX)) { + if (fwrite($fh, $contents) === false) { + return false; + } + flock($fh, LOCK_UN); + } else { + return false; + } + } + fclose($fh); + return true; + } + /** + * Method to replace the old db.php with the new one. + * + * @return boolean + * @access private + */ + private function update_db_file() { + $new_file = PDODIR . 'db.php'; + if (file_exists($new_file) && is_readable($new_file)) { + $contents = file_get_contents($new_file); + } else { + return false; + } + if (defined('WP_CONTENT_DIR')) { + $path = WP_CONTENT_DIR . '/db.php'; + } else { + $path = ABSPATH . 'wp-content/db.php'; + } + if (($handle = @fopen($path, 'w+')) && flock($handle, LOCK_EX)) { + if (fwrite($handle, $contents) == false) { + flock($handle, LOCK_UN); + fclose($handle); + return false; + } + flock($handle, LOCK_UN); + fclose($handle); + } else { + return false; + } + return true; + } + /** + * Method to optimize SQLite database. + * + * This only gives VACUUM command to SQLite database. This query is rewritten in + * the query.class.php file. + * + * @return boolean + * @access private + */ + private function optimize_db() { + global $wpdb; + $result = $wpdb->query("OPTIMIZE"); + return $result; + } + /** + * Method to get SQLite database file size. + * + * @return string + * @access private + */ + private function get_database_size() { + $db_file = FQDB; + if (file_exists($db_file)) { + $size = filesize($db_file); + clearstatcache(true, $db_file); + return $this->convert_to_formatted_number($size); + } + } + /** + * Method to format the file size number to the unit byte. + * + * @param integer $size + * @return string + * @access private + */ + private function convert_to_formatted_number($size) { + $unim = array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); + $count = 0; + while ($size >= 1024) { + $count++; + $size = $size / 1024; + } + return number_format($size, ($count ? 2 : 0), '.', ',') . ' ' . $unim[$count]; + } - /** - * Method to parse FQDBDIR and return backup database files. - * - * @return nothing returned. - * @access private - */ - private function get_backup_files() { - $db_name = basename(FQDB); - $names_to_exclude = array('.', '..', '.htaccess', 'debug.txt', '.ht.sqlite', 'index.php', $db_name); - $backup_files = array(); - if (is_dir(FQDBDIR)) { - if ($dir_handle = opendir(FQDBDIR)) { - while (($file_name = readdir($dir_handle)) !== false) { - if (in_array($file_name, $names_to_exclude)) continue; - $backup_files[] = $file_name; - } - } - } - return $backup_files; - } - - /** - * Method to create backup database file. - * - * @return string array - * @access private - */ - private function backup_db() { - $domain = $this->text_domain; - $result = array(); - $database_file = FQDB; - $db_name = basename(FQDB); - if (!file_exists($database_file)) { - return false; - } - $today = date("Ymd"); - if (!extension_loaded('zip')) { - $backup_file = $database_file . '.' . $today . '.back'; - if (copy($database_file, $backup_file)) { - $result['success'] = basename($backup_file) . __(' was created.', $domain); - } else { - $result['error'] = basename($backup_file) . __(' was not created.', $domain); - } - } else { - $backup_file = $database_file . '.' . $today . '.zip'; - $zip = new ZipArchive(); - $res = $zip->open($backup_file, ZipArchive::CREATE | ZipArchive::OVERWRITE); - if ($res === true) { - $zip->addFile($database_file, $db_name); - $result['success'] = basename($backup_file) . __(' was created.', $domain); - } else { - $result['error'] = basename($backup_file) . __(' was not created.', $domain); - } - $zip->close(); - } - return $result; - } + /** + * Method to echo plugins info table component. + * + * @return nothing returned. + * @access private + */ + private function show_plugins_info() { + $domain = $this->text_domain; + if (file_exists(SQLiteListFile)) { + $contents = file_get_contents(SQLiteListFile); + $plugin_info_list = json_decode($contents); + $plugins = get_plugins(); + foreach ($plugins as $key => $data) { + $name = ''.$data['Name'].''; + foreach ($plugin_info_list as $plugin_info) { + if ($data['Name'] == $plugin_info->name) { + $class = 'class="'.$plugin_info->class.'"'; + // for Internationalization... it's a redundant codes, mm... + // I might have made a mistake to store data in json format... + switch ($plugin_info->compat) { + case 'Needs Patch': + if (!empty($plugin_info->patch_url)) { + $compat = ''.__('Needs Patch', $domain).''; + } else { + $compat = __('Needs Patch', $domain); + } + break; + case 'Probably No': + $compat = __('Probably No', $domain); + break; + case 'Probably Yes': + $compat = __('Probably Yes', $domain); + break; + case 'No': + $compat = __('No', $domain); + break; + case 'Checked': + if (!empty($plugin_info->informed) && stripos($plugin_info->informed, 'Users\' Information') !== false) { + $compat = __('Checked*', $domain); + } else { + $compat = __('Checked', $domain); + } + break; + default: + $compat = __('Not Checked', $domain); + break; + } + break; + } else { + $class = 'class="compatible"'; + $compat = __('Not Checked', $domain); + } + } + if (is_plugin_active_for_network($key)) { + echo '"; + echo sprintf('%1$s%2$s%3$s', $name, __('Sitewide Active', $domain), $compat); + } elseif (is_plugin_active($key)) { + echo '"; + echo sprintf('%1$s%2$s%3$s', $name, __('Active', $domain), $compat); + } else { + echo '"; + echo sprintf('%1$s%2$s%3$s', $name, __('Inactive', $domain), $compat); + } + echo ''; + } + } + } + + /** + * Method to return output of phpinfo() as an array. + * + * @See PHP Manual + * @return array + * @access private + */ + private function parse_php_modules() { + ob_start(); + phpinfo(INFO_MODULES); + $infos = ob_get_contents(); + ob_end_clean(); + + $infos = strip_tags($infos, '

    '); + $infos = preg_replace('/]*>([^<]+)<\/th>/', "\\1", $infos); + $infos = preg_replace('/]*>([^<]+)<\/td>/', "\\1", $infos); + $info_array = preg_split('/(

    [^<]+?<\/h2>)/', $infos, -1, PREG_SPLIT_DELIM_CAPTURE); + $modules = array(); + for ($i = 1; $i < count($info_array); $i++) { + if (preg_match('/

    ([^<]+)<\/h2>/', $info_array[$i], $match)) { + $name = trim($match[1]); + $info_array2 = explode("\n", $info_array[$i+1]); + foreach ($info_array2 as $info) { + $pattern = '([^<]+)<\/info>'; + $pattern3 = "/$pattern\\s*$pattern\\s*$pattern/"; + $pattern2 = "/$pattern\\s*$pattern/"; + if (preg_match($pattern3, $info, $match)) { + $modules[$name][trim($match[1])] = array(trim($match[2]), trim($match[3])); + } elseif (preg_match($pattern2, $info, $match)) { + $modules[$name][trim($match[1])] = trim($match[2]); + } + } + } + } + return $modules; + } + /** + * Method to echo PHP module info. + * + * @param string $module_name + * @param string $setting_name + * @access private + */ + private function get_module_setting($module_name, $setting_name) { + $module_info = $this->parse_php_modules(); + echo $module_info[$module_name][$setting_name]; + } + function show_parent() { + if (function_exists('is_multisite') && is_multisite()) { + return 'settings.php'; + } else { + return 'options-general.php'; + } + } + + /** + * Method to parse FQDBDIR and return backup database files. + * + * @return nothing returned. + * @access private + */ + private function get_backup_files() { + $db_name = basename(FQDB); + $names_to_exclude = array('.', '..', '.htaccess', 'debug.txt', '.ht.sqlite', 'index.php', $db_name); + $backup_files = array(); + if (is_dir(FQDBDIR)) { + if ($dir_handle = opendir(FQDBDIR)) { + while (($file_name = readdir($dir_handle)) !== false) { + if (in_array($file_name, $names_to_exclude)) continue; + $backup_files[] = $file_name; + } + } + } + return $backup_files; + } + + /** + * Method to create backup database file. + * + * @return string array + * @access private + */ + private function backup_db() { + $domain = $this->text_domain; + $result = array(); + $database_file = FQDB; + $db_name = basename(FQDB); + if (!file_exists($database_file)) { + return false; + } + $today = date("Ymd"); + if (!extension_loaded('zip')) { + $backup_file = $database_file . '.' . $today . '.back'; + if (copy($database_file, $backup_file)) { + $result['success'] = basename($backup_file) . __(' was created.', $domain); + } else { + $result['error'] = basename($backup_file) . __(' was not created.', $domain); + } + } else { + $backup_file = $database_file . '.' . $today . '.zip'; + $zip = new ZipArchive(); + $res = $zip->open($backup_file, ZipArchive::CREATE | ZipArchive::OVERWRITE); + if ($res === true) { + $zip->addFile($database_file, $db_name); + $result['success'] = basename($backup_file) . __(' was created.', $domain); + } else { + $result['error'] = basename($backup_file) . __(' was not created.', $domain); + } + $zip->close(); + } + return $result; + } /** * Method to delete backup database file(s). - * + * * Users can delete multiple files at a time. - * + * * @return false if file names aren't checked, empty array if failed, array of messages if succeeded. * @access private */ - private function delete_backup_db() { - $domain = $this->text_domain; - $file_names = array(); - $results = array(); - if (isset($_POST['backup_checked'])) { - $file_names = $_POST['backup_checked']; - } else { - return false; - } - if (chdir(FQDBDIR)) { - foreach ($file_names as $file) { - if (unlink($file)) { - $results[$file] = sprintf(__('File %s was deleted.', $domain), $file); - } else { - $results[$file] = sprintf(__('Error! File was not deleted.', $domain), $file); - } - } - } - return $results; - } - /** - * Method to download a backup file. - * - * This method uses header() function, so we have to register this function using - * admin_init action hook. It must also be declared as public. We check HTTP_REFERER - * and input button name, and ,after that, wp_nonce. When the admin_init is executed - * it only returns true. - * - * The database file might be several hundred mega bytes, so we don't use readfile() - * but use fread() instead. - * - * Users can download one file at a time. - * - * @return 1 if the file name isn't checked, 2 if multiple files are checked, true if succeeded. - */ - static function download_backup_db() { - if (is_multisite()) { - $script_url = network_admin_url('settings.php?page=setting-file'); - } else { - $script_url = admin_url('options-general.php?page=setting-file'); - } - if (isset($_POST['download_backup_file']) && stripos($_SERVER['HTTP_REFERER'], $script_url) !== false) { - check_admin_referer('sqliteintegration-backup-manip-stats'); - if (!isset($_POST['backup_checked'])) return 1; - $file_names = array(); - $file_names = $_POST['backup_checked']; - if (count($file_names) != 1) return 2; - $file_name = $file_names[0]; - $file_path = FQDBDIR . $file_name; + private function delete_backup_db() { + $domain = $this->text_domain; + $file_names = array(); + $results = array(); + if (isset($_POST['backup_checked'])) { + $file_names = $_POST['backup_checked']; + } else { + return false; + } + if (chdir(FQDBDIR)) { + foreach ($file_names as $file) { + if (unlink($file)) { + $results[$file] = sprintf(__('File %s was deleted.', $domain), $file); + } else { + $results[$file] = sprintf(__('Error! File was not deleted.', $domain), $file); + } + } + } + return $results; + } + /** + * Method to download a backup file. + * + * This method uses header() function, so we have to register this function using + * admin_init action hook. It must also be declared as public. We check HTTP_REFERER + * and input button name, and ,after that, wp_nonce. When the admin_init is executed + * it only returns true. + * + * The database file might be several hundred mega bytes, so we don't use readfile() + * but use fread() instead. + * + * Users can download one file at a time. + * + * @return 1 if the file name isn't checked, 2 if multiple files are checked, true if succeeded. + */ + static function download_backup_db() { + if (is_multisite()) { + $script_url = network_admin_url('settings.php?page=setting-file'); + } else { + $script_url = admin_url('options-general.php?page=setting-file'); + } + if (isset($_POST['download_backup_file']) && stripos($_SERVER['HTTP_REFERER'], $script_url) !== false) { + check_admin_referer('sqliteintegration-backup-manip-stats'); + if (!isset($_POST['backup_checked'])) return 1; + $file_names = array(); + $file_names = $_POST['backup_checked']; + if (count($file_names) != 1) return 2; + $file_name = $file_names[0]; + $file_path = FQDBDIR . $file_name; $blog_name = str_replace(array(' ', ' ', ';'), array('_', '_', '_'), get_bloginfo('name')); $download_file_name = $blog_name . '_' . $file_name; - header('Pragma: public'); - header('Cache-Control: must-revalidate,post-check=0,pre-check=0'); - header('Content-Type: application/force-download'); - header('Content-Type: application/octet-stream'); - header('Content-Type: application/download'); - header('Content-Disposition: attachment; filename='.$download_file_name.';'); - header('Content-Transfer-Encoding: binary'); - header('Content-Length: '.filesize($file_path)); - $fp = fopen($file_path, 'r'); - while (!feof($fp)) { - echo fread($fp, 65536); - flush(); - } - fclose($fp); - } - return true; - } - /** - * Method to show Welcome page. - * - */ - function welcome() { - $domain = $this->text_domain; - if (isset($_GET['page']) && $_GET['page'] == 'sqlite-integration') :?> -
    -

    -

    - -

    -

    - -

    -

    - -

    -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - text_domain; - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to access this page!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to access this page!', $domain)); - } - if (isset($_GET['page']) && $_GET['page'] == 'sys-info') :?> - -
    -

    -

    - get_system_info(); ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    get_module_setting('PDO', 'PDO support');?>
    get_module_setting('PDO', 'PDO drivers');?>
    get_module_setting('pdo_sqlite', 'PDO Driver for SQLite 3.x');?>
    get_module_setting('pdo_sqlite', 'SQLite Library');?> -
    - -

    - - - - - - - - - get_database_status();?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    - - '; - echo ($i+1).'. '.$col; - $i++; - } - ?> -
    - '; - echo ($i+1).'. '.$op; - $i++; - } - ?> -
    - -

    -

    - -

    - - - - - - - - - get_tables_info(); - $table_seq = $this->get_sequence(); - $network_tables = array(); - if (is_multisite()) { - $tmp_tables = $wpdb->tables('blog', false); - $blogs = $wpdb->get_col("SELECT * FROM {$wpdb->prefix}blogs"); - if (count($blogs) > 1) { - foreach ($blogs as $id) { - if ($id == 1) continue; - foreach ($tmp_tables as $tmp_tbl) { - $network_tables[] = $wpdb->prefix.$id.'_'.$tmp_tbl; - } - } - } - } - foreach ($table_info as $tbl_name => $index) : ?> - tables('all', true)) || in_array($tbl_name, $network_tables) || $tbl_name == 'sqlite_sequence') { - $which_table = 'system'; - } else { - $which_table = 'user'; - } - echo ''; - if (array_key_exists($tbl_name, $table_seq)) $tbl_name .= " ($table_seq[$tbl_name])"; - echo ''; - echo '';?> - - - - -
    -
    ' . $tbl_name . '' . $which_table . ' table';} ?>
    -
    - -
    -

    -

    - -

    - - - - - - - - - - show_plugins_info();?> - -
    -

    - -

    -
    - text_domain; + if (isset($_GET['page']) && $_GET['page'] == 'sqlite-integration') :?> +
    +

    +

    + +

    +

    + +

    +

    + +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + text_domain; + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to access this page!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to access this page!', $domain)); + } + if (isset($_GET['page']) && $_GET['page'] == 'sys-info') :?> + +
    +

    +

    + get_system_info(); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    get_module_setting('PDO', 'PDO support');?>
    get_module_setting('PDO', 'PDO drivers');?>
    get_module_setting('pdo_sqlite', 'PDO Driver for SQLite 3.x');?>
    get_module_setting('pdo_sqlite', 'SQLite Library');?> +
    - /** - * Method to show Setting File page. - * - */ - function edit_db_file() { - $domain = $this->text_domain; - if (is_multisite() && !current_user_can('manage_network_options')) { - die(__('You are not allowed to access this page!', $domain)); - } elseif (!current_user_can('manage_options')) { - die(__('You are not allowed to access this page!', $domain)); - } - if (isset($_POST['sqlitewordpress_log_reset'])) { - check_admin_referer('sqlitewordpress-log-reset-stats'); - if ($this->clear_log_file()) { - $messages = __('Log cleared', $domain); - echo '
    '.$messages.'
    '; - } else { - $messages = __('Log not cleared', $domain); - echo '
    '.$messages.'
    '; - } - } - if (isset($_POST['sqlitewordpress_db_save'])) { - check_admin_referer('sqlitewordpress-db-save-stats'); - if (isset($_POST['dbfile'])) { - $contents = $_POST['dbfile']; - if (get_magic_quotes_gpc() || version_compare(PHP_VERSION, '5.4', '>=')) { - $contents = stripslashes($contents); - } - if ($this->save_db_php($contents)) { - $messages = __('db.php was saved', $domain); - echo '
    '.$messages.'
    '; - } else { - $messages = __('Error! db.php couldn\'t be saved', $domain); - echo '
    '.$messages.'
    '; - } - } - } - if (isset($_POST['sqlitewordpress_db_optimize'])) { - check_admin_referer('sqlitewordpress-db-optimize-stats'); - $size_before = $this->get_database_size(); - $result = $this->optimize_db(); - if ($result) { - $size_after = $this->get_database_size(); - $messages = sprintf(__('Optimization finished. Before optimization: %1$s, After optimization: %2$s.', $domain), $size_before, $size_after); - echo '
    '.$messages.'
    '; - } else { - $messages = __('Optimization failed', $domain); - echo '
    '.$messages.'
    '; - } - } - if (isset($_POST['backup_db'])) { +

    + + + + + + + + + get_database_status();?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + + '; + echo ($i+1).'. '.$col; + $i++; + } + ?> +
    + '; + echo ($i+1).'. '.$op; + $i++; + } + ?> +
    + +

    +

    + +

    + + + + + + + + + get_tables_info(); + $table_seq = $this->get_sequence(); + $network_tables = array(); + if (is_multisite()) { + $tmp_tables = $wpdb->tables('blog', false); + $blogs = $wpdb->get_col("SELECT * FROM {$wpdb->prefix}blogs"); + if (count($blogs) > 1) { + foreach ($blogs as $id) { + if ($id == 1) continue; + foreach ($tmp_tables as $tmp_tbl) { + $network_tables[] = $wpdb->prefix.$id.'_'.$tmp_tbl; + } + } + } + } + foreach ($table_info as $tbl_name => $index) : ?> + tables('all', true)) || in_array($tbl_name, $network_tables) || $tbl_name == 'sqlite_sequence') { + $which_table = 'system'; + } else { + $which_table = 'user'; + } + echo ''; + if (array_key_exists($tbl_name, $table_seq)) $tbl_name .= " ($table_seq[$tbl_name])"; + echo ''; + echo '';?> + + + + +
    +
    ' . $tbl_name . '' . $which_table . ' table';} ?>
    +
    + +
    +

    +

    + +

    + + + + + + + + + + show_plugins_info();?> + +
    +

    + +

    +
    + text_domain; + if (is_multisite() && !current_user_can('manage_network_options')) { + die(__('You are not allowed to access this page!', $domain)); + } elseif (!current_user_can('manage_options')) { + die(__('You are not allowed to access this page!', $domain)); + } + if (isset($_POST['sqlitewordpress_log_reset'])) { + check_admin_referer('sqlitewordpress-log-reset-stats'); + if ($this->clear_log_file()) { + $messages = __('Log cleared', $domain); + echo '
    '.$messages.'
    '; + } else { + $messages = __('Log not cleared', $domain); + echo '
    '.$messages.'
    '; + } + } + if (isset($_POST['sqlitewordpress_db_save'])) { + check_admin_referer('sqlitewordpress-db-save-stats'); + if (isset($_POST['dbfile'])) { + $contents = $_POST['dbfile']; + if (get_magic_quotes_gpc() || version_compare(PHP_VERSION, '5.4', '>=')) { + $contents = stripslashes($contents); + } + if ($this->save_db_php($contents)) { + $messages = __('db.php was saved', $domain); + echo '
    '.$messages.'
    '; + } else { + $messages = __('Error! db.php couldn\'t be saved', $domain); + echo '
    '.$messages.'
    '; + } + } + } + if (isset($_POST['sqlitewordpress_db_optimize'])) { + check_admin_referer('sqlitewordpress-db-optimize-stats'); + $size_before = $this->get_database_size(); + $result = $this->optimize_db(); + if ($result) { + $size_after = $this->get_database_size(); + $messages = sprintf(__('Optimization finished. Before optimization: %1$s, After optimization: %2$s.', $domain), $size_before, $size_after); + echo '
    '.$messages.'
    '; + } else { + $messages = __('Optimization failed', $domain); + echo '
    '.$messages.'
    '; + } + } + if (isset($_POST['backup_db'])) { check_admin_referer('sqliteintegration-backup-manip-stats'); $results = $this->backup_db(); if ($results === false) { @@ -929,134 +929,134 @@ class SQLiteIntegrationUtils { } } if (isset($_POST['sqliteintegration_update_db_file'])) { - check_admin_referer('sqliteintegration-db-update-stats'); - $result = $this->update_db_file(); - if ($result === false) { - $message = __('Couldn"t update db.php file. Please replace it manually.', $domain); - echo '
    '.$message.'
    '; - } else { - echo <<update_db_file(); + if ($result === false) { + $message = __('Couldn"t update db.php file. Please replace it manually.', $domain); + echo '
    '.$message.'
    '; + } else { + echo << // JS; - $message = __('Your db.php is updated.', $domain); - echo '
    '.$message.'
    '; - } - } - if (isset($_GET['page']) && $_GET['page'] == 'setting-file') :?> - -
    -

    -

    -

    - -

    -
    - -

    - -

    -
    -

    -

    - -

    -

    - -

    -

    - -

    - get_backup_files();?> -
    - - - - - - - - - - - - - - - - - - -
    -

    - - - -

    -
    -

    -

    - -

    -
    - - show_error_log(); - if ($ret_val === false || empty($ret_val)) { - $ret_val = __('No error messages are found', $domain); - } - ?> - -

    - -

    -
    + $message = __('Your db.php is updated.', $domain); + echo '
    '.$message.'
    '; + } + } + if (isset($_GET['page']) && $_GET['page'] == 'setting-file') :?> + +
    +

    +

    +

    + +

    +
    + +

    + +

    +
    +

    +

    + +

    +

    + +

    +

    + +

    + get_backup_files();?> +
    + + + + + + + + + + + + + + + + + + +
    +

    + + + +

    +
    +

    +

    + +

    +
    + + show_error_log(); + if ($ret_val === false || empty($ret_val)) { + $ret_val = __('No error messages are found', $domain); + } + ?> + +

    + +

    +
    - - ';?> - -

    '; ?> - If you don\'t understand well, please don\'t edit this file.', $domain)?> - '; ?> - '; ?> - - show_db_php();?> - '.$db_contents.'

    '; ?> - ', __('Save', $domain), __('Are you sure to save this file?\n\nClick [Cancel] to stop, [OK] to continue.', $domain)); ?> - '; ?> - -

    -

    -
    - -

    ', __('Update', $domain), __('Are you sure to update this file?\n\nClick [Cancel] to stop, [OK] to continue.', $domain));?>

    -
    -
    - + ';?> + +

    '; ?> + If you don\'t understand well, please don\'t edit this file.', $domain)?> + '; ?> + '; ?> + + show_db_php();?> + '.$db_contents.'

    '; ?> + ', __('Save', $domain), __('Are you sure to save this file?\n\nClick [Cancel] to stop, [OK] to continue.', $domain)); ?> + '; ?> + +

    +

    +
    + +

    ', __('Update', $domain), __('Are you sure to update this file?\n\nClick [Cancel] to stop, [OK] to continue.', $domain));?>

    +
    +
    +