From: <abe...@us...> - 2013-03-19 23:46:22
|
Revision: 6002 http://astlinux.svn.sourceforge.net/astlinux/?rev=6002&view=rev Author: abelbeck Date: 2013-03-19 23:46:10 +0000 (Tue, 19 Mar 2013) Log Message: ----------- web interface, version bump of phpliteadmin to 1.9.4.1 and new style css Modified Paths: -------------- branches/1.0/package/webinterface/altweb/admin/phpliteadmin.php branches/1.0/package/webinterface/altweb/common/phpliteadmin.css Modified: branches/1.0/package/webinterface/altweb/admin/phpliteadmin.php =================================================================== --- branches/1.0/package/webinterface/altweb/admin/phpliteadmin.php 2013-03-18 23:20:53 UTC (rev 6001) +++ branches/1.0/package/webinterface/altweb/admin/phpliteadmin.php 2013-03-19 23:46:10 UTC (rev 6002) @@ -2,14 +2,16 @@ // // Project: phpLiteAdmin (http://phpliteadmin.googlecode.com) -// Version: 1.9.3.3 +// Version: 1.9.4.1 // Summary: PHP-based admin tool to manage SQLite2 and SQLite3 databases on the web -// Last updated: 2013-01-14 +// Last updated: 2013-03-18 // Developers: // Dane Iracleous (dan...@gm...) // Ian Aldrighetti (ian...@gm...) // George Flanagin & Digital Gaslight, Inc (ge...@di...) -// Christopher Kramer (cra...@gm...) +// Christopher Kramer (cra...@gm..., http://en.christosoft.de) +// Ayman Teryaki (http://havalite.com) +// Dreadnaut (dre...@gm..., http://dreadnaut.altervista.org) // // // Copyright (C) 2013 phpLiteAdmin @@ -43,18 +45,36 @@ } if (($global_user = getPHPusername()) !== 'admin') { echo '<p style="color: red;">User "'.$global_user.'" does not have permission to access the "phpliteadmin" tab.</p>'; - exit; + exit(); } //AstLinux// end of restrict to 'admin' user. - //BEGIN USER-DEFINED VARIABLES ////////////////////////////// +// These are the default configuration value for phpLiteAdmin and will be overridden +// by the optional configuration file. Feel free to edit below if you want to use +// phpLiteAdmin as a single file; otherwise, rename phpliteadmin.config.sample.php to +// phpliteadmin.config.php and edit it. +// +// Please see http://code.google.com/p/phpliteadmin/wiki/Configuration for more details + //password to gain access -//AstLinux// Password ignored. -$password = "astlinux"; +$password = ''; +// Theme! If you want to change theme, save the CSS file in same folder of phpliteadmin or in folder 'themes' +$theme = 'phpliteadmin.css'; + +// the default language! If you want to change it, save the language file in same folder of phpliteadmin or in folder 'languages' +// More about localizations (downloads, how to translate etc.): http://code.google.com/p/phpliteadmin/wiki/Localization +$language = 'en'; + +// set default number of rows. You need to relog after changing the number +$rowsNum = 30; + +// reduce string characters by a number bigger than 10 +$charsNum = 300; + //directory relative to this file to search for databases (if false, manually list databases in the $databases variable) $directory = false; @@ -80,31 +100,13 @@ } //AstLinux// end of define database files + //a list of custom functions that can be applied to columns in the databases //make sure to define every function below if it is not a core PHP function -$custom_functions = array('md5', 'md5rev', 'sha1', 'sha1rev', 'time', 'mydate', 'strtotime', 'myreplace'); +$custom_functions = array('md5', 'sha1', 'time', 'strtotime'); -//define all the non-core custom functions -function md5rev($value) -{ - return strrev(md5($value)); -} -function sha1rev($value) -{ - return strrev(sha1($value)); -} -function mydate($value) -{ - return date("H:i n/j/y", intval($value)); -} -function myreplace($value) -{ - return preg_replace("/[^A-Za-z0-9]/", "", strval($value)); -} - //changing the following variable allows multiple phpLiteAdmin installs to work under the same domain. -//AstLinux// -$cookie_name = 'astlinux-db-2013'; +$cookie_name = 'pla3412'; //whether or not to put the app in debug mode where errors are outputted $debug = false; @@ -115,14 +117,319 @@ //////////////////////////// //END USER-DEFINED VARIABLES +// load optional configuration file +//$config_filename = './phpliteadmin.config.php'; +//if (is_readable($config_filename)) { +// include_once $config_filename; +//} + +// Start English language-texts +// Read our wiki on how to translate: http://code.google.com/p/phpliteadmin/wiki/Localization +$lang = array( + "direction" => "LTR", + "date_format" => 'M d H:i:s T Y', //AstLinux// + "ver" => "version", + "for" => "for", + "to" => "to", + "go" => "Go", + "yes" => "Yes", + "sql" => "SQL", + "csv" => "CSV", + "csv_tbl" => "Table that CSV pertains to", + "srch" => "Search", + "srch_again" => "Do Another Search", + "login" => "Log In", + "logout" => "Logout", + "view" => "View", + "confirm" => "Confirm", + "cancel" => "Cancel", + "save_as" => "Save As", + "options" => "Options", + "no_opt" => "No options", + "help" => "Help", + "installed" => "installed", + "not_installed" => "not installed", + "done" => "done", + "insert" => "Insert", + "export" => "Export", + "import" => "Import", + "rename" => "Rename", + "empty" => "Empty", + "drop" => "Drop", + "tbl" => "Table", + "chart" => "Chart", + "err" => "ERROR", + "act" => "Action", + "rec" => "Records", + "col" => "Column", + "cols" => "Columns", + "rows" => "row(s)", + "edit" => "Edit", + "del" => "Delete", + "add" => "Add", + "backup" => "Backup database file", + "before" => "Before", + "after" => "After", + "passwd" => "Password", + "passwd_incorrect" => "Incorrect password.", + "chk_ext" => "Checking supported SQLite PHP extensions", + "autoincrement" => "Autoincrement", + "not_null" => "Not NULL", + "attention" => "Attention", + + "sqlite_ext" => "SQLite extension", + "sqlite_ext_support" => "It appears that none of the supported SQLite library extensions are available in your installation of PHP. You may not use %s until you install at least one of them.", + "sqlite_v" => "SQLite version", + "sqlite_v_error" => "It appears that your database is of SQLite version %s but your installation of PHP does not contain the necessary extensions to handle this version. To fix the problem, either delete the database and allow %s to create it automatically or recreate it manually as SQLite version %s.", + "report_issue" => "The problem cannot be diagnosed properly. Please file an issue report at", + "sqlite_limit" => "Due to the limitations of SQLite, only the field name and data type can be modified.", + + "php_v" => "PHP version", + + "db_dump" => "database dump", + "db_f" => "database file", + "db_ch" => "Change Database", + "db_event" => "Database Event", + "db_name" => "Database name", + "db_rename" => "Rename Database", + "db_renamed" => "Database '%s' has been renamed to", + "db_del" => "Delete Database", + "db_path" => "Path to database", + "db_size" => "Size of database", + "db_mod" => "Database last modified", + "db_create" => "Create New Database", + "db_vac" => "The database, '%s', has been VACUUMed.", + "db_not_writeable" => "The database, '%s', does not exist and cannot be created because the containing directory, '%s', is not writable. The application is unusable until you make it writable.", + "db_setup" => "There was a problem setting up your database, %s. An attempt will be made to find out what's going on so you can fix the problem more easily", + "db_exists" => "A database, other file or directory of the name '%s' already exists.", + + "exported" => "Exported", + "struct" => "Structure", + "struct_for" => "structure for", + "on_tbl" => "on table", + "data_dump" => "Data dump for", + "backup_hint" => "Hint: To backup your database, the easiest way is to %s.", + "backup_hint_linktext" => "download the database-file", + "total_rows" => "a total of %s rows", + "total" => "Total", + "not_dir" => "The directory you specified to scan for databases does not exist or is not a directory.", + "bad_php_directive" => "It appears that the PHP directive, 'register_globals' is enabled. This is bad. You need to disable it before continuing.", + "page_gen" => "Page generated in %s seconds.", + "powered" => "Powered by", + "remember" => "Remember me", + "no_db" => "Welcome to %s. It appears that you have selected to scan a directory for databases to manage. However, %s could not find any valid SQLite databases. You may use the form below to create your first database.", + "no_db2" => "The directory you specified does not contain any existing databases to manage, and the directory is not writable. This means you can't create any new databases using %s. Either make the directory writable or manually upload databases to the directory.", + + "create" => "Create", + "created" => "has been created", + "create_tbl" => "Create new table", + "create_tbl_db" => "Create new table on database", + "create_trigger" => "Creating new trigger on table", + "create_index" => "Creating new index on table", + "create_index1" => "Create Index", + "create_view" => "Create new view on database", + + "trigger" => "Trigger", + "triggers" => "Triggers", + "trigger_name" => "Trigger name", + "trigger_act" => "Trigger Action", + "trigger_step" => "Trigger Steps (semicolon terminated)", + "when_exp" => "WHEN expression (type expression without 'WHEN')", + "index" => "Index", + "indexes" => "Indexes", + "index_name" => "Index name", + "name" => "Name", + "unique" => "Unique", + "seq_no" => "Seq. No.", + "emptied" => "has been emptied", + "dropped" => "has been dropped", + "renamed" => "has been renamed to", + "altered" => "has been altered successfully", + "inserted" => "inserted", + "deleted" => "deleted", + "affected" => "affected", + "blank_index" => "Index name must not be blank.", + "one_index" => "You must specify at least one index column.", + "docu" => "Documentation", + "license" => "License", + "proj_site" => "Project Site", + "bug_report" => "This may be a bug that needs to be reported at", + "return" => "Return", + "browse" => "Browse", + "fld" => "Field", + "fld_num" => "Number of Fields", + "fields" => "Fields", + "type" => "Type", + "operator" => "Operator", + "val" => "Value", + "update" => "Update", + "comments" => "Comments", + + "specify_fields" => "You must specify the number of table fields.", + "specify_tbl" => "You must specify a table name.", + "specify_col" => "You must specify a column.", + + "tbl_exists" => "Table of the same name already exists.", + "show" => "Show", + "show_rows" => "Showing %s row(s). ", + "showing" => "Showing", + "showing_rows" => "Showing rows", + "query_time" => "(Query took %s sec)", + "syntax_err" => "There is a problem with the syntax of your query (Query was not executed)", + "run_sql" => "Run SQL query/queries on database '%s'", + + "ques_empty" => "Are you sure you want to empty the table '%s'?", + "ques_drop" => "Are you sure you want to drop the table '%s'?", + "ques_drop_view" => "Are you sure you want to drop the view '%s'?", + "ques_del_rows" => "Are you sure you want to delete row(s) %s from table '%s'?", + "ques_del_db" => "Are you sure you want to delete the database '%s'?", + "ques_del_col" => "Are you sure you want to delete column(s) %s from table '%s'?", + "ques_del_index" => "Are you sure you want to delete index '%s'?", + "ques_del_trigger" => "Are you sure you want to delete trigger '%s'?", + + "export_struct" => "Export with structure", + "export_data" => "Export with data", + "add_drop" => "Add DROP TABLE", + "add_transact" => "Add TRANSACTION", + "fld_terminated" => "Fields terminated by", + "fld_enclosed" => "Fields enclosed by", + "fld_escaped" => "Fields escaped by", + "fld_names" => "Field names in first row", + "rep_null" => "Replace NULL by", + "rem_crlf" => "Remove CRLF characters within fields", + "put_fld" => "Put field names in first row", + "null_represent" => "NULL represented by", + "import_suc" => "Import was successful.", + "import_into" => "Import into", + "import_f" => "File to import", + "rename_tbl" => "Rename table '%s' to", + + "rows_records" => "row(s) starting from record # ", + "rows_aff" => "row(s) affected. ", + + "as_a" => "as a", + "readonly_tbl" => "'%s' is a view, which means it is a SELECT statement treated as a read-only table. You may not edit or insert records.", + "chk_all" => "Check All", + "unchk_all" => "Uncheck All", + "with_sel" => "With Selected", + + "no_tbl" => "No table in database.", + "no_chart" => "If you can read this, it means the chart could not be generated. The data you are trying to view may not be appropriate for a chart.", + "no_rows" => "There are no rows in the table for the range you selected.", + "no_sel" => "You did not select anything.", + + "chart_type" => "Chart Type", + "chart_bar" => "Bar Chart", + "chart_pie" => "Pie Chart", + "chart_line" => "Line Chart", + "lbl" => "Labels", + "empty_tbl" => "This table is empty.", + "click" => "Click here", + "insert_rows" => "to insert rows.", + "restart_insert" => "Restart insertion with ", + "ignore" => "Ignore", + "func" => "Function", + "new_insert" => "Insert As New Row", + "save_ch" => "Save Changes", + "def_val" => "Default Value", + "prim_key" => "Primary Key", + "tbl_end" => "field(s) at end of table", + "query_used_table" => "Query used to create this table", + "query_used_view" => "Query used to create this view", + "create_index2" => "Create an index on", + "create_trigger2" => "Create a new trigger", + "new_fld" => "Adding new field(s) to table '%s'", + "add_flds" => "Add Fields", + "edit_col" => "Editing column '%s'", + "vac" => "Vacuum", + "vac_desc" => "Large databases sometimes need to be VACUUMed to reduce their footprint on the server. Click the button below to VACUUM the database '%s'.", + "event" => "Event", + "each_row" => "For Each Row", + "define_index" => "Define index properties", + "dup_val" => "Duplicate values", + "allow" => "Allowed", + "not_allow" => "Not Allowed", + "asc" => "Ascending", + "desc" => "Descending", + "warn0" => "You have been warned.", + "warn_passwd" => "You are using the default password, which can be dangerous. You can change it easily at the top of %s.", + "warn_dumbass" => "You didn't change the value dumbass ;-)", + "sel_state" => "Select Statement", + "delimit" => "Delimiter", + "back_top" => "Back to Top", + "choose_f" => "Choose File", + "instead" => "Instead of", + "define_in_col" => "Define index column(s)", + + "delete_only_managed" => "You can only delete databases managed by this tool!", + "rename_only_managed" => "You can only rename databases managed by this tool!", + "db_moved_outside" => "You either tried to move the database into a directory where it cannot be managed anylonger, or the check if you did this failed because of missing rights.", + "extension_not_allowed" => "The extension you provided is not within the list of allowed extensions. Please use one of the following extensions", + "add_allowed_extension" => "You can add extensions to this list by adding your extension to \$allowed_extensions in the configuration.", + "directory_not_writable" => "The database-file itself is writable, but to write into it, the containing directory needs to be writable as well. This is because SQLite puts temporary files in there for locking.", + "tbl_inexistent" => "Table %s does not exist", + + // errors that can happen when ALTER TABLE fails. You don't necessarily have to translate these. + "alter_failed" => "Altering of Table %s failed", + "alter_tbl_name_not_replacable" => "could not replace the table name with the temporary one", + "alter_no_def" => "no ALTER definition", + "alter_parse_failed" =>"failed to parse ALTER definition", + "alter_action_not_recognized" => "ALTER action could not be recognized", + "alter_no_add_col" => "no column to add detected in ALTER statement", + "alter_pattern_mismatch"=>"Pattern did not match on your original CREATE TABLE statement", + "alter_col_not_recognized" => "could not recognize new or old column name", + "alter_unknown_operation" => "Unknown ALTER operation!", + + /* Help documentation */ + "help_doc" => "Help Documentation", + "help1" => "SQLite Library Extensions", + "help1_x" => "%s uses PHP library extensions that allow interaction with SQLite databases. Currently, %s supports PDO, SQLite3, and SQLiteDatabase. Both PDO and SQLite3 deal with version 3 of SQLite, while SQLiteDatabase deals with version 2. So, if your PHP installation includes more than one SQLite library extension, PDO and SQLite3 will take precedence to make use of the better technology. However, if you have existing databases that are of version 2 of SQLite, %s will be forced to use SQLiteDatabase for only those databases. Not all databases need to be of the same version. During the database creation, however, the most advanced extension will be used.", + "help2" => "Creating a New Database", + "help2_x" => "When you create a new database, the name you entered will be appended with the appropriate file extension (.db, .db3, .sqlite, etc.) if you do not include it yourself. The database will be created in the directory you specified as the \$directory variable.", + "help3" => "Tables vs. Views", + "help3_x" => "On the main database page, there is a list of tables and views. Since views are read-only, certain operations will be disabled. These disabled operations will be apparent by their omission in the location where they should appear on the row for a view. If you want to change the data for a view, you need to drop that view and create a new view with the appropriate SELECT statement that queries other existing tables. For more information, see <a href='http://en.wikipedia.org/wiki/View_(database)' target='_blank'>http://en.wikipedia.org/wiki/View_(database)</a>", + "help4" => "Writing a Select Statement for a New View", + "help4_x" => "When you create a new view, you must write an SQL SELECT statement that it will use as its data. A view is simply a read-only table that can be accessed and queried like a regular table, except it cannot be modified through insertion, column editing, or row editing. It is only used for conveniently fetching data.", + "help5" => "Export Structure to SQL File", + "help5_x" => "During the process for exporting to an SQL file, you may choose to include the queries that create the table and columns.", + "help6" => "Export Data to SQL File", + "help6_x" => "During the process for exporting to an SQL file, you may choose to include the queries that populate the table(s) with the current records of the table(s).", + "help7" => "Add Drop Table to Exported SQL File", + "help7_x" => "During the process for exporting to an SQL file, you may choose to include queries to DROP the existing tables before adding them so that problems do not occur when trying to create tables that already exist.", + "help8" => "Add Transaction to Exported SQL File", + "help8_x" => "During the process for exporting to an SQL file, you may choose to wrap the queries around a TRANSACTION so that if an error occurs at any time during the importation process using the exported file, the database can be reverted to its previous state, preventing partially updated data from populating the database.", + "help9" => "Add Comments to Exported SQL File", + "help9_x" => "During the process for exporting to an SQL file, you may choose to include comments that explain each step of the process so that a human can better understand what is happening." + + ); + + //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //there is no reason for the average user to edit anything below this comment //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -session_start(); //don't mess with this - required for the login session +//constants 1 +define("PROJECT", "phpLiteAdmin"); +define("VERSION", "1.9.4.1"); +define("PAGE", basename(__FILE__)); +//AstLinux// Force PDO +define("FORCETYPE", "PDO"); //force the extension that will be used (set to false in almost all circumstances except debugging) +define("SYSTEMPASSWORD", $password); // Makes things easier. +define('PROJECT_URL','http://phpliteadmin.googlecode.com'); +define('PROJECT_BUGTRACKER_LINK','<a href="http://code.google.com/p/phpliteadmin/issues/list" target="_blank">http://code.google.com/p/phpliteadmin/issues/list</a>'); + +// Resource output (css and javascript files) +// we get out of the main code as soon as possible, without inizializing the session +if (isset($_GET['resource'])) { + Resources::output($_GET['resource']); + exit(); +} + +// don't mess with this - required for the login session +ini_set('session.cookie_httponly', '1'); +session_start(); //AstLinux// Use /etc/timezone for the timezone -//date_default_timezone_set(date_default_timezone_get()); //needed to fix STRICT warnings about timezone issues function system_timezone() { if (($tz = trim(@file_get_contents('/etc/timezone'))) === '') { $tz = @date_default_timezone_get(); @@ -136,33 +443,45 @@ { ini_set("display_errors", 1); error_reporting(E_STRICT | E_ALL); +} else +{ + @ini_set("display_errors", 0); } -$startTimeTot = microtime(true); //start the timer to record page load time +// start the timer to record page load time +$pageTimer = new MicroTimer(); -//the salt and password encrypting is probably unnecessary protection but is done just for the sake of being very secure -//create a random salt for this session if a cookie doesn't already exist for it -if(!isset($_SESSION[$cookie_name.'_salt']) && !isset($_COOKIE[$cookie_name.'_salt'])) -{ - $n = rand(10e16, 10e20); - $_SESSION[$cookie_name.'_salt'] = base_convert($n, 10, 36); +// load language file +if($language != 'en') { + if(is_file('languages/lang_'.$language.'.php')) + include('languages/lang_'.$language.'.php'); + elseif(is_file('lang_'.$language.'.php')) + include('lang_'.$language.'.php'); } -else if(!isset($_SESSION[$cookie_name.'_salt']) && isset($_COOKIE[$cookie_name.'_salt'])) //session doesn't exist, but cookie does so grab it -{ - $_SESSION[$cookie_name.'_salt'] = $_COOKIE[$cookie_name.'_salt']; +// version-number added so after updating, old session-data is not used anylonger +// cookies names cannot contain symbols, except underscores +define("COOKIENAME", preg_replace('/[^a-zA-Z0-9_]/', '_', $cookie_name . '_' . VERSION) ); + +// stripslashes if MAGIC QUOTES is turned on +// This is only a workaround. Please better turn off magic quotes! +// This code is from http://php.net/manual/en/security.magicquotes.disabling.php +if (get_magic_quotes_gpc()) { + $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); + while (list($key, $val) = each($process)) { + foreach ($val as $k => $v) { + unset($process[$key][$k]); + if (is_array($v)) { + $process[$key][stripslashes($k)] = $v; + $process[] = &$process[$key][stripslashes($k)]; + } else { + $process[$key][stripslashes($k)] = stripslashes($v); + } + } + } + unset($process); } -//constants -define("PROJECT", "phpLiteAdmin"); -define("VERSION", "1.9.3.3"); -define("PAGE", basename(__FILE__)); -define("COOKIENAME", $cookie_name); -define("SYSTEMPASSWORD", $password); // Makes things easier. -define("SYSTEMPASSWORDENCRYPTED", md5($password."_".$_SESSION[$cookie_name.'_salt'])); //extra security - salted and encrypted password used for checking -//AstLinux// Force PDO -define("FORCETYPE", 'PDO'); //force the extension that will be used (set to false in almost all circumstances except debugging) - //data types array $types = array("INTEGER", "REAL", "TEXT", "BLOB"); define("DATATYPES", serialize($types)); @@ -263,7 +582,8 @@ //the function echo the help [?] links to the documentation function helpLink($name) { - return "<a href='javascript:void' onclick='openHelp(\"".$name."\");' class='helpq' title='Help: ".$name."'>[?]</a>"; + global $lang; + return "<a href='".PAGE."?help=1' onclick='openHelp(\"".$name."\"); return false;' class='helpq' title='".$lang['help'].": ".$name."' target='_blank'><span>[?]</span></a>"; } // function to encode value into HTML just like htmlentities, but with adjusted default settings @@ -279,6 +599,23 @@ return trim(trim($s), "'"); } +// reduce string chars +function subString($str) +{ + global $charsNum; + if($charsNum > 10){ + if(strlen($str)>$charsNum) $str = substr($str, 0, $charsNum).'...'; + } + return $str; +} + +function getRowId($table, $where=''){ + global $db; + $query = "SELECT ROWID FROM ".$db->quote_id($table).$where; + $result = $db->selectArray($query); + return $result; +} + // checks the (new) name of a database file function checkDbName($name) { @@ -319,45 +656,100 @@ // class Authorization { - public function grant($remember) + private $authorized; + private $login_failed; + private $system_password_encrypted; + + public function __construct() { - if($remember) //user wants to be remembered, so set a cookie + // the salt and password encrypting is probably unnecessary protection but is done just + // for the sake of being very secure + if(!isset($_SESSION[COOKIENAME.'_salt']) && !isset($_COOKIE[COOKIENAME.'_salt'])) { - $expire = time()+60*60*24*30; //set expiration to 1 month from now - setcookie(COOKIENAME, SYSTEMPASSWORD, $expire); - setcookie(COOKIENAME."_salt", $_SESSION[COOKIENAME.'_salt'], $expire); + // create a random salt for this session if a cookie doesn't already exist for it + $_SESSION[COOKIENAME.'_salt'] = self::generateSalt(20); } - else + else if(!isset($_SESSION[COOKIENAME.'_salt']) && isset($_COOKIE[COOKIENAME.'_salt'])) { - //user does not want to be remembered, so destroy any potential cookies - setcookie(COOKIENAME, "", time()-86400); - setcookie(COOKIENAME."_salt", "", time()-86400); - unset($_COOKIE[COOKIENAME]); - unset($_COOKIE[COOKIENAME.'_salt']); + // session doesn't exist, but cookie does so grab it + $_SESSION[COOKIENAME.'_salt'] = $_COOKIE[COOKIENAME.'_salt']; } - $_SESSION[COOKIENAME.'password'] = SYSTEMPASSWORDENCRYPTED; + // salted and encrypted password used for checking + $this->system_password_encrypted = md5(SYSTEMPASSWORD."_".$_SESSION[COOKIENAME.'_salt']); + + $this->authorized = + // no password + SYSTEMPASSWORD == '' + // correct password stored in session + || isset($_SESSION[COOKIENAME.'password']) && $_SESSION[COOKIENAME.'password'] == $this->system_password_encrypted + // correct password stored in cookie + || isset($_COOKIE[COOKIENAME]) && isset($_COOKIE[COOKIENAME.'_salt']) && md5(SYSTEMPASSWORD."_".$_COOKIE[COOKIENAME.'_salt']) == $_COOKIE[COOKIENAME]; } + + public function attemptGrant($password, $remember) + { + if ($password == SYSTEMPASSWORD) { + if ($remember) { + // user wants to be remembered, so set a cookie + $expire = time()+60*60*24*30; //set expiration to 1 month from now + setcookie(COOKIENAME, $this->system_password_encrypted, $expire, null, null, null, true); + setcookie(COOKIENAME."_salt", $_SESSION[COOKIENAME.'_salt'], $expire, null, null, null, true); + } else { + // user does not want to be remembered, so destroy any potential cookies + setcookie(COOKIENAME, "", time()-86400, null, null, null, true); + setcookie(COOKIENAME."_salt", "", time()-86400, null, null, null, true); + unset($_COOKIE[COOKIENAME]); + unset($_COOKIE[COOKIENAME.'_salt']); + } + + $_SESSION[COOKIENAME.'password'] = $this->system_password_encrypted; + $this->authorized = true; + return true; + } + + $this->login_failed = true; + return false; + } + public function revoke() { //destroy everything - cookies and session vars - setcookie(COOKIENAME, "", time()-86400); - setcookie(COOKIENAME."_salt", "", time()-86400); + setcookie(COOKIENAME, "", time()-86400, null, null, null, true); + setcookie(COOKIENAME."_salt", "", time()-86400, null, null, null, true); unset($_COOKIE[COOKIENAME]); unset($_COOKIE[COOKIENAME.'_salt']); session_unset(); session_destroy(); + $this->authorized = false; } + public function isAuthorized() { - // Is this just session long? (What!?? -DI) - if((isset($_SESSION[COOKIENAME.'password']) && $_SESSION[COOKIENAME.'password'] == SYSTEMPASSWORDENCRYPTED) || (isset($_COOKIE[COOKIENAME]) && isset($_COOKIE[COOKIENAME.'_salt']) && md5($_COOKIE[COOKIENAME]."_".$_COOKIE[COOKIENAME.'_salt']) == SYSTEMPASSWORDENCRYPTED)) - return true; - else - { - return false; + return $this->authorized; + } + + public function isFailedLogin() + { + return $this->login_failed; + } + + public function isPasswordDefault() + { + return SYSTEMPASSWORD == 'admin'; + } + + private static function generateSalt($saltSize) + { + $set = 'ABCDEFGHiJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + $setLast = strlen($set) - 1; + $salt = ''; + while ($saltSize-- > 0) { + $salt .= $set[mt_rand(0, $setLast)]; } + return $salt; } + } // @@ -371,9 +763,11 @@ protected $data; protected $lastResult; protected $fns; + protected $alterError; public function __construct($data) { + global $lang; $this->data = $data; $this->fns = array(); try @@ -381,10 +775,10 @@ if(!file_exists($this->data["path"]) && !is_writable(dirname($this->data["path"]))) //make sure the containing directory is writable if the database does not exist { echo "<div class='confirm' style='margin:20px;'>"; - echo "The database, '".htmlencode($this->data["path"])."', does not exist and cannot be created because the containing directory, '".htmlencode(dirname($this->data["path"]))."', is not writable. The application is unusable until you make it writable."; + printf($lang['db_not_writeable'], htmlencode($this->data["path"]), htmlencode(dirname($this->data["path"]))); //AstLinux// //echo "<form action='".PAGE."' method='post'>"; - //echo "<input type='submit' value='Log Out' name='logout' class='btn'/>"; + //echo "<input type='submit' value='Log Out' name='".$lang['logout']."' class='btn'/>"; //echo "</form>"; echo "</div><br/>"; exit(); @@ -457,8 +851,14 @@ public function getError() { - if($this->type=="PDO") + if($this->alterError!='') { + $error = $this->alterError; + $this->alterError = ""; + return $error; + } + else if($this->type=="PDO") + { $e = $this->db->errorInfo(); return $e[2]; } @@ -474,37 +874,38 @@ public function showError() { + global $lang; $classPDO = class_exists("PDO"); $classSQLite3 = class_exists("SQLite3"); $classSQLiteDatabase = class_exists("SQLiteDatabase"); if($classPDO) - $strPDO = "installed"; + $strPDO = $lang['installed']; else - $strPDO = "not installed"; + $strPDO = $lang['not_installed']; if($classSQLite3) - $strSQLite3 = "installed"; + $strSQLite3 = $lang['installed']; else - $strSQLite3 = "not installed"; + $strSQLite3 = $lang['not_installed']; if($classSQLiteDatabase) - $strSQLiteDatabase = "installed"; + $strSQLiteDatabase = $lang['installed']; else - $strSQLiteDatabase = "not installed"; + $strSQLiteDatabase = $lang['not_installed']; echo "<div class='confirm' style='margin:20px;'>"; - echo "There was a problem setting up your database, ".$this->getPath().". An attempt will be made to find out what's going on so you can fix the problem more easily.<br/><br/>"; - echo "<i>Checking supported SQLite PHP extensions...<br/><br/>"; + printf($lang['db_setup'], $this->getPath()); + echo ".<br/><br/><i>".$lang['chk_ext']."...<br/><br/>"; echo "<b>PDO</b>: ".$strPDO."<br/>"; echo "<b>SQLite3</b>: ".$strSQLite3."<br/>"; - echo "<b>SQLiteDatabase</b>: ".$strSQLiteDatabase."<br/><br/>...done.</i><br/><br/>"; + echo "<b>SQLiteDatabase</b>: ".$strSQLiteDatabase."<br/><br/>...".$lang['done'].".</i><br/><br/>"; if(!$classPDO && !$classSQLite3 && !$classSQLiteDatabase) - echo "It appears that none of the supported SQLite library extensions are available in your installation of PHP. You may not use ".PROJECT." until you install at least one of them."; + printf($lang['sqlite_ext_support'], PROJECT); else { if(!$classPDO && !$classSQLite3 && $this->getVersion()==3) - echo "It appears that your database is of SQLite version 3 but your installation of PHP does not contain the necessary extensions to handle this version. To fix the problem, either delete the database and allow ".PROJECT." to create it automatically or recreate it manually as SQLite version 2."; + printf($lang['sqlite_v_error'], 3, PROJECT, 2); else if(!$classSQLiteDatabase && $this->getVersion()==2) - echo "It appears that your database is of SQLite version 2 but your installation of PHP does not contain the necessary extensions to handle this version. To fix the problem, either delete the database and allow ".PROJECT." to create it automatically or recreate it manually as SQLite version 3."; + printf($lang['sqlite_v_error'], 2, PROJECT, 3); else - echo "The problem cannot be diagnosed properly. Please file an issue report at http://phpliteadmin.googlecode.com."; + echo $lang['report_issue'].' '.PROJECT_BUGTRACKER_LINK.'.'; } echo "</div><br/>"; } @@ -533,6 +934,18 @@ return $this->data["path"]; } + //is the db-file writable? + public function isWritable() + { + return $this->data["writable"]; + } + + //is the db-folder writable? + public function isDirWritable() + { + return $this->data["writable_dir"]; + } + //get the version of the database public function getVersion() { @@ -551,17 +964,17 @@ } } - //get the size of the database + //get the size of the database (in KB) public function getSize() { - return round(filesize($this->data["path"])*0.0009765625, 1)." KB"; + return round(filesize($this->data["path"])*0.0009765625, 1); } //get the last modified time of database public function getDate() { - //AstLinux// - return date("M d H:i:s T Y", filemtime($this->data["path"])); + global $lang; + return date($lang['date_format'], filemtime($this->data['path'])); } //get number of affected rows from last query @@ -732,11 +1145,12 @@ { if($name=="*" || $name=="+") { - $nameSingle = "(?:[^']|'')".$name; - $nameDouble = "(?:[^\"]|\"\")".$name; - $nameBacktick = "(?:[^`]|``)".$name; - $nameSquare = "(?:[^\]]|\]\])".$name; - $nameNo = "[^".$notAllowedIfNone."]".$name; + // use possesive quantifiers to save memory + $nameSingle = "(?:[^']$name+|'')$name+"; + $nameDouble = "(?:[^\"]$name+|\"\")$name+"; + $nameBacktick = "(?:[^`]$name+|``)$name+"; + $nameSquare = "(?:[^\]]$name+|\]\])$name+"; + $nameNo = "[^".$notAllowedIfNone."]$name"; } else { @@ -762,18 +1176,24 @@ // this has been completely debugged / rewritten by Christopher Kramer public function alterTable($table, $alterdefs) { - global $debug; + global $debug, $lang; + $this->alterError=""; + $errormsg = $lang['err'].': '.sprintf($lang['alter_failed'],htmlencode($table)).' - '; if($debug) echo "ALTER TABLE: table=($table), alterdefs=($alterdefs)<hr>"; if($alterdefs != '') { $recreateQueries = array(); - $tempQuery = "SELECT sql,name,type FROM sqlite_master WHERE tbl_name = ".$this->quote($table)." ORDER BY type DESC"; + $tempQuery = "SELECT sql,name,type FROM sqlite_master WHERE tbl_name = ".$this->quote($table); $result = $this->query($tempQuery); $resultArr = $this->selectArray($tempQuery); if($this->type=="PDO") $result->closeCursor(); if(sizeof($resultArr)<1) + { + $this->alterError = $errormsg . sprintf($lang['tbl_inexistent'], htmlencode($table)); + if($debug) echo "ERROR: unknown table<hr>"; return false; + } for($i=0; $i<sizeof($resultArr); $i++) { $row = $resultArr[$i]; @@ -788,8 +1208,16 @@ // ALTER the table $tmpname = 't'.time(); $origsql = $row['sql']; - $createtemptableSQL = "CREATE TEMPORARY TABLE ".$this->quote($tmpname)." ". - preg_replace("/^\s*CREATE\s+TABLE\s+".$this->sqlite_surroundings_preg($table)."\s*(\(.*)$/i", '$1', $origsql, 1); + $preg_remove_create_table = "/^\s*+CREATE\s++TABLE\s++".$this->sqlite_surroundings_preg($table)."\s*+(\(.*+)$/is"; + $origsql_no_create = preg_replace($preg_remove_create_table, '$1', $origsql, 1); + if($debug) echo "origsql=($origsql)<br />preg_remove_create_table=($preg_remove_create_table)<hr>"; + if($origsql_no_create == $origsql) + { + $this->alterError = $errormsg . $lang['alter_tbl_name_not_replacable']; + if($debug) echo "ERROR: could not get rid of CREATE TABLE<hr />"; + return false; + } + $createtemptableSQL = "CREATE TEMPORARY TABLE ".$this->quote($tmpname)." ".$origsql_no_create; if($debug) echo "createtemptableSQL=($createtemptableSQL)<hr>"; $createindexsql = array(); preg_match_all("/(?:DROP|ADD|CHANGE|RENAME TO)\s+(?:\"(?:[^\"]|\"\")+\"|'(?:[^']|'')+')((?:[^,')]|'[^']*')+)?/i",$alterdefs,$matches); @@ -817,6 +1245,7 @@ $createtesttableSQL = $createtemptableSQL; if(count($defs)<1) { + $this->alterError = $errormsg . $lang['alter_no_def']; if($debug) echo "ERROR: defs<1<hr />"; return false; } @@ -826,11 +1255,13 @@ $parse_def = preg_match("/^(DROP|ADD|CHANGE|RENAME TO)\s+(?:\"((?:[^\"]|\"\")+)\"|'((?:[^']|'')+)')((?:\s+'((?:[^']|'')+)')?\s+(TEXT|INTEGER|BLOB|REAL).*)?\s*$/i",$def,$matches); if($parse_def===false) { + $this->alterError = $errormsg . $lang['alter_parse_failed']; if($debug) echo "ERROR: !parse_def<hr />"; return false; } if(!isset($matches[1])) { + $this->alterError = $errormsg . $lang['alter_action_not_recognized']; if($debug) echo "ERROR: !isset(matches[1])<hr />"; return false; } @@ -851,22 +1282,22 @@ 3. 'colX' ..., - (with colX being the column to change/drop) 4. 'colX+1' ..., ..., 'colK') $5 (with colX+1-colK being columns after the column to change/drop) */ - $preg_create_table = "\s*(CREATE\s+TEMPORARY\s+TABLE\s+'?".preg_quote($tmpname,"/")."'?\s*\()"; // This is group $1 (keep unchanged) - $preg_column_definiton = "\s*".$this->sqlite_surroundings_preg("+",false," '\"\[`")."(?:\s+".$this->sqlite_surroundings_preg("*",false,"'\",`\[) ").")+"; // catches a complete column definition, even if it is + $preg_create_table = "\s*+(CREATE\s++TEMPORARY\s++TABLE\s++".preg_quote($this->quote($tmpname),"/")."\s*+\()"; // This is group $1 (keep unchanged) + $preg_column_definiton = "\s*+".$this->sqlite_surroundings_preg("+",false," '\"\[`,")."(?:\s+".$this->sqlite_surroundings_preg("*",false,"'\",`\[ ").")++"; // catches a complete column definition, even if it is // 'column' TEXT NOT NULL DEFAULT 'we have a comma, here and a double ''quote!' if($debug) echo "preg_column_definition=(".$preg_column_definiton.")<hr />"; $preg_columns_before = // columns before the one changed/dropped (keep) "(?:". "(". // group $2. Keep this one unchanged! "(?:". - "$preg_column_definiton,\s*". // column definition + comma + "$preg_column_definiton,\s*+". // column definition + comma ")*". // there might be any number of such columns here $preg_column_definiton. // last column definition ")". // end of group $2 - ",\s*" // the last comma of the last column before the column to change. Do not keep it! + ",\s*+" // the last comma of the last column before the column to change. Do not keep it! .")?"; // there might be no columns before if($debug) echo "preg_columns_before=(".$preg_columns_before.")<hr />"; - $preg_columns_after = "(,\s*([^)]+))?"; // the columns after the column to drop. This is group $3 (drop) or $4(change) (keep!) + $preg_columns_after = "(,\s*(.+))?"; // the columns after the column to drop. This is group $3 (drop) or $4(change) (keep!) // we could remove the comma using $6 instead of $5, but then we might have no comma at all. // Keeping it leaves a problem if we drop the first column, so we fix that case in another regex. $table_new = $table; @@ -876,10 +1307,11 @@ case 'add': if(!isset($matches[4])) { + $this->alterError = $errormsg . ' (add) - '. $lang['alter_no_add_col']; return false; } $new_col_definition = "'$column_escaped' ".$matches[4]; - $preg_pattern_add = "/^".$preg_create_table."(.*)\\)\s*$/"; + $preg_pattern_add = "/^".$preg_create_table."(.*)\\)\s*$/s"; // append the column definiton in the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_add, '$1$2, ', $createtesttableSQL).$new_col_definition.')'; if($debug) @@ -888,50 +1320,58 @@ echo $newSQL."<hr>"; echo $preg_pattern_add."<hr>"; } - if($newSQL==$createtesttableSQL) // pattern did not match, so column removal did not succed + if($newSQL==$createtesttableSQL) // pattern did not match, so column adding did not succed + { + $this->alterError = $errormsg . ' (add) - '.$lang['alter_pattern_mismatch'].'. '.$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; return false; + } $createtesttableSQL = $newSQL; break; case 'change': if(!isset($matches[5]) || !isset($matches[6])) { + $this->alterError = $errormsg . ' (change) - '.$lang['alter_col_not_recognized']; return false; } $new_col_name = $matches[5]; $new_col_type = $matches[6]; $new_col_definition = "'$new_col_name' $new_col_type"; - $preg_column_to_change = "\s*".$this->sqlite_surroundings_preg($column)."(?:\s+".preg_quote($coltypes[$column]).")?(\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\")`\[").")+)?"; + $preg_column_to_change = "\s*".$this->sqlite_surroundings_preg($column)."(?:\s+".preg_quote($coltypes[$column]).")?(\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\"`\[").")+)?"; // replace this part (we want to change this column) // group $3 contains the column constraints (keep!). the name & data type is replaced. - $preg_pattern_change = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_change.$preg_columns_after."\s*\\)\s*$/"; + $preg_pattern_change = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_change.$preg_columns_after."\s*\\)\s*$/s"; // replace the column definiton in the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_change, '$1$2,'.strtr($new_col_definition, array('\\' => '\\\\', '$' => '\$')).'$3$4)', $createtesttableSQL); // remove comma at the beginning if the first column is changed // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+'".preg_quote($tmpname,"/")."'\s+\(),\s*/",'$1',$newSQL); + $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { echo "preg_column_to_change=(".$preg_column_to_change.")<hr />"; echo $createtesttableSQL."<hr />"; echo $newSQL."<hr />"; + echo $preg_pattern_change."<hr />"; } if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed + { + $this->alterError = $errormsg . ' (change) - '.$lang['alter_pattern_mismatch'].'. '.$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; return false; + } $createtesttableSQL = $newSQL; $newcols[$column] = str_replace("''","'",$new_col_name); break; case 'drop': - $preg_column_to_drop = "\s*".$this->sqlite_surroundings_preg($column)."\s+(?:".$this->sqlite_surroundings_preg("*",false,",')\"\[`").")+"; // delete this part (we want to drop this column) - $preg_pattern_drop = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_drop.$preg_columns_after."\s*\\)\s*$/"; + $preg_column_to_drop = "\s*".$this->sqlite_surroundings_preg($column)."\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\"\[`").")+"; // delete this part (we want to drop this column) + $preg_pattern_drop = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_drop.$preg_columns_after."\s*\\)\s*$/s"; // remove the column out of the CREATE TABLE statement $newSQL = preg_replace($preg_pattern_drop, '$1$2$3)', $createtesttableSQL); // remove comma at the beginning if the first column is removed // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+'".preg_quote($tmpname,"/")."'\s+\(),\s*/",'$1',$newSQL); + $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { echo $createtesttableSQL."<hr>"; @@ -939,7 +1379,10 @@ echo $preg_pattern_drop."<hr>"; } if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed + { + $this->alterError = $errormsg . ' (drop) - '.$lang['alter_pattern_mismatch'].'. '.$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; return false; + } $createtesttableSQL = $newSQL; unset($newcols[$column]); break; @@ -950,13 +1393,14 @@ $table_new = $column; break; default: - if($default) echo 'ERROR: unknown alter operation!<hr />'; + if($debug) echo 'ERROR: unknown alter operation!<hr />'; + $this->alterError = $errormsg . $lang['alter_unknown_operation']; return false; } } $droptempsql = 'DROP TABLE '.$this->quote_id($tmpname); - $createnewtableSQL = "CREATE TABLE ".$this->quote($table_new)." ".preg_replace("/^\s*CREATE\s+TEMPORARY\s+TABLE\s+'?".str_replace("'","''",preg_quote($tmpname,"/"))."'?\s+(.*)$/i", '$1', $createtesttableSQL, 1); + $createnewtableSQL = "CREATE TABLE ".$this->quote($table_new)." ".preg_replace("/^\s*CREATE\s+TEMPORARY\s+TABLE\s+'?".str_replace("'","''",preg_quote($tmpname,"/"))."'?\s+(.*)$/is", '$1', $createtesttableSQL, 1); $newcolumns = ''; $oldcolumns = ''; @@ -1039,11 +1483,36 @@ } } + + // checks whether a table has a primary key + public function hasPrimaryKey($table) + { + $query = "PRAGMA table_info(".$this->quote_id($table).")"; + $table_info = $this->selectArray($query); + foreach($table_info as $row_id => $row_data) + { + if($row_data['pk']) + { + return true; + } + + } + return false; + } + //get number of rows in table - public function numRows($table) + public function numRows($table, $dontTakeLong = false) { - $result = $this->select("SELECT Count(*) FROM ".$this->quote_id($table)); - return $result[0]; + // as Count(*) can be slow on huge tables without PK, + // if $dontTakeLong is set and the size is > 2MB only count() if there is a PK + if(!$dontTakeLong || $this->getSize() <= 2000 || $this->hasPrimaryKey($table)) + { + $result = $this->select("SELECT Count(*) FROM ".$this->quote_id($table)); + return $result[0]; + } else + { + return '?'; + } } //correctly escape a string to be injected into an SQL query @@ -1064,7 +1533,7 @@ } } - //correctly escape an identifier (column / table / trigger / index name) to be injected into an SQL query + //correctly escape an identifier (column / table / trigger / index name) to be injected into an SQL query public function quote_id($value) { // double-quotes need to be escaped by doubling them @@ -1131,7 +1600,7 @@ //export csv public function export_csv($tables, $field_terminate, $field_enclosed, $field_escaped, $null, $crlf, $fields_in_first_row) { - $field_enclosed = stripslashes($field_enclosed); + $field_enclosed = $field_enclosed; $query = "SELECT * FROM sqlite_master WHERE type='table' or type='view' ORDER BY type DESC"; $result = $this->selectArray($query); for($i=0; $i<sizeof($result); $i++) @@ -1195,13 +1664,14 @@ //export sql public function export_sql($tables, $drop, $structure, $data, $transaction, $comments) { + global $lang; if($comments) { echo "----\r\n"; - echo "-- phpLiteAdmin database dump (http://phpliteadmin.googlecode.com)\r\n"; - echo "-- phpLiteAdmin version: ".VERSION."\r\n"; - echo "-- Exported on ".date('M jS, Y, h:i:sA')."\r\n"; - echo "-- Database file: ".$this->getPath()."\r\n"; + echo "-- ".PROJECT." ".$lang['db_dump']." (".PROJECT_URL.")\r\n"; + echo "-- ".PROJECT." ".$lang['ver'].": ".VERSION."\r\n"; + echo "-- ".$lang['exported'].": ".date($lang['date_format'])."\r\n"; + echo "-- ".$lang['db_f'].": ".$this->getPath()."\r\n"; echo "----\r\n"; } $query = "SELECT * FROM sqlite_master WHERE type='table' OR type='index' OR type='view' OR type='trigger' ORDER BY type='trigger', type='index', type='view', type='table'"; @@ -1226,7 +1696,7 @@ if($comments) { echo "\r\n----\r\n"; - echo "-- Drop ".$result[$i]['type']." for ".$result[$i]['name']."\r\n"; + echo "-- ".$lang['drop']." ".$result[$i]['type']." ".$lang['for']." ".$result[$i]['name']."\r\n"; echo "----\r\n"; } echo "DROP ".strtoupper($result[$i]['type'])." ".$this->quote_id($result[$i]['name']).";\r\n"; @@ -1237,9 +1707,9 @@ { echo "\r\n----\r\n"; if($result[$i]['type']=="table" || $result[$i]['type']=="view") - echo "-- ".ucfirst($result[$i]['type'])." structure for ".$result[$i]['tbl_name']."\r\n"; + echo "-- ".ucfirst($result[$i]['type'])." ".$lang['struct_for']." ".$result[$i]['tbl_name']."\r\n"; else // index or trigger - echo "-- Structure for ".$result[$i]['type']." ".$result[$i]['name']." on table ".$result[$i]['tbl_name']."\r\n"; + echo "-- ".$lang['struct_for']." ".$result[$i]['type']." ".$result[$i]['name']." ".$lang['on_tbl']." ".$result[$i]['tbl_name']."\r\n"; echo "----\r\n"; } echo $result[$i]['sql'].";\r\n"; @@ -1252,7 +1722,7 @@ if($comments) { echo "\r\n----\r\n"; - echo "-- Data dump for ".$result[$i]['tbl_name'].", a total of ".sizeof($arr)." rows\r\n"; + echo "-- ".$lang['data_dump']." ".$result[$i]['tbl_name'].", ".sprintf($lang['total_rows'], sizeof($arr))."\r\n"; echo "----\r\n"; } $query = "PRAGMA table_info(".$this->quote_id($result[$i]['tbl_name']).")"; @@ -1288,50 +1758,45 @@ } $auth = new Authorization(); //create authorization object -//AstLinux// Disable authorization, always grant permission. -if(! $auth->isAuthorized()) { - $auth->grant(false); -} -// -//if(isset($_POST['logout'])) //user has attempted to log out + +//AstLinux// +// check if user has attempted to log out +//if (isset($_POST['logout'])) // $auth->revoke(); -//else if(isset($_POST['login']) || isset($_POST['proc_login'])) //user has attempted to log in -//{ -// $_POST['login'] = true; -// -// if($_POST['password']==SYSTEMPASSWORD) //make sure passwords match before granting authorization -// { -// if(isset($_POST['remember'])) -// $auth->grant(true); -// else -// $auth->grant(false); -// } -//} +// check if user has attempted to log in +//else if (isset($_POST['login']) && isset($_POST['password'])) +// $auth->attemptGrant($_POST['password'], isset($_POST['remember'])); -if($auth->isAuthorized()) +if ($auth->isAuthorized()) { //user is creating a new Database - if(isset($_POST['new_dbname']) && $auth->isAuthorized()) + if(isset($_POST['new_dbname'])) { - $str = preg_replace('@[^\w-.]@','', $_POST['new_dbname']); - $dbname = $str; - $dbpath = $str; - if(checkDbName($dbname)) + if($_POST['new_dbname']=='') { - $tdata = array(); - $tdata['name'] = $dbname; - $tdata['path'] = $directory.DIRECTORY_SEPARATOR.$dbpath; - $td = new Database($tdata); - $td->query("VACUUM"); - } else + // TODO: Display an error message (do NOT echo here. echo below in the html-body!) + } + else { - if(is_file($dbname) || is_dir($dbname)) $dbexists = true; - else $extension_not_allowed=true; + $str = preg_replace('@[^\w-.]@','', $_POST['new_dbname']); + $dbname = $str; + $dbpath = $str; + if(checkDbName($dbname)) + { + $tdata = array(); + $tdata['name'] = $dbname; + $tdata['path'] = $directory.DIRECTORY_SEPARATOR.$dbpath; + $td = new Database($tdata); + $td->query("VACUUM"); + } else + { + if(is_file($dbname) || is_dir($dbname)) $dbexists = true; + else $extension_not_allowed=true; + } } } - //if the user wants to scan a directory for databases, do so if($directory!==false) { @@ -1351,7 +1816,7 @@ if($subdirectories===false) $arr[$i] = $directory.DIRECTORY_SEPARATOR.$arr[$i]; - if(!is_file($arr[$i])) continue; + if(@!is_file($arr[$i])) continue; $con = file_get_contents($arr[$i], NULL, NULL, 0, 60); if(strpos($con, "** This file contains an SQLite 2.1 database **", 0)!==false || strpos($con, "SQLite format 3", 0)!==false) { @@ -1360,18 +1825,9 @@ $databases[$j]['name'] = basename($arr[$i]); else $databases[$j]['name'] = $arr[$i]; - // 22 August 2011: gkf fixed bug 49. - $perms = 0; - $perms += is_readable($databases[$j]['path']) ? 4 : 0; - $perms += is_writeable($databases[$j]['path']) ? 2 : 0; - switch($perms) - { - case 6: $perms = "[rw] "; break; - case 4: $perms = "[r ] "; break; - case 2: $perms = "[ w] "; break; // God forbid, but it might happen. - default: $perms = "[ ] "; break; - } - $databases[$j]['perms'] = $perms; + $databases[$j]['writable'] = is_writable($databases[$j]['path']); + $databases[$j]['writable_dir'] = is_writable(dirname($databases[$j]['path'])); + $databases[$j]['readable'] = is_readable($databases[$j]['path']); $j++; } } @@ -1391,9 +1847,7 @@ } else //the directory is not valid - display error and exit { - echo "<div class='confirm' style='margin:20px;'>"; - echo "The directory you specified to scan for databases does not exist or is not a directory."; - echo "</div>"; + echo "<div class='confirm' style='margin:20px;'>".$lang['not_dir']."</div>"; exit(); } } @@ -1403,20 +1857,15 @@ { if(!file_exists($databases[$i]['path'])) continue; //skip if file not found ! - probably a warning can be displayed - later - $perms = 0; - $perms += is_readable($databases[$i]['path']) ? 4 : 0; - $perms += is_writeable($databases[$i]['path']) ? 2 : 0; - switch($perms) - { - case 6: $perms = "[rw] "; break; - case 4: $perms = "[r ] "; break; - case 2: $perms = "[ w] "; break; // God forbid, but it might happen. - default: $perms = "[ ] "; break; - } - $databases[$i]['perms'] = $perms; + $databases[$i]['writable'] = is_writable($databases[$i]['path']); + $databases[$i]['writable_dir'] = is_writable(dirname($databases[$i]['path'])); + $databases[$i]['readable'] = is_readable($databases[$i]['path']); } sort($databases); } + // we now have the $databases array set. Check whethet currentDB is a managed Db (is in this array) + if(isset($_SESSION[COOKIENAME.'currentDB']) && isManagedDB($_SESSION[COOKIENAME.'currentDB']['path']) === false) + unset($_SESSION[COOKIENAME.'currentDB']); //user is deleting a database if(isset($_GET['database_delete'])) @@ -1429,7 +1878,7 @@ unlink($dbpath); unset($_SESSION[COOKIENAME.'currentDB']); unset($databases[$checkDB]); - } else die('You can only delete databases managed by this tool!'); + } else die($lang['err'].': '.$lang['delete_only_managed']); } //user is renaming a database @@ -1447,14 +1896,12 @@ // we need to make sure it stays within $directory... $new_realpath = realpath($newpath_parts['dirname']).DIRECTORY_SEPARATOR; $directory_realpath = realpath($directory).DIRECTORY_SEPARATOR; - echo $_POST['newname']."=>".$new_realpath."<br>"; - echo $directory_realpath."<br>"; if(strpos($new_realpath, $directory_realpath)===0) { // its okay, the new directory is within $directory $newpath = $_POST['newname']; } - else die('You either tried to move the database into a directory where it cannot be managed anylonger, or the check if you did this failed because of missing rights.'); + else die($lang['err'].': '.$lang['db_moved_outside']); } if(checkDbName($newpath)) @@ -1462,14 +1909,13 @@ $checkDB = isManagedDB($oldpath); if($checkDB !==false ) { - copy($oldpath, $newpath); - unlink($oldpath); + rename($oldpath, $newpath); $databases[$checkDB]['path'] = $newpath; $databases[$checkDB]['name'] = basename($newpath); $_SESSION[COOKIENAME.'currentDB'] = $databases[$checkDB]; $justrenamed = true; } - else die('You can only rename databases managed by this tool!'); + else die($lang['err'].': '.$lang['rename_only_managed']); } else { @@ -1477,8 +1923,8 @@ else $extension_not_allowed = true; } } + - //user is downloading the exported database file if(isset($_POST['export'])) { @@ -1562,46 +2008,44 @@ <!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" xml:lang="en" lang="en"> <head> -<!-- Copyright <?php echo date("Y"); ?> phpLiteAdmin (http://phpliteadmin.googlecode.com) --> +<!-- Copyright <?php echo date("Y").' '.PROJECT.' ('.PROJECT_URL.')'; ?> --> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> +<link rel="shortcut icon" href="<?php echo PAGE ?>?resource=favicon" /> <title><?php echo PROJECT ?></title> <?php +//AstLinux// use external style sheet. +echo "<link href='/common/phpliteadmin.css' rel='stylesheet' type='text/css' />", PHP_EOL; +//if(isset($_GET['theme'])) $theme = basename($_GET['theme']); +// +// allow themes to be dropped in subfolder "themes" +//if(is_file('themes/'.$theme)) $theme = 'themes/'.$theme; +// +//if (file_exists($theme)) +// // an external stylesheet exists - import it +// echo "<link href='{$theme}' rel='stylesheet' type='text/css' />", PHP_EOL; +//else +// // only use the default stylesheet if an external one does not exist +// echo "<link href='", PAGE, "?resource=css' rel='stylesheet' type='text/css' />", PHP_EOL; +// +//AstLinux// -//AstLinux// Remove built-in stylesheet, only use external one. -echo "<link href='/common/phpliteadmin.css' rel='stylesheet' type='text/css' />"; - if(isset($_GET['help'])) //this page is used as the popup help section { //help section array $help = array ( - 'SQLite Library Extensions' => - 'phpLiteAdmin uses PHP library extensions that allow interaction with SQLite databases. Currently, phpLiteAdmin supports PDO, SQLite3, and SQLiteDatabase. Both PDO and SQLite3 deal with version 3 of SQLite, while SQLiteDatabase deals with version 2. So, if your PHP installation includes more than one SQLite library extension, PDO and SQLite3 will take precedence to make use of the better technology. However, if you have existing databases that are of version 2 of SQLite, phpLiteAdmin will be forced to use SQLiteDatabase for only those databases. Not all databases need to be of the same version. During the database creation, however, the most advanced extension will be used.', - 'Creating a New Database' => - 'When you create a new database, the name you entered will be appended with the appropriate file extension (.db, .db3, .sqlite, etc.) if you do not include it yourself. The database will be created in the directory you specified as the $directory variable.', - 'Tables vs. Views' => - 'On the main database page, there is a list of tables and views. Since views are read-only, certain operations will be disabled. These disabled operations will be apparent by their omission in the location where they should appear on the row for a view. If you want to change the data for a view, you need to drop that view and create a new view with the appropriate SELECT statement that queries other existing tables. For more information, see <a href="http://en.wikipedia.org/wiki/View_... [truncated message content] |