[ PHPXref.com ] [ Generated: Sun Jul 20 20:47:44 2008 ] [ TUTOS 1.2 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/php/ -> task.pinc (source)

   1  <?php
   2  /**
   3   * Copyright 1999 - 2004 by Gero Kohnert
   4   *
   5   *  CVS Info:  $Id: task.pinc,v 1.150.2.8 2005/03/21 11:29:09 gokohnert Exp $
   6   *  $Author: gokohnert $
   7   *
   8   */
   9  
  10  # include_once 'file/file.pinc'; // never load modules directly
  11   
  12  define ('TASK_PRE',0);
  13  define ('TASK_RUNNING',1);
  14  define ('TASK_FINISH',2);
  15  define ('TASK_OVERDUE',3);
  16  
  17  function gantt_get_bar(&$task, $n, $depth) {
  18    global $tutos,$font;
  19  
  20    $over = false;
  21    $name    = $task->name;
  22    $start   = $task->s_start->getYYYYMMDD();
  23    $end     = $task->s_end->getYYYYMMDD();
  24    $vol     = $task->volume_done;  #not used in coding, I guess...
  25    $planned = $task->volume;
  26    $todo    = $task->volume_todo;
  27    $comp    = $task->getcompletion();
  28    $worker  = $task->worker;
  29  
  30    for ($i = 1; $i < $depth; $i++) {
  31      $name = "  ". $name;
  32    }
  33    $name .= " [";
  34    $sep = "";
  35    foreach ( $worker as $w => $f) {
  36      $name .= $sep . $f->GetFullname();
  37      $sep = ", ";
  38    }
  39    $name .= "]";
  40    
  41    #----workaround for presentation
  42    #if ( $todo == -1 ) {
  43    #  $todo = "100 %";
  44    #} else {
  45    #  $todo = hour_format($todo,2);
  46    #}
  47    #-------------------------------
  48    
  49    if ($tutos[jpgraph_old] == 0) {
  50      $xx = array($name, hour_format($planned,2), $task->s_start->getDate(), $task->s_end->getDate());
  51    } else {
  52      $xx = $name;
  53    }
  54    if ( $comp > 100.0 ) {
  55      $over = true;
  56    }
  57    if ($task->milestone == 1) {
  58      $bar = new MileStone($n, $xx, $end,sprintf("[%.0f %%]", $comp), 0.5);
  59    } else {
  60      $bar = new GanttBar($n, $xx, $start, $end,sprintf("[%.0f %%]", $comp), 0.5);
  61      if ( $over ) {
  62        $bar->progress->Set(1);
  63        $bar->SetColor("red");
  64        $bar->SetPattern(BAND_RDIAG, "red");
  65        $bar->progress->SetPattern(BAND_RDIAG, "red"); 
  66      } else {
  67        $bar->progress->Set($comp/100.0);
  68      }
  69    }
  70    if ($tutos[jpgraph_old] == 0) {
  71      $bar->SetCSIMTarget(addSessionKey($task->getUrl()),myentities($task->getFullName()));
  72    }
  73    /* Outline first level tasks */
  74    $bar->title->SetFont($font, FS_NORMAL, 8); 
  75    if( $depth == 1 ) {
  76      $bar->title->SetFont($font, FS_BOLD, 8);
  77    }
  78    return $bar;
  79  }
  80  
  81  /* Recursive adding of project tasks */
  82  function gantt_addTasks(&$parent, &$graph, &$count, $depth) {
  83    if ( $parent->getType() == "task" ) {
  84      $graph->Add(gantt_get_bar($parent, $count++, $depth));
  85    }
  86  
  87    $parent->readTasks();
  88    foreach($parent->tasklist as $i => $f) {
  89      $graph = gantt_addTasks($f, $graph, $count, $depth+1);
  90    }
  91    return $graph;
  92  }
  93  
  94  Function gantt_draw(&$parent) {
  95    global $lang , $font, $tutos;
  96  
  97    #
  98    # If we use a non western laguage encoding force the use of truetype fonts
  99    #
 100    if ($lang['content_encoding'] != "iso-8859-1") {
 101      $font = FF_ARIAL;
 102    } else {
 103      $font = FF_FONT1;
 104    }
 105    # ugly fix
 106    $font = FF_FONT1;
 107  
 108    task_calc($parent);
 109  
 110    // Standard calls to create a new graph
 111    $graph = new GanttGraph();
 112    //$graph->SetShadow();
 113    $graph->SetBox();
 114    // Titles for chart
 115    $graph->title->Set($lang['TaskGantt']." ". $lang['forphrase'] ." " .
 116               html_entity_decode($parent->getFullName()) );
 117  
 118    $graph->title->SetFont($font,FS_BOLD,12);
 119  
 120    // For illustration we enable all headers. 
 121    $graph->ShowHeaders(GANTT_HMONTH | GANTT_HDAY | GANTT_HWEEK);
 122  
 123    $graph->scale->week->SetStyle(WEEKSTYLE_FIRSTDAY);
 124    $graph->scale->month->SetStyle(MONTHSTYLE_LONGNAMEYEAR4);
 125    if (isset($graph->scale->actinfo)) {
 126      $graph->scale->actinfo->SetFont($font, FS_NORMAL, 8);
 127      $graph->scale->actinfo->SetColTitles(array($lang['Task'] ." [". $lang['TaskWorker'] ."]",$lang['TaskVolumeFull'],$lang['TaskS_Start'],$lang['TaskS_End']));
 128    }
 129    /* TODO: we could use locale */
 130    // $graph->scale->SetDateLocale("fr_FR");
 131  
 132    // Change the scale font 
 133    $graph->scale->week->SetFont(FF_FONT0);
 134    $graph->scale->year->SetFont($font,FS_BOLD,12);
 135  
 136    $count = 0;
 137    
 138    $graph = gantt_addTasks($parent, $graph, $count, 0);
 139    
 140    // Add a vertical line for the current day
 141  #  $vline = new GanttVLine(strftime("%Y-%m-%d", time()));
 142  #  $vline->SetDayOffset(0.5);
 143  #  $graph->Add($vline);
 144    if ($tutos[jpgraph_old] == 0) {
 145      $graph->StrokeCSIM('gantt_png.php');
 146    } else {
 147      $graph->Stroke();
 148    }
 149  }
 150  
 151  /* ---------------------------------------------------------------------------
 152   * get the latest and earliest datetimes
 153   */
 154  function task_calc (&$obj) {
 155    task::obj_read($obj);
 156  
 157    if ( ($obj->getType() == "address")||($obj->getType() == "team") ) {
 158      $recursive = false;
 159    } else {
 160      $recursive = true;
 161    }
 162  
 163    $obj->max_end     = new DateTime(0);
 164    $obj->min_start   = new DateTime(0);
 165    $obj->sum['volume'] = 0.0;
 166    $obj->sum['volume_done'] = 0.0;
 167    if ( $obj->getType() == "task") {
 168      $obj->max_end->setDateTimeTS($obj->s_end->ts);
 169      $obj->min_start->setDateTimeTS($obj->s_start->ts);
 170      $obj->sum['volume'] = $obj->volume;
 171      $obj->sum['volume_done'] = $obj->volume_done;
 172    }
 173  
 174    if ( count($obj->tasklist) > 0 ) {
 175      foreach ($obj->tasklist as $i => $f) {
 176        if ( $recursive ) {
 177          task_calc($f);
 178          $min = $f->min_start->ts;
 179          $max = $f->max_end->ts;
 180        } else {
 181          $min = $f->s_start->ts;
 182          $max = $f->s_end->ts;
 183          $f->sum['volume'] = $f->volume;
 184          $f->sum['volume_done'] = $f->volume_done;
 185        }
 186  
 187        // For address, we have to only count the work done by $obj...
 188        if( $obj->getType() == "address" ) {
 189          if( $obj->creator->id == $obj->id
 190              || array_key_exists((int)$obj->id, $f->worker) ) {
 191            $obj->sum['volume'] += $f->sum['volume'];
 192            $obj->sum['volume_done'] += computeWorkedHours($obj, $f);
 193          }
 194        } else {
 195          $obj->sum['volume'] += $f->sum['volume'];
 196          $obj->sum['volume_done'] += $f->sum['volume_done'];
 197        }
 198        if ( ($min != -1) ) {
 199          if ( ($obj->min_start->ts != -1) ) {
 200            $obj->min_start->setDateTimeTS(min($min,$obj->min_start->ts));
 201          } else {
 202            $obj->min_start->setDateTimeTS($min);
 203          }
 204        }
 205        if ( ($max != -1) ) {
 206          if ( ($obj->max_end->ts != -1) ) {
 207            $obj->max_end->setDateTimeTS(max($max,$obj->max_end->ts));
 208          } else {
 209            $obj->max_end->setDateTimeTS($max);
 210          }
 211        }
 212      }
 213    }
 214  }
 215  
 216  function tasks_clone_recursive( $tasklist, $newpid, $owner, $diff ) {
 217    global $tutos;
 218    foreach ($tasklist as $t) {
 219      $oldid  = $t->id;
 220      $oldacl = $t->acl;
 221      $t->readTasks();
 222      $t->id = -1;
 223      $t->p_id = $newpid;
 224  
 225      # add time diff to make dates relative to project's beginning
 226      $t->s_start->addDays($diff);
 227      $t->s_end->addDays($diff);
 228  
 229      # real dates are not welcome
 230      $t->r_start->setNoTime();
 231      $t->r_end->setNoTime();
 232      
 233      $t->save();
 234      # set previous permissions and raise for current user
 235      $t->acl = $oldacl;
 236      acl_save($t);
 237  
 238      $t->modified = array ();
 239      $t->modified[] = array ( "field" => "CloneEntry" ,
 240                                "old" => $oldid ,
 241                                "new" => $t->id,
 242                                "obj_id" => $nf->id
 243                              );
 244      history_save($t);
 245  
 246      if (function_exists('files_clone')) {
 247        files_clone( $t->dbconn, $oldid, $t->id, $owner );
 248      }
 249      tasks_clone_recursive( $t->tasklist, $t->id, $owner, $diff );
 250    }
 251  }
 252  
 253  /**
 254   * a task (something ToDo)
 255   *
 256   * @modulegroup task
 257   * @module task
 258   * @package task
 259   */
 260  class task extends tutos_base {
 261    /* ---------------------------------------------------------------------------
 262     */
 263    function task(&$dbconn) {
 264      global $current_user,$table;
 265  
 266      $this->init($dbconn);
 267  
 268      $this->p_id        = -1;
 269      $this->parent      = -1;
 270      $this->plist       = array();
 271      $this->name        = "";
 272      $this->desc        = "";
 273      $this->volume      = 0;
 274      $this->volume_done = 0;
 275      $this->volume_todo = -1;
 276      $this->worker      = array();
 277      $this->s_start     = new DateTime();
 278      $this->s_end       = new DateTime();
 279      $this->r_start     = new DateTime(0);
 280      $this->r_end       = new DateTime(0);
 281      $this->state       = TASK_PRE;
 282      $this->diff        = 0;
 283      $this->milestone   = 0;
 284      $this->email       = 0;
 285  
 286      $this->tablename   = $this->dbconn->prefix .$table['task'][name];
 287      $this->tablename2  = $this->dbconn->prefix .$table['taskworker'][name];
 288    }
 289      
 290    function exportXML_body ($only_ids = false) {
 291      global $lang;
 292      
 293      $r = parent::exportXML_body();
 294      if (!$only_ids) {
 295      $r .=  "<name>". utf8_encode(htmlspecialchars($this->name)) ."</name>\n";
 296      $r .=  "<desc>". utf8_encode(htmlspecialchars($this->desc)) ."</desc>\n";
 297      $r .=  "<p_id>". $this->p_id ."</p_id>\n";
 298      $r .=  "<volume>". $this->volume ."</volume>\n";
 299      $r .=  "<volume_done>". $this->volume_done ."</volume_done>\n";
 300      $r .=  "<volume_todo>". $this->volume_todo ."</volume_todo>\n";
 301      $r .=  "<state_id>". $this->state ."</state_id>\n";
 302      $r .=  "<state>". utf8_encode(htmlspecialchars($lang['TaskStates'][$this->state])) ."</state>\n";
 303      $r .=  "<milestone>". $this->milestone ."</milestone>\n";
 304      $r .=  "<email>". $this->email ."</email>\n";
 305      if ( $this->s_start->notime != 1 ) {
 306        $r .=  "<s_start>". $this->s_start->exportXML_body() ."</s_start>\n";
 307      } else {
 308        $r .= "<s_start/>";
 309      }  
 310      if ( $this->s_end->notime != 1 ) {
 311        $r .=  "<s_end>". $this->s_end->exportXML_body() ."</s_end>\n";
 312      } else {
 313        $r .= "<s_end/>";
 314      }  
 315      if ( $this->r_start->notime != 1 ) {
 316        $r .=  "<r_start>". $this->r_start->exportXML_body() ."</r_start>\n";
 317      } else {
 318        $r .= "<r_start/>";
 319      }  
 320      if ( $this->r_end->notime != 1 ) {
 321        $r .=  "<r_end>". $this->r_end->exportXML_body() ."</r_end>\n";
 322      } else {
 323        $r .= "<r_end/>";
 324      }  
 325      foreach ( $this->worker as $i => $f) {
 326          $r .= "<worker>";
 327          $r .= "<id>". $f->id ."</id>";
 328          $r .= "<name>". utf8_encode(htmlspecialchars($f->GetFullname())) ."</name>";
 329          $r .= "<type>". utf8_encode(htmlspecialchars($f->GetType())) ."</type>";
 330          $r.= "</worker>";
 331      }
 332      }
 333      return $r;
 334    }
 335    /**
 336     * read a resultset
 337     */
 338    function read_result (&$r, $pos ) {
 339      global $current_user, $tutos;
 340  
 341      $this->p_id        = $r->get($pos, "p_id");
 342      $this->parent      = getObject($this->dbconn,$this->p_id);
 343      $this->state       = $r->get($pos, "status");
 344      $this->volume      = $r->get($pos, "volume");
 345      $this->volume_done = $r->get($pos, "volume_done");
 346      $this->volume_todo = $r->get($pos, "volume_todo");
 347      $this->name        = $r->get($pos, "name");
 348      $this->desc        = $r->get($pos, "description");
 349      $this->milestone   = $r->get($pos, "milestone");
 350  
 351      $this->r_start     = $r->getDateTime($pos, "r_start");
 352      $this->r_end       = $r->getDateTime($pos, "r_end");
 353      $this->s_start     = $r->getDateTime($pos, "s_start");
 354      $this->s_end       = $r->getDateTime($pos, "s_end");
 355  
 356      parent::read_result($r,$pos);
 357  
 358      $wid = $r->get($pos, "worker");
 359      $w = GetObject($this->dbconn,$wid);
 360      if ( $w != -1 ) {
 361        $this->worker[$wid] = &$w;
 362      }
 363      $this->readWorker();
 364  
 365      $cid = $r->get($pos, "creator");
 366      $this->creator = getObject($this->dbconn,$cid);
 367      if ( $this->parent == -1 ) {
 368        # Project not found
 369        $this->parent = $this->worker[$wid];
 370      }
 371      if ( $this->parent == -1 ) {
 372        # Project and worker  not found
 373        $this->parent = $this->creator;
 374      }
 375      if ( $this->parent == -1 ) {
 376        # Project, worker and creator not found
 377        $this->parent = $current_user;
 378      }
 379      $this->p_id = $this->parent->id;
 380  
 381      if ( ($this->volume == "") ) {
 382        $this->volume = 0;
 383      }
 384      if ( ($this->volume_done == "") ) {
 385        $this->volume_done = 0;
 386      }
 387      if ( ($this->volume_todo == "") ) {
 388        $this->volume_todo = -1;
 389      }
 390  
 391      # If timetrack is used then the volume_done is read as the sum of all connected tt entries
 392      if ( ($tutos[usetimetrack] == 1) ) {
 393        $this->readTimetrackSum();
 394        $this->volume_done = $this->timetracksum;
 395        if ( ($this->volume_done == "") ) {
 396          $this->volume_done = 0;
 397        }
 398      }
 399  
 400      # Tasks with used volume are not longer in prestate
 401      if ( ($this->volume_done > 0) && ($this->state == TASK_PRE) ) {
 402        $this->state = TASK_RUNNING;
 403      }
 404  
 405      return;
 406    }
 407    /**
 408     * get a list of possible new parents
 409     */
 410    function read_relations ( ) {
 411      global $lang;
 412  
 413      $this->plist = array();
 414      if ($this->parent != -1) {
 415        # Read possible new parents
 416        $this->plist = $this->parent->getNeighbours();
 417      }
 418      # !!! FIX ME Remove own subtasks from list
 419      unset ($this->plist[$this->id]);
 420      task::obj_read($this);
 421      foreach ($this->fulltasklist as $a => $b) {
 422        unset ($this->plist[$a]);
 423      }
 424    }
 425    /**
 426     * fill the internal neighbour list with possible objects where a object
 427     * currently attached/referncing to THIS task  could be reattached
 428     */
 429    function getNeighbours () {
 430      global $lang;
 431  
 432      if (count ($this->neighbours) > 0 ) return $this->neighbours;
 433  
 434      parent::getNeighbours();
 435  
 436      # Possible new parents are all parent tasks
 437      $x = $this;
 438      while ($x->getType() == "task") {
 439        if ($x->see_ok() ) {
 440          $this->neighbours[$x->id] = $x;
 441        }
 442        $x = $x->parent;
 443      }
 444      if ($x->getType() == "product") {
 445        $n =  $x->getNeighbours() ;
 446        foreach($n as $i) {
 447          $this->neighbours[$i->id] = &$i;
 448          unset($i);
 449        }
 450      }
 451      return $this->neighbours;
 452    }
 453    /**
 454     * read worker
 455     */
 456    function readWorker() {
 457      if ( empty($this->id) ) return;
 458      if ( -1 == $this->id ) return;
 459  
 460      $query = "SELECT w_id FROM ". $this->tablename2 ." WHERE t_id = ". $this->id;
 461      $result = $this->dbconn->Exec($query);
 462  
 463      $n = $result->numrows();
 464      $a = 0;
 465      while ($a < $n) {
 466        $xx = $result->get($a, "w_id");
 467        $p = getObject($this->dbconn,$xx);
 468        $this->worker[$xx] = &$p;
 469        $a++;
 470        unset($p);
 471      }
 472      $result->free();
 473    }
 474    /**
 475     * save worker
 476     */
 477    function saveWorker() {
 478      $q = "DELETE FROM ". $this->tablename2 ." WHERE t_id = ". $this->id;
 479      $this->dbconn->Exec($q);
 480      foreach ($this->worker as $i => $f) {
 481        $q = "INSERT INTO ". $this->tablename2 ." (t_id,w_id) VALUES (". $this->id .",". $i .")";
 482        $this->dbconn->Exec($q);
 483      }
 484    }
 485    /**
 486     * search for a task
 487     * fill a array with possible tasks
 488     */
 489    function search_by_name(&$arr,&$user,$name) {
 490      if ( trim($name) == "" ) return;
 491  
 492      $q = "SELECT * from ". $user->dbconn->prefix ."tasks WHERE". $user->dbconn->Like("name",$name);
 493      $q .= " order by name ";
 494      check_dbacl( $q, $user->id);
 495      $r = $user->dbconn->Exec($q);
 496      $n = $r->numrows();
 497      $a = 0;
 498      while ( $a < $n ) {
 499        $x = new task($user->dbconn);
 500        $x->read_result($r,$a);
 501        $arr[$x->id] = &$x;
 502  #     echo $x->getFullName() ."<br />";
 503        unset($x);
 504        $a++;
 505      }
 506      $r->free();
 507      return;
 508    }
 509    /**
 510     * set the Name
 511     */
 512    function setName($value) {
 513      return $this->setStrField("name",$value,"TaskName");
 514    }
 515    /**
 516     * set the Description
 517     */
 518    function setDescription($value) {
 519      return $this->setStrField("desc",$value,"TaskDesc");
 520    }
 521    /**
 522     * set the State
 523     */
 524    function setState($value) {
 525      return $this->setIntField("state",$value,"TaskState");
 526    }
 527    /**
 528     * set the Mielstone flag
 529     */
 530    function setMilestone($value) {
 531      return $this->setIntField("milestone",$value,"TaskMilestone");
 532    }
 533    /**
 534     * set the Start
 535     */
 536    function setRStart($value) {
 537      return $this->setDateField("r_start",$value,"TaskR_Start");
 538    }
 539    /**
 540     * set the End
 541     */
 542    function setREnd($value) {
 543      return $this->setDateField("r_end",$value,"TaskR_End");
 544    }
 545    /**
 546     * set the scheduled Start
 547     */
 548    function setSStart($value) {
 549      return $this->setDateField("s_start",$value,"TaskS_Start");
 550    }
 551    /**
 552     * set the scheduled end
 553     */
 554    function setSEnd($value) {
 555      return $this->setDateField("s_end",$value,"TaskS_End");
 556    }
 557    /**
 558     * set the Volume
 559     */
 560    function setVolume($value) {
 561      return $this->setFloatField("volume",$value,"TaskVolumeFull");
 562    }
 563    /**
 564     * set the VolumeDone
 565     */
 566    function setVolumeDone($value) {
 567      # Book the time to the task and users
 568      # timetrack
 569      $this->diff = $value - $this->volume_done;
 570  
 571      return $this->setFloatField("volume_done",$value,"TaskVolumeDone");
 572    }
 573    /**
 574     * set the Volume Todo
 575     */
 576    function setVolumeTodo($value) {
 577      return $this->setFloatField("volume_todo",$value,"TaskVolumeTodo");
 578    }
 579    /**
 580     * set the parent
 581     */
 582    function setParent($pid) {
 583      if ( $this->p_id != $pid ) {
 584        $this->modified[] = array ( "field" => "TaskSubTask" , "old" => $this->p_id , "new" => $pid);
 585        $this->p_id = $pid;
 586      }
 587      return;
 588    }
 589    /**
 590     * Replaces the strings in the mail body
 591     */
 592    function make_mail_body(&$body,&$to) {
 593      global $lang;
 594  
 595      $url = getBaseURL(true). $this->getURL();
 596      
 597      $body = eregi_replace("@CREATOR@",$this->creator->getFullName(),$body);
 598      $body = eregi_replace("@SHORT@",$this->name,$body);
 599      $body = eregi_replace("@DESC@",$this->desc,$body);
 600      $body = eregi_replace("@STATE@",$to->lg['TaskStates'][$this->state],$body);
 601      $body = eregi_replace("@VOLUME@",$this->volume,$body);
 602      
 603      $worker = "";
 604      if (count($this->worker) > 1) {
 605        foreach ($this->worker as $i => $f) {
 606          $worker .= $f->GetFullname()."\n";
 607        }
 608        $body = eregi_replace("@WORKERS@",$worker,$body);
 609        $body = eregi_replace("<WORKERS>","",$body);
 610        $body = eregi_replace("</WORKERS>","",$body);
 611      } else {
 612        $body = eregi_replace("<WORKERS>.*</WORKERS>","",$body);
 613      }
 614      
 615      $body = eregi_replace("@URL@",$url,$body);
 616  
 617      if ( $to->gettype() == "team" ) {
 618        $body = eregi_replace("@TO@",$lang[$to->gettype()] ." ".$to->getFullName(),$body);
 619        $body = eregi_replace("<TEAM>","",$body);
 620        $body = eregi_replace("</TEAM>","",$body);
 621      } else  {
 622        $body = eregi_replace("@TO@",$to->getFullName(),$body);
 623        # Remove the TEAM part
 624        $body = eregi_replace("<TEAM>.*</TEAM>","",$body);
 625      }
 626      
 627      $body = eregi_replace("@START@",$this->s_start->getDateTime(),$body);
 628      $body = eregi_replace("@END@",$this->s_end->getDateTime(),$body);
 629    }
 630    /**
 631     * Save Task to DB
 632     */
 633    function save() {
 634      global $tutos,$table,$current_user;
 635  
 636      $msg = "";
 637  
 638      $q = new query($this->dbconn);
 639      $q->setTable($this->tablename);
 640  
 641      @reset($this->worker);    
 642      $q->addFV("worker",current($this->worker),"OBJ");
 643  
 644      $q->addFV("p_id",$this->p_id,"INT");
 645      $q->addFV("status",$this->state,"INT");
 646      $q->addFV("milestone",$this->milestone,"INT");
 647      $q->addFV("volume",$this->volume,"FLOAT");
 648      $q->addFV("volume_todo",$this->volume_todo,"FLOAT");
 649      $q->addFV("name",$this->name,"STRING",$table['task']['name'][size]);
 650      $q->addFV("description",$this->desc,"TEXT");
 651      $q->addFV("r_start",$this->r_start,"DATETIME");
 652      $q->addFV("r_end",$this->r_end,"DATETIME");
 653      $q->addFV("s_start",$this->s_start,"DATETIME");
 654      $q->addFV("s_end",$this->s_end,"DATETIME");
 655      $this->save_custom_fields($q);
 656  
 657      if ( $this->id < 0 ) {
 658        $task_is_new = true;
 659        $this->modified = array();
 660        if ( isset($this->newid) ) {
 661          $this->id = $this->newid;
 662          $q->addFV("id",$this->id,"");
 663        } else {
 664          $this->id = $q->addFV("id",-1,"NEXTID");
 665          # Defaut Access Control (get parents acl as default)
 666          $this->acl  = $this->parent->acl;
 667          $this->modified[] = array ( "field" => "created" ,
 668                                      "old" => $this->getType() ,
 669                                      "new" => $this->id,
 670                                      "obj_id" => $this->id
 671                                    );
 672          # to not trigger watchlist if parent is a address
 673          $this->modified[] = array ( "field" => "TaskCreate" ,
 674                                      "old" => "-1" ,
 675                                      "new" => $this->id,
 676                                      "obj_id" => $this->parent->id
 677                                    );
 678        }
 679        $q->addFV("creator",$this->creator,"OBJ");
 680        $q->addFV("creation",$this->creation,"DATETIME");
 681  
 682        $query = $q->getInsert();
 683      } else {
 684        $task_is_new = false;
 685        $q->addWC("id",$this->id,"");
 686        $query = $q->getUpdate();
 687      }
 688      foreach ($this->worker as $i => $f) {
 689        acl_raise($this,$f->id,$tutos[modok]);
 690        // fix the fact that user that changes task are in solvers list
 691        if ($f->getType() == "address" && $f->id == $current_user->id) {
 692          $cw = $f;
 693        }
 694      }
 695      acl_raise($this,$this->creator->id,$tutos[delok]);
 696  
 697      $this->dbconn->Exec($query);
 698      $this->saveWorker();
 699  
 700      $msg .= parent::save();
 701  
 702      # If the volume_done has been changed, we add a timetrack entry
 703      if ( ($this->diff != 0) ) {
 704        $tt = new timetrack($this->dbconn);
 705        if( isset($cw) ) {
 706          // A worker has made the change
 707          $tt->worker      = $cw;
 708        } else {
 709          // The task creator or a mod_ok tutos user made the change...
 710         $tt->worker      = $current_user;
 711        }
 712        $tt->link_id     = $this->id;
 713        $tt->ref         = $this;
 714        $tt->volume      = $this->diff;
 715        $tt->volume_todo = $this->volume_todo;
 716        $tt->desc        = $this->name;
 717        $msg .= $tt->save($norec=1);
 718      }
 719      
 720      # Mail stuff
 721      if ( $this->email == 1 ) {
 722        $m = new mail($current_user);
 723        $m->setFrom($this->creator);
 724  
 725        foreach ($this->worker as $i => $f) {
 726          $m->addTo($f);
 727          $body = "";
 728  
 729          if ( $task_is_new ) {
 730            if ( ! findMailTemplate("task_new.proto",$f,$body) ) {
 731              $msg .= sprintf($lang['Err0037'],$m->subject,$body) ."<br />\n";
 732              continue;
 733            }
 734            $m->setSubject(sprintf($f->lg['EmailNewTask'],$this->getFullName(),sprintf($f->lg['TaskStates'][$this->state])));
 735            $m->addHeader("X-PRIORITY","1");
 736            $m->addHeader("priority","urgent");
 737          } else {
 738            if ( ! findMailTemplate("task_mod.proto",$f,$body) ) {
 739              $msg .= sprintf($lang['Err0037'],$m->subject,$body) ."<br />\n";
 740              continue;
 741            }
 742            $m->setSubject(sprintf($f->lg['EmailChangesTask'],$this->getFullName(),sprintf($f->lg['TaskStates'][$this->state])));
 743          }
 744  
 745          $this->make_mail_body($body,$f);
 746          
 747          $m->addBody($body,"text/plain",$f->lg['TaskDetail'],"",$f->lg['content_encoding']);
 748                  
 749          $msg .= $m->send();
 750          $m->resetBody();
 751          $m->resetTo();
 752        }
 753      }
 754      
 755      return $msg;
 756    }
 757    /**
 758     * Delete tasks from DB
 759     */
 760    function delete() {
 761      global $current_user;
 762  
 763      $msg = "";
 764  
 765  
 766      $q = "UPDATE ". $this->tablename ." SET p_id = ". $this->p_id ." WHERE p_id = ". $this->id;
 767      $this->dbconn->Exec($q);
 768  
 769      $q = "DELETE FROM ". $this->tablename2 ." WHERE t_id = ". $this->id;
 770      $this->dbconn->Exec($q);
 771  
 772      $q = "DELETE FROM ". $this->tablename ." WHERE id = ". $this->id;
 773      $this->dbconn->Exec($q);
 774  
 775  
 776      $msg .= timetrack::obj_delete($current_user,$this);
 777      $msg .= parent::delete();
 778      return $msg;
 779    }
 780    /**
 781     * Popup for overlib
 782     */
 783    function getPopInfo() {
 784      global $lang;
 785  
 786      $n =str_replace("\n","<br />",myentities(wordwrap($this->desc,80)));
 787      $n =str_replace("\r","",$n);
 788      $n =str_replace("'","\'",$n);
 789  
 790      $t =myentities($this->name);
 791      $t =str_replace("'","\'",$t);
 792  
 793      $info = "";
 794      $info .= "<html>";
 795      $info .= "<body>";
 796      $info .= "<table class=\"inner\" border=\"0\" cellspacing=\"0\" cellpadding=\"1\">";
 797  
 798      $x = $this->parent;
 799      if( $x == -1 ) unset($x);
 800      $pre = "";
 801      $name = "";
 802      while ( isset ( $x ) ) {
 803        $name = myentities($x->getFullName()) . $pre . $name;
 804        if (isset($x->parent) && $x->parent != -1) {
 805          $x = $x->parent;
 806        } else {
 807          unset($x);
 808        }
 809        $pre = "  &#8594; ";
 810      }
 811      $name .= $pre . "&nbsp;" . $t;
 812      
 813      $info .= "<tr><th>". $name ."</th></tr>";
 814      if ( ($this->s_start->notime != 1) || ($this->s_end->notime != 1) ) {
 815        $info .= "<tr><td><font size=\"-2\">";
 816        $info .= $this->s_start->getDate() ." - ". $this->s_end->getDate();
 817        $info .= "</font></td></tr>";
 818      }
 819      if ( $this->volume != 0 ) {
 820        $info .= "<tr><td><font size=\"-2\">";
 821        $info .= hour_format($this->volume) ." / ". hour_format($this->volume_done) ." ". $lang['hours'] . sprintf(" (%3.2f %%)", $this->getcompletion());
 822        $info .= "</font></td></tr>";
 823      }
 824      $info .= "<tr><td><font size=\"-2\"><pre>";
 825      $info .= $n;
 826      $info .= "</pre></font></td></tr>";
 827      $info .= "</table></body></html>";
 828      return $info;
 829    }
 830    /**
 831     * Return a link to this task
 832     */
 833    function getURL() {
 834      return "task_show.php?id=".$this->id;
 835    }
 836    /**
 837     * Return a link to modify this task
 838     */
 839    function getModURL() {
 840      return "task_new.php?id=".$this->id;
 841    }
 842    /**
 843     * Return a link to delete this task
 844     */
 845    function getDelURL() {
 846      return "task_del.php?id=".$this->id;
 847    }
 848    /**
 849     * Return a link to this task
 850     */
 851    function getLink($text = "") {
 852      global $lang;
 853  
 854      if ( $text == "" ) {
 855        $text = $this->getFullName();
 856      }
 857      if ( $this->see_ok() ) {
 858        return makelink($this->getURL() , myentities($text) ,sprintf($lang['TaskLinkInfo'], $this->getFullName()),$this->getPopInfo());
 859      } else {
 860        return myentities($text);
 861      }
 862    }
 863    /**
 864     * Return a fullname i.e name
 865     */
 866    function getFullname() {
 867      global $lang;
 868  
 869      if ($this->milestone == 1) {
 870        return $lang['TaskMilestone']." ".$this->name;
 871      } 
 872      return $this->name;
 873    }
 874    /**
 875     * get the info as text
 876     */
 877    function getAsText (&$lang) {
 878      $r = "";
 879      $r .= format_asText($lang['TaskName'],$this->name);
 880      $r .= format_asText($lang['TaskState'],$lang['TaskStates'][$this->state]);
 881      $r .= format_asText($lang['TaskDesc'],$this->desc);
 882      $r .= format_asText($lang['TaskSched']." / ". $lang['DateTimeFrom'],$this->s_start->getDate());
 883      $r .= format_asText($lang['TaskSched']." / ". $lang['DateTimeTill'],$this->s_end->getDate());
 884      return $r;
 885    }
 886    /**
 887     * get the timespan
 888     */
 889    function getTimespan () {
 890      $r = array();
 891      $r['start'] =  $this->s_start->getYYYYMMDD() ."0000";
 892      $r['end'] =  $this->s_end->getYYYYMMDD() ."2359";
 893      $r['desc'] = $this->s_start->getDate() ." - " . $this->s_end->getDate() ;
 894      return $r;
 895    }
 896    /**
 897     * Return Info about bugs in this task
 898     */
 899    function bugSum() {
 900      return bugSummary($this);
 901    }
 902  
 903  
 904    /**
 905     * Add in the given array entries $task_id => $project_id
 906     * Returns the project
 907     */
 908    function getProject(&$projects_tasks) {
 909      $project = -1;
 910      $obj     = $this;
 911      $ptasks  = array();
 912  
 913      // Walk through parents to find project 
 914      while( $project == -1 ) {
 915        if( array_key_exists($obj->p_id, $projects_tasks) ) {
 916          $ptasks[] = $obj->id;
 917          $project = getObject($this->dbconn, $projects_tasks[$obj->p_id]);
 918        } else {
 919          $t = getObject($this->dbconn, $obj->p_id);
 920          if( $t == -1 ) {
 921            // Parent no longer exists ?
 922            break;
 923          }
 924          $ptasks[] = $obj->id;
 925          if( $t->getType() != "task" ) {
 926            // found first node
 927            $project = &$t;
 928          } else {
 929            $obj = getObject($this->dbconn, $obj->p_id);
 930          }
 931          unset($t);
 932        }
 933      }
 934      foreach( $ptasks as $pid ) {
 935        $projects_tasks[$pid] = $project->id;
 936      }
 937  
 938      return $project;
 939    }
 940  
 941    /**
 942     * get the type of object
 943     */
 944  
 945    function printRow (&$layout,$depth, &$parent, $fld = "", $slimit=0, $elimit=0) {
 946       global $lang, $tutos, $projects_tasks,$table;
 947  
 948       if( !isset($projects_tasks) ) $projects_tasks = array();
 949  
 950       // I sometimes get -1 as $this->id
 951       if( $this->id == -1 )
 952         return;
 953  
 954       if ( ($parent->getType() == "address")||($parent->getType() == "team")||($parent->getType() == "base") ) {
 955         $recursive = false;
 956         # print only unfinished tasks
 957         if ( $this->state == TASK_FINISH ) {
 958           return 1;
 959         }
 960       } else {
 961         $recursive = true;
 962       }
 963  
 964       /* we limit the date range of printed tasks */
 965       if( $slimit == 0 && $elimit == 0
 966       || ($slimit != 0 && $elimit != 0
 967           && $slimit->datecmp($this->s_start) <= 0
 968           && ($elimit->datecmp($slimit) == 0
 969           || $elimit->datecmp($this->s_end) >= 0) )) {
 970  
 971         $c = $this->getcompletion();
 972  
 973         echo $layout->OverviewRowStart($layout->line);
 974  
 975         switch( $parent->getType() ) {
 976         case "address": {
 977           /* We show the project name and the task name
 978            * As we already know the person name, we should not have the need
 979            * to display it (see Person Task Overview)
 980            *
 981            * That can take some times to complete... even with the
 982            * $projects_tasks static var, keeping projects associations in
 983            * memory, in order not to make too much data base access...
 984            */
 985           $project = $this->getProject($projects_tasks);
 986  
 987           if( $this->getLink() != "" ) {
 988             echo "  <td class=\"task". $this->state . "\" valign=\"top\" colspan=\"2\" nowrap=\"nowrap\">&nbsp;".  ($project != -1 ? $project->getLink() : "DTC") ."&nbsp; &#8594; ".  $this->getLink()."&nbsp;</td>\n";
 989           }
 990           break;
 991         }
 992         case "team": {
 993           echo "  <td class=\"task". $this->state ."\" valign=\"top\" colspan=\"2\" nowrap=\"nowrap\">&nbsp;".
 994           $parent->getLink() ."&nbsp;&8594; ".
 995           $this->getLink()."&nbsp;</td>\n";
 996           break;
 997         }
 998         default: {
 999           echo "  <td class=\"task". $this->state ."\" align=\"right\" valign=\"top\">&nbsp;". $depth ."&nbsp;</td>\n";
1000           echo "  <td valign=\"top\" nowrap=\"nowrap\"><p>&nbsp;";
1001           for ($i = 0; $i <= $depth; $i++) {
1002             echo "&nbsp;&nbsp;";
1003           }
1004           echo $this->getLink()."&nbsp;";
1005  
1006           switch( $fld ) {
1007           case "worker":
1008             echo "<p align=\"right\">".$lang['TaskWorker'];
1009             $w = 0;
1010             foreach ($this->worker as $i => $x) {
1011               echo ($w %2 ? "<br />":"&nbsp;").($w >0 ? ",":"").
1012                    $this->worker[$i]->getLink();
1013              $w++;
1014             }
1015             break;
1016  
1017          case "product":
1018             $project = $this->getProject($projects_tasks);
1019             echo "<p align=\"right\">".$lang['Product']." ".$project->getLink();
1020             break;
1021  
1022             default:
1023                break;
1024             }
1025  
1026             echo "</td>\n";
1027           }
1028         } // end of switch $parent->getType()
1029  
1030         // I have some strange bug where I reach non existing entities.
1031         if( $this->getLink() == "" )
1032           return 0;
1033  
1034         // When displaying an address time overview, we have to compute
1035         // the volume done by the $parent address !
1036         if( $parent->getType() == "address" ) {
1037           $volume = $this->volume;
1038           $volume_done = computeWorkedHours($parent, $this);
1039         } else {
1040           $volume = $this->volume;
1041           $volume_done = $this->volume_done;
1042         }     
1043  
1044         echo "  <td align=\"right\" valign=\"top\" nowrap=\"nowrap\">"
1045       .sprintf("%3.2f %%",$c )
1046       ."&nbsp;<br />&nbsp;"
1047       .hour_format($volume_done,2) ." / ". hour_format($volume,2)
1048       ." ". $lang['hours'] ."&nbsp;</td>\n";
1049         
1050         echo "  <td valign=\"top\" align=\"right\">"
1051       .$this->s_start->getDate() ."&nbsp;</td>\n";
1052  
1053         $w = 200;
1054         $h  = 32; // height
1055         // seconds per pixel
1056         $t = time();
1057         $max_end = max($parent->max_end->ts,$t);
1058         $min_start = min($parent->min_start->ts,$t);
1059         $p = ( ($max_end - $min_start) / $w);
1060         if ( $p == 0 ) {
1061  #       $p = 1;
1062         }
1063  
1064         // from earliest to start
1065         $x1 = round(($this->s_start->ts - $min_start)/$p);
1066         $x1a = round( ($t - $min_start)/$p);
1067         $x1b = round(( $this->s_start->ts - $t )/$p);
1068  
1069         $x2 = round(($this->s_end->ts - $this->s_start->ts)/$p);
1070  
1071         $x3 = round(($max_end - $this->s_end->ts)/$p);
1072         $x3a = round(( $t - $this->s_end->ts)/$p);
1073         $x3b = round( ($max_end - $t )/$p);
1074  
1075         echo "  <td align=\"left\" colspan=\"2\" width=\"".($w +1)."\" nowrap=\"nowrap\">";
1076  
1077         if ( $x1a + $x1b > 0 ) {
1078           if ( $x1b < 0 ) {
1079             echo "<img border=\"0\" height=\"". $h ."\" width=\"".( $x1a + $x1b) ."\" src=\"". $tutos['base'] ."/html/gray.png\" alt=\"\">";
1080           } else {
1081             if ( $x1a > 0 ) {
1082               echo "<img border=\"0\" height=\"". $h ."\" width=\"". $x1a  ."\" src=\"". $tutos['base'] ."/html/gray.png\" alt=\"\">";
1083             }
1084           }
1085           if ( $x1b > 0 ) {
1086             echo "<img border=\"0\" height=\"". $h ."\" width=\"".$x1b."\" src=\"". $tutos['base'] ."/html/white.png\" alt=\"\">";
1087           }
1088         }
1089         if ( $x2 == 0 ) {
1090           $x2=1;
1091         }
1092         $x2a = Round($x2 * $c/100.0);
1093         $x2b = Round($x2 * (100 - $c)/100.0);
1094         if ( $x2a != 0 ) {
1095           echo "<img border=\"0\" height=\"". $h ."\" width=\"". $x2a."\" src=\"". $tutos['base'] ."/html/green.png\" alt=\"". myentities($this->getFullName()) ."\">";
1096         }
1097         if ( $x2b > 0 ) {
1098           echo "<img border=\"0\" height=\"". $h ."\" width=\"". $x2b."\" src=\"". $tutos['base'] ."/html/red.png\"  alt=\"". myentities($this->getFullName()) ."\">";
1099         }
1100  
1101         if ( $x3a + $x3b > 0 ) {
1102           if ( $x3a > 0 ) {
1103             echo "<img border=\"0\" height=\"". $h ."\" width=\"".$x3a."\" src=\"". $tutos['base'] ."/html/gray.png\" alt=\"\">";
1104             if ( $x3b > 0 ) {
1105               echo "<img border=\"0\" height=\"". $h ."\" width=\"". ($x3b - 1) ."\" src=\"". $tutos['base'] ."/html/white.png\" alt=\"\">";
1106             }
1107           } else {
1108             if ( ($x3b + $x3a) > 0 ) {
1109               echo "<img border=\"0\" height=\"". $h ."\" width=\"".($x3b + $x3a)."\" src=\"". $tutos['base'] ."/html/white.png\" alt=\"\">";
1110             }
1111           }
1112         }
1113         echo "</td>\n";
1114         echo "  <td valign=\"bottom\">&nbsp;". $this->s_end->getDate() ."&nbsp;</td>\n";
1115         echo "  <td>&nbsp;";
1116         echo makelink("task_new.php?pid=".$this->id,$lang['NewEntry'],sprintf($lang['TaskCreateInfo'],$this->name));
1117         echo "  </td>\n";
1118  
1119  
1120         echo "  <td align=\"center\">&nbsp;";
1121         if ( $tutos[massupdate] == 1 ) {
1122           # Checkbox column for massupdate
1123           if ( $this->mod_ok() ) {
1124             echo "<input name=\"mark[]\" type=\"checkbox\" value=\"". $this->id ."\">";
1125           } else {
1126             echo "-";
1127           }
1128         } else {
1129           if ( $this->del_ok() ) {
1130             echo confirmlink("task_del.php?id=".$this->id,$lang['Delete'],sprintf($lang['TaskDelete'],$this->name));
1131           } else {
1132             echo $lang['Delete'];
1133           }
1134         }
1135         echo "&nbsp;</td>\n";
1136         echo $layout->OverviewRowEnd($layout->line++);
1137       }
1138  
1139       if ( $recursive ) {
1140         task::obj_read($this);
1141         foreach($this->tasklist as $i => $f) {
1142           $f->printRow($layout,$depth +1,$parent, $fld, $slimit, $elimit);
1143         }
1144       }
1145       return 0;
1146    }
1147    /**
1148     * get the percentage of completion
1149     */
1150    function getcompletion () {
1151      if( $this->state == TASK_FINISH )
1152        return 100.0;
1153  
1154      if ( $this->volume <= 0 ) {
1155        return 0.0;
1156      }
1157      if( $this->volume_todo > -1 ) {
1158        if ( ($this->volume_todo + $this->volume_done) == 0 ) {
1159          return 0.0;
1160        }
1161        return (100.0*($this->volume_done/
1162               ($this->volume_todo + $this->volume_done)));
1163      }
1164      return ( 100.0 * ( $this->volume_done / $this->volume ));
1165    }
1166    /**
1167     * output the formatted task in one table row
1168     */
1169    function formatted () {
1170      global $lang,$tutos,$current_user;
1171  
1172      $class = "task". $this->state;
1173  
1174      echo "  <tr>\n";
1175      echo "   <td nowrap=\"nowrap\" class=\"". $class ."\" colspan=\"3\">". $this->getLink() ."</td>\n";
1176      echo "  </tr>\n";
1177      echo "  <tr>\n";
1178      if ( $this->parent->getType() == "address" ) {
1179        if ( $this->parent->id == $current_user->id ) {
1180          echo "   <td nowrap=\"nowrap\" class=\"". $class ."\" colspan=\"3\" align=\"right\">".$lang['TaskStates'][$this->state] ."</td>\n";
1181        } else {
1182          echo "   <td nowrap=\"nowrap\" class=\"". $class ."\" colspan=\"3\" align=\"right\">".$lang['TaskStates'][$this->state]."&nbsp;(". $this->parent->getLink() .")</td>\n";
1183        }
1184      } else {
1185        echo "   <td nowrap=\"nowrap\" class=\"". $class ."\" colspan=\"3\" align=\"right\">".$lang['TaskStates'][$this->state]."&nbsp;&#8594;&nbsp;". $this->parent->getLink() ."</td>\n";
1186      }
1187      echo "  </tr>\n";
1188  
1189      return;
1190    }
1191    /**
1192     * checks if the task is planned that day
1193     * Date d   true if taks work should happen that day
1194     */
1195    function inside (&$d) {
1196      $d->setDateTime($d->getYYYYMMDD() . "000000");
1197      $x = $d->getYYYYMMDD();
1198  
1199      if ( $x < $this->s_start->getYYYYMMDD()  ) return false;
1200      if ( $x > $this->s_end->getYYYYMMDD()  ) return false;
1201  
1202      return true;
1203    }
1204    /**
1205     * Transfer reference ids according to given table
1206     */
1207    function transfer_ids (&$trans) {
1208      parent::transfer_ids ($trans);
1209  
1210      if (isset($trans[$this->p_id])) {
1211        $this->p_id = $trans[$this->p_id];
1212      }
1213      foreach ($this->worker as $i => $f) {
1214        if (isset($trans[$i])) {
1215          $this->worker[$trans[$i]] = $this->worker[$i] ;
1216          $this->worker[$trans[$i]]->id = $trans[$i] ;
1217          unset($this->worker[$i]);
1218        }
1219      }
1220      if (isset($trans[$this->creator->id])) {
1221        $this->creator->id = $trans[$this->creator->id];
1222      }
1223      return;
1224    }
1225    /**
1226     * get the type of object
1227     */
1228    function getType () {
1229      return "task";
1230    }
1231    /**
1232     * get the type id of object
1233     */
1234    function gettypeid () {
1235      return usetaskmanagement;
1236    }
1237    /**
1238     * get name of icons
1239     */
1240    function getHtmlIcon () {
1241      return 'task';
1242    }
1243    /* ---------------------------------------------------------------------------
1244     * The following methods are abstract factory functions for groups
1245     * which handle the membership list of an object
1246     * --------------------------------------------------------------------------- */
1247    /**
1248     * create a link to a overview page
1249     */
1250    function getOverviewLink (&$user,$text = "") {
1251      global $lang,$tutos;
1252      if ( ! $user->feature_ok(usetaskmanagement,PERM_NEW) ) {
1253        return;
1254      }
1255    }
1256    /**
1257     * create a link where a note to for the given object could be added
1258     */
1259    function getaddlink (&$user,&$obj,$text = "") {
1260      global $lang;
1261  
1262      if ( $obj == -1 ) return ""; 
1263      if (! is_object($obj) ) return "";
1264      if (! $user->feature_ok(usetaskmanagement,PERM_NEW) ) return "";
1265      if (! $obj->mod_ok() ) return "";
1266  
1267      $x = array( url => "task_new.php?pid=". $obj->id,
1268                  confirm => false,
1269                  text => ($text == "" ? $lang['TaskCreate']:$text),
1270                  info => sprintf($lang['TaskCreateInfo'], $obj->getFullName())
1271                );
1272      if ( $obj->gettype() == "task" ) {
1273        $x[category] = array("task","new","obj");
1274      } else {
1275        $x[category] = array("task","new","module");
1276      }
1277  
1278      return $x;
1279    }
1280  
1281    /**
1282     * Return Info about connected tasks for given object
1283     */
1284    function obj_read(&$obj) {
1285      global $table;
1286  
1287      if ( $obj == -1 ) return; 
1288      if (! is_object($obj) ) return;
1289  
1290      if ( isset($obj->tasklist) ) return;
1291  
1292      $obj->tasklist = array();
1293      $obj->fulltasklist = array();
1294  
1295      $obj->tsum['Tasks'] = 0;
1296      $readall = false;
1297      if ( ($obj->getType() == "address") || ($obj->getType() == "user") ) {
1298        $q = "SELECT distinct t_id from ". $obj->dbconn->prefix .$table['taskworker'][name] ." WHERE ";
1299         # Select the workers and all his teams tasks
1300        team::obj_read($obj);
1301        $q .= " w_id in ( ". $obj->id;
1302        foreach ( $obj->teamlist as $i => $f) {
1303          $q .= ",". $i;
1304        }
1305        $q .= ")";
1306        $readall = true;
1307      } else if ( $obj->getType() == "team" ) {
1308        $q = "SELECT distinct t_id from ". $obj->dbconn->prefix .$table['taskworker'][name] ." WHERE ";
1309        $q .= "w_id = ". $obj->id;
1310        $readall = true;
1311      } else {
1312        $q = "SELECT * from ". $obj->dbconn->prefix .$table['task'][name]." WHERE ";
1313        $q .= "p_id = ". $obj->id;
1314        $q .= " ORDER by s_start";
1315      }
1316      $r = $obj->dbconn->Exec($q);
1317      $n = $r->numrows();
1318      $a = 0;
1319      while ($a < $n) {
1320        $t = new task($obj->dbconn);
1321        if ( $readall ) {
1322          $id =$r->get($a,"t_id"); 
1323          $t = $t->read($id,$t);
1324        } else {
1325          $t->read_result($r,$a);
1326        }
1327        task::obj_read($t);
1328        if ( class_exists('bug') ) {
1329          bug::obj_read($t);
1330        } else {
1331          $t->tsum['Bugs'] = 0;
1332        }
1333        $t->readTimetrackSum();
1334        $obj->tsum['Tasks'] += $t->timetracksum;
1335        # Add Subtask-Sum
1336        $obj->tsum['Tasks'] += $t->tsum['Tasks'];
1337        $obj->tsum['Tasks'] += $t->tsum['Bugs'];
1338        $obj->tasklist[$t->id] = &$t;
1339  
1340        $obj->fulltasklist[$t->id] = &$t;
1341        foreach ($t->fulltasklist as $i => $f) {
1342          $obj->fulltasklist[$i] = &$f;
1343          unset($f);
1344        }
1345        $a++;
1346        unset($t);
1347      }
1348  
1349      $r->free();
1350      return;
1351    }
1352    /**
1353     * a object that may hold tasks is deleted
1354     */
1355    Function obj_delete(&$user,&$obj) {
1356      global $table;
1357  
1358      $msg = "";
1359  
1360      $q = "DELETE FROM ". $obj->dbconn->prefix .$table['taskworker'][name] ." WHERE w_id = ". $obj->id;
1361      $obj->dbconn->Exec($q);
1362  
1363      if ( $obj->getType() != "address" ) {
1364        task::obj_read($obj);
1365        if ( count($obj->tasklist) > 0 ) {
1366          foreach ($obj->tasklist as $i => $f) {
1367            $msg .= $f->delete();
1368          }
1369        }
1370      }
1371      return $msg;
1372    }
1373    /**
1374     * Read a list of tasks for a timerange and make it a array in the
1375     * given object (compare readAppsCal in appointment.pinc)
1376     * start    is a  TUTOS DateTime object
1377     */
1378    function readCal(&$obj, &$from, &$to) {
1379      global $current_user,$table;
1380  
1381      if ( ! $current_user->feature_ok(usetaskmanagement,PERM_SEE) ) {
1382        return;
1383      }
1384  
1385      $from->setDateTime($from->getYYYYMMDD() . "000000");
1386      $to->setDateTime($to->getYYYYMMDD() . "000000");
1387  
1388      $x1 =  $obj->dbconn->DateTime($from);
1389      $x2 =  $obj->dbconn->DateTime($to);
1390      #
1391      #
1392      #
1393      $q = "SELECT c.* FROM ". $obj->dbconn->prefix ."tasks c ";
1394      $pre = " WHERE";
1395      if ( ($obj->getType() == "address") || ($obj->getType() == "user") ) {
1396        # Select the workers and all his teams tasks
1397        $q .= $pre. "( c.worker in ( ". $obj->id;
1398        foreach ($obj->teamlist as $i => $f) {
1399          $q .= ",". $i;
1400        }
1401        $q .= ")";
1402  #
1403        $qq = "SELECT DISTINCT t_id FROM ". $obj->dbconn->prefix .$table['taskworker'][name]. " WHERE w_id in (".$obj->id;
1404        foreach ($obj->teamlist as $i => $f) {
1405          $qq .= "," . $i;
1406        }
1407        $qq .= ")";
1408        $r = $obj->dbconn->Exec($qq);
1409        $n = $r->numrows();
1410        $a = 0;
1411        if ( $n > 0 ) {
1412          $q .= " OR ( c.id in (";
1413          $xpre = "";
1414          while ( $a < $n ) {
1415            $x = $r->get($a,"t_id");
1416            $q .= $xpre . $x;
1417            $xpre = ",";
1418            $a++;
1419          }
1420          $r->free();
1421          $q .= ") )";
1422        }
1423  #
1424        $q .= ")";
1425        $pre = " AND";
1426      }
1427      $q .= $pre. "(";
1428      $q .= "   ( c.s_start < ". $x2 ." and c.s_start >= ". $x1 .")";
1429      $q .= "or ( c.s_end <   ". $x2 ." and c.s_end >=   ". $x1 .")";
1430      $q .= "or ( c.s_start < ". $x1 ." and c.s_end >=   ". $x1 .")";
1431      $q .= ")";
1432      $q .= " ORDER by c.s_start";
1433  
1434      $r = $obj->dbconn->Exec($q);
1435      $n = $r->numrows();
1436      $a = 0;
1437      while ( $a < $n ) {
1438        $o = new task($obj->dbconn);
1439        $o->read_result($r,$a);
1440        $a++;
1441        if ( $o->see_ok() ) {
1442          $obj->callist[$o->id] = &$o;
1443        }
1444        unset($o);
1445      }
1446      $r->free();
1447    }
1448    /**
1449     * get the help index
1450     */
1451    function getHelpIndex () {
1452      global $lang;
1453  
1454      $r = "";
1455      $r .= "<h3>". makelink("help.php?p=glossary#tasks",$lang['Tasks'],$lang['Tasks']) ."</h3><ul>\n";
1456      $r .= "<li>". makelink("help.php?p=task_new",$lang["NewEntry"]."/". $lang["Modify"],$lang["NewEntry"]."/". $lang["Modify"]) ."</li>\n";
1457      $r .= "<li>". makelink("help.php?p=task_show",$lang["show"],$lang["show"]) ."</li>\n";
1458      $r .= "<li>". makelink("help.php?p=res_cal",$lang['ResCal'],$lang['ResCal'])."</li>\n";
1459      $r .= "</ul>\n";
1460      return $r;
1461    }
1462  }
1463  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]