first release

git-svn-id: https://plugins.svn.wordpress.org/sqlite-integration/trunk@737264 b8457f37-d9ea-0310-8a92-e5e31aec5664
This commit is contained in:
kjmtsh 2013-07-07 06:49:38 +00:00
parent 290bd89db5
commit e8312985a2
24 changed files with 8174 additions and 0 deletions

96
db.php Normal file
View File

@ -0,0 +1,96 @@
<?php
/**
* This file must be placed in the directory
*
* wordpress/wp-content/db.php
*
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
function pdo_log_erro($message, $data = null) {
if (strpos($_SERVER['SCRIPT_NAME'], 'wp-admin') !== false) {
$admin_dir = '';
} else {
$admin_dir = 'wp-admin/';
}
die(<<<HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>WordPress &rsaquo; Error</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="{$admin_dir}install.css" type="text/css" />
</head>
<body>
<h1 id="logo"><img alt="WordPress" src="{$admin_dir}images/wordpress-logo.png" /></h1>
<p>$message</p>
<p>$data</p>
</body>
<html>
HTML
);
}
if (version_compare( PHP_VERSION, '5.2.4', '<')) {
pdo_log_erro(__('PHP version on this server is too old.'), sprinf(__("Your server is running PHP version %d but this version of WordPress requires at least 5.2.4"), phpversion()));
}
if (!extension_loaded('pdo')) {
pdo_log_erro(__('PHP PDO Extension is not loaded.'), __('Your PHP installation appears to be missing the PDO extension which is required for this version of WordPress.'));
}
if (!extension_loaded('pdo_sqlite')) {
pdo_log_erro(__('PDO Driver for SQLite is missing.'), __('Your PHP installtion appears not to have the right PDO drivers loaded. These are required for this version of WordPress and the type of database you have specified.'));
}
/**
* Notice:
* Your scripts have the permission to create directories or files on your server.
* If you write in your wp-config.php like below, we take these definitions.
* define('DB_DIR', '/full_path_to_the_database_directory/');
* define('DB_FILE', 'database_file_name');
*/
if (defined('WP_PLUGIN_DIR')) {
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('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('DB_FILE' )) {
define('FQDB', FQDBDIR . DB_FILE);
} else {
define('FQDB', FQDBDIR . '.ht.sqlite');
}
if (version_compare(PHP_VERSION, '5.3', '<')) {
define('UDF_FILE', PDODIR . 'functions-5-2.php');
} elseif (version_compare(PHP_VERSION, '5.3', '>=')) {
define('UDF_FILE', PDODIR . 'functions.php');
}
require_once PDODIR . 'pdodb.class.php';
?>

370
functions-5-2.php Normal file
View File

@ -0,0 +1,370 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
/**
* This class defines user defined functions(UDFs) for PDO
* This replaces the functions used in the SQL statement with the PHP functions.
* If you want another, add the name in the array and define the function with
* PHP script.
*/
class PDOSQLiteUDFS {
public function __construct(&$pdo){
foreach ($this->functions as $f=>$t) {
$pdo->sqliteCreateFunction($f, array($this, $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',
//'date'=>'date',
'isnull' => 'isnull',
'if' => '_if',
'regexpp' => 'regexp',
'concat' => 'concat',
'field' => 'field',
'log' => 'log',
'least' => 'least',
'get_lock' => 'get_lock',
'release_lock' => 'release_lock',
'ucase' => 'ucase',
'lcase' => 'lcase',
'inet_ntoa' => 'inet_ntoa',
'inet_aton' => 'inet_aton',
'datediff' => 'datediff'
);
public function month($field){
$t = strtotime($field);
return date('n', $t);
}
public function year($field){
$t = strtotime($field);
return date('Y', $t);
}
public function day($field){
$t = strtotime($field);
return date('j', $t);
}
public function unix_timestamp($field = null){
return is_null($field) ? time() : strtotime($field);
}
public function second($field){
$t = strtotime($field);
return intval( date("s", $t) );
}
public function minute($field){
$t = strtotime($field);
return intval(date("i", $t));
}
public function hour($time){
list($hours, $minutes, $seconds) = explode(":", $time);
return intval($hours);
}
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);
}
public function now(){
return date("Y-m-d H:i:s");
}
public function curdate() {
return date("Y-m-d");
}
public function char_length($field){
return strlen($field);
}
public function md5($field){
return md5($field);
}
public function rand(){
return rand(0,1);
}
public function substring($text, $pos, $len=null){
if (is_null($len)) return substr($text, $pos-1);
else return substr($text, $pos-1, $len);
}
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;
}
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;
}
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;
}
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":
case "minute":
case "hour":
case "day":
case "week":
case "month":
case "year":
if (intval($_parts[0]) > 1){
$type .= 's';
}
return "$_parts[0] $_parts[1]";
break;
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;
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;
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;
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;
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;
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;
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;
}
}
public function date($date){
return date("Y-m-d", strtotime($date));
}
public function isnull($field){
return is_null($field);
}
public function _if($expression, $true, $false){
return ($expression == true) ? $true : $false;
}
public function regexp($field, $pattern){
$pattern = str_replace('/', '\/', $pattern);
$pattern = "/" . $pattern ."/i";
return preg_match ($pattern, $field);
}
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 field() {
$numArgs = func_num_args();
if ($numArgs < 2 or is_null(func_get_arg(0))) {
return null;
}
$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 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 false;
}
}
public function least() {
$arr = func_get_args();
return min($arr);
}
/**
* These two functions are meaningless in SQLite
* So we return meaningless statement and do nothing
* @param string $name
* @param integer $timeout
* @return string
*/
public function get_lock($name, $timeout) {
return '1=1';
}
public function release_lock($name) {
return '1=1';
}
/**
* MySQL aliases for upper and lower functions
* @param unknown $string
* @return string
*/
public function ucase($string) {
return "upper($string)";
}
public function lcase($string) {
return "lower($string)";
}
/**
* MySQL aliases for INET_NTOA and INET_ATON functions
* @param unsigned integer, string respectively
* @return string, unsigned integer respectively
*/
public function inet_ntoa($num) {
return long2ip($num);
}
public function inet_aton($addr) {
$int_data = ip2long($addr);
$unsigned_int_data = sprintf('%u', $address);
return $unsigned_int_data;
}
/**
* MySQL aliase for DATEDIFF function
* @param string, string
* @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;
}
}
?>

344
functions.php Normal file
View File

@ -0,0 +1,344 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
/**
* This class defines user defined functions(UDFs) for PDO
* This replaces the functions used in the SQL statement with the PHP functions.
* If you want another, add the name in the array and define the function with
* PHP script.
*/
class PDOSQLiteUDFS {
public function __construct(&$pdo){
foreach ($this->functions as $f=>$t) {
$pdo->sqliteCreateFunction($f, array($this, $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',
//'date'=>'date',
'isnull' => 'isnull',
'if' => '_if',
'regexpp' => 'regexp',
'concat' => 'concat',
'field' => 'field',
'log' => 'log',
'least' => 'least',
'replace' => 'replace',
'get_lock' => 'get_lock',
'release_lock' => 'release_lock',
'ucase' => 'ucase',
'lcase' => 'lcase',
'inet_ntoa' => 'inet_ntoa',
'inet_aton' => 'inet_aton',
'datediff' => 'datediff'
);
public function month($field){
$t = strtotime($field);
return date('n', $t);
}
public function year($field){
$t = strtotime($field);
return date('Y', $t);
}
public function day($field){
$t = strtotime($field);
return date('j', $t);
}
public function unix_timestamp($field = null){
return is_null($field) ? time() : strtotime($field);
}
public function second($field){
$t = strtotime($field);
return intval( date("s", $t) );
}
public function minute($field){
$t = strtotime($field);
return intval(date("i", $t));
}
public function hour($time){
list($hours, $minutes, $seconds) = explode(":", $time);
return intval($hours);
}
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);
}
public function now(){
return date("Y-m-d H:i:s");
}
public function curdate() {
return date("Y-m-d");
}
public function char_length($field){
return strlen($field);
}
public function md5($field){
return md5($field);
}
public function rand(){
return rand(0,1);
}
public function substring($text, $pos, $len=null){
if (is_null($len)) return substr($text, $pos-1);
else return substr($text, $pos-1, $len);
}
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;
}
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;
}
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;
}
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;
}
}
public function date($date){
return date("Y-m-d", strtotime($date));
}
public function isnull($field){
return is_null($field);
}
public function _if($expression, $true, $false){
return ($expression == true) ? $true : $false;
}
public function regexp($field, $pattern){
$pattern = str_replace('/', '\/', $pattern);
$pattern = "/" . $pattern ."/i";
return preg_match ($pattern, $field);
}
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 field() {
$numArgs = func_num_args();
if ($numArgs < 2 or is_null(func_get_arg(0))) {
return null;
}
$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 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 false;
}
}
public function least() {
$arr = func_get_args();
return min($arr);
}
public function replace($haystack, $needle, $replace) {
return str_replace($needle, $replace, $haystack);
}
/**
* These two functions are meaningless in SQLite
* So we return meaningless statement and do nothing
* @param string $name
* @param integer $timeout
* @return string
*/
public function get_lock($name, $timeout) {
return '1=1';
}
public function release_lock($name) {
return '1=1';
}
/**
* MySQL aliases for upper and lower functions
* @param $string
* @return string
*/
public function ucase($string) {
return "upper($string)";
}
public function lcase($string) {
return "lower($string)";
}
/**
* MySQL aliases for INET_NTOA and INET_ATON functions
* @param unsigned integer, string respectively
* @return string, unsigned integer respectively
*/
public function inet_ntoa($num) {
return long2ip($num);
}
public function inet_aton($addr) {
$int_data = ip2long($addr);
$unsigned_int_data = sprintf('%u', $address);
return $unsigned_int_data;
}
/**
* MySQL aliase for DATEDIFF function
* @param string, string
* @return string
*/
public function datediff($start, $end) {
/* PHP 5.3.2 has a serious bug in DateTime::diff()
* see https://bugs.php.net/bug.php?id=51184
*/
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');
}
}
}
?>

63
install.php Normal file
View File

@ -0,0 +1,63 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
/**
* This function overrides wp_install() in wp-admin/upgrade.php
*/
function wp_install($blog_title, $user_name, $user_email, $public, $deprecated = '', $user_password = '') {
if (!empty($deprecated))
_deprecated_argument(__FUNCTION__, '2.6');
wp_check_mysql_version();
wp_cache_flush();
/* changes */
require_once PDODIR . 'schema.php';
make_db_sqlite();
/* changes */
populate_options();
populate_roles();
update_option('blogname', $blog_title);
update_option('admin_email', $user_email);
update_option('blog_public', $public);
$guessurl = wp_guess_url();
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 = __('<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> 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 = '<em>'.__('Your chosen password.').'</em>';
$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();
return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message);
}
?>

101
js/sqlite.js Normal file
View File

@ -0,0 +1,101 @@
/*
* script for SQLite Integration
* this file is only included on the documentation page and the utilities page
*/
jQuery(document).ready(function($) {
var $table = null;
var $headers = null;
if (document.getElementById("sqlite-table") != null) {
$table = $('#sqlite-table');
$headers = $table.find('thead th').slice(0,2);
} else if (document.getElementById("plugins-table") != null) {
$table = $('#plugins-table');
$headers = $table.find('thead th').slice(0);
} else if (document.getElementById("patch-files") != null) {
$table = $('#patch-files');
$headers = $table.find('thead th').slice(1);
}
$headers
.wrapInner('<a href="#"></a>')
.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;
if ($header.hasClass('sorted-asc')) {
sortDirection = -1;
}
rows.sort(function(a, b) {
var keyA = $(a).data('table')[sortKey];
var keyB = $(b).data('table')[sortKey];
if (keyA < keyB) return -sortDirection;
if (keyA > keyB) return sortDirection;
return 0;
});
$headers.removeClass('sorted-asc sortd-desc');
$headers.addClass(sortDirection == 1 ? 'sorted-asc' : 'sorted-desc');
$.each(rows, function(index, row) {
$table.children('tbody').append(row);
});
stripe('#plugins-table');
stripe('#sqlite-table');
stripe('#patch-files');
});
function stripe(arg) {
$(arg).find('tr.alt').removeClass('alt');
var $args = arg + ' tbody';
$($args).each(function() {
$(this).children(':visible').has('td').filter(function(index) {
return (index % 2) == 1;
}).addClass('alt');
});
}
stripe('#plugins-table');
stripe('#sys-info');
stripe('#sqlite-table');
stripe('#status');
stripe('#patch-files');
});
jQuery(document).ready(function($) {
var $table = $('#plugins-info');
var $headers = $table.find('thead th').slice(0);
$headers
.wrapInner('<a href="#"></a>')
.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;
if ($header.hasClass('sorted-asc')) {
sortDirection = -1;
}
rows.sort(function(a, b) {
var keyA = $(a).data('table')[sortKey];
var keyB = $(b).data('table')[sortKey];
if (keyA < keyB) return -sortDirection;
if (keyA > keyB) return sortDirection;
return 0;
});
$headers.removeClass('sorted-asc sortd-desc');
$headers.addClass(sortDirection == 1 ? 'sorted-asc' : 'sorted-desc');
$.each(rows, function(index, row) {
$table.children('tbody').append(row);
});
stripe('#plugins-info');
});
function stripe(arg) {
$(arg).find('tr.alt').removeClass('alt');
var $args = arg + ' tbody';
$($args).each(function() {
$(this).children(':visible').has('td').filter(function(index) {
return (index % 2) == 1;
}).addClass('alt');
});
}
stripe('#plugins-info');
});

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

240
pdodb.class.php Normal file
View File

@ -0,0 +1,240 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
require_once PDODIR . 'pdoengine.class.php';
require_once PDODIR . 'install.php';
if (!defined('SAVEQUERIES')){
define ('SAVEQUERIES', false);
}
if(!defined('PDO_DEBUG')){
define('PDO_DEBUG', false);
}
if (!isset($wpdb)){
global $wpdb;
$wpdb = 'somevar';
require_once ABSPATH . 'wp-includes/wp-db.php';
unset($wpdb);
}
/**
* This class extends wpdb and replaces it.
* It also rewrites some functions that use mysql specific functions.
*
*/
class PDODB extends wpdb {
protected $dbh = null;
/**
* Constructor: emulates wpdb but this gets another parameter $db_type,
* which is given by the constant 'DB_TYPE' defined in wp-config.php.
* SQLite uses only $db_type and all the others are simply ignored.
*
*/
function __construct() {
register_shutdown_function(array($this, '__destruct'));
if (WP_DEBUG)
$this->show_errors();
$this->init_charset();
$this->db_connect();
}
function __destruct() {
return true;
}
/**
* dummy out the MySQL function
* @see wpdb::select()
*/
function select($db, $dbh = null) {
if (is_null($dbh))
$dbh = $this->dbh;
$this->ready = true;
return;
}
/**
* overrides wpdb::_real_escape(), which uses mysql_real_escape_string().
* @see wpdb::_real_escape()
*/
function _real_escape($string) {
if ($this->dbh && $this->real_escape)
return $this->dbh->quote($string);
else
return addslashes($string);
}
/**
* overrides wpdb::print_error()
* @see wpdb::print_error()
*/
function print_error($str = '') {
global $EZSQL_ERROR;
if (!$str) {
$err = $this->dbh->get_error_message() ? $this->dbh->get_error_message() : '';
$str = $err[2];
}
$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 "<div id='error'>
<p class='wpdberror'><strong>WordPress database error:</strong> [$str]<br />
<code>$query</code></p>
</div>";
}
}
/**
* overrides wpdb::db_connect()
* @see wpdb::db_connect()
*/
function db_connect() {
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(__("<h1>Error establlishing a database connection</h1><p>We have been unable to connect to the specified database. <br />The error message received was %s"), $this->dbh->errorInfo()));
return;
}
$this->ready = true;
}
/**
* overrides wpdb::query()
* @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;
}
/**
* overrides wpdb::load_col_info(), which uses a mysql function.
* @see wpdb::load_col_info()
*/
function load_col_info() {
if ($this->col_info)
return;
$this->col_info = $this->dbh->get_columns();
}
/**
* overrides wpdb::has_cap()
* We don't support collation, group_concat, 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;
}
}
/**
* overrides wpdb::db_version()
* Returns mysql version number but it means nothing for SQLite.
* @see wpdb::db_version()
*/
function db_version() {
global $required_mysql_version;
return $required_mysql_version;
}
}
/**
* Initialize $wpdb with PDODB class
*/
if (!isset($wpdb)) {
global $wpdb;
$wpdb = new PDODB();
}
?>

898
pdoengine.class.php Normal file
View File

@ -0,0 +1,898 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
/**
* This class does the real work
* accepts a request from wpdb class, initialize PDO instance,
* execute SQL statement, and returns the results to wpdb class.
*/
class PDOEngine extends PDO {
public $is_error = false;
public $found_rows_result;
private $rewritten_query;
private $query_type;
private $results = null;
private $_results = null;
private $pdo;
private $prepared_query;
private $extracted_variables = array();
private $error_messages = array();
private $errors;
public $queries = array();
private $last_insert_id;
private $affected_rows;
private $column_names;
private $num_rows;
private $return_value;
private $can_insert_multiple_rows = false;
private $param_num;
protected $has_active_transaction = false;
/**
* Constructor
* registers __destruct function and initialize the database environment
* @param array $DatabaseParams
*/
function __construct() {
register_shutdown_function(array($this, '__destruct'));
$this->init();
}
function __destruct() {
$this->pdo = null;
return true;
}
/**
* Function to initialize database
* 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!<br />", 'sqlite-integration');
$message .= sprintf(__("Error message is: ", 'sqlite-integration'), $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 connection error!<br />", 'sqlite-integration');
$message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err->getMessage());
$this->set_error(__LINE__, __FUNCTION__, $message);
return false;
}
$this->make_sqlite_tables();
}
}
/**
* Make database direcotry and .htaccess file
* executed once while installation process
*/
private function prepare_directory() {
global $wpdb;
$u = umask(0000);
if (!is_dir(FQDBDIR)) {
if (!@mkdir(FQDBDIR, 0777, true)) {
umask($u);
$message = __('Unable to create the required directory! Please check your server settings.', 'sqlite-integration');
echo $message;
return false;
}
}
if (!is_writable(FQDBDIR)) {
umask($u);
$message = __('Unable to create a file in the directory! Please check your server settings.', 'sqlite-integration');
echo $message;
return false;
}
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.', 'sqlite-integration');
echo $message;
return false;
}
fwrite($fh, "DENY FROM ALL");
fclose($fh);
}
umask($u);
return true;
}
/**
* Make database file itself and WordPress tables
* executed once while installation process
*/
private function make_sqlite_tables() {
require_once PDODIR . "install.php";
}
public function query($query) {
$this->flush();
$this->queries[] = "Raw query:\t$query";
$res = $this->determine_query_type($query);
if (!$res) {
$bailoutString = sprintf(__("<h1>Unknown query type</h1><p>Sorry, we cannot determine the type of query that is requested.</p><p>The query is %s</p>", 'sqlite-integration'), $query);
$this->set_error(__LINE__, __FUNCTION__, $bailoutString);
}
switch (strtolower($this->query_type)) {
case 'foundrows':
$this->results = $this->found_rows_result;
$this->num_rows = count($this->results);
$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;
default:
$engine = $this->prepare_engine($this->query_type);
$this->rewritten_query = $engine->rewrite_query($query, $this->query_type);
$this->queries[] = "Rewritten: $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(), FLIE_APPEND);
}
return $this->return_value;
}
public function get_insert_id() {
return $this->last_insert_id;
}
public function get_affected_rows() {
return $this->affected_rows;
}
public function get_columns() {
return $this->column_names;
}
public function get_query_results() {
return $this->results;
}
public function get_num_rows() {
return $this->num_rows;
}
public function get_return_value() {
return $this->return_value;
}
public function get_error_message(){
if (count($this->error_messages) === 0){
$this->is_error = false;
$this->error_messages = array();
return '';
}
$output = '<div style="clear:both">&nbsp;</div>';
if ($this->is_error === false){
// return $output;
return '';
}
$output .= "<div class=\"queries\" style=\"clear:both; margin_bottom:2px; border: red dotted thin;\">Queries made or created this session were<br/>\r\n\t<ol>\r\n";
foreach ($this->queries as $q){
$output .= "\t\t<li>".$q."</li>\r\n";
}
$output .= "\t</ol>\r\n</div>";
foreach ($this->error_messages as $num=>$m){
$output .= "<div style=\"clear:both; margin_bottom:2px; border: red dotted thin;\" class=\"error_message\" style=\"border-bottom:dotted blue thin;\">Error occurred at line {$this->errors[$num]['line']} in Function {$this->errors[$num]['function']}. <br/> Error message was: $m </div>";
}
ob_start();
debug_print_backtrace();
$output .= "<pre>" . ob_get_contents() . "</pre>";
ob_end_clean();
return $output;
}
private function get_debug_info(){
$output = '';
foreach ($this->queries as $q){
$output .= $q ."\r\n";
}
return $output;
}
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_names = 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;
}
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;
}
private function prepare_query(){
$this->queries[] = "Prepare:\t". $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();
}
} while (5 == $reason || 6 == $reason);
if ($reason > 0){
$err_message = sprintf(__("Problem preparing the PDO SQL Statement. Error was: %s", 'sqlite-integration'), $message);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
}
return $statement;
}
private function execute_query($statement) {
$reason = 0;
$message = '';
if (!is_object($statement))
return;
if (count($this->extracted_variables) > 0) {
$this->queries[] = "Executing: ". var_export($this->extracted_variables, true);
do {
if ($this->query_type == 'update' || $this->query_type == 'replace') {
try {
$this->beginTransaction();
$statement->execute($this->extracted_variables);
$this->commit();
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
$this->rollBack();
}
} else {
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)\t ";
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 {
try {
$statement->execute();
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
}
}
} while (5 == $reason || 6 == $reason);
}
if ($reason > 0) {
$err_message = sprintf(__("Error while executing query! Error message was: %s", 'sqlite-integration'), $message);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
return false;
} else {
$this->_results = $statement->fetchAll(PDO::FETCH_OBJ);
}
//generate the results that $wpdb will want to see
switch ($this->query_type) {
case "insert":
case "update":
case "replace":
$this->last_insert_id = $this->pdo->lastInsertId();
$this->affected_rows = $statement->rowCount();
$this->return_value = $this->affected_rows;
break;
case "select":
case "show":
case "showcolumns":
case "showindex":
case "describe":
case "desc":
// case "foundrows":
$this->num_rows = count($this->_results);
$this->return_value = $this->num_rows;
break;
case "delete":
$this->affected_rows = $statement->rowCount();
$this->return_value = $this->affected_rows;
break;
case "alter":
case "drop":
case "create":
case "optimize":
case "truncate":
if ($this->is_error) {
$this->return_value = false;
} else {
$this->return_value = true;
}
break;
}
}
private function extract_variables() {
if ($this->query_type == 'create') {
$this->prepared_query = $this->rewritten_query;
return;
}
//long queries can really kill this
$pattern = '/(?<!\\\\)([\'"])(.*?)(?<!\\\\)\\1/imsx';
$_limit = $limit = ini_get('pcre.backtrack_limit');
do {
if ($limit > 10000000) {
$message = __("The query is too big to parse properly", 'sqlite-integration');
$this->set_error(__LINE__, __FUNCTION__, $message);
break; //no point in continuing execution, would get into a loop
} else {
ini_set('pcre.backtrack_limit', $limit);
$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: $query ";
$this->prepared_query = $query;
}
private function replace_variables_with_placeholders($matches) {
//remove the wordpress escaping mechanism
$param = stripslashes($matches[0]);
//remove trailing spaces
$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
}
if (in_array($param{0}, array("'",'"'))) {
$param = substr($param, 1); //start
}
//$this->extracted_variables[] = $param;
$key = ':param_'.$this->param_num++;
$this->extracted_variables[] = $param;
//return the placeholder
//return ' ? ';
return ' '.$key.' ';
}
/**
* takes the query string ,determines the type and returns the type string
* if the query is the type PDO for Wordpress can't executes, returns false
* @param string $query
* @return boolean|string
*/
private function determine_query_type($query) {
$result = preg_match('/^\\s*(EXPLAIN|PRAGMA|SELECT\\s*FOUND_ROWS|SELECT|INSERT|UPDATE|REPLACE|DELETE|ALTER|CREATE|DROP|SHOW\\s*\\w+\\s*\\w+\\s*|DESCRIBE|DESC|TRUNCATE|OPTIMIZE)/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 tables') !== false) {
$this->query_type = 'show';
} elseif (stripos($this->query_type, 'show columns') !== false || stripos($this->query_type, 'show fields') !== 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;
}
}
return true;
}
/**
* SQLite version 3.7.11 began 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: $this->rewritten_query";
$this->extract_variables();
$statement = $this->prepare_query();
$this->execute_query($statement);
}
/**
* executes the INSERT query for SQLite version 3.7.10 or lesser
* @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: $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: $this->rewritten_query";
$this->extract_variables();
$statement = $this->prepare_query();
$this->execute_query($statement);
}
}
/**
* helper function for execute_insert_query()
* @param string $values
* @return array
*/
private function parse_multiple_inserts($values) {
$tokens = preg_split("/(''|(?<!\\\\)'|(?<!\()\),(?=\s*\())/s", $values, -1, PREG_SPLIT_DELIM_CAPTURE);
$exploded_parts = array();
$part = '';
$literal = false;
foreach ($tokens as $token) {
switch ($token) {
case "),":
if (!$literal) {
$exploded_parts[] = $part;
$part = '';
} else {
$part .= $token;
}
break;
case "'":
if ($literal) {
$literal = false;
} else {
$literal = true;
}
$part .= $token;
break;
default:
$part .= $token;
break;
}
}
if (!empty($part)) {
$exploded_parts[] = $part;
}
return $exploded_parts;
}
/**
* function to execute CREATE query
* @param string
* @return boolean
*/
private function execute_create_query($query) {
$engine = $this->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:\t" . $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", 'sqlite-integration'), $message);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
return false;
}
return true;
}
/**
* function 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 = '';
$rewritten_query = $engine->rewrite_query($query, $this->query_type);
try {
$this->beginTransaction();
if (is_array($rewritten_query)) {
foreach ($rewritten_query as $single_query) {
$this->queries[] = "Executing:\t" . $single_query;
$single_query = trim($single_query);
if (empty($single_query)) continue;
$this->pdo->exec($single_query);
}
} else {
$this->queries[] = "Executing:\t" . $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 ($reason > 0) {
$err_message = sprintf(__("Problem in executing alter query. Error was: %s", 'sqlite-integration'), $message);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
return false;
}
return true;
}
/**
* function to execute SHOW VARIABLES query
*
* This query is meaningless for SQLite. This function returns null data and
* avoid 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;
}
$_results[] = new ObjectArray($dummy_data);
$this->results = $_results;
$this->num_rows = count($this->results);
$this->return_value = $this->num_rows;
return true;
}
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();
} else {
$this->results = $this->_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 that takes the associative array of query results and creates a numeric array of anonymous objects
*/
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 rewrite pragma results to mysql compatible array
* when query_type is describe, we use sqlite pragma function.
* see pdo_sqlite_driver.php
*/
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;
}
/**
* rewrites the result of SHOW INDEX to the Object compatible with MySQL
*/
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);
}
}
$this->results = $_results;
}
/**
* function to get SQLite library version
* this is used for checking if SQLite can execute multiple rows insert
* @return version number string or 0
*/
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';
}
}
/**
* function call to PDO::beginTransaction()
* @see PDO::beginTransaction()
*/
public function beginTransaction() {
if ($this->has_active_transaction) {
return false;
} else {
$this->has_active_transaction = $this->pdo->beginTransaction();
return $this->has_active_transaction;
}
}
/**
* function call to PDO::commit()
* @see PDO::commit()
*/
public function commit() {
$this->pdo->commit();
$this->has_active_transaction = false;
}
/**
* function call to PDO::rollBack()
* @see PDO::rollBack()
*/
public function rollBack() {
$this->pdo->rollBack();
$this->has_active_transaction = false;
}
}
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;
}
}
}
}
?>

526
query.class.php Normal file
View File

@ -0,0 +1,526 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*/
/**
* base class for sql rewriting except CREATE, ALTER TABLE
*/
class PDOSQLiteDriver {
//required variables
public $query_type = '';
public $_query = '';
/**
* function to determin which functions to use
* @param strin $query
* @param string $query_type
* @return string
*/
public function rewrite_query($query, $query_type){
$this->query_type = $query_type;
$this->_query = $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();
break;
case 'insert':
$this->_strip_backticks();
$this->_execute_duplicate_key_update();
$this->_rewrite_insert_ignore();
$this->_rewrite_regexp();
break;
case 'update':
$this->_strip_backticks();
$this->_rewrite_update_ignore();
// $this->_rewrite_date_sub();
$this->_rewrite_limit_usage();
$this->_rewrite_order_by_usage();
$this->_rewrite_regexp();
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->_strip_backticks();
$this->_rewrite_date_sub();
$this->_rewrite_regexp();
break;
case 'optimize':
$this->_rewrite_optimize();
break;
default:
}
return $this->_query;
}
/**
* method to dummy the SHOW TABLES query
*/
private function _handle_show_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]);
}
if (!empty($table_name)) {
$suffix = ' AND name LIKE '. "'" . $table_name . "'";
} else {
$suffix = '';
}
$this->_query = "SELECT name FROM sqlite_master WHERE type='table'" . $suffix . ' ORDER BY name DESC';
}
/**
* method to strip all column qualifiers (backticks) from a query
*/
private function _strip_backticks(){
$this->_query = str_replace('`', '', $this->_query);
}
/**
* method to emulate the SQL_CALC_FOUND_ROWS placeholder for mysql
*
* this is a kind of tricky play.
* 1. remove SQL_CALC_FOUND_ROWS option, and give it to the pdo engine
* 2. make another $wpdb instance, and execute SELECT COUNT(*) query
* 3. give the returned value to the original instance variable
*
* when SQL statement contains GROUP BY option, SELECT COUNT query doesn't
* go well. So we remove the GROUP BY, which means the returned value may
* be a approximate one.
*
* this kind of statement is required for WordPress to calculate the paging.
* see also WP_Query class in wp-includes/query.php
*/
private function _handle_sql_count(){
if (stripos($this->_query, 'SELECT SQL_CALC_FOUND_ROWS') !== false){
global $wpdb;
// first strip the code. this is the end of rewriting process
$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('/\\bFALSE\\s*.*/imsx', '0', $unlimited_query);
$unlimited_query = preg_replace('/\\bGROUP\\s*BY\\s*.*/imsx', '', $unlimited_query);
$unlimited_query = $this->__transform_to_count($unlimited_query);
$_wpdb = new PDODB();
$result = $_wpdb->query($unlimited_query);
$wpdb->dbh->found_rows_result = $_wpdb->last_result;
}
}
/**
* transforms a select query to a select count(*)
*
* @param string $query the query to be transformed
* @return string the transformed query
*/
private function __transform_to_count($query){
$pattern = '/^\\s*SELECT\\s*(DISTINCT|)?.*?FROM\b/imsx';
$_query = preg_replace($pattern, 'SELECT \\1 COUNT(*) FROM ', $query);
return $_query;
}
/**
* rewrites the insert ignore phrase for sqlite
*/
private function _rewrite_insert_ignore(){
$this->_query = str_ireplace('INSERT IGNORE', 'INSERT OR IGNORE ', $this->_query);
}
/**
* rewrites the update ignore phrase for sqlite
*/
private function _rewrite_update_ignore(){
$this->_query = str_ireplace('UPDATE IGNORE', 'UPDATE OR IGNORE ', $this->_query);
}
/**
* rewrites the date_add function for udf to manipulate
*/
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);
}
}
/**
* rewrite the data_sub function for udf to manipulate
*/
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);
}
}
/**
* handles the create query
* this function won't be used... See PDOEngine class
*/
private function _handle_create_query(){
require_once PDODIR.'query_create.class.php';
$engine = new CreateQuery();
$this->_query = $engine->rewrite_query($this->_query);
$engine = null;
}
/**
* handles the ALTER query
* this function won't be used... See PDOEngine class
*/
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;
}
/**
* handles DESCRIBE or DESC query
* this is required in the WordPress install process
*/
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)";
}
}
/**
* 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.
*/
private function _rewrite_limit_usage(){
if (stripos($this->_query, '(select') === false) {
$this->_query = preg_replace('/\\s*LIMIT\\s*[0-9]$/i', '', $this->_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.
*/
private function _rewrite_order_by_usage() {
if (stripos($this->_query, '(select') === false) {
$this->_query = preg_replace('/\\s*ORDER\\s*BY\\s*.*$/i', '', $this->_query);
}
}
private function _handle_truncate_query(){
$pattern = '/TRUNCATE TABLE (.*)/im';
$this->_query = preg_replace($pattern, 'DELETE FROM $1', $this->_query);
}
/**
* rewrites use of Optimize queries in mysql for sqlite.
* table name is ignored.
*/
private function _rewrite_optimize(){
$this->_query ="VACUUM";
}
/**
* 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
*/
private function _rewrite_badly_formed_dates(){
$pattern = '/([12]\d{3,}-\d{2}-)(\d )/ims';
$this->_query = preg_replace($pattern, '${1}0$2', $this->_query);
}
/**
* function to remove unsupported index hinting from mysql queries
*
* @return void
*/
private function _delete_index_hints(){
$pattern = '/use\s+index\s*\(.*?\)/i';
$this->_query = preg_replace($pattern, '', $this->_query);
}
/**
* Justin Adie says:
* method to fix inconsistent use of quoted, unquoted etc date values in query function
* this is ironic, given the above rewrite badlyformed dates method
* examples
* where month(fieldname)=08 becomes month(fieldname)='8'
* where month(fieldname)='08' becomes month(fieldname)='8'
*
* I don't understand...
*
* @return void
*/
private function _fix_date_quoting(){
$pattern = '/(month|year|second|day|minute|hour|dayofmonth)\s*\((.*?)\)\s*=\s*["\']?(\d{1,4})[\'"]?\s*/ei';
$this->_query = preg_replace($pattern, "'\\1(\\2)=\'' . intval('\\3') . '\' ' ", $this->_query);
}
private function _rewrite_regexp(){
$pattern = '/\s([^\s]*)\s*regexp\s*(\'.*?\')/im';
$this->_query = preg_replace($pattern, ' regexpp(\1, \2)', $this->_query);
}
/**
* rewrites boolean to numeral
* SQLite doesn't support true/false type
*/
private function _rewrite_boolean() {
$query = str_ireplace('TRUE', "1", $this->_query);
$query = str_ireplace('FALSE', "0", $query);
$this->_query = $query;
}
/**
* method to execute SHOW COLUMNS query
*/
private function _handle_show_columns_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 execute SHOW INDEX query
*/
private function _handle_show_index() {
$_columns = array(// No, you'll get no meaningful information..
'Key_name' => 'name',
);
$pattern_0 = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?\\s*WHERE\\s*(.*)$/im';
$pattern_1 = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im';
if (preg_match($pattern_0, $this->_query, $match_0)) {
$table_name = str_replace("'", '', $match_0[1]);
list($key, $value) = explode('=', $match_0[2]);
$key = trim($key);
$value = preg_replace("/[\';]/", '', $value);
$value = trim($value);
if (array_key_exists($key, $_columns)) {
$key = $_columns[$key];
$where_clause = 'AND ' . $key . ' LIKE ' . "'" . $value . "%'";
} else {
$where_clause = '';
}
$this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name' $where_clause";
} elseif (preg_match($pattern_1, $this->_query, $match_1)) {
$table_name = preg_replace("/[\';]/", '', $match_1[1]);
$table_name = trim($table_name);
$this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name'";
}
}
/**
* function to rewrite ON DUPLICATE KEY UPDATE statement
* I use SELECT query and check if INSERT is allowed or not
* Rewriting procedure looks like a detour, but I've got another way.
*
* @return void
*/
private function _execute_duplicate_key_update() {
$update = false;
$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*\((.*)\)$/im', $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 {
// wordaround...
$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;
}
}
/**
* workaround function to avoid DELETE with JOIN
* 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.
*/
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";
$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;
}
}
}
?>

453
query_alter.class.php Normal file
View File

@ -0,0 +1,453 @@
<?php
/**
* The class for manipulating ALTER query
* newly supports multiple variants
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu
*/
class AlterQuery {
public $_query = null;
public function rewrite_query($query, $query_type) {
$tokens = array();
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)) {
$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);
foreach ($command_array as $single_command) {
$command_tokens = $this->command_tokenizer($single_command);
if (!empty($command_tokens)) {
$tokens[] = array_merge($tmp_tokens, $command_tokens);
} else {
$this->_query = 'SELECT 1=1';
}
}
foreach ($tokens as $token) {
$command_name = $token['command'];
switch ($command_name) {
case 'add column': case 'rename to': case 'add index': case 'drop index':
$this->_query = $this->handle_single_command($token);
break;
case 'add primary key':
$this->_query = $this->handle_add_primary_key($token);
break;
case 'drop primary key':
$this->_query = $this->handle_drop_primary_key($token);
break;
case 'modify column':
$this->_query = $this->handle_modify_command($token);
break;
case 'change column':
$this->_query = $this->handle_change_command($token);
break;
case 'alter column':
$this->_query = $this->handle_alter_command($token);
break;
default:
break;
}
}
} else {
$this->_query = 'SELECT 1=1';
}
return $this->_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 = strtolower(trim($match[1]));
$match_2 = strtolower(trim($match[2]));
$match_3 = isset($match[3]) ? strtolower(trim($match[3])) : '';
switch ($match_1) {
case 'add':
if (in_array($match_2, array('fulltext', 'constraint', 'foreign'))) {
break;
} elseif ($match_2 == 'column') {
$tokens['command'] = $match_1.' '.$match_2;
$tokens['column_name'] = $match_3;
$tokens['column_def'] = trim($the_rest);
} elseif ($match_2 == 'primary') {
$tokens['command'] = $match_1.' '.$match_2.' '.$match_3;
$tokens['column_name'] = $the_rest;
} elseif ($match_2 == 'unique') {
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($match_2, array('index', 'key'))) {
$tokens['command'] = $match_1.' '.$match_2;
$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 ($match_2 == 'column') {
$tokens['command'] = $match_1.' '.$match_2;
$tokens['column_name'] = trim($match_3);
} elseif ($match_2 == 'primary') {
$tokens['command'] = $match_1.' '.$match_2.' '.$match_3;
} elseif (in_array($match_2, array('index', 'key'))) {
$tokens['command'] = $match_1.' '.$match_2;
$tokens['index_name'] = $match_3;
} elseif ($match_2 == 'primary') {
$tokens['command'] = $match_1.' '.$match_2.' '.$match_3;
} else {
$tokens['command'] = $match_1.' column';
$tokens['column_name'] = $match_2;
}
break;
case 'rename':
if ($match_2 == 'to') {
$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 ($match_2 == 'column') {
$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':
if ($match_2 == 'column') {
$tokens['command'] = $match_1.' '.$match_2;
$tokens['old_column'] = $match_3;
list($new_col) = preg_split('/\s/s', trim($the_rest), -1, PREG_SPLIT_DELIM_CAPTURE);
$tokens['new_column'] = $new_col;
$col_def = str_ireplace($new_col, '', $the_rest);
$tokens['column_def'] = trim($col_def);
} else {
$tokens['command'] = $match_1.' column';
$tokens['old_column'] = $match_2;
$tokens['new_column'] = $match_3;
$tokens['column_def'] = trim($the_rest);
}
break;
case 'alter':
if ($match_2 == 'column') {
$tokens['command'] = $match_1.' '.$match_2;
$tokens['column_name'] = $match_3;
list($set_or_drop) = explode(' ', $the_rest);
if ($set_or_drop == 'set') {
$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 ($match_3 == 'set') {
$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;
}
}
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;
}
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 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;
}
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;
}
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*{$tokenized_query['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']} {$tokenized_query['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']} {$tokenized_query['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;
}
private function handle_change_command($queries) {
$col_check = false;
$old_fields = '';
$new_fields = '';
$tokenized_query = $queries;
$temp_table = 'temp_'.$tokenized_query['table_name'];
$column_def = $this->convert_field_types($tokenized_query['new_column'], $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 ($col->Field == $tokenized_query['old_column']) $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_replace($tokenized_query['old_column'], $tokenized_query['new_column'], $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 ($tokenized_query['column_def'] == trim($match[1])) {
return 'SELECT 1=1';
} else {
$create_query = preg_replace("/\\b{$tokenized_query['old_column']}\\s*.*?(?=,)/ims", "{$tokenized_query['new_column']} {$tokenized_query['column_def']}", $create_query);
}
} elseif (preg_match("/\\b{$tokenized_query['old_column']}\\s*(.+?)(?=\))/ims", $create_query, $match)) {
if ($tokenized_query['column_def'] == trim($match[1])) {
return 'SELECT 1=1';
} else {
$create_query = preg_replace("/\\b{$tokenized_query['old_column']}\\s*.*?(?=\))/ims", "{$tokenized_query['new_column']} {$tokenized_query['column_def']}", $create_query);
}
}
$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;
}
private function handle_alter_command($queries) {
$tokenized_query = $queries;
$temp_table = 'temp_'.$tokenized_query['table_name'];
if (stripos($tokenized_query['default_command'], 'set') !== false) {
$def_value = $this->convert_field_types($tokenized_query['column_name'], $tokenized_query['default_value']);
$def_value = 'DEFAULT '.$def_value;
} else {
$def_value = '';
}
$_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*.*?)\\s*(DEFAULT\\s*.*)[,)]/im", $create_query, $match)) {
$col_def = trim($match[1]);
$old_default = trim($match[2]);
$create_query = preg_replace("/($col_def)\\s*$old_default/im", "\\1 $def_value", $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;
}
/**
* Change the field definition to SQLite compatible data type.
* @param string $col_name
* @param string $col_def
* @return string
*/
private function convert_field_types($col_name, $col_def){
$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'
);
$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 ($array_types as $o=>$r){
$pattern = "/\\b" . $o . "\\s*(\([^\)]*\))?\\s*/imsx";
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;
}
}
?>

285
query_create.class.php Normal file
View File

@ -0,0 +1,285 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*/
/**
* Provides a class for rewriting create queries
* this class borrows its inspiration from the work done on tikiwiki.
*/
class CreateQuery{
private $_query = '';
private $index_queries = array();
private $_errors = array();
private $table_name = '';
private $has_primary_key = false;
/**
* initialises the object properties
* @param string $query the query being processed
* @return string|array the processed (rewritten) query
*/
public function rewrite_query($query){
$this->_query = $query;
$this->_errors [] = '';
$this->strip_backticks();
$this->get_table_name();
$this->rewrite_comments();
$this->rewrite_field_types();
$this->rewrite_character_set();
$this->rewrite_engine_info();
$this->rewrite_unsigned();
$this->rewrite_autoincrement();
$this->rewrite_primary_key();
$this->rewrite_unique_key();
$this->rewrite_enum();
$this->rewrite_set();
$this->rewrite_key();
$this->add_if_not_exists();
return $this->post_process();
}
/**
* Method for getting the table name from the create query.
* taken from PDO for WordPress
* we don't need 'IF NOT EXISTS', so we changed the pattern.
*/
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';
if (preg_match($pattern, $this->_query, $matches)) {
$this->table_name = trim($matches[1]);
}
}
/**
* Method for changing the field type to SQLite compatible type.
*/
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'
);
foreach ($array_types as $o=>$r){
$pattern = '/\\b(?<!`)'.$o.'\\b\\s*(\([^\)]*\)*)?\\s*/imsx';
$this->_query = preg_replace($pattern, " $r ", $this->_query);
}
}
/**
* Method for stripping the comments from the SQL statement
*/
private function rewrite_comments(){
$this->_query = preg_replace("/# --------------------------------------------------------/","-- ******************************************************",$this->_query);
$this->_query = preg_replace("/#/","--",$this->_query);
}
/**
* Method for stripping the engine and other stuffs
*/
private function rewrite_engine_info(){
$this->_query = preg_replace("/\\s*(TYPE|ENGINE)\\s*=\\s*.*(?<!;)/ims",'',$this->_query);
$this->_query = preg_replace("/ AUTO_INCREMENT\\s*=\\s*[0-9]*/ims",'',$this->_query);
}
/**
* Method for stripping unsigned
*/
private function rewrite_unsigned(){
$this->_query = preg_replace('/\\bunsigned\\b/ims', ' ', $this->_query);
}
/**
* Method for rewriting auto_increment
* if the field type is 'integer primary key', it is automatically autoincremented
*/
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);
if ($count > 0){
$this->has_primary_key = true;
}
}
/**
* Method for rewriting primary key
*/
private function rewrite_primary_key(){
if ($this->has_primary_key) {
$this->_query = preg_replace('/\\bprimary key\\s*\([^\)]*\)/ims', ' ', $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);
}
}
/**
* Method for rewriting unique key
*/
private function rewrite_unique_key(){
$this->_query = preg_replace_callback('/\\bunique key\\b([^\(]*)(\([^\)]*\))/ims', array($this, '_rewrite_unique_key'), $this->_query);
}
/**
* Callback method for rewrite_unique_key
* @param array $matches an array of matches from the Regex
*/
private function _rewrite_unique_key($matches){
$index_name = trim($matches[1]);
$col_name = trim($matches[2]);
$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 = 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
*/
private function rewrite_enum(){
$pattern = '/(,|\))([^,]*)enum\((.*?)\)([^,\)]*)/ims';
$this->_query = preg_replace_callback($pattern, array($this, '_rewrite_enum'), $this->_query);
}
/**
* Method for the callback function rewrite_enum and rewrite_set
*/
private function _rewrite_enum($matches){
$output = $matches[1] . ' ' . $matches[2]. ' TEXT '. $matches[4].' CHECK ('.$matches[2].' IN ('.$matches[3].')) ';
return $output;
}
/**
* Method for rewriting usage of set
* whilst not identical to enum, they are similar and sqlite does not
* support either.
*/
private function rewrite_set(){
$pattern = '/\b(\w)*\bset\\s*\((.*?)\)\\s*(.*?)(,)*/ims';
$this->_query = preg_replace_callback($pattern, array($this, '_rewrite_enum'), $this->_query);
}
/**
* 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
*/
private function rewrite_key(){
$this->_query = preg_replace_callback('/,\\s*(KEY|INDEX)\\s*(\\w+)?\\s*(\(.*(?<!\\d)\))/im', array($this, '_rewrite_key'), $this->_query);
}
/**
* Callback method for rewrite_key
* @param array $matches an array of matches from the Regex
*/
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;
}
}
}
$this->index_queries[] = 'CREATE INDEX '. $index_name . ' ON ' . $tbl_name . $col_name ;
return '';
}
private function _remove_length($match) {
return '';
}
/**
* Method to assemble the main query and index queries into an array
* to be returned to the base class
* @return array
*/
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);
} while ($count > 0);
$return_val[] = $mainquery;
$return_val = array_merge($return_val, $this->index_queries);
return $return_val;
}
/**
* Method to add IF NOT EXISTS to query defs
* sometimes, if upgrade.php is being called, wordpress seems to want to run
* new create queries. this stops the query from throwing an error and halting
* output
*/
private function add_if_not_exists(){
$pattern_table = '/^\\s*CREATE\\s*(TEMP|TEMPORARY)?\\s*TABLE\\s*(IF NOT EXISTS)?\\s*/ims';
$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]);
}
}
/**
* Method to strip back ticks
*/
private function strip_backticks(){
$this->_query = str_replace('`', '', $this->_query);
foreach ($this->index_queries as &$query) {
$query = str_replace('`', '', $query);
}
}
/**
* Method to remove the character set information from within mysql queries
*/
private function rewrite_character_set(){
$pattern_charset = '/\\b(default\\s*character\\s*set|default\\s*charset|character\\s*set)\\s*(?<!\()[^ ]*/im';
$pattern_collate1 = '/\\s*collate\\s*[^ ]*(?=,)/im';
$pattern_collate2 = '/\\s*collate\\s*[^ ]*(?<!;)/im';
$patterns = array($pattern_charset, $pattern_collate1, $pattern_collate2);
$this->_query = preg_replace($patterns, '', $this->_query);
}
}

170
readme-ja.txt Normal file
View File

@ -0,0 +1,170 @@
=== SQLite Integration ===
Contributors: kjmtsh
Plugin Name: SQLite Integration
Plugin URI: http://dogwood.skr.jp/wordpress/sqlite-integration-ja/
Tags: database, SQLite, PDO
Author: Kojima Toshiyasu
Author URI: http://dogwood.skr.jp/
Requires at least: 3.3
Tested up to: 3.5.2
Stable tag: 1.0
License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
SQLite IntegrationはSQLiteでWordPressを使えるようにするプラグインです。
== Description ==
このプラグインは[SQLite](http://www.sqlite.org/)を使ってWordPressを運用するためのものです。MySQLデータベース・サーバを用意する必要はありません。SQLiteは自己完結的で、サーバを必要とせず、トランザクションをサポートしたデータベース・エンジンです。MySQLのようにたくさんの拡張機能を持たないかわりに、小規模から中規模のトラフィックがあるウェブサイトに適しています。
SQLite Integrationはラッパ・プログラムです。WordPressとSQLiteの間に入って、やり取りを中継し、次のように動作します。
1. WordPressからMySQLに発行されるSQLステートメントをインターセプトします
2. それをSQLiteが実行できる形に書き換えます
3. SQLiteに渡します
4. SQLiteから結果を受け取ります
5. 必要なら、WordPressが望む形式にフォーマットしなおします
6. WordPressに結果を返します
WordPressはMySQLと話していると思っていて、背後で何が起こっているかは知りません。実際にはSQLiteと話しているのですが、WordPressはいつもの通り仕事をします。
SQLite Integrationは[PDO for WordPress](http://wordpress.org/extend/plugins/pdo-for-wordpress)プラグインの後継です。後者は残念なことに、もうメンテナンスされていないようです。SQLite IntegrationはPDO for WordPressの基本的なアイディアと構造を借りて、より多くの機能とユーティリティを追加しました。
= Features =
SQLite Integrationは普通の「プラグイン」ではありません。WordPressをインストールするときに使います。そのため、少し準備が必要です。インストールのセクションを参照してください。[SQLite Integration Page](http://dogwood.skr.jp/wordpress/sqlite-integration/)をご覧になると、もっと詳しい説明を読むことができます。
インストールに成功したら、MySQLを使う他のWordPressと同じように使うことができます。オプションとして、管理パネルでこのプラグインを有効化することができます。有効化すると有益な情報と説明を見ることができます。これは必須ではありませんが、お勧めします。
= Backward Compatibility =
現在[PDO for WordPress](http://wordpress.org/extend/plugins/pdo-for-wordpress)をお使いの場合は、データベースを移行することができます。インストールのセクションをご覧ください。
= Support =
下の方法でコンタクトを取ってください。
[Support Forum](http://wordpress.org/support/plugin/sqlite-integration)にポストする。
注意: WordPress.orgはMySQL以外のデータベースを正式にサポートしていません。だから、WordPress.orgからのサポートは得られません。フォーラムに投稿しても、回答を得ることはまずないでしょう。また、パッチをあてたプラグインを使う場合は、そのプラグインの作者からのサポートはないものと思ってください。自分でリスクを負う必要があります。
= Translation =
ドキュメントは英語で書かれています。日本語のカタログファイルと、.potファイルがアーカイブに含まれています。もしあなたの言語に翻訳をしたら、知らせてください。
== Installation ==
このプラグインは他のプラグインとはちがいます。管理パネルのプラグイン・ページでインストールすることはできません。
まず、WordPressのインストールを準備しなければなりません。Codexの[Installing Wordpress ](http://codex.wordpress.org/Installing_WordPress)をご覧ください。
必要要件をチェックし、WordPressのアーカイブを展開したら、wp-config-sample.phpをwp-config.phpにリネームして、[Codex page](http://codex.wordpress.org/Editing_wp-config.php)に書いてあるように、少し編集する必要があります。データベースの設定*以外*の部分を設定してください。
終わったら、オプションの設定を書き加えることができます。次の説明に従ってください。
* デフォルト(wp-content/database)とは違うディレクトリにSQLiteデータベース・ファイルを置きたい場合は、次の行を追加してください(最後のスラッシュを忘れずに)。
`define('DB_DIR', '/home/youraccount/database_directory/');`
注意: PHPスクリプトがこのディレクトリを作ったり、中にファイルを書き込んだりする権限を持っていることが必要です。
* デフォルト(.ht.sqlite)とは違うデータベース・ファイル名を使いたい場合は、次の行を追加してください。
`define('DB_FILE', 'database_file_name');`
注意: PDO for WordPressをお使いの方は、「データベースを移行する」のセクションをご覧ください。
よくわからない場合は、何も追加する必要はありません。
wp-config.phpの準備が終わったら、次のステップに進みます。
1. プラグインのアーカイブを展開します。
2. アーカイブに含まれるdb.phpファイルをwp-contentディレクトリに移動(またはコピー)してください。
3. sqlite-wordpressディレクトリをwp-content/plugin/ディレクトリの下に移動してください。
`wordpress/wp-contents/db.php`
と、
`wordpress/wp-contents/sqlite-integration`
のようになります。
さあ、これでお終いです。ディレクトリの構造をそのままに、あなたのサーバにアップロードして、お好きなブラウザでwp-admin/install.phpにアクセスしてください。WordPressのインストールが始まります。Enjoy blogging!
= Migrate your database to SQLite Integration =
一番よい方法は、次のようにすることです。
1. データをエクスポートする。
2. 最新のWordPressを、SQLite Integrationを使って新規インストールする。
3. WordPress Importerを使って以前のデータをインポートする。
何らかの理由で、データがエクスポートできない場合は、次の方法を試すことができます。
1. あなたのMyBlog.sqliteがWordPressの必要とするテーブルを全て含んでいるかどうかチェックしてください。[SQLite Manager Mozilla Addon](https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/)のようなユーティリティが必要かもしれません。また、Codexの[Database Description](http://codex.wordpress.org/Database_Description)を参照してください。
2. MyBlog.sqliteとdb.phpファイルをバックアップしてください。
3. あなたのMyBlog.sqliteを.ht.sqliteにリネームするか、または、wp-config.phpに次の行を追加してください。
`define('FQDB', 'MyBlog.sqlite');`
4. wp-content/db.phpをSQLite Integrationに含まれている同名のファイルと入れ替えてください。
これでおしまいです。忘れずに必要要件とWordPressのバージョンをチェックしてください。*SQLite IntegrationはWordPress 3.2.x以前のものでは動作しません。*
== Frequently Asked Questions ==
= データベース・ファイルが作られません =
ディレクトリやファイルを作るのに失敗するのは、多くの場合、PHPにその権限がないことが原因です。サーバの設定を確認するか、管理者に聞いてみてください。
= あれこれのプラグインが有効化できません、あるいはちゃんと動作しません =
ある種のプラグイン、特にキャッシュ系のプラグインやデータベース管理系のプラグインはこのプラグインと一緒に使えません。SQLite Integrationを有効化して、ドキュメントの「プラグイン互換性」のセクションをご覧ください。あるいは、[SQLite Integration Plugin Page](http://dogwood.skr.jp/wordpress/plugins/)をご覧ください。
= 管理画面のドキュメントは必要ないのですが =
無効化すればすぐに消えます。有効化と無効化は管理画面の表示・非表示だけで、本体には影響を与えません。プラグインを削除したい場合は、単に削除すれば消えます。
== Screenshots ==
1. システム情報の画面ではデータベースの状態やプラグインの対応状況を見ることができます。
== Requirements ==
* PHP 5.2 以上で PDO extension が必要です(PHP 5.3 以上をお勧めします)。
* PDO SQLite ドライバがロードされている必要があります。
== Known Limitations ==
多くのプラグインはちゃんと動作するはずです。が、中にはそうでないものもあります。一般的には、WordPressの関数を通さず、PHPのMysqlあるいはMysqliライブラリの関数を使ってデータベースを操作しようとするプラグインは問題を起こすでしょう。
他には下のようなものがあります。
= これらのプラグインを使うことはできません。SQLite Integrationと同じファイルを使おうとするからです。 =
* [W3 Total Cache](http://wordpress.org/extend/plugins/w3-total-cache/)
* [DB Cache Reloaded Fix](http://wordpress.org/extend/plugins/db-cache-reloaded-fix/)
* [HyperDB](http://wordpress.org/extend/plugins/hyperdb/)
= これらのプラグインも使えません。SQLiteがエミュレートできないMySQL独自の拡張機能を使っているからです。 =
* [Yet Another Related Posts](http://wordpress.org/extend/plugins/yet-another-related-posts-plugin/)
* [Better Related Posts](http://wordpress.org/extend/plugins/better-related/)
たぶん、もっとあるでしょう。
== Changelog ==
= 1.0 (2013-07-07) =
最初のリリース。
== Upgrade Notice ==
SQLite Integrationのアップグレードに失敗するようなら、FTPを使っての手動アップグレードを試してみてください。

162
readme.txt Normal file
View File

@ -0,0 +1,162 @@
=== SQLite Integration ===
Contributors: kjmtsh
Plugin Name: SQLite Integration
Plugin URI: http://dogwood.skr.jp/wordpress/sqlite-integration/
Tags: database, SQLite, PDO
Author: Kojima Toshiyasu
Author URI: http://dogwood.skr.jp/
Requires at least: 3.3
Tested up to: 3.5.2
Stable tag: 1.0
License: GPLv2
License URI: http://www.gnu.org/licenses/gpl-2.0.html
SQLite Integration is the plugin that enables WordPress to use SQLite. If you want to build a WordPress website with it, this plugin is for you.
== Description ==
This plugin enables WordPress to work with [SQLite](http://www.sqlite.org/). You don't have to prepare MySQL database server and its configuration. SQLite is a self-contained, serverless, transactional SQL database engine. It is not a full-featured database system like MySQL or PostgreSQL, but it best fits for low to medium traffic websites.
SQLite Integration is a kind of wrapper program, which is placed between WordPress and SQLite database and works as a mediator. It works as follows:
1. Intercepts the SQL statement for MySQL from WordPress
2. Rewrites it for SQLite to execute
3. Give it to SQLite
4. Gets the results from SQLite
5. Formats the results as WordPress wants, if necessary
6. Give the results back to WordPress
WordPress thinks she talks with MySQL and doesn't know what has happened in the background. She really talks with SQLite and will be happy with it.
SQLite Integration is a successor to [PDO for WordPress](http://wordpress.org/extend/plugins/pdo-for-wordpress) plugin, which unfortunately enough, doesn't seem to be maintained any more. SQLite Integration uses the basic idea and structures of that plugin and adds some more features or some utilities.
= Features =
SQLite Integration is not an ordinary 'plugin'. It is used to install WordPress itself. You need to do some preparations. Please read the install section. And see more detailed instruction in the [SQLite Integration Page](http://dogwood.skr.jp/wordpress/sqlite-integration).
Once you succeeded in installing WordPress, you can use it just like the others using MySQL. Optionally, you can activate this plugin in the installed plugins panel of the adimn dashboard, and you can see the useful information and instructions. It is not required but I recommend it.
= Backward Compatibility =
If you are using [PDO for WordPress](http://wordpress.org/extend/plugins/pdo-for-wordpress), you can migrate your database. See install section.
= Support =
Please contact us with the methods below:
Post to [Support Forum](http://wordpress.org/support/plugin/sqlite-integration/).
Notes: WordPress.org doesn't officially support using any other database than MySQL. So there will be no supports from WordPress.org. Even if you post to the general Forum, you have few chances to get the answer. And if you use patched plugins, you will have be no support from the plugin authors, eithter.
= Translation =
Documentation is written in English. Japanese catalog file and .pot file are included in the archive. If you translate it into your language, please let me know.
== Installation ==
This plugin is *not* like the other plugins. You can't install and activate it on the plugin administration panel.
First of all, you've got to prepare WordPress installation. See [Installing Wordpress ](http://codex.wordpress.org/Installing_WordPress) section in the Codex.
After checking the prerequisites and unzipping the WordPress archive file, you must rename wp-contig-sample.php file to wp-config.php and do some editting as the [Codex page](http://codex.wordpress.org/Editing_wp-config.php) says. Please follow the instructions *except* the database settings.
When you finish, you can add optional settings. Follow the steps below:
* If you want to put the SQLite database file to the directory different from the default setting (wp-content/database), you can add the line below (don't forget to add a trailing slash):
`define('DB_DIR', '/home/youraccount/database_directory/');`
Note: Your PHP scripts must be able to create that directory and files in it.
* If you want to change the database file name to the one different from the default (.ht.sqlite), you can add the line below:
`define('DB_FILE', 'database_file_name');`
Note: If you are using 'PDO for WordPress' plugin, see also 'Migrating your database' section.
If you don't understand well, you don't have to add any of the lines above.
After you finish preparing wp-config.php, follow the next steps:
1. Unzip the plugin archive file.
2. Move db.php file contained in the archive to wp-content directory.
3. Move the sqlite-integration directory to wp-content/plugin/ directory.
`wordpress/wp-contents/db.php`
and
`wordpress/wp-contents/sqlite-integration`
respectively.
OK. This is all. Upload everything (keeping the directory structure) to your server and access the wp-admin/install.php with your favorite browser, and WordPress installation process will begin. Enjoy your blogging!
= Migrate your database to SQLite Integration =
If you are using PDO for WordPress now, you can migrate your database to SQLite Integration. You don't have to reinstall WordPress. Please follow the next steps:
1. Check if your MyBlog.sqlite file contains all the tables required by WordPress. You have to use a utility software like [SQLite Manager Mozilla Addon](https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/). See also [Database Description](http://codex.wordpress.org/Database_Description) in Codex.
2. Backup your MyBlog.sqlite and db.php files.
3. EITHER rename your MyBlog.sqlite to .ht.sqlite OR add the next line in wp-config.php file.
`define('FQDB', 'MyBlog.sqlite');`
4. Overwrite your wp-content/db.php with the db.php file contained in SQLite Integration archive.
That's all. Don't forget to check the requirement and your WordPress version. *SQLite Integration doesn't work with WordPress version 3.2.x or lesser*.
== Frequently Asked Questions ==
= Database file is not created =
The reason of failure in creating directory or files is often that PHP is not allowed to craete them. Please check your server setting or ask the administrator.
= Such and such plugins can't be activated or doesn't seem to work properly =
Some of the plugins, especially cache plugins or database maintenace plugins, are not compatible with this plugin. Please activate SQLite Integration and see the plugin comatibility section in the documentation or visit the [SQLite Integration Page](http://dogwood.skr.jp/wordpress/sqlite-integration/).
= I don't want the admin menu and documentation =
Just deactivate the plugin, and you can remove them. Activation and deactivation affect only admin menu. If you want to remove all the plugin files, just delete it.
== Screenshots ==
1. System Information tells you your database status and installed plugins compatibility.
== Requirements ==
* PHP 5.2 or newer with PDO extension (PHP 5.3 or newer is better).
* PDO SQLite driver must be loaded.
== Known Limitations ==
Many of the other plugins will work fine with this plugin. But there are some you can't use. Generally speaking, the plugins that manipulate database not with WordPress functions but with Mysql or Mysqli native drivers from PHP might cause the problem.
These are other examples:
= You can't use these plugins because they create the same file that this plugin uses: =
* [W3 Total Cache](http://wordpress.org/extend/plugins/w3-total-cache/)
* [DB Cache Reloaded Fix](http://wordpress.org/extend/plugins/db-cache-reloaded-fix/)
* [HyperDB](http://wordpress.org/extend/plugins/hyperdb/)
= You can't use some of the plugins, because they are using MySQL specific features that SQLite can't emulate. For example: =
* [Yet Another Related Posts](http://wordpress.org/extend/plugins/yet-another-related-posts-plugin/)
* [Better Related Posts](http://wordpress.org/extend/plugins/better-related/)
Probably there are more, I'm afraid.
== Changelog ==
= 1.0 (2013-07-07) =
First release version of the plugin.
== Upgrade Notice ==
When you fail in upgrading SQLite Integration, I recommend that you should try manual upgrade via FTP.

91
schema.php Normal file
View File

@ -0,0 +1,91 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*/
/**
* Function to create tables according to the schemas of WordPress
* This is run only once while installation.
* @return boolean
*/
function make_db_sqlite() {
include_once PDODIR . 'query_create.class.php';
include_once ABSPATH . 'wp-admin/includes/schema.php';
$index_array = array();
ob_end_clean();
$table_schemas = wp_get_db_schema();
$queries = explode (";", $table_schemas);
$query_parser = new CreateQuery();
try {
$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!<br />", 'sqlite-integration');
$message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err_data[2]);
echo $message;
return false;
}
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();
}
} 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...<br />Query was: %s<br />", 'sqlite-integration'), var_export($rewritten_query, true));
$message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err_data[2]);
echo $message;
return false;
}
}
$query_parser = null;
$pdo = null;
return true;
}
?>

BIN
screenshots-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

238
sqlite-integration.php Normal file
View File

@ -0,0 +1,238 @@
<?php
/*
Plugin Name: SQLite Integration
Plugin URI: http://wordpress.org/extend/plugins/sqlite-integration
Description: SQLite Integration is the plugin that enables WordPress to use SQLite. If you don't have MySQL and want to build a WordPress website, it's for you.
Author: Kojima Toshiyasu
Version: 1.0
Author URI: http://dogwood.skr.jp
Text Domain: sqlite-integration
Domain Path: /languages
License: GPL2 or later
*/
/* Copyright 2013 Kojima Toshiyasu (email: kjm@dogwood.skr.jp)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Globals
*/
$siteurl = get_option('siteurl');
define('SQLiteDir', dirname(plugin_basename(__FILE__)));
define('SQLiteFilePath', dirname(__FILE__));
define('SQLiteDirName', basename(SQLiteFilePath));
define('SQLiteUrl', $siteurl . '/wp-content/plugins/' . SQLiteDir);
if (defined('UPLOADS')) {
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');
}
}
define('SQLiteListFile', SQLiteFilePath . '/utilities/plugin_lists.json');
if (!class_exists('SQLiteIntegrationUtils')) {
require_once SQLiteFilePath . '/utilities/utility.php';
$utils = new SQLiteIntegrationUtils();
}
if (!class_exists('SQLiteIntegrationDocument')) {
require_once SQLiteFilePath . '/utilities/documentation.php';
$doc = new SQLiteIntegrationDocument();
}
if (!class_exists('PatchUtils')) {
require_once SQLiteFilePath . '/utilities/patch.php';
$patch_utils = new PatchUtils();
}
/**
* This class is for WordPress Administration Panel
* This class and other utility classes don't affect the base functionality
* of the plugin.
*
* @package SQLite Integration
* @author Kojima Toshiyasu
*
*/
class SQLiteIntegration {
/**
* This constructor does everything needed
*/
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'));
} else {
add_action('admin_menu', array($this, 'add_pages'));
}
add_action('plugins_loaded', array($this, 'textdomain_init'));
}
/**
* Nothing to install
* for future use...
*/
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;
}
}
/**
* Nothing to do...
* We show menu and documents only to the network administrator
*/
function _install() {
}
/**
* Is it better that we remove wp-content/db.php and wp-content/patches
* directory?...
* If you migrate the site to the sever with MySQL, you have only to
* migrate the data in the database.
*/
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);
}
}
/**
* 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.
*/
function add_pages() {
global $utils, $doc, $patch_utils;
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'));
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_doc_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'));
}
}
/**
* Network admin can only see documents and manipulate patch files.
* So, capability is set to manage_network_options.
*/
function add_network_pages() {
global $utils, $doc, $patch_utils;
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'));
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_doc_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'));
}
}
/**
* Japanese catalog is only available
*/
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/');
}
/**
* Styles and JavaScripts
*/
function add_style_sheet() {
$style_url = SQLiteUrl . '/styles/style.css';
$style_file = SQLiteFilePath . '/styles/style.css';
if (file_exists($style_file)) {
wp_enqueue_style('sqlite_integration_stylesheet', $style_url);
}
}
function add_doc_style_sheet() {
$style_url = SQLiteUrl . '/styles/doc.css';
$style_file = SQLiteFilePath . '/styles/doc.css';
if (file_exists($style_file)) {
wp_enqueue_style('sqlite_integration_doc_style', $style_url);
}
}
function add_sqlite_script() {
$script_url = SQLiteUrl . '/js/sqlite.js';
$script_file = SQLiteFilePath . '/js/sqlite.js';
if (file_exists($script_file)) {
wp_enqueue_script('sqlite-integration', $script_url, 'jquery');
}
}
}
/* this is enough for initialization */
new SQLiteIntegration;
?>

141
styles/doc.css Normal file
View File

@ -0,0 +1,141 @@
@CHARSET "UTF-8";
#sqlite-admin-wrap h2,
#sqlite-admin-side-wrap h2 {
background: rgb(73, 90, 88);
background: -moz-linear-gradient(bottom, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.5), rgba(73, 90, 88, 0));
background: -webkit-gradient(linear, bottom, top, from(rgba(73, 90, 88, 1)), color-stop(0.5, rgba(73, 90, 88, 0.5)), to(rgba(73, 90, 88, 0)));
background: linear-gradient(to top, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.2));
color: rgb(247, 254, 236);
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-moz-border-radius-topleft: 6px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
text-shadow: -1px -1px 0 rgb(93, 69, 35),
1px -1px 0 rgb(93, 69, 35),
-1px 1px 0 rgb(93, 69, 35),
1px 1px 0 rgb(93, 69, 35);
padding-left: 5px;
}
.navigation {
display: block;
margin-top: 0;
margin-bottom: 0;
min-height: 20px;
/* border: 1px solid #000; */
}
.navi-menu {
margin-left: 0;
}
.menu-item {
font-size: 20px;
display: inline;
min-width: 150px;
height: 50px;
margin-left: 0;
margin-right: 10px;
padding: 5px;
border: .5px solit #000;
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-moz-border-radius-topleft: 6px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
box-shadow: 5px 5px 5px #eee;
}
.menu-selected {
font-size: 20px;
display: inline;
min-width: 150px;
height: 50px;
margin-left: 0;
margin-right: 10px;
padding: 5px;
border: .5px solit #000;
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-moz-border-radius-topleft: 6px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
box-shadow: 5px 5px 5px #eee;
background: rgb(73, 90, 88);
background: -moz-linear-gradient(bottom, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.5), rgba(73, 90, 88, 0));
background: -webkit-gradient(linear, bottom, top, from(rgba(73, 90, 88, 1)), color-stop(0.5, rgba(73, 90, 88, 0.5)), to(rgba(73, 90, 88, 0)));
background: linear-gradient(to top, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.2));
color: rgb(247, 254, 236);
text-shadow: -1px -1px 0 rgb(93, 69, 35),
1px -1px 0 rgb(93, 69, 35),
-1px 1px 0 rgb(93, 69, 35),
1px 1px 0 rgb(93, 69, 35);
}
.menu-item a {
text-decoration: none;
}
#sqlite-admin-wrap {
color: #1d1d1d;
font-size: 10pt;
border: 1px solid #ddd;
/* border-top: 0; */
-webkit-border-bottom-right-radius: 6px;
-webkit-border-bottom-left-radius: 6px;
-moz-border-radius-bottomright: 6px;
-moz-border-radius-bottomleft: 6px;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
display: block;
float: left;
min-height: 100px;
position: relative;
width: 47%;
margin-top: 10px;
padding: 5px;
box-shadow: 5px 5px 5px #eee;
z-index: 1;
}
#sqlite-admin-side-wrap {
color: #1d1d1d;
font-size: 10pt;
border: 1px solid #ddd;
/* border-top: 0; */
-webkit-border-bottom-right-radius: 6px;
-webkit-border-bottom-left-radius: 6px;
-moz-border-radius-bottomright: 6px;
-moz-border-radius-bottomleft: 6px;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
display: block;
float: left;
min-height: 100px;
position: relative;
width: 47%;
margin-top: 10px;
padding: 5px;
box-shadow: 5px 5px 5px #eee;
z-index: 1;
}
p {
text-indent: 15px;
line-height: 150%;
margin-left: 10px;
margin-right: 10px;
}
ul {
margin-left: 20px;
}
ol {
margin-left: 40px;
}
pre.code {
margin-left: 10px;
background: #eee;
}
.alt {
background: rgb(247, 254, 236);
}
.em {
font-weight: bold;
text-transform: capitalize;
}

216
styles/style.css Normal file
View File

@ -0,0 +1,216 @@
@CHARSET "UTF-8";
#sqlite-admin-wrap h2,
#sqlite-admin-side-wrap h2 {
background: rgb(73, 90, 88);
background: -moz-linear-gradient(bottom, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.5), rgba(73, 90, 88, 0));
background: -webkit-gradient(linear, bottom, top, from(rgba(73, 90, 88, 1)), color-stop(0.5, rgba(73, 90, 88, 0.5)), to(rgba(73, 90, 88, 0)));
background: linear-gradient(to top, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.2));
color: rgb(247, 254, 236);
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-moz-border-radius-topleft: 6px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
text-shadow: -1px -1px 0 rgb(93, 69, 35),
1px -1px 0 rgb(93, 69, 35),
-1px 1px 0 rgb(93, 69, 35),
1px 1px 0 rgb(93, 69, 35);
padding-left: 5px;
}
h3 {
clear: both;
}
.navigation {
display: block;
margin-top: 0;
margin-bottom: 0;
min-height: 20px;
/* border: 1px solid #000; */
}
.navi-menu {
margin-left: 0;
}
.menu-item {
font-size: 20px;
display: inline;
min-width: 150px;
height: 50px;
margin-left: 0;
margin-right: 10px;
padding: 5px;
border: .5px solit #000;
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-moz-border-radius-topleft: 6px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
box-shadow: 5px 5px 5px #eee;
}
.menu-selected {
font-size: 20px;
display: inline;
min-width: 150px;
height: 50px;
margin-left: 0;
margin-right: 10px;
padding: 5px;
border: .5px solit #000;
-webkit-border-top-right-radius: 6px;
-webkit-border-top-left-radius: 6px;
-moz-border-radius-topright: 6px;
-moz-border-radius-topleft: 6px;
border-top-right-radius: 6px;
border-top-left-radius: 6px;
box-shadow: 5px 5px 5px #eee;
background: rgb(73, 90, 88);
background: -moz-linear-gradient(bottom, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.5), rgba(73, 90, 88, 0));
background: -webkit-gradient(linear, bottom, top, from(rgba(73, 90, 88, 1)), color-stop(0.5, rgba(73, 90, 88, 0.5)), to(rgba(73, 90, 88, 0)));
background: linear-gradient(to top, rgba(73, 90, 88, 1), rgba(73, 90, 88, 0.2));
color: rgb(247, 254, 236);
text-shadow: -1px -1px 0 rgb(93, 69, 35),
1px -1px 0 rgb(93, 69, 35),
-1px 1px 0 rgb(93, 69, 35),
1px 1px 0 rgb(93, 69, 35);
}
.menu-item a {
text-decoration: none;
}
#sqlite-admin-wrap {
color: #1d1d1d;
font-size: 10pt;
border: 1px solid #ddd;
/* border-top: 0; */
-webkit-border-bottom-right-radius: 6px;
-webkit-border-bottom-left-radius: 6px;
-moz-border-radius-bottomright: 6px;
-moz-border-radius-bottomleft: 6px;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
display: block;
float: left;
min-height: 100%;
position: relative;
width: 60%;
margin-top: 10px;
padding: 5px;
box-shadow: 5px 5px 5px #eee;
z-index: 1;
}
#sqlite-admin-side-wrap {
color: #1d1d1d;
font-size: 10pt;
border: 1px solid #ddd;
/* border-top: 0; */
-webkit-border-bottom-right-radius: 6px;
-webkit-border-bottom-left-radius: 6px;
-moz-border-radius-bottomright: 6px;
-moz-border-radius-bottomleft: 6px;
border-bottom-right-radius: 6px;
border-bottom-left-radius: 6px;
display: block;
float: left;
min-height: 100%;
position: relative;
width: 35%;
margin-top: 10px;
padding: 5px 5px 5px 5px;
box-shadow: 5px 5px 5px #eee;
z-index: 1;
}
p {
text-indent: 15px;
line-height: 150%;
}
table#sys-info{
/* width: 600px; */
width: 450px;
}
table#status {
width: 450px;
}
table#sqlite-table {
/* width: 700px; */
width: 650px;
}
th.tbl-name {
width: 200px;
}
th.tbl_owner {
width: 105px;
}
th.tbl_index {
width: 350px;
}
td.system {
color: rgb(153, 0, 0);
}
td.user {
color: rgb(0, 0, 255);
}
td.menu-title {
width: 90px;
}
table.statement {
width: 500px;
}
ul {
margin-left: 20px;
}
ol {
margin-left: 40px;
}
pre.code {
padding: 5px 5px 5px 5px;
margin-left: 15px;
margin-right: 10px;
background: #eee;
}
tr.incompatible {
background: rgb(251, 229, 221);
}
tr.workaround {
background: rgb(217, 232, 237);
}
tr.compatible {
}
th.active-plugins {
width: 100px;
}
th.compatible {
width: 80px;
}
input.button-primary {
display: block;
clear: both;
width: 100px;
}
.alt {
background: rgb(247, 254, 236);
}
table#patch-files .item {
width: 40px;
}
.alert {
color: rgb(256, 0, 0);
}
div.alert {
display: block;
width: 95%;
text-align: center;
margin: 0 auto;
color: rgb(256, 0, 0);
text-transform: capitalize;
}
blockquote.caution {
display: block;
width: 95%;
border: 3px double rgb(0, 0, 0);
margin: 0 auto;
padding: 5px;
}
blockquote.caution > p {
margin: 5px;
padding: 0;
}

