myorama
3/25/2016 - 4:38 PM

Dashboard class for monitoring layout

Dashboard class for monitoring layout

<?php

include_once('core/databases.php');
require_once('core/PdoConnexion.php');

function get_kayako_status_by_team($team) {
  global $auths;
  global $cache;
  
  // donnes en cache  
  $cached = $team . '-departments';
  $result = $cache->get($cached);
  if ($result !== false) return $result;  
  
  // connexion a la bdd kayako
  $db = new PdoConnexion($auths['kayako']);
  
  $sql = "select department
                 , IFNULL(SUM(IF(task = 0, isopen, 0)), 0) as open
                 , IFNULL(SUM(IF(task = 0, isassigned, 0)) + SUM(IF(task = 0, isinprogress, 0)), 0) as work
                 , IFNULL(SUM(IF(task = 0, iswaiting, 0)), 0) as wait
                 , IFNULL(SUM(IF(task = 0, overdue, 0)), 0) as over
                 , IFNULL(SUM(IF(task = 1 AND iswaiting = 0, 1, 0)), 0) as task
                 , IFNULL(SUM(IF(task = 1 AND iswaiting = 1, 1, 0)), 0) as taskw
                 , COUNT(ticketid) as total
            from
            (
            select t.ticketid as ticketid, dep.title as department
                 , CASE ts.title WHEN  'Assigned'  THEN 1 ELSE 0 END as isassigned
                 , CASE ts.title WHEN  'In progress'  THEN 1 ELSE 0 END as isinprogress
                 , CASE ts.title WHEN  'Waiting'  THEN 1 ELSE 0 END as iswaiting
                 , CASE ts.title WHEN  'Open'  THEN 1 ELSE 0 END as isopen
                 , CASE WHEN (t.resolutionduedateline > 0 and FROM_UNIXTIME(t.resolutionduedateline) < NOW() and ts.title != 'Waiting' ) THEN 1 ELSE 0 END AS overdue
                 , CASE WHEN t.tickettypetitle like 'TME %' THEN 1 ELSE 0 END AS task
            from swtickets t
            join swticketstatus ts on t.ticketstatusid = ts.ticketstatusid
            join swdepartments dep on t.departmentid = dep.departmentid
            join swgroupassigns ga on dep.departmentid = ga.departmentid
            join swstaffgroup grp on ga.staffgroupid = grp.staffgroupid and grp.title = concat(:team, ' Team')
            left outer join swstaff s on t.ownerstaffid = s.staffid
            where t.isresolved = 0
              and (t.ownerstaffid = 0 or grp.staffgroupid = s.staffgroupid)
              and ((
                    (t.tickettypetitle not like '%Issue%' and t.tickettypetitle not like '%Information%')
                  and (t.tickettypeid <= 6 or t.tickettypetitle like 'APP %' or t.tickettypetitle like 'TME %'
                   or (:team = 'DBA' and t.tickettypetitle like 'BDD %')
                   or (:team in ('EXP','SYS') and t.tickettypetitle like 'SYS %'))
             ) or grp.title like 'SAP%')
            ) as liste
            group by department";
    
  // mise en cache
  $result = $db->get_array($sql, array(':team' => strtoupper($team)));
  if (get_class($cache) == 'Memcached') {
    $cache->set($cached, $result, $auths['kayako']['cached']);
  } else {
    $cache->set($cached, $result, false, $auths['kayako']['cached']);
  }
  
  return $result;
}

function get_team_tickets_number($team) {
  global $auths;
  global $cache;
  
  // donnes en cache  
  $cached = $team . '-tickets';
  $result = $cache->get($cached);
  if ($result !== false) return $result;  
  
  // connexion a la bdd kayako
  $db = new PdoConnexion($auths['kayako']);

  $sql = "select IFNULL(COUNT(ticketid), 0) as team
            from swtickets t
            left outer join swstaff s on t.ownerstaffid = s.staffid
           where t.isresolved = 0 and t.tickettypetitle not like 'TME %'
             and ((:team = 'DBA' and s.lastname = 'DBA')
              or (:team = 'SYS' and s.lastname = 'System'))";
    
  // mise en cache
  $result = $db->get_scalar($sql, array(':team' => strtoupper($team)));
  if (get_class($cache) == 'Memcached') {
    $cache->set($cached, $result, $auths['kayako']['cached']);
  } else {
    $cache->set($cached, $result, false, $auths['kayako']['cached']);
  }
  
  return $result;
}

function get_centreon_status_by_name($name) {
  global $auths;
  global $cache;
  
  // donnes en cache  
  $result = $cache->get($name);
  if ($result !== false) return $result;
    
  // connexion a la bdd centreon
  $db = new PdoConnexion($auths[$name]);
  
  // requête de l'état des hosts
  $hosts = "0 as unkn,
               sum(case when hs.current_state = 2
                         and hs.problem_has_been_acknowledged = 0 
                         and hs.scheduled_downtime_depth = 0 
                         and hs.notifications_enabled = 1
                   then 1 else 0 end) as warn,
               sum(case when hs.current_state = 1
                         and hs.problem_has_been_acknowledged = 0 
                         and hs.scheduled_downtime_depth = 0 
                         and hs.notifications_enabled = 1
                   then 1 else 0 end) as crit,
               sum(case when hs.problem_has_been_acknowledged = 1
                         and hs.scheduled_downtime_depth = 0
                         and hs.notifications_enabled = 1
                   then 1 else 0 end) as ackn,
               sum(case when hs.scheduled_downtime_depth = 1
                         and hs.notifications_enabled = 1
                   then 1 else 0 end) as down,
               sum(not hs.notifications_enabled) as noti
        FROM nagios_instances i
  LEFT OUTER JOIN nagios_hosts h on h.instance_id = i.instance_id
  LEFT OUTER JOIN nagios_hoststatus hs ON hs.host_object_id = h.host_object_id 
         AND hs.instance_id = i.instance_id
       WHERE hs.current_check_attempt >= (hs.max_check_attempts - 1)";
  
  // requête de l'état des services
  $services = "sum(case when st.current_state = 3 
                         and st.problem_has_been_acknowledged = 0 
                         and st.scheduled_downtime_depth = 0 
                         and st.notifications_enabled = 1
                         and hs.current_state = 0
                   then 1 else 0 end) as unkn,
               sum(case when st.current_state = 1 
                         and st.problem_has_been_acknowledged = 0 
                         and st.scheduled_downtime_depth = 0 
                         and st.notifications_enabled = 1
                         and hs.current_state = 0
                   then 1 else 0 end) as warn,
               sum(case when st.current_state = 2 
                         and st.problem_has_been_acknowledged = 0 
                         and st.scheduled_downtime_depth = 0
                         and st.notifications_enabled = 1
                         and hs.current_state = 0
                   then 1 else 0 end) as crit,
               sum(case when st.problem_has_been_acknowledged = 1
                         and st.scheduled_downtime_depth = 0
                         and st.notifications_enabled = 1
                         and hs.current_state = 0
                   then 1 else 0 end) as ackn,
               sum(case when st.scheduled_downtime_depth = 1
                         and st.notifications_enabled = 1
                         and hs.current_state = 0
                   then 1 else 0 end) as down,
               sum(not st.notifications_enabled) as noti
          FROM nagios_instances i
      LEFT OUTER JOIN nagios_hosts h on h.instance_id = i.instance_id
      LEFT OUTER JOIN nagios_hoststatus hs ON hs.host_object_id = h.host_object_id 
           and hs.instance_id = i.instance_id
      LEFT OUTER JOIN nagios_services s ON h.host_object_id=s.host_object_id 
           and s.instance_id = i.instance_id
      LEFT OUTER JOIN nagios_servicestatus st ON s.service_object_id = st.service_object_id 
           and st.instance_id = i.instance_id
         WHERE st.current_check_attempt >= (st.max_check_attempts - 1)";
    
  switch ($name) {
    case 'centreon_all4it':
      $hosts = "SELECT case when instr(h.display_name, 'VPN') > 0 then 'VPN' else substring_index(h.display_name, '_', 1) end client_alias, $hosts
            GROUP BY case when instr(h.display_name, 'VPN') > 0 then 'VPN' else substring_index(h.display_name, '_', 1) end";
      
      $services = "SELECT case when instr(h.display_name, 'VPN') > 0 then 'VPN' else substring_index(h.display_name, '_', 1) end client_alias, $services
            GROUP BY case when instr(h.display_name, 'VPN') > 0 then 'VPN' else substring_index(h.display_name, '_', 1) end";
      
      
      $sql = "SELECT client_alias,
                     sum(unkn) as unkn, sum(warn) as warn, sum(crit) as crit,
                     sum(down) as down, sum(ackn) as ackn, sum(noti) as noti
                FROM ($hosts union $services) t
               GROUP BY client_alias";
      break;
    case 'centreon_ccml':
      $hosts = "SELECT $hosts";
      $services = "SELECT $services AND s.display_name not like '%Pole_Infra%'";
      $sql = "SELECT sum(unkn) as unkn, sum(warn) as warn, sum(down) as down, 
                     sum(crit) as crit, sum(ackn) as ackn, sum(noti) as noti
                FROM ($hosts union $services) t";
      break;
    default:
      $hosts = "SELECT $hosts";
      $services = "SELECT $services";
      $sql = "SELECT sum(unkn) as unkn, sum(warn) as warn, sum(down) as down, 
                     sum(crit) as crit, sum(ackn) as ackn, sum(noti) as noti
                FROM ($hosts union $services) t";
  }
  
  
  // mise en cache
  $result = $db->get_array($sql);
  if (get_class($cache) == 'Memcached') {
    $cache->set($name, $result, $auths[$name]['cached']);
  } else {
    $cache->set($name, $result, false, $auths[$name]['cached']);
  }
  
  return $result;
}

function get_team_tasks($team) {
  global $auths;
  global $cache;
  
  // donnes en cache  
  $cached = $team . '-tasks';
  $result = $cache->get($cached);
  if ($result !== false) return $result;  
  
  // connexion a la bdd 4control de production
  $db = new PdoConnexion($auths['4control']);

  $sql = "select sum(case when closed then 1 else 0 end) as done,
                 sum(case when not closed and s.user_id is null and 'today' > planned_at::date then 1 else 0 end) as overdue_nobody,
                 sum(case when not closed and s.user_id is not null and 'today' > planned_at::date then 1 else 0 end) as overdue_started,
                 sum(case when not closed and 'now' - planned_at > '4 hours' and 'today' = planned_at::date then 1 else 0 end) as late,
                 sum(case when not closed and 'now' - planned_at < '4 hours' and 'now' > planned_at then 1 else 0 end) as in_time,
                 sum(case when not closed and planned_at > 'now' then 1 else 0 end) as soon
            from schedules s
        left join tasks t on t.id = s.action_id
        left join checklists l on l.id = s.action_id
        left join users u on u.id = s.user_id
           where (planned_at between 'today' and 'tomorrow'
              or (planned_at <= 'today'::date + coalesce(delay, '0') and not closed))
             and is_authorized(coalesce(t.roles, l.roles), :team)";
    
  // mise en cache
  $result = $db->get_single($sql, array(':team' => strtolower($team)));
  if (get_class($cache) == 'Memcached') {
    $cache->set($cached, $result, $auths['4control']['cached']);
  } else {
    $cache->set($cached, $result, false, $auths['4control']['cached']);
  }
  
  return $result;  
}

function get_mantis_issues($name = 'btoc_mantis') {
  global $auths;
  global $cache;
  
  // donnes en cache  
  $result = $cache->get($name);
  if ($result !== false) return $result;
  
  $states = array(
    'new' => '<name xsi:type="xsd:string">Nouveau</name>',
    'assigned' => '<name xsi:type="xsd:string">Affecte</name>',
    'planned' => '<name xsi:type="xsd:string">Planifie</name>',
  );
  
  // Request issues by project
  $wsdl = $auths[$name]['string'];
  $options = array('exceptions' => 0, 'trace' => 1);
  $client = new SoapClient($wsdl, $options);
  
  $response = $client->mc_filter_get_issues(
    $auths[$name]['user'], 
    $auths[$name]['pass'],
    653,     // projet :  IPROD - Application SAP
    13011,   // filtre : A4I_SAP_Monitoring 
    1, 50    // 50 derniers résultats
  );
  $response = $client->__getLastResponse();
  
  // mise en cache
  $result = array();
  foreach ($states as $k => $s) {
    $result[$k] = substr_count($response, $s) ?: 0;
  }
  
  if (get_class($cache) == 'Memcached') {
    $cache->set($name, $result, $auths[$name]['cached']);
  } else {
    $cache->set($name, $result, false, $auths[$name]['cached']);
  }
  
  return $result;
}
<?php
include_once('core/queries.php');
include_once('core/functions.php');

global $auths;
global $cache;

$team = $_GET['team'];
$data = get_kayako_status_by_team($team);

$table = array('cols' => array(), 'rows' => array());
$table['cols'] = array(
  array('label' => 'Department', 'type' => 'string'),
  array('label' => 'Open', 'type' => 'number'),
  array('label' => 'In Progress', 'type' => 'number'),
  array('label' => 'Waiting', 'type' => 'number'),
  array('label' => 'Task in progress', 'type' => 'number'),
  array('label' => 'Waiting Task', 'type' => 'number'),
);

foreach($data as $row) {
  $table['rows'][] = array('c' => array(
    array('v' => $row['department']),
    array('v' => $row['open']),
    array('v' => $row['work']),
    array('v' => $row['wait']),
    array('v' => $row['task'] + $row['taskw']),
  ));
}

echo json_encode($table);
<?php

/*
 * Determine la couleur du fond (background-color)
 * en fonction des seuils définis dans le tableau $rules
 * 
 * les keys correspondent aux intervales [0-n[ où n est la borne supérieure exclue
 */
function get_color_by_type($type, $value) {
  $rules = array(
    // Status Kayako
    'open' => array(0 => 'bg-green', 1 => 'bg-purple'),
    'work' => array(0 => 'bg-green', 1 => 'bg-yellow', 15 => 'bg-red'),
    'wait' => array(0 => 'bg-green', 1 => 'bg-aqua', 20 => 'bg-yellow', 35 => 'bg-red'),
    'over' => array(0 => 'bg-green', 1 => 'bg-gray', 15 => 'bg-yellow', 20 => 'bg->red'),
    'team' => array(0 => 'bg-green', 1 => 'bg-purple'),
    'task' => array(0 => 'bg-lime'),
    'taskw' => array(0 => 'bg-lime'),
    // Status Centreon
    'crit' => array(0 => 'bg-green', 1 => 'bg-red'),
    'warn' => array(0 => 'bg-green', 1 => 'bg-yellow'),
    'unkn' => array(0 => 'bg-green', 1 => 'bg-gray'),
    'ackn' => array(0 => 'bg-green', 1 => 'bg-lime'),
    'down' => array(0 => 'bg-green', 1 => 'bg-aqua'),
    'noti' => array(0 => 'bg-green', 1 => 'bg-orange'),
    // Status Mantis
    'new' => array(0 => 'bg-green', 1 => 'bg-orange', 5 => 'bg-red'),
    'assigned' => array(0 => 'bg-green', 1 => 'bg-yellow', 15 => 'bg-orange'),
    'planned' => array(0 => 'bg-green', 1 => 'bg-lime'),
  );
  
  $rule = $rules[$type];
  krsort($rule);
  list($key, $color) = each($rule);
  do {
    if ($value >= $key) return $color;
  } while (list($key, $color) = each($rule));
  
  return $color;
}

if (!function_exists('array_column')) {
  /**
   * Returns the values from a single column of the input array, identified by
   * the $columnKey.
   *
   * Optionally, you may provide an $indexKey to index the values in the returned
   * array by the values from the $indexKey column in the input array.
   *
   * @param array $input A multi-dimensional array (record set) from which to pull
   *                     a column of values.
   * @param mixed $columnKey The column of values to return. This value may be the
   *                         integer key of the column you wish to retrieve, or it
   *                         may be the string key name for an associative array.
   * @param mixed $indexKey (Optional.) The column to use as the index/keys for
   *                        the returned array. This value may be the integer key
   *                        of the column, or it may be the string key name.
   * @return array
   */
  function array_column($input = null, $columnKey = null, $indexKey = null)
  {
    // Using func_get_args() in order to check for proper number of
    // parameters and trigger errors exactly as the built-in array_column()
    // does in PHP 5.5.
    $argc = func_num_args();
    $params = func_get_args();

    if ($argc < 2) {
      trigger_error("array_column() expects at least 2 parameters, {$argc} given", E_USER_WARNING);
      return null;
    }

    if (!is_array($params[0])) {
      trigger_error(
        'array_column() expects parameter 1 to be array, ' . gettype($params[0]) . ' given',
        E_USER_WARNING
      );
      return null;
    }

    if (!is_int($params[1])
      && !is_float($params[1])
      && !is_string($params[1])
      && $params[1] !== null
      && !(is_object($params[1]) && method_exists($params[1], '__toString'))
    ) {
      trigger_error('array_column(): The column key should be either a string or an integer', E_USER_WARNING);
      return false;
    }

    if (isset($params[2])
      && !is_int($params[2])
      && !is_float($params[2])
      && !is_string($params[2])
      && !(is_object($params[2]) && method_exists($params[2], '__toString'))
    ) {
      trigger_error('array_column(): The index key should be either a string or an integer', E_USER_WARNING);
      return false;
    }

    $paramsInput = $params[0];
    $paramsColumnKey = ($params[1] !== null) ? (string) $params[1] : null;

    $paramsIndexKey = null;
    if (isset($params[2])) {
      if (is_float($params[2]) || is_int($params[2])) {
        $paramsIndexKey = (int) $params[2];
      } else {
        $paramsIndexKey = (string) $params[2];
      }
    }

    $resultArray = array();

    foreach ($paramsInput as $row) {
      $key = $value = null;
      $keySet = $valueSet = false;

      if ($paramsIndexKey !== null && array_key_exists($paramsIndexKey, $row)) {
        $keySet = true;
        $key = (string) $row[$paramsIndexKey];
      }

      if ($paramsColumnKey === null) {
        $valueSet = true;
        $value = $row;
      } elseif (is_array($row) && array_key_exists($paramsColumnKey, $row)) {
        $valueSet = true;
        $value = $row[$paramsColumnKey];
      }

      if ($valueSet) {
        if ($keySet) {
          $resultArray[$key] = $value;
        } else {
          $resultArray[] = $value;
        }
      }
    }

    return $resultArray;
  }

}
google.load('visualization', '1', {'packages':['corechart'], 'language': 'en'});

function Dashboard(selector) {
  var obj = $(selector);
  var alarm_occured_at = null;
  
  function alarm() {
    if (alarm_occured_at > +Date.now() - 6000) return 0;
    
    var soundUrl = $('head').data('sound');
    var sound = new Audio(soundUrl);
    alarm_occured_at = +Date.now();
    sound.play();
  }
  
  function get(cell, options) {
    $.get(options.url, options.params)
    .success(function(data) {
      data = jQuery.parseJSON(data);
      var title = $('<div class="title">'+ data.title +'</div>');
      var content = $('<div class="content '+ data.class +'">'+ data.value +'</div>');
      
      cell.html(content);
      content.css('font-size', content.height() * .6 +'px');      
      content.prepend(title);
      
      if (options.alarm && data.value > 0) {
        alarm();
      }
    })
    .fail(function() {
      get(cell, options);
    });
  }
  
  function draw(cell, options) {
    var container = cell[0];
    var chart = new google.visualization[options.type](container);
    
    $.get(options.url, options.params)
    .done(function(response) {
      var data = new google.visualization.DataTable(response);
      chart.draw(data, $.extend(options.style, {
        fontSize: 18,
        enableInteractivity: false
      }));
    });
  }
  
  this.init = function init(options) {
    obj.append(Array(options.length + 1).join('<div class="row"></div>'));
    obj.find('.row').each(function(i) {
      $(this).css('height', 100 / options.length + '%');
      for (var j in options[i]) {
        if (typeof options[i][j] != "object") {
          $(this).append(
            '<div class="cell ' + options[i][j] + '" data-coord="' + i + ',' + j + '"></div>'
          );
        } else {        
          var innerOptions = options[i][j];
          var innerClass = Object.keys(innerOptions)[0];
          innerOptions = innerOptions[innerClass];
          
          var cell = $('<div class="cell ' + innerClass + '" data-coord="' + i + ',' + j + '"></div>')
          
          $(cell).append(Array(innerOptions.length + 1).join('<div class="row"></div>'));
          $(cell).find('.row').each(function(x) {
            $(this).css('height', 100 / options.length + '%');
            for (var y in innerOptions[x]) {
              $(this).append(
                '<div class="inner cell ' + innerOptions[x][y] + '" data-coord="' + i + ',' + j + ',' + x + ',' + y + '"></div>'
              );
            }
          });
          $(this).append(cell);
        }
      }
    });
  },
  
  this.fill = function fill(options) {
    var coord = options.cell.join(',');
    var cell = obj.find('.cell[data-coord="' + coord + '"]');
    get(cell, options);
  }
  
  this.graph = function graph(options) {
    var coord = options.cell.join(',');
    var cell = obj.find('.cell[data-coord="' + coord + '"]');  
    draw(cell, options);
  }
  
  this.image = function image(options) {
    var coord = options.cell.join(',');
    var cell = obj.find('.cell[data-coord="' + coord + '"]');    
    var content = $('<div class="content"><img src="'+ options.src +'"/></div>');
    cell.html(content);
  }
  
  this.special = function special(options) {
    var coord = options.cell.join(',');
    var cell = obj.find('.cell[data-coord="' + coord + '"]');
    
    var name = 'bonjourmadame';
    name = 'bonjourlechat';
    
    var key = 'fuiKNFp9vQFvjLNvx4sUwti4Yb5yGutBN4Xh10LXZhhRKjWlV4';
    var url = 'http://api.tumblr.com/v2/blog/' + name + '.tumblr.com/posts/photo?api_key=' + key;
    $.ajax({
      url: url, dataType: "jsonp", async: false,
      success: function(data) {
        var posts = data.response.posts;
        var item = posts[Math.floor(Math.random()*posts.length)].photos[0].alt_sizes[2];
        var content = $('<div class="content"><img src="'+ item.url +'"/></div>');
        cell.html(content);
      }
    });
  }
}
<?php

