Trying to implement a PHP Gantt chart

I have been asked by my work to make a web based gantt chart.
I found an open source php gantt (because my php is very basic) called Mahatma Gantti but I am having trouble configuring it.

[code]<?php
$con=mysqli_connect(“localhost”,“root”,"",“db”);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$result = mysqli_query($con,“SELECT * FROM table”);

while($row = mysqli_fetch_array($result))
{
$data[] = array(
‘label’ => $row[‘jobref’],
‘start’ => ‘2014/04/20’,
‘end’ => ‘2014/05/10’
);
}

mysqli_close($con);

?>[/code]

The above code works and pulls all my jobrefs into the gantt chart but makes them set to those 2 dates.
I have tired changing the dates to a start date and end date that I have in my database by doing the following, but i get a blank page. Im sure im doing something stupid.

[code]<?php
$con=mysqli_connect(“localhost”,“root”,"",“db”);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}

$result = mysqli_query($con,“SELECT * FROM table”);

while($row = mysqli_fetch_array($result))
{
$data[] = array(
‘label’ => $row[‘jobref’],
‘start’ => $row[‘start_date’],
‘end’ => $row[‘end_date’]’
);
}

mysqli_close($con);

?>[/code]

You did not specify in your query what the start and end date is.

WHERE start_date= AND end_date=

There is no set start and end date, it is taking them from the database just like the jobref.
So I dont want them to be a specific start and end date, only pull it from the database.

I meant to say thanks to you for the previous problem I had, your solution worked great :slight_smile:

If I set the code to
[php]$result = mysqli_query($con,“SELECT * FROM outworkers WHERE start_date=‘2014-02-14’ AND end_date=‘2014-02-25’”);

while($row = mysqli_fetch_array($result))
{
$data[] = array(
‘label’ => $row[‘jobref’],
‘start’ => $row[‘start_date’],
‘end’ => $row[‘end_date’]
);
}[/php]

I get just that 1 resault:

If I set it to:
[php]$result = mysqli_query($con,"SELECT * FROM outworkers ");

while($row = mysqli_fetch_array($result))
{
$data[] = array(
‘label’ => $row[‘jobref’],
‘start’ => ‘2014/04/20’,
‘end’ => ‘2014/05/10’
);
}
[/php]

I get all my jobref’s but obv it gives them all that date range.

And my original code brings up a blank page. How do I get it to show each job ref with its own start/end date? Is this possible. Thanks for your help anyways its much appreciated.

Post your database schema with a few sample records.(The sql to recreate your tables with data). You didn’t tell me the format the dates are stored in. (I will see from your schema though.)

[code]CREATE TABLE IF NOT EXISTS outworkers (
id int(11) NOT NULL AUTO_INCREMENT,
jobref varchar(20) NOT NULL,
client varchar(20) NOT NULL,
site varchar(40) NOT NULL,
Job_description varchar(40) NOT NULL,
start_date date NOT NULL,
end_date date NOT NULL,
duration varchar(20) NOT NULL,
machines varchar(50) NOT NULL,
technicians varchar(30) NOT NULL,
Data1 varchar(20) NOT NULL,
Data2 varchar(20) NOT NULL,
Data3 varchar(20) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=54 ;


– Dumping data for table outworkers

INSERT INTO outworkers (id, jobref, client, site, Job_description, start_date, end_date, duration, machines, technicians, Data1, Data2, Data3) VALUES
(36, ‘S13173’, ‘Company 1’, ‘Malaysia’, ‘Inspection/Machining’, ‘2014-02-14’, ‘2014-02-25’, ‘7 Days’, ‘F100’, ‘Phil, Mike’, ‘’, ‘’, ‘’),
(37, ‘S13136’, ‘Company 2’, ‘Borne, Holland’, ‘Seal Seat Machining’, ‘2014-03-02’, ‘2014-03-08’, ‘6 Days’, ‘F30, F8’, ‘Brad, Tim’, ‘’, ‘’, ‘’);[/code]

Sorry for the slow reply.

From the default unmodified files delete everything in data.php and replace with the following code. Change the database connection settings to your setup.

  • On a side not for those reading this: This is a perfect example of how quickly and easily we can get you an answer to your database problems if you post your table SQL with sample records.

data.php
[php]<?php
$data = array();
try
{
try
{
$dbhost = ‘localhost’;
$dbname = ‘workers’;
$dbuser = ‘root’;
$dbpass = ‘’;
$pdo = new PDO(“mysql:host=$dbhost; dbname=$dbname”, $dbuser, $dbpass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
die("<span style=“color:red”>

ERROR: No Database Connection

");
}
$sql  = "SELECT * FROM outworkers";
$stmt = $pdo->prepare($sql);
$stmt->execute();

$result = $stmt->fetchAll();

if (count($result))
    {
    foreach ($result as $row)
        {            
        $data[] = array(
            'label' => $row['client'],
            'start' => $row['start_date'],
            'end' => $row['end_date'],
            'class' => 'urgent'
        );
        }
    }
else
    {
    echo "No rows returned.";
    }
}

catch (PDOException $e)
{
die($e);
}
?>[/php]

Unfortunately when I replace the old data.php with your above code it just returns a blank page.
There is no source code I can see.

Did you set the database credentials and table name to match your setup? If you can provide a temporary login I can check it where it sits.

It runs perfectly for me with the DB sql you gave me.

Its something to do with my webserver. I replicated the site onto my machine and added you changes and it worked perfectly.

So all I need to do now is work out why it wont work on my webserver.
(I unfortunately cannot set up a temp login as the site is running on the internal network with no external access.

Webserver is displaying this error:

[24-Feb-2014 15:46:09 GMT] PHP Fatal error: Call to a member function month() on a non-object in C:\inetpub\wwwroot\gantt\lib\gantti.php on line 58

which is:
[php] $current = $this->first->month();[/php]
[php]function parse() {

foreach($this->data as $d) {
          
  $this->blocks[] = array(
    'label' => $d['label'],
    'start' => $start = strtotime($d['start']),
    'end'   => $end   = strtotime($d['end']),
    'class' => @$d['class']
  );
  
  if(!$this->first || $this->first > $start) $this->first = $start;
  if(!$this->last  || $this->last  < $end)   $this->last  = $end;
      
}

$this->first = $this->cal->date($this->first);
$this->last  = $this->cal->date($this->last);

$current = $this->first->month();
$lastDay = $this->last->month()->lastDay()->timestamp;[/php]

The exact same database and site works fine on my local machine.
The php on the webserver is PHP Version 5.4.14 and its running off IIS7.
Local machine is using XAMPP

Hard to troubleshoot in bits and pieces. Post your entire data.php and the index.php

/index.php
[php]<?php

require(‘lib/gantti.php’);
require(‘data.php’);

date_default_timezone_set(‘GMT’);
setlocale(LC_ALL, ‘en_UK’);

$gantti = new Gantti($data, array(
‘title’ => ‘Destec’,
‘cellwidth’ => 25,
‘cellheight’ => 35,
‘today’ => true
));

?>

Destec Outworkers Gantt Chart <?php echo $gantti ?> [/php]

/Data.php
[php]<?php
$data = array();
try
{
try
{
$dbhost = ‘localhost’;
$dbname = ‘dbname’;
$dbuser = ‘root’;
$dbpass = ‘’;
$pdo = new PDO(“mysql:host=$dbhost; dbname=$dbname”, $dbuser, $dbpass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
die("<span style=“color:red”>

ERROR: No Database Connection

");
}
 $sql  = "SELECT * FROM outworkers";
 $stmt = $pdo->prepare($sql);
 $stmt->execute();
 
 $result = $stmt->fetchAll();
 
 if (count($result))
     {
     foreach ($result as $row)
         {
         
         $data[] = array(
             'label' => $row['client'],
             'start' => $row['start_date'],
             'end' => $row['end_date'],
             'class' => 'urgent'
         );
         }
     }
 else
     {
     echo "No rows returned.";
     }
 }

catch (PDOException $e)
{
die($e);
}
?>[/php]

/lib/gantt.php
[php]<?php

require(‘calendar.php’);

class Gantti {

var $cal = null;
var $data = array();
var $first = false;
var $last = false;
var $options = array();
var $cellstyle = false;
var $blocks = array();
var $months = array();
var $days = array();
var $seconds = 0;

function __construct($data, $params=array()) {

$defaults = array(
  'title'      => false,
  'cellwidth'  => 40,
  'cellheight' => 40,
  'today'      => true,
);
    
$this->options = array_merge($defaults, $params);    
$this->cal     = new Calendar();
$this->data    = $data;
$this->seconds = 60*60*24;

$this->cellstyle = 'style="width: ' . $this->options['cellwidth'] . 'px; height: ' . $this->options['cellheight'] . 'px"';

// parse data and find first and last date  
$this->parse();                

}

function parse() {

foreach($this->data as $d) {
          
  $this->blocks[] = array(
    'label' => $d['label'],
    'start' => $start = strtotime($d['start']),
    'end'   => $end   = strtotime($d['end']),
    'class' => @$d['class']
  );
  
  if(!$this->first || $this->first > $start) $this->first = $start;
  if(!$this->last  || $this->last  < $end)   $this->last  = $end;
      
}

$this->first = $this->cal->date($this->first);
$this->last  = $this->cal->date($this->last);

$current = $this->first->month();
$lastDay = $this->last->month()->lastDay()->timestamp;

// build the months      
while($current->lastDay()->timestamp <= $lastDay) {
  $month = $current->month();
  $this->months[] = $month;
  foreach($month->days() as $day) {
    $this->days[] = $day;
  }
  $current = $current->next();
}

}

function render() {

$html = array();

// common styles    
$cellstyle  = 'style="line-height: ' . $this->options['cellheight'] . 'px; height: ' . $this->options['cellheight'] . 'px"';
$wrapstyle  = 'style="width: ' . $this->options['cellwidth'] . 'px"';
$totalstyle = 'style="width: ' . (count($this->days)*$this->options['cellwidth']) . 'px"';
// start the diagram    
$html[] = '<figure class="gantt">';    

// set a title if available
if($this->options['title']) {
  $html[] = '<figcaption>' . $this->options['title'] . '</figcaption>';
}

// sidebar with labels
$html[] = '<aside>';
$html[] = '<ul class="gantt-labels" style="margin-top: ' . (($this->options['cellheight']*2)+1) . 'px">';
foreach($this->blocks as $i => $block) {
  $html[] = '<li class="gantt-label"><strong ' . $cellstyle . '>' . $block['label'] . '</strong></li>';      
}
$html[] = '</ul>';
$html[] = '</aside>';

// data section
$html[] = '<section class="gantt-data">';
    
// data header section
$html[] = '<header>';

// months headers
$html[] = '<ul class="gantt-months" ' . $totalstyle . '>';
foreach($this->months as $month) {
  $html[] = '<li class="gantt-month" style="width: ' . ($this->options['cellwidth'] * $month->countDays()) . 'px"><strong ' . $cellstyle . '>' . $month->name() . '</strong></li>';
}                      
$html[] = '</ul>';    

// days headers
$html[] = '<ul class="gantt-days" ' . $totalstyle . '>';
foreach($this->days as $day) {

  $weekend = ($day->isWeekend()) ? ' weekend' : '';
  $today   = ($day->isToday())   ? ' today' : '';

  $html[] = '<li class="gantt-day' . $weekend . $today . '" ' . $wrapstyle . '><span ' . $cellstyle . '>' . $day->padded() . '</span></li>';
}                      
$html[] = '</ul>';    

// end header
$html[] = '</header>';

// main items
$html[] = '<ul class="gantt-items" ' . $totalstyle . '>';
    
foreach($this->blocks as $i => $block) {
  
  $html[] = '<li class="gantt-item">';
  
  // days
  $html[] = '<ul class="gantt-days">';
  foreach($this->days as $day) {

    $weekend = ($day->isWeekend()) ? ' weekend' : '';
    $today   = ($day->isToday())   ? ' today' : '';

    $html[] = '<li class="gantt-day' . $weekend . $today . '" ' . $wrapstyle . '><span ' . $cellstyle . '>' . $day . '</span></li>';
  }                      
  $html[] = '</ul>';    

  // the block
  $days   = (($block['end'] - $block['start']) / $this->seconds);
  $offset = (($block['start'] - $this->first->month()->timestamp) / $this->seconds);
  $top    = round($i * ($this->options['cellheight'] + 1));
  $left   = round($offset * $this->options['cellwidth']);
  $width  = round($days * $this->options['cellwidth'] - 9);
  $height = round($this->options['cellheight']-8);
  $class  = ($block['class']) ? ' ' . $block['class'] : '';
  $html[] = '<span class="gantt-block' . $class . '" style="left: ' . $left . 'px; width: ' . $width . 'px; height: ' . $height . 'px"><strong class="gantt-block-label">' . $days . '</strong></span>';
  $html[] = '</li>';

}

$html[] = '</ul>';    

if($this->options['today']) {

  // today
  $today  = $this->cal->today();
  $offset = (($today->timestamp - $this->first->month()->timestamp) / $this->seconds); 
  $left   = round($offset * $this->options['cellwidth']) + round(($this->options['cellwidth'] / 2) - 1);
      
  if($today->timestamp > $this->first->month()->firstDay()->timestamp && $today->timestamp < $this->last->month()->lastDay()->timestamp) {
    $html[] = '<time style="top: ' . ($this->options['cellheight'] * 2) . 'px; left: ' . $left . 'px" datetime="' . $today->format('Y-m-d') . '">Today</time>';
  }

}

// end data section
$html[] = '</section>';    

// end diagram
$html[] = '</figure>';

return implode('', $html);

}

function __toString() {
return $this->render();
}

}
[/php]

But as with you, when I try it on a local machine it works as expected. Must be some server side thing im missing.

I have not included the code for calender.php

I am confused. You said

when I try it on a local machine it works as expected

So what/where is the problem? I used the files you posted and it still works.

All the above code came from the web server which when I run index.php I get a blank page.
When I check the php error log I get the following line:
[24-Feb-2014 16:22:28 GMT] PHP Fatal error: Call to a member function month() on a non-object in C:\inetpub\wwwroot\gantt\lib\gantti.php on line 58

The web server is running IIS7, php 5.4.14 on windows server 2008.

If I copy all the code and database and run it from my local machine using XAMPP I get no errors and it works fine.

So I am assuming there is something not quite right with my webserver for it not to be showing anything.

If you have no idea what I could be thats fine and I am very grateful for the help you have given me.
You code works great, just my stupid server messing something up.

OK, I know whats wrong. Run this code.
[php]<?php
$str = ‘TWljcm9zb2Z0IGFuZCBXaW5kb3dzIFNlcnZlciBTVUNLUyEgVXNlIExpbnV4Lg==’;
echo base64_decode($str);
?>[/php]

Ha, unexpected but still amusing.

I do agree with you though, I will look at making a virtual Linux web server and porting my system over to that.

Give Zend Server Community Edition a shot. Hassle free install. Never any server issues.

https://www.zend.com/en/products/server/downloads

Sponsor our Newsletter | Privacy Policy | Terms of Service