193
utilities/documentation.php Normal file
View File

@ -0,0 +1,193 @@
<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Toshiyasu Kojima
*
*/
/**
* dispaly documentation page
* TODO: separate database access methods and display methods for maintenance
*/
class SQLiteIntegrationDocument {
function show_doc() {
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') :?>
<div class="navigation">
<ul class="navi-menu">
<li class="menu-selected"><?php _e('Documentation', $domain);?></li>
<li class="menu-item"><a href="<?php echo $utils->show_parent();?>?page=sys-info"><?php _e('System Info', $domain); ?></a></li>
<li class="menu-item"><a href="<?php echo $utils->show_parent();?>?page=setting-file"><?php _e('Miscellaneous', $domain);?></a></li>
<li class="menu-item"><a href="<?php echo $utils->show_parent();?>?page=patch"><?php _e('Patch Utility', $domain);?></a></li>
</ul>
</div>
<div class="wrap" id="sqlite-admin-wrap">
<h2><?php _e('Documentation', $domain); ?></h2>
<p>
<?php _e('This is a brief documentation about this plugin. For more details, see also the <a href="http://dogwood.skr.jp/wordpress/sqlite-integration">Plugin Page</a>.', $domain);?>
</p>
<p>
<?php _e('Please don\'t forget: WordPress DOES NOT OFFICIALLY SUPPORT any database other than MySQL. So if you ask about this plugin in the Forum, it\'s not unlikely that you won\'t get no answers at all.', $domain);?>
</p>
<h3><?php _e('Features', $domain);?></h3>
<p>
<?php _e('This plugin is a successor to <a href="http://wordpress.org/extend/plugins/pdo-for-wordpress/">PDO for WordPress</a>, 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.5.1 and 3.6 beta).', $domain); ?>
</p>
<p>
<?php _e('<a href="http://www.sqlite.org/">SQLite Web Page</a> says &mdash; SQLite is a &quot;software library that implements selfcontained, serverless, zero-configuration, transactional SQL database engine&quot;. It is &quot;a good choice for small to medium size websites&quot;. It\'s small and portable, and you don\'t need any database server system.', $domain); ?>
</p>
<p>
<?php _e('Unfortunately enough, WordPress only supports MySQL. Consequently it doesn\'t provide any APIs for SQLite. So if you want to create a website using WordPress without a database server, you\'ve got to write a kind of wrapper program yourself to use SQLite. This is the way SQLite Integration goes.', $domain);?>
</p>
<p>
<?php _e('SQLite Integration does the work as follows:', $domain); ?>
</p>
<ol>
<li><?php _e('Intercepts SQL statement for MySQL from WordPress', $domain); ?></li>
<li><?php _e('Rewrites it as SQLite can execute', $domain); ?></li>
<li><?php _e('Gives it to SQLite', $domain); ?></li>
<li><?php _e('Gets the results from SQLite', $domain); ?></li>
<li><?php _e('Format the results as MySQL returns, if necessary', $domain);?></li>
<li><?php _e('Gives back the results to WordPress', $domain); ?></li>
</ol>
<p>
<?php _e('WordPress doesn\'t know what has happened in the background and will be happy with it.', $domain);?>
</p>
<h3><?php _e('Limitations', $domain);?></h3>
<p>
<?php _e('SQLite Integration uses SQLite, so the limitations of SQLite is, as it is, those of SQLite Integration. MySQL is far from a simple SQL engine and has many extended features and functionalities. WordPress uses some of them. Among those are some SQLite doesn\'t implement. For those features that WordPress uses, I made them work with SQLite Integration. But for others that some plugins are using, SQLite Integration can\'t manipulate. So...', $domain); ?>
</p>
<ol>
<li><strong><?php _e('There are some plugins that you can\'t use in any way.<br />', $domain);?></strong>
<?php _e('Some plugins can\'t be activated or work properly. See the &quot;Plugin Compatibility/Incompatibility&quot; section.', $domain);?></li>
<li><strong><?php _e('There are some plugins that you can\'t use without rewriting some codes in them.<br />', $domain);?></strong>
<?php echo sprintf(__('Some plugins do work fine if you rewrite MySQL functions. I made some patch files and <a href="%s?page=patch">Patch Utility</a>. See also the <a href="http://dogwood.skr.jp/wordpress/sqlite-integration">Plugin Page</a> for more details.', $domain), $utils->show_parent());?></li>
</ol>
<p>
<?php _e('And there may be other problems I overlooked. If you find malfunctionality, please let me know at the <a href="http://wordpress.org/support/plugin/sqlite-integration">Support Forum</a>.', $domain);?>
</p>
<h3><?php _e('User Defined Functions', $domain); ?></h3>
<p>
<?php _e('SQLite Integration replaces some functions of MySQL with the user defined functions built in PHP PDO library. But some of the functions are meaningless in SQLite database: e.g. get_lock() or release_lock(). When SQLite Integration meets those functions, it does nothing but prevent the error.', $domain); ?>
</p>
<p>
<?php _e('If you want SQLite Integration to execute more functions, you can add the definition in the file sqlite-integration/functions.php (functions-5-2.php is for PHP 5.2 or lesser).', $domain);?>
</p>
<h3><?php _e('Database Administration and Maintenance', $domain);?></h3>
<p>
<?php _e('SQLite Integration doesn\'t contain database maintenace functionality, because there are some other free or proprietary softwares that give you such functionalities. For example, these are among free softwares:', $domain);?>
</p>
<ul>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/">SQLite Manager Mozilla Addon</a>(<?php _e('my recommendation', $domain);?>)</li>
<li><a href="http://www.sqlitemanager.org/">SQLiteManager</a>(<?php _e('unfortunately seems not to maintained...', $domain); ?>)</li>
</ul>
<p>
<?php _e('I\'m not sure if future release may have some of the database maintenance functionality.', $domain);?>
</p>
</div>
<div class="wrap" id="sqlite-admin-side-wrap">
<h2><?php _e('Plugin Compatibility/Incompatibility', $domain);?></h2>
<p>
<?php _e('WordPress without its plugins is a king without people. Of course, you need plugins, I know.', $domain);?>
</p>
<p>
<?php echo sprintf(__('Most of the plugins will work fine with this plugin. But there are some that you need to rewrite some codes in them, and there are others that you can\'t use with this plugin. This is the list of the problematic plugins (far from complete). You can see informations about your installed plugins in the <a href="%s?page=sys-info">System Info</a> page. To see more details, please visit the <a href="http://dogwood.skr.jp/wordpress/sqlite-integration">Plugin Page</a>.', $domain), $utils->show_parent());?>
</p>
<table class="widefat page fixed" id="plugins-table">
<thead>
<tr>
<th data-sort='{"key":"name"}' class="item"><?php _e('Plugins Name', $domain); ?></th>
<th data-sort='{"key":"compat"}'><?php _e('Compatibility', $domain); ?></th>
<th data-sort='{"key":"reason"}'><?php _e('Reasons', $domain);?></th>
</tr>
</thead>
<tbody>
<?php
if (file_exists(SQLiteListFile)) :?>
<?php
$contents = file_get_contents(SQLiteListFile);
$plugin_info_list = json_decode($contents);
foreach ($plugin_info_list as $plugin_info) :?>
<?php if (in_array($plugin_info->compat, array('No', 'Probably No', 'Needs Patch'))) :?>
<tr data-table='{"name":"<?php echo $plugin_info->name;?>", "compat":"<?php echo $plugin_info->compat;?>", "reason":"<?php echo $plugin_info->reason;?>"}'>
<td><?php echo $plugin_info->name;?></a></td>
<?php if (stripos($plugin_info->compat, 'patch') !== false) :?>
<td><a href="<?php echo $plugin_info->patch_url;?>"><?php _e('Needs Patch', $domain);?></a></td>
<?php elseif (stripos($plugin_info->compat, 'probably no')) :?>
<td><?php _e('Probably No', $domain);?></td>
<?php else :?>
<td><?php _e('No', $domain);?></td>
<?php endif;?>
<td><?php echo $plugin_info->reason;?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
<?php endif;?>
</tbody>
</table>
<h3><?php _e('Caching Plugins', $domain); ?></h3>
<p>
<?php _e('Some plugins that give you cache functinality might cause problems. It is because they try to create the db.php file in wp-content directory, which file SQLite Integration is using.', $domain);?>
</p>
<p>
<?php _e('If those plugins overwrite the db.php file, SQLite Integration doesn\'t work. <span class="em">My recommendation is not to use caching plugins</span>. Even so, if you want a caching plugin, you could try <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache</a>, which doesn\'t use db.php file. But no warranty, try at your own risk.', $domain);?>
</p>
<p>
<?php _e('I have not tested none of those caching plugins.', $domain);?>
</p>
<h3><?php _e('MySQL specific functions', $domain);?></h3>
<p>
<?php _e('Some plugins don\'t use WordPress database functions such as dbDelta(), and use PHP native MySQL functions when they create and manage tables in the database. But PHP doesn\'t permit redefining of the native functions (at least, under ordinary server setting). So SQLite Integration can\'t intercept and rewrite those functions.', $domain);?>
</p>
<p>
<?php _e('For example, you can see these codes in Google XML Sitemaps.', $domain);?>
</p>
<pre class="code">
$postRes = mysql_query($sql,$wpdb->dbh);
</pre>
<p>
<?php _e('or in Camera Slideshow', $domain); ?>
</p>
<pre class="code">
if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') ) {
</pre>
<p>
<?php _e('Such functions as mysql_get_server_info() or mysql_query() are from the MySQL driver of PHP. Not only some plugins but WordPress uses them, but SQLite Integration has no way to rewrite or redefine them. If the plugin you want to use has those functions in it, it won\'t work or give the error messages.', $domain); ?>
</p>
<p>
<?php _e('So, you have to rewrite them for SQLite Integration can execute. The two example above can be rewritten like this:', $domain);?>
</p>
<pre class="code">
$postRes = $wpdb->query($sql);
</pre>
<pre class="code">
if ( version_compare($wpdb->db_version(), '4.1.0', '>=') ) {
</pre>
<p>
<?php _e('As for those functions in WordPress, I overrode the WordPress functions themselves that contains such MySQL functions as mysql_query() or mysql_real_escape_string().', $domain); ?>
</p>
<h3><?php _e('FULLTEXT index');?></h3>
<p>
<?php _e('Some plugins use FULLTEXT index of MySQL. Of course SQLite does have the functionality named &quot;full-text search&quot;. But it is not correlated with that of MySQL. In fact it is not an &quot;index&quot; and requires another new table for that. And it has a different syntax. So you can\'t use the plugins which uses FULLTEXT index', $domain);?>
</p>
<p>
<?php _e('If your language is not written by separating words with spaces, e.g. Japanese, Chinese or Thai, neither FULLTEXT index nor full-text search work effectively. Even if your language is space-separating-words one, you don\'t have to be disappointed. Whatever languages you use, you can use <a href="http://wordpress.org/extend/plugins/wordpress-23-related-posts-plugin/">WordPress Related Posts</a> or <a href="http://wordpress.org/extend/plugins/related-posts/">Related Posts</a> or others. They are working fine with SQLite Integration!', $domain);?>
</p>
</div>
<?php endif;
}
}
?>

340
utilities/patch.php Normal file
View File

@ -0,0 +1,340 @@
<?php
/**
* This file contains PatchUtils class
*
* @package SQLite Integration
* @since 1.0
*
*/
class PatchUtils {
/**
* Reads wp-content/uploads/patches directory and returns file names in it.
* If directory contains none, returns empty array.
* @return array
*/
private function get_patch_files() {
$patch_files = array();
if (!is_dir(SQLitePatchDir)) {
return $patch_files;
} else {
if ($dir_handle = opendir(SQLitePatchDir)) {
while (($file_name = readdir($dir_handle)) !== false) {
if ($file_name == '.' || $file_name == '..')
continue;
$patch_files[] = $file_name;
}
}
return $patch_files;
}
}
/**
* Execute patch command and apply it to the target plugins.
* If patch file(s) is not selected, returns false.
* Or else returns array contains messages.
* @return boolean|array
*/
private function apply_patches() {
$installed_plugins = array();
$file_names = array();
$output = array();
$retval = 0;
$patch_results = array();
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.'<br />';
}
$patch_results[$file] = sprintf(__('Error! Messages: %s', $domain), $message);
}
}
return $patch_results;
}
/**
* Delete uploaded patch file(s).
* If patch file(s) is not selected, returns false.
* Or else returns array contains messages.
* @return boolean|array
*/
private function delete_patch_files() {
$file_names = array();
$rm_results = array();
if (isset($_POST['plugin_checked'])) {
$file_names = $_POST['plugin_checked'];
} else {
return false;
}
$command = 'rm -f';
foreach ($file_names as $file) {
if (chdir(SQLitePatchDir)) {
exec("$command $file", $output, $retval);
} else {
$rm_results[$file] = __('Error!: patches directory is not accessible.', $domain);
}
if ($retval > 0) {
$rm_results[$file] = sprintf(__('Error! Messages: %s', $domain), $output);
} else {
$rm_results[$file] = sprintf(__('File %s is deleted.', $domain), $file);
}
}
return $rm_results;
}
/**
* Uploads a patch file.
* No return values.
*/
private function upload_file() {
if (!file_exists(SQLitePatchDir) || !is_dir(SQLitePatchDir)) {
mkdir(SQLitePatchDir, 0705, true);
}
if (is_uploaded_file($_FILES['upfile']['tmp_name'])) {
if (move_uploaded_file($_FILES['upfile']['tmp_name'], SQLitePatchDir.'/'.$_FILES['upfile']['name'])) {
$message = __('File is uploaded', $domain);
echo '<div id="message" class="updated fade">'.$message.'</div>';
chmod(SQLitePatchDir.'/'.$_FILES['upfile']['name'], 0644);
} else {
$message = __('File is not uploaded', $domain);
echo '<div id="message" class="updated fade">'.$message.'</div>';
}
} else {
$message = __('File is not selected', $domain);
echo '<div id="message" class="updated fade">'.$message.'</div>';
}
}
/**
* Displays patch util page
*/
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 '<div id="message" class="updated fade">'.$message.'</div>';
} elseif (is_array($result) && count($result) > 0) {
echo '<div id="message" class="updated fade">';
foreach ($result as $key => $val) {
echo $key.' => '.$val.'<br />';
}
echo '</div>';
} else {
$message = __('None of the patches is applied!');
echo '<div id="message" class="updated fade">'.$message.'</div>';
}
}
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 '<div id="message" class="updated fade">'.$message.'</div>';
} elseif (is_array($result) && count($result) > 0) {
echo '<div id="message" class="updated fade">';
foreach ($result as $key => $val) {
echo $key.' => '.$val.'<br />';
}
echo '</div>';
} else {
$message = __('Error! Please remove files manually');
echo '<div id="message" class="updated fade">'.$message.'</div>';
}
}
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') : ?>
<div class="navigation">
<ul class="navi-menu">
<li class="menu-item"><a href="<?php echo $utils->show_parent();?>?page=doc"><?php _e('Documentation', $domain);?></a></li>
<li class="menu-item"><a href="<?php echo $utils->show_parent();?>?page=sys-info"><?php _e('System Info', $domain);?></a></li>
<li class="menu-item"><a href="<?php echo $utils->show_parent();?>?page=setting-file"><?php _e('Miscellaneous', $domain);?></a></li>
<li class="menu-selected"><?php _e('Patch Utility', $domain);?></li>
</ul>
</div>
<div class="wrap" id="sqlite-admin-wrap">
<h2><?php _e('Patch Files Upload and Apply', $domain);?></h2>
<h3><?php _e('What you can do in this page', $domain);?></h3>
<p>
<?php _e('I made patch files for some plugins that are incompatible with SQLite Integration and need rewriting. And I wrote in the <a href="http://dogwood.skr.jp/wordpress/sqlite-integration">Plugin Page</a> about how to apply a patch file to the plugin. But the command line interface sometimes embarrasses some people, especially newbies.', $domain);?>
</p>
<p>
<?php _e('In this page, you can upload patch files and apply them automatically. But there are some requirements.', $domain)?>
</p>
<ol>
<li><?php _e('Think before you leap. Is the plugin to which you are going to apply patch really necessary for your site? Did you search in the <a href="http://wordpress.org/extend/plugins/">Plugin Directory</a> for the substitutes?', $domain)?></li>
<li><?php _e('Your PHP script has the permission to create a directory and write a file in it.', $domain);?></li>
<li><?php _e('Your PHP scripts can execute exec() function on the server.', $domain);?></li>
<li><?php _e('Your PHP script can execute &quot;patch&quot; shell command.(Script will check if it is executable or not.)', $domain);?></li>
</ol>
<p>
<?php _e('If uploading fails, it\' very likely that application will fail. When you try uploading with FTP client, the patch files must be put into the directory wp-content/uploads/patches/. When constant UPLOADS is defined, script follows it.', $domain)?>
</p>
<p>
<?php _e('You can create your patch file yourself. When you create one, please test it on your local server first and check if it works fine without PHP error or notice ( set error_reporting(E_ALL) ). If you use this utility, name your patch file as follows:', $domain);?>
</p>
<ol>
<li><?php _e('Use the file name beginning with the plugin directory name.', $domain);?></li>
<li><?php _e('Use the plugin version number after the directory name with underscore.', $domain);?></li>
<li><?php _e('Use the suffix .patch.', $domain);?></li>
<li><?php _e('Use diff command options &quot;-Naur&quot;.', $domain);?></li>
</ol>
<p>
<?php _e('For example, the patch file for the plugin &quot;Debug Bar&quot; is &quot;debug-bar_0.8.patch&quot;. Script interprets &quot;debug-bar&quot; as the target directory and &quot;0.8&quot; as the target version. If the version number doesn\'t match with the target, script shows the error message and skip applying the patch file. And script will reject any other file name.', $domain);?>
</p>
<h3><?php _e('How to install, patch and activate plugins', $domain);?></h3>
<ol>
<li><?php _e('Install the plugin (not yet activate it)', $domain);?></li>
<li><?php _e('Upload the patch file (if any) to the server and ppply it in this page', $domain);?></li>
<li><?php _e('Back to the installed plugin page and activate it', $domain);?></li>
</ol>
<h3><?php _e('How to upgrade plugins', $domain);?></h3>
<p>
<?php _e('When upgrading the plugin, it will be safer to follow next steps.', $domain);?>
</p>
<ol>
<li><?php _e('Deactivate the plugin', $domain);?></li>
<li><?php _e('Upgrade the plugin', $domain);?></li>
<li><?php _e('Upload the patch file (if any) and apply it', $domain);?></li>
<li><?php _e('Reactivate the plugin', $domain);?></li>
</ol>
<p><?php _e('If there isn\'t a patch file to match with the newest version of the plugin, it won\'t work properly. Please wait for somebody to make one or rewrite the codes checking the patch file for the previous version (it\'s not so difficult a matter, I guess, for almost all the cases, you\'ll have only to replace the MySQL functions with the WordPress built-in functions).', $domain);?></p>
<h3><?php _e('Upload and Apply', $domain)?></h3>
<table class="form-table">
<tbody>
<tr>
<th scope="row"><?php _e('File Select', $domain);?></th>
<td>
<form action="" id="upload-form" class="wp-upload-form" method="post" enctype="multipart/form-data">
<?php if (function_exists('wp_nonce_field')) {
wp_nonce_field('sqlitewordpress-plugin-patch-file-stats');
}
?>
<label for="upload"><?php _e('Select file from your computer. If the file name is the same as existent file, this operation will override it.', $domain);?></label><br />
<input type="file" id="upload" name="upfile" size="60"/>
<input type="submit" name="upload" id="submit-upload" class="button" value="<?php _e('Upload', $domain)?>" />
</form>
</td>
</tr>
<tr>
<th scope="row"><?php _e('Patch files uploaded', $domain)?></th>
<td>
<form action="" method="post">
<?php if (function_exists('wp_nonce_field')) {
wp_nonce_field('sqlitewordpress-plugin-manip-stats');
}
?>
<label for="plugin_check"><?php _e('Select the file(s) you want to apply to the plugin(s) or you want to delete. You can select multiple files.', $domain);?></label>
<table class="widefat page fixed" id="patch-files">
<thead>
<tr>
<th class="item"><?php _e('Apply/Hold', $domain)?></th>
<th data-sort='{"key":"name"}'><?php _e('Patch files to apply', $domain)?></th>
</tr>
</thead>
<tbody>
<?php $files = $this->get_patch_files();
if (!empty($files)) : ?>
<?php foreach ($files as $file) : ?>
<tr data-table='{"name":"<?php echo $file ?>"}'>
<td><input type="checkbox" id="plugin_check" name="plugin_checked[]" value="<?php echo $file ?>"/></td>
<td><?php echo $file ?></td>
</tr>
<?php endforeach;?>
<?php endif;?>
</tbody>
</table>
<p>
<input type="submit" name="apply_patch" class="button-primary" value="<?php _e('Apply patch', $domain);?>" onclick="return confirm('<?php _e('Are you sure to apply patch files?\n\nClick [Cancel] to stop,[OK] to continue.', $domain);?>')" />
<input type="submit" name="patch_file_delete" class="button-primary" value="<?php _e('Delete file', $domain);?>" onclick="return confirm('<?php _e('Are you sure to delete patch files?\n\nClick [Cancel] to stop,[OK] to continue.', $domain);?>')" />
</p>
</form>
</td>
</tr>
</tbody>
</table>
</div>
<div class="wrap" id="sqlite-admin-side-wrap">
<div class="alert">
<?php _e('Caution about your patch file(s)', $domain);?>
</div>
<blockquote class="caution">
<p>
<?php _e('If you don\'t know where it comes from or who created it, I strongly recommend that you should see and check the contents of the file. If a person who created it secretly inserted a malicious codes, it will be executed by the plugin and may damage your site or your server, for which damage I don\'t incur any liability. If you don\'t understand well, you\'d better use the substitute plugins. Take your own risk, please.', $domain);?>
</p>
</blockquote>
</div>
<?php endif;
}
}
?>

