Contributing ------------ Chamilo LMS is a free software learning management platform. The Chamilo project includes documentation, a mobile app, a terminal console, integrations with other projects and a series of related subprojects that are part of the Chamilo ecosystem. Chamilo LMS is a LAMP-based e-learning web platform that focuses on providing an easy-to-use environment for teachers to improve both the quality and availability of their educational material and on providing students with an awesome learning platform. Before you report an issue, please check the [official Chamilo documentation](https://docs.chamilo.org) (not always up to date). The Chamilo "editorial" team is small and greatly welcomes any external contribution. We will thoroughly review them before integration to make sure they do not introduce security vulnerabilities or degrade the platform's ease of use, but we do appreciate any sincere effort to help. Version 3.0 of Chamilo is composed of 2 parts: one (now minor) legacy part located mostly in the "public/main" folder, and the main Symfony-based part located in the "src" folder (with support of a VueJS frontent in assets/vue/). Any contribution to the project should either strive to convert legacy code to Symfony or to add new features to the Symfony part. # Installing Chamilo The following instructions are all intended to set a development environment up for Chamilo 3. If you want to install Chamilo on a production server, please refer to the official installation guide in the documentation/ folder. ## Requirements ### Hardware We recommend developing Chamilo on a machine with at least - 8GB of RAM (or 4GB + 4GB of swap on SSD/NVMe) - 2 powerful CPUs - about 10GB of disk space ### Software - Some Linux distribution (tests on Windows server have been limited for development) - Composer 2.x - https://getcomposer.org/download/ - Yarn 4.x+ - https://yarnpkg.com/getting-started/install - NodeJS >= v20+ (lts) - https://github.com/nodesource/distributions/blob/master/README.md - A web server with a virtualhost in a domain or subdomain (not in a subfolder inside a domain with another application). - A working PHP configuration with PHP 8.2 or 8.3 # Installing Chamilo for development ## Quick step-by-step You will need PHP8.3, 8.4 or 8.5 and NodeJS v20+ to run Chamilo 2. On Ubuntu 24.04+, the following should take care of all dependencies (certbot is optional). Replace 'chamilo' by the database name and user you want, and '{password}' by a more secure password. ~~~~ sudo apt update && apt -y upgrade sudo apt install apache2 libapache2-mod-php mariadb-client mariadb-server php-pear php-{apcu,bcmath,cli,curl,dev,gd,intl,ldap,mbstring,mysql,soap,xml,zip} git unzip curl certbot sudo mysql mysql> CREATE USER chamilo@localhost IDENTIFIED BY '{password}'; mysql> GRANT ALL PRIVILEGES ON chamilo.* TO chamilo@localhost; mysql> exit cd ~ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - sudo apt-get install -y nodejs sudo corepack enable cd ~ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php composer-setup.php php -r "unlink('composer-setup.php');" sudo mv composer.phar /usr/local/bin/composer cd /var/www git clone -b master --depth=1 https://github.com/chamilo/chamilo-lms.git chamilo cd chamilo composer install sudo a2enmod rewrite ssl headers expires sudo cp public/main/install/apache.dist.conf /etc/apache2/sites-available/my.chamilo.net.conf # edit if you want to change the local domain name sudo a2ensite my.chamilo.net sudo systemctl restart apache2 yarn set version stable yarn up && yarn install && NODE_OPTIONS="--max-old-space-size=4096" yarn dev # The NODE_OPTIONS is to avoid "FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory", use this instead of only "yarn dev" sudo touch .env sudo chown -R www-data: var/ .env config/ # load http://my.chamilo.net in your browser and follow the installation wizard sudo chown -R root: .env config/ ~~~~ ## Detailed procedure The following is the section above, but with more details and hedge cases. ~~~~ sudo apt update sudo apt -y upgrade sudo apt install apache2 libapache2-mod-php mariadb-client mariadb-server php-pear php-{apcu,bcmath,cli,curl,dev,gd,intl,ldap,mbstring,mysql,soap,xml,zip} git unzip curl certbot sudo mysql mysql> CREATE USER chamilo@localhost IDENTIFIED BY '{password}'; mysql> GRANT ALL PRIVILEGES ON chamilo.* TO chamilo@localhost; mysql> exit ~~~~ On older Ubuntu versions (like 22.04), you have to install PHP through third-party sources: ~~~~ sudo apt update sudo apt -y upgrade sudo apt -y install ca-certificates curl gnupg software-properties-common sudo add-apt-repository ppa:ondrej/php sudo apt update sudo apt install apache2 libapache2-mod-php8.3 mariadb-client mariadb-server php-pear php8.3-{apcu,bcmath,cli,curl,dev,gd,intl,ldap,mbstring,mysql,soap,xml,zip} git unzip curl sudo mysql mysql> CREATE USER chamilo@localhost IDENTIFIED BY '{password}'; mysql> GRANT ALL PRIVILEGES ON chamilo.* TO chamilo@localhost; mysql> exit ~~~~ (replace 'chamilo' by the database name and user you want, and '{password}' by a more secure password) ## NodeJS, Yarn, Composer If you already have nodejs installed, check the version with `node -v` Otherwise, install Node.js 20 or above. Use the following lines to get a static version of Node.js 20 from https://deb.nodesource.com/ (recommended) ~~~~ cd ~ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - sudo apt-get install -y nodejs ~~~~ Alternative (not recommended): install Node.js by using NVM (Node Version Manager). You can install it following the instructions [here](https://github.com/nvm-sh/nvm#installing-and-updating). You can install the desired node version (preferably, the LTS version): ~~~~ sudo nvm install --lts sudo nvm use --lts ~~~~ Once NodeJS is installed, you must enable `corepack` and then continue with the requirements ~~~~ sudo corepack enable cd ~ ~~~~ Follow the instructions at https://getcomposer.org/download/ to get Composer, then add it to the local binaries for easier use: ~~~~ sudo mv composer.phar /usr/local/bin/composer ~~~~ ## Apache tweaks Apache's rewrite module is mandatory if you use Apache. The rest is optional and depends on your needs. ~~~~ sudo apt install libapache2-mod-xsendfile #only for optimization if used in the vhost config sudo a2enmod rewrite ssl headers expires sudo systemctl restart apache2 ~~~~ When your system is all set, you can use the following: ~~~~ cd /var/www git clone -b master --depth=1 https://github.com/chamilo/chamilo-lms.git chamilo cd chamilo composer install ~~~~ We do not recommend running composer as the root user! When asked whether you want to execute the recipes or install plugins for some of the components, you can safely type 'n' (for 'no'). ~~~~ yarn set version stable # delete yarn.lock if present, as it might contain restrictive packages from a different context yarn up && yarn install && yarn dev # you can safely ignore any "warning" mentioned by yarn dev sudo touch .env sudo chown -R www-data: var/ .env config/ ~~~~ In your web server configuration, ensure you allow for the interpretation of .htaccess (`AllowOverride all` or `Require all granted`), and point the `DocumentRoot` to the `public/` subdirectory. Finally, make sure your PHP config points at Redis for sessions management. This should look similar to the short excerpt below (in your Apache vhost block) if you use SSL. If you do not use SSL, you can remove the first block and change `*:443` by `*:80` for the second block. ~~~~ ServerName my.chamilo.net RewriteEngine On RedirectMatch 302 (.*) https://my.chamilo.net$1 DocumentRoot /var/www/chamilo/public/ ServerName my.chamilo.net # Error logging rules... # SSL rules... RewriteEngine On AllowOverride All Require all granted Require all denied php_value session.cookie_httponly 1 php_admin_value upload_max_filesize 256M php_admin_value post_max_size 256M ~~~~ Don't forget to reload your Apache configuration after each change: ~~~~ sudo systemctl reload apache2 ~~~~ ## Quick updates for development/testing purposes If Chamilo is already installed in a development environment and you only want to update the code and dependencies, use: ~~~~ git pull origin master composer install && php bin/console cache:clear && chown -R www-data: var/cache && yarn install && NODE_OPTIONS="--max-old-space-size=4096" yarn dev && php bin/console cache:warmup && chown -R www-data: var/cache php bin/console doctrine:migrations:migrate --no-interaction ~~~~ Note: the double `chown` in the command above is just to make sure you can use your Chamilo portal in the meantime. In some cases, `yarn dev` or `cache:warmup` might take a while to "come back", and in the meantime the changes you have made through composer install might have written some files or created some directories to `var/cache` as another user, which might prevent Chamilo itself to write its cache there while yarn is running. If your local clone uses a fork, replace `origin` with the remote that tracks the official Chamilo repository (commonly `upstream`). `doctrine:migrations:migrate` is the normal way to update the database of an existing development installation. Do not use `doctrine:schema:update --force` as a replacement: schema updates do not execute the data-processing logic contained in migrations and can result in data loss. Occasionally a change can add data to a migration that your local database has already marked as executed. In that specific case, re-run the migration explicitly as instructed by the change: ``` php bin/console doctrine:migrations:execute "Chamilo\CoreBundle\Migrations\Schema\V300\Version[date]" --up ``` ### Fixtures for development and testing Doctrine fixtures are intended for fresh or disposable development/test databases. `doctrine:fixtures:load` purges existing data by default, so do not run it against a database containing data you want to keep. For the PHPUnit test database, after creating the schema as described in `tests/README.md`, load the fixtures with: ``` php bin/console --env=test doctrine:fixtures:load --no-interaction ``` Playwright uses additional browser-level seed scenarios. Run them once, in this order, before the main browser test suite: ``` yarn test:playwright:seed yarn test:playwright:seed-course yarn test:playwright:seed-private-course yarn test:playwright:seed-settings ``` These seeds create the fixed test users, the `TEMP` and `TEMPPRIVATE` courses, and the platform settings expected by the Playwright scenarios. The `yarn test:playwright:install` command is destructive because it recreates the database and is intended for CI installation testing, not for updating an existing development environment. Fixture groups are not a substitute for migrations on an existing installation. Changes that must reach already-installed databases should be delivered through the corresponding migration. If an update causes dependency or cache problems, first retry the normal installation commands (`composer install`, `yarn install`, and `php bin/console cache:clear`) before removing lock files or replacing pinned dependencies. ### Refresh configuration settings In case you believe some settings in Chamilo might not have been processed correctly based on an incomplete migration or a migration that was added after you installed your development version of Chamilo, the /admin/settings_sync URL is built to try and fix that automatically by updating PHP classes based on the database state. This issue rarely happens, though. ## Quick re-install If you have it installed in a dev environment and feel like you should clean it up completely (might be necessary after changes to the database), you can do so by: * Removing the `.env` file * Loading the {url}/main/install/index.php page again The database should be automatically destroyed, table by table. In some extreme cases (a previous version created a table that is not necessary anymore and creates issues), you might want to clean it completely by just dropping the database, but this shouldn't be necessary most of the time. If, for some reason, you have issues with either composer or yarn, a good first step is to delete completely the `vendor/` folder (for composer) or the `node_modules/` folder (for yarn). ## Development setup (Dev environment, stable environment not yet available) If you are a developer and want to contribute to Chamilo in the current development branch (not stable yet), then please follow the instructions below. Please bear in mind that the development version is NOT STABLE at this time, and many features are just not working yet. This is because we are working on root components that require massive changes to the structure of the code, files and database. As such, to get a working version, you might need to completely uninstall and re-install from time to time. You've been warned. First, apply the procedure described here: [Managing CSS and JavaScript in Chamilo](assets/README.md) (in particular, make sure you follow the given links to install all the necessary components on your computer). Then make sure your database supports large prefixes (see [this Stack Overflow thread](https://stackoverflow.com/questions/43379717/how-to-enable-large-index-in-mariadb-10/43403017#43403017) if you use MySQL < 5.7 or MariaDB < 10.2.2). Load the (your-domain)/main/install/index.php URL to start the installer (which is very similar to the installer in previous versions). If the installer is pure-HTML and doesn't appear with a clean layout, that's probably because you didn't follow these instructions carefully. Go back to the beginning of this section and try again. If you want hot reloading for assets use the command `yarn run encore dev-server`. This will refresh automatically your assets when you modify them under `assets/vue`. Access your chamilo instance as usual. In the background, this will serve assets from a custom server on http://localhost:8080. Do not access this url directly since [Encore](https://symfony.com/doc/current/frontend.html#webpack-encore) is in charge of changing url assets as needed. ### Supporting PHP 7.4 and 8.3 in parallel You might want to support PHP 8.3 (for Chamilo 2) and PHP 7.4 (for all other things) on the same server simultaneously. On Ubuntu, you could do it this way: ``` sudo add-apt-repository ppa:ondrej/php sudo apt update sudo apt install php8.3 libapache2-mod-php7.4 php8.3-{modules} php7.4-{modules} sudo apt remove libapache2-mod-php8.3 php7.4-fpm sudo a2enmod proxy_fcgi sudo vim /etc/apache2/sites-available/[your-chamilo-vhost].conf ``` In the vhost configuration, make sure you set PHP 8.3 FPM to answer this single vhost by adding, somewhere between your `` tags, the following: ``` SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1 SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost" Require all denied Require all denied ``` Then exit and restart Apache: ``` sudo systemctl restart apache2 ``` Finally, remember that PHP settings will have to be changed in `/etc/php/8.3/fpm/php.ini` and you will have to reload `php8.3-fpm` to take those config changes into account. ``` sudo systemctl reload php8.3-fpm ``` When using 2 versions, you will also have issues when calling `composer update`, as this one needs to be called by the relevant PHP version. This can be done like so: ``` /usr/bin/php8.3 /usr/local/bin/composer update or, for Chamilo 1.11 /usr/bin/php7.4 /usr/local/bin/composer update ``` If your default php-cli uses PHP7.4 (see `ln -s /etc/alternatives/php`), you might have issues running with a so-called `platform_check.php` script when running `composer update` anyway. This is because this script doesn't user the proper launch context, and you might need to change your default settings on Ubuntu (i.e. change the link /etc/alternatives/php to point to the other php version) before launching `composer update`. You can always revert that operation later on if you need to go back to work on Chamilo 1.11 and Composer complains again. ### git hooks `composer install` points git at `tests/scripts/git-hooks/`, so every clone gets the project hooks without any manual step. If you cloned before that change, or composer ran with `--no-scripts`, enable them with: git config core.hooksPath tests/scripts/git-hooks/ An existing `core.hooksPath` of your own is never overwritten. The `pre-push` hook runs ECS (the tool behind `composer phpcs-fix`) over the PHP files of the commits you push. If it finds a code style problem, it fixes the files in your working tree and stops the push. Add the fix to your commits and push again: git add -u && git commit --amend --no-edit The hook uses the `php` of your machine when it can see `vendor/`. If it cannot, the hook uses the Docker container `chamilo2-php83`. Set `CHAMILO_PHP` or `CHAMILO_PHP_CONTAINER` if your setup is different. To skip the hook one time, push with `--no-verify`. ## Big changes from 1.x (for developers) This is a list of structural changes to help developers/maintainers of Chamilo 1.11 find their way in Chamilo 2. It is *not* a features list (refer to `public/documentation/changelog.html` for that). * in general, the `main/` folder has been moved to `public/main/` * a big part of the frontend has been migrated to VueJS + Tailwind CSS (see `assets/vue/`) * `app/Resources/public/assets/` moved to `assets/` * `main/inc/lib/javascript/` moved to `assets/js/` * `main/img/` moved to `public/img/` * `main/template/default/` moved to `src/CoreBundle/Resources/views/` * `src/Chamilo/XXXBundle/` moved to `src/CoreBundle/` or `src/CourseBundle/` * `bin/doctrine.php` removed, use `bin/console doctrine:xyz` options * plugin images, CSS and JS libs are loaded inside the `public/plugin/` folder and the folder names have been renamed to CamelCase * plugins templates use the `asset()` function instead of using `_p.web_plugin` * `main/inc/local.inc.php` has been removed and `main/inc/global.inc.php` greatly reduced * translations are managed through Gettext, from the `translations/` directory for PHP code and from `assets/locales/` for VueJS code * files in `app/config/` have been restructured (to `.yaml`) and moved to `config/` * `app/config/configuration.php` has essentially been emptied to the `settings` table (accessible via the admin page in Chamilo), while the critical settings (database access etc) have been transferred to `.env` ### Libraries * Integration with Symfony 7.4 * PHPMailer replaced with Symfony's Mailer * Bower replaced by [yarn](https://yarnpkg.com) # Contributing patches or new features If you'd like to contribute to this project, please read the following documents: * [Coding conventions][1]: The main conventions document * [PSR-1][2]: PSR-1 are standard conventions rules we use as a base (conversion of old code still in progress) * [PSR-2][3]: PSR-2 are more detailed standard conventions rules we use as base (conversion of old code still in progress) We expect contributions to be sent through Pull Requests, a very clean feature of our versioning control platform. We recommend you follow this guide to understand a little more about the way it works: https://guides.github.com/activities/contributing-to-open-source/ In short, we ask you to send us Pull Requests based on a branch that you create with this purpose into your own repository, forked from the original Chamilo repository (`master` branch). ## Testing new features As new major features are added, automated tests should be added that ensure that the feature continues to work for the foreseeable future. In Chamilo, we rely on "Playwright":https://playwright.dev/ (with "playwright-bdd":https://vitalets.github.io/playwright-bdd/, so the scenarios stay plain Gherkin) to do Automated Behavior Testing. You can find the feature files in tests/playwright/features/, the shared step definitions in tests/playwright/steps/, and run them with `yarn test:playwright`. Tests are run automatically for every new contribution, courtesy of Github actions, so you can follow your feature in time and see whether something breaks it. Check the Chamilo tests URL here: https://github.com/chamilo/chamilo-lms/actions # Making changes to the database If your changes require database changes, here are a few instructions on how to proceed. You will then need to submit these changes as explained above. ## Database structure changes If your changes are about structure, you want to follow these steps: 1. Create or modify an entity in src/*something*Bundle/Entity/ 2. Create a new Migration in src/CoreBundle/Migrations/Schema/V{VERSION}/Version{time-stamp}.php This second step is most easily done by copying one of the current migration files in that directory. For example, if you're doing it on the 14th of July 2019 at noon: 1. Copy Version20190527120703.php to Version20190714120000.php 2. Edit the file and change any "20190527120703" you find to "20190714120000" 3. Check it works by issuing an update command from the command line: ``` php bin/console migrations:execute 20190714120000 --up --configuration=app/config/migrations.yml ``` ## Database data changes If you only want to change the *data* in the database, then you don't need to modify or create an entity, but you will still need to follow these two steps: 1. Modify one of the fixtures in `src/CoreBundle/DataFixtures/` 2. Create a new Migration in `src/Chamilo/CoreBundle/Migrations/Schema/{version}/` For configuration settings, check https://github.com/chamilo/chamilo-lms/wiki/Add-a-new-Chamilo-setting # Testing through Docker Coming soon... [1]: https://github.com/chamilo/chamilo-lms/wiki/Coding-conventions [2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md [3]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md