bio blog

A PHP Wrapper for the Clockify API

10/26/2018

I recently switched to using Clockify as my time tracking tool. It's completely free and has desktop apps for Windows, Mac, and Linux.

The one issue I had was that the summary reports on their website aggregate at the client and project levels, but not at the entry level. This means that if I have two entries with the same name, the summary report displays both of them. I usually attach summary reports to client invoices, so this level of detail is not useful.

Clockify summary report displaying four clients: Donatello Donuts, Michelangelo Music Company, Raphael Realty Corp, and Leonardo and Associates. Leonardo and Associates is expanded and shows two entries labelled "Merge latest changes from feature branch"

Luckily, Clockify has an API you can use to generate your own reports: https://clockify.github.io/clockify_api_docs/. The only drawback is that they don't have any client libraries for the API so you have to build your own, and I did.

This is just a rough PHP wrapper that's built to address the one issue I was trying to solve. The most useful method is getReportByDay, which returns a data model of a report. Internally, it uses the apiRequest( $apiPath, $payload = false ) method, which you can call directly to make arbitrary GET and POST calls.

To install, simply

composer require moismailzai/clockify dev-master

then use like so

require_once './vendor/autoload.php';
use MoIsmailzai\Clockify;

$clockify = new Clockify( "YOUR_API_KEY", "YOUR_WORKSPACE_NAME" );

$dates = array(
    "2018-10-26"
);

$result = "";

foreach ( $dates as $date ) {
    $report = $clockify->getReportByDay( $date );
    $result .= $clockify->formatReport( $report );
}

print_r( $result );

which will yield something like

---------------------------------------------------------
 Report for 2018-10-26 (7 hours, 13 minutes, 37 seconds)
---------------------------------------------------------

Donatello Donuts (0 hours, 1 minutes, 33 seconds):

• Try one of their donuts (research...) (0 hours, 1 minutes, 33 seconds)

Michelangelo Music Company (5 hours, 41 minutes, 12 seconds):

• Create new Live Music section (3 hours, 10 minutes, 12 seconds)
• Debug frontpage iPhoneSE bug (0 hours, 18 minutes, 25 seconds)
• Fix typo on About page (0 hours, 4 minutes, 44 seconds)
• Remove reliance on unbounce library (1 hours, 30 minutes, 57 seconds)
• Update ads.txt (0 hours, 3 minutes, 18 seconds)
• Update robots.txt (0 hours, 10 minutes, 58 seconds)
• Replace banner images (0 hours, 22 minutes, 38 seconds)

Raphael Realty Corp (1 hours, 22 minutes, 07 seconds):

• Add lead capture form (1 hours, 22 minutes, 07 seconds)

Leonardo and Associates (0 hours, 8 minutes, 45 seconds):

• Merge latest changes from feature branch (0 hours, 8 minutes, 45 seconds)

You'll note this text report doesn't have the duplicate entries that the web generated report had under Leonardo and Associates. The formatting of this report is handled in formatReport and decoupled from the data model generated by getReportByDay:

public function formatReport( $report )
{
    $result = "---------------------------------------------------------\n" ;
    $result .= " Report for " . $report['date'] . " (" . $report['total'] . ")\n";
    $result .= "---------------------------------------------------------\n";
    foreach ($report['projects'] as $key => $project) {
        $result .="\n";
        $result .= $key . " (" . $project['time'] . "): \n\n";
        foreach ($project['entries'] as $key2 => $entry) {
            $result .= "• " . $key2 . " (" . $entry['totalString'] . ")\n";
        }
    }
    $result .="\n";
    return $result;
}

...which means you can easily roll your own formatter.

Check out the code and fork it on Github!