313
utilities/plugin_lists.json Normal file
View File

@ -0,0 +1,313 @@
[
{
"name":"Akismet",
"compat":"Checked",
"class":"compatible"
},
{
"name":"All In One SEO Pack",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Any Mobile Theme Switcher",
"compat":"Checked",
"class":"compatible"
},
{
"name":"BAW Manual Related Posts",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Better Related Posts",
"compat":"No",
"reason":"FULLTEXT index",
"class":"incompatible"
},
{
"name":"Breadcrumb NavXT",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Broken Link Checker",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Browser Shots",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Camera slideshow",
"compat":"Needs Patch",
"patch_url":"http://dogwood.skr.jp/wordpress/plugins/",
"reason":"MySQL function",
"class":"workaround"
},
{
"name":"Category Order and Taxonomy Terms Order",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Contact Form 7",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Contact Form 7 reCAPTCHA extension",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Crayon Syntax Highlighter",
"compat":"Checked",
"class":"compatible"
},
{
"name":"DB Cache Reloaded Fix",
"compat":"Probably No",
"reason":"db.php conflict",
"class":"probable"
},
{
"name":"Debug Bar",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Debug Bar Console",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Debug Bar Extender",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Dynamic To Top",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Google Analyticator",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Google Analytics Popular Posts",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Google XML Sitemaps",
"compat":"Needs Patch",
"patch_url":"http://dogwood.skr.jp/wordpress/plugins/",
"reason":"MySQL function",
"class":"workaround"
},
{
"name":"Hello Dolly",
"compat":"Checked",
"class":"compatible"
},
{
"name":"HyperDB",
"compat":"Probably No",
"reason":"db.php conflict",
"class":"probable"
},
{
"name":"Jetpack by WordPress.com",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Ktai Style",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Limit Login Attempts",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Optimize Database after Deleting Revisions",
"compat":"Probably No",
"reason":"MySQL function/MySQL specific table",
"class":"workaround"
},
{
"name":"Polylang",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Related Posts",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Revision Cleaner",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Search Everything",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Search Meter",
"compat":"Checked",
"class":"compatible"
},
{
"name":"SQLite Integration",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Synchi",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Theme-Check",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Wordfence Security",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WordPress Beta Tester",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WordPress Importer",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Wordpress Popular Posts",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WordPress Related Posts",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP Multibyte Patch",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP-PageNavi",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP-PostRatings",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP-reCAPTCHA",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP Social Bookmarking Light",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP Super Cache",
"compat":"Checked",
"class":"compatible"
},
{
"name":"WP Video Lightbox",
"compat":"Checked",
"class":"compatible"
},
{
"name":"Wysija Newsletters",
"compat":"Needs Patch",
"patch_url":"http://dogwood.skr.jp/wordpress/plugins/",
"reason":"MySQL function/table name",
"class":"workaround"
},
{
"name":"W3 Total Cache",
"compat":"Probably No",
"reason":"db.php conflict",
"class":"probable"
},
{
"name":"Yet Another Related Posts Plugin",
"compat":"No",
"reason":"FULLTEX index",
"class":"incompatible"
}
]

