Contributing to Matomo (formerly Piwik) Core

About this guide

Read this guide if

  • you've found a bug, fixed it and want to know how to get your fix accepted upstream
  • you're interested in contributing changes to Matomo and want to know where to start or want to know what the process is like
  • you'd like to know what Matomo developers consider to be good code

Guide assumptions

This guide assumes that you:

  • can code in PHP and JavaScript,
  • can use the git source code management tool
  • are familiar with GitHub,
  • and have the necessary tools to contribute to Matomo (if not, see this section of our Getting started extending Matomo guide).

Contribution process

The contribution process starts with a bug you want to fix or an idea that you want to implement. If you don't have one, feel free to pick an open ticket on github.com/matomo-org/matomo/milestones.

Once you've decided on something, continue below.

Getting a copy of Matomo to work on

Before you can start contributing you need to get setup with git & GitHub. If needed, you can create a GitHub account here.

If you are a Matomo core developer then you have write permissions to the Matomo repository and therefore you don't need to fork Matomo and can skip below steps. Instead clone the Matomo repository and push to it directly. This will simplify a lot of your work.

Fork the Matomo repository

While logged in GitHub, visit Matomo's repository. In the upper right corner there is a Fork button. Click it. Github will copy the repository into your account. This copy (or fork) is the one you will work on. If you don't know forks, read more about forks on GitHub.

Setup git

When committing, git will need to know your username and email. To set them, run the following commands:

git config --global user.name John Doe
git config --global user.email john@example.com

Clone the forked repository

Clone your Matomo fork (replace myusername with you GitHub user name):

git clone https://github.com/myusername/piwik

This will copy the entire forked repository (including all history) to the piwik folder on your machine.

Now, we'll run one more command so git remembers the original Matomo repository in addition to your fork:

git remote add upstream https://github.com/matomo-org/matomo

This will save https://github.com/matomo-org/matomo as a remote and name it upstream.

Configure PHP

Contributions should not generate PHP errors or warnings. Applying the following settings to your php.ini file will enable you to catch these errors:

display_errors  = On
error_reporting = E_ALL | E_STRICT

Hacking Matomo

Now that you have a copy of the latest Matomo source code, you can start modifying it. For this section, we'll assume there's a bug that you found and want to fix.

Create a new branch

Before you start coding, you should make sure to keep your changes separate from the 4.x-dev branch. This will make it much easier to track the changes specific to your feature since your changes won't be mixed with any new commits to the 4.x-dev branch from other developers.

We'll give our new branch a name. The branch name ideally always contains the GitHub issue number eg 1111 or m1111 or if it's a Jira issue then eg dev-1111. Optionally, a descriptive name can be added if wanted. It's not a requirement though since the branch usually exists only temporarily anyway and a PR with description etc often exists too. To add a new branch, run the following command:

git checkout -b bugfix

The checkout command will create a new branch if the -b option is supplied, otherwise it will try to load an existing branch.

Work on the code

Once you've created a branch, you have a place to start working on the feature. There's nothing special about this part of the process, just fix the bug or finish the feature you're working on.

If you're working on something more complex than a bugfix, you may have the need to keep your new branch updated with changes from the main repository. Keeping your branch up to date is a two-step process.

First, on your 4.x-dev branch, pull changes from the main Matomo repository, nicknamed upstream:

git pull upstream 4.x-dev

Then, on your new branch (bugfix for this tutorial), merge with 4.x-dev:

git merge 4.x-dev

If there are conflicts, you can read this guide: How to resolve Git conflicts.

Save your changes

Now that you've finished the bug fix or new feature (or just part of it), it's time to commit your changes and push them to your fork (the origin remote).

git add ModifiedFile.php AnotherFile.js
git commit -m 'Added new feature: XYZ (replace this with a descriptive commit message)'
git push

You can read this guide to learn how to commit changes. You can read this guide to learn how to push commits.

In a branch it's fine to commit often and regularly. Later, when the PR will be merged we always squash the PR meaning it will only become one commit and the PR title will become the commit message and the PR will be linked to find more information about the commit if needed. This means the individual commit messages aren't too important but should still be useful.

Creating a pull request

Now that you have pushed your changes it's time to get your changes merged. To learn more about this read our Pull Requests & Reviews guide.

Switching between branches

Keeping dependencies up to date

Every time you change the branch you may need to run composer install (and maybe also npm install). You can automate this task by following these steps:

  • Create a file called .git/hooks/compile.sh containing this content
#!/bin/bash

changedFiles="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)"

runOnChange() {
    echo "$changedFiles" | grep -q "$1" && eval "$2"
}

runOnChange package-lock.json "npm install"
runOnChange composer.lock "composer install"
  • Make sure the file can be executed: chmod +x .git/hooks/compile.sh
  • Add below line to the end of the file .git/hooks/post-checkout
.git/hooks/compile.sh

It will only be executed when the composer or npm actually changes.

Dealing with Matomo updates

When the version inreases and there is an update, the UI/API will automatically let you know that a migration update needs to be executed. The UI will directly present the update screen where it asks you to execute any outstanding migration updates. The API will return an error message mentioning an update is available and then you need to open the UI to execute this update or run ./console core:update --yes.

In some cases a required migration update may not be executed. This happens for example if you're working in a different branch where the version number is higher and meanwhile in eg 4.x-dev an update was added for a lower version number. It also happens when you're working on the current version number and an update is added to the current Matomo version number without increasing the version number. Matomo will then think it already executed the update because the version number didn't increase. You can't really detect when this happens until you run into a problem because for example a column is missing. When this happens, you need to manually set back the version number of your Matomo in the database and run for example below queries:

-- you may need to replace the DB table prefix "matomo_" and you need to set the version number to the correct version number so the not executed update script will be executed.
set @current_version = (select option_value from matomo_option x where option_name = 'version_core');
update matomo_option set option_value ='{new_version_number_you_want_to_set}' where option_name like 'version_%' and option_value = @current_version;

Note: Matomo updates are designed to always be executed multiple times. If the update already happened, for example a column was already added, then Matomo will "detect" this and not error.

Downgrading Matomo updates (not possible)

Sometimes you may need to run some code on a previous version of Matomo, for example, making a change to Matomo 3. There's no current way to downgrade a database (undo an update) so in this case you'll have to use an upgraded version of Matomo with the older code.

In practice this means creating features that downgrade still work on older versions. The only exception being changing major versions. In this case there will be documentation for how to manually downgrade a database so we can run the older version (for example this faq: https://matomo.org/faq/how-to/how-do-i-downgrade-from-matomo-4-to-matomo-3/).

Learn more about Updates and how to write them

See our docs on Updates if you need to make changes to matomo for your pull request: https://developer.matomo.org/guides/updates-aka-migrations.

Matomo Core code standards

See our dedicated guide for Matomo Code Standards.

Debugging

See our debugging Matomo core guide.

Submodules

Matomo has various submodules. These will be updated weekly automatically using a GitHub action. This means if you push something to a submodule, for example the Tag Manager, then you won't need to create another pull request in Matomo repository to update the submodule. In some cases, for example if an important fix was made shortly before a release then you may need to create a PR to update the submodule reference in the Matomo repository.

Automated tests

If you are fixing a bug, it is usually better to also submit a testcase covering this fix. Such a test will be useful to prevent the bug from reappearing again in the future.

If you are adding a new feature to Matomo, adding a new API method or modifying a core Archiving or Tracking algorithm, generally it is required to also submit new or updated unit or integration tests.

For more information about running or creating tests, read our Testing guide.

When naming unit/integration tests, it helps to use the Given, When, Then convention for writing tests.

Tests are critical part of ensuring Matomo stays a stable and useful software platform. We aim to keep test code as clean as production code so it is easy to improve and maintain.

Submitting a plugin for integration into Core

If you've already developed a plugin (congratulations!) which you think could be included in Matomo Core, you can offer it for inclusion.

The adoption of a plugin into Matomo Core requires that we consider such criteria as (but not limited to):

  • audience: plugin appeals to a broad spectrum of users
  • desirability: is it a frequently requested feature by the Matomo community?
  • functionality: feature completeness
  • testability: use of unit, integration and UI tests and impact to manual testing (e.g., differences when plugin is activated vs deactivated)
  • maturity: history and popularity of the plugin
  • performance: impact on archiving and/or UI interaction
  • supportability: likelihood of spawning support tickets and forum posts of the "how do I?" or "why does it?" variety
  • complexity: simpler is better; +1 if developer has git commit privileges
  • dependencies: does it depend on closed source and/or paid subscription services?
  • licensing: license compatibility with GPLv3

In most cases, it should be enough for your plugin to be available on the Marketplace.

Learn more