From 8df3db566a3a937b45ebf11adb90d265e6f5e2d4 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 17 Nov 2019 20:45:02 +0100 Subject: initial checking of customized version 1.0rc9 --- setup/cleanupaftersetup.php | 7 + setup/composerit.php | 68 ++ setup/composerit.pl | 24 + setup/composerit2.php | 78 ++ setup/composerit2.pl | 29 + setup/composertest.php | 68 ++ setup/exportdb.php | 27 + setup/images/exclamation.png | Bin 0 -> 1917 bytes setup/images/title.png | Bin 0 -> 13303 bytes setup/index.php | 1226 ++++++++++++++++++++++++ setup/lang/de.php | 22 + setup/lang/en.php | 101 ++ setup/lang/es.php | 100 ++ setup/lang/fr.php | 14 + setup/lang/it.php | 100 ++ setup/lang/zh_cn.php | 46 + setup/styles/setup.css | 177 ++++ setup/styles/theme.css | 994 +++++++++++++++++++ setup/templates/administration.tpl | 79 ++ setup/templates/complete_install.tpl | 50 + setup/templates/database.tpl | 47 + setup/templates/pre_install.tpl | 124 +++ setup/templates/structure.tpl | 56 ++ setup/templates/upgrade.tpl | 76 ++ setup/upgrade.php | 643 +++++++++++++ setup/upgrade/0.9.9.2/flyspray-install.xml | 1049 ++++++++++++++++++++ setup/upgrade/0.9.9.2/flyspray.conf.php | 33 + setup/upgrade/0.9.9.2/lowercase_emails.php | 6 + setup/upgrade/0.9.9.2/update_users.xml | 70 ++ setup/upgrade/0.9.9.2/upgrade.info | 34 + setup/upgrade/0.9.9.4/flyspray-install.xml | 1055 ++++++++++++++++++++ setup/upgrade/0.9.9.4/flyspray.conf.php | 33 + setup/upgrade/0.9.9.4/upgrade.info | 32 + setup/upgrade/0.9.9.4/upgrade.xml | 199 ++++ setup/upgrade/0.9.9.5/flyspray-install.xml | 1058 +++++++++++++++++++++ setup/upgrade/0.9.9.5/flyspray.conf.php | 33 + setup/upgrade/0.9.9.5/upgrade.info | 34 + setup/upgrade/0.9.9.5/upgrade.xml | 41 + setup/upgrade/0.9.9.7/flyspray-install.xml | 1059 +++++++++++++++++++++ setup/upgrade/0.9.9.7/flyspray.conf.php | 30 + setup/upgrade/0.9.9.7/upgrade.info | 35 + setup/upgrade/0.9.9/add_data.php | 34 + setup/upgrade/0.9.9/add_duplicates.php | 41 + setup/upgrade/0.9.9/add_searches.php | 22 + setup/upgrade/0.9.9/clean_unique.php | 67 ++ setup/upgrade/0.9.9/convert_categories.php | 43 + setup/upgrade/0.9.9/convert_private.php | 26 + setup/upgrade/0.9.9/flyspray-begin.xml | 748 +++++++++++++++ setup/upgrade/0.9.9/flyspray-final.xml | 976 +++++++++++++++++++ setup/upgrade/0.9.9/flyspray-install.xml | 1044 ++++++++++++++++++++ setup/upgrade/0.9.9/flyspray.conf.php | 33 + setup/upgrade/0.9.9/rename_columns.php | 14 + setup/upgrade/0.9.9/upgrade.info | 44 + setup/upgrade/0.9.9/upgrade_assignments.php | 31 + setup/upgrade/1.0/datadict-postgres.inc.php | 606 ++++++++++++ setup/upgrade/1.0/flyspray-install.xml | 1373 +++++++++++++++++++++++++++ setup/upgrade/1.0/flyspray.conf.php | 48 + setup/upgrade/1.0/upgrade.info | 70 ++ setup/upgrade/1.0/upgrade.xml | 902 ++++++++++++++++++ setup/upgrade/1.0/varchartotext.php | 17 + 60 files changed, 15096 insertions(+) create mode 100644 setup/cleanupaftersetup.php create mode 100644 setup/composerit.php create mode 100755 setup/composerit.pl create mode 100644 setup/composerit2.php create mode 100755 setup/composerit2.pl create mode 100644 setup/composertest.php create mode 100644 setup/exportdb.php create mode 100644 setup/images/exclamation.png create mode 100644 setup/images/title.png create mode 100644 setup/index.php create mode 100644 setup/lang/de.php create mode 100644 setup/lang/en.php create mode 100644 setup/lang/es.php create mode 100644 setup/lang/fr.php create mode 100644 setup/lang/it.php create mode 100644 setup/lang/zh_cn.php create mode 100644 setup/styles/setup.css create mode 100644 setup/styles/theme.css create mode 100644 setup/templates/administration.tpl create mode 100644 setup/templates/complete_install.tpl create mode 100644 setup/templates/database.tpl create mode 100644 setup/templates/pre_install.tpl create mode 100644 setup/templates/structure.tpl create mode 100644 setup/templates/upgrade.tpl create mode 100644 setup/upgrade.php create mode 100644 setup/upgrade/0.9.9.2/flyspray-install.xml create mode 100644 setup/upgrade/0.9.9.2/flyspray.conf.php create mode 100644 setup/upgrade/0.9.9.2/lowercase_emails.php create mode 100644 setup/upgrade/0.9.9.2/update_users.xml create mode 100644 setup/upgrade/0.9.9.2/upgrade.info create mode 100644 setup/upgrade/0.9.9.4/flyspray-install.xml create mode 100644 setup/upgrade/0.9.9.4/flyspray.conf.php create mode 100644 setup/upgrade/0.9.9.4/upgrade.info create mode 100644 setup/upgrade/0.9.9.4/upgrade.xml create mode 100644 setup/upgrade/0.9.9.5/flyspray-install.xml create mode 100644 setup/upgrade/0.9.9.5/flyspray.conf.php create mode 100644 setup/upgrade/0.9.9.5/upgrade.info create mode 100644 setup/upgrade/0.9.9.5/upgrade.xml create mode 100644 setup/upgrade/0.9.9.7/flyspray-install.xml create mode 100644 setup/upgrade/0.9.9.7/flyspray.conf.php create mode 100644 setup/upgrade/0.9.9.7/upgrade.info create mode 100644 setup/upgrade/0.9.9/add_data.php create mode 100644 setup/upgrade/0.9.9/add_duplicates.php create mode 100644 setup/upgrade/0.9.9/add_searches.php create mode 100644 setup/upgrade/0.9.9/clean_unique.php create mode 100644 setup/upgrade/0.9.9/convert_categories.php create mode 100644 setup/upgrade/0.9.9/convert_private.php create mode 100644 setup/upgrade/0.9.9/flyspray-begin.xml create mode 100644 setup/upgrade/0.9.9/flyspray-final.xml create mode 100644 setup/upgrade/0.9.9/flyspray-install.xml create mode 100644 setup/upgrade/0.9.9/flyspray.conf.php create mode 100644 setup/upgrade/0.9.9/rename_columns.php create mode 100644 setup/upgrade/0.9.9/upgrade.info create mode 100644 setup/upgrade/0.9.9/upgrade_assignments.php create mode 100644 setup/upgrade/1.0/datadict-postgres.inc.php create mode 100644 setup/upgrade/1.0/flyspray-install.xml create mode 100644 setup/upgrade/1.0/flyspray.conf.php create mode 100644 setup/upgrade/1.0/upgrade.info create mode 100644 setup/upgrade/1.0/upgrade.xml create mode 100644 setup/upgrade/1.0/varchartotext.php (limited to 'setup') diff --git a/setup/cleanupaftersetup.php b/setup/cleanupaftersetup.php new file mode 100644 index 0000000..a62ed7d --- /dev/null +++ b/setup/cleanupaftersetup.php @@ -0,0 +1,7 @@ +You can now use Flyspray.'; +?> diff --git a/setup/composerit.php b/setup/composerit.php new file mode 100644 index 0000000..75c2175 --- /dev/null +++ b/setup/composerit.php @@ -0,0 +1,68 @@ + + + + + + + Flyspray Install - Third Party Packages needed + + + +

Step 1: Trying to download Composer

+'; + $argv = array('--disable-tls'); # just for avoiding warnings + ?> +

Step 2: Trying to load composerinstaller into the running php script

+

Wait a few seconds until composerinstaller put his output under the button. Once the output looks good, try installing the dependencies using the button.

+ Install dependencies +
+			';
+		} else {
+			$phpexe='php';
+			# TODO: autodetect the matching commandline php on the host matching the php version of the webserver
+			# Any idea? Using $_SERVER['PHP_PEAR_SYSCONF_DIR'] or $_SERVER['PHPRC'] for detecting can help a bit, but weak hints..
+			# This is just a temp hack for installing flyspray on xampp on Windows
+			if (getenv('OS') == 'Windows_NT' && isset($_SERVER['PHPRC']) && strstr($_SERVER['PHPRC'], 'xampp')) {
+				$phpexe=$_SERVER['PHPRC'].'\php.exe';
+			}
+			shell_exec($phpexe.' -r "readfile(\'https://getcomposer.org/installer\');" | '.$phpexe);
+			if (!is_readable('composer.phar')) {
+				die('Composer installer download failed! Please consider downloading vendors directly from Flyspray support website');
+			}
+			echo 'Successfully downloaded Composer.

'; + echo 'Try to install dependencies'; + } +?> + + diff --git a/setup/composerit.pl b/setup/composerit.pl new file mode 100755 index 0000000..6363430 --- /dev/null +++ b/setup/composerit.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +use CGI; + +$cgi=new CGI; +print $cgi->header(); +print ' + + + +Flyspray Install - curl -sS https://getcomposer.org/installer | php + + + +'; +print '

Trying to load composer stuff

> curl -sS https://getcomposer.org/installer | php
'; +chdir('../'); +@step1= `curl -sS https://getcomposer.org/installer | php`; +print '

Step 1 result


';
+foreach (@step1) {
+    print;
+}
+print '
'; + +print 'Next Step'; diff --git a/setup/composerit2.php b/setup/composerit2.php new file mode 100644 index 0000000..09aade9 --- /dev/null +++ b/setup/composerit2.php @@ -0,0 +1,78 @@ + + + + + + Flyspray Install - Third Party Packages needed - Step 3 + + + + PHP safe_mode is enabled. We currently don\'t know how to run the "php composer.phar install" from php web frontend under this circumstances. +

But lets test if we can workaround it with Perl:

+ Test using Perl: composerit2.pl'; + } else { + echo '

Step 3: Trying to install dependencies

'; + # $argv=('install'); + # chdir('..'); + # echo '
';
+			# require 'composer.phar';
+			# echo '
'; + + # without chdir('..'); + $phpexe='php'; + # TODO: autodetect the matching commandline php on the host matching the php version of the webserver + # Any idea? Using $_SERVER['PHP_PEAR_SYSCONF_DIR'] or $_SERVER['PHPRC'] for detecting can help a bit, but weak hints.. + # This is just a temp hack for installing flyspray on xampp on Windows + if (getenv('OS') == 'Windows_NT' && isset($_SERVER['PHPRC']) && strstr($_SERVER['PHPRC'], 'xampp')) { + $phpexe=$_SERVER['PHPRC'].'\php.exe'; + } + $cmd2 = $phpexe.' composer.phar --working-dir=.. install'; + + # with chdir('..'); + #$cmd2 = 'php composer.phar install'; + + echo $cmd2.'

'; + shell_exec($cmd2); + echo 'Done'; + + echo '

Step 4: Checking and cleaning:

'; + if (is_readable('../vendor/autoload.php')) { + echo 'Composer installation ok
'; + } else { + echo 'Composer installation failed
'; + } + if (is_file('composer.phar')) { + unlink('composer.phar'); + } + echo 'Cleanup made

'; + echo 'Go back'; + } + ?> + + diff --git a/setup/composerit2.pl b/setup/composerit2.pl new file mode 100755 index 0000000..04bd81b --- /dev/null +++ b/setup/composerit2.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl +use CGI; + +$cgi=new CGI; +print $cgi->header( + -expires => 'Sat, 26 Jul 1997 05:00:00 GMT', + -Pragma => 'no-cache', + -Cache_Control => join(', ', qw(private no-cache no-store must-revalidate max-age=0 pre-check=0 post-check=0)), +); +print ' + + + +Flyspray Install - php composer.phar install + + + +'; + +print '

Trying to install packages

'; +print 'Go to setup page'; +#chdir('..'); +@step2= `export COMPOSER_HOME=. ; php composer.phar --working-dir=.. install 2>&1`; +print '
> php composer.phar install
'; +print '
';
+foreach (@step2) {
+    print;
+}
+print '
'; diff --git a/setup/composertest.php b/setup/composertest.php new file mode 100644 index 0000000..b8a5663 --- /dev/null +++ b/setup/composertest.php @@ -0,0 +1,68 @@ + + + + + + Flyspray Install - Third Party Packages needed + + + +

It seems you try to install a development version of Flyspray.

+

+ +

+ In case the above solution doesn't work for you, use ssh to login to your server, move to the root directory of your unpacked flyspray sources and execute this: +

+
+  				curl -sS https://getcomposer.org/installer | php
+  				php composer.phar install
+			
+ +
+

Shared Hostings

+

If you are on a shared hosting, there are probably different php versions available. The hosting companies name them often like php5.4, php5.5-cli or php-cgi-7.0. Choose the best matching php-version for your Hosting (should ideally match that of what the webserver uses). To see available php versions on the commandline type

+
php tab tab
+

tab tab is autocompletion on bash, so it shows all executable that start with php.

+

Lets say the webserver uses PHP 5.6 by default, than a php5.6 you found on the commandline is a good choice:

+
curl -sS https://getcomposer.org/installer | php5.6
+php5.6 composer.phar install
+
+
+ +

Or take an official release, which contains all needed external packages bundled.

+

README.md

+
+
+		
+		
+
+ + diff --git a/setup/exportdb.php b/setup/exportdb.php new file mode 100644 index 0000000..fd714a3 --- /dev/null +++ b/setup/exportdb.php @@ -0,0 +1,27 @@ +Connect( $conf['database']['dbhost'], $conf['database']['dbuser'], + $conf['database']['dbpass'], $conf['database']['dbname']) or die('Cannot connect to DB.'); +$db->debug= true; + +/* Use the database connection to create a new adoSchema object. */ +$schema = new adoSchema($db); + +$withdata=false; +$stripprefix=true; +$data = $schema->ExtractSchema( $withdata, ' ', $conf['database']['dbprefix'], $stripprefix); + +file_put_contents('flyspray-schema.xml', $data); + +?> diff --git a/setup/images/exclamation.png b/setup/images/exclamation.png new file mode 100644 index 0000000..3e788f5 Binary files /dev/null and b/setup/images/exclamation.png differ diff --git a/setup/images/title.png b/setup/images/title.png new file mode 100644 index 0000000..9f615da Binary files /dev/null and b/setup/images/title.png differ diff --git a/setup/index.php b/setup/index.php new file mode 100644 index 0000000..f55e748 --- /dev/null +++ b/setup/index.php @@ -0,0 +1,1226 @@ + +// | Copyright (C) 2006-2007 by Cristian Rodriguez and Florian Schmitz +// +---------------------------------------------------------------------- + +@set_time_limit(0); +ini_set('memory_limit', '64M'); + +define('IN_FS', 1 ); +define('APPLICATION_NAME', 'Flyspray'); +define('BASEDIR', dirname(__FILE__)); +define('APPLICATION_PATH', dirname(BASEDIR)); +define('OBJECTS_PATH', APPLICATION_PATH . '/includes'); +define('TEMPLATE_FOLDER', BASEDIR . '/templates/'); + +require_once OBJECTS_PATH.'/fix.inc.php'; +require_once OBJECTS_PATH.'/class.gpc.php'; +require_once OBJECTS_PATH.'/class.flyspray.php'; +require_once OBJECTS_PATH.'/i18n.inc.php'; +require_once OBJECTS_PATH.'/class.tpl.php'; + +// Load translations +load_translations(); + +# must be sure no-cache before any possible redirect, we maybe come back later here after composer install stuff. +header("Expires: Tue, 03 Jul 2001 06:00:00 GMT"); +header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +if (is_readable(APPLICATION_PATH . '/vendor/autoload.php')){ + // Use composer autoloader + require APPLICATION_PATH . '/vendor/autoload.php'; +} else{ + Flyspray::redirect('composertest.php'); + exit; +} + +// no transparent session id improperly configured servers +ini_set('session.use_trans_sid', 0); +session_start(); + +if (is_readable('../flyspray.conf.php') && count(parse_ini_file('../flyspray.conf.php')) > 0){ + die('
+Flyspray already installed. Use the Upgrader to upgrade your Flyspray, +or delete flyspray.conf.php to run setup. You can *not* use the setup on an existing database.
'); +} + +$conf['general']['syntax_plugin'] = ''; + +// --------------------------------------------------------------------- +// Application Web locations +// --------------------------------------------------------------------- +define('APPLICATION_SETUP_INDEX', Flyspray::absoluteURI()); + +class Setup extends Flyspray +{ + public $mPhpRequired; + public $mSupportedDatabases; + public $mAvailableDatabases; + + public $mProceed; + public $mPhpVersionStatus; + public $mDatabaseStatus; + public $xmlStatus; + public $mConfigText; + public $mHtaccessText; + public $mWriteStatus; + + public $mDbConnection; + public $mProductName; + + /** + * @var string To store the data filter type + */ + public $mDataFilter; + + /** + * @var array To store the type of database setup (install or Upgrade). + */ + + public $mAttachmentsTable; + public $mCommentsTable; + + public $mServerSoftware; + public $mMinPasswordLength; + public $mAdminUsername; + public $mAdminPassword; + /** + * @var object to store the adodb datadict object. + */ + public $mDataDict; + + public $mXmlSchema; + + public function __construct() + { + // Look for ADOdb + $this->mAdodbPath = dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb.inc.php'; + $this->mProductName = 'Flyspray'; + $this->mMinPasswordLength = 8; + + // Initialise flag for proceeding to next step. + $this->mProceed = false; + $this->mPhpRequired = '5.4'; + $this->xmlStatus = function_exists('xml_parser_create'); + $this->sapiStatus = (php_sapi_name() != 'cgi'); + + // If the database is supported in Flyspray, the function to check in PHP. + $this->mSupportedDatabases = array( + 'MySQLi' => array(true,'mysqli_connect','mysqli'), + 'MySQL' => array(true, 'mysql_connect', 'mysql'), + 'Postgres' => array(true, 'pg_connect', 'pgsql'), + ); + $this->mAvailableDatabases = array(); + + // Process the page actions + $this->processActions(); + } + + /** + * Function to check the permission of the config file + * @param void + * @return string An html formatted boolean answer + */ + public function checkWriteability($path) + { + // Get the full path to the file + $file = APPLICATION_PATH .'/' . $path; + + // In case it is flyspray.conf.php, the file does not exist + // so we can't tell that it is writeable. So we attempt to create an empty one + if ($path == 'flyspray.conf.php') { + $fp = @fopen($file, 'wb'); + @fclose($fp); + // Let's try at least... + #@chmod($file, 0666); + @chmod($file, 0644); # looks a bit better than worldwritable + } + if(is_dir($path)){ + # for cache and attachement directories x-bit needed + @chmod($file, 0755); + } + $this->mWriteStatus[$path] = $this->IsWriteable($file); + + // Return an html formated writeable/un-writeable string + return $this->returnStatus($this->mWriteStatus[$path], $type = 'writeable'); + } + + /** + * Function to check the availability of the Database support + * @param void + * @return void + */ + public function checkDatabaseSupport() + { + $status = array(); + + foreach ($this->mSupportedDatabases as $which => $database) + { + // Checking if the database has libraries built into PHP. Returns true/false + $this->mAvailableDatabases[$which]['status'] = function_exists($database[1]); + + // If the Application(Flyspray) supports the available database supported in PHP + $this->mAvailableDatabases[$which]['supported'] = ($database[0] === $this->mAvailableDatabases[$which]['status']) + ? $this->mAvailableDatabases[$which]['status'] + : false; + + // Just transferring the value for ease of veryfying Database support. + $status[] = $this->mAvailableDatabases[$which]['supported']; + + // Generating the output to be displayed + $this->mAvailableDatabases[$which]['status_output'] = + $this->returnStatus($this->mAvailableDatabases[$which]['status'], $type = 'available'); + } + + // Check if any one database support exists. + // Update the status of database availability + $this->mDatabaseStatus = in_array('1', $status); + } + + + /** + * CheckPreStatus + * we proceed or not ? + * @access public + * @return bool + */ + public function checkPreStatus() + { + $this->mProceed = ($this->mDatabaseStatus && $this->mPhpVersionStatus && $this->xmlStatus); + + return $this->mProceed; + } + + + /** + * Function to check the version of PHP available compared to the + * Applications requirements + * @param void + * @return string An html formatted boolean answer + */ + public function checkPhpCompatibility() + { + // Check the PHP version. + $this->mPhpVersionStatus = version_compare(PHP_VERSION, $this->mPhpRequired, '>='); + + // Return an html formated Yes/No string + return $this->returnStatus($this->mPhpVersionStatus, $type = 'yes'); + } + + /** + * Function to check the posted data from forms. + * @param array $expectedFields Array of field names which needs processing + * If the array of filed names don't exist in the Posted data, then this function + * will accumulate error messages in the $_SESSION[PASS_PHRASE]['page_message'] array. + * return boolean/array $data will be returned if successful + */ + public function checkPostedData($expectedFields, $pageHeading) + { + if(!is_array($expectedFields)){ + $expectedFields = array(); + } + + // Grab the posted data and trim it. + $data = array_filter($_POST, array(&$this, "trimArgs")); + + + // Loop through the required values and check data + foreach($expectedFields as $key => $value) + { + + // If the data is Required and is empty or not set + if (!isset($data[$key]) || empty($data[$key])) + { + if ($expectedFields[$key][2] == true) + { + // accumulate error messages + $_SESSION['page_message'][] = "{$expectedFields[$key][0]} is required"; + } + } + // Check for variable types + elseif (!$this->verifyVariableTypes($expectedFields[$key][1], $data[$key])) + { + $_SESSION['page_message'][] = "{$expectedFields[$key][0]} has to be a {$expectedFields[$key][1]}"; + } + } + + // If there were messages, return false + if (isset($_SESSION['page_message'])) + { + $_SESSION['page_heading'] = $pageHeading; + return false; + } + else + { + return $data; + } + } + + public function displayAdministration() + { + // Trim the empty values in the $_POST array + $data = array_filter($_POST, array($this, "trimArgs")); + + $templates = + array( + 'admin_body' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'administration.tpl', + 'vars' => array( + 'product_name' => $this->mProductName, + 'message' => $this->getPageMessage(), + 'admin_email' => $this->getParamValue($data, 'admin_email', ''), + 'pass_phrase' => $this->getParamValue($data, 'pass_phrase', ''), + 'admin_username' => $this->getParamValue($data, 'admin_username', ''), + 'admin_realname' => $this->getParamValue($data, 'admin_realname', ''), + 'admin_xmpp' => $this->getParamValue($data, 'admin_xmpp', ''), + 'admin_password' => $this->getParamValue($data, 'admin_password', substr(md5(mt_rand()), 0, $this->mMinPasswordLength)), + 'db_type' => $this->getParamValue($data, 'db_type', ''), + 'db_hostname' => $this->getParamValue($data, 'db_hostname', ''), + 'db_username' => $this->getParamValue($data, 'db_username', ''), + 'db_password' => $this->getParamValue($data, 'db_password', ''), + 'db_name' => $this->getParamValue($data, 'db_name', ''), + 'db_prefix' => $this->getParamValue($data, 'db_prefix', ''), + 'daemonise' => $this->getReminderDaemonSelection($this->getParamValue($data, 'reminder_daemon', '0')), + ), + ), + + 'structure' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'structure.tpl', + 'vars' => array( + 'title' => 'Administration setup for', + 'headers' => '', + 'index' => APPLICATION_SETUP_INDEX, + 'version' => $this->version, + ), + 'block' => array('body' => 'admin_body') + ) + ); + + // Output the final template. + $this->outputPage($templates); + } + + + public function displayCompletion() + { + // Trim the empty values in the $_POST array + $data = array_filter($_POST, array($this, "trimArgs")); + + $templates = + array( + 'complete_body' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'complete_install.tpl', + 'vars' => array( + 'product_name' => $this->mProductName, + 'message' => $this->getPageMessage(), + 'config_writeable' => $this->mWriteStatus['flyspray.conf.php'], + 'config_text' => $this->mConfigText, + 'admin_username' => $this->mAdminUsername, + 'admin_password' => $this->mAdminPassword, + 'site_index' => dirname($_SERVER['REQUEST_URI']) . '/../', + 'complete_action' => 'index.php', + 'daemonise' => true, + ), + ), + + 'structure' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'structure.tpl', + 'vars' => array( + 'title' => 'Setup confirmation for', + 'headers' => '', + 'index' => APPLICATION_SETUP_INDEX, + 'version' => $this->version, + ), + 'block' => array('body' => 'complete_body') + ) + ); + + // Output the final template. + $this->outputPage($templates); + } + + public function displayDatabaseSetup() + { + + // Trim the empty values in the $_POST array + $data = array_filter($_POST, array($this, "trimArgs")); + $this->checkDatabaseSupport(); + + // Make sure that the user can't choose a DB which is not supported + foreach ($this->mSupportedDatabases as $db => $arr) { + if (!$this->mAvailableDatabases[$db]['supported']) { + unset($this->mSupportedDatabases[$db]); + } + } + + $templates = + array( + 'database_body' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'database.tpl', + 'vars' => array( + 'product_name' => $this->mProductName, + 'message' => $this->getPageMessage(), + 'databases' => $this->mSupportedDatabases, + 'db_type' => $this->getParamValue($data, 'db_type', ''), + 'db_hostname' => $this->getParamValue($data, 'db_hostname', 'localhost'), + 'db_username' => $this->getParamValue($data, 'db_username', ''), + 'db_password' => $this->getParamValue($data, 'db_password', ''), + 'db_name' => $this->getParamValue($data, 'db_name', ''), + 'db_prefix' => $this->getParamValue($data, 'db_prefix', 'flyspray_'), + 'version' => $this->version, + ), + ), + 'structure' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'structure.tpl', + 'vars' => array( + 'title' => 'Database setup for', + 'headers' => '', + 'index' => APPLICATION_SETUP_INDEX, + 'version' => $this->version, + ), + 'block' => array('body' => 'database_body') + ) + ); + + // Output the final template. + $this->outputPage($templates); + } + + + public function displayPreInstall() + { + // Check the Database support on the server. + $this->checkDatabaseSupport(); + + $templates = + array( + 'index_body' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'pre_install.tpl', + 'vars' => array( + 'product_name' => $this->mProductName, + 'required_php' => $this->mPhpRequired, + 'php_output' => $this->checkPhpCompatibility(), + 'database_output' => $this->getDatabaseOutput(), + 'config_output' => $this->checkWriteability('flyspray.conf.php'), + 'cache_output' => $this->checkWriteability('cache'), + 'att_output' => $this->checkWriteability('attachments'), + 'ava_output' => $this->checkWriteability('avatars'), + 'config_status' => $this->mWriteStatus['flyspray.conf.php'], + 'xmlStatus' => $this->xmlStatus, + 'sapiStatus' => $this->sapiStatus, + 'php_settings' => $this->getPhpSettings(), + 'status' => $this->checkPreStatus(), + 'message' => $this->getPageMessage(), + ), + ), + + 'structure' => array( + 'path' => TEMPLATE_FOLDER, + 'template' => 'structure.tpl', + 'vars' => array( + 'title' => 'Pre-Installation Check for', + 'headers' => '', + 'index' => APPLICATION_SETUP_INDEX, + 'version' => $this->version, + ), + 'block' => array('body' => 'index_body') + ) + ); + + // Output the final template. + $this->outputPage($templates); + } + + public function getDatabaseOutput() + { + $output = ''; + // Loop through the supported databases array + foreach ($this->mSupportedDatabases as $which => $database) + { + $output .= " + + - $which support + {$this->mAvailableDatabases[$which]['status_output']} + ". $this->returnStatus($this->mAvailableDatabases[$which]['supported'], $type = 'support') . " + "; + + } + // Return the html formatted results + return $output; + } + + + /** + * Function to get the php ini config values + * @param string $option The ini setting name to check the status for + * @return string The status of the setting either "On" or "OFF" + */ + public function getIniSetting($option) + { + return (ini_get($option) == '1' ? L('on') : L('off')); + } + + /** + * Function to get the error messages and generate an error output for the template + * @string $heading The value for the Error message heading + * The error message is stored in the $_SESSION Global array + * $_SESSION[PASS_PHRASE]['page_message']. If there is no value in + * this array, then there will be no error message outputed. + * @return string $message The message which needs outputting + */ + public function getPageMessage() + { + // If there is an error + if (isset($_SESSION['page_message']) || isset($_SESSION['page_heading'])) + { + $message = ''; + if (isset($_SESSION['page_heading'])) { + $message = '

' . $_SESSION['page_heading'] . '

'; + } + + if (isset($_SESSION['page_message'])) { + // Get an html formated list + $message .= '
' . $this->outputHtmlList($_SESSION['page_message'],'ul') . '
'; + } + + + // Destroy the session value + unset($_SESSION['page_heading']); + unset($_SESSION['page_message']); + + return $message; + } + else + { + return ''; + } + } + + + /** + * Utility function to return a value from a named array or a specified default + * @param array &$arr The array to get the values from + * @param string $name The name of the key to check the value for + * @param string $default The default value if the value is not set with the array + * @return string $value The value to be returned + */ + public function getParamValue(&$arr, $name, $default=null ) + { + $value = isset($arr[$name]) ? $arr[$name] : $default; + return $value; + } + + /** + * Function to get a listing of recommended and actual settings + * for php. + * @param void + * @return string $output HTML formatted string. + */ + public function getPhpSettings() + { + // Array of the setting name, php ini name and the recommended value + $test_settings = + array( + //array ('Safe Mode','safe_mode', L('off')), # removed since PHP5.4 + array ('File Uploads','file_uploads', L('on')), + //array ('Magic Quotes GPC','magic_quotes_gpc', L('off')), # removed since PHP5.4 + //array ('Register Globals','register_globals', L('off')), # removed since PHP5.4 + //array ('Output Buffering','output_buffering', L('off')), + ); + + if (substr(php_sapi_name(), 0, 3) == 'cgi') { + $test_settings[] = array('CGI fix pathinfo','cgi.fix_pathinfo', L('on')); + } + + $output = ''; + + foreach ($test_settings as $recommended) + { + $actual_setting = $this->getIniSetting($recommended[1]); + + $result = ($actual_setting == $recommended[2] ) + ? '' . $recommended[2] . '' + : '' . $actual_setting . ''; + + $output .= + " + + {$recommended[0]}{$recommended[2]}{$result} + + "; + } + return $output; + } + + public function getReminderDaemonSelection($value) + { + $selection = ' '; + $selection .= ' '; + return $selection; + } + + + /** + * Function to check if a particular folder/file is writeable. + * @param string $fileSystem Path to check + * $return boolean true/false + */ + public function isWriteable($fileSystem) + { + // Clear the cache + clearstatcache(); + + // Return the status of the permission + return is_writable($fileSystem); + } + + /** + * Function to Output an Ordered/Un-ordered list from an array. Default list type is un-ordered. + * @param array() $list_array An array list of data to be made into a list. + * @return string $list An HTML list + */ + public function outputHtmlList($list_array = array(), $list_type = 'ul') + { + $list = "<$list_type>"; + foreach ($list_array as $list_item) + { + $list .= '
  • ' . $list_item .'
  • '; + } + $list .= ""; + + return $list; + } + + + /** + * Function to act on all the actions during Flyspray Setup + * The Post variables are extracted for deciding which function to call. + */ + public function processActions() + { + $action = 'index'; + $what = ''; + + extract($_POST); + + switch($action) + { + case 'database': + $this->displayDatabaseSetup(); + break; + + case 'administration': + // Prepare the required data + $required_data = + array( + 'db_hostname' => array('Database hostname', 'string', true), + 'db_type' => array('Database type', 'string', true), + 'db_username' => array('Database username', 'string', true), + 'db_password' => array('Database password', 'string', false), + 'db_name' => array('Database name', 'string', true), + 'db_prefix' => array('Table prefix', 'string', false), + ); + if ($data = $this->checkPostedData($required_data, $message = 'Configuration Error')) + { + // Process the database checks and install tables + if ($this->processDatabaseSetup($data)) + { + // Proceed to Administration part + $this->displayAdministration(); + } + else + { + $_POST['action'] = 'database'; + $this->displayDatabaseSetup(); + } + } + else + { + $_POST['action'] = 'database'; + $this->displayDatabaseSetup(); + } + break; + + case 'complete': + // Prepare the required data + $required_data = array( + 'db_hostname' => array('Database hostname', 'string', true), + 'db_type' => array('Database type', 'string', true), + 'db_username' => array('Database username', 'string', true), + 'db_password' => array('Database password', 'string', false), + 'db_name' => array('Database name', 'string', true), + 'db_prefix' => array('Table prefix', 'string', false), + 'admin_username' => array('Administrator\'s username', 'string', true), + 'admin_realname' => array('Administrator\'s realname', 'string', false), + 'admin_password' => array("Administrator's Password must be minimum {$this->mMinPasswordLength} characters long and", 'password', true), + 'admin_email' => array('Administrator\'s email address', 'email address', true), + 'admin_xmpp' => array('Administrator\'s jabber/xmpp address', 'xmpp address', false), + 'syntax_plugin' => array('Syntax', 'option', true), + 'reminder_daemon' => array('Reminder Daemon', 'option', false), + ); + if ($data = $this->checkPostedData($required_data, $message = 'Missing config values')) { + // Set a page heading in case of errors. + $_SESSION['page_heading'] = 'Administration Processing'; + + if ($this->processAdminConfig($data)) { + $this->displayCompletion($data); + } else { + $_POST['action'] = 'administration'; + $this->displayAdministration(); + } + } else { + $_POST['action'] = 'administration'; + $this->displayAdministration(); + } + break; + + default: + $this->displayPreInstall(); + break; + } + } + + + + public function processAdminConfig($data) + { + // Extract the variables to local namespace + extract($data); + + if(!isset($db_password)) { + $db_password = ''; + } + if(!isset($admin_xmpp)) { + $admin_xmpp = ''; + } + if(!isset($admin_realname)) { + $admin_realname = ''; + } + + if(!isset($syntax_plugin)) { + $syntax_plugin = ''; + } + + $config_intro = + "; + + ; This is the Flysplay configuration file. It contains the basic settings + ; needed for Flyspray to operate. All other preferences are stored in the + ; database itself and are managed directly within the Flyspray admin interface. + ; You should consider putting this file somewhere that isn't accessible using + ; a web browser, and editing header.php to point to wherever you put this file.\n"; + $config_intro = str_replace("\t", "", $config_intro); + + // Create a random cookie salt + $cookiesalt = md5(uniqid(mt_rand(), true)); + + // check to see if to enable the Reminder Daemon. + $daemonise = ( (isset($data['reminder_daemon'])) && ($data['reminder_daemon'] == 1) ) + ? 1 + : 0; + $db_prefix = (isset($data['db_prefix']) ? $data['db_prefix'] : ''); + + $config = array(); + $config[] = "[database]"; + $config[] = "dbtype = \"$db_type\" ; Type of database (\"mysql\", \"mysqli\" or \"pgsql\" are currently supported)"; + $config[] = "dbhost = \"$db_hostname\" ; Name or IP of your database server"; + $config[] = "dbname = \"$db_name\" ; The name of the database"; + $config[] = "dbuser = \"$db_username\" ; The user to access the database"; + $config[] = "dbpass = \"$db_password\" ; The password to go with that username above"; + $config[] = "dbprefix = \"$db_prefix\" ; The prefix to the {$this->mProductName} tables"; + $config[] = "\n"; + $config[] = '[general]'; + $config[] = "cookiesalt = \"$cookiesalt\" ; Randomisation value for cookie encoding"; + $config[] = 'output_buffering = "on" ; Available options: "on" or "gzip"'; + $config[] = 'passwdcrypt = "" ; Available options: "" which chooses best default (coming FS1.0: using crypt/password_hash() with blowfish), "crypt" (auto salted md5), "md5", "sha1" Note: md5 and sha1 are considered insecure for hashing passwords, avoid if possible.'; + $config[] = "dot_path = \"\" ; Path to the dot executable (for graphs either dot_public or dot_path must be set)"; + $config[] = "dot_format = \"png\" ; \"png\" or \"svg\""; + $config[] = "reminder_daemon = \"$daemonise\" ; Boolean. 0 = off, 1 = on (cron job), 2 = on (PHP)."; + $config[] = "doku_url = \"http://en.wikipedia.org/wiki/\" ; URL to your external wiki for [[dokulinks]] in FS"; + $config[] = 'syntax_plugin = "'.$syntax_plugin.'" ; dokuwiki, none, or html'; + $config[] = "update_check = \"1\" ; Boolean. 0=off, 1=on"; + $config[] = "\n"; + $config[] = "[attachments]"; + $config[] = "zip = \"application/zip\" ; MIME-type for ZIP files"; + $config[] = "\n"; + $config[] = "[oauth]"; + $config[] = "; These are only needed if you plan to use them. You can turn them on in the admin panel."; + $config[] = "\n"; + $config[] = 'github_secret = ""'; + $config[] = 'github_id = ""'; + $config[] = 'github_redirect = "YOURDOMAIN/index.php?do=oauth&provider=github"'; + $config[] = 'google_secret = ""'; + $config[] = 'google_id = ""'; + $config[] = 'google_redirect = "YOURDOMAIN/index.php?do=oauth&provider=google"'; + $config[] = 'facebook_secret = ""'; + $config[] = 'facebook_id = ""'; + $config[] = 'facebook_redirect = "YOURDOMAIN/index.php?do=oauth&provider=facebook"'; + $config[] = 'microsoft_secret = ""'; + $config[] = 'microsoft_id = ""'; + $config[] = 'microsoft_redirect = "YOURDOMAIN/index.php"'; + + $config_text = $config_intro . implode( "\n", $config ); + + if (is_writable('../flyspray.conf.php') && ($fp = fopen('../flyspray.conf.php', "wb"))) + { + fputs($fp, $config_text, strlen($config_text)); + fclose($fp); + $this->mWriteStatus['flyspray.conf.php'] = true; + } + else + { + $this->mConfigText = $config_text; + $this->mWriteStatus['flyspray.conf.php'] = false; + } + + + // Setting the database for the ADODB connection + require_once($this->mAdodbPath); + + # 20160408 peterdd: hack to enable database socket usage with adodb-5.20.3 . For instance on german 1und1 managed linux servers ( e.g. $db_hostname ='localhost:/tmp/mysql5.sock' ) + if( $db_type=='mysqli' && 'localhost:/'==substr($db_hostname,0,11) ){ + $dbsocket=substr($db_hostname,10); + $db_hostname='localhost'; + ini_set( 'mysqli.default_socket', $dbsocket ); + } + + $this->mDbConnection = ADONewConnection(strtolower($db_type)); + $this->mDbConnection->connect($db_hostname, $db_username, $db_password, $db_name); + $this->mDbConnection->setCharSet('utf8'); + + // Get the users table name. + $users_table = (isset($db_prefix) ? $db_prefix : '') . 'users'; + + $sql = "SELECT * FROM $users_table WHERE user_id = '1'"; + + // Check if we already have an Admin user. + $result = $this->mDbConnection->execute($sql); + if ($result) + { + // If the record exists, we update it. + $row = $result->fetchRow(); + $this->mAdminUsername = $row['user_name']; + $this->mAdminPassword = $row['user_pass']; + } + + $pwhash= Flyspray::cryptPassword($admin_password); + $update_user = " + UPDATE + $users_table + SET + user_name = ?, + user_pass = ?, + email_address = ?, + jabber_id = ?, + real_name = ? + WHERE + user_id = '1'"; + + $update_params = array($admin_username, $pwhash, $admin_email, $admin_xmpp, $admin_realname); + + $result = $this->mDbConnection->execute($update_user, $update_params); + + if (!$result) + { + $errorno = $this->mDbConnection->metaError(); + $_SESSION['page_heading'] = 'Failed to update Admin users details.'; + $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($errorno)) . ': '. $this->mDbConnection->errorMsg($errorno); + return false; + } + else + { + $this->mAdminUsername = $admin_username; + $this->mAdminPassword = $admin_password; + } + + return true; + } + + + public function processDatabaseSetup($data) + { + require_once($this->mAdodbPath); + + // Perform a number of fatality checks, then die gracefully + if (!defined('_ADODB_LAYER')) + { + trigger_error('ADODB Libraries missing or not correct version'); + } + + # 20160408 peterdd: hack to enable database socket usage with adodb-5.20.3 . For instance on german 1und1 managed linux servers ( e.g. $data['db_hostname'] ='localhost:/tmp/mysql5.sock' ) + if( strtolower($data['db_type'])=='mysqli' && 'localhost:/'==substr($data['db_hostname'],0,11) ){ + $dbsocket=substr($data['db_hostname'],10); + $data['db_hostname']='localhost'; + ini_set( 'mysqli.default_socket', $dbsocket ); + } + + // Setting the database type for the ADODB connection + $this->mDbConnection = ADONewConnection(strtolower($data['db_type'])); + if (!$this->mDbConnection->connect(array_get($data, 'db_hostname'), array_get($data, 'db_username'), array_get($data, 'db_password'), array_get($data, 'db_name'))) + { + $_SESSION['page_heading'] = 'Database Processing'; + switch($error_number = $this->mDbConnection->metaError()) + { + case '-1': + // We are using the unknown error code(-1) because ADOdb library may not have the error defined. + // It could be totally some weird error. + $_SESSION['page_message'][] = $this->mDbConnection->errorMsg(); + return false; + break; + + case '-24': + // Could not connect to database with the hostname provided + $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($error_number)) . ': ' . ucfirst($this->mDbConnection->ErrorMsg($error_number)); + $_SESSION['page_message'][] = 'Usually the database host name is "localhost". In some occassions, it maybe an internal ip-address or another host name to your webserver.'; + $_SESSION['page_message'][] = 'Double check with your hosting provider or System Administrator.'; + return false; + break; + + case '-25': + // Database does not exist, try to create one + $this->mDbConnection = ADONewConnection(strtolower($data['db_type'])); + $this->mDbConnection->connect(array_get($data, 'db_hostname'), array_get($data, 'db_username'), array_get($data, 'db_password')); + $dict = NewDataDictionary($this->mDbConnection); + + # if possible set correct default character set for mysql. + # MySQL below 5.5.3 only supports 1,2,3 byte chars of utf8. But some language's chars or emojis(argh) are defined as 4byte chars + $mysqldbcharset='DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci'; # default for mysql for compat + if( $data['db_type']=='mysqli' || $data['db_type']=='mysql' ) { + $dbinfo=$this->mDbConnection->serverInfo(); # provides 'description' and 'version' + if( version_compare($dbinfo['version'], '5.5.3') >=0 ){ + $mysqldbcharset='DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci'; + $this->mDbConnection->setCharSet('utf8mb4'); + }else{ + $mysqldbcharset='DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci'; + $this->mDbConnection->setCharSet('utf8'); + $_SESSION['page_message'][]='Your MySQL server '.$dbinfo['version'].' < 5.5.3, so database has limited utf8 support (no unicode emojis for instance). Upgrading your MySQL server to 5.5.3 or newer is suggested.'; + } + }else{ + # postgresql + $this->mDbConnection->setCharSet('utf8'); + } + + $sqlarray = $dict->createDatabase(array_get($data, 'db_name'), array('mysql'=>$mysqldbcharset) ); + + if (!$dict->executeSQLArray($sqlarray)) { + $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($error_number)) . ': ' . ucfirst($this->mDbConnection->ErrorMsg($error_number)); + $_SESSION['page_message'][] = 'Your database does not exist and could not be created. Either create the database yourself, choose an existing database or + use a database user with sufficient permissions to create a database.'; + return false; + } else { + $this->mDbConnection->selectDB(array_get($data, 'db_name')); + unset($_SESSION['page_heading']); + break; + } + + case '-26': + // Username passwords don't match for the hostname provided + $_SESSION['page_message'][] = ucfirst($this->mDbConnection->metaErrorMsg($error_number)) . ': ' . ucfirst($this->mDbConnection->ErrorMsg($error_number)); + $_SESSION['page_message'][] = "Apparently you haven't set up the right permissions for the database hostname provided."; + $_SESSION['page_message'][] = 'Double check the provided credentials or contact your System Administrator for further assistance.'; + return false; + break; + + default: + $_SESSION['page_message'][] = "Please verify your username/password/database details (error=$error_number)" . $this->mDbConnection->MetaErrorMsg($error_number); + return false; + break; + } + } + // Check that table prefix is OK, some DBs don't like it + $prefix = array_get($data, 'db_prefix'); + if (strlen($prefix) > 0 && is_numeric($prefix[0])) { + $_SESSION['page_heading'] = 'Database Processing'; + $_SESSION['page_message'][] = 'The table prefix may not start with a number.'; + return false; + } + + // Setting the Fetch mode of the database connection. + $this->mDbConnection->setFetchMode(ADODB_FETCH_BOTH); + + if( $data['db_type']=='mysqli') { + $dbinfo=$this->mDbConnection->serverInfo(); # provides 'description' and 'version' + if( version_compare($dbinfo['version'], '5.5.3') >=0 ){ + $this->mDbConnection->setCharSet('utf8mb4'); + }else{ + $this->mDbConnection->setCharSet('utf8'); + } + }else{ + $this->mDbConnection->setCharSet('utf8'); + } + + //creating the datadict object for further operations + $this->mDataDict = NewDataDictionary($this->mDbConnection); + + include_once dirname($this->mAdodbPath) . '/adodb-xmlschema03.inc.php'; + + $this->mXmlSchema = new adoSchema($this->mDbConnection); + + // Populate the database with the new tables and return the result (boolean) + if (!$this->populateDb($data)) + { + return false; + } + + return true; + } + + /** + * Function to populate the database with the sql constructs which is in an sql file + * @param array $data The actual database configuration values + * @return boolean + */ + + public function populateDb($data) + { + // Check available upgrade scripts, use the script of very latest version + $folders = glob_compat(BASEDIR . '/upgrade/[0-9]*'); + usort($folders, 'version_compare'); // start with lowest version + $folders = array_reverse($folders); // start with highest version + $sql_file = APPLICATION_PATH . '/setup/upgrade/' . reset($folders) . '/flyspray-install.xml'; + + $upgradeInfo = APPLICATION_PATH . '/setup/upgrade/' . reset($folders) . '/upgrade.info'; + $upgradeInfo = parse_ini_file($upgradeInfo, true); + + // Check if the install/upgrade file exists + if (!is_readable($sql_file)) { + + $_SESSION['page_message'][] = 'SQL file required for importing structure and data is missing.'; + return false; + } + + // Extract the variables to local namespace + extract($data); + if (!isset($db_prefix)) { + $db_prefix = ''; + } + + if(is_numeric($db_prefix)) { + $_SESSION['page_message'][] = 'database prefix cannot be numeric only'; + return false; + } + + // Set the prefix for database objects ( before parsing) + $this->mXmlSchema->setPrefix( (isset($db_prefix) ? $db_prefix : ''), false); + $this->mXmlSchema->parseSchema($sql_file); + + $this->mXmlSchema->executeSchema(); + + // Last but not least global prefs update + if (isset($upgradeInfo['fsprefs'])) { + $existing = $this->mDbConnection->getCol("SELECT pref_name FROM {$db_prefix}prefs"); + // Add what is missing + foreach ($upgradeInfo['fsprefs'] as $name => $value) { + if (!in_array($name, $existing)) { + $this->mDbConnection->execute("INSERT INTO {$db_prefix}prefs (pref_name, pref_value) VALUES (?, ?)", array($name, $value)); + } + } + // Delete what is too much + foreach ($existing as $name) { + if (!isset($upgradeInfo['fsprefs'][$name])) { + $this->mDbConnection->execute("DELETE FROM {$db_prefix}prefs WHERE pref_name = ?", array($name)); + } + } + } + + $this->mDbConnection->execute("UPDATE {$db_prefix}prefs SET pref_value = ? WHERE pref_name = 'fs_ver'", array($this->version)); + + if (($error_no = $this->mDbConnection->metaError())) + { + $_SESSION['page_heading'] = 'Database Processing'; + switch ($error_no) + { + case '-5': + // If there are tables with the same name + $_SESSION['page_message'][] = 'Table ' .$this->mDbConnection->metaErrorMsg($this->mDbConnection->metaError()); + $_SESSION['page_message'][] = 'There probably are tables in the database which have the same prefix you provided.'; + $_SESSION['page_message'][] = 'It is advised to change the prefix provided or you can drop the existing tables if you don\'t need them. Make a backup if you are not certain.'; + return false; + break; + + case '-1': + // We are using the unknown error code(-1) because ADOdb library may not have the error defined. + $_SESSION['page_message'][] = $this->mDbConnection->errorMsg(); + return false; + break; + + default: + $_SESSION['page_message'][] = $this->mDbConnection->errorMsg() . ': ' . $this->mDbConnection->errorNo(); + $_SESSION['page_message'][] = 'Unknown error, please notify Developer quoting the error number'; + return false; + break; + } + } + + return true; + } + + + + + /** + * Function to return status of boolean results in html format + * @param boolean $boolean The status of the result in True/False form + * @param string $type The type of html format to return + * @return string Depending on the type of format to return + */ + public static function returnStatus($boolean, $type = 'yes') + { + // Do a switch on the type of status + switch($type) + { + case 'yes': + return ($boolean) + ? ''.L('yes').'' + : ''.L('no').''; + break; + + case 'available': + return ($boolean) + ? ''.L('available').'' + : ''.L('missing').''; + break; + + case 'writeable': + return ($boolean) + ? ''.L('writeable').'' + : ''.L('unwriteable').''; + break; + + case 'on': + return ($boolean) + ? ''.L('on').'' + : ''.L('off').''; + break; + case 'support': + return ($boolean) + ? ''.L('supported').'' + : ''.L('x').''; + break; + default: + return ($boolean) + ? ''.L('true').'' + : ''.L('false').''; + break; + } + } + + /** + * To verify if a string was empty or not. + * + * Usually used to validate user input. If the user has inputted empty data + * or just blank spaces, we need to trim of such empty data and see if + * anything else is left after trimming. If there is data remaining, then + * the return value will be greater than 0 else it will be 0 (zero) which + * equates to a true/false scenario + * + * @param string $arg The data to be checked + * + * @return The result of the check. + */ + public function trimArgs($arg) + { + return strlen(trim($arg)); + } + + public function verifyVariableTypes($type, $value) + { + $message = ''; + switch($type) + { + case 'string': + return is_string($value); + break; + + case 'number': + return is_numeric($value); + break; + + case 'xmpp address': + case 'email address': + return filter_var($value, FILTER_VALIDATE_EMAIL); + break; + + case 'boolean': + return (bool) $value; + break; + + case 'password': + return (strlen($value) >= $this->mMinPasswordLength); + break; + + case 'folder': + return is_dir($value); + break; + + default: + return true; + break; + } + } + + /** + * Function to output the templates + * @param array $templates The collection of templates with their associated variables + * + */ + public function outputPage($templates = array()) + { + if (sizeof($templates) == 0) + { + trigger_error("Templates not configured properly", E_USER_ERROR); + } + + // Define a set of common variables which plugin to the structure template. + $page = new Tpl; + $body = ''; + + // Loop through the templates array to dynamically create objects and assign variables to them. + /// XXX: this is not a common way to use our template class, but I didn't want to rewrite + /// the whole setup only to change the templating engine + foreach($templates as $name => $module) + { + foreach ($module['vars'] as $var_name => $value) { + $page->assign($var_name, $value); + } + + if ($name == 'structure') { + $page->assign('body', $body); + $page->display('structure.tpl'); + } else { + $body .= $page->fetch($module['template']); + } + } + } +} + +//start the installer, it handles the rest inside the class +new Setup(); diff --git a/setup/lang/de.php b/setup/lang/de.php new file mode 100644 index 0000000..2d76ae0 --- /dev/null +++ b/setup/lang/de.php @@ -0,0 +1,22 @@ + 'verfügbar', +'missing' => 'fehlt', +'needcomposer' => 'Flyspray benötigt einige zusätzliche Programmbibliotheken, die mit Composer installiert werden können.', +'no' => 'nein', +'installcomposer' => 'Starte Composer', +'performupgrade' => 'Aktualisierung durchführen', +'precautions' => 'Vorsichtsmaßnahmen', +'precautionbackup' => 'Erstelle eine Sicherung deiner Datenbank und aller zu Flyspray gehörenden Dateien vor der Aktualisierung', +'preconditionchecks' => 'Voraussetzungen', +'proceedtodbsetup' => 'weiter zu den Datenbankeinstellungen', +'recommended' => 'empfohlen', +'supported' => 'unterstützt', +'upgrade' => 'Aktualisierung', +'upgradepossible' => 'Eine Aktualisierung ist möglich.', +'versioncompare' => 'Deine derzeitige Flysprayversion ist %s und es kann auf Version %s aktualisiert werden.', +'writeable' => 'schreibbar', +'writeaccessconf' => 'Um Flyspray zu aktualisieren muß Lese- und Schreibrecht für flyspray.conf.php existieren.', +'yes' => 'ja', +); +?> diff --git a/setup/lang/en.php b/setup/lang/en.php new file mode 100644 index 0000000..e848e9b --- /dev/null +++ b/setup/lang/en.php @@ -0,0 +1,101 @@ + 'You need some required libraries installed by Composer.', +'installcomposer' => 'Run Composer', +'performupgrade' => 'Perform Upgrade', +'precautions' => 'Precautions', +'precautionbackup' => 'Create a backup of your database and all Flyspray related files before performing the upgrade.', +'preconditionchecks' => 'Precondition checks', +'upgrade' => 'Upgrade', +'upgradepossible' => 'Apparently, an upgrade is possible.', +'versioncompare' => 'Your current version is %s and the version we can upgrade to is %s.', +'writeaccessconf' => 'In order to upgrade Flyspray correctly it needs to be able to access and write flyspray.conf.php.', +'adminemail' => 'Admin Email Address', +'adminxmpp' => 'Admin Jabber Address', +'adminusername' => 'Admin Username', +'adminrealname' => 'Admin Realname', +'adminpassword' => 'Admin Password', +'slogan' => 'The bug Killer!', +'progress' => 'Progress', +'documents' => 'Docs', +'preinstallcheck' => 'Pre-installation Check', +'databasesetup' => 'Database Setup', +'administration' => 'Administration', +'installflyspray' => 'Install Flyspray', +'libcheck' => 'PHP and Supported Libraries', +'libchecktext' => 'To make setup possible, you must have a correct PHP version installed and at least one supported database.', +'recsettings' => 'Recommended Settings', +'recsettingstext1' => 'These settings are recommended for PHP in order to ensure full compatibility with Flyspray.', +'recsettingstext2' => 'However, Flyspray will still operate if your settings do not quite match the recommended shown here.', +'dirandfileperms' => 'Directory and File Permissions', +'dirandfilepermstext'=> 'In order for Flyspray to function correctly it needs to be able to access or write to certain files or directories. If you see "Unwriteable" you need to change the permissions on the file or directory to allow Flyspray to write to it.', +'proceedtodbsetup' => 'Proceed to Database Setup', +'proceedtodbsetuptext'=>'All configurations seems to be in place. You may proceed to the Database Setup page.', +'library' => 'library', +'status' => 'status', +'database' => 'database', +'recommended' => 'Recommended', +'actual' => 'Actual', +'yes' => 'Yes', +'no' => 'No', +'explainwhatandwhyheader' => 'Formatting of task descriptions and comments has changed', +'explainwhatandwhycontent' => 'Previously those installations of Flyspray that didn\'t use dokuwiki formatting engine stored data as plain text. ' + . 'We now use HTML as the default and can try to add paragraph and line break tags to already existing data entries, so your data retains it\'s ' + . 'structure. But if your existing data already contains manually added HTML tags something probably goes wrong and you have some corrupted ' + . 'entries in your database that must be manually fixed. If unsure, answer "No", unless you can examine the situation before proceeding. ' + . 'If you are fluent in programming with PHP, see also at the end of setup/upgrade.php, look at what it does and possibly modify according to ' + . 'your needs. ', +'databaseconfiguration'=>'Database Configuration for ', +'proceedtoadmin'=>'Proceed to Administration setup', +'databasehostname'=>'database hostname', +'databasehostnamehint'=>'Enter the database hostname of the server Flyspray is to be installed on. This is usually "localhost" or an IP.', +'databasetype'=>'database type', +'databasetypehint'=>'Choose the database type. If you have both the choice between MySQL driver and MySQLi driver, use MySQLi. The old MySQL driver (mysql_*) is deprecated in PHP since a long time. If you have MariaDB as MySQL replacement, select MySQLi.', +'databasename'=>'database name', +'databasenamehint'=>'Insert a name of an existing database or a new name. If the database not exists, Flyspray tries to create that database for you. Use simple names like "flyspray".', +'databaseusername'=>'database username', +'databaseusernamehint'=>'Enter the database username and password. +Flyspray requires that you have a database setup with a username and password to install the database schema. +If you are not sure about these details, please consult with your administrator or web hosting provider. +(Local xampp or wampp servers default installs could work with "root" and an empty password field)', +'databasepassword'=>'database password', +'databasepasswordhint'=>'', +'tableprefix'=>'table prefix', +'tableprefixhint'=>'Optional table prefix to avoid collisions with existing tables. "flyspray_" or "fs_" are good choices.', +'next'=>'Next', +'showpassword' => 'Show Password', +'lgpllicense' => 'LGPL License', +'installationguide' => 'Install Guide', +'developermanual' => "Developer's Manual", +'supported' => 'Supported', +'inphp' => 'in PHP', +'available' => 'Available', +'missing' => 'Missing', +'writeable' => 'Writeable', +'unwriteable' => 'Un-writeable', +'on' => 'ON', +'off' => 'OFF', +'x' => 'X', +'true' => 'True', +'false' => 'False', +'directive' => 'Directive', +'enable' => 'Enable', +'disable' => 'Disable', +'administrationsetup' => 'Administration setup', +'setupapplicationvalue' => 'Setup all the Application values', +'adminsetuptip1' => 'The Database schema has been populated. Please follow the instructions to complete the Admin configuration.', +'adminsetuptip2' => '1) Admin Email, Username, Password are values for the Administrator of your Flyspray Installation. You can change these values through the administration section of Flyspray.', +'adminsetuptip3' => 'Choosing a Syntax is a setting that cannot be simply changed and is set at install for the whole Flyspray installation. Choose Text/Dokuwiki if you are unsure which you choose.', +'syntax' => 'Syntax', +'syntaxtext' => 'If you are unsure choose Text/Dokuwiki. The switch from dokuwiki to HTML is easy. But a switch from HTML back to dokuwiki or another text format like markdown is nearly impossible without some information loss like deep nested HTML content or formatting.', +'scheduletitle' => 'You can setup a crontab entry that calls scheduler.php in a time interval. This setting can be switched on/off everytime in Flyspray admin section.', +'enablescheduling' => 'Enable scheduling', +'proceedtofinalsetup' => 'Proceed to final Setup', +'proceedtofinalsetuptext' => 'Proceed to complete Flyspray setup.', +'installstatus' => 'Install status', +'congratulations' => 'Congratulations! Flyspray is now installed and ready to use.', +'removesetupdirectory' => 'Please remove the setup directory now.', +'viewsite' => 'View Site', +'proceedtoindex' => 'Proceed to Flyspray index', +); +?> diff --git a/setup/lang/es.php b/setup/lang/es.php new file mode 100644 index 0000000..2fb4874 --- /dev/null +++ b/setup/lang/es.php @@ -0,0 +1,100 @@ + 'Parece que estás instalando una versión de desarrollo de Flyspray.', +'needcomposer' => 'Es necesario instalar algunas librerías usando Composer.', +'installcomposer' => 'Ejecutar Composer', +'performupgrade' => 'Perform Upgrade', +'precautions' => 'Advertencias', +'precautionbackup' => 'Antes de actualizar se recomienta realizar una copia de seguridad de ficheros y base de datos de FlySpray.', +'preconditionchecks' => 'Precondition checks', +'upgrade' => 'Actualizar', +'upgradepossible' => 'Parece que hay una actualización disponible', +'versioncompare' => 'Your current version is %s and the version we can upgrade to is %s.', +'writeaccessconf' => 'Para actualizar Flyspray el fichero
    flyspray.conf.php
    debe tener permisos de escritura', +'adminemail' => 'Email del administrador', +'adminusername' => 'Usuario administrador', +'adminpassword' => 'Contraseña del administrador', +'slogan' => 'The bug Killer!', +'progress' => 'Progress', +'documents' => 'Docs', +'preinstallcheck' => 'Pre-instalacion', +'databasesetup' => 'Base de Datos', +'administration' => 'Aplicación', +'installflyspray' => 'Instalación Flyspray', +'libcheck' => 'PHP y módulos requeridos', +'libchecktext' => 'Para poder completar correctamente la instalación de FlySpray, debes tener instalado una versión de PHP y al menos una base de datos compatible.', +'recsettings' => 'Configuración recomendada', +'recsettingstext1' => 'A continuación se indica la configuración de PHP recomendada para asegurar la compatibilidad de Flyspray.', +'recsettingstext2' => 'Nota: No obstante, es posible que FlySpray funcione con una configuración diferente a la recomendada.', +'dirandfileperms' => 'Permisos en carpetas y ficheros', +'dirandfilepermstext'=> 'Para poder utilizar Flyspray se necesita tener acceso de escritura en determinados ficheros y carpetas. + Si se muestra el mensaje "Sin permiso de escritura" será necesario cambiar los permisos de forma que el servidor de Flyspray pueda escribir en ellos', +'proceedtodbsetup' => 'Ir a Configuración de Base de Datos', +'proceedtodbsetuptext'=>'Cuando la configuración sea correcta, continua al siguiente paso para configurar la base de datos.', +'library' => 'Módulo', +'status' => 'Estado', +'database' => 'Base de datos', +'recommended' => 'Recomendada', +'actual' => 'Actual', +'yes' => 'Sí', +'no' => 'No', +'explainwhatandwhyheader' => 'Formatting of task descriptions and comments has changed', +'explainwhatandwhycontent' => 'Previously those installations of Flyspray that didn\'t use dokuwiki formatting engine stored data as plain text. ' + . 'We now use HTML as the default and can try to add paragraph and line break tags to already existing data entries, so your data retains it\'s ' + . 'structure. But if your existing data already contains manually added HTML tags something probably goes wrong and you have some corrupted ' + . 'entries in your database that must be manually fixed. If unsure, answer "No", unless you can examine the situation before proceeding. ' + . 'If you are fluent in programming with PHP, see also at the end of setup/upgrade.php, look at what it does and possibly modify according to ' + . 'your needs. ', +'databaseconfiguration'=>'Configuración de la Base de Datos para ', +'proceedtoadmin'=>'Ir a la Configuración del Administrador', +'databasehostname'=>'Servidor ', +'databasehostnamehint'=>'Introduce el host del servidor de base de datos donde se instalará la BDD de Flyspray. Normalmente se usa "localhost" o una dirección IP.', +'databasetype'=>'Tipo ', +'databasetypehint'=>'Selecciona el tipo de base de datos. Si están disponible las opciones MySQL y MySQLi, seleccione esta última. Idem si su base de datos es MariaDB en lugar de MySQL', +'databasename'=>'Esquema (nombre)', +'databasenamehint'=>'Introduce el nombre de la base de datos (esquema). Si no existe Flyspray intentará crearlo por ti. Nota: Usa nombres simples sin espacios, ej. "flyspray".', +'databaseusername'=>'Usuario', +'databaseusernamehint'=>'Introduce el usuario y contraseña de la base de datos. +El configurador de Flyspray requiere un usuario que tenga permisos para crear el esquema de base de datos. +Si no estás seguro, por favor, consulta con tu administrador o proveedor de hosting. +Nota: Los servidores Xampp o Wampp, por defecto, se instalan con un usuario "root" sin password (vacío)', +'databasepassword'=>'Contraseña', +'databasepasswordhint'=>'', +'tableprefix'=>'Prefijo de las tablas', +'tableprefixhint'=>'[Opcional] puedes indicar un prefijo para evitar la colisión con tablas existentes. Se recomienda "flyspray_" o "fs_"', +'next'=>'Next', +'showpassword' => 'Mostrar Password', +'lgpllicense' => 'Licencia LGPL', +'installationguide' => 'Guía de instalación', +'developermanual' => "Manual del desarrollador", +'supported' => 'Soportado', +'inphp' => 'en PHP', +'available' => 'Sí', +'missing' => '--', +'writeable' => 'Escribible', +'unwriteable' => 'Sin permiso de escritura', +'on' => 'ON', +'off' => 'OFF', +'x' => 'X', +'true' => 'Verdadero', +'false' => 'Falso', +'directive' => 'Directiva', +'enable' => 'Activo', +'disable' => 'Desactivado', +'administrationsetup' => 'Configuración de la aplicación', +'setupapplicationvalue' => '', +'adminsetuptip1' => 'El esquema de base de datos de Flyspray ha sido creado. Por favor, sigue las instrucciones para completar la configuración de la aplicación.', +'adminsetuptip2' => '1) Introduce los valores de Usuario, correo electrónico y contraseña del usuario administrador de Flyspray. Puedes cambiar estos valores desde en la sección de administración de Flyspray.', +'adminsetuptip3' => '2) Selecciona el formado de documentación. Importante: este valor es configurado durante la instalación y no puede ser cambiado posteriormente. Selecciona Text/Dokuwiki si no estás seguro de cual elegir.', +'syntaxtext' => 'Sintaxis
    Selecciona Text/docuwiki si no estás seguro de cual elegir. Nota: El cambio de dokuwiki a Html es sencillo. Sin embargo el cambio de Html a dokuwiki u otro formato (como markdown) conlleva pérdidas de información, tanto contenido como formato.', +'scheduletitle' => 'Recuerda añadir una entrada en el crontab que llame al script "scheduler.php" de forma periódica. El planificador puede ser activado/desactivado desde la sección de administración de Flyspray.', +'enablescheduling' => 'Activar planificador de tareas', +'proceedtofinalsetup' => 'Finalizar instalación', +'proceedtofinalsetuptext' => 'Continua para completar la instalación de Flyspray.', +'installstatus' => 'Estado de la instalación', +'congratulations' => 'Enhorabuena! Flyspray está instalado y listo para usar.', +'removesetupdirectory' => 'Por favor, borra el directorio setup antes de seguir.', +'viewsite' => 'Finalizar y acceder a Flyspray', +'proceedtoindex' => 'Ir a la página principal de Flyspray', +); +?> diff --git a/setup/lang/fr.php b/setup/lang/fr.php new file mode 100644 index 0000000..ffd5091 --- /dev/null +++ b/setup/lang/fr.php @@ -0,0 +1,14 @@ + 'Vous avez besoin de certaines librairies installées par Composer.', +'installcomposer' => 'Lancer Composer', +'performupgrade' => 'Procéder à la mise à jour', +'precautions' => 'Précautions', +'precautionbackup' => 'Créez une sauvegarde de votre base de données ainsi que de tous les fichiers de Flyspray avant tout mise à jour.', +'preconditionchecks' => 'Contrôle des préconditions', +'upgrade' => 'Mise à jour', +'upgradepossible' => 'Apparemment la mise à jour n\'est pas possible.', +'versioncompare' => 'Votre version actuelle est %s et la version vers laquelle nous pouvons mettre à jour est %s.', +'writeaccessconf' => 'Afin de mettre à jour correctement Flyspray, nous avons besoin d\'accéder en lecture et écriture le fichier flyspray.conf.php.', +); +?> diff --git a/setup/lang/it.php b/setup/lang/it.php new file mode 100644 index 0000000..9e4f3eb --- /dev/null +++ b/setup/lang/it.php @@ -0,0 +1,100 @@ + 'Sono richieste alcune librerie installate da Composer.', +'installcomposer' => 'Esegui Composer', +'performupgrade' => 'Esegui Aggiornamento', +'precautions' => 'Attenzione', +'precautionbackup' => 'Crea un backup del database e di tutti i file relativi a Flyspray prima di eseguire l\'aggiornamento', +'preconditionchecks' => 'Verifica dei prerequisiti', +'upgrade' => 'Aggiorna', +'upgradepossible' => 'Sembra che sia possibile aggiornare.', +'versioncompare' => 'La tua versione installata è %s e la versione a cui si può aggiornare è %s.', +'writeaccessconf' => 'Per essere aggiornato correttamente Flyspray deve avere i diritti di lettura e scrittura su flyspray.conf.php.', +'adminemail' => 'Indirizzo Email di Admin', +'adminxmpp' => 'Indirizzo Jabber di Admin', +'adminusername' => 'Username di Admin', +'adminrealname' => 'Nome Reale di Admin', +'adminpassword' => 'Password di Admin', +'slogan' => 'The bug Killer!', +'progress' => 'Avanzamento', +'documents' => 'Documentazione', +'preinstallcheck' => 'Verifiche Preliminari', +'databasesetup' => 'Impostazione Database', +'administration' => 'Amministrazione', +'installflyspray' => 'Installa Flyspray', +'libcheck' => 'PHP e Librerie Supportate', +'libchecktext' => 'Per eseguire l\'installazione devi avere la versione corretta di PHP ed almeno uno dei database supportati.', +'recsettings' => 'Impostazioni Consigliate', +'recsettingstext1' => 'Queste sono le impostazioni di PHP consigliate per la piena compatibilità con Flyspray.', +'recsettingstext2' => 'Ad ogni modo, Flyspray può funzionare anche se le tue impostazioni non sono totalmente corrispondenti a quelle consigliate.', +'dirandfileperms' => 'Permessi per File e Directory', +'dirandfilepermstext'=> 'Per funzionare correttamente Flyspray deve avere accesso, a volte anche in scrittura, ad alcuni file e directory. Se vedi la scritta "Non scrivibile" devi cambiare i permessi sul file o la directory corrispondente per consentirne l\'accesso a Flyspray.', +'proceedtodbsetup' => 'Prosegui con il Setup del Database', +'proceedtodbsetuptext'=>'Tutte le configurazioni sembrano corrette. Puoi proseguire con l\'impostazione del database', +'library' => 'Libreria', +'status' => 'Stato', +'database' => 'database', +'recommended' => 'Consigliato', +'actual' => 'Attuale', +'yes' => 'Sì', +'no' => 'No', +'explainwhatandwhyheader' => 'La formattazione nella descrizione dei task e nei commenti è cambiata', +'explainwhatandwhycontent' => 'Precedentemente, le installazioni di Flyspray che non usavano il motore di formattazione di Dokuwiki memorizzavano i dati come testo semplice. ' + . 'Adesso utilizziamo HTML come default e proviamo ad aggiungere i tag di paragrafo e a capo ai dati preesitenti così i tuoi dati mantengono ' + . 'la propria struttura. Se i tuoi dati contengono già dei tag HTML inseriti manualmente, c\'è il rischio che qualcosa possa andare storto e risulti in dati corrotti ' + . 'nel database che andranno poi corretti manualmente. Se non sei sicuro, rispondi "No", a meno che tu non sia in grado di analizzare la situazione prima di procedere. ' + . 'Se sai programmare in PHP, esamina la parte finale dello script setup/upgrade.php, guarda cosa fa ed eventualmente modificalo in base alle tue necessità.', +'databaseconfiguration'=>'Configurazione Database per ', +'proceedtoadmin'=>'Prosegui con il Setup Amministrazione', +'databasehostname'=>'Hostname', +'databasehostnamehint'=>'Inserisci l\'hostname del database su cui stai installando Flyspray. Di solito è "localhost" o un indirizzo IP.', +'databasetype'=>'Tipo DB', +'databasetypehint'=>'Seleziona il tipo di database. Se hai installati entrambi i driver MySQL e MySQLi, usa MySQLi. Il vecchio driver MySQL (mysql_*) è stato deprecato in PHP da tempo immemore. Se hai MariaDB al posto di MySQL, seleziona comunque MySQLi.', +'databasename'=>'Nome del DB', +'databasenamehint'=>'Inserisci il nome di un database esistente o un nuovo nome. Se il database non esiste, Flyspray tenterà di crearlo. È consigliabile un nome semplice tipo "flyspray".', +'databaseusername'=>'Nome Utente', +'databaseusernamehint'=>'Inserisci il nome utente e la password per il database. +Flyspray richiede un database impostato con nome utente e password per installarvi lo schema. +Se non sei sicuro di questi parametri, chiedi all\'amministratore del database o al tuo hosting provider. +(A volte le installazioni locali di XAMPP o WAMPP sono configurate di default come "root" con password vuota)', +'databasepassword'=>'Password', +'databasepasswordhint'=>'', +'tableprefix'=>'Prefisso per le Tabelle', +'tableprefixhint'=>'Prefisso opzionale per le tabelle al fine di evitare conflitti con eventuali tabelle già esistenti. È consigliabile un prefisso semplice come "flyspray_" o "fs_" .', +'next'=>'Prossimo', +'showpassword' => 'Mostra la Password', +'lgpllicense' => 'Licenza LGPL', +'installationguide' => 'Guida all\'Installazione', +'developermanual' => "Manuale per Sviluppatori", +'supported' => 'Supportato', +'inphp' => 'in PHP', +'available' => 'Disponibile', +'missing' => 'Mancante', +'writeable' => 'Scrivibile', +'unwriteable' => 'Non scrivibile', +'on' => 'ON', +'off' => 'OFF', +'x' => 'X', +'true' => 'Vero', +'false' => 'Falso', +'directive' => 'Direttiva', +'enable' => 'Abilita', +'disable' => 'Disabilita', +'administrationsetup' => 'Impostazione Amministrazione', +'setupapplicationvalue' => 'Impostazione di tutti i valori dell\'Applicazione', +'adminsetuptip1' => 'Lo schema del database è stato configurato. Segui le istruzioni per completare le impostazioni di Amministrazione.', +'adminsetuptip2' => '1) Email, Nome Utente e Password di Admin sono per l\'Amministratore della tua installazione di Flyspray. Puoi modificare questi valori dalla sezione di amministrazione di Flyspray.', +'adminsetuptip3' => 'L\'impostazione di una Sintassi non è semplice da cambiare una volta installato Flyspray perciò viene impostata globalmente all\'atto dell\'installazione. Se non sei sicuro su cosa scegliere, seleziona Text/Dokuwiki.', +'syntax' => 'Sintassi', +'syntaxtext' => 'Se non sei sicuro, seleziona Text/Dokuwiki. Il cambio da Dokuwiki a HTML è semplice. Invece, cambiare successivamente da HTML a Dokuwiki o un altro formato come Markdown, è praticamente impossibile senza la perdita di alcune informazioni come HTML fortemente nidifcati o altra formattazione.', +'scheduletitle' => 'Puoi impostare un crontab che richiamerà scheduler.php a intervalli di tempo predefiniti. Questa impostazione può essere abilitata e disabilitata a piacere dalla sezione di amministrazione di Flyspray.', +'enablescheduling' => 'Abilita la schedulazione', +'proceedtofinalsetup' => 'Prosegui con il Setup finale', +'proceedtofinalsetuptext' => 'Prosegui per completare l\'installazione di Flyspray.', +'installstatus' => 'Stato dell\'Installazione', +'congratulations' => 'Congratulazioni! Flyspray è stato installato ed è pronto all\'uso.', +'removesetupdirectory' => 'Ricordati di eliminare la directory setup ora.', +'viewsite' => 'Visualizza il Sito', +'proceedtoindex' => 'Vai alla pagina principale di Flyspray', +); +?> diff --git a/setup/lang/zh_cn.php b/setup/lang/zh_cn.php new file mode 100644 index 0000000..9a82dab --- /dev/null +++ b/setup/lang/zh_cn.php @@ -0,0 +1,46 @@ + '请先通过 Composer 来安装一些依赖库。', +'installcomposer' => '运行 Composer', +'upgrade' => '升级', +'adminemail' => '管理员邮箱', +'adminusername' => '管理员帐户', +'adminpassword' => '管理员密码', +'progress' => '安装进度', +'documents' => '文档', +'preinstallcheck' => '运行环境检查', +'databasesetup' => '数据库设置', +'administration' => '管理员设置', +'install' => '安装', +'libcheck' => 'PHP和数据库', +'libchecktext' => '在开始设置前,必须安装好合适的PHP版本,并且最少要支持一种数据库。', +'recsettings' => '推荐设置项', +'recsettingstext1' => '为了使Flyspray获得更好的兼容性,建议参考此处的 PHP 配置。', +'recsettingstext2' => '当然,即使你的PHP环境配置和此处不同,Flyspray 仍然可以正常工作。', +'dirandfileperms' => '目录和文件权限', +'proceedtodbsetup' => '前往数据库设置', +'library' => '库', +'status' => '状态', +'database' => '数据库', +'recommended' => '推荐', +'actual' => '实际', +'yes' => '是', +'no' => '否', +'databaseconfiguration'=> '数据库连接设置,版本:', +'proceedtoadmin'=> '前往管理员设置', +'databasehostname'=> '数据库主机', +'databasehostnamehint' => '请输入数据库主机名,通常可能是 "localhost" 或者 IP 地址。', +'databasetype' => '数据库类型', +'databasename' => '数据库名', +'databaseusername' => '用户名', +'databasepassword' => '密码', +'tableprefix' => '表前缀', +'next' => '下一步', +'showpassword' => '显示密码', +'lgpllicense' => 'LGPL协议', +'installationguide' => '安装手册', +'developermanual' => '开发者手册', +'writeable' => '可写', +'unwriteable' => '不可写', +); +?> diff --git a/setup/styles/setup.css b/setup/styles/setup.css new file mode 100644 index 0000000..00a8014 --- /dev/null +++ b/setup/styles/setup.css @@ -0,0 +1,177 @@ +body { + margin:0; padding:0; + font-family: Verdana, sans-serif; + font-size:13px; +} +a { text-decoration: none; } +input:required {border: 1px solid #f90;} + +#header { + /*background-color:#47617B;*/ + background-color:#5e5e5e; /* matching grayscale brightness of title.png */ + margin:0; + padding:0; + border-bottom:4px solid #5f9729; +} +#logo { + background-image:url(../images/title.png); + background-position: 10px 10px; + background-repeat: no-repeat; + background-attachment:scroll; + + -webkit-filter: grayscale(100%); + -moz-filter: grayscale(100%); + -o-filter: grayscale(100%); + filter: gray; /* IE6-9 */ + filter: grayscale(100%); /* grayscale until a transparent logo exists that match colors of default theme */ +} +#logo h1 { + padding:0; + margin:0; + font-size:2em; + line-height: 90px; + font-weight:normal; +} +#logo h1 a { + display: block; + height: 90px; + color:#fff; + border: 0; + padding: 0; + margin: 0 auto; + padding-left:260px; +} +#content {max-width:800px;margin-left:auto;margin-right:auto;} + +#footer { + background-color: #333; + padding: 1em; + margin:0; + border-top: 2px solid #5f9729; + text-align: center; + color:#ccc; +} +#footer p, #footer ul{display:inline-block;} +#footer li {display:inline-block; list-style:none;} +#footer a{ display:inline-block; padding:0.5em; color:#fff; } +#footer a:hover {background-color:#000;} + +#stepbar{ margin-top:1em;} +#stepbar div { + box-sizing:border-box; + height:36px; + font-weight: bold; + padding: 10px; + background-color:#ddd; + margin-right:10px; + margin-bottom:6px; /* when it wraps on small displays */ + display:inline-block; + position:relative; /* for the :after rightarrow */ +} + +#stepbar .step-on { background-color:#5f9729; color:#fff;} +#stepbar .done { background-color:#333; color:#ccc;} + +/* css arrow to right */ +#stepbar div:after{ + position:absolute; + content:""; + width:0; + height:0; + top:0; + + border-top:18px solid transparent; + border-bottom:18px solid transparent; + border-left:8px solid #ddd; + right:-8px; +} + +#stepbar div::before { + position: absolute; + content: ""; + height: 0; + width: 0; + top: 0; + + border-bottom: 18px solid #ddd; + border-top: 18px solid #ddd; + border-left: 8px solid transparent; + left:-8px; +} +#stepbar .step-on::after{border-left-color:#5f9729;} +#stepbar .step-on::before{border-top-color:#5f9729;border-bottom-color:#5f9729;} +#stepbar .done::after{border-left-color:#333;} +#stepbar .done::before{border-top-color:#333;border-bottom-color:#333;} +#stepbar div:first-child::before{display:none;} + +.install { + margin-left: auto; + margin-right: auto; + margin-bottom: .5em; + padding: 10px; + border: 1px solid #ddd; + max-width: 700px; + background-color: #f1f1f1; +} + +.formBlock { + border: 1px solid #ddd; + padding:5px; + margin:5px; + background: #f1f1f1; + color:#000; +} + +.formBlock td { + vertical-align:top; + padding-top:1.5em; + min-width:150px; +} + +.button { + display: block; + font-size: 3em; + margin: 0.5em auto; + cursor:pointer; +} + +.error { + color : #c00; + font-weight : bold; + padding-top: 10px; + padding-bottom: 10px; +} + +.red { + color:#F00; +} +.orange { + color:#FFA500; +} +.green { + color:#078843; +} + +.install h1 { + color:#47617B; + text-align:center; +} +.install h2 { + color:#688EB4; +} + +h1.error { + background-image: url(../images/exclamation.png); + border:none; + text-indent: 45px; + background-position: 0px 0px; + background-repeat: no-repeat; + text-align:left; +} + +.box { + border: 5px solid #688EB4; + padding:0; + margin:0; + background-color: #F1F3F5; +} diff --git a/setup/styles/theme.css b/setup/styles/theme.css new file mode 100644 index 0000000..a52f3e3 --- /dev/null +++ b/setup/styles/theme.css @@ -0,0 +1,994 @@ +@media screen { + +html { + margin : 0px; + padding : 0px; +} + +body { + margin : 0px; + padding : 0px; + background-color : #F5F9FD; + color : #000; + font-size : 12px; + font-family : Helvetica, Verdana, sans-serif; +} + +img { + border : none; +} + +a { + text-decoration : none; +} + +a:link { + color : #47617b; + background-color : transparent; + font-weight : bold; +} + +a:visited { + color : #47617b; + background-color : transparent; + font-weight : bold; +} + +a:hover { + color : #6395c8; + background-color : transparent; + text-decoration : none; +} + +/* offsite is only used for the link to the Flyspray homepage */ +a.offsite:after { + content : "\2197"; +} + +h1 { + /*text-align : center;*/ + font-size : 150%; +} + +/* the main title; h1 alone is also used in the popup windows. */ +h1#title { + margin : 0px; + padding : 1ex 0px; + background-color : #47617b; + background-image : url("title.png"); + background-repeat : no-repeat; + height : 45px; +} + +/* there is a span element within the h1 element to enable displaying + an image only and blanking out the span */ +h1 span { + display : none; +} + +h2 { /* Heading for link to task list and details */ + margin : 0px; + padding : 0px; + font-size : 150%; +} + +h4 { + padding : 0px; + margin-bottom : -10px; +} + +p { + margin : 1ex 0px; + padding : 0.5ex 0.5em; +} + +form { + margin : 0px; + padding : 0px; + display : inline; +} + +form p { + margin : 0px; + padding : 0px; +} + +td { + vertical-align : top; +} + +th { + vertical-align : top; +} + +input, textarea, select, button { + background-color : #eef7ff; + color : #03008f; + border : 1px ridge #000000; + margin : 2px; + font-size : 100%; +} + +textarea { + width : 95%; +} + +/* labels are used nearly in every form */ +label { + text-align : right; + display : block; + margin-right : 8px; + font-weight : bold; + white-space : nowrap; +/* padding : 3px 0 0 0; */ +} + +label.inline { + display : inline; +} + +/* div.admin and p.admin is used for areas that only administrators can use + p.admin for instance for adding comments + table.admin serves the same purpose */ +/* table.login is the framework for the login form at the bottom of a page */ +/* table.userlist is found in the user&groups section */ +div.admin, p.admin, table.admin, table.userlist { + border : 1px solid #ccc; + margin : 1em 0px; + padding : 0px; + margin-bottom : 30px; + background-color : #e6eef6; + color : #000000; + font-family : Helvetica, Verdana, sans-serif; +} + +div#loginbox { + border : 1px solid #ccc; + margin : 0em 0px; + padding : 0px; + background-color : #e6eef6; + height : 22px; +} + +div#loginbox p { + padding : 0px; + margin : 0px; +} + +div#loginbox em { + display : none; +} + +div#loginbox label, div#loginbox input.maintext, div#loginbox input.mainbutton { + display : inline; + padding : 0 3px 0 3px; +/* height : 14px; */ +} + +div#loginbox a { + padding : 0 0 0 13px; + text-align : center; +} + +div#loginbox span#links { + position : absolute; + top : 5px; + right : 5px; +} + +div#loginbox span#links a { + color : #ffffff; + background-color : transparent; + font-weight : normal; +} + +/* The paragraph containing the main menu */ +p#menu { + border : 1px solid #ccc; + margin : 0em 0px; + padding : 4px 0 0 0; + background-color : #e6eef6; + height : 18px; + vertical-align : baseline; +} + +p#menu a { + height : 18px; + padding : 3px 1px 3px 20px; + background-repeat : no-repeat; + background-position : 1px 1px; + font-size : 12px; + font-weight : normal; + vertical-align : baseline; +} + +p#menu a:hover { + color : #6395c8; + background-color : transparent; + text-decoration : none; +} + +div#anonopen { + position : absolute; + top : 30px; + right : 5px; + padding : 0px; +} + +div#anonopen a { + color : #ffffff; + background-color : transparent; + padding : 0px; + font-weight : normal; +} + +/* Links in menus */ + +a#newtasklink { + background-image : url(menu/newtask.png); +} + +a#reportslink { + background-image : url(menu/reports.png); +} + +a#editmydetailslink { + background-image : url(menu/editmydetails.png); +} + +a#lastsearchlink { + background-image : url(menu/search.png); +} + +a#logoutlink { + background-image : url(menu/logout.png); +} + +a#optionslink { + background-image : url(menu/options.png); +} + +a#projectslink { + background-image : url(menu/projectprefs.png); +} + +/* For pending admin requests */ +a#attention { + color : #ff0000; + background-color : #fff000; +} + +table.userlist td, table.userlist th { + border : 1px solid #ccc; +} + +/* p#showtask contains the form to search for a specific task number */ +p#showtask { + text-align : right; + width : 40%; + margin-left : auto; + position : relative; + top : -2em; +} + +/* The paragraph containing the search form */ +div#search { + margin-bottom : 1em; + border : 1px solid #000000; + background-color : #e6eef6; +} + +div#search p { + padding : 0px; + margin : 0px; +} + +div#search span#date_d { + min-width : 20px; + margin : 0px 5px 0px 5px; + padding : 0px 5px 0px 5px; + display : inline; + background-color : #eef7ff; + color : #03008f; + border : 1px ridge #000000; + margin : 2px; + font-size : 100%; +} + +div#search select { + background-color : #eef7ff; + color : #03008f; + border : 1px ridge black; +} + +div#search em { + float : left; + display : block; + padding : 0.5ex; + height : 2.5em; +} + +div#tasklist { + width : 100%; + border : 1px solid #000000; + color : #000000; + background-color : #e6eef6; +} + +/* The table listing tasks on the main page */ +div#tasklist table { + width : 100%; + border-spacing : 0px; + border-collapse : collapse; +} + +div#tasklist table th { + text-align : left; + padding : 2px 1em 2px 2px; + border-bottom : 1px solid #cccccc; +} + +div#tasklist table td { + border-bottom : 1px solid #CCC; + padding : 2px 1ex 2px 2px; +} + +div#tasklist table td.taskid, div#tasklist table th.taskid { + text-align : center; + padding : 2px 1ex; +} + +div#tasklist table td.taskdate { + text-align : left; + white-space : nowrap; +} + +div#tasklist table td.progress { + vertical-align : middle; + text-align : center; +} + +table#pagenumbers { + width : 100%; +} + +table#pagenumbers td#taskrange { + padding : 0px 0px 0px 5px; + } + +table#pagenumbers td#numbers { + padding : 0px 5px 0px 0px; + text-align : right; +} + +/* table.list is any table holding lists like resolutions, ... */ +table.list th, table.list td { + padding-right : 2em; +} + +table.list label, p#showtask label, p.admin label, form#formaddrelatedtask label { + display : inline; +} + +/* Area containing all details to a given task */ +div#taskdetails { + margin : 2em 0px 1em 0px; + background-color : #e6eef6; + border : 1px solid #000000; +} + +div#taskdetails h2 { + font-size : 100%; + padding : 0.3ex 1ex; + font-weight : normal; +} + +table.taskdetails td { +} + +/* Task details are listed within a table */ +div#taskdetails table { + width : 90%; +} + +div#taskdetails table th { + text-align : left; + font-weight : bold; +} + +/* div#content is a generic container for anything but the title and + the footer paragraph */ +div#content { +/* border : 2px solid #948d94;*/ + margin : 5px; + padding : 5px; +/* color : #000000; + background-color : #ffffff; + z-index : -1;*/ +} + +div#content div, div#content fieldset { +/* -moz-border-radius : 13px; */ +} + +div#content div h2 { +/* -moz-border-radius : 15px; */ +} + +/* Powered by Flyspray */ +p#footer { + margin : 0em 0em; + padding : 5px; + background-color : #47617b; + border : 3px double white; + color : #ffffff; + text-align : center; + margin-top : 15px; + clear : both; +} + +p#footer a:link { + color : #ffffff; + background-color : transparent; +} + +p#footer a:visited { + color : #ffffff; + background-color : transparent; +} + +p#footer a:hover { + color : #ffffff; + background-color : transparent; +} + +/* used solely for several browsers do not support [type="submit"] + selectors. These are buttons and buttons only used by the admin */ +input.adminbutton, input.mainbutton, button { + background-color : #838ab5; + color : #ffffff; + background-image : url(button.png); + background-repeat : repeat-x; + border : 1px ridge #000000; + font-weight : bold; +} + +input.adminbutton:hover, input.mainbutton:hover, button:hover { + cursor : pointer; +} + +/* div.redirectmessage is used in modify.inc.php when you change things and are redirected + to the index or details page */ +div.redirectmessage { + border : 1px solid #CCC; + background-color : #e6eef6; + padding : 1ex; + text-align : center; +} + +/* form#registernewuser, form#chgpassword, form#newgroup are used in + the popup windows */ +form#chgpassword h1, form#registernewuser h1, form#newgroup h1 { + font-size : 110%; + margin : 2px; + padding : 0px; +} + +/* .buttons used for table cells containing buttons */ +.buttons { + text-align : center; +} + +form#registernewuser strong, form#newgroup strong { + color : red; +} + + + +p#tabs { + margin : 0px; + padding : 0px; +} + +p#tabs a { + background-image : url("tab-notactive.png"); + background-repeat : no-repeat; + background-position : top left; + background-color : #cad0d7; + border-right : 1px solid #93989D; +} + +p#tabs a.tabactive { + background-image : url("tab-active.png"); + background-repeat : no-repeat; + background-position : top left; + background-color : #e6eef6; + border-right : 1px solid #CCC; + padding-bottom : 2px; +} + +div.tabentries { + background-color : #e6eef6; + margin : 0px 0px 1em 0px; + border : 1px solid #CCC; + min-height : 5em; +} + +.tabentry { + margin : 2px 1em; + border-bottom : 1px solid #ccc; +} + +/* This is the division that keeps the buttons to modify comments + (delete, edit) */ +div.modifycomment { + float: right; + width : 20em; + text-align : right; +} + +div.modifycomment p { + display : inline; + margin : 0px; + padding : 0px; +} + +/* The tabs containing the links to comments, attachments, ... + in details.php */ +p#tabs a { + margin : 2px 0px; + padding : 0px 1em; + white-space : nowrap; +} + +/* separators between the links in the tabs */ +p#tabs small { + display : none; +} + +/* p.unregistered holds links to open new task when you're unregistered */ +p.unregistered { + margin : 0px; + padding : 0px; +} + +/* Some generic classes; severity classes are used for colour + indication of severities + IE can't do hover on anything but A elements, so there is a + script in /js/ie_hover.js that fixes this with + javascript. That javascript only checks background-color and + color. If you want to change other properties during the hover + you'll have to adjust the javascript + */ +.severity1 { + background-color : #fff5dd; + color : #000000; + height : 1%; +} + +.severity1:hover { + background-color : #ffe9b4; + color : #000000; + cursor : pointer; +} + +.severity2 { + background-color : #ecdbb7; + color : #000000; + height : 1%; +} + +.severity2:hover { + background-color : #efca80; + color : #000000; + cursor : pointer; +} + +.severity3 { + background-color : #ecd0b7; + color : #000000; + height : 1%; +} + +.severity3:hover { + background-color : #edb98a; + color : #000000; + cursor : pointer; +} + +.severity4 { + background-color : #ffd5d1; + color : #000000; + height : 1%; +} + +.severity4:hover { + background-color : #ffb2ac; + color : #000000; + cursor : pointer; +} + +.severity5 { + background-color : #f3a29b; + color : #000000; + height : 1%; +} + +.severity5:hover { + background-color : #f3867e; + color : #000000; + cursor : pointer; +} + +/* .fineprint is merely used for the details about when a task has + been created and changed (in the details pages) */ +div#fineprint { + font-size : smaller; + border-bottom : 1px solid #cccccc; + margin : 0px 0px 10px 5px; + padding-bottom : 10px; + height : 1%; +} + +table.history +{ + width : 100%; + margin : 1em 0px 1em 0px; + padding : 0px 1em 0px 1em; + background-color : #e6eef6; + color : black; + font-family : Helvetica, Verdana, Sans-Serif; +} + +table.history td { + border-bottom : 1px solid #ccc; + border-left : 1px solid #ccc; + padding-left : 5px; +} + +table.history td.taskid { + text-align : center; + padding : 2px 1ex; +} + +div#intromessage { + margin : 1px; + margin-top : -20px; + margin-bottom : 10px; +} + +map#formselecttasks { + margin : 0em 0px 0em 0px; +} + +a.closedtasklink { + text-decoration: line-through; +} + +div#taskfields1 { + float: left; + width: 49%; + border-right: 1px solid #cccccc; + margin-bottom: 8px; +} + +div#taskfields2 { + float: left; + width: 49%; + margin-bottom: 8px; +} + +div#taskfields1 table td { + width: 50%; +} + +div#taskfields2 table td { + width: 50%; +} + +div#taskdetailsfull { + clear : both; + width : 99%; + margin-top : 15px; + padding : 15px 0px 15px 8px; + border-top : 1px solid #cccccc; + border-bottom : 1px solid #cccccc; + text-align : left; +} + +div#taskdetailsfull label { + text-align : left; +} + +div#deps { + padding : 8px; + width : 98%; + border-bottom : 1px solid #cccccc; + min-height : 50px; + float : left; +} + +div#taskdeps { + float: left; + width: 45%; + margin-bottom: 8px; +} + +div#taskblocks { + float: left; + width: 50%; +} + +div#actionbuttons { + clear : both; + padding : 5px; +} + +div#actionbuttons a { + background-image : url(button.png); + background-repeat : repeat-x; + color : #ffffff; + background-color : transparent; + border : 1px solid #000000; + margin : 0px 3px 0px 3px; + /* padding values: top, right, bottom, left */ + padding : 2px 5px 2px 5px; +} + +div#actionbuttons a#hideclosetask { + position : absolute; + top : 3px; + right : 3px; + width : 16px; + height : 16px; + background-image : url(cancel.png); + background-repeat : no-repeat; + color : #000000; + background-color : transparent; + border : none; +} + +div#actionbuttons a#hideclosetask:hover { + position : absolute; + top : 3px; + right : 3px; + width : 16px; + height : 16px; + background-image : url(cancel-over.png); + background-repeat : no-repeat; + color : #000000; + background-color : transparent; + border : none; +} + +div#massopsactions { + padding : 0px 0px 0px 3px; +} + +div#closeform { + visibility : hidden; + position : absolute; + background-color : #e6eef6; + color : #000000; + border : 3px ridge #000000; + padding : 5px 30px 5px 5px; + margin-top : 5px; + display : block; + width : 300px; + height : auto; +} + +div#closeform textarea { + width : 100%; + height : 100px; +} + +div.denyform { + visibility : hidden; + position : absolute; + right : 12px; + background-color : #e6eef6; + color : #000000; + border : 3px ridge #000000; + padding : 5px 30px 5px 5px; + margin-top : 5px; + display : block; + width : 300px; + height : auto; +} + +div#denyform textarea { + width : 100%; + height : 100px; +} + +fieldset.admin { + margin-top : 15px; + background-color : #e6eef6; + color : #000000; + border : 1px solid #000000; +} + +fieldset.admin legend { + border-bottom : 1px solid #000000; + border-right : 1px solid #000000; + padding : 2px; + font : 120% Helvetica, Verdana, sans-serif; + margin : 5px; + background-color : #f5f9fd; + color : #000000; +} + +div#errorbar { + width : 100%; + height : 20px; + color : yellow; + background-color : red; + font-weight : bold; + position : fixed; + bottom : 0px; + background-image : url(frown.png); + background-repeat : no-repeat; + background-position : 5px 0px; + padding-left : 30px; +} + +div#successbar { + width : 100%; + height : 20px; + color : #ffffff; + background-color : green; + font-weight : bold; + position : fixed; + bottom : 0px; + background-image : url(smile.png); + background-repeat : no-repeat; + background-position : 5px 0px; + padding-left : 30px; +} + +div#toolboxmenu { + width : auto; + float : left; + margin-right : 25px; + margin-top : 15px; +} + +div#toolboxmenu small { + display : none; +} + +div#toolboxmenu a { + display : block; + border : 1px solid #000000; + padding-top : 1em; + padding-bottom : 1em; + width : 120px; + text-align : center; +} + +div#toolboxmenu a:hover { + color : #6395c8; + background-color : #d7e9ff; +} + +div#toolbox { + margin-left : 150px; + min-height : 350px; +} + +a.grouptitle { + font-size : 16px; +} + +/* The new tabs stuff */ +/* colors */ +#submenu a, div.tab { color: #000000; background-color: #e6eef6; } + +#submenu a.active { + color : #000000; + border-bottom-color : #cdc; +} + +#submenu a:hover { + color : #000000; +} + +#submenu a { color: #999;text-decoration: none; } +#submenu a.active { z-index:5;} + +/* margins */ +#submenu, #submenu * { margin: 0; padding: 0; } +#submenu a, div.tab { border: solid 1px black; } +#submenu a { margin: auto auto -1px 1ex; padding: 2px 1ex; } +* html #submenu { margin-bottom: -1em; } +div.tab { margin: 0; padding: 1ex; padding-bottom: 1cm; margin-right: 1ex; margin-bottom: 10px;} + +/* flow */ +#submenu li { display: inline; width: 0; height: 0; } +#submenu a { display: block; float: left; } +div.tab h2 { display: none; } +div.tab { clear: left; } +* html .tab div.clear { clear: none; height: 14em; } + +div#permslink { + position : absolute; + top : 5px; + right : 5px; + color : #ffffff; + background-color : transparent; +} + +div#permslink a { + color : #ffffff; + background-color : transparent; +} + +div#permissions { + visibility : hidden; + position : absolute; + top : 25px; + right : 5px; + padding : 5px; + margin-top : none; + overflow : auto; + z-index : 5; +} + +div#permissions table { + color : #000000; + background-color : #ffffff; + border : 1px dotted #000000; +} + +div#permissions table td { + border : 0px; +} + +div#fileupload { + margin : 20px 0px 20px 0px; +} + +span#pendingreq { + margin : 0px 0px 0px 9px; + display: : block; + clear : both; + font-size : 120%; + font-weight : bold; + float : right; + color : red; + background-color : yellow; +} + +/* container for the next/previous links in the task details */ +span#navigation { + position : absolute; + right : 1em; +} + +span#navigation a#next { + padding-right : 20px; + background-image : url(next.png); + background-repeat : no-repeat; + background-position : right; +} + +span#navigation a#prev { + padding-left : 20px; + background-image : url(prev.png); + background-repeat : no-repeat; + background-position : left; +} + + + +/* End of the @screen section */ +} + +@media print { +p#menu { + display : none; +} + +/* End of the @print section */ +} diff --git a/setup/templates/administration.tpl b/setup/templates/administration.tpl new file mode 100644 index 0000000..58909b0 --- /dev/null +++ b/setup/templates/administration.tpl @@ -0,0 +1,79 @@ +
    +
    + +

    +

    +
    + + +

    +

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + + + + + + + +

    + + + +
    +
    +
    diff --git a/setup/templates/complete_install.tpl b/setup/templates/complete_install.tpl new file mode 100644 index 0000000..2def1e6 --- /dev/null +++ b/setup/templates/complete_install.tpl @@ -0,0 +1,50 @@ +
    +
    +

    +

    +
    +

    + + + + + + + + +
    + The configuration file is not writeable. You will have to upload the following + code manually. Click in the textarea to highlight all of the code. Copy and + paste the contents into the flyspray.conf.php file available in the base of + installation. +
    + +
    +

    flyspray.conf.php NOT writeable

    +

    + To complete setup, copy and paste the contents of the textarea box into flyspray.conf.php + This file resides in the base of your installation. +

    + + +

    Administration Login Details

    +

    + Username:
    + Password: +

    + + + + + + + + +

    + + + +
    +
    +
    diff --git a/setup/templates/database.tpl b/setup/templates/database.tpl new file mode 100644 index 0000000..f5e29a8 --- /dev/null +++ b/setup/templates/database.tpl @@ -0,0 +1,47 @@ +
    +
    + + +

    +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    +
    +
    diff --git a/setup/templates/pre_install.tpl b/setup/templates/pre_install.tpl new file mode 100644 index 0000000..3c65e43 --- /dev/null +++ b/setup/templates/pre_install.tpl @@ -0,0 +1,124 @@ +
    + + +

    +

    +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     
    PHP >=  
    XML Extension 
    cURL Libraryrequired if you want allow Oauth2 authentications
    GD Library 
    Exif Library 
    SAPI () 
    + + +

    CGI server API is not supported. Consider upgrading to FastCGI, otherwise you have to add + force_baseurl = "http://yourflyspray/" manually to flyspray.conf.php after setup. +

    + +
    + +

    +
    +

    +

    + + + + + + + +
    +
    + +

    +
    +

    + + + + + + + + + + + + + + + + + + + + + +
    ../flyspray.conf.php 
    ../cache 
    ../attachments 
    ../avatars 
    + + +

    + The installer has detected that the flyspray.conf.php file is not + writeable. Please make it writeable by the web-server user or world writeable to + proceed with the setup. Alternatively if you wish to proceed, the installer will + make available the contents of the configuration file at the end of the setup. You + will then have to manually copy and paste the contents into the configuration file + located at . +

    + + + +

    + You seem to have problems with the Pre-install configuration. Once you have fixed the + problem, please refresh the page to be able to proceed to the next stage of + setup. +

    + +

    + +
    + + +
    +
    +
    diff --git a/setup/templates/structure.tpl b/setup/templates/structure.tpl new file mode 100644 index 0000000..84a7491 --- /dev/null +++ b/setup/templates/structure.tpl @@ -0,0 +1,56 @@ + + + +<?php echo Filters::noXSS($title . ' ' . $product_name); ?> + + + + + + +
    +
    + +
    3rd party libs
    + >
    + >
    + > + > + + + + + + diff --git a/setup/templates/upgrade.tpl b/setup/templates/upgrade.tpl new file mode 100644 index 0000000..68e1619 --- /dev/null +++ b/setup/templates/upgrade.tpl @@ -0,0 +1,76 @@ + + + +<?php echo Filters::noXSS($title); ?> Flyspray + + + + + +
    +
    + +
    +

    +

    +

    +
    + + + + + + + + + +
    ../writeablenot writeable
    Database connectionOKFailed
    +
    + +

    Apparently, an upgrade is not possible.

    +

    Back to Home

    + +

    +

    +

    + + +

    Upgrade options

    +

    + + + +

    +

    +

    +

    + + +

    +

    + +
    ',$upgradelog); ?>
    +

    If all went fine:

    +
      +
    1. Delete setup directory or restrict access to this directory by a htaccess rule.
    2. +
    3. Back to Overview
    4. +
    + +

    Info: This may take a while depending on the upgrade type and your database size: from a few seconds up to doing a coffee break.

    +

    We do not get upgrade progress feedback while the upgrading process is running, but if it takes longer it can be a sign of problem.

    + + +
    +
    +
    + + + diff --git a/setup/upgrade.php b/setup/upgrade.php new file mode 100644 index 0000000..46d108b --- /dev/null +++ b/setup/upgrade.php @@ -0,0 +1,643 @@ + +// | Copyright (C) 2007 by Florian Florian Schmitz +// +---------------------------------------------------------------------- +// | +// | Copyright: See COPYING file that comes with this distribution +// +---------------------------------------------------------------------- +// + +@set_time_limit(0); +//do it fast damn it +ini_set('memory_limit', '64M'); + +// define basic stuff first. +define('IN_FS', 1); +define('BASEDIR', dirname(__FILE__)); +define('APPLICATION_PATH', dirname(BASEDIR)); +define('OBJECTS_PATH', APPLICATION_PATH . '/includes'); +require_once OBJECTS_PATH . '/class.flyspray.php'; +define('CONFIG_PATH', Flyspray::get_config_path(APPLICATION_PATH)); + +define('TEMPLATE_FOLDER', BASEDIR . '/templates/'); +$conf = @parse_ini_file(CONFIG_PATH, true) or die('Cannot open config file at ' . CONFIG_PATH); + +$borked = str_replace( 'a', 'b', array( -1 => -1 ) ); + +if(!isset($borked[-1])) { + die("Flyspray cannot run here, sorry :-( \n PHP 4.4.x/5.0.x is buggy on your 64-bit system; you must upgrade to PHP 5.1.x\n" . + "or higher. ABORTING. (http://bugs.php.net/bug.php?id=34879 for details)\n"); +} + +require_once OBJECTS_PATH . '/fix.inc.php'; +require_once OBJECTS_PATH . '/class.gpc.php'; +require_once OBJECTS_PATH . '/i18n.inc.php'; + +# fake objects for load_translation() +class user{var $infos=array();}; class project{var $id=0;}; +$user=new user; $proj=new project; +load_translations(); + +// Use composer autoloader +require dirname(__DIR__) . '/vendor/autoload.php'; + +// Initialise DB +require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb.inc.php'; +require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb-xmlschema03.inc.php'; + +$db = new Database; +$db->dbOpenFast($conf['database']); + +$webdir = dirname(htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'utf-8')); +$baseurl = rtrim(Flyspray::absoluteURI($webdir),'/\\') . '/' ; + +// --------------------------------------------------------------------- +// Application Web locations +// --------------------------------------------------------------------- +$fs = new Flyspray(); + +define('APPLICATION_SETUP_INDEX', Flyspray::absoluteURI()); +define('UPGRADE_VERSION', Flyspray::base_version($fs->version)); + +define('DOMAIN_HASH', md5($_SERVER['SERVER_NAME'] . (int) $_SERVER['SERVER_PORT'])); +define('CACHE_DIR', Flyspray::get_tmp_dir() . DIRECTORY_SEPARATOR . DOMAIN_HASH); + +// Get installed version +$sql = $db->query('SELECT pref_value FROM {prefs} WHERE pref_name = ?', array('fs_ver')); +$installed_version = $db->fetchOne($sql); + +$page = new Tpl; +$page->assign('title', 'Upgrade '); +$page->assign('short_version', UPGRADE_VERSION); + +if (!isset($conf['general']['syntax_plugin']) || !$conf['general']['syntax_plugin'] || $conf['general']['syntax_plugin'] == 'none') { + $page->assign('ask_for_conversion', true); +} else { + $page->assign('ask_for_conversion', false); +} + +//cleanup +//the cache dir +@rmdirr(sprintf('%s/cache/dokuwiki', APPLICATION_PATH)); + +// --------------------------------------------------------------------- +// Now the hard work +// --------------------------------------------------------------------- + +// Find out which upgrades need to be run +$folders = glob_compat(BASEDIR . '/upgrade/[0-9]*'); +usort($folders, 'version_compare'); // start with lowest version + +if (Post::val('upgrade')) { + $uplog=array(); + $uplog[]="Start database transaction"; + $db->dblink->StartTrans(); + fix_duplicate_list_entries(true); + foreach ($folders as $folder) { + if (version_compare($installed_version, $folder, '<=')) { + $uplog[]="Start $installed_version to $folder"; + $uplog[]= execute_upgrade_file($folder, $installed_version); + $installed_version = $folder; + $uplog[]="End $installed_version to $folder"; + } + } + + # maybe as Filter: $out=html2wiki($input, 'wikistyle'); and $out=wiki2html($input, 'wikistyle') ? + # No need for any filter, because dokuwiki format wouldn't be touched anyway. But maybe ask the user + # first and explain that html-formatting is now used instead of plain text on installations that didn't + # use dokuwiki format. Then, adding paragraph tags and line breaks might enhance readability. + // For testing, do not use yet, have to discuss this one with others. + if ((!isset($conf['general']['syntax_plugin']) || !$conf['general']['syntax_plugin'] || $conf['general']['syntax_plugin'] == 'none') && Post::val('yes_please_do_convert')) { + convert_old_entries('tasks', 'detailed_desc', 'task_id'); + convert_old_entries('projects', 'intro_message', 'project_id'); + convert_old_entries('projects', 'default_task', 'project_id'); + convert_old_entries('comments', 'comment_text', 'comment_id'); + $page->assign('conversion', true); + } else { + $page->assign('conversion', false); + } + + // we should be done at this point + $db->query('UPDATE {prefs} SET pref_value = ? WHERE pref_name = ?', array($fs->version, 'fs_ver')); + + // Fix the sequence in tasks table for PostgreSQL. + if ($db->dblink->dataProvider == 'postgres') { + $rslt = $db->query('SELECT MAX(task_id) FROM {tasks}'); + $maxid = $db->fetchOne($rslt); + // The correct sequence should normally have a name containing at least both the table and column name in this format. + $rslt = $db->query('SELECT relname FROM pg_class WHERE NOT relname ~ \'pg_.*\' AND relname LIKE \'%' . $conf['database']['dbprefix'] . 'tasks_task_id%\' AND relkind = \'S\''); + if ($db->countRows($rslt) == 1) { + $seqname = $db->fetchOne($rslt); + $db->query('SELECT setval(?, ?)', array($seqname, $maxid)); + } + } + // */ + $db->dblink->completeTrans(); + $installed_version = $fs->version; + $page->assign('done', true); + $page->assign('upgradelog', $uplog); +} + +function execute_upgrade_file($folder, $installed_version) +{ + global $db, $page, $conf; + // At first the config file + $upgrade_path = BASEDIR . '/upgrade/' . $folder; + new ConfUpdater(CONFIG_PATH, $upgrade_path); + + $upgrade_info = parse_ini_file($upgrade_path . '/upgrade.info', true); + // dev version upgrade? + if ($folder == Flyspray::base_version($installed_version)) { + $type = 'develupgrade'; + } else { + $type = 'defaultupgrade'; + } + + // Next a mix of XML schema files and PHP upgrade scripts + if (!isset($upgrade_info[$type])) { + die('#1 Bad upgrade.info file.'); + } + + ksort($upgrade_info[$type]); + foreach ($upgrade_info[$type] as $file) { + if (substr($file, -4) == '.php') { + require_once $upgrade_path . '/' . $file; + } + + if (substr($file, -4) == '.xml') { + $schema = new adoSchema($db->dblink); + $xml = file_get_contents($upgrade_path . '/' . $file); + // $xml = str_replace('setPrefix($conf['database']['dbprefix'], false); + $schema->parseSchemaString($xml); + $schema->executeSchema(null, true); + } + } + + // Last but not least global prefs update + if (isset($upgrade_info['fsprefs'])) { + $sql = $db->query('SELECT pref_name FROM {prefs}'); + $existing = $db->fetchCol($sql); + // Add what is missing + foreach ($upgrade_info['fsprefs'] as $name => $value) { + if (!in_array($name, $existing)) { + $db->query('INSERT INTO {prefs} (pref_name, pref_value) VALUES (?, ?)', array($name, $value)); + } + } + // Delete what is too much + foreach ($existing as $name) { + if (!isset($upgrade_info['fsprefs'][$name])) { + $db->query('DELETE FROM {prefs} WHERE pref_name = ?', array($name)); + } + } + } + + $db->query('UPDATE {prefs} SET pref_value = ? WHERE pref_name = ?', array(basename($upgrade_path), 'fs_ver')); + #$page->assign('done', true); + return "Write ".basename($upgrade_path)." into table {prefs} fs_ver in database"; +} + + /** + * Delete a file, or a folder and its contents + * + * @author Aidan Lister + * @version 1.0.3 + * @link http://aidanlister.com/repos/v/function.rmdirr.php + * @param string $dirname Directory to delete + * @return bool Returns TRUE on success, FALSE on failure + * @license Public Domain. + */ + + function rmdirr($dirname) + { + // Sanity check + if (!file_exists($dirname)) { + return false; + } + + // Simple delete for a file + if (is_file($dirname) || is_link($dirname)) { + return unlink($dirname); + } + + // Loop through the folder + $dir = dir($dirname); + while (false !== $entry = $dir->read()) { + // Skip pointers + if ($entry == '.' || $entry == '..') { + continue; + } + // Recurse + rmdirr($dirname . DIRECTORY_SEPARATOR . $entry); + } + // Clean up + $dir->close(); + return rmdir($dirname); + } + + +class ConfUpdater +{ + var $old_config = array(); + var $new_config = array(); + + /** + * Reads the existing config file and updates it + * @param string $location + * @access public + * @return bool + */ + function ConfUpdater($location, $upgrade_path) + { + if (!is_writable($location)) { + return false; + } + + $this->old_config = parse_ini_file($location, true) or die('Aborting: Could not open config file at ' . $location); + $this->new_config = parse_ini_file($upgrade_path . '/flyspray.conf.php', true); + // Now we overwrite all values of the *default* file if there is one in the existing config + array_walk($this->new_config, array($this, '_merge_configs')); + // save custom attachment definitions + $this->new_config['attachments'] = $this->old_config['attachments']; + # first try to keep an existing oauth config on upgrades + $this->new_config['oauth'] = $this->old_config['oauth']; + + $this->_write_config($location); + } + + /** + * Callback function, merges config values + * @param array $settings + * @access private + * @return array + */ + function _merge_configs(&$settings, $group) + { + foreach ($settings as $key => $value) { + if (isset($this->old_config[$group][$key])) { + $settings[$key] = $this->old_config[$group][$key]; + } + // Upgrade to MySQLi if possible + if ($key == 'dbtype' && strtolower($settings[$key]) == 'mysql' && function_exists('mysqli_connect')) { + + //mysqli is broken on 64bit systems in versions < 5.1 do not use it, tested, does not work. + if (php_uname('m') == 'x86_64' && version_compare(phpversion(), '5.1.0', '<')) { + continue; + } + + $settings[$key] = 'mysqli'; + } + //no matter what, change the randomization key on each upgrade as an extra security improvement. + if($key === 'cookiesalt') { + $settings[$key] = md5(uniqid(mt_rand(), true)); + } + } + } + + /** + * Writes the new config file to a given $location + * @param string $location + * @access private + */ + function _write_config($location) + { + $new_config = "; \n\n"; + foreach ($this->new_config as $group => $settings) { + $new_config .= "[{$group}]\n"; + foreach ($settings as $key => $value) { + if (is_array($value)) { + foreach ($value as $_key => $_value) { + $new_config .= sprintf('%s="%s"', "{$key}[{$_key}]", addslashes($_value)). "\n"; + } + } else { + $new_config .= sprintf('%s="%s"', $key, addslashes($value)). "\n"; + } + } + $new_config .= "\n"; + } + + $fp = fopen($location, 'wb'); + fwrite($fp, $new_config); + fclose($fp); + } +} + +function postgresql_adodb() { + if (class_exists('ReflectionClass')) { + require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/adodb-datadict.inc.php'; + require_once dirname(__DIR__) . '/vendor/adodb/adodb-php/datadict/datadict-postgres.inc.php'; + $refclass = new ReflectionClass('ADODB2_postgres'); + $refmethod = $refclass->getMethod('ChangeTableSQL'); + $implclass = $refmethod->getDeclaringClass(); + if ($implclass->name === 'ADODB2_postgres') { + return true; + } + return false; + } else { + // Can't even do the test, hope the user is able to handle the situation him/serself. + return true; + } +} + +$checks = $todo = array(); +$checks['version_compare'] = version_compare($installed_version, UPGRADE_VERSION) === -1; +$checks['config_writable'] = is_writable(CONFIG_PATH); +$checks['db_connect'] = (bool) $db->dblink; +$checks['installed_version'] = version_compare($installed_version, '0.9.6') === 1; +$todo['config_writable'] = 'Please make sure that the file at ' . CONFIG_PATH . ' is writable.'; +$todo['db_connect'] = 'Connection to the database could not be established. Check your config.'; +$todo['version_compare'] = 'No newer version than yours can be installed with this upgrader.'; +$todo['installed_version'] = 'An upgrade from Flyspray versions lower than 0.9.6 is not possible. + You will have to upgrade manually to at least 0.9.6, the scripts which do that are included in all Flyspray releases <= 0.9.8.'; + +if ($conf['database']['dbtype'] == 'pgsql') { + $checks['postgresql_adodb'] = (bool) postgresql_adodb(); + $todo['postgresql_adodb'] = 'You have a version of ADOdb that does not contain overridden version of method ChangeTableSQL for PostgreSQL. ' + . 'Please copy setup/upgrade/1.0/datadict-postgres.inc.php to ' + . 'vendor/adodb/adodb-php/datadict/ before proceeding with the upgrade process.'; +} + +$upgrade_possible = true; +foreach ($checks as $check => $result) { + if ($result !== true) { + $upgrade_possible = false; + $page->assign('todo', $todo[$check]); + break; + } +} + +if (isset($upgrade_info['options'])) { + // piece of HTML which adds user input, quick and dirty*/ + $page->assign('upgrade_options', implode('', $upgrade_info['options'])); +} + +$page->assign('index', APPLICATION_SETUP_INDEX); +$page->uses('checks', 'fs', 'upgrade_possible'); +$page->assign('installed_version', $installed_version); + +$page->display('upgrade.tpl'); + +// Functions for checking and fixing possible duplicate entries +// in database for those tables that now have a unique index. + +function fix_duplicate_list_entries($doit=true) { + global $db,$uplog; + + // Categories need a bit more thinking. A real life example from + // my own database: A big project originally written (horrible!) + // in VB6, that I ported to .NET -environment. Categories: + // BackOfficer (main category) + // -> Reports (subcategory - should be allowed) + // BackOfficer.NET (main category) + // -> Reports (subcategory - should be allowed) + // -> Reports (I added a fake duplicate - should not be allowed) + + $sql = $db->query('SELECT MIN(os_id) id, project_id, os_name + FROM {list_os} + GROUP BY project_id, os_name + HAVING COUNT(*) > 1'); + $dups = $db->fetchAllArray($sql); + if (count($dups) > 0) { + if($doit){ + fix_os_table($dups); + } else{ + $uplog[]=''.count($dups).' duplicate entries in {list_os}'; + } + } + + $sql = $db->query('SELECT MIN(resolution_id) id, project_id, resolution_name + FROM {list_resolution} + GROUP BY project_id, resolution_name + HAVING COUNT(*) > 1'); + $dups = $db->fetchAllArray($sql); + if (count($dups) > 0) { + if($doit){ + fix_resolution_table($dups); + }else{ + $uplog[]=''.count($dups).' duplicate entries in {list_resolution}'; + } + } + + $sql = $db->query('SELECT MIN(status_id) id, project_id, status_name + FROM {list_status} + GROUP BY project_id, status_name + HAVING COUNT(*) > 1'); + $dups = $db->fetchAllArray($sql); + if (count($dups) > 0) { + if($doit){ + fix_status_table($dups); + }else{ + $uplog[]=''.count($dups).' duplicate entries in {list_status}'; + } + } + $sql = $db->query('SELECT MIN(tasktype_id) id, project_id, tasktype_name + FROM {list_tasktype} + GROUP BY project_id, tasktype_name + HAVING COUNT(*) > 1'); + $dups = $db->fetchAllArray($sql); + if (count($dups) > 0) { + if($doit){ + fix_tasktype_table($dups); + }else{ + $uplog[]=''.count($dups).' duplicate entries in {list_tasktype}'; + } + } + + $sql = $db->query('SELECT MIN(version_id) id, project_id, version_name + FROM {list_version} + GROUP BY project_id, version_name + HAVING COUNT(*) > 1'); + $dups = $db->fetchAllArray($sql); + if (count($dups) > 0) { + if($doit){ + fix_version_table($dups); + }else{ + $uplog[]=''.count($dups).' duplicate entries in {list_version}'; + } + } +} + +function fix_os_table($dups) { + global $db; + + foreach ($dups as $dup) { + $update_id = $dup['id']; + + $sql = $db->query('SELECT os_id id + FROM {list_os} + WHERE project_id = ? AND os_name = ?', + array($dup['project_id'], $dup['os_name'])); + $entries = $db->fetchAllArray($sql); + foreach ($entries as $entry) { + if ($entry['id'] == $update_id) { + continue; + } + + $db->query('UPDATE {tasks} + SET operating_system = ? + WHERE operating_system = ?', + array($update_id, $entry['id'])); + $db->query('DELETE FROM {list_os} WHERE os_id = ?', array($entry['id'])); + } + } +} + +function fix_resolution_table($dups) { + global $db; + + foreach ($dups as $dup) { + $update_id = $dup['id']; + + $sql = $db->query('SELECT resolution_id id + FROM {list_resolution} + WHERE project_id = ? AND resolution_name = ?', + array($dup['project_id'], $dup['resolution_name'])); + $entries = $db->fetchAllArray($sql); + foreach ($entries as $entry) { + if ($entry['id'] == $update_id) { + continue; + } + + $db->query('UPDATE {tasks} + SET resolution_reason = ? + WHERE resolution_reason = ?', + array($update_id, $entry['id'])); + $db->query('DELETE FROM {list_resolution} WHERE resolution_id = ?', array($entry['id'])); + } + } +} + +function fix_status_table($dups) { + global $db; + + foreach ($dups as $dup) { + $update_id = $dup['id']; + + $sql = $db->query('SELECT status_id id + FROM {list_status} + WHERE project_id = ? AND status_name = ?', + array($dup['project_id'], $dup['status_name'])); + $entries = $db->fetchAllArray($sql); + foreach ($entries as $entry) { + if ($entry['id'] == $update_id) { + continue; + } + + $db->query('UPDATE {tasks} + SET item_status = ? + WHERE item_status = ?', + array($update_id, $entry['id'])); + $db->query('DELETE FROM {list_status} WHERE status_id = ?', array($entry['id'])); + } + } +} + +function fix_tasktype_table($dups) { + global $db; + + foreach ($dups as $dup) { + $update_id = $dup['id']; + + $sql = $db->query('SELECT tasktype_id id + FROM {list_tasktype} + WHERE project_id = ? AND tasktype_name = ?', + array($dup['project_id'], $dup['tasktype_name'])); + $entries = $db->fetchAllArray($sql); + foreach ($entries as $entry) { + if ($entry['id'] == $update_id) { + continue; + } + + $db->query('UPDATE {tasks} + SET task_type = ? + WHERE task_type = ?', + array($update_id, $entry['id'])); + $db->query('DELETE FROM {list_tasktype} WHERE tasktype_id = ?', array($entry['id'])); + } + } +} + +function fix_version_table($dups) { + global $db; + + foreach ($dups as $dup) { + $update_id = $dup['id']; + + $sql = $db->query('SELECT version_id id + FROM {list_version} + WHERE project_id = ? AND version_name = ?', + array($dup['project_id'], $dup['version_name'])); + $entries = $db->fetchAllArray($sql); + foreach ($entries as $entry) { + if ($entry['id'] == $update_id) { + continue; + } + + $db->query('UPDATE {tasks} + SET product_version = ? + WHERE product_version = ?', + array($update_id, $entry['id'])); + $db->query('DELETE FROM {list_version} WHERE version_id = ?', array($entry['id'])); + } + } +} + +// Just a sketch on how database columns could be updated to the new format. +// Not tested for errors or used anywhere yet. + +function convert_old_entries($table, $column, $key) { + global $db; + + // Assuming that anything not beginning with < was made with older + // versions of flyspray. This will not catch neither those old entries + // where the user for some reason really added paragraph tags nor those + // made with development version before fixing ckeditors configuration + // settings. You can't have everything in a limited time frame, this + // should be just good enough. + $sql = $db->query("SELECT $key, $column " + . "FROM {". $table . "} " + . "WHERE $column NOT LIKE '<%'"); + $entries = $db->fetchAllArray($sql); + + # We should probably better use existing and proven filters for the conversions + # maybe this or existing dokuwiki functionality? + # $out=html2wiki($input, 'wikistyle'); and $out=wiki2html($input, 'wikistyle') + + foreach ($entries as $entry) { + $id = $entry[$key]; + $data = $entry[$column]; + + if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + $data = htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + } else{ + $data = htmlspecialchars($data, ENT_QUOTES , 'UTF-8'); + } + // Convert two or more line breaks to paragrahs, Windows/Unix/Linux formats + $data = preg_replace('/(\h*\r?\n)+\h*\r?\n/', "

    ", $data); + // Data coming from Macs has only carriage returns, and couldn't say + // \r?\n? in the previous regex, it would also have matched nothing. + // Even a short word like "it" has three nothings in it, one before + // i, one between i and t and one after t... + $data = preg_replace('/(\h*\r)+\h*\r/', "

    ", $data); + // Remaining single line breaks + $data = preg_replace('/\h*\r?\n/', "
    ", $data); + $data = preg_replace('/\h*\r/', "
    ", $data); + // Remove final extra break, if the data to converted ended with a line break + $data = preg_replace('#
    $#', '', $data); + // Remove final extra paragraph tags, if the data to converted ended with + // more than one line breaks + $data = preg_replace('#

    $#', '', $data); + // Enclose the whole in paragraph tags, so it looks + // the same as what ckeditor produces. + $data = '

    ' . $data . '

    '; + + $db->query("UPDATE {". $table . "} " + . "SET $column = ?" + . "WHERE $key = ?", + array($data, $id)); + } +} diff --git a/setup/upgrade/0.9.9.2/flyspray-install.xml b/setup/upgrade/0.9.9.2/flyspray-install.xml new file mode 100644 index 0000000..eac0638 --- /dev/null +++ b/setup/upgrade/0.9.9.2/flyspray-install.xml @@ -0,0 +1,1049 @@ + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + + + task_id + user_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_tense + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    + + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + + + + + + + + + + + + + + + + +
    + + INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1); + INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', ''); + INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3); + INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2); + INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4); + INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1); + INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0); + INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2); + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0) + INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4'); + INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com'); + INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en'); + INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat', ''); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress'); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', ''); + INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::'); + INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1'); + INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index'); + INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0'); + INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0); + INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1); + + diff --git a/setup/upgrade/0.9.9.2/flyspray.conf.php b/setup/upgrade/0.9.9.2/flyspray.conf.php new file mode 100644 index 0000000..86ccc51 --- /dev/null +++ b/setup/upgrade/0.9.9.2/flyspray.conf.php @@ -0,0 +1,33 @@ +; + +; This is the Flysplay configuration file. It contains the basic settings +; needed for Flyspray to operate. All other preferences are stored in the +; database itself and are managed directly within the Flyspray admin interface. +; You should consider putting this file somewhere that isn't accessible using +; a web browser, and editing header.php to point to wherever you put this file. + + + +[general] +cookiesalt = "f1s" ; Randomisation value for cookie encoding +output_buffering = "on" ; Available options: "off", "on" and "gzip" +address_rewriting = "0" ; Boolean. 0 = off, 1 = on. +reminder_daemon = "0" ; Boolean. 0 = off, 1 = on. +passwdcrypt = "md5" ; Available options: "crypt", "md5", "sha1" +doku_url = "http://en.wikipedia.org/wiki/" ; URL to your external wiki for [[dokulinks]] in FS +syntax_plugin = "none" ; Plugin name for Flyspray's syntax (use any non-existing plugin name for deafult syntax) +update_check = "1" ; Boolean. 0 = off, 1 = on. +dot_public = "http://public.research.att.com/~north/cgi-bin/webdot/webdot.cgi" ; URL to a public dot server +dot_path = "" ; Path to the dot executable (for graphs either dot_public or dot_path must be set) +dot_format = "png" ; "png" or "svg" + +[database] +dbtype = "mysql" ; Type of database ("mysql" or "pgsql" are currently supported) +dbhost = "localhost" ; Name or IP of your database server +dbname = "DBNAME" ; The name of the database +dbuser = "DBUSER" ; The user to access the database +dbpass = "DBPASS" ; The password to go with that username above +dbprefix = "flyspray_" ; Prefix of the Flyspray tables + +[attachments] +zip = "application/zip" ; MIME-type for ZIP files \ No newline at end of file diff --git a/setup/upgrade/0.9.9.2/lowercase_emails.php b/setup/upgrade/0.9.9.2/lowercase_emails.php new file mode 100644 index 0000000..24fd28e --- /dev/null +++ b/setup/upgrade/0.9.9.2/lowercase_emails.php @@ -0,0 +1,6 @@ +query('UPDATE {users} SET email_address = LOWER(email_address), jabber_id = LOWER(jabber_id)'); + +?> + diff --git a/setup/upgrade/0.9.9.2/update_users.xml b/setup/upgrade/0.9.9.2/update_users.xml new file mode 100644 index 0000000..591a1bb --- /dev/null +++ b/setup/upgrade/0.9.9.2/update_users.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    +
    \ No newline at end of file diff --git a/setup/upgrade/0.9.9.2/upgrade.info b/setup/upgrade/0.9.9.2/upgrade.info new file mode 100644 index 0000000..4ea91dd --- /dev/null +++ b/setup/upgrade/0.9.9.2/upgrade.info @@ -0,0 +1,34 @@ +[defaultupgrade] +1="update_users.xml" +2="lowercase_emails.php" + + +[develupgrade] +1="update_users.xml" + +[fsprefs] +fs_ver="0.9.7" ; doesn't matter which version +jabber_server="" +jabber_port="5222" +jabber_username="" +jabber_password="" +anon_group="0" +user_notify="1" +admin_email="flyspray@example.com" +lang_code="en" +spam_proof="1" +default_project="1" +dateformat="" +dateformat_extended="" +anon_reg="1" +page_title="Flyspray:: " +notify_registration="0" +jabber_ssl="0" +last_update_check="0" +cache_feeds="1" +global_theme="CleanFS" +visible_columns="id project tasktype severity summary status progress" +smtp_server="" +smtp_user="" +smtp_pass="" +lock_for="5" \ No newline at end of file diff --git a/setup/upgrade/0.9.9.4/flyspray-install.xml b/setup/upgrade/0.9.9.4/flyspray-install.xml new file mode 100644 index 0000000..ae2de1d --- /dev/null +++ b/setup/upgrade/0.9.9.4/flyspray-install.xml @@ -0,0 +1,1055 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + + + task_id + user_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_tense + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    + + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + + + + + + + + + + + + + + + + +
    + + INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1); + INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', ''); + INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3); + INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2); + INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4); + INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1); + INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0); + INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2); + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0) + INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4'); + INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com'); + INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en'); + INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat', ''); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress'); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', ''); + INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::'); + INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1'); + INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index'); + INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0'); + INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0); + INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1); + +
    diff --git a/setup/upgrade/0.9.9.4/flyspray.conf.php b/setup/upgrade/0.9.9.4/flyspray.conf.php new file mode 100644 index 0000000..86ccc51 --- /dev/null +++ b/setup/upgrade/0.9.9.4/flyspray.conf.php @@ -0,0 +1,33 @@ +; + +; This is the Flysplay configuration file. It contains the basic settings +; needed for Flyspray to operate. All other preferences are stored in the +; database itself and are managed directly within the Flyspray admin interface. +; You should consider putting this file somewhere that isn't accessible using +; a web browser, and editing header.php to point to wherever you put this file. + + + +[general] +cookiesalt = "f1s" ; Randomisation value for cookie encoding +output_buffering = "on" ; Available options: "off", "on" and "gzip" +address_rewriting = "0" ; Boolean. 0 = off, 1 = on. +reminder_daemon = "0" ; Boolean. 0 = off, 1 = on. +passwdcrypt = "md5" ; Available options: "crypt", "md5", "sha1" +doku_url = "http://en.wikipedia.org/wiki/" ; URL to your external wiki for [[dokulinks]] in FS +syntax_plugin = "none" ; Plugin name for Flyspray's syntax (use any non-existing plugin name for deafult syntax) +update_check = "1" ; Boolean. 0 = off, 1 = on. +dot_public = "http://public.research.att.com/~north/cgi-bin/webdot/webdot.cgi" ; URL to a public dot server +dot_path = "" ; Path to the dot executable (for graphs either dot_public or dot_path must be set) +dot_format = "png" ; "png" or "svg" + +[database] +dbtype = "mysql" ; Type of database ("mysql" or "pgsql" are currently supported) +dbhost = "localhost" ; Name or IP of your database server +dbname = "DBNAME" ; The name of the database +dbuser = "DBUSER" ; The user to access the database +dbpass = "DBPASS" ; The password to go with that username above +dbprefix = "flyspray_" ; Prefix of the Flyspray tables + +[attachments] +zip = "application/zip" ; MIME-type for ZIP files \ No newline at end of file diff --git a/setup/upgrade/0.9.9.4/upgrade.info b/setup/upgrade/0.9.9.4/upgrade.info new file mode 100644 index 0000000..3acfddb --- /dev/null +++ b/setup/upgrade/0.9.9.4/upgrade.info @@ -0,0 +1,32 @@ +[defaultupgrade] +1="upgrade.xml" + +[develupgrade] +1="upgrade.xml" + +[fsprefs] +fs_ver="0.9.7" ; doesn't matter which version +jabber_server="" +jabber_port="5222" +jabber_username="" +jabber_password="" +anon_group="0" +user_notify="1" +admin_email="flyspray@example.com" +lang_code="en" +spam_proof="1" +default_project="1" +dateformat="" +dateformat_extended="" +anon_reg="1" +page_title="Flyspray:: " +notify_registration="0" +jabber_ssl="0" +last_update_check="0" +cache_feeds="1" +global_theme="CleanFS" +visible_columns="id project tasktype severity summary status progress" +smtp_server="" +smtp_user="" +smtp_pass="" +lock_for="5" \ No newline at end of file diff --git a/setup/upgrade/0.9.9.4/upgrade.xml b/setup/upgrade/0.9.9.4/upgrade.xml new file mode 100644 index 0000000..5953d91 --- /dev/null +++ b/setup/upgrade/0.9.9.4/upgrade.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    diff --git a/setup/upgrade/0.9.9.5/flyspray-install.xml b/setup/upgrade/0.9.9.5/flyspray-install.xml new file mode 100644 index 0000000..11dc5ff --- /dev/null +++ b/setup/upgrade/0.9.9.5/flyspray-install.xml @@ -0,0 +1,1058 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + + + task_id + user_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_tense + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    + + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + + + + + + + + + + + + + + + + + + task_id + +
    + + INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1); + INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', ''); + INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3); + INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2); + INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4); + INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1); + INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0); + INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2); + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0) + INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4'); + INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com'); + INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en'); + INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat', ''); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress'); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', ''); + INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::'); + INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1'); + INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index'); + INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0'); + INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0); + INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1); + +
    diff --git a/setup/upgrade/0.9.9.5/flyspray.conf.php b/setup/upgrade/0.9.9.5/flyspray.conf.php new file mode 100644 index 0000000..86ccc51 --- /dev/null +++ b/setup/upgrade/0.9.9.5/flyspray.conf.php @@ -0,0 +1,33 @@ +; + +; This is the Flysplay configuration file. It contains the basic settings +; needed for Flyspray to operate. All other preferences are stored in the +; database itself and are managed directly within the Flyspray admin interface. +; You should consider putting this file somewhere that isn't accessible using +; a web browser, and editing header.php to point to wherever you put this file. + + + +[general] +cookiesalt = "f1s" ; Randomisation value for cookie encoding +output_buffering = "on" ; Available options: "off", "on" and "gzip" +address_rewriting = "0" ; Boolean. 0 = off, 1 = on. +reminder_daemon = "0" ; Boolean. 0 = off, 1 = on. +passwdcrypt = "md5" ; Available options: "crypt", "md5", "sha1" +doku_url = "http://en.wikipedia.org/wiki/" ; URL to your external wiki for [[dokulinks]] in FS +syntax_plugin = "none" ; Plugin name for Flyspray's syntax (use any non-existing plugin name for deafult syntax) +update_check = "1" ; Boolean. 0 = off, 1 = on. +dot_public = "http://public.research.att.com/~north/cgi-bin/webdot/webdot.cgi" ; URL to a public dot server +dot_path = "" ; Path to the dot executable (for graphs either dot_public or dot_path must be set) +dot_format = "png" ; "png" or "svg" + +[database] +dbtype = "mysql" ; Type of database ("mysql" or "pgsql" are currently supported) +dbhost = "localhost" ; Name or IP of your database server +dbname = "DBNAME" ; The name of the database +dbuser = "DBUSER" ; The user to access the database +dbpass = "DBPASS" ; The password to go with that username above +dbprefix = "flyspray_" ; Prefix of the Flyspray tables + +[attachments] +zip = "application/zip" ; MIME-type for ZIP files \ No newline at end of file diff --git a/setup/upgrade/0.9.9.5/upgrade.info b/setup/upgrade/0.9.9.5/upgrade.info new file mode 100644 index 0000000..68f3208 --- /dev/null +++ b/setup/upgrade/0.9.9.5/upgrade.info @@ -0,0 +1,34 @@ +[defaultupgrade] +1="upgrade.xml" + +[develupgrade] +1="upgrade.xml" + +[fsprefs] +fs_ver="0.9.7" ; doesn't matter which version +jabber_server="" +jabber_port="5222" +jabber_username="" +jabber_password="" +anon_group="0" +user_notify="1" +admin_email="flyspray@example.com" +lang_code="en" +spam_proof="1" +default_project="1" +dateformat="" +dateformat_extended="" +anon_reg="1" +page_title="Flyspray:: " +notify_registration="0" +jabber_ssl="0" +last_update_check="0" +cache_feeds="1" +global_theme="CleanFS" +visible_columns="id project tasktype severity summary status progress" +smtp_server="" +smtp_user="" +smtp_pass="" +lock_for="5" +email_ssl="0" +email_tls="0" \ No newline at end of file diff --git a/setup/upgrade/0.9.9.5/upgrade.xml b/setup/upgrade/0.9.9.5/upgrade.xml new file mode 100644 index 0000000..f11b3c8 --- /dev/null +++ b/setup/upgrade/0.9.9.5/upgrade.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    +
    \ No newline at end of file diff --git a/setup/upgrade/0.9.9.7/flyspray-install.xml b/setup/upgrade/0.9.9.7/flyspray-install.xml new file mode 100644 index 0000000..10c79d1 --- /dev/null +++ b/setup/upgrade/0.9.9.7/flyspray-install.xml @@ -0,0 +1,1059 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + + + task_id + user_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_tense + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    + + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + + + + + + + + + + + + + + + + + + task_id + +
    + + INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1); + INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', ''); + INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3); + INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2); + INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4); + INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1); + INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0); + INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2); + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0) + INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9'); + INSERT INTO prefs VALUES (DEFAULT, 'logo', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4'); + INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com'); + INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en'); + INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat', ''); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress'); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', ''); + INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::'); + INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1'); + INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index'); + INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0'); + INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0, 0, 0); + INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1); + +
    diff --git a/setup/upgrade/0.9.9.7/flyspray.conf.php b/setup/upgrade/0.9.9.7/flyspray.conf.php new file mode 100644 index 0000000..3b018e3 --- /dev/null +++ b/setup/upgrade/0.9.9.7/flyspray.conf.php @@ -0,0 +1,30 @@ +; + +; This is the Flysplay configuration file. It contains the basic settings +; needed for Flyspray to operate. All other preferences are stored in the +; database itself and are managed directly within the Flyspray admin interface. +; You should consider putting this file somewhere that isn't accessible using +; a web browser, and editing header.php to point to wherever you put this file. + + + +[general] +cookiesalt = "f1s" ; Randomisation value for cookie encoding +output_buffering = "on" ; Available options: "off", "on" and "gzip" +address_rewriting = "0" ; Boolean. 0 = off, 1 = on. +reminder_daemon = "0" ; Boolean. 0 = off, 1 = on. +passwdcrypt = "md5" ; Available options: "crypt", "md5", "sha1" +doku_url = "http://en.wikipedia.org/wiki/" ; URL to your external wiki for [[dokulinks]] in FS +syntax_plugin = "none" ; Plugin name for Flyspray's syntax (use any non-existing plugin name for deafult syntax) +update_check = "1" ; Boolean. 0 = off, 1 = on. + +[database] +dbtype = "mysql" ; Type of database ("mysql" or "pgsql" are currently supported) +dbhost = "localhost" ; Name or IP of your database server +dbname = "DBNAME" ; The name of the database +dbuser = "DBUSER" ; The user to access the database +dbpass = "DBPASS" ; The password to go with that username above +dbprefix = "flyspray_" ; Prefix of the Flyspray tables + +[attachments] +zip = "application/zip" ; MIME-type for ZIP files \ No newline at end of file diff --git a/setup/upgrade/0.9.9.7/upgrade.info b/setup/upgrade/0.9.9.7/upgrade.info new file mode 100644 index 0000000..324d70e --- /dev/null +++ b/setup/upgrade/0.9.9.7/upgrade.info @@ -0,0 +1,35 @@ +[defaultupgrade] +;1="upgrade.xml" + +[develupgrade] +;1="upgrade.xml" + +[fsprefs] +fs_ver="0.9.7" ; doesn't matter which version +jabber_server="" +jabber_port="5222" +jabber_username="" +jabber_password="" +anon_group="0" +user_notify="1" +admin_email="flyspray@example.com" +lang_code="en" +spam_proof="1" +default_project="1" +dateformat="" +dateformat_extended="" +anon_reg="1" +page_title="Flyspray:: " +notify_registration="0" +jabber_ssl="0" +last_update_check="0" +cache_feeds="1" +global_theme="CleanFS" +visible_columns="id project tasktype severity summary status progress" +smtp_server="" +smtp_user="" +smtp_pass="" +lock_for="5" +email_ssl="0" +email_tls="0" +default_timezone="0" \ No newline at end of file diff --git a/setup/upgrade/0.9.9/add_data.php b/setup/upgrade/0.9.9/add_data.php new file mode 100644 index 0000000..8c32d38 --- /dev/null +++ b/setup/upgrade/0.9.9/add_data.php @@ -0,0 +1,34 @@ +query('SELECT count(*) FROM {list_status}'); +if ($db->fetchOne($sql) < 1) { + $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0)"); + $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0)"); + $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0)"); + $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0)"); + $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0)"); + $db->query("INSERT INTO {list_status} (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0)"); +} + +if (Post::val('replace_resolution')) { + $db->query('UPDATE {list_resolution} SET resolution_name = ? WHERE resolution_id = ?', array('Duplicate (the real one)', 6)); +} + +$db->query("DELETE FROM {list_status} WHERE status_id = 7"); +$db->query("DELETE FROM {notifications} WHERE user_id = 0 OR task_id = 0"); + +$db->query("UPDATE {tasks} SET closure_comment='' WHERE closure_comment='0'"); +$db->query("UPDATE {groups} SET add_to_assignees = '1' WHERE assign_others_to_self =1 "); +$db->query("UPDATE {groups} SET add_votes = 1 WHERE group_id = 2 OR group_id = 3 OR group_id = 6"); +$db->query("UPDATE {groups} SET edit_assignments = '1' WHERE group_id = 2"); +$db->query("UPDATE {history} SET event_type = 3 WHERE event_type = 0"); +$db->query("UPDATE {history} SET event_type = 11 WHERE event_type = 15"); +$db->query("UPDATE {history} SET event_type = 12 WHERE event_type = 16"); +$db->query("UPDATE {history} SET field_changed = 'project_id' WHERE field_changed = 'attached_to_project'"); + +?> diff --git a/setup/upgrade/0.9.9/add_duplicates.php b/setup/upgrade/0.9.9/add_duplicates.php new file mode 100644 index 0000000..4a00a8a --- /dev/null +++ b/setup/upgrade/0.9.9/add_duplicates.php @@ -0,0 +1,41 @@ +query('SELECT task_id, closure_comment, resolution_reason FROM {tasks}'); + +while ($row = $db->fetchRow($check_sql)) +{ + if ($row['resolution_reason'] == 6) { + preg_match("/\b(?:FS#|bug )(\d+)\b/", $row['closure_comment'], $dupe_of); + if (count($dupe_of)) { + $existing = $db->query('SELECT * FROM {related} WHERE this_task = ? AND related_task = ? AND is_duplicate = 1', + array($row['task_id'], $dupe_of[1])); + + if ($db->countRows($existing) == 0) { + $db->query('INSERT INTO {related} (this_task, related_task, is_duplicate) VALUES(?,?,1)', + array($row['task_id'], $dupe_of[1])); + echo $row['task_id'] . ' is a duplicate of ' . $dupe_of[1] . '.
    '; + } + } + } +} + +$check_sql = $db->query('SELECT this_task, related_task FROM {related} WHERE is_duplicate = 0'); +$deleted = array(); + +while ($row = $db->fetchRow($check_sql)) +{ + $existing = $db->query('SELECT related_id FROM {related} WHERE this_task = ? AND related_task = ? AND is_duplicate = 0', + array($row['related_task'], $row['this_task'])); + + if ($db->countRows($existing) == 1 && !isset($deleted[$row['related_task'].'-'.$row['this_task']])) { + $deleted[$row['this_task'].'-'.$row['related_task']] = true; + $db->query('DELETE FROM {related} WHERE related_id = ?', array($db->fetchOne($existing))); + } +} + +?> diff --git a/setup/upgrade/0.9.9/add_searches.php b/setup/upgrade/0.9.9/add_searches.php new file mode 100644 index 0000000..6e5031c --- /dev/null +++ b/setup/upgrade/0.9.9/add_searches.php @@ -0,0 +1,22 @@ +query('SELECT user_id FROM {users}'); + +while ($row = $db->fetchRow($check_sql)) +{ + $db->query('DELETE FROM {searches} WHERE (name = ? OR name = ? OR name = ?) AND user_id = ?', array('Tasks I watch', 'Tasks assigned to me', 'Tasks I opened', $row['user_id'])); + $db->query('INSERT INTO {searches} (user_id, name, search_string, time) VALUES (?, \'Tasks I watch\', \'a:16:{s:6:"string";N;s:4:"type";a:1:{i:0;s:0:"";}s:3:"sev";a:1:{i:0;s:0:"";}s:3:"due";a:1:{i:0;s:0:"";}s:3:"dev";N;s:3:"cat";a:1:{i:0;s:0:"";}s:6:"status";a:1:{i:0;s:4:"open";}s:5:"order";N;s:4:"sort";N;s:7:"percent";a:1:{i:0;s:0:"";}s:6:"opened";N;s:18:"search_in_comments";N;s:14:"search_for_all";N;s:8:"reported";a:1:{i:0;s:0:"";}s:12:"only_primary";N;s:12:"only_watched";s:1:"1";}\', ' . time() . ')', + array($row['user_id'])); + $db->query('INSERT INTO {searches} (user_id, name, search_string, time) VALUES (?, \'Tasks assigned to me\', \'a:16:{s:6:"string";N;s:4:"type";a:1:{i:0;s:0:"";}s:3:"sev";a:1:{i:0;s:0:"";}s:3:"due";a:1:{i:0;s:0:"";}s:3:"dev";s:' . strlen($row['user_id']) . ':"' . $row['user_id'] .'";s:3:"cat";a:1:{i:0;s:0:"";}s:6:"status";a:1:{i:0;s:4:"open";}s:5:"order";N;s:4:"sort";N;s:7:"percent";a:1:{i:0;s:0:"";}s:6:"opened";N;s:18:"search_in_comments";N;s:14:"search_for_all";N;s:8:"reported";a:1:{i:0;s:0:"";}s:12:"only_primary";N;s:12:"only_watched";N;}\', ' . time() . ')', + array($row['user_id'])); + $db->query('INSERT INTO {searches} (user_id, name, search_string, time) VALUES (?, \'Tasks I opened\', \'a:16:{s:6:"string";N;s:4:"type";a:1:{i:0;s:0:"";}s:3:"sev";a:1:{i:0;s:0:"";}s:3:"due";a:1:{i:0;s:0:"";}s:3:"dev";N;s:3:"cat";a:1:{i:0;s:0:"";}s:6:"status";a:1:{i:0;s:4:"open";}s:5:"order";N;s:4:"sort";N;s:7:"percent";a:1:{i:0;s:0:"";}s:6:"opened";s:' . strlen($row['user_id']) . ':"' . $row['user_id'] .'";s:18:"search_in_comments";N;s:14:"search_for_all";N;s:8:"reported";a:1:{i:0;s:0:"";}s:12:"only_primary";N;s:12:"only_watched";N;}\', ' . time() . ')', + array($row['user_id'])); +} + + +?> + diff --git a/setup/upgrade/0.9.9/clean_unique.php b/setup/upgrade/0.9.9/clean_unique.php new file mode 100644 index 0000000..652630b --- /dev/null +++ b/setup/upgrade/0.9.9/clean_unique.php @@ -0,0 +1,67 @@ +query('SELECT * FROM {users} ORDER BY user_id ASC'); + +while ($row = $db->fetchRow($users)) +{ + if (!isset($deleted[$row['user_name']])) { + $deleted[$row['user_name']] = $row['user_id']; + } + + $db->query('DELETE FROM {users} WHERE user_name = ? AND user_id != ?', + array($row['user_name'], $deleted[$row['user_name']])); +} + + +$users = $db->query('SELECT * FROM {registrations} ORDER BY reg_id ASC'); + +while ($row = $db->fetchRow($users)) +{ + if (!isset($deleted[$row['user_name']])) { + $deleted[$row['user_name']] = $row['reg_id']; + } + + $db->query('DELETE FROM {registrations} WHERE user_name = ? AND reg_id != ?', + array($row['user_name'], $deleted[$row['user_name']])); +} + +// Users in groups + +$sql = $db->query('SELECT * FROM {users_in_groups} ORDER BY record_id'); +while ($row = $db->fetchRow($sql)) +{ + $db->query('DELETE FROM {users_in_groups} WHERE user_id = ? AND group_id = ? AND record_id <> ?', + array($row['user_id'], $row['group_id'], $row['record_id'])); +} + +// Group names + +$sql = $db->query('SELECT * FROM {groups} ORDER BY group_id ASC'); +while ($row = $db->fetchRow($sql)) +{ + $col = 'belongs_to_project'; + if (!isset($row[$col])) { + $col = 'project_id'; + } + + $db->query('DELETE FROM {groups} WHERE group_name = ? AND '.$col.' = ? AND group_id <> ?', + array($row['group_name'], $row[$col], $row['group_id'])); +} + +// Out of range value adjusted for column.. +$sql = $db->query('SELECT * FROM {tasks}'); +while ($row = $db->fetchRow($sql)) +{ + $db->query('UPDATE {tasks} SET date_closed = ?, last_edited_time = ? WHERE task_id = ?', + array(intval($row['date_closed']), intval($row['last_edited_time']), $row['task_id'])); + if (isset($row['due_date'])) { + $db->query('UPDATE {tasks} SET due_date = ? WHERE task_id = ?', + array(intval($row['due_date']), $row['task_id'])); + } +} +?> diff --git a/setup/upgrade/0.9.9/convert_categories.php b/setup/upgrade/0.9.9/convert_categories.php new file mode 100644 index 0000000..99789ad --- /dev/null +++ b/setup/upgrade/0.9.9/convert_categories.php @@ -0,0 +1,43 @@ +query('SELECT category_id FROM {list_category} WHERE parent_id = ? AND project_id = ?', array($parent, $pr)); + + while ($row = $db->fetchRow($result)) { + // recursive execution of this function for each + // child of this node + // $right is the current right value, which is + // incremented by the rebuild_tree function + $right = rebuild_tree($row['category_id'], $right, $pr); + } + + // we've got the left value, and now that we've processed + // the children of this node we also know the right value + $db->query('UPDATE {list_category} SET lft= ?, rgt= ? WHERE category_id = ?', array($left, $right, $parent)); + $sql = $db->query('SELECT * FROM {list_category} WHERE category_id = ? OR project_id=? AND parent_id=-1', array($parent, $pr)); + if (!$db->countRows($sql)) { + $db->query('INSERT INTO {list_category} (project_id, lft, rgt, category_name, parent_id) VALUES(?,?,?,?,-1)', + array($pr,$left,$right,'root')); + } + // return the right value of this node + 1 + return $right+1; +} + +$projects = $db->query('SELECT project_id FROM {projects}'); + +// Global project +rebuild_tree(0, 1, 0); +while ($pr = $db->fetchRow($projects)) { + rebuild_tree(0, 1, $pr['project_id']); +} + +?> diff --git a/setup/upgrade/0.9.9/convert_private.php b/setup/upgrade/0.9.9/convert_private.php new file mode 100644 index 0000000..b871d39 --- /dev/null +++ b/setup/upgrade/0.9.9/convert_private.php @@ -0,0 +1,26 @@ +query('SELECT * FROM {history} WHERE event_type = 26 OR event_type = 27'); + +while ($row = $db->fetchRow($check_sql)) +{ + $db->query('DELETE FROM {history} WHERE history_id = ?', array($row['history_id'])); + if ($row['event_type'] == 26) { + $row['old_value'] = 0; + $row['new_value'] = 1; + } + if ($row['event_type'] == 27) { + $row['old_value'] = 1; + $row['new_value'] = 0; + } + $db->query("INSERT INTO {history} (task_id, user_id, event_date, event_type, field_changed, old_value, new_value) + VALUES(?, ?, ?, 0, 'mark_private', ?, ?)", + array($row['task_id'], $row['user_id'], $row['event_date'], $row['old_value'], $row['new_value'])); +} + + +?> diff --git a/setup/upgrade/0.9.9/flyspray-begin.xml b/setup/upgrade/0.9.9/flyspray-begin.xml new file mode 100644 index 0000000..aac979a --- /dev/null +++ b/setup/upgrade/0.9.9/flyspray-begin.xml @@ -0,0 +1,748 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    +
    diff --git a/setup/upgrade/0.9.9/flyspray-final.xml b/setup/upgrade/0.9.9/flyspray-final.xml new file mode 100644 index 0000000..5db6a96 --- /dev/null +++ b/setup/upgrade/0.9.9/flyspray-final.xml @@ -0,0 +1,976 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + + + task_id + user_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_tense + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    + + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + + + + + + + + + + + + + + + + +
    +
    diff --git a/setup/upgrade/0.9.9/flyspray-install.xml b/setup/upgrade/0.9.9/flyspray-install.xml new file mode 100644 index 0000000..7496241 --- /dev/null +++ b/setup/upgrade/0.9.9/flyspray-install.xml @@ -0,0 +1,1044 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + + + task_id + user_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_tense + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + task_id + user_id + +
    + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + user_name + +
    + + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + + + + + + + + + + + + + + + + +
    + + INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality.', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1); + INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts.', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project.', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1); + INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', ''); + INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3); + INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2); + INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4); + INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1); + INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0); + INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2); + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0) + INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '0.9.9'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4'); + INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com'); + INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en'); + INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat', ''); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id project category tasktype severity summary status progress'); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', ''); + INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::'); + INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1'); + INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org/support. You can customise this message by clicking the **Manage Project** link in the menu above...', 1, 'id category tasktype severity summary status progress', 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index'); + INSERT INTO tasks VALUES (1, 1, 1, 1130024797, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0'); + INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Mr Super User', 'super@example.com', 'super@example.com', 0, 1, 1, '', '', 25, 0, 0, 0); + INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1); + +
    diff --git a/setup/upgrade/0.9.9/flyspray.conf.php b/setup/upgrade/0.9.9/flyspray.conf.php new file mode 100644 index 0000000..86ccc51 --- /dev/null +++ b/setup/upgrade/0.9.9/flyspray.conf.php @@ -0,0 +1,33 @@ +; + +; This is the Flysplay configuration file. It contains the basic settings +; needed for Flyspray to operate. All other preferences are stored in the +; database itself and are managed directly within the Flyspray admin interface. +; You should consider putting this file somewhere that isn't accessible using +; a web browser, and editing header.php to point to wherever you put this file. + + + +[general] +cookiesalt = "f1s" ; Randomisation value for cookie encoding +output_buffering = "on" ; Available options: "off", "on" and "gzip" +address_rewriting = "0" ; Boolean. 0 = off, 1 = on. +reminder_daemon = "0" ; Boolean. 0 = off, 1 = on. +passwdcrypt = "md5" ; Available options: "crypt", "md5", "sha1" +doku_url = "http://en.wikipedia.org/wiki/" ; URL to your external wiki for [[dokulinks]] in FS +syntax_plugin = "none" ; Plugin name for Flyspray's syntax (use any non-existing plugin name for deafult syntax) +update_check = "1" ; Boolean. 0 = off, 1 = on. +dot_public = "http://public.research.att.com/~north/cgi-bin/webdot/webdot.cgi" ; URL to a public dot server +dot_path = "" ; Path to the dot executable (for graphs either dot_public or dot_path must be set) +dot_format = "png" ; "png" or "svg" + +[database] +dbtype = "mysql" ; Type of database ("mysql" or "pgsql" are currently supported) +dbhost = "localhost" ; Name or IP of your database server +dbname = "DBNAME" ; The name of the database +dbuser = "DBUSER" ; The user to access the database +dbpass = "DBPASS" ; The password to go with that username above +dbprefix = "flyspray_" ; Prefix of the Flyspray tables + +[attachments] +zip = "application/zip" ; MIME-type for ZIP files \ No newline at end of file diff --git a/setup/upgrade/0.9.9/rename_columns.php b/setup/upgrade/0.9.9/rename_columns.php new file mode 100644 index 0000000..07a949a --- /dev/null +++ b/setup/upgrade/0.9.9/rename_columns.php @@ -0,0 +1,14 @@ +dblink); + +$sqlarray = $dict->RenameColumnSQL($conf['database']['dbprefix'] . 'tasks', 'attached_to_project', 'project_id', 'TYPE INT(3) NOTNULL DEFAULT 0'); +$dict->ExecuteSQLArray($sqlarray); + +$sqlarray = $dict->RenameColumnSQL($conf['database']['dbprefix'] . 'groups', 'belongs_to_project', 'project_id', ' TYPE INT(3) NOTNULL DEFAULT 0'); +$dict->ExecuteSQLArray($sqlarray); + +?> \ No newline at end of file diff --git a/setup/upgrade/0.9.9/upgrade.info b/setup/upgrade/0.9.9/upgrade.info new file mode 100644 index 0000000..e5ea7e5 --- /dev/null +++ b/setup/upgrade/0.9.9/upgrade.info @@ -0,0 +1,44 @@ +[defaultupgrade] +0="clean_unique.php" +1="flyspray-begin.xml" +2="upgrade_assignments.php" +3="convert_categories.php" +4="convert_private.php" +5="add_duplicates.php" +6="add_searches.php" +7="rename_columns.php" +8="flyspray-final.xml" +9="add_data.php" + +[develupgrade] +1="flyspray-final.xml" + +[options] + +1="
    " + +[fsprefs] +fs_ver="0.9.7" ; doesn't matter which version +jabber_server="" +jabber_port="5222" +jabber_username="" +jabber_password="" +anon_group="0" +user_notify="1" +admin_email="flyspray@example.com" +lang_code="en" +spam_proof="1" +default_project="1" +dateformat="" +dateformat_extended="" +anon_reg="1" +page_title="Flyspray:: " +notify_registration="0" +jabber_ssl="0" +last_update_check="0" +cache_feeds="1" +global_theme="CleanFS" +visible_columns="id project tasktype severity summary status progress" +smtp_server="" +smtp_user="" +smtp_pass="" \ No newline at end of file diff --git a/setup/upgrade/0.9.9/upgrade_assignments.php b/setup/upgrade/0.9.9/upgrade_assignments.php new file mode 100644 index 0000000..a9aa53c --- /dev/null +++ b/setup/upgrade/0.9.9/upgrade_assignments.php @@ -0,0 +1,31 @@ +query("SELECT task_id, assigned_to + FROM {tasks} + WHERE assigned_to > '0'"); + +while ($row = $db->fetchRow($check_sql)) +{ + $check = $db->query('SELECT assigned_id FROM {assigned} WHERE task_id = ? AND user_id = ?', + array($row['task_id'], $row['assigned_to'])); + if ($db->fetchOne($check)) { + continue; + } + + $db->query('INSERT INTO {assigned} + (task_id, user_id) + VALUES (?,?)', + array($row['task_id'], $row['assigned_to'])); + + $db->query('UPDATE {tasks} + SET assigned_to = 0 + WHERE task_id = ?', + array($row['task_id'])); +} +?> diff --git a/setup/upgrade/1.0/datadict-postgres.inc.php b/setup/upgrade/1.0/datadict-postgres.inc.php new file mode 100644 index 0000000..ebcb001 --- /dev/null +++ b/setup/upgrade/1.0/datadict-postgres.inc.php @@ -0,0 +1,606 @@ +type; + $len = $fieldobj->max_length; + } + $is_serial = is_object($fieldobj) && !empty($fieldobj->primary_key) && !empty($fieldobj->unique) && + !empty($fieldobj->has_default) && substr($fieldobj->default_value,0,8) == 'nextval('; + + switch (strtoupper($t)) { + case 'INTERVAL': + case 'CHAR': + case 'CHARACTER': + case 'VARCHAR': + case 'NAME': + case 'BPCHAR': + if ($len <= $this->blobSize) return 'C'; + + case 'TEXT': + return 'X'; + + case 'IMAGE': // user defined type + case 'BLOB': // user defined type + case 'BIT': // This is a bit string, not a single bit, so don't return 'L' + case 'VARBIT': + case 'BYTEA': + return 'B'; + + case 'BOOL': + case 'BOOLEAN': + return 'L'; + + case 'DATE': + return 'D'; + + case 'TIME': + case 'DATETIME': + case 'TIMESTAMP': + case 'TIMESTAMPTZ': + return 'T'; + + case 'INTEGER': return !$is_serial ? 'I' : 'R'; + case 'SMALLINT': + case 'INT2': return !$is_serial ? 'I2' : 'R'; + case 'INT4': return !$is_serial ? 'I4' : 'R'; + case 'BIGINT': + case 'INT8': return !$is_serial ? 'I8' : 'R'; + + case 'OID': + case 'SERIAL': + return 'R'; + + case 'FLOAT4': + case 'FLOAT8': + case 'DOUBLE PRECISION': + case 'REAL': + return 'F'; + + default: + return 'N'; + } + } + + function actualType($meta) + { + switch($meta) { + case 'C': return 'VARCHAR'; + case 'XL': + case 'X': return 'TEXT'; + + case 'C2': return 'VARCHAR'; + case 'X2': return 'TEXT'; + + case 'B': return 'BYTEA'; + + case 'D': return 'DATE'; + case 'TS': + case 'T': return 'TIMESTAMP'; + + case 'L': return 'BOOLEAN'; + case 'I': return 'INTEGER'; + case 'I1': return 'SMALLINT'; + case 'I2': return 'INT2'; + case 'I4': return 'INT4'; + case 'I8': return 'INT8'; + + case 'F': return 'FLOAT8'; + case 'N': return 'NUMERIC'; + default: + return $meta; + } + } + + /** + * Adding a new Column + * + * reimplementation of the default function as postgres does NOT allow to set the default in the same statement + * + * @param string $tabname table-name + * @param string $flds column-names and types for the changed columns + * @return array with SQL strings + */ + function addColumnSQL($tabname, $flds) + { + $tabname = $this->tableName($tabname); + $sql = array(); + $not_null = false; + list($lines,$pkey) = $this->_genFields($flds); + $alter = 'ALTER TABLE ' . $tabname . $this->addCol . ' '; + foreach($lines as $v) { + if (($not_null = preg_match('/NOT NULL/i',$v))) { + $v = preg_replace('/NOT NULL/i','',$v); + } + + if (preg_match('/^([^ ]+) .*DEFAULT (\'[^\']+\'|\"[^\"]+\"|[^ ]+)/',$v,$matches)) { + list(,$colname,$default) = $matches; + $sql[] = $alter . str_replace('DEFAULT '.$default,'',$v); + $sql[] = 'UPDATE '.$tabname.' SET '.$colname.'='.$default; + $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET DEFAULT ' . $default; + } + // SERIAL is not a true type in PostgreSQL and is only allowed when creating a new table. + // See http://www.postgresql.org/docs/9.4/static/datatype-numeric.html, 8.1.4. Serial Types. + elseif (preg_match('/^([^ ]+) .*SERIAL/i',$v,$matches)) { + list(,$colname,$default) = $matches; + $sql[] = 'CREATE SEQUENCE '.$tabname.'_'.$colname.'_seq'; + $sql[] = $alter.$colname.' INTEGER'; + $sql[] = 'ALTER SEQUENCE '.$tabname.'_'.$colname.'_seq OWNED BY '.$tabname.'.'.$colname; + $sql[] = 'UPDATE '.$tabname.' SET '.$colname.' = nextval(\''.$tabname.'_'.$colname.'_seq\')'; + $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET DEFAULT nextval(\''.$tabname.'_'.$colname.'_seq\')'; + $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL'; + $not_null = false; + } else { + $sql[] = $alter . $v; + } + if ($not_null) { + list($colname) = explode(' ',$v); + $sql[] = 'ALTER TABLE '.$tabname.' ALTER COLUMN '.$colname.' SET NOT NULL'; + } + } + return $sql; + } + + + function dropIndexSQL ($idxname, $tabname = NULL) + { + return array(sprintf($this->dropIndex, $this->tableName($idxname), $this->tableName($tabname))); + } + + /** + * Change the definition of one column + * + * Postgres can't do that on it's own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds complete defintion of the new table, eg. for postgres, default '' + * @param array/ $tableoptions options for the new table see createTableSQL, default '' + * @return array with SQL strings + */ + /* + function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + if (!$tableflds) { + if ($this->debug) ADOConnection::outp("alterColumnSQL needs a complete table-definiton for PostgreSQL"); + return array(); + } + return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions); + }*/ + + function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + // Check if alter single column datatype available - works with 8.0+ + $has_alter_column = 8.0 <= (float) @$this->serverInfo['version']; + + if ($has_alter_column) { + $tabname = $this->tableName($tabname); + $sql = array(); + list($lines,$pkey) = $this->_genFields($flds); + $set_null = false; + foreach($lines as $v) { + $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; + if ($not_null = preg_match('/NOT NULL/i',$v)) { + $v = preg_replace('/NOT NULL/i','',$v); + } + + // SERIAL is not a true type in PostgreSQL and is only allowed when creating a new table. + // See http://www.postgresql.org/docs/9.4/static/datatype-numeric.html, 8.1.4. Serial Types. + if (preg_match('/SERIAL/i',$v)) { + continue; + } + // this next block doesn't work - there is no way that I can see to + // explicitly ask a column to be null using $flds + else if ($set_null = preg_match('/NULL/i',$v)) { + // if they didn't specify not null, see if they explicitely asked for null + // Lookbehind pattern covers the case 'fieldname NULL datatype DEFAULT NULL' + // only the first NULL should be removed, not the one specifying + // the default value + $v = preg_replace('/(?metaColumns($tabname); + list(,$colname,$default) = $matches; + $alter .= $colname; + if ($this->connection) { + $old_coltype = $this->connection->metaType($existing[strtoupper($colname)]); + } + else { + $old_coltype = $t; + } + $v = preg_replace('/^' . preg_quote($colname) . '\s/', '', $v); + $t = trim(str_replace('DEFAULT '.$default,'',$v)); + + // Type change from bool to int + if ( $old_coltype == 'L' && $t == 'INTEGER' ) { + $sql[] = $alter . ' DROP DEFAULT'; + $sql[] = $alter . " TYPE $t USING ($colname::BOOL)::INT"; + $sql[] = $alter . " SET DEFAULT $default"; + } + // Type change from int to bool + else if ( $old_coltype == 'I' && $t == 'BOOLEAN' ) { + if( strcasecmp('NULL', trim($default)) != 0 ) { + $default = $this->connection->qstr($default); + } + $sql[] = $alter . ' DROP DEFAULT'; + $sql[] = $alter . " TYPE $t USING CASE WHEN $colname = 0 THEN false ELSE true END"; + $sql[] = $alter . " SET DEFAULT $default"; + } + // Any other column types conversion + else { + $sql[] = $alter . " TYPE $t"; + $sql[] = $alter . " SET DEFAULT $default"; + } + + } + else { + // drop default? + preg_match ('/^\s*(\S+)\s+(.*)$/',$v,$matches); + list (,$colname,$rest) = $matches; + $alter .= $colname; + $sql[] = $alter . ' TYPE ' . $rest; + } + +# list($colname) = explode(' ',$v); + if ($not_null) { + // this does not error out if the column is already not null + $sql[] = $alter . ' SET NOT NULL'; + } + if ($set_null) { + // this does not error out if the column is already null + $sql[] = $alter . ' DROP NOT NULL'; + } + } + return $sql; + } + + // does not have alter column + if (!$tableflds) { + if ($this->debug) ADOConnection::outp("AlterColumnSQL needs a complete table-definiton for PostgreSQL"); + return array(); + } + return $this->_recreate_copy_table($tabname,False,$tableflds,$tableoptions); + } + + /** + * Drop one column + * + * Postgres < 7.3 can't do that on it's own, you need to supply the complete defintion of the new table, + * to allow, recreating the table and copying the content over to the new table + * @param string $tabname table-name + * @param string $flds column-name and type for the changed column + * @param string $tableflds complete defintion of the new table, eg. for postgres, default '' + * @param array/ $tableoptions options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + function dropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='') + { + $has_drop_column = 7.3 <= (float) @$this->serverInfo['version']; + if (!$has_drop_column && !$tableflds) { + if ($this->debug) ADOConnection::outp("DropColumnSQL needs complete table-definiton for PostgreSQL < 7.3"); + return array(); + } + if ($has_drop_column) { + return ADODB_DataDict::dropColumnSQL($tabname, $flds); + } + return $this->_recreate_copy_table($tabname,$flds,$tableflds,$tableoptions); + } + + /** + * Save the content into a temp. table, drop and recreate the original table and copy the content back in + * + * We also take care to set the values of the sequenz and recreate the indexes. + * All this is done in a transaction, to not loose the content of the table, if something went wrong! + * @internal + * @param string $tabname table-name + * @param string $dropflds column-names to drop + * @param string $tableflds complete defintion of the new table, eg. for postgres + * @param array/string $tableoptions options for the new table see CreateTableSQL, default '' + * @return array with SQL strings + */ + function _recreate_copy_table($tabname,$dropflds,$tableflds,$tableoptions='') + { + if ($dropflds && !is_array($dropflds)) $dropflds = explode(',',$dropflds); + $copyflds = array(); + foreach($this->metaColumns($tabname) as $fld) { + if (!$dropflds || !in_array($fld->name,$dropflds)) { + // we need to explicit convert varchar to a number to be able to do an AlterColumn of a char column to a nummeric one + if (preg_match('/'.$fld->name.' (I|I2|I4|I8|N|F)/i',$tableflds,$matches) && + in_array($fld->type,array('varchar','char','text','bytea'))) { + $copyflds[] = "to_number($fld->name,'S9999999999999D99')"; + } else { + $copyflds[] = $fld->name; + } + // identify the sequence name and the fld its on + if ($fld->primary_key && $fld->has_default && + preg_match("/nextval\('([^']+)'::text\)/",$fld->default_value,$matches)) { + $seq_name = $matches[1]; + $seq_fld = $fld->name; + } + } + } + $copyflds = implode(', ',$copyflds); + + $tempname = $tabname.'_tmp'; + $aSql[] = 'BEGIN'; // we use a transaction, to make sure not to loose the content of the table + $aSql[] = "SELECT * INTO TEMPORARY TABLE $tempname FROM $tabname"; + $aSql = array_merge($aSql,$this->dropTableSQL($tabname)); + $aSql = array_merge($aSql,$this->createTableSQL($tabname,$tableflds,$tableoptions)); + $aSql[] = "INSERT INTO $tabname SELECT $copyflds FROM $tempname"; + if ($seq_name && $seq_fld) { // if we have a sequence we need to set it again + $seq_name = $tabname.'_'.$seq_fld.'_seq'; // has to be the name of the new implicit sequence + $aSql[] = "SELECT setval('$seq_name',MAX($seq_fld)) FROM $tabname"; + } + $aSql[] = "DROP TABLE $tempname"; + // recreate the indexes, if they not contain one of the droped columns + foreach($this->metaIndexes($tabname) as $idx_name => $idx_data) + { + if (substr($idx_name,-5) != '_pkey' && (!$dropflds || !count(array_intersect($dropflds,$idx_data['columns'])))) { + $aSql = array_merge($aSql,$this->createIndexSQL($idx_name,$tabname,$idx_data['columns'], + $idx_data['unique'] ? array('UNIQUE') : False)); + } + } + $aSql[] = 'COMMIT'; + return $aSql; + } + + function dropTableSQL($tabname) + { + $sql = ADODB_DataDict::dropTableSQL($tabname); + + $drop_seq = $this->_dropAutoIncrement($tabname); + if ($drop_seq) $sql[] = $drop_seq; + + return $sql; + } + + // return string must begin with space + function _createSuffix($fname, &$ftype, $fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned) + { + if ($fautoinc) { + $ftype = 'SERIAL'; + return ''; + } + $suffix = ''; + if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault"; + if ($fnotnull) $suffix .= ' NOT NULL'; + if ($fconstraint) $suffix .= ' '.$fconstraint; + return $suffix; + } + + // search for a sequece for the given table (asumes the seqence-name contains the table-name!) + // if yes return sql to drop it + // this is still necessary if postgres < 7.3 or the SERIAL was created on an earlier version!!! + function _dropAutoIncrement($tabname) + { + $tabname = $this->connection->quote('%'.$tabname.'%'); + + $seq = $this->connection->getOne("SELECT relname FROM pg_class WHERE NOT relname ~ 'pg_.*' AND relname LIKE $tabname AND relkind='S'"); + + // check if a tables depends on the sequenz and it therefor cant and dont need to be droped separatly + if (!$seq || $this->connection->getOne("SELECT relname FROM pg_class JOIN pg_depend ON pg_class.relfilenode=pg_depend.objid WHERE relname='$seq' AND relkind='S' AND deptype='i'")) { + return False; + } + return "DROP SEQUENCE ".$seq; + } + + function renameTableSQL($tabname,$newname) + { + if (!empty($this->schema)) { + $rename_from = $this->tableName($tabname); + $schema_save = $this->schema; + $this->schema = false; + $rename_to = $this->tableName($newname); + $this->schema = $schema_save; + return array (sprintf($this->renameTable, $rename_from, $rename_to)); + } + + return array (sprintf($this->renameTable, $this->tableName($tabname),$this->tableName($newname))); + } + + /* + CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name ( + { column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ] + | table_constraint } [, ... ] + ) + [ INHERITS ( parent_table [, ... ] ) ] + [ WITH OIDS | WITHOUT OIDS ] + where column_constraint is: + [ CONSTRAINT constraint_name ] + { NOT NULL | NULL | UNIQUE | PRIMARY KEY | + CHECK (expression) | + REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL ] + [ ON DELETE action ] [ ON UPDATE action ] } + [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + and table_constraint is: + [ CONSTRAINT constraint_name ] + { UNIQUE ( column_name [, ... ] ) | + PRIMARY KEY ( column_name [, ... ] ) | + CHECK ( expression ) | + FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] + [ MATCH FULL | MATCH PARTIAL ] [ ON DELETE action ] [ ON UPDATE action ] } + [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] + */ + + + /* + CREATE [ UNIQUE ] INDEX index_name ON table +[ USING acc_method ] ( column [ ops_name ] [, ...] ) +[ WHERE predicate ] +CREATE [ UNIQUE ] INDEX index_name ON table +[ USING acc_method ] ( func_name( column [, ... ]) [ ops_name ] ) +[ WHERE predicate ] + */ + function _indexSQL($idxname, $tabname, $flds, $idxoptions) + { + $sql = array(); + + if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) { + $sql[] = sprintf ($this->dropIndex, $idxname, $tabname); + if ( isset($idxoptions['DROP']) ) + return $sql; + } + + if ( empty ($flds) ) { + return $sql; + } + + $unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : ''; + + $s = 'CREATE' . $unique . ' INDEX ' . $idxname . ' ON ' . $tabname . ' '; + + if (isset($idxoptions['HASH'])) + $s .= 'USING HASH '; + + if ( isset($idxoptions[$this->upperName]) ) + $s .= $idxoptions[$this->upperName]; + + if ( is_array($flds) ) + $flds = implode(', ',$flds); + $s .= '(' . $flds . ')'; + $sql[] = $s; + + return $sql; + } + + function _getSize($ftype, $ty, $fsize, $fprec) + { + if (strlen($fsize) && $ty != 'X' && $ty != 'B' && $ty != 'I' && strpos($ftype,'(') === false) { + $ftype .= "(".$fsize; + if (strlen($fprec)) $ftype .= ",".$fprec; + $ftype .= ')'; + } + return $ftype; + } + + /** + "Florian Buzin [ easywe ]" + + This function changes/adds new fields to your table. You don't + have to know if the col is new or not. It will check on its own. + */ + function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false) + { + global $ADODB_FETCH_MODE; + + $save = $ADODB_FETCH_MODE; + $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC; + if ($this->connection->fetchMode !== false) $savem = $this->connection->setFetchMode(false); + + // check table exists + $save_handler = $this->connection->raiseErrorFn; + $this->connection->raiseErrorFn = ''; + $cols = $this->metaColumns($tablename); + $this->connection->raiseErrorFn = $save_handler; + + if (isset($savem)) $this->connection->setFetchMode($savem); + $ADODB_FETCH_MODE = $save; + + if ( empty($cols)) { + return $this->createTableSQL($tablename, $flds, $tableoptions); + } + + $addedcols = array(); + $modifiedcols = array(); + + if (is_array($flds)) { + // Cycle through the update fields, comparing + // existing fields to fields to update. + // if the Metatype and size is exactly the + // same, ignore - by Mark Newham + foreach($flds as $k=>$v) { + if ( isset($cols[$k]) && is_object($cols[$k]) ) { + // If already not allowing nulls, then don't change + $obj = $cols[$k]; + if (isset($obj->not_null) && $obj->not_null) + $v = str_replace('NOT NULL','',$v); + if (isset($obj->auto_increment) && $obj->auto_increment && empty($v['AUTOINCREMENT'])) + $v = str_replace('AUTOINCREMENT','',$v); + + $c = $cols[$k]; + $ml = $c->max_length; + $mt = $this->metaType($c->type,$ml); + + if (isset($c->scale)) $sc = $c->scale; + else $sc = 99; // always force change if scale not known. + + if ($sc == -1) $sc = false; + list($fsize, $fprec) = $this->_getSizePrec($v['SIZE']); + + if ($ml == -1) $ml = ''; + if ($mt == 'X') $ml = $v['SIZE']; + if (($mt != $v['TYPE']) || ($ml != $fsize || $sc != $fprec) || (isset($v['AUTOINCREMENT']) && $v['AUTOINCREMENT'] != $obj->auto_increment)) { + $modifiedcols[$k] = $v; + } + } else { + $addedcols[$k] = $v; + } + } + } + + + $sql = array(); + $sql = $this->addColumnSQL($tablename, $addedcols); + + // already exists, alter table instead + list($lines,$pkey,$idxs) = $this->_genFields($modifiedcols); + // genfields can return FALSE at times + if ($lines == null) $lines = array(); + + $holdflds = array(); + foreach ( $lines as $id => $v ) { + if ( isset($cols[$id]) && is_object($cols[$id]) ) { + + $flds = lens_ParseArgs($v,','); + + // We are trying to change the size of the field, if not allowed, simply ignore the request. + // $flds[1] holds the type, $flds[2] holds the size -postnuke addition + if ($flds && in_array(strtoupper(substr($flds[0][1],0,4)),$this->invalidResizeTypes4) + && (isset($flds[0][2]) && is_numeric($flds[0][2]))) { + if ($this->debug) ADOConnection::outp(sprintf("

    %s cannot be changed to %s currently

    ", $flds[0][0], $flds[0][1])); + #echo "

    $this->alterCol cannot be changed to $flds currently

    "; + continue; + } + $holdflds[] = $modifiedcols[$id]; + } + } + $modifiedcols = $holdflds; + $sql += $this->alterColumnSQL($tablename, $modifiedcols); + + if ($dropOldFlds) { + $alter = 'ALTER TABLE ' . $this->tableName($tablename); + foreach ( $cols as $id => $v ) + if ( !isset($lines[$id]) ) + $sql[] = $alter . $this->dropCol . ' ' . $v->name; + } + return $sql; + } +} diff --git a/setup/upgrade/1.0/flyspray-install.xml b/setup/upgrade/1.0/flyspray-install.xml new file mode 100644 index 0000000..ee7102b --- /dev/null +++ b/setup/upgrade/1.0/flyspray-install.xml @@ -0,0 +1,1373 @@ + + + + multiple addresses for users. subject to change in FS1.1+! + + + + + + + + + + +
    + + Do not use this table. pre FS1.0-beta table + + +
    + + Pending requests for admins and PMs to attend to + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + resolved_by + project_id + +
    + + Who is assigned what task + + + + + + + + + + + + + + + task_id + user_id + +
    + + List the names and locations of files attached to tasks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + Table to cache RSS/Atom feeds + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    + + task comments + + + + + + + + + + + + + + + + + + + + + + + + + task_id + + + user_id + +
    + + Task inter-dependencies + + + + + + + + + + + + + + + task_id + dep_task_id + +
    + + log of time spent on tasks + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + User Groups for the Flyspray bug killer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + log of Flyspray activities + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + + + event_date + + + event_type + +
    + + hierarchic task categories + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + Operating system list for the Flyspray bug killer + + + + + + + + + + + + + + + + + + + + + + project_id + os_name + +
    + + task close reasons + + + + + + + + + + + + + + + + + + + + + + project_id + resolution_name + +
    + + List of possible task statuses + + + + + + + + + + + + + + + + + + + + + + project_id + status_name + +
    + + definition of tags/labels for tasks + + + + + + + + + + + + + + + + + + + + + + + project_id + tag_name + +
    + + List of possible task types + + + + + + + + + + + + + + + + + + + + + + project_id + tasktype_name + +
    + + list of project versions/milestones/software release versions + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_name + + + project_id + version_tense + +
    + + Notification body and subject + + + + + + + + + + + + + + +
    + + Notification recipient list + + + + + + + + + + + + + + +
    + + Extra task notification registrations are stored here + + + + + + + + + + + + + + + task_id + user_id + +
    + + global settings of Flyspray + + + + + + + + +
    + + project settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + > + +
    + + table for yet unconfirmed user registrations + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + contains loose task relations to another task or task duplicates + + + + + + + + + + + + + + + + + + + this_task + related_task + is_duplicate + +
    + + scheduled task reminders + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + Saves custom searches of users + + + + + + + + + + + + + + + + + + +
    + + main table for storing tasks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + + + project_id + supertask_id + + + supertask_id + task_id + project_id + +
    + + join table to add tags/labels to tasks + + + + + + + + + task_id + tag_id + +
    + + user accounts of Flyspray + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + last login of a user + + + + + user_name + +
    + + Which users are in which groups + + + + + + + + + + + + + + + group_id + user_id + + + user_id + +
    + + votes for tasks + + + + + + + + + + + + + + + + + + task_id + +
    + + link a resource (e.g. an URL) with a task - in a more structured way than the task description text area. + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + INSERT INTO groups VALUES (DEFAULT, 'Admin', 'Members have unlimited access to all functionality', 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Developers', 'Global Developers for all projects', 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Reporters', 'Open new tasks / add comments in all projects', 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Basic', 'Members can login, relying upon Project permissions only', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1); + INSERT INTO groups VALUES (DEFAULT, 'Pending', 'Users who are awaiting approval of their accounts', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + INSERT INTO groups VALUES (DEFAULT, 'Project Managers', 'Permission to do anything related to the Default Project', 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + INSERT INTO history VALUES (DEFAULT, 1, 1, 1130024797, 1, '', '', ''); + INSERT INTO list_category VALUES (DEFAULT, 1, 'Backend / Core', 1, 0, 2, 3); + INSERT INTO list_category VALUES (DEFAULT, 0, 'root', 0, 0, 1, 2); + INSERT INTO list_category VALUES (DEFAULT, 1, 'root', 0, 0, 1, 4); + INSERT INTO list_os VALUES (DEFAULT, 1, 'All', 1, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Windows', 2, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Linux', 3, 1); + INSERT INTO list_os VALUES (DEFAULT, 1, 'Mac OS', 4, 1); + INSERT INTO list_resolution VALUES (DEFAULT, 'Not a bug', 1, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t fix', 2, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Won''t implement', 3, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Works for me', 4, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Deferred', 5, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Duplicate', 6, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Fixed', 7, 1, 0); + INSERT INTO list_resolution VALUES (DEFAULT, 'Implemented', 8, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Bug Report', 1, 1, 0); + INSERT INTO list_tasktype VALUES (DEFAULT, 'Feature Request', 2, 1, 0); + INSERT INTO list_version VALUES (DEFAULT, 1, 'Development', 1, 1, 2); + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Unconfirmed', 1, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('New', 2, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Assigned', 3, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Researching', 4, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Waiting on Customer', 5, 1, 0) + INSERT INTO list_status (status_name, list_position, show_in_list, project_id) VALUES ('Requires testing', 6, 1, 0) + INSERT INTO prefs VALUES (DEFAULT, 'fs_ver', '1.0'); + INSERT INTO prefs VALUES (DEFAULT, 'logo', 'flyspray_small.png'); + INSERT INTO prefs VALUES (DEFAULT, 'gravatars', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'emailNoHTML', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_port', '5222'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_username', ''); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_password', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_group', '4'); + INSERT INTO prefs VALUES (DEFAULT, 'user_notify', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'admin_email', 'flyspray@example.com'); + INSERT INTO prefs VALUES (DEFAULT, 'lang_code', 'en'); + INSERT INTO prefs VALUES (DEFAULT, 'need_approval', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'spam_proof', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_project', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'default_entry', 'index'); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat', ''); + INSERT INTO prefs VALUES (DEFAULT, 'dateformat_extended', ''); + INSERT INTO prefs VALUES (DEFAULT, 'anon_reg', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'global_theme', 'CleanFS'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_columns', 'id category tasktype priority severity summary status progress'); + INSERT INTO prefs VALUES (DEFAULT, 'visible_fields', 'tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes'); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_server', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_user', ''); + INSERT INTO prefs VALUES (DEFAULT, 'smtp_pass', ''); + INSERT INTO prefs VALUES (DEFAULT, 'page_title', 'Flyspray::'); + INSERT INTO prefs VALUES (DEFAULT, 'notify_registration', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'jabber_ssl', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'last_update_check', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'intro_message', ''); + INSERT INTO prefs VALUES (DEFAULT, 'cache_feeds', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'disable_lostpw', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'disable_changepw', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'days_before_alert', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'hide_emails', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'pages_welcome_msg', 'index'); + INSERT INTO prefs VALUES (DEFAULT, 'active_oauths', ''); + INSERT INTO prefs VALUES (DEFAULT, 'only_oauth_reg', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'enable_avatars', '1'); + INSERT INTO prefs VALUES (DEFAULT, 'max_avatar_size', '50'); + INSERT INTO prefs VALUES (DEFAULT, 'default_order_by', 'id'); + INSERT INTO prefs VALUES (DEFAULT, 'default_order_by_dir', 'desc'); + INSERT INTO prefs VALUES (DEFAULT, 'url_rewriting', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'max_vote_per_day', '2'); + INSERT INTO prefs VALUES (DEFAULT, 'votes_per_project', '10'); + INSERT INTO prefs VALUES (DEFAULT, 'custom_style', ''); + INSERT INTO prefs VALUES (DEFAULT, 'general_integration', ''); + INSERT INTO prefs VALUES (DEFAULT, 'footer_integration', ''); + INSERT INTO prefs VALUES (DEFAULT, 'repeat_password', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'repeat_emailaddress', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'massops', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'captcha_securimage', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'captcha_recaptcha', '0'); + INSERT INTO prefs VALUES (DEFAULT, 'captcha_recaptcha_sitekey', ''); + INSERT INTO prefs VALUES (DEFAULT, 'captcha_recaptcha_secret', ''); + INSERT INTO projects VALUES (DEFAULT, 'Default Project', 'CleanFS', 0, 'Welcome to your first Flyspray project! We hope that Flyspray provides you with many hours of increased productivity. If you have any issues, go to http://flyspray.org . You can customise this message [[?do=pm&project=1|here]]', 1, 'id category tasktype priority severity summary status progress', 'tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes', 1, 1, 0, '', '', NULL, '0', NULL, NULL, '', 'en', 0, 0, 0, NULL, 'index', 0, 0,'Undecided', '', 0, 0, 0, 'id desc', 'DESC', '', 1 ); + INSERT INTO tasks VALUES (DEFAULT, 1, 1, 1452600000, 1, 0, 0, 0, ' ', 'Sample Task', 'This isn''t a real task. You should close it and start opening some real tasks.', 2, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 0, 0, '', '0', 0, 0, 0); + INSERT INTO users VALUES (DEFAULT, 'super', '1b3231655cebb7a1f783eddf27d254ca', 'Superuser', '', '', 0, 1, 1, '', '', '', 25, 0, 0, 0, 0, 'en', '0', '', '', 0, 0, NULL); + INSERT INTO users_in_groups VALUES (DEFAULT, 1, 1); + +
    diff --git a/setup/upgrade/1.0/flyspray.conf.php b/setup/upgrade/1.0/flyspray.conf.php new file mode 100644 index 0000000..2b2e7f4 --- /dev/null +++ b/setup/upgrade/1.0/flyspray.conf.php @@ -0,0 +1,48 @@ +; + +; This is the Flysplay configuration file. It contains the basic settings +; needed for Flyspray to operate. All other preferences are stored in the +; database itself and are managed directly within the Flyspray admin interface. +; You should consider putting this file somewhere that isn't accessible using +; a web browser, and editing header.php to point to wherever you put this file. + + + +[general] +cookiesalt = "f1s" ; Randomisation value for cookie encoding +output_buffering = "on" ; Available options: "off", "on" and "gzip" +address_rewriting = "0" ; Boolean. 0 = off, 1 = on. +reminder_daemon = "0" ; Boolean. 0 = off, 1 = on. +passwdcrypt = "" ; Available options: "" - chooses best default (currently "crypt"), "crypt", "md5", "sha1", "sha512" Note: md5 and sha1 are considered insecure for hashing passwords (statement date: 2016) +doku_url = "http://en.wikipedia.org/wiki/" ; URL to your external wiki for [[dokulinks]] in FS +syntax_plugin = "none" ; Plugin name for syntax format for task description and other textarea fields, "none" for the default ckeditor (or any nonexistent plugin folder name), popular alternative: "dokuwiki", see plugins/ directory +update_check = "1" ; Boolean. 0 = off, 1 = on. + +securecookies = false ; Boolean false or true. You can set it only to true if you have a HTTPS Flyspray setup fully working with valid SSL/TLS certificate. +; If set to true the Flyspray session cookies should be sent only over HTTPS, never HTTP. +; Check cookie properties within devtools (press F12) of modern (year 2015) webbrowsers. + +[database] +dbtype = "mysql" ; Type of database ("mysql" or "pgsql" are currently supported) +dbhost = "localhost" ; Name or IP of your database server +dbname = "DBNAME" ; The name of the database +dbuser = "DBUSER" ; The user to access the database +dbpass = "DBPASS" ; The password to go with that username above +dbprefix = "flyspray_" ; Prefix of the Flyspray tables + +[attachments] +zip = "application/zip" ; MIME-type for ZIP files + +[oauth] +github_secret = "" +github_id = "" +github_redirect = "YOURDOMAIN/index.php?do=oauth&provider=github" +google_secret = "" +google_id = "" +google_redirect = "YOURDOMAIN/index.php?do=oauth&provider=google" +facebook_secret = "" +facebook_id = "" +facebook_redirect = "YOURDOMAIN/index.php?do=oauth&provider=facebook" +microsoft_secret = "" +microsoft_id = "" +microsoft_redirect = "YOURDOMAIN/index.php" diff --git a/setup/upgrade/1.0/upgrade.info b/setup/upgrade/1.0/upgrade.info new file mode 100644 index 0000000..a1510a5 --- /dev/null +++ b/setup/upgrade/1.0/upgrade.info @@ -0,0 +1,70 @@ +[defaultupgrade] +1="upgrade.xml" +2="varchartotext.php" + +[develupgrade] +1="upgrade.xml" +2="varchartotext.php" + +[fsprefs] +fs_ver="1.0" +logo="flyspray_small.png" +jabber_server="" +jabber_port="5222" +jabber_username="" +jabber_password="" +anon_group="0" +user_notify="1" +admin_email="flyspray@example.com" +lang_code="en" +need_approval="0" +spam_proof="1" +default_project="1" +default_entry="index" +dateformat="" +dateformat_extended="" +anon_reg="1" +page_title="Flyspray:: " +notify_registration="0" +jabber_ssl="0" +last_update_check="0" +cache_feeds="1" +global_theme="CleanFS" +visible_columns="id supertask project tasktype severity summary status progress" +visible_fields="supertask tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes" +smtp_server="" +smtp_user="" +smtp_pass="" +lock_for="5" +email_ssl="0" +email_tls="0" +gravatars="0" +emailNoHTML="0" +default_timezone="0" +intro_message="" +disable_lostpw="0" +disable_changepw="0" +days_before_alert="0" +hide_emails="1" +pages_welcome_msg="index" +active_oauths="" +only_oauth_reg="0" +enable_avatars="1" +max_avatar_size="50" +default_order_by="id" +default_order_by_dir="desc" +url_rewriting="0" +max_vote_per_day="2" +votes_per_project="10" +custom_style="" +general_integration="" +footer_integration="" +repeat_password="0" +repeat_emailaddress="0" +massops="0" +; Would like to see captchastuff be optional prefs, but +; current upgrade logic wipes such additional prefs if not listed here too. +captcha_securimage="0" +captcha_recaptcha="0" +captcha_recaptcha_sitekey="" +captcha_recaptcha_secret="" diff --git a/setup/upgrade/1.0/upgrade.xml b/setup/upgrade/1.0/upgrade.xml new file mode 100644 index 0000000..0a48596 --- /dev/null +++ b/setup/upgrade/1.0/upgrade.xml @@ -0,0 +1,902 @@ + + + + List the names and locations of files attached to tasks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + comment_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + type + topic + project_id + max_items + + + type + topic + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + last login of a user + + + + + user_name + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + group_name + project_id + + + project_id + +
    + + global settings of Flyspray + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + + + task_severity + + + task_type + + + product_category + + + item_status + + + is_closed + + + closedby_version + + + due_date + + + project_id + supertask_id + list_order + + + supertask_id + list_order + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + task_id + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + +
    + + + + + + + + + + + + + + + + + + + + + + + project_id + os_name + +
    + + + + + + + + + + + + + + + + + + + + + + + project_id + resolution_name + +
    + + + + + + + + + + + + + + + + + + + + + + + project_id + status_name + +
    + + + + + + + + + + + + + + + + + + + + + + + + project_id + tag_name + +
    + + + + + + + + + + + + + + + + + + + + + + + project_id + tasktype_name + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + project_id + version_name + + + project_id + version_tense + +
    + + + + + + + + + + task_id + tag_id + +
    + + UPDATE projects SET visible_fields = 'tasktype category severity priority status private assignedto reportedin dueversion duedate progress os votes' WHERE visible_fields = '' + UPDATE projects SET theme_style = 'CleanFS' + UPDATE prefs SET pref_value = 'CleanFS' WHERE pref_name = 'global_theme' + +
    diff --git a/setup/upgrade/1.0/varchartotext.php b/setup/upgrade/1.0/varchartotext.php new file mode 100644 index 0000000..3bba5ea --- /dev/null +++ b/setup/upgrade/1.0/varchartotext.php @@ -0,0 +1,17 @@ +query('ALTER TABLE {prefs} ALTER COLUMN pref_value TYPE text'); + $db->query('ALTER TABLE {prefs} ALTER COLUMN pref_value SET DEFAULT \'\''); +} +elseif($db->dbtype=='mysqli' || $db->dbtype=='mysql') { + $sinfo=$db->dblink->serverInfo(); + if(isset($sinfo['version']) && version_compare($sinfo['version'], '5.5.3')>=0 ){ + $db->query('ALTER TABLE {prefs} CHANGE `pref_value` `pref_value` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL'); + }else{ + $db->query('ALTER TABLE {prefs} CHANGE `pref_value` `pref_value` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'); + } +} +else{ + $db->query('ALTER TABLE {prefs} CHANGE `pref_value` `pref_value` TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL'); +} +?> -- cgit v1.2.3-54-g00ecf