679
utilities/utility.php Normal file
View File

@ -0,0 +1,679 @@
<?php
/**
*
* @package SQLite Integration
* @author kjm
*
*/
class SQLiteIntegrationUtils {
public $text_domain = 'sqlite-integration';
function __construct() {
}
/**
* function to return contents of 'FQDBDIR/debug.txt'.
* if the file is not existent, returns false.
* @return string|boolean
*/
private function show_error_log() {
$file = FQDBDIR . 'debug.txt';
if (file_exists($file)) {
$contents = file_get_contents($file);
return $contents;
} else {
return false;
}
}
/**
* function to clear the contents of 'FQDBIR/debug.txt'
* @return boolean
*/
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;
}
/**
* function to return associative array of system informations
* sys_info['WordPress'] => WordPress Version
* sys_info['PHP'] => PHP Version
* @return array
*/
private function get_system_info() {
global $wp_version;
$sys_info = array();
$sys_info['WordPress'] = $wp_version;
$sys_info['PHP'] = PHP_VERSION;
return $sys_info;
}
/**
* function to return various database information
* @return assoc array
*/
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;
}
/**
* function to return associative array
* array( table name => array( index name ( column name )))
* for each table in the database
* @return array
*/
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;
}
/**
* function to return the autoincremented values of each table
* @return assoc array name => sequence, or false
*/
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;
}
}
/**
* function to return contents of 'wp-content/db.php' file
* if the file is not existent, returns false.
* @return string|boolean
*/
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);
echo $contents;
} else {
echo 'file is not readable';
}
} else {
echo 'file doesn\'t exist';
return false;
}
}
/**
* function to get the textarea contents and write into db.php file
* @param string $contents
* @return boolean
*/
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;
}
/**
* function to optimize database file
* only to give vacuum command to SQLite
* @return boolean
*/
private function optimize_db() {
global $wpdb;
$result = $wpdb->query("OPTIMIZE");
return $result;
}
/**
* function to get SQLite database file size
* @return string
*/
private function get_database_size() {
$db_file = FQDB;
if (file_exists($db_file)) {
$size = filesize($db_file);
clearstatcache(false, $db_file);
return $this->convert_to_formatted_number($size);
}
}
/**
* function to format file size to unit byte
* @param integer $size
* @return string
*/
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];
}
/**
* function to echo plugins info table component
*/
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 = '<a href="'.$data['PluginURI'].'">'.$data['Name'].'</a>';
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 = '<a href="'.$plugin_info->patch_url.'">'.__('Needs Patch', $domain).'</a>';
} 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':
$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 '<tr data-table='.'\'{"name":"'.$data['Name'].'","active":"sitewide active","comp":"'.strip_tags($compat).'"}\''." $class>";
echo sprintf('<td>%1$s</td><td>%2$s</td><td>%3$s</td>', $name, __('Sitewide Active', $domain), $compat);
} elseif (is_plugin_active($key)) {
echo '<tr data-table='.'\'{"name":"'.$data['Name'].'","active":"active","comp":"'.strip_tags($compat).'"}\''." $class>";
echo sprintf('<td>%1$s</td><td>%2$s</td><td>%3$s</td>', $name, __('Active', $domain), $compat);
} else {
echo '<tr data-table='.'\'{"name":"'.$data['Name'].'","active":"inactive","comp":"'.strip_tags($compat).'"}\''." $class>";
echo sprintf('<td>%1$s</td><td>%2$s</td><td>%3$s</td>', $name, __('Inactive', $domain), $compat);
}
echo '</tr>';
}
}
}
/**
* function to return output of phpinfo() as an array
* See PHP Manual
* @return array
*/
private function parse_php_modules() {
ob_start();
phpinfo(INFO_MODULES);
$infos = ob_get_contents();
ob_end_clean();
$infos = strip_tags($infos, '<h2><th><td>');
$infos = preg_replace('/<th[^>]*>([^<]+)<\/th>/', "<info>\\1</info>", $infos);
$infos = preg_replace('/<td[^>]*>([^<]+)<\/td>/', "<info>\\1</info>", $infos);
$info_array = preg_split('/(<h2>[^<]+?<\/h2>)/', $infos, -1, PREG_SPLIT_DELIM_CAPTURE);
$modules = array();
for ($i = 1; $i < count($info_array); $i++) {
if (preg_match('/<h2>([^<]+)<\/h2>/', $info_array[$i], $match)) {
$name = trim($match[1]);
$info_array2 = explode("\n", $info_array[$i+1]);
foreach ($info_array2 as $info) {
$pattern = '<info>([^<]+)<\/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;
}
/**
* function to echo PHP module info
* @param string $module_name
* @param string $setting_name
*/
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';
}
}
function welcome() {
$domain = $this->text_domain;
if (isset($_GET['page']) && $_GET['page'] == 'sqlite-integration') :?>
<div class="wrap" id="sqlite-admin-wrap">
<h2><?php _e('Welcome to SQLite Integration', $domain) ?></h2>
<p>
<?php _e('Thank you for using SQLite Integration plugin!', $domain) ?>
</p>
<p>
<?php _e('You read this message, which means you have succeeded in installing WordPress with this plugin SQLite Integration. Congratulations and enjoy your Blogging!', $domain) ?>
</p>
<p>
<?php _e('You don\'t have to set any special settings. In fact there are no other settings. You can write articles or pages and customize you WordPress in an ordinary way. You want to install your plugins? All right, go ahead. But some of them may be incompatible with this. Please read more information about this plugin and your SQLite database below.', $domain)?>
</p>
<p><?php _e('Deactivation makes this documents and utilities disappear from the dashboard, but it doesn\'t affect the functionality of the SQLite Integration. when uninstalled, it will remove wp-content/uploads/patches directory (if exists) and wp-content/db.php file altogether.', $domain);?></p>
<table class="widefat" cellspacing="0" id="menu">
<thead>
<th><?php _e('Title', $domain);?></th>
<th><?php _e('Contents', $domain);?></th>
</thead>
<tbody>
<tr>
<td class="menu-title"><a href="<?php echo $this->show_parent(); ?>?page=doc"><?php _e('Documentation', $domain) ?></a></td>
<td><?php _e('You can read documentation about this plugin and plugin compatibility.', $domain)?></td>
</tr>
<tr>
<td class="menu-title"><a href="<?php echo $this->show_parent();?>?page=sys-info"><?php _e('System Info', $domain) ?></a></td>
<td><?php _e('You can see database and system information.', $domain)?></td>
</tr>
<tr>
<td class="menu-title"><a href="<?php echo $this->show_parent(); ?>?page=setting-file"><?php _e('Miscellaneous', $domain) ?></a></td>
<td><?php _e('You can see the error log and edit db.php file (if necessary) and optimize your database.', $domain)?></td>
</tr>
<tr>
<td><a href="<?php echo $this->show_parent();?>?page=patch"><?php _e('Patch Utility', $domain)?></a></td>
<td><?php _e('You can upload patch files and apply them to the incompatible plugins.', $domain)?></td>
</tr>
</tbody>
</table>
</div>
<?php endif;
}
/**
* function to show Utiliy page contents
*/
function show_utils() {
$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($_GET['page']) && $_GET['page'] == 'sys-info') :?>
<div class="navigation">
<ul class="navi-menu">
<li class="menu-item"><a href="<?php echo $this->show_parent();?>?page=doc"><?php _e('Documentation', $domain)?></a></li>
<li class="menu-selected"><?php _e('System Info', $domain);?></li>
<li class="menu-item"><a href="<?php echo $this->show_parent();?>?page=setting-file"><?php _e('Miscellaneous', $domain);?></a></li>
<li class="menu-item"><a href="<?php echo $this->show_parent();?>?page=patch"><?php _e('Patch Utility', $domain);?></a></li>
</ul>
</div>
<div class="wrap" id="sqlite-admin-wrap">
<h2><?php _e('System Information', $domain) ?></h2>
<h3><?php _e('PHP Informations', $domain) ?></h3>
<?php $info = $this->get_system_info(); ?>
<table class="widefat page fixed" cellspacing="0" id="sys-info">
<thead>
<tr>
<th class="item"><?php _e('Items', $domain);?></th>
<th><?php _e('Description', $domain);?></th>
</tr>
</thead>
<tbody>
<tr>
<td class="item"><?php _e('WordPress Version', $domain);?></td>
<td><?php echo $info['WordPress']; ?></td>
</tr>
<tr>
<td class="item"><?php _e('PHP Version', $domain);?></td>
<td><?php echo $info['PHP']; ?></td>
</tr>
<tr>
<td class="item"><?php _e('PDO Support', $domain);?></td>
<td><?php $this->get_module_setting('PDO', 'PDO support');?></td>
</tr>
<tr>
<td class="item"><?php _e('PDO Drivers', $domain);?></td>
<td><?php $this->get_module_setting('PDO', 'PDO drivers');?></td>
</tr>
<tr>
<td class="item"><?php _e('PDO Driver for SQLite 3.x', $domain);?></td>
<td><?php $this->get_module_setting('pdo_sqlite', 'PDO Driver for SQLite 3.x');?></td>
</tr>
<tr>
<td class="item"><?php _e('SQLite Library Version', $domain);?></td>
<td><?php $this->get_module_setting('pdo_sqlite', 'SQLite Library');?>
</tr>
</tbody>
</table>
<h3><?php _e('Your Database Status', $domain)?></h3>
<table class="widefat page fixed" cellspacing="0" id="status">
<thead>
<tr>
<th><?php _e('Items', $domain)?></th>
<th><?php _e('Status', $domain)?></th>
</tr>
</thead>
<tbody>
<?php $status = $this->get_database_status();?>
<tr>
<td><?php _e('Database Size', $domain);?></th>
<td><?php echo $status['size'];?></td>
</tr>
<tr>
<td><?php _e('Page Size', $domain);?></td>
<td><?php echo $status['pagesize'];?></td>
</tr>
<tr>
<td><?php _e('Total Number of Pages', $domain);?></td>
<td><?php echo $status['page'];?></td>
</tr>
<tr>
<td><?php _e('Unused Page', $domain)?></td>
<td><?php echo $status['unused'];?></td>
</tr>
<tr>
<td><?php _e('Integrity Check', $domain);?></td>
<td><?php echo strtoupper($status['integrity']);?></td>
</tr>
<tr>
<td><?php _e('Encoding', $domain);?></th>
<td><?php echo $status['encoding'];?></td>
</tr>
<tr>
<td><?php _e('Collations', $domain);?></th>
<td>
<?php $i = 0;
foreach($status['collations'] as $col) {
if ($i != 0) echo '<br />';
echo ($i+1).'. '.$col;
$i++;
}
?>
</td>
</tr>
<tr>
<td><?php _e('Compile Options', $domain);?></td>
<td>
<?php $i = 0;
foreach ($status['options'] as $op) {
if ($i != 0) echo '<br />';
echo ($i+1).'. '.$op;
$i++;
}
?>
</td>
</tr>
</tbody>
</table>
<h3><?php _e('Database Tables and Indexes', $domain) ?></h3>
<p>
<?php _e('Table names in brown are required by WordPress, and those in blue are created by some plugins. The table sqlite_sequence is not a WordPress table but a table required by SQLite to store the current autoincremented value of each table, which is displayed in the parenthesis after the table names. You can\'t manipulate the tables or indexes here. Please use SQLite utilities (e.g. SQLiteManager).', $domain) ?>
</p>
<table class="widefat page fixed" cellspacing="0" id="sqlite-table">
<thead>
<tr>
<th data-sort='{"key":"tblName"}' class="tbl-name"><?php _e('Table Name', $domain) ?></th>
<th data-sort='{"key":"which"}' class="tbl_owner"><?php _e('System/User', $domain) ?>
<th class="tbl_index"><?php _e('Index ( Column )', $domain) ?></th>
</tr>
</thead>
<tbody>
<?php global $wpdb;
$table_info = $this->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) : ?>
<?php if (in_array($tbl_name, $wpdb->tables('all', true)) || in_array($tbl_name, $network_tables) || $tbl_name == 'sqlite_sequence') {
$which_table = 'system';
} else {
$which_table = 'user';
}
echo '<tr data-table=\'{"tblName":"' . $tbl_name . '","which":"' . $which_table . '"}\'>';
if (array_key_exists($tbl_name, $table_seq)) $tbl_name .= " ($table_seq[$tbl_name])";
echo '<td class="'. $which_table . '">' . $tbl_name . '</td>';
echo '<td class="'.$which_table.'">' . $which_table . ' table</td>';?>
<td class="<?php echo $which_table?>"><?php foreach ($index as $idx) { echo $idx . '<br />';} ?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<div class="wrap" id="sqlite-admin-side-wrap">
<h2><?php _e('Plugin Info', $domain)?></h2>
<p>
<?php _e('This table shows plugins you have installed and their compatibility.', $domain)?>
</p>
<table class="widefat page fixed" cellspacing="0" id="plugins-info">
<thead>
<tr>
<th data-sort='{"key":"name"}' class="installed-plugins"><?php _e('Installed Plugins', $domain)?></th>
<th data-sort='{"key":"active"}' class="active-plugins"><?php _e('Active/Inactive', $domain)?></th>
<th data-sort='{"key":"comp"}' class="compatible"><?php _e('Compatible', $domain)?></th>
</tr>
</thead>
<tbody>
<?php $this->show_plugins_info();?>
</tbody>
</table>
</div>
<?php endif;
}
/**
* function 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 '<div id="message" class="updated fade">'.$messages.'</div>';
} else {
$messages = __('Log not cleared', $domain);
echo '<div id="message" class="updated fade">'.$messages.'</div>';
}
}
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 '<div id="message" class="updated fade">'.$messages.'</div>';
} else {
$messages = __('Error! db.php couldn\'t be saved', $domain);
echo '<div id="message" class="updated fade">'.$messages.'</div>';
}
}
}
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 '<div id="message" class="updated fade">'.$messages.'</div>';
} else {
$messages = __('Optimization failed', $domain);
echo '<div id="message" class="updated fade">'.$messages.'</div>';
}
}
if (isset($_GET['page']) && $_GET['page'] == 'setting-file') :?>
<div class="navigation">
<ul class="navi-menu">
<li class="menu-item"><a href="<?php echo $this->show_parent();?>?page=doc"><?php _e('Documentation', $domain)?></a></li>
<li class="menu-item"><a href="<?php echo $this->show_parent();?>?page=sys-info"><?php _e('System Info', $domain) ?></a></li>
<li class="menu-selected"><?php _e('Miscellaneous', $domain);?></li>
<li class="menu-item"><a href="<?php echo $this->show_parent();?>?page=patch"><?php _e('Patch Utility', $domain)?></a></li>
</ul>
</div>
<div class="wrap" id="sqlite-admin-wrap">
<h2><?php _e('Database Optimization, Error Log, Init File', $domain)?></h2>
<h3><?php _e('Optimize You Database', $domain)?></h3>
<p>
<?php _e('This button sends &quot;vacuum&quot; command to your SQLite database. That command reclaims space after data has been deleted.', $domain)?>
</p>
<form action="" method="post">
<?php if (function_exists('wp_nonce_field')) {
wp_nonce_field('sqlitewordpress-db-optimize-stats');
}
?>
<p>
<input type="submit" name="sqlitewordpress_db_optimize" value="<?php _e('Optimize', $domain)?>" onclick="return confirm('<?php _e('Are you sure to optimize your database?\n\nClick [Cancel] to stop, [OK] to continue.', $domain);?>')" class="button-primary">
</p>
</form>
<h3><?php _e('SQLite Integration Error Log', $domain)?></h3>
<p>
<?php _e('This is the contents of SQLite Integration error log file(default: wp-content/database/debug.txt). If you want to clear this file, click the Clear Log button.', $domain)?>
</p>
<form action="" method="post">
<?php if (function_exists('wp_nonce_field')) {
wp_nonce_field('sqlitewordpress-log-reset-stats');
}
?>
<textarea name="errorlog" id="errorlog" cols="85" rows="10">
<?php $ret_val = $this->show_error_log();
if ($ret_val === false || empty($ret_val)) {
$message = __('No error messages are found', $domain);
echo $message;
} else {
echo $ret_val;
}
?>
</textarea>
<p>
<input type="submit" name="sqlitewordpress_log_reset" value="<?php _e('Clear Log', $domain)?>" onclick="return confirm('<?php _e('Are you sure to clear Log?\n\nClick [Cancel] to stop, [OK] to continue.', $domain);?>')" class="button-primary">
</p>
</form>
<h3><?php _e('Edit Initial File (wp-content/db.php)', $domain)?></h3>
<p>
<?php _e('When you go &quot;Plugins &raquo; Edit Plugin&quot; page, you can edit plugin source file. But you can\'t see this file there because it is not in the plugin directory. If you need to edit this file, you can edit here. This settings may cause problems. <span class="alert">If you don\'t understand well, please don\'t edit this file</span>.', $domain)?>
</p>
<form action="" method="post">
<?php if (function_exists('wp_nonce_field')) {
wp_nonce_field('sqlitewordpress-db-save-stats');
}
?>
<textarea name="dbfile" id="dbfile" cols="85" rows="30">
<?php $this->show_db_php();?></textarea>
<p>
<input type="submit" name="sqlitewordpress_db_save" value="<?php _e('Save')?>" onclick="return confirm('<?php _e('Are you sure to save this file?\n\nClick [Cancel] to stop, [OK] to continue.', $domain);?>')" class="button-primary">
</p>
</form>
</div>
<?php endif;
}
}
?>