The topic of this article is somewhat unusual, given the fact that Magently is a group of developers creating applications based on the popular e-commerce – Magento. However, every team that is simultaneously implementing a dozen of projects or so needs a tool to manage the workload and track the progress accurately.

At Magently, we use Redmine, which is an open-source web tool written in a popular framework called Ruby on Rails ( Redmine is a cross-browser and cross-database application. It’s an interesting, free and user-friendly solution to the issue of managing projects.

The application offers a wide range of functionalities, including:

  • managing multiple projects;
  • access control based on a flexible role system;
  • managing multiple databases;
  • flexible system of tracking threads (issues);
  • non-standard fields for issues, dates of entries, projects and users;
  • support for messages, documents and files;

and many other options that can be found on project’s overview page.

A while ago I was asked to develop an application that would provide additional support to Redmine. It was supposed to present a simple view of two calendar weeks with marked planned tasks and the ones currently being implemented. I’ve used PHP Laravel 4.2, AngularJS framework and kbsali/php-redmine-api library for the assignment. The last one can be found on GitHub:


The first step was getting to know Redmine and its API, which turned out to be well supported by the PHP library by Kevin Saliou.

Next step was choosing the frameworks for the backend (Laravel 4.2) and the frontend (AngularJS). I decided to use a PHP framework, since it’s easier to add other libraries or functionalities later on, and Angular provides a wide range of possibilities for a user to process data without the necessity of sending repeated queries to API or of additionally caching the previously fetched data (e.g. MemcacheD or other).

Application logic assumptions

The application logic is quite simple – after a user logs in, the data with adequate conditions for each developer in the team are fetched. Then the data are supplemented with necessary information and transferred to the view in the following form:

| Developer:      |   date1     |   date2     |   date3     |   dateN     |
| Parent Feature: | quantity -h | quantity -h | quantity -h | quantity -h |
| Child Task:     | quantity -h | quantity -h | quantity -h | quantity -h |
|       .
|       .
|       .
| Parent Feature: | quantity -h | quantity -h | quantity -h | quantity -h |
| Child Task:     | quantity -h | quantity -h | quantity -h | quantity -h |
| Sum of hours    | sum         | sum         | sum         | sum         |


The view in this form gives a clear idea to a team leader, project owner or scrum master of the number of hours devoted to a particular feature or task in a given day by each developer. This significantly facilitates managing the developers’ time and meeting deadlines!

Using the library and some of its functions

We simply need to use a composer to install the library:

$ php composer.phar require kbsali/redmine-api:~1.0

We need to remember to attach to our project an autoload file created by the composer (if we’re not using a framework).

require_once 'vendor/autoload.php';

In my case, I just had to use the name space for Laravel 4.2, e.g.:

use Redmine\Client as Client;

and create an instance of such class, e.g.:

$client = new Client($this->address,$this->login,$this->password);

Once we’ve loaded the autoload.php file, we can move on to connecting with Redmine.

The first thing to do is creating an instance of the Client class with 2-3 arguments. The first argument is the same in both cases – it’s the address where Redmine is located. Next argument may be the user’s API key or his login and password.

Address and API Key

$client = new Redmine\Client('', '1234567890abcdfgh');


$client = new Redmine\Client('', 'login', 'password');

Using a username and password for the authorization is more convenient, as we don’t have to memorize a string of several dozen characters, i.e. the user’s API key. Moreover, we don’t need to implement an additional authentication to the application or user tables in the database (if we need to create a new dedicated database at all).

The above actions provide our application with an access to all Redmine resources in line with the permissions of the logged user, for example to information regarding projects, tasks, attachments or other users.

The php-redmine-api library has several types of methods, among others: displaying, creating and editing data, which is crucial in my opinion. Depending on what we want to display, create, remove or edit, we need to specify the element and the type of operation.


The fragment of code presented below will give us all issues that we have the access to:

return $this->client->issue->all();

Displaying data

The library enables us to display everything that we have access to in Redmine, for example:

  • Trackers
    There are 2 methods available here: all() and listing(). As the names suggest, the all() method gives all information about each tracker and the listing() method gives a list of the tracker ID numbers.
  • Statuses
    The library provides us with 3 methods: the above-mentioned all() and listing() methods, and an additional one – getIdByName(‘New’), which takes a string with the status name as an argument.
  • Projects
    We have access to several methods for projects: all(), listing(), show($id), getIdByName(‘string’), create(), update() and remove().

Creating data

For example:

          'name' => 'some name',
              'identifier' => 'the_identifier',
                  'tracker_ids' => array(),

The create() method takes a data array as an argument. In the example above it’s the project name, an identifier and an array with tracker IDs. Using such method we can create a project with all required fields without turning Redmine on.

Removing data

The remove() method takes an ID or a data array as a parameter. For example:


The above code will remove an issue with ID equal to 5.

The next article will focus on displaying specific data in Redmine, so stay tuned!

Many other examples of using the library can be found under the following link: