yipo
3/27/2015 - 5:04 PM

redmine-api-spent-time-workaround

redmine-api-spent-time-workaround

<?php

define('REDMINE_API', 'http://user:password@redmine/');
define('CACHE_FILE',  './cache.json');

if ( file_exists(CACHE_FILE) && filemtime(CACHE_FILE) > strtotime('10 minutes ago') )
{
    $data = file_get_contents(CACHE_FILE);
}
else
{
    file_put_contents(CACHE_FILE, '');

    $data = json_encode(array('time_entries' => build_time_entries(REDMINE_API)));
    file_put_contents(CACHE_FILE, $data);
}

echo isset($_GET['callback']) ? $_GET['callback']."($data)" : $data;


function request_enough($url, $total)
{
    $array = array();

    while (count($array) < $total)
    {
        set_time_limit(10);

        $str = file_get_contents($url.'?'.http_build_query(
            array(
                'nometa' => 1,
                'offset' => count($array),
                'limit'  => $total - count($array),
                )
            ));

        foreach (json_decode($str) as $key => $value)
        {
            // There should only be one element whose type is 'array', due to 'nometa=1'.

            if (is_array($value))
            {
                $array = array_merge($array, $value);
            }
        }
    }

    return $array;
}

function build_time_entries($url)
{
    $entry = request_enough($url.'time_entries.json', 300);
    $issue = request_enough($url.'issues.json',      1200);

    $issue = array_reduce($issue, function($carry, $item)
        {
            $carry[$item->id] = $item;
            return $carry;
        });

    foreach ($entry as $key => $value)
    {
        if (!isset($value->issue)) continue;

        $issue_id = $value->issue->id;
        $value->issue->name = isset($issue[$issue_id]) ? $issue[$issue_id]->subject : 'issue #'.$issue_id;
    }

    return $entry;
}