diff --git a/.github/workflows/php-syntax-check.yml b/.github/workflows/php-syntax-check.yml index d31edbd99..55ed48b4a 100644 --- a/.github/workflows/php-syntax-check.yml +++ b/.github/workflows/php-syntax-check.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Check PHP syntax run: | diff --git a/docker/Dockerfile-php7 b/docker/Dockerfile-php7 deleted file mode 100644 index 45519042b..000000000 --- a/docker/Dockerfile-php7 +++ /dev/null @@ -1,14 +0,0 @@ -FROM php:7.4-apache -MAINTAINER craigk5n - -RUN docker-php-ext-install mysqli - -#COPY docker/cron-hourly /tmp/cron.hourly -#RUN crontab /tmp/cron.hourly - -# Run the cron every hour -#RUN echo '0 * * * * php /var/www/html/tools/send_reminders.php' > /etc/crontabs/root -#TODO: setup cron - -#RUN chown -R www-data:www-data /var/www - diff --git a/docker/Dockerfile-php8 b/docker/Dockerfile-php8 index 9a962caf5..625e9f984 100644 --- a/docker/Dockerfile-php8 +++ b/docker/Dockerfile-php8 @@ -1,11 +1,9 @@ -#escape=` -# To run on Windows, where \ is the path separator. - -FROM php:8.0-apache -# MAINTAINER deprecated in favor of LABEL. -LABEL craigk5n -LABEL vendor "k5n.us" +# Use the official PHP image with Apache +FROM php:8-apache +LABEL maintainer="craig@k5n.us" +LABEL vendor="k5n.us" +# Install mysqli extension RUN docker-php-ext-install mysqli # Copy all files except those in .dockerignore @@ -15,3 +13,9 @@ COPY . /var/www/html/ # to allow the web-based installer to update it. RUN touch /var/www/html/includes/settings.php RUN chmod 777 /var/www/html/includes/settings.php + +# Set working directory +WORKDIR /var/www/html + +# Start Apache server in the foreground +CMD ["apache2-foreground"] diff --git a/docker/Dockerfile-php8-dev b/docker/Dockerfile-php8-dev index 207f576cc..7a1576408 100644 --- a/docker/Dockerfile-php8-dev +++ b/docker/Dockerfile-php8-dev @@ -1,12 +1,21 @@ -FROM php:8.0-apache -LABEL org.opencontainers.image.authors="craig@k5n.us" +# Use the official PHP image with Apache +FROM php:8-apache +LABEL maintainer="craig@k5n.us" +LABEL vendor="k5n.us" + +# Install mysqli extension RUN docker-php-ext-install mysqli -#COPY docker/cron-hourly /tmp/cron.hourly -#RUN crontab /tmp/cron.hourly +# Install GD extension and its dependencies +RUN apt-get update && apt-get install -y \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libpng-dev \ + && docker-php-ext-configure gd --with-freetype --with-jpeg \ + && docker-php-ext-install -j$(nproc) gd -# Run the cron every hour -#RUN echo '0 * * * * php /var/www/html/tools/send_reminders.php' > /etc/crontabs/root -#TODO: setup cron +# Set working directory +WORKDIR /var/www/html -#RUN chown -R www-data:www-data /var/www +# Start Apache server in the foreground +CMD ["apache2-foreground"] diff --git a/docker/docker-compose-php7.yml b/docker/docker-compose-php7.yml deleted file mode 100644 index 58d6c5cd3..000000000 --- a/docker/docker-compose-php7.yml +++ /dev/null @@ -1,44 +0,0 @@ -# The first time you run this, you will need to grant permission -# for the webcalendar user to access mariadb (after you have run -# docker-compose up). You only need to do this once. -# -# Start a shell on the mariadb container: -# docker-compose exec db /bin/sh -# Start the mariadb client: -# /bin/mariadb -p -# (enter the MYSQL_ROOT_PASSWORD below) -# Execute the following three db commands: -# GRANT ALL PRIVILEGES ON *.* TO webcalendar@localhost IDENTIFIED BY 'Webcalendar.1' WITH GRANT OPTION; -# FLUSH PRIVILEGES; -# QUIT - -version: '3.1' - -services: - - db: - image: mariadb - container_name: webcalendar-db - volumes: - - mysql-data:/var/lib/mysql - - /etc/localtime:/etc/localtime:ro - environment: - - MYSQL_ROOT_PASSWORD=Webcalendar.1 - - MYSQL_PASSWORD=Webcalendar.1 - - MYSQL_DATABASE=webcalendar - - MYSQL_USER=webcalendar - restart: unless-stopped - - webcalendar-php7: - build: - context: . - dockerfile: Dockerfile - depends_on: - - db - ports: - - 8080:80 - volumes: - - .:/var/www/html/ - -volumes: - mysql-data: diff --git a/docker/docker-compose-php8-dev.yml b/docker/docker-compose-php8-dev.yml index 85663f9ec..a9de423a3 100644 --- a/docker/docker-compose-php8-dev.yml +++ b/docker/docker-compose-php8-dev.yml @@ -1,9 +1,10 @@ +# Run docker-compose from the top-level WebCalendar directory and not from this "docker" subdirectory. # The first time you run this, you will need to grant permission # for the webcalendar user to access mariadb (after you have run # docker-compose up). You only need to do this once. # # Start a shell on the mariadb container: -# docker-compose -f docker-compose-php8.yml exec db /bin/sh +# docker-compose -f docker/docker-compose-php8-dev.yml exec db /bin/sh # Start the mariadb client: # /bin/mariadb -p # (enter the MYSQL_ROOT_PASSWORD below) @@ -14,7 +15,7 @@ # # If you need shell access on the webserver container running WebCalendar, you can use # the following command: -# docker-compose -f docker-compose-php8.yml exec webcalendar-php8 /bin/sh +# docker-compose -f docker/docker-compose-php8-dev.yml exec webcalendar-php8 /bin/sh version: '3.1' @@ -42,7 +43,7 @@ services: ports: - 8080:80 volumes: - - .:/var/www/html/ + - ..:/var/www/html/ volumes: mysql-data: diff --git a/docker/docker-compose-php8.yml b/docker/docker-compose-php8.yml index 05373334f..1e8b13c1f 100644 --- a/docker/docker-compose-php8.yml +++ b/docker/docker-compose-php8.yml @@ -1,9 +1,10 @@ +# Run docker-compose from the top-level WebCalendar directory and not from this "docker" subdirectory. # The first time you run this, you will need to grant permission # for the webcalendar user to access mariadb (after you have run # docker-compose up). You only need to do this once. # # Start a shell on the mariadb container: -# docker-compose -f docker-compose-php8.yml exec db /bin/sh +# docker-compose -f docker/docker-compose-php8.yml exec db /bin/sh # Start the mariadb client: # /bin/mariadb -p # (enter the MYSQL_ROOT_PASSWORD below) @@ -14,7 +15,7 @@ # # If you need shell access on the webserver container running WebCalendar, you can use # the following command: -# docker-compose -f docker-compose-php8.yml exec webcalendar-php8 /bin/sh +# docker-compose -f docker/docker-compose-php8.yml exec webcalendar-php8 /bin/sh version: '3.1' diff --git a/includes/classes/Event.php b/includes/classes/Event.php index cbebdd4f4..994ed8140 100644 --- a/includes/classes/Event.php +++ b/includes/classes/Event.php @@ -17,192 +17,141 @@ class Event { /** * The event's name. - * @var string - * @access private */ - var $_name; + private string $_name; /** * The event's description. - * @var string - * @access private */ - var $_description; + private string $_description; /** * The event's date (in YYYYMMDD format). - * @var string - * @access private */ - var $_date; + private string $_date; /** * The event's date in the local user's timezone */ - var $_localDate; + private $_localDate; /** * The event's time (in HHMMSS format). - * @var string - * @access private */ - var $_time; + private string $_time; /** * The event's time in local timezone (in HHMM format) */ - var $_localTime; + private string $_localTime; /** * The event's modified date (in YYYYMMDD format). - * @var string - * @access private */ - var $_moddate; + private string $_moddate; /** * The event's modified time (in HHMMSS format). - * @var string - * @access private */ - var $_modtime; + private string $_modtime; /** * The event's ID. - * @var int - * @access private */ - var $_id; + private int $_id; /** * Extension ID. * * If this event is an extension of an event that carried over into the * current date, $_extForID will hold the original event's date. - * - * @var mixed - * @access private */ - var $_extForID; + private $_extForID; /** * The event's priority. - * @var int - * @access private */ - var $_priority; + private int $_priority; /** * The event's access level. - * @var string - * @access private */ - var $_access; + private string $_access; /** * The event's duration in minutes. - * @var int - * @access private */ - var $_duration; + private int $_duration; /** * The event's status. - * @var string - * @access private */ - var $_status; + private string $_status; /** * The event's owner. - * @var string - * @access private */ - var $_owner; + private string $_owner; /** * The event's category ID. - * @var int - * @access private */ - var $_category; + private string $_category; /** - * Array of categories... not set by default. + * Array of categories... not set by default. * Must be set with setCategories first. */ - var $_categories; + private $_categories; /** * The event's owner. - * @var mixed - * @access private */ - var $_login; + private string $_login; /** * The event's type. - * @var mixed - * @access private */ - var $_calType; + private $_calType; /** * The event's type name. - * @var mixed - * @access private */ - var $_calTypeName; + private $_calTypeName; /** * The event's location. * @var mixed * @access private */ - var $_location; + private $_location; /** * The event's url. - * @var mixed - * @access private */ - var $_url; + private mixed $_url; /** * The event's dueDate. - * @var mixed - * @access private */ - var $_dueDate; + private string $_dueDate; /** * The event's dueTime. - * @var mixed - * @access private */ - var $_dueTime; + private $_dueTime; + /** + * The event's due date and time. + */ + private string $_due; /** * The event's percent. - * @var mixed - * @access private */ - var $_percent; + private $_percent; /** * The event's end time . - * @var mixed - * @access private */ - var $_endTime; + private $_endTime; /** * The event's end datetime . - * @var mixed - * @access private */ - var $_endDateTime; + private $_endDateTime; /** * Is this an All Day event? - * @var bool - * @access private */ - var $_allDay; + private $_allDay; /** * Is this an Timed event? - * @var bool - * @access private */ - var $_timed; + private $_timed; /** * Is this an Untimed event? - * @var bool - * @access private */ - var $_untimed; - + private $_untimed; /** * Flag to record a cloned event - * @var int - * @access private */ - var $_clone; + private $_clone; + /** * Creates a new Event. * @@ -235,7 +184,6 @@ class Event { function __construct ( $name, $description, $date, $time, $id, $extForID, $priority, $access, $duration, $status, $owner, $category, $login, $calType, $location, $url, $dueDate, $dueTime, $percent, $moddate, $modtime ) { - $this->_name = $name; $this->_description = $description; $this->_date = $date; @@ -303,19 +251,21 @@ function getDate() { return $this->_date; } - function getDateTimeAdjusted() { - $year = substr ( $this->_date, 0, 4 ); - $month = substr ( $this->_date, 4, 2 ); - $day = substr ( $this->_date, 6, 2 ); - if ( $this->isTimed() ) { - $h = (int) ( $this->_time / 10000 ); - $m = ( $this->_time / 100 ) % 100; - $this->_Date = date ( 'Ymd', gmmktime ( $h, $m, 0, $month, $day, $year ) ); - } else { - $h = $m = 0; - $this->_Date = date ( 'Ymd', mktime ( $h, $m, 0, $month, $day, $year ) ); - } - return $this->_Date; + function getDateTimeAdjusted() + { + $year = substr($this->_date, 0, 4); + $month = substr($this->_date, 4, 2); + $day = substr($this->_date, 6, 2); + $ret = null; + if ($this->isTimed()) { + $h = (int) ($this->_time / 10000); + $m = ($this->_time / 100) % 100; + $ret = date('Ymd', gmmktime($h, $m, 0, $month, $day, $year)); + } else { + $h = $m = 0; + $ret = date('Ymd', mktime($h, $m, 0, $month, $day, $year)); + } + return $ret; } /** * Gets the event's time @@ -402,8 +352,7 @@ function getDueDateTimeTS() { */ function getDateTime() { $time = ($this->_time > 0? $this->_time: 0); - $this->_DateTime = $this->_date . sprintf ( "%06d", $time ); - return $this->_DateTime; + return $this->_date . sprintf ( "%06d", $time ); } /** @@ -413,19 +362,21 @@ function getDateTime() { * * @access public */ - function getDateTimeTS() { - $year = substr ( $this->_date, 0, 4 ); - $month = substr ( $this->_date, 4, 2 ); - $day = substr ( $this->_date, 6, 2 ); - if ( $this->isTimed() ) { - $h = (int) ( $this->_time / 10000 ); - $m = ( $this->_time / 100 ) % 100; - $this->_DateTime = gmmktime ( $h, $m, 0, $month, $day, $year ); - } else { - $h = $m = 0; - $this->_DateTime = mktime ( $h, $m, 0, $month, $day, $year ); - } - return $this->_DateTime; + function getDateTimeTS() + { + $ret = null; + $year = substr($this->_date, 0, 4); + $month = substr($this->_date, 4, 2); + $day = substr($this->_date, 6, 2); + if ($this->isTimed()) { + $h = (int) ($this->_time / 10000); + $m = ($this->_time / 100) % 100; + $ret = gmmktime($h, $m, 0, $month, $day, $year); + } else { + $h = $m = 0; + $ret = mktime($h, $m, 0, $month, $day, $year); + } + return $ret; } /** diff --git a/includes/config.php b/includes/config.php index 825ea5c33..1d4d07c65 100644 --- a/includes/config.php +++ b/includes/config.php @@ -191,9 +191,17 @@ function do_config($callingFromInstall=false) } } } + } else if (!file_exists(__DIR__ . '/settings.php') && !$callingFromInstall) { + // Redirect to installer + if (file_exists(__DIR__ . '/../install/index.php')) { + header('Location: install/index.php'); + exit; + } else { + die_miserable_death(translate('Could not find settings.php file...')); + } } else { // Load from settings.php file - $settings_content = file_get_contents(__DIR__ . '/settings.php'); + $settings_content = @file_get_contents(__DIR__ . '/settings.php'); if (empty($settings_content)) { if ($callingFromInstall) { return; // not an error during install @@ -228,11 +236,10 @@ function do_config($callingFromInstall=false) } // Extract db settings into global vars. - $db_database = $settings['db_database']; - $db_host = $settings['db_host']; - $db_login = $settings['db_login']; - $db_password = (empty($settings['db_password']) - ? '' : $settings['db_password']); + $db_database = $settings['db_database'] ?? ''; + $db_host = $settings['db_host'] ?? ''; + $db_login = $settings['db_login'] ?? ''; + $db_password = $settings['db_password'] ?? ''; $db_persistent = (preg_match( '/(1|yes|true|on)/i', $settings['db_persistent'] @@ -241,7 +248,7 @@ function do_config($callingFromInstall=false) '/(1|yes|true|on)/i', $settings['db_debug'] ) ? true : false); - $db_type = $settings['db_type']; + $db_type = $settings['db_type'] ?? ''; // If no db settings, then user has likely started install but not yet // completed. So, send them back to the install script. @@ -346,7 +353,7 @@ function do_config($callingFromInstall=false) // (only an option when there are no database schema changes between // the version and the new version.) if (upgrade_requires_db_changes($db_type, $versionInDb, $PROGRAM_VERSION)) { - header($locateStr . $versionInDb); + header($locateStr); exit; } else { // We can just update the version in the database and move on. diff --git a/includes/dbi4php.php b/includes/dbi4php.php index 7e4412115..354a83c93 100644 --- a/includes/dbi4php.php +++ b/includes/dbi4php.php @@ -571,89 +571,103 @@ function dbi_get_blob( $table, $column, $key ) { * * @return bool True on success */ -function dbi_free_result( $res ) { - if( $res === true ) // Not needed for UPDATE, DELETE, etc - return; +function dbi_free_result($res) +{ + if ($res === true) { // Not needed for UPDATE, DELETE, etc. + return true; + } - if( strcmp( $GLOBALS['db_type'], 'ibase' ) == 0 ) - return ibase_free_result( $res ); - elseif( strcmp( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) - return db2_free_result( $res ); - elseif( strcmp( $GLOBALS['db_type'], 'mysqli' ) == 0 ) - return mysqli_free_result( $res ); - elseif( strcmp( $GLOBALS['db_type'], 'odbc' ) == 0 ) - return odbc_free_result( $res ); - elseif( strcmp( $GLOBALS['db_type'], 'oracle' ) == 0 ) { - // Not supported. Ingore. - if( $GLOBALS['oracle_statement'] >= 0 ) { - OCIFreeStatement( $GLOBALS['oracle_statement'] ); - $GLOBALS['oracle_statement'] = -1; - } - } elseif( strcmp( $GLOBALS['db_type'], 'postgresql' ) == 0 ) - return pg_freeresult( $res ); - elseif( strcmp( $GLOBALS['db_type'], 'sqlite' ) == 0 ) { - // Not supported + $dbType = $GLOBALS['db_type'] ?? 'undefined'; + switch ($dbType) { + case 'ibase': + return ibase_free_result($res); + case 'ibm_db2': + return db2_free_result($res); + case 'mysqli': + return mysqli_free_result($res); + case 'odbc': + return odbc_free_result($res); + case 'oracle': + if ($GLOBALS['oracle_statement'] >= 0) { + OCIFreeStatement($GLOBALS['oracle_statement']); + $GLOBALS['oracle_statement'] = -1; + } + return true; // Assuming a successful operation as it's not directly supported. + case 'postgresql': + return pg_freeresult($res); + case 'sqlite': + // Not supported for SQLite, just return true. + return true; + case 'sqlite3': + // Not needed for SQLite3, just return true. + return true; + case 'undefined': + dbi_fatal_error('dbi_free_result(): ' . translate('db_type not defined.')); + break; + default: + dbi_fatal_error('dbi_free_result(): ' . translate('Unsupported db_type.') . ' (' . htmlentities($dbType) . ')'); + break; } - elseif( strcmp( $GLOBALS['db_type'], 'sqlite3' ) == 0 ) { - // Not needed - } else - dbi_fatal_error( 'dbi_free_result(): ' - . translate( 'db_type not defined.' ) ); } -/** - * Gets the latest database error message. - * - * @return string The text of the last database error. (The type of information - * varies depending on which type of database is being used.) - */ -function dbi_error() { - if( strcmp( $GLOBALS['db_type'], 'ibase' ) == 0 ) - $ret = ibase_errmsg(); - elseif( strcmp( $GLOBALS['db_type'], 'ibm_db2' ) == 0 ) { - $ret = db2_conn_errormsg(); - if( $ret == '' ) - $ret = db2_stmt_errormsg(); - } elseif (strcmp($GLOBALS['db_type'], 'mysqli') == 0) { - if (!empty($GLOBALS['db_connection_info']['last_error'])) { - $ret = $GLOBALS['db_connection_info']['last_error']; - } else { - $ret = $GLOBALS['db_connection']->error; - } - } elseif( strcmp( $GLOBALS['db_type'], 'odbc' ) == 0 ) - // No way to get error from ODBC API. - $ret = translate( 'Unknown ODBC error.' ); - elseif( strcmp( $GLOBALS['db_type'], 'oracle' ) == 0 ) { - $e = OCIError( $GLOBALS['oracle_connection'] - ? $GLOBALS['oracle_connection'] : '' ); - $ret = htmlentities( $e['message'] ); - } elseif( strcmp( $GLOBALS['db_type'], 'postgresql' ) == 0 ) - $ret = pg_errormessage( $GLOBALS['postgresql_connection'] ); - elseif( strcmp( $GLOBALS['db_type'], 'sqlite' ) == 0 ) { - if( empty( $GLOBALS['db_sqlite_error_str'] ) ) { - $ret = sqlite_last_error( $GLOBALS['sqlite_c'] ); - } else { - $ret = $GLOBALS['db_sqlite_error_str']; - $GLOBALS['db_sqlite_error_str'] = ''; - } - } elseif ( strcmp ( $GLOBALS['db_type'], 'sqlite3' ) == 0 ) { - try { - if ( empty($$GLOBALS['sqlite3_c']) || !empty($GLOBALS['db_sqlite_error_str'])) { - $ret = $GLOBALS['db_sqlite_error_str']; +function dbi_error() +{ + $dbType = $GLOBALS['db_type'] ?? 'undefined'; + + switch ($dbType) { + case 'ibase': + return ibase_errmsg(); + + case 'ibm_db2': + $ret = db2_conn_errormsg(); + return ($ret == '') ? db2_stmt_errormsg() : $ret; + + case 'mysqli': + if (!empty($GLOBALS['db_connection_info']['last_error'])) { + return $GLOBALS['db_connection_info']['last_error']; } else { - $ret = $GLOBALS['sqlite3_c']->lastErrorMsg (); + return $GLOBALS['db_connection']->error; } - } catch ( Exception $e) { - $GLOBALS['db_sqlite_error_str'] = $e->getMessage(); - $ret = $e->getMessage(); - } - } else - $ret = 'dbi_error(): ' . translate( 'db_type not defined.' ); - return ( strlen( $ret ) ? $ret : translate( 'Unknown error.' ) ); + case 'odbc': + return translate('Unknown ODBC error.'); + + case 'oracle': + $e = OCIError($GLOBALS['oracle_connection'] ? $GLOBALS['oracle_connection'] : ''); + return htmlentities($e['message']); + + case 'postgresql': + return pg_errormessage($GLOBALS['postgresql_connection']); + + case 'sqlite': + if (empty($GLOBALS['db_sqlite_error_str'])) { + return sqlite_last_error($GLOBALS['sqlite_c']); + } else { + return $GLOBALS['db_sqlite_error_str']; + } + + case 'sqlite3': + try { + if (empty($GLOBALS['sqlite3_c']) || !empty($GLOBALS['db_sqlite_error_str'])) { + return $GLOBALS['db_sqlite_error_str']; + } else { + return $GLOBALS['sqlite3_c']->lastErrorMsg(); + } + } catch (Exception $e) { + $GLOBALS['db_sqlite_error_str'] = $e->getMessage(); + return $e->getMessage(); + } + + case 'undefined': + return 'dbi_error(): ' . translate('db_type not defined.'); + + default: + return 'dbi_error(): ' . translate('Unsupported db_type.') . ' (' . htmlentities($dbType) . ')'; + } } + /** * Displays a fatal database error and aborts execution. * diff --git a/install/index.php b/install/index.php index b9edf2584..5d644dbb8 100644 --- a/install/index.php +++ b/install/index.php @@ -230,6 +230,7 @@ function_exists('gd_info'), $databaseExists = false; $databaseCurrent = false; $settingsSaved = true; // True if a valid settings.php found unless user changes settings +$detectedDbVersion = 'Unknown'; if ($canConnectDb) { $reportedDbVersion = getDbVersion(); $detectedDbVersion = getDatabaseVersionFromSchema(); @@ -381,7 +382,11 @@ function_exists('gd_info'), =')) ? "Supported" : "Not supported"; ?> diff --git a/install/install_appsettings.php b/install/install_appsettings.php index 780467787..1e40da88e 100644 --- a/install/install_appsettings.php +++ b/install/install_appsettings.php @@ -202,6 +202,6 @@ function handlePulldownUpdate() { printNextPageButton($action); } } else { - printSubmitButton($action, $html, $buttonLabel); + printSubmitButton($action, $html ?? null, $buttonLabel ?? null); } ?> \ No newline at end of file diff --git a/install/install_appsettings_handler.php b/install/install_appsettings_handler.php index fea01fc7c..e7200e3b5 100644 --- a/install/install_appsettings_handler.php +++ b/install/install_appsettings_handler.php @@ -1,38 +1,44 @@ "; print_r($_SESSION); echo ""; exit; - // Did the user change anything - $foundChange = false; - foreach ($app_settings as $setting) { - if ($_SESSION[$setting] != $settings[$setting] ){ - $foundChange = true; - } - } - if ($foundChange) { - // Require user to save and overwrite settings.php in a future step. - $_SESSION['appSettingsModified'] = 1; + $_SESSION['mode'] = $_POST['mode']; + $_SESSION['single_user_login'] = $_POST['single_user_login']; + // echo "
"; print_r($_SESSION); echo "
"; exit; + // Did the user change anything + $foundChange = false; + foreach ($app_settings as $setting) { + if (empty($settings[$setting]) || $_SESSION[$setting] != $settings[$setting]) { + $foundChange = true; } - redirectToNextAction(); - } else { - $error = translate('Invalid Application Settings'); } + if ($foundChange) { + // Require user to save and overwrite settings.php in a future step. + $_SESSION['appSettingsModified'] = 1; + } + $appSettingsCorrect = isset($_SESSION['readonly']) && isset($_SESSION['user_inc']) && + isset($_SESSION['use_http_auth']) && isset($_SESSION['single_user']) + && isset($_SESSION['mode']); +} +if ($appSettingsCorrect) { + redirectToNextAction(); +} else { + $error = translate('Invalid Application Settings'); } diff --git a/install/install_auth_handler.php b/install/install_auth_handler.php index 642a09912..cadc6cd6c 100644 --- a/install/install_auth_handler.php +++ b/install/install_auth_handler.php @@ -1,35 +1,45 @@ format('D, d M Y H:i:s O'); - $content = preg_replace('/updated via install\/index.php on .*/', 'updated via install/index.php on ' . $formattedDate, $content); + // Update the date + $date = new DateTime(); + $formattedDate = $date->format('D, d M Y H:i:s O'); + $content = preg_replace('/updated via install\/index.php on .*/', 'updated via install/index.php on ' . $formattedDate, $content); - // Write the updated content back to the file - return file_put_contents($file, $content); + // Write the updated content back to the file + return file_put_contents($file, $content); +} + +function write_password_in_new_settings($file, $password, $hint) +{ + $date = new DateTime(); + $formattedDate = $date->format('D, d M Y H:i:s O'); + $content = "\n"; + return file_put_contents($file, $content); } // Handle form submission on Auth page (both setting and checking password) @@ -43,9 +53,14 @@ function update_password_in_settings($file, $password, $hint) { $error = translate('Your passwords must match.'); } $hint = $_POST['hint']; - $ret = update_password_in_settings(__DIR__ . '/../includes/settings.php', md5($password), $hint); - if (! $ret) { - $error = 'Error writing includes/settings.php file.'; + $settingsFile = __DIR__ . '/../includes/settings.php'; + if (file_exists($settingsFile) && strlen(file_get_contents($settingsFile) > 10)) { + $ret = update_password_in_settings($settingsFile, md5($password), $hint); + } else { + $ret = write_password_in_new_settings($settingsFile, md5($password), $hint); + } + if (!$ret) { + $error = 'Error writing ' . $settingsFile . ' file.'; } else { redirectToNextAction(); } @@ -62,4 +77,3 @@ function update_password_in_settings($file, $password, $hint) { $error = translate("Invalid passphrase."); } } -?> diff --git a/install/install_dbload_handler.php b/install/install_dbload_handler.php index 9adfe11eb..7c5aa3bb9 100644 --- a/install/install_dbload_handler.php +++ b/install/install_dbload_handler.php @@ -110,8 +110,6 @@ function createDB2Database($hostname, $login, $password, $databaseName): bool return true; } - - try { switch ($_SESSION['db_type']) { case 'mysqli': diff --git a/install/install_dbsettings.php b/install/install_dbsettings.php index e0ca704f5..5523d5c2e 100644 --- a/install/install_dbsettings.php +++ b/install/install_dbsettings.php @@ -43,7 +43,7 @@ function printDbSetting($name) list($checkType, $checkValue) = explode(':', $value); $isSupported = ($checkType === 'function') ? @function_exists($checkValue) : @class_exists($checkValue); ?> - diff --git a/install/install_dbsettings_handler.php b/install/install_dbsettings_handler.php index ecc6cb0be..bcf479b93 100644 --- a/install/install_dbsettings_handler.php +++ b/install/install_dbsettings_handler.php @@ -27,6 +27,7 @@ } if (!empty($value)) { $fileContent .= "$key: $value\n"; + $_SESSION[$key] = $value; } } diff --git a/install/install_dbtables.php b/install/install_dbtables.php index 421c91bd7..f1b1a6de1 100644 --- a/install/install_dbtables.php +++ b/install/install_dbtables.php @@ -5,6 +5,7 @@ //$detectedDbVersion = "v1.1.2"; //$databaseCurrent = false; $sql = ''; + $buttonLabel = translate('Upgrade Database'); if ($databaseCurrent) { $msg = translate("Your XXX database named 'YYY' is up to date. You may go on to the next step."); $msg = str_replace('XXX', $_SESSION['db_type'], $msg); @@ -17,6 +18,7 @@ $msg = str_replace('YYY', $_SESSION['db_database'], $msg); $sqlFile = getSqlFile($_SESSION['db_type'], false); $sql = extractSqlCommandsFromFile($sqlFile); + $buttonLabel = translate('Create Database'); } else { $msg = translate("Your XXX database named 'YYY' needs upgrading from version ZZZ."); $msg = str_replace('XXX', $_SESSION['db_type'], $msg); @@ -40,7 +42,7 @@ ?> diff --git a/install/install_dbtables_handler.php b/install/install_dbtables_handler.php index 03d5d767e..b98fed423 100644 --- a/install/install_dbtables_handler.php +++ b/install/install_dbtables_handler.php @@ -39,7 +39,7 @@ try { $success = true; if (empty($error)) { - if ($emptyDb) { + if ($emptyDatabase) { executeSqlFromFile($install_filename); } else { if (empty($detectedDbVersion) || $detectedDbVersion == 'Unknown') { diff --git a/install/install_functions.php b/install/install_functions.php index 04334c20b..81977d6bf 100644 --- a/install/install_functions.php +++ b/install/install_functions.php @@ -313,12 +313,12 @@ function do_v1_9_11_updates() $base64Data = base64_encode($iconData); // Create a data URL. $dataUrl = 'data:image/png;base64,' . $base64Data; - echo 'Embedded Image
'; - echo "cat $catId done
\n"; + //echo 'Embedded Image
'; + //echo "cat $catId done
\n"; // Delete the files so we don't repeat this later - //if (!unlink($iconFile)) { - // echo "Failed to delete icon file $iconFile"; - //} + if (!unlink($iconFile)) { + echo "Failed to delete icon file $iconFile"; + } } } } @@ -487,7 +487,7 @@ function getDatabaseVersionFromSchema($silent = true) global $database_upgrade_matrix, $PROGRAM_VERSION, $settings, $show_all_errors; $dbVersion = null; $success = true; - //$silent = false; + $silent = true; // Suppress errors based on $show_all_errors. if (!$show_all_errors) @@ -514,6 +514,9 @@ function getDatabaseVersionFromSchema($silent = true) // could have worked on. $res = false; $success = false; + if (!$silent) { + echo "Failed at: $sql
"; + } } if ($res) { if (!$silent) { @@ -627,6 +630,7 @@ function executeSqlFromFile($filename) foreach ($sqlStatements as $statement) { if (!empty($statement)) { // Assuming dbi_execute() is a function that takes a SQL statement and executes it + echo "Statement: $statement
"; dbi_execute($statement); } } diff --git a/install/sql/tables-db2.sql b/install/sql/tables-db2.sql index cbefb53ab..e13f6336d 100644 --- a/install/sql/tables-db2.sql +++ b/install/sql/tables-db2.sql @@ -156,7 +156,7 @@ CREATE TABLE webcal_categories ( cat_status CHAR DEFAULT 'A', cat_icon_mime VARCHAR(32) DEFAULT NULL, cat_icon_blob BLOB DEFAULT NULL, - PRIMARY KEY (cal_id, cat_id, cat_order, cat_owner) + PRIMARY KEY (cat_id, cat_order, cat_owner) ); CREATE TABLE webcal_asst ( cal_boss VARCHAR(25) NOT NULL, diff --git a/install/sql/tables-mysql.sql b/install/sql/tables-mysql.sql index 72ed8e7e3..62e95f8e5 100644 --- a/install/sql/tables-mysql.sql +++ b/install/sql/tables-mysql.sql @@ -432,7 +432,7 @@ CREATE TABLE webcal_categories ( cat_icon_mime VARCHAR(32) DEFAULT NULL, /* category icon image blob */ cat_icon_blob LONGBLOB DEFAULT NULL, - PRIMARY KEY ( cal_id, cat_id, cat_order, cat_owner ) + PRIMARY KEY ( cat_id, cat_owner ) ); /** diff --git a/install/sql/tables-oracle.sql b/install/sql/tables-oracle.sql index 4cc134af7..5a4c30b59 100644 --- a/install/sql/tables-oracle.sql +++ b/install/sql/tables-oracle.sql @@ -159,7 +159,7 @@ CREATE TABLE webcal_categories ( cat_status CHAR DEFAULT 'A', cat_icon_mime VARCHAR(32) DEFAULT NULL, cat_icon_blob BLOB DEFAULT NULL, - PRIMARY KEY ( cal_id, cat_id, cat_order, cat_owner ) + PRIMARY KEY ( cat_id, cat_order, cat_owner ) ); CREATE TABLE webcal_asst ( cal_boss VARCHAR2(25) NOT NULL, diff --git a/install/sql/tables-postgres.sql b/install/sql/tables-postgres.sql index 58412cff5..6caa5889e 100644 --- a/install/sql/tables-postgres.sql +++ b/install/sql/tables-postgres.sql @@ -158,7 +158,7 @@ CREATE TABLE webcal_categories ( cat_status CHAR DEFAULT 'A', cat_icon_mime VARCHAR(32) DEFAULT NULL, cat_icon_blob BYTEA DEFAULT NULL, - PRIMARY KEY ( cal_id, cat_id, cat_order, cat_owner ) + PRIMARY KEY ( cat_id, cat_order, cat_owner ) ); CREATE TABLE webcal_asst ( cal_boss VARCHAR(25) NOT NULL, diff --git a/install/sql/upgrade_matrix.php b/install/sql/upgrade_matrix.php index dfa3403d8..221c9869e 100644 --- a/install/sql/upgrade_matrix.php +++ b/install/sql/upgrade_matrix.php @@ -36,7 +36,7 @@ ['INSERT INTO webcal_nonuser_cals ( cal_login, cal_admin, cal_url ) VALUES ( "zzz", "zzz", "zzz" )', 'DELETE FROM webcal_nonuser_cals WHERE cal_login = "zzz"', 'v1.1.0e-CVS', 'upgrade_v1.1.1'], - ['INSERT INTO webcal_categories ( cat_id, cat_name, cat_color ) VALUES ( "999", "zzz", "#FFFFFF" )', + ['INSERT INTO webcal_categories ( cat_id, cat_name, cat_color, cat_owner ) VALUES ( "999", "zzz", "#FFFFFF", "nobody" )', 'DELETE FROM webcal_categories WHERE cat_id = 999', 'v1.1.1', 'upgrade_v1.1.2'], // Upgrade from 1.1.2 -> 1.3.0 diff --git a/view_entry.php b/view_entry.php index 9df2d6250..c098ac61e 100644 --- a/view_entry.php +++ b/view_entry.php @@ -893,9 +893,9 @@ else { echo ' ' . $num_comment . ' ' . translate('comments') . ' - ' - . '
' . $comment_text . '
'; // We could put the following JS in includes/js/view_entry.php, diff --git a/views_edit.php b/views_edit.php index fd0250918..b8bb07eb4 100644 --- a/views_edit.php +++ b/views_edit.php @@ -158,7 +158,7 @@ -