Getting File Downloads from the Piwik API in PHP/Joomla

Thu 09 June 2011 by Javex

Hey there,

got a problem today where I have to track file downloads from a site. Since I got Piwik tracking them, I will use their API to get my information, saving me loads of work.

Piwik offers the possibilty to integrate it directly into your PHP Framework and use the API without any URLs. See here.

Scroll down and you find the corresponding basic script. I wanted to implement this as two functions: Initialization and Request.

function initPiwikAPI($piwik_path = "")
    if($piwik_path == "") { $piwik_path = JPATH_BASE . DS . 'piwik'; }
    $index = strpos($piwik_path,'index.php');
    if($index !== FALSE)
        $piwik_path = substr($piwik_path,0,$index-1);

    // if you don't include 'index.php', you must also define PIWIK_DOCUMENT_ROOT
    // and include "libs/upgradephp/upgrade.php" and "core/Loader.php"
    define('PIWIK_INCLUDE_PATH', realpath($piwik_path));
    define('PIWIK_USER_PATH', realpath($piwik_path));
    define('PIWIK_ENABLE_DISPATCH', false);
    define('PIWIK_ENABLE_ERROR_HANDLER', false);
    define('PIWIK_ENABLE_SESSION_START', false);
    define('PIWIK_DOCUMENT_ROOT', realpath($piwik_path));
    define('PIWIK_TOKEN', 'abc123'); //your piwik token here; option, just in case you need one and don't define it elsewhere
    require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";
    require_once PIWIK_INCLUDE_PATH . DS . 'libs' . DS . 'upgradephp' . DS . 'upgrade.php';
    require_once PIWIK_INCLUDE_PATH . DS . 'core' . DS . 'Loader.php';

    return true;

The init-functions removes any index.php and trailing slashes and then sets any global variables and includes necessary files.


Because we use Joomla! here, including Piwiks index will screw up Joomla!. So we followed the comment above and could omit index.php.

The next function is for the request:

function piwikRequest($method = "", $idSite = 1, $date = "", $period = "", $additional_params = "")
    $token = $this->piwik_token;
    // This inits the API Request with the specified parameters
    $request = new Piwik_API_Request("
    return unserialize($request->process());

Okay normally you would have to set the module=API in the request, but since this is already an API_Request, we don't need that. This one works for my needs (the File Downloads) but it may need some modifications if some params are omitted. The URL will be entered into $additional_params, since this is clearly not a standard param. You could also declare a base function piwikRequest() and then some functions like piwik_getFileDownload() and call the base function with set parameters. Dunno, up to you.

Okay so we got the functions. The init-process needs only to be made once, I do it in my class constructor:

$this->piwik_token = PIWIK_TOKEN;

I also set the token as a class variable to access it.

Now for the function to actually get something:

$stats = $this->piwikRequest('Actions.getDownload', 1, $date, "range", "downloadUrl=" . urlencode("THEFILEURL"));
$download_count = $stats[0]["nb_visits"];

This should be it. First line gets the values from Piwik (this is an assoc. array, as returned by piwik and then unserialized). Second line just extracts the unique downloads.

One word on the date-part: This needs, in my example, to be a range, so sth like this:

$date = date("Y-m-d", $from) . ',' . date("Y-m-d", $to);

Vary $date and range to your needs and get some nice stats.