diff --git a/assets/adminer/plugins/001-tables-filter.php b/assets/adminer/plugins/001-tables-filter.php new file mode 100644 index 00000000000..c2265a32e97 --- /dev/null +++ b/assets/adminer/plugins/001-tables-filter.php @@ -0,0 +1,4 @@ +adminer = $adminer; + } + + private function _testJson($value) { + if ((substr($value, 0, 1) == '{' || substr($value, 0, 1) == '[') && ($json = json_decode($value, true))) { + return $json; + } + return $value; + } + + function editInput($table, $field, $attrs, $value) { + $json = $this->_testJson($value); + if ($json !== $value) { + $jsonText = json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + return <<$jsonText +HTML; + } + return ''; + } + + function processInput($field, $value, $function = '') { + if ($function === '') { + $json = $this->_testJson($value); + if ($json !== $value) { + $value = json_encode($json); + } + } + return $this->adminer->_callParent('processInput', array($field, $value, $function)); + } +} diff --git a/assets/adminer/plugins/readable-dates.php b/assets/adminer/plugins/readable-dates.php new file mode 100644 index 00000000000..d9ca75ac16d --- /dev/null +++ b/assets/adminer/plugins/readable-dates.php @@ -0,0 +1,49 @@ +prepend = <<'; + tds[i].innerHTML = tds[i].newDate; + tds[i].dateIsNew = true; + + tds[i].addEventListener('click', function(event) { + this.innerHTML = (this.dateIsNew ? this.oldDate : this.newDate); + this.dateIsNew = !this.dateIsNew; + }); + } + } +}); + +EOT; + } + + function head() { + echo script($this->prepend); + } +} diff --git a/assets/adminer/plugins/table-header-scroll.php b/assets/adminer/plugins/table-header-scroll.php new file mode 100644 index 00000000000..69eace5c3ac --- /dev/null +++ b/assets/adminer/plugins/table-header-scroll.php @@ -0,0 +1,75 @@ +. + * + * LICENSE: + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +class AdminerTableHeaderScroll +{ + public function head() + { + ?> + +> +function tableHeaderPositionUpdate(){ + // If your theme has a fixed position header, change these for compatibility + var offset = -1; + var zindex = 10000; + + // Find tables in the content + var tables = document.getElementById('content').getElementsByTagName('table'); + for (var i = 0; i < tables.length; i++) { + var table = tables[i]; + + // Find the table header + var tableHeader = table.getElementsByTagName('thead'); + if (tableHeader.length) { + tableHeader = tableHeader[0]; + } else { + continue; + } + + // Calculate the distance from the top and bottom + var tableTop = table.getBoundingClientRect().top - offset; + var tableBottom = table.getBoundingClientRect().bottom - offset - tableHeader.offsetHeight; + + // Set the relative position based on the distance + if (tableTop < 0 && tableBottom > 0){ + tableHeader.style['z-index'] = zindex; + tableHeader.style.position = 'relative'; + + if (typeof tableHeader.style.transform === 'undefined') { + tableHeader.style.top = -tableTop + 'px'; + } else { + tableHeader.style.transform = 'translateY(' + -tableTop + 'px)'; + } + } else { + tableHeader.style.position = 'static'; + tableHeader.style.transform = 'none'; + } + } +} + +if (window.addEventListener) { + window.addEventListener('scroll', tableHeaderPositionUpdate); +} + + + --character-set-server=utf8mb4 --collation-server=utf8mb4_bin diff --git a/k1many.sh b/k1many.sh new file mode 100755 index 00000000000..1ff1a909672 --- /dev/null +++ b/k1many.sh @@ -0,0 +1,519 @@ +#!/usr/bin/env bash + +# Define colors for various output messages. +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +help_messages () { + echo + echo + echo -e "${GREEN}Usage:${NC}" + echo " Script that can start multiple Moodle instances." + echo " ./k1many.sh option folder1 [folder2] [folder3] [--debug]" + echo + echo -e "${GREEN}Options:${NC}" + echo " --build Create and start the containers for the passed folders." + echo " --destroy Stop and remove all running containers. All data is lost." + echo " --help Display this message." + echo " --restart Restart all running containers." + echo " --start Start all stopped containers. Needs folder(s) path as well." + echo " --stop Stop all running containers." + echo " --debug Enable verbose debug output for troubleshooting." + echo + echo -e "${GREEN}Folders:${NC}" + echo " folder1 Folder pointing to first Moodle instance (Mandatory)." + echo " [folder2] Folder pointing to second Moodle instance (optional)." + echo " [folder3] Folder pointing to third Moodle instance (optional)." + echo + echo -e "${GREEN}Examples:${NC}" + echo " Start three Moodle instances in /home/username/projects/[folder]." + echo " In this example, the first Moodle instance will be in /home/username/projects/M405:" + echo " ./k1many.sh --build M405 M401 M501 --debug" + echo " Start all Moodle instances passed in parameters:" + echo " ./k1many.sh --start M405 M401 M501" + echo " Stop all running containers:" + echo " ./k1many.sh --stop" + echo " Stop and destroy all containers and data:" + echo " ./k1many.sh --destroy" + echo + echo +} + +# Decorator to output information message to the user. +# Takes 1 param, the message to be displayed. +info_message() { + echo + echo -e "${CYAN}$1${NC}" + echo +} + +# Decorator to output error message to the user. +# Takes 1 param, the message to be displayed. +error_message() { + echo + echo -e "${RED}$1${NC}" + echo +} + +# Debug message, only output if DEBUG is true. +# Takes 1 param, the message to be displayed. +debug_message() { + if [ "$DEBUG" = true ]; then + echo -e "${CYAN}[DEBUG] $1${NC}" + fi +} + +# Determines Moodle version-specific settings (PHP version, document root, CLI path, DB version). +# Args: +# $1: Full path to the Moodle folder. +# Sets global variables: +# MOODLE_DOCKER_PHP_VERSION: PHP version for the Docker image (e.g., 8.3). +# MOODLE_DOCKER_DB_VERSION: MariaDB version (e.g., 10.6). +# DOCUMENT_ROOT: Apache DocumentRoot (e.g., /var/www/html/public for Moodle 5.1). +# CLI_PATH: Path to CLI scripts (e.g., admin/cli/). +# PLUGIN_PREFIX: Prefix for plugin paths (e.g., /public for Moodle 5.1). +configure_moodle_version() { + local folder=$1 + local version_file + local branch + local grep_output + # Check for version.php in root or public folder + if [ -f "${folder}/version.php" ]; then + version_file="${folder}/version.php" + elif [ -f "${folder}/public/version.php" ]; then + version_file="${folder}/public/version.php" + else + error_message "version.php not found in ${folder} or ${folder}/public" + exit 1 + fi + debug_message "Checking version.php at ${version_file}" + # Extract $branch from version.php (matches $branch = '[number]';) + grep_output=$(grep "\$branch\s*=\s*['\"][0-9]\+['\"];" "${version_file}" || true) + debug_message "grep output: '${grep_output}'" + branch=$(echo "${grep_output}" | sed -E "s/.*['\"]([0-9]+)['\"];.*/\1/" || true) + debug_message "Extracted branch: '${branch}'" + if [ -z "$branch" ]; then + error_message "Failed to extract branch from ${version_file}" + exit 1 + fi + # Default settings (for older Moodle versions). + MOODLE_DOCKER_PHP_VERSION=8.1 + MOODLE_DOCKER_DB_VERSION=10.2 + DOCUMENT_ROOT="/var/www/html" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="" + # Version-specific settings. + case "$branch" in + "501") + # Moodle 5.1: Requires PHP 8.3, MariaDB 10.11+, DocumentRoot /var/www/html/public. + MOODLE_DOCKER_PHP_VERSION=8.3 + MOODLE_DOCKER_DB_VERSION=10.11 + DOCUMENT_ROOT="/var/www/html/public" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="/public" + info_message "Detected Moodle 5.1 (branch ${branch}): Using PHP 8.3, MariaDB 10.11, DocumentRoot ${DOCUMENT_ROOT}." + ;; + "405") + # Moodle 4.5: Requires PHP 8.3, MariaDB 10.6+, traditional structure. + MOODLE_DOCKER_PHP_VERSION=8.3 + MOODLE_DOCKER_DB_VERSION=10.6 + DOCUMENT_ROOT="/var/www/html" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="" + info_message "Detected Moodle 4.5 (branch ${branch}): Using PHP 8.3, MariaDB 10.6." + ;; + "401") + # Moodle 4.1: Requires PHP 8.1, MariaDB 10.4+, traditional structure. + MOODLE_DOCKER_PHP_VERSION=8.1 + MOODLE_DOCKER_DB_VERSION=10.4 + DOCUMENT_ROOT="/var/www/html" + CLI_PATH="admin/cli" + PLUGIN_PREFIX="" + info_message "Detected Moodle 4.1 (branch ${branch}): Using PHP 8.1, MariaDB 10.4." + ;; + *) + # Default to PHP 8.1 and MariaDB 10.2 for unrecognized or older branches + info_message "Unrecognized Moodle branch '${branch}' in ${version_file}. Using default PHP 8.1, MariaDB 10.2." + ;; + esac + # Export variables for use in the script. + export MOODLE_DOCKER_PHP_VERSION + export MOODLE_DOCKER_DB_VERSION + export DOCUMENT_ROOT + export CLI_PATH + export PLUGIN_PREFIX +} + +start_server() { + + # Start the server. + bin/moodle-docker-compose up -d + info_message "Started Docker containers for ${COMPOSE_PROJECT_NAME}" + + # Sleep for 6 seconds to allow database to come up. + # sleep 6 + + # Just in case there is still some latency. + bin/moodle-docker-wait-for-db + info_message "Database is ready for ${COMPOSE_PROJECT_NAME}" +} + +start_instances() { + + local projectname=$1 + + # Configure Moodle version-specific settings. + configure_moodle_version "${fullfolderpath}" + + # Start the container and wait for DB. + start_server + info_message "${projectname} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" +} + +build_instances() { + + local projectname=$1 + local folder=$2 + local xdebug_port=${xDebugPort[$iterator]} + + # Configure Moodle version-specific settings. + configure_moodle_version "${folder}" + + # Install tool_excimer plugin on host. + local plugin_dir="${folder}${PLUGIN_PREFIX}/admin/tool" + mkdir -p "${plugin_dir}" + + # Only clone if the directory doesn't exist. + if [ ! -d "${plugin_dir}/excimer" ]; then + git clone https://github.com/catalyst/moodle-tool_excimer.git "${plugin_dir}/excimer" || { + info_message "Warning: Failed to clone tool_excimer plugin for ${projectname} (directory may already exist)" + } + else + info_message "tool_excimer plugin already exists at ${plugin_dir}/excimer for ${projectname}, skipping clone" + fi + info_message "Ensured tool_excimer plugin for ${projectname} at ${plugin_dir}/excimer" + debug_message "Using port ${MOODLE_DOCKER_WEB_PORT} for ${projectname}" + + # Copy the config.php file to the Moodle folder. + cp config.docker-template.php "${folder}/config.php" + debug_message "config.php will dynamically set wwwroot to http://localhost:${MOODLE_DOCKER_WEB_PORT} at runtime via env vars" + + # Add wwwrootcheck = false to prevent redirect loops. + echo "\$CFG->wwwrootcheck = false;" >> "${folder}/config.php" + info_message "Added \$CFG->wwwrootcheck = false to ${folder}/config.php to prevent redirect loops" + + # Update XDebug configuration. + local xdebug_config_file="assets/php/docker-php-ext-xdebug.ini" + cp "${xdebug_config_file}" "${xdebug_config_file}.bak" || { + error_message "Failed to backup ${xdebug_config_file}" + exit 1 + } + cat > "${xdebug_config_file}" <' >> /etc/apache2/sites-available/000-default.conf && + echo ' Options Indexes FollowSymLinks' >> /etc/apache2/sites-available/000-default.conf && + echo ' AllowOverride All' >> /etc/apache2/sites-available/000-default.conf && + echo ' Require all granted' >> /etc/apache2/sites-available/000-default.conf && + echo '' >> /etc/apache2/sites-available/000-default.conf && + a2enmod rewrite && + apache2ctl configtest + " || { + error_message "Apache config test failed for ${projectname}" + exit 1 + } + bin/moodle-docker-compose restart webserver + info_message "Restarted webserver after updating DocumentRoot to ${DOCUMENT_ROOT} for ${projectname} and enabled mod_rewrite" + fi + + # Debug checks (optional). + if [ "$DEBUG" = true ]; then + debug_message "Verifying Apache DocumentRoot for ${projectname}:" + bin/moodle-docker-compose exec webserver grep "DocumentRoot" /etc/apache2/sites-available/000-default.conf || echo "DocumentRoot not found" + debug_message "Verifying PHP version for ${projectname}:" + bin/moodle-docker-compose exec webserver php -v | grep "PHP ${MOODLE_DOCKER_PHP_VERSION}" || echo "PHP version check failed" + debug_message "Verifying Apache modules for ${projectname}:" + bin/moodle-docker-compose exec webserver apache2ctl -M | grep php || echo "PHP module not found" + debug_message "Verifying key files for ${projectname} in container:" + bin/moodle-docker-compose exec webserver ls -l /var/www/html/index.php || echo "Root index.php not found" + bin/moodle-docker-compose exec webserver ls -l /var/www/html/public/index.php || echo "Public index.php not found" + bin/moodle-docker-compose exec webserver ls -l /var/www/html/public/login/index.php || echo "Public login/index.php not found" + fi + + # Install Excimer PHP extension. + bin/moodle-docker-compose exec webserver bash -c "pecl channel-update pecl.php.net && pecl install excimer && docker-php-ext-enable excimer" || { + error_message "Failed to install Excimer for ${projectname}" + exit 1 + } + info_message "Installed and enabled Excimer PHP extension for ${projectname}" + + # Install Moodle. + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/install_database.php --agree-license --fullname="${projectname}" --shortname="${projectname}" --summary="${projectname}" --adminpass="test" --adminemail="admin@example.com" || { + error_message "Failed to install Moodle for ${projectname}" + exit 1 + } + + # Upgrade Moodle to register the tool_excimer plugin. + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/upgrade.php --non-interactive || { + error_message "Failed to upgrade Moodle for ${projectname}" + exit 1 + } + info_message "Ran Moodle upgrade for ${projectname} to register tool_excimer plugin" + + # Enable the tool_excimer plugin. + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/cfg.php --component=tool_excimer --name=enable --set=1 || { + error_message "Failed to enable tool_excimer plugin for ${projectname}" + exit 1 + } + info_message "Enabled tool_excimer plugin for ${projectname}" + + # Install and enable XDebug extension. + bin/moodle-docker-compose exec webserver bash -c "pecl uninstall xdebug || true && pecl install xdebug && docker-php-ext-enable xdebug" || { + error_message "Failed to install XDebug for ${projectname}" + exit 1 + } + bin/moodle-docker-compose restart webserver + info_message "Installed and enabled XDebug for ${projectname}" + + # Verify XDebug is loaded. + bin/moodle-docker-compose exec webserver php -i | grep -q xdebug && info_message "XDebug is loaded for ${projectname}" || { + error_message "XDebug failed to load for ${projectname}" + exit 1 + } + if [ "$DEBUG" = true ]; then + debug_message "XDebug configuration for ${projectname}:" + bin/moodle-docker-compose exec webserver php -i | grep -E 'xdebug\.(mode|client_host|client_port|log|log_level|idekey|discover_client_host)' + fi + + # Set Moodle configurations. + local configs=( + "sessioncookie=${projectname}" + "coursebinenable=0" + "backup_general_users=0 component=backup" + "updateautocheck=0" + "updatenotifybuilds=0" + "allowguestmymoodle=0" + "forcelogin=1" + "forceloginforprofiles=1" + "country=CA" + "defaultcity=Montreal" + "timezone=America/Toronto" + "guestloginbutton=0" + "enableanalytics=0" + "enablestats=0" + "categorybinenable=0" + "allowsearchengines=2" + ) + for config in "${configs[@]}"; do + bin/moodle-docker-compose exec webserver php ${CLI_PATH}/cfg.php --name="${config%%=*}" --set="${config#*=}" || { + error_message "Failed to set config ${config%%=*} for ${projectname}" + exit 1 + } + done + info_message "${projectname} is available at http://localhost:${MOODLE_DOCKER_WEB_PORT}" +} + +reset_config_files() { + rm -f local.yml + git checkout assets/php/docker-php-ext-xdebug.ini || { + error_message "Failed to reset assets/php/docker-php-ext-xdebug.ini" + exit 1 + } + info_message "Reset configuration files" +} + +exists_in_list() { + LIST=$1 + DELIMITER=$2 + VALUE=$3 + LIST_WHITESPACES=$(echo "$LIST" | tr "$DELIMITER" " ") + for x in $LIST_WHITESPACES; do + if [ "$x" = "$VALUE" ]; then + return 1 + fi + done + return 0 +} + +validate_folder_path() { + if [ ! -d "${1}" ]; then + error_message "${1} is not a valid folder." + help_messages + exit 1 + fi +} + +################### +### Validations ### +if [ $# -eq 0 ]; then + error_message "No arguments supplied. See help message below." + help_messages + exit 1 +fi + +# Check for debug flag. +DEBUG=false +if [[ " $@ " =~ " --debug " ]]; then + DEBUG=true + debug_message "Debug mode enabled" +fi + +# Validate number of arguments (1-4, or 5 with --debug). +if [ $# -lt 1 ] || [ $# -gt 5 ]; then + error_message "Invalid number of arguments passed in. Must be between 1 and 4 arguments (or 5 with --debug)." + help_messages + exit 1 +fi + +# Validate the switch. +list_of_options="--build --destroy --help --restart --stop --start --debug" +SWITCH=$1 +if exists_in_list "$list_of_options" " " "$SWITCH"; then + error_message "Invalid option $SWITCH." + help_messages + exit 1 +fi + +# Display help message if the --help switch is present. +if [ "$SWITCH" = "--help" ]; then + help_messages + exit 0 +fi + +######################## +### Global variables ### +# MOODLE_DOCKER_DB - database used by Moodle - default maria db. +# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located. +# MOODLE_DOCKER_PORT - port (default 8000). +# MOODLE_DOCKER_PHP_VERSION - php version used in Moodle - default 8.1. +# COMPOSE_PROJECT_NAME - Docker project name - used to identify sites. + +# We always use Maria DB for all our Moodle. +export MOODLE_DOCKER_DB=mariadb +cwd=$(dirname "$PWD") +moodleDockerPort=(8000 1234 5678) +xDebugPort=(9003 9004 9005) + +# Use the multiple instances local.yml file. +cp local.yml_many local.yml || { + error_message "Failed to copy local.yml_many to local.yml" + exit 1 +} +info_message "Copied local.yml_many to local.yml" + +################################################ +### Process switches that don't need options ### +case $SWITCH in + "--destroy") + if ! docker ps | grep -q 'moodlehq'; then + info_message "No containers running. Nothing to shutdown." + exit 0 + fi + docker stop $(docker ps -a -q) || { + error_message "Failed to stop containers" + exit 1 + } + docker rm $(docker ps -a -q) || { + error_message "Failed to remove containers" + exit 1 + } + reset_config_files + info_message "All containers shut down and removed." + exit 0 + ;; + "--restart") + if ! docker ps | grep -q 'moodlehq'; then + info_message "No containers running. Nothing to restart." + exit 0 + fi + docker restart $(docker ps -q) || { + error_message "Failed to restart containers" + exit 1 + } + info_message "All sites restarted." + exit 0 + ;; + "--stop") + if ! docker ps | grep -q 'moodlehq'; then + info_message "No containers running. Nothing to stop." + exit 0 + fi + docker stop $(docker ps -q) || { + error_message "Failed to stop containers" + exit 1 + } + info_message "All sites stopped." + exit 0 + ;; +esac + +############################################# +### Process switches that require options ### + +# Ignore first parm passed to the script. +# Skip the --switch to cycle the folders in argument. +shift + +iterator=0 +for i in "$@"; do + if [ "$i" = "--debug" ]; then + continue + fi + argfolder="$i" + + # Full system path of the Moodle instance. + validate_folder_path "${cwd}/${argfolder}" + fullfolderpath="${cwd}/${argfolder}" + export MOODLE_DOCKER_WWWROOT=${fullfolderpath} + + # Used to name the project according to the folder name + # which makes it easier to recognize who is who in Docker. + projectname="${argfolder}" + export COMPOSE_PROJECT_NAME=${projectname} + export MOODLE_DOCKER_WEB_PORT="${moodleDockerPort[$iterator]}" + + # Domain name for web server (defaults to localhost). + # export MOODLE_DOCKER_WEB_HOST="example.com" + + case $SWITCH in + "--build") + if [ -n "$(docker ps -f "name=${projectname}-webserver-1" -f "status=running" -q)" ]; then + error_message "The site ${projectname} is already running! It cannot be re-initialized." + exit 1 + fi + build_instances "${projectname}" "${fullfolderpath}" + ;; + "--start") + start_instances "${projectname}" + ;; + esac + iterator=$((iterator + 1)) +done +exit 0 \ No newline at end of file diff --git a/k1run.sh b/k1run.sh new file mode 100644 index 00000000000..1018f08d1a2 --- /dev/null +++ b/k1run.sh @@ -0,0 +1,211 @@ +#!/bin/bash + +adminer_plugins () { + # Add in Adminer plugins + docker cp assets/adminer/plugins/readable-dates.php docker-Adminer:/var/www/html/plugins/readable-dates.php + docker cp assets/adminer/plugins/table-header-scroll.php docker-Adminer:/var/www/html/plugins/table-header-scroll.php + docker cp assets/adminer/plugins/pretty-json-column.php docker-Adminer:/var/www/html/plugins/pretty-json-column.php + docker cp assets/adminer/plugins/002-readable-dates.php docker-Adminer:/var/www/html/plugins-enabled/002-readable-dates.php + docker cp assets/adminer/plugins/003-table-header-scroll.php docker-Adminer:/var/www/html/plugins-enabled/003-table-header-scroll.php + docker cp assets/adminer/plugins/004-pretty-json-column.php docker-Adminer:/var/www/html/plugins-enabled/004-pretty-json-column.php +} + +error_message() { + RED='\033[0;31m' + NC='\033[0m' # No Color + echo + echo "${RED}$1${NC}" + echo +} + +help_messages () { + echo + echo "Script that automates managing docker." + echo + echo "Usage: sh k1run.sh [folder] [option] [option2]" + echo + echo "If no parameter is passed then display this help message." + echo + echo "--build Start the site and initialize the site." + echo "--build --phpunit|--behat Start the containers, install Moodle then initialize Behat or PHPUnit" + echo "--down Stop the site. Keep data" + echo "--destroy Stop the site, destory data" + echo "--reboot Restart the site - destroy all containers and re-initialize" + echo "--load Reload the site, use existing data" + echo "--phpunit Initialize for phpunit tests" + echo "--behat Initialize for behat tests" +} + +exists_in_list() { + LIST=$1 + DELIMITER=$2 + VALUE=$3 + LIST_WHITESPACES=`echo $LIST | tr "$DELIMITER" " "` + for x in $LIST_WHITESPACES; do + if [ "$x" = "$VALUE" ]; then + return 1 + fi + done + return 0 +} + +if [ $# -eq 0 ]; then + help_messages + exit 1 +fi + +#Count the variables passed in. +variablecount=$# +if [ $# -lt 1 ] || [ $# -gt 3 ] ; then + error_message "Invalid number of arguments passed in. Must be between 1 and 3 arguments" + help_messages + exit 1 +fi + +cwd=$( dirname "$PWD" ) + +folder="${1}" + +folder="${cwd}/${folder}" +if [ ! -d "${folder}" ]; then + error_message "${folder} is not valid" + help_messages + exit 1 +fi + +SWITCH=$2 +SWITCH2=$3 + +# Variables +# MOODLE_DOCKER_DB - database used by Moodle - default maria db. +# MOODLE_DOCKER_WWWROOT - folder where the Moodle code is located; +# MOODLE_DOCKER_PHP_VERSION - version of PHP used by Moodle. Default 8.1. + +if [ "$SWITCH" = "--help" ]; then + help_messages + exit 1 +fi + +list_of_options="--build --down --destroy --reboot --load --phpunit --behat" + +if exists_in_list "$list_of_options" " " $SWITCH; then + error_message "Invalid option $SWITCH" + help_messages + exit 1 +fi + +if [ "$variablecount" -eq 3 ]; then + if exists_in_list "$list_of_options" " " $SWITCH2; then + error_message "Invalid option $SWITCH2" + help_messages + exit 1 + fi +fi + +# Always use mariadb as a database. +export MOODLE_DOCKER_DB=mariadb +export MOODLE_DOCKER_WWWROOT=${folder} + +# Check the Moodle version. If its 4.5 then set php version to 8.3 +moodlever=$(grep "$branch = '405';" $folder/version.php) +if [ "$moodlever" ]; then + export MOODLE_DOCKER_PHP_VERSION=8.3 +fi + +# Use the local.yml_single for one site - includes adminer. +cp local.yml_single local.yml +cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php + +# Build +if [ "$SWITCH" = "--build" ]; then + # Check to see if the docker containers are running. + if [ -n "$(docker ps -f "name=docker-webserver-1" -f "status=running" -q )" ]; then + error_message "The Webserver is already running!. It cannot be re-initialized." + help_messages + exit 1 + fi + # Start up containers + bin/moodle-docker-compose up -d + # Wait for DB to come up + bin/moodle-docker-wait-for-db + # Initialize the database + bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license --fullname="K1MOODLE" --shortname="K1MOODLE" --summary="K1 Moodle dev" --adminpass="test" --adminemail="admin@example.com" + if [ "$SWITCH2" = "--phpunit" ]; then + # Add in unit tests initialization. + bin/moodle-docker-compose exec webserver php admin/tool/phpunit/cli/init.php + fi + if [ "$SWITCH2" = "--behat" ]; then + # Add in unit tests initialization. + bin/moodle-docker-compose exec webserver php admin/tool/behat/init.php + fi + adminer_plugins +fi + +# DESTROY +if [ "$SWITCH" = "--destroy" ]; then + if ! docker ps | grep -q 'moodlehq'; then + error_message "No containers running. Nothing to shutdown" + exit 1 + fi + bin/moodle-docker-compose down +fi + +# PNPUNIT ONLY +if [ "$SWITCH" = "--phpunit" ]; then + # Only start the containers if they are not running. + if ! docker ps | grep -q 'moodlehq'; then + # Start up containers + bin/moodle-docker-compose up -d + # Wait for DB to come up + bin/moodle-docker-wait-for-db + adminer_plugins + fi + bin/moodle-docker-compose exec webserver php admin/tool/phpunit/cli/init.php +fi + +# BEHAT ONLY +if [ "$SWITCH" = "--behat" ]; then + # Only start the containers if they are not running. + if ! docker ps | grep -q 'moodlehq'; then + # Start up containers + bin/moodle-docker-compose up -d + # Wait for DB to come up + bin/moodle-docker-wait-for-db + adminer_plugins + fi + bin/moodle-docker-compose exec webserver php admin/tool/behat/cli/init.php +fi + +# REBOOT +if [ "$SWITCH" = "--reboot" ]; then + # Stop the containers + if ! docker ps | grep -q 'moodlehq'; then + error_message "No containers running. Nothing to reboot" + exit 1 + fi + bin/moodle-docker-compose stop + sleep 3 + # Re-start up containers + bin/moodle-docker-compose start + adminer_plugins +fi + +# DOWN +if [ "$SWITCH" = "--down" ]; then + # Check to see if containers are running. + if ! docker ps | grep -q 'moodlehq'; then + error_message "No containers running. Nothing to shutdown" + exit 1 + fi + # Stop the containers + bin/moodle-docker-compose stop +fi + +# LOAD existing data. +if [ "$SWITCH" = "--load" ]; then + # Start the containers + bin/moodle-docker-compose start + adminer_plugins +fi + +exit 0 diff --git a/local.yml b/local.yml new file mode 100644 index 00000000000..77f724c604f --- /dev/null +++ b/local.yml @@ -0,0 +1,18 @@ +version: "2" +services: + webserver: + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + - "${ASSETDIR}/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" + environment: + XDEBUG_MODE: debug,develop + XDEBUG_CONFIG: + client_host=host.docker.internal + start_with_request=yes + log=./tmp/xdebug.log + log_level=10 + idekey=VSCODE + discover_client_host=1 + diff --git a/local.yml_many b/local.yml_many new file mode 100644 index 00000000000..6be642b6788 --- /dev/null +++ b/local.yml_many @@ -0,0 +1,7 @@ +services: + webserver: + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + - "${ASSETDIR}/php/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini" diff --git a/local.yml_single b/local.yml_single new file mode 100644 index 00000000000..4ef5deca548 --- /dev/null +++ b/local.yml_single @@ -0,0 +1,30 @@ +services: + webserver: + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - "${ASSETDIR}/php/10-docker-php-moodle.ini:/usr/local/etc/php/conf.d/10-docker-php-moodle.ini" + environment: + XDEBUG_MODE: debug,develop + XDEBUG_CONFIG: + client_host=host.docker.internal + start_with_request=yes + log=./tmp/xdebug.log + log_level=10 + idekey=VSCODE + discover_client_host=1 + + adminer: + image: adminer:latest + container_name: "${COMPOSE_PROJECT_NAME}-Adminer" + environment: + ADMINER_DEFAULT_SERVER: db + ADMINER_PLUGINS: tables-filter + MYSQL_DATABASE: moodle + MYSQL_USER: moodle + MYSQL_PASSWORD: m@0dl3ing + build: + context: "./bin/Adminer/" + ports: + - 8089:8080 +