| [ PHPXref.com ] | [ Generated: Sun Jul 20 20:47:44 2008 ] | [ TUTOS 1.2 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
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 = " → "; 810 } 811 $name .= $pre . " " . $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\"> ". ($project != -1 ? $project->getLink() : "DTC") ." → ". $this->getLink()." </td>\n"; 989 } 990 break; 991 } 992 case "team": { 993 echo " <td class=\"task". $this->state ."\" valign=\"top\" colspan=\"2\" nowrap=\"nowrap\"> ". 994 $parent->getLink() ." &8594; ". 995 $this->getLink()." </td>\n"; 996 break; 997 } 998 default: { 999 echo " <td class=\"task". $this->state ."\" align=\"right\" valign=\"top\"> ". $depth ." </td>\n"; 1000 echo " <td valign=\"top\" nowrap=\"nowrap\"><p> "; 1001 for ($i = 0; $i <= $depth; $i++) { 1002 echo " "; 1003 } 1004 echo $this->getLink()." "; 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 />":" ").($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 ." <br /> " 1047 .hour_format($volume_done,2) ." / ". hour_format($volume,2) 1048 ." ". $lang['hours'] ." </td>\n"; 1049 1050 echo " <td valign=\"top\" align=\"right\">" 1051 .$this->s_start->getDate() ." </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\"> ". $this->s_end->getDate() ." </td>\n"; 1115 echo " <td> "; 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\"> "; 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 " </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]." (". $this->parent->getLink() .")</td>\n"; 1183 } 1184 } else { 1185 echo " <td nowrap=\"nowrap\" class=\"". $class ."\" colspan=\"3\" align=\"right\">".$lang['TaskStates'][$this->state]." → ". $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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |