diff --git a/README.md b/README.md index d8f1ab45b..1c371579e 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,12 @@ install script that the web service process has write permissions to. ### Option 2: Environment Variables Instead of using the `includes/settings.php` file for your settings, you can use environment -variables instead. +variables instead. This is primarily targeted towards those running WebCalendar in containers (docker, AWS Fargate, etc) -where it's easier to pass in environment settings than to write to a config file on a container. +where it's easier to pass in environment settings than to write to a config file on a container. You can do this with the docker-compose file if you are using docker. If you want to do this with a standard Web Server, -you can set the evironment variables within your web server's configuration. +you can set the evironment variables within your web server's configuration. Depending on your web server, there may be more than one way to do this. You could do this in your `php.ini` file, but those env vars would be available to all PHP apps on the server. A better solution would be to setup a `.htaccess` file in your @@ -93,19 +93,6 @@ and MariaDb running that is setup with the `docker-compose` command. - Start the containers: `docker-compose -f docker/docker-compose-php8.yml up` -- In order to grant the proper permissions inside of MariaDb, you - will need to run a few MySQL commands. First shell into the mariadb - container: `docker-compose -f docker/docker-compose-php8.yml exec db /bin/sh` -- Start up the db client: `/bin/mariadb -p` (the password will be - "Webcalendar.1" as specified in the `docker-compose-php8.yml' file. You - can change it to make your dev environment more secure (before you - build the containers in step above). -- Run the following db commands: - ``` - GRANT ALL PRIVILEGES ON *.* TO webcalendar_php8@localhost IDENTIFIED BY 'Webcalendar.1' WITH GRANT OPTION; - FLUSH PRIVILEGES; - QUIT - ``` - Start up your web browser and go to: [http://localhost:8080/](http://localhost:8080/). - Follow the guided web-based setup and choose "mysqli" as the database @@ -125,19 +112,6 @@ files in the container. `docker-compose -f docker/docker-compose-php8-dev.yml build` - Start the containers with `docker-compose -f docker/docker-compose-php8-dev.yml up` -- In order to grant the proper permissions inside of MariaDb, you - will need to run a few MySQL commands. First shell into the mariadb - container: `docker-compose -f docker/docker-compose-php8-dev.yml exec db /bin/sh` -- Start up the db client: `/bin/mariadb -p` (the password will be - "Webcalendar.1" as specified in the `docker-compose-php8-dev.yml' file. You - can change it to make your dev environment more secure (before you - build the containers in step above). -- Run the following db commands: - ``` - GRANT ALL PRIVILEGES ON *.* TO webcalendar_php8@localhost IDENTIFIED BY 'Webcalendar.1' WITH GRANT OPTION; - FLUSH PRIVILEGES; - QUIT - ``` - Start up your web browser and go to: [http://localhost:8080/](http://localhost:8080/). - Follow the guided web-based setup and choose "mysqli" as the database diff --git a/category_handler.php b/category_handler.php index 4d030ad29..e296f3703 100644 --- a/category_handler.php +++ b/category_handler.php @@ -71,7 +71,7 @@ function updateIconBlob($catId, $iconData, $iconMimeType) { if (!dbi_execute( 'DELETE FROM webcal_entry_categories WHERE cat_id = ? AND ( cat_owner = ?' - . ($is_admin ? ' OR cat_owner = '' )' : ' )'), + . ($is_admin ? ' OR cat_owner = \'\'' : ' )'), [$id, $login] )) { $error = db_error(); diff --git a/docker/docker-compose-php8-dev.yml b/docker/docker-compose-php8-dev.yml index 9586cf590..50a679834 100644 --- a/docker/docker-compose-php8-dev.yml +++ b/docker/docker-compose-php8-dev.yml @@ -1,21 +1,7 @@ -# 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/docker-compose-php8-dev.yml exec db-mariadb /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 -# +# Run docker compose from the top-level WebCalendar directory and not from this "docker" subdirectory. # If you need shell access on the webserver container running WebCalendar, you can use # the following command: -# docker-compose -f docker/docker-compose-php8-dev.yml exec webcalendar-php8-mariadb /bin/sh +# docker compose -f docker/docker-compose-php8-dev.yml exec webcalendar-php8-mariadb /bin/sh version: '3.1' @@ -27,6 +13,17 @@ services: volumes: - mysql-data:/var/lib/mysql - /etc/localtime:/etc/localtime:ro + # install sql at start + # To test the installer's built-in installer, comment this out +# - type: bind +# source: ../install/sql/tables-mysql.sql +# target: /docker-entrypoint-initdb.d/tables-mysql.sql + # Set mariadb access policy + # NOTE: The specified SQL needs to match the password specified + # in the ENV vars listed below. + - type: bind + source: ../install/sql/permissions-mysql.sql + target: /docker-entrypoint-initdb.d/permissions-mysql.sql environment: - MYSQL_ROOT_PASSWORD=Webcalendar.1 - MYSQL_PASSWORD=Webcalendar.1 @@ -84,7 +81,7 @@ services: - WEBCALENDAR_MODE=dev # To access the pgsql command line: - # docker-compose -f docker/docker-compose-php8-dev.yml exec db-pgsql /bin/bash + # docker compose -f docker/docker-compose-php8-dev.yml exec db-pgsql /bin/bash # Before the webcalendar db is created: # psql -h localhost -p 5432 -U webcalendar -W -d postgres db-pgsql: diff --git a/docker/docker-compose-php8.yml b/docker/docker-compose-php8.yml index dcb92487d..6919ecf4c 100644 --- a/docker/docker-compose-php8.yml +++ b/docker/docker-compose-php8.yml @@ -1,21 +1,7 @@ -# 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/docker-compose-php8.yml 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 -# +# Run docker compose from the top-level WebCalendar directory and not from this "docker" subdirectory. # If you need shell access on the webserver container running WebCalendar, you can use # the following command: -# docker-compose -f docker/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' @@ -27,6 +13,17 @@ services: volumes: - mysql-data:/var/lib/mysql - /etc/localtime:/etc/localtime:ro + # install sql at start + # To test the installer's built-in installer, comment this out + - type: bind + source: ../install/sql/tables-mysql.sql + target: /docker-entrypoint-initdb.d/tables-mysql.sql + # Set mariadb access policy + # NOTE: The specified SQL needs to match the password specified + # in the ENV vars listed below. + - type: bind + source: ../install/sql/permissions-mysql.sql + target: /docker-entrypoint-initdb.d/permissions-mysql.sql environment: - MYSQL_ROOT_PASSWORD=Webcalendar.1 - MYSQL_PASSWORD=Webcalendar.1 diff --git a/docs/WebCalendar-UserManual.html b/docs/WebCalendar-UserManual.html index ea2c6c0d5..3cb38f8e9 100644 --- a/docs/WebCalendar-UserManual.html +++ b/docs/WebCalendar-UserManual.html @@ -7,7 +7,7 @@
WebCalendar Version: 1.9.9
+WebCalendar Version: 1.9.12
Events may be associated with one or more categories, but it is not required. Categories can be user-level or global. Each user maintains his/her own list of user-level categories, while the system administrator maintains the list of global categories.
When creating or editing event, you may specify the categories for the event. If the category you select isn't a global category, and you select participants other than yourself for that event, other users will see "None" as the category. If you selected a global category, all users will be able to see the same category.
When viewing the calendar (month, week or day), a selection box is displayed near the top of the page that allows you to filter events based on a category. When you select a category from this menu, only events associated with that category will appear on your calendar.
-If enabled, icons can also be uploaded and assigned to categories to be displayed before the event name. You will also be able to choose an icon from existing icons that have already been uploaded. This requires that a folder named icons exist in the WebCalendar directory.
+If enabled, icons can also be uploaded and assigned to categories to be displayed before the event name. You will also be able to choose an icon from existing icons that have already been uploaded. This requires that a folder named icons exist in the WebCalendar directory.
↑ top' . nl2br ( $trace ) . ''; + . '
' . nl2br ( $trace ) . ''; if ( function_exists ( 'die_miserable_death' ) ) die_miserable_death ( $msg ); else { diff --git a/includes/classes/WebCalendar.php b/includes/classes/WebCalendar.php index 81e08dd6b..6514ae2c1 100644 --- a/includes/classes/WebCalendar.php +++ b/includes/classes/WebCalendar.php @@ -91,9 +91,9 @@ class WebCalendar { /** * WebCalendar constructor. * - * @param string $path Full path of file being viewed. + * @param string $path full path of file being viewed * - * @return WebCalendar New WebCalendar object. + * @return WebCalendar new WebCalendar object * * @access public */ @@ -126,8 +126,7 @@ function _initInitFirstPhase() { if ( empty ( $HTTP_POST_VARS ) ) $HTTP_POST_VARS = $_POST; - if ( ! empty ( $HTTP_GET_VARS ) && empty ( $HTTP_GET_VARS['user'] ) && ! - empty ( $HTTP_POST_VARS ) && empty ( $HTTP_POST_VARS['user'] ) && + if ( ! empty ( $HTTP_GET_VARS ) && empty ( $HTTP_GET_VARS['user'] ) && ! empty ( $HTTP_POST_VARS ) && empty ( $HTTP_POST_VARS['user'] ) && isset ( $GLOBALS['user'] ) ) unset ( $GLOBALS['user'] ); @@ -234,10 +233,10 @@ function _initInitSecondPhase() { if ( $PUBLIC_ACCESS_OTHERS != 'Y' ) $user = ''; // Security precaution. } - if (!$is_admin && !$is_assistant && !$is_nonuser_admin) { + if ( ! $is_admin && ! $is_assistant && ! $is_nonuser_admin ) { if ($is_nonuser) $can_add = false; - else if (!empty($user) && $user != $login && $user != '__public__') + elseif ( ! empty ( $user ) && $user !== $login && $user !== '__public__' ) $can_add = false; } @@ -258,7 +257,7 @@ function _initInitSecondPhase() { if ( ! empty ( $user ) ) { $u_url = 'user=' . $user . '&'; - if (!user_load_variables ( $user, 'user_' )) + if ( ! user_load_variables ( $user, 'user_' ) ) nonuser_load_variables($user, 'user_'); if ( $user == '__public__' ) $user_fullname = translate ( $PUBLIC_ACCESS_FULLNAME ); @@ -582,7 +581,7 @@ function _initValidate() { if ( empty($cooie_check[0]) || empty($cooie_check[1])) $session_not_found = true; } - if (! $session_not_found) { + if ( ! $session_not_found ) { $login_pw = explode('|', decode_string($encoded_login)); $login = $login_pw[0]; $cryptpw = $login_pw[1]; @@ -598,9 +597,9 @@ function _initValidate() { // The following deletes the bad cookie. // So, the user just needs to reload. sendCookie ( 'webcalendar_session', '', 0 ); - die_miserable_death ( 'Illegal characters in login ' + die_miserable_death ( 'Illegal characters in login ' . htmlentities ( $login ) - . '. Press browser reload to clear bad cookie.' ); + . '. Press browser reload to clear bad cookie.' ); } // Make sure we are connected to the database for password check. @@ -684,8 +683,8 @@ function _initConnect() { // make sure that the login selected is a valid login. if ( $single_user == 'Y' ) { if ( empty ( $single_user_login ) ) - die_miserable_death ( 'You have not defined single_user_login ' - . 'in includes/settings.php.' ); + die_miserable_death ( 'You have not defined single_user_login ' + . 'in includes/settings.php.' ); $res = dbi_execute ( 'SELECT COUNT( * ) FROM webcal_user WHERE cal_login = ?', [$single_user_login] ); @@ -699,8 +698,8 @@ function _initConnect() { if ( ! dbi_execute ( 'INSERT INTO webcal_user ( cal_login, cal_passwd, cal_is_admin ) VALUES ( ?, ?, ? )', [$single_user_login, md5 ( $single_user_login ), 'Y'] ) ) - die_miserable_death ( 'User ' . $single_user_login - . ' does not exist in webcal_user table and we were ' + die_miserable_death ( 'User ' . $single_user_login + . ' does not exist in webcal_user table and we were ' . 'not able to add it for you:
' . dbi_error() . '' ); @@ -942,7 +941,7 @@ function _initTranslate() { if (extension_loaded('mbstring')) { $mb_lang = strtok($lang, '-'); // Check the language against the map, default to 'neutral' if not found - $mapped_lang = isset($this->mb_language_map[$mb_lang]) ? $this->mb_language_map[$mb_lang] : 'neutral'; + $mapped_lang = $this->mb_language_map[$mb_lang] ?? 'neutral'; if (@mb_language($mapped_lang) && mb_internal_encoding(translate('charset'))) { $enable_mbstring = true; } else { @@ -958,7 +957,7 @@ function _initTranslate() { /** * Gets the initialization phases for the page being viewed. * - * @return array Array of initialization phases. + * @return array of initialization phases * * @access private */ @@ -976,9 +975,9 @@ function _getPhases() { /** * Gets the initialization steps for the current page and phase. * - * @param int $phase Initialization phase number + * @param int $phase Initialization phase number * - * @return array Array of initialization steps. + * @return array of initialization steps * * @access private */ @@ -991,7 +990,7 @@ function _getSteps ( $phase ) { /** * Performs initialization steps. * - * @param int $phase Which step of initialization should we perform? + * @param int $phase Which step of initialization should we perform? * * @access private */ @@ -1006,7 +1005,7 @@ function _doInit ( $phase ) { /** * Begins initialization of WebCalendar. * - * @param string $path Full path of page being viewed + * @param string $path Full path of page being viewed * * @access public */ @@ -1017,7 +1016,7 @@ function initializeFirstPhase() { /** * Continues initialization of WebCalendar. * - * @param string $path Full path of page being viewed + * @param string $path Full path of page being viewed * * @access public */ @@ -1034,13 +1033,13 @@ function setLanguage() { $this->_initTranslate(); } - /** - * Construct an absolute path. - * - * @param string $path The path relative to the WebCalendar install directory - * - * @return string The absolute path - */ + /** + * Construct an absolute path. + * + * @param string $path relative to the WebCalendar install directory + * + * @return string The absolute path + */ function absolutePath ( $path ) { return $this->_directory . $path; } diff --git a/includes/css/docs.css b/includes/css/docs.css index a8719a827..de8c24281 100644 --- a/includes/css/docs.css +++ b/includes/css/docs.css @@ -126,7 +126,7 @@ ul { } .tt { - font: 0.85rem monospace; + font: 0.85rem 'Lucida Console', monospace; } .vtop { diff --git a/includes/css/styles.css b/includes/css/styles.css index c76900e38..e8de28f79 100644 --- a/includes/css/styles.css +++ b/includes/css/styles.css @@ -305,6 +305,11 @@ a#programname { margin-top:.4375rem; margin-right:.1875rem; } + +.tt { + font-family: 'Lucida Console', monospace"; +} + #activitylog .next, #activitylog .prev { border:0; diff --git a/includes/js/edit_entry.php b/includes/js/edit_entry.php index 2aa901886..adea98205 100644 --- a/includes/js/edit_entry.php +++ b/includes/js/edit_entry.php @@ -2,8 +2,7 @@ defined ( '_ISVALID' ) or die ( 'You cannot access this file directly!' ); global $GROUPS_ENABLED,$WORK_DAY_START_HOUR,$WORK_DAY_END_HOUR; -$user = $arinc[3]; - +load_user_categories(); ?> var bydayAr = bymonthdayAr = bysetposAr = []; @@ -602,7 +601,6 @@ function editCats ( evt ) { var selected_ids = cat_ids.split ( ',' ); $cat ) { if ( $catid == 0 || $catid == -1 ) continue; // Ignore these special cases (0=All, -1=None) @@ -632,6 +630,7 @@ function catOkHandler () { var catIds = '', catNames = ''; $cat ) { + echo ' // Processing catid=' . $catid . "\n"; if ( $catid == 0 || $catid == -1 ) continue; // Ignore these special cases (0=All, -1=None) ?> @@ -665,7 +664,7 @@ function catOkHandler () { cats.val(catNames); var catId = $('#cat_id'); catId.val(catIds); - console.log("cat_id.value = " + catId.value); + //console.log("cat_id.value = " + catId.value); $('#catModal').modal('hide'); return true; } diff --git a/install/headless.php b/install/headless.php index e5a848b59..283e1a3d1 100644 --- a/install/headless.php +++ b/install/headless.php @@ -27,6 +27,7 @@ // We need the $_SESSION superglobal to pass data to and from some of the update // functions. Sessions are basically useless in CLI mode, but technically the // session functions *do* work. +session_name(getSessionName()); session_start(); // Load the settings.php file or get settings from env vars. diff --git a/install/sql/permissions-mysql.sql b/install/sql/permissions-mysql.sql new file mode 100644 index 000000000..d37a852dd --- /dev/null +++ b/install/sql/permissions-mysql.sql @@ -0,0 +1,2 @@ +GRANT ALL PRIVILEGES ON *.* TO webcalendar_php8@localhost IDENTIFIED BY 'Webcalendar.1' WITH GRANT OPTION; +FLUSH PRIVILEGES; diff --git a/js_cacher.php b/js_cacher.php index 6aff9a4d9..32f05593f 100644 --- a/js_cacher.php +++ b/js_cacher.php @@ -46,6 +46,7 @@ send_no_cache_header(); load_global_settings(); +session_name(getSessionName()); @session_start(); $login = ( empty( $_SESSION['webcal_login'] ) diff --git a/purge.php b/purge.php index c22dbb990..d1cacc9af 100644 --- a/purge.php +++ b/purge.php @@ -112,8 +112,8 @@ ' - . "$sqlLog\n"; + echo '