class PdoConnexion {
  protected $conn;
  
  public function __construct($auth) {
    try {
      $this->conn = new PDO(
        $auth['string'], $auth['user'], $auth['pass']
      );
      if ( !$this->conn->inTransaction())
        $this->conn->beginTransaction();
    } catch (PDOException $e) {
      $error = htmlentities($e->getMessage(), ENT_QUOTES);
      throw new Exception($error, 500);
    }
  }
  
  public function __destruct() {
    self::commit();
    $this->conn = null;
  }
  
  // return $bool
  public function execute_dml($sql, array $binds = array()) {
    $statement = $this->conn->prepare($sql);
    $result = $statement->execute($binds);
    
    if ($result ==! true) {
      $err = $statement->errorInfo();
      print "<pre>${err[2]}<br /><br /><code>${sql}</code></pre>";
    }
    
    $this->last_id = $statement->fetchColumn();    
    $statement->closeCursor();
    return $result;
  }
  
  // return two-dimensional $array
  public function get_array($sql, array $binds = array()) {
    $statement = $this->conn->prepare($sql);
    $result = $statement->execute($binds);    
		
    if ($result ==! true) {
      $err = $statement->errorInfo();
      print "<pre>${err[2]}<br /><br /><code>${sql}</code></pre>";
    } else {
      $result = $statement->fetchAll(PDO::FETCH_ASSOC);
    }
    
    $statement->closeCursor();
    return $result;
  }
  
  // return the first row of result
  public function get_single($sql, array $binds = array()) {
    $result = self::get_array($sql, $binds);
    
    return array_shift($result);
  }
  
  // return only column group of array
  public function get_column($sql, $column, array $binds = array()) {
    $result = self::get_array($sql, $binds);
    
    return array_column($result, $column);
  }
  
  // return the first column of row
  public function get_scalar($sql, array $binds = array()) {
    $result = self::get_single($sql, $binds);    
    if ($result === null) return null;
    
    return array_shift($result);
  }
  
  public function commit() {
    if ( !empty($classes)) {
      foreach($this->classes as $class) {
        if ($class->conn->inTransaction())
          $class->commit();
      }
    }
    if ($this->conn->inTransaction())
    $this->conn->commit();
  }
  
  public function rollback() {
    if ( !empty($classes)) {
      foreach($this->classes as $class) {
        if ($class->conn->inTransaction())
          $class->rollback();
      }
    }
    if ($this->conn->inTransaction())
      $this->conn->rollBack();
  }
}
<?php
include_once('core/queries.php');
include_once('core/functions.php');

$what = $_GET['what'];
$title = $_GET['title'];
$team = $_GET['team'];

$data = get_kayako_status_by_team($team);
if ( ! is_array($data)) http_response_code(500);

$result = array_sum(array_column($data, $what));

echo json_encode(array(
  'title' => $title,
  'value' => $result,
  'class' => get_color_by_type($what, $result)
));
<!DOCTYPE html>
<html>
<head data-sound="res/warn.ogg">
  <meta http-equiv="refresh" content="300">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
  <link rel="stylesheet" href="res/style.css">
  <script src="https://www.google.com/jsapi"></script>
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  <script src="res/classes.js"></script>
</head>
<body>
  <div class="dashboard"></div>
  <script>
    var team = location.hash.slice(1);
    var dashboard = new Dashboard('.dashboard');
    dashboard.init([
      ['col-xs-5', {'col-xs-1': [['col-xs-12'], ['col-xs-12']]}, {'col-xs-1': [['col-xs-12'], ['col-xs-12']]}, 'col-xs-5'],
      [{ 'col-xs-6': [['col-xs-4', 'col-xs-4', 'col-xs-4'], ['col-xs-4', 'col-xs-4', 'col-xs-4']] }, 'col-xs-6']
    ]);
        
    // 4Control tasks progression
    dashboard.graph({
      cell: [0, 3], params: { team: team },
      type: 'PieChart', url: 'server/4control_graph.php',
      style: {
        title: '4Control Tasks - ' + team.toUpperCase() + ' Team',
        pieSliceText: 'none', pieHole: 0.4,
        legend: {position: 'labeled'},
        slices: {
          0: {color: '#FF4136'}, // overdue nobody
          1: {color: '#FF851B'}, // overdue started
          2: {color: '#FFDC00'}, // late
          3: {color: '#7FDBFF'}, // in time
          4: {color: '#ADCF4F'}, // done
          5: {color: '#DDDDDD'}  // soon
        }
      }
    });
    
    // Kayako status
    dashboard.graph({
      cell: [0, 0], params: { team: team },
      type: 'ColumnChart', url: 'server/kayako_graph.php',
      style: {
        title: 'Kayako - ' + team.toUpperCase() + ' Team',
        isStacked: true,
        legend: {position: 'none'},
        hAxis: {viewWindow: {min: 0}},
        series: [{color: '#9C61FA'}, {color: '#FFDC00'}, {color: '#7FDBFF'}, {color: '#ADCF4F'}]
      }
    });
    dashboard.fill({
      cell: [0, 1, 0, 0], 
      url: 'server/kayako_status.php', params: {
        title: 'Overdue', what: 'over', team: team
      }
    });
    dashboard.fill({
      cell: [0, 1, 1, 0], 
      url: 'server/kayako_team_tickets.php', params: {
        title: 'Team', team: team
      }
    });
    dashboard.fill({
      cell: [0, 2, 0, 0], 
      url: 'server/kayako_status.php', params: {
        title: 'Tasks', what: 'task', team: team
      }
    });
    dashboard.fill({
      cell: [0, 2, 1, 0], 
      url: 'server/kayako_status.php', params: {
        title: 'Hold', what: 'taskw', team: team
      }
    });
    
    // Centreon status
    dashboard.fill({
      cell: [1, 0, 0, 0], alarm: true,
      url: 'server/centreon_status.php', params: {
        title: 'Critical', what: 'crit'
      }
    });
    dashboard.fill({
      cell: [1, 0, 0, 1], 
      url: 'server/centreon_status.php', params: {
        title: 'Warning', what: 'warn'
      }
    });
    dashboard.fill({
      cell: [1, 0, 0, 2], 
      url: 'server/centreon_status.php', params: {
        title: 'Unknown', what: 'unkn'
      }
    });
    dashboard.fill({
      cell: [1, 0, 1, 0], 
      url: 'server/centreon_status.php', params: {
        title: 'Acknowledged', what: 'ackn'
      }
    });
    dashboard.fill({
      cell: [1, 0, 1, 1], 
      url: 'server/centreon_status.php', params: {
        title: 'Downtimed', what: 'down'
      }
    });
    dashboard.fill({
      cell: [1, 0, 1, 2], 
      url: 'server/centreon_status.php', params: {
        title: 'Disabled', what: 'noti'
      }
    });
    dashboard.graph({
      cell: [1, 1], 
      type: 'BarChart', url: 'server/centreon_graph.php',
      style: {
        title: 'Centreon Global View',
        isStacked: true,
        bar: {groupWidth: '90%'},
        legend: {position: 'none'},
        vAxis: {textPosition: 'in'},
        hAxis: {viewWindow: {min: 0}},
        series: [{color: '#FF4136'}, {color: '#FFDC00'}, {color: '#DDDDDD'}, {color: '#ADCF4F'}, {color: '#7FDBFF'}, {color: '#FF851B'}]
      }
    });
  </script>
</body>  
</html>