home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / dotproject / modules / tasks / tasks.class.php < prev    next >
Encoding:
PHP Script  |  2004-01-26  |  18.6 KB  |  628 lines

  1. <?php /* TASKS $Id: tasks.class.php,v 1.31 2004/01/25 20:24:34 gregorerhardt Exp $ */
  2.  
  3. require_once( $AppUI->getSystemClass( 'libmail' ) );
  4. require_once( $AppUI->getSystemClass( 'dp' ) );
  5. require_once( $AppUI->getModuleClass( 'projects' ) );
  6.  
  7. // user based access
  8. $task_access = array(
  9.     '0'=>'Public',
  10.     '1'=>'Protected',
  11.     '2'=>'Participant',
  12.     '3'=>'Private'
  13. );
  14.  
  15. // this var is intended to track new status in task
  16. $new_status = null;
  17.  
  18. /*
  19. * CTask Class
  20. */
  21. class CTask extends CDpObject {
  22. /** @var int */
  23.     var $task_id = NULL;
  24. /** @var string */
  25.     var $task_name = NULL;
  26. /** @var int */
  27.     var $task_parent = NULL;
  28.     var $task_milestone = NULL;
  29.     var $task_project = NULL;
  30.     var $task_owner = NULL;
  31.     var $task_start_date = NULL;
  32.     var $task_duration = NULL;
  33.     var $task_duration_type = NULL;
  34. /** @deprecated */
  35.     var $task_hours_worked = NULL;
  36.     var $task_end_date = NULL;
  37.     var $task_status = NULL;
  38.     var $task_priority = NULL;
  39.     var $task_percent_complete = NULL;
  40.     var $task_description = NULL;
  41.     var $task_target_budget = NULL;
  42.     var $task_related_url = NULL;
  43.     var $task_creator = NULL;
  44.  
  45.     var $task_order = NULL;
  46.     var $task_client_publish = NULL;
  47.     var $task_dynamic = NULL;
  48.     var $task_access = NULL;
  49.     var $task_notify = NULL;
  50.     var $task_departments = NULL;
  51.     var $task_contacts = NULL;
  52.     var $task_custom = NULL;
  53.  
  54.     
  55.     function CTask() {
  56.         $this->CDpObject( 'tasks', 'task_id' );
  57.     }
  58.  
  59. // overload check
  60.     function check() {
  61.         global $new_status;
  62.         
  63.         if ($this->task_id === NULL) {
  64.             return 'task id is NULL';
  65.         }
  66.     // ensure changes to checkboxes are honoured
  67.         $this->task_milestone = intval( $this->task_milestone );
  68.         $this->task_dynamic   = intval( $this->task_dynamic );
  69.         
  70.         $this->task_percent_complete = intval( $this->task_percent_complete );
  71.     
  72.         if (!$this->task_duration) {
  73.             $this->task_duration = '0';
  74.         }
  75.         if (!$this->task_duration_type) {
  76.             $this->task_duration_type = 1;
  77.         }
  78.         if (!$this->task_related_url) {
  79.             $this->task_related_url = '';
  80.         }
  81.         if (!$this->task_notify) {
  82.             $this->task_notify = 0;
  83.         }
  84.         
  85.         $actual_status = db_loadResult("select task_status from tasks where task_id='$this->task_id'");
  86.         if($actual_status != $this->task_status){
  87.             $new_status = $this->task_status;
  88.         }
  89.         return NULL;
  90.     }
  91.  
  92.     
  93.     function updateDynamics( $fromChildren = false ) {
  94.         //Has a parent or children, we will check if it is dynamic so that it's info is updated also
  95.         
  96.         $modified_task = new CTask();
  97.  
  98.         if ( $fromChildren ){
  99.             $modified_task = &$this;
  100.         } else {
  101.             $modified_task->load($this->task_parent);
  102.         }
  103.  
  104.         if ( $modified_task->task_dynamic == 1 ) {
  105.             //Update allocated hours based on children
  106.             $sql = "SELECT SUM( task_duration * task_duration_type ) from " . $this->_tbl . " WHERE task_parent = " . $modified_task->task_id .
  107.                     " and task_id != " . $modified_task->task_id . " GROUP BY task_parent;";
  108.             $children_allocated_hours = (float) db_loadResult( $sql );
  109.             if ( $modified_task->task_duration_type == 1 ) {
  110.                 $modified_task->task_duration = round($children_allocated_hours,2);
  111.             } else {
  112.                 $modified_task->task_duration = round($children_allocated_hours / $modified_task->task_duration_type, 2);
  113.             }
  114.             
  115.             //Update worked hours based on children
  116.             $sql = "SELECT sum( task_log_hours ) FROM tasks, task_log
  117.                     WHERE task_id = task_log_task AND task_parent = " . $modified_task->task_id .  
  118.                     " AND task_id != " . $modified_task->task_id .
  119.                     " AND task_dynamic = 0";
  120.             $children_hours_worked = (float) db_loadResult( $sql );
  121.             
  122.             
  123.             //Update worked hours based on dynamic children tasks
  124.             $sql = "SELECT sum( task_hours_worked ) FROM tasks
  125.                     WHERE task_dynamic = 1 AND task_parent = " . $modified_task->task_id .
  126.                     " AND task_id != " . $modified_task->task_id;
  127.             $children_hours_worked += (float) db_loadResult( $sql );
  128.             
  129.             $modified_task->task_hours_worked = $children_hours_worked;
  130.                     
  131.             //Update percent complete
  132.             $sql = "SELECT sum( task_percent_complete )  / count( task_percent_complete ) 
  133.                     FROM tasks WHERE task_parent = " . $modified_task->task_id . 
  134.                     " AND task_id != " . $modified_task->task_id;
  135.             $modified_task->task_percent_complete = (float) db_loadResult( $sql );
  136.  
  137.             //Update start date
  138.             $sql = "SELECT min( task_start_date ) FROM tasks
  139.                     WHERE task_parent = " . $modified_task->task_id .
  140.                     " AND task_id != " . $modified_task->task_id .
  141.                     " AND ! isnull( task_start_date ) AND task_start_date !=  '0000-00-00 00:00:00'";
  142.             $modified_task->task_start_date = db_loadResult( $sql );
  143.  
  144.             //Update end date
  145.             $sql = "SELECT max( task_end_date ) FROM tasks
  146.                     WHERE task_parent = " . $modified_task->task_id .
  147.                     " AND task_id != " . $modified_task->task_id .
  148.                     " AND ! isnull( task_end_date ) AND task_end_date !=  '0000-00-00 00:00:00'";
  149.             $modified_task->task_end_date = db_loadResult( $sql );
  150.  
  151.             //If we are updating a dynamic task from its children we don't want to store() it
  152.             //when the method exists the next line in the store calling function will do that
  153.             if ( $fromChildren == false ) $modified_task->store();
  154.         }
  155.     }
  156.  
  157. /**
  158. *    Copy the current task
  159. *
  160. *    @author    handco <handco@users.sourceforge.net>
  161. *    @param    int        id of the destination project
  162. *    @return    object    The new record object or null if error
  163. **/
  164.     function copy($destProject_id = 0) {
  165.         $newObj = $this->clone();
  166.  
  167.         //Fix the parent task
  168.         if ($newObj->task_parent == $this->task_id)
  169.             $newObj->task_parent = $newObj->task_id;
  170.  
  171.         // Copy this task to another project if it's specified
  172.         if ($destProject_id != 0)
  173.             $newObj->task_project = $destProject_id;
  174.  
  175.         $msg = $newObj->store();
  176.  
  177.         return $newObj;
  178.     }// end of copy()
  179.  
  180. /**
  181. * @todo Parent store could be partially used
  182. */
  183.     function store() {
  184.         GLOBAL $AppUI, $new_status;
  185.  
  186.         $msg = $this->check();
  187.         if( $msg ) {
  188.             return get_class( $this )."::store-check failed - $msg";
  189.         }
  190.         if( $this->task_id ) {
  191.             $this->_action = 'updated';
  192.  
  193.             // if task_status chenged, then update subtasks
  194.             if(!is_null($new_status)){
  195.                 $this->updateSubTasksStatus($new_status);
  196.             }
  197.             $this->updateDynamics(true);
  198.  
  199.             $ret = db_updateObject( 'tasks', $this, 'task_id', false );
  200.  
  201.  
  202.         } else {
  203.             $this->_action = 'added';
  204.             $ret = db_insertObject( 'tasks', $this, 'task_id' );
  205.  
  206.             if (!$this->task_parent) {
  207.             // new task, parent = task id
  208.                 $sql = "UPDATE tasks SET task_parent = $this->task_id WHERE task_id = $this->task_id";
  209.                 db_exec( $sql );
  210.             }
  211.         // insert entry in user tasks
  212.             $sql = "INSERT INTO user_tasks (user_id, task_id, user_type) VALUES ($AppUI->user_id, $this->task_id, -1)";
  213.             db_exec( $sql );
  214.         }
  215.  
  216.         if ( $this->task_parent != $this->task_id ){
  217.             //Has parent
  218.             $this->updateDynamics();
  219.         }
  220.  
  221.         if( !$ret ) {
  222.             return get_class( $this )."::store failed <br />" . db_error();
  223.         } else {
  224.             return NULL;
  225.         }
  226.     }
  227.  
  228. /**
  229. * @todo Parent store could be partially used
  230. * @todo Can't delete a task with children
  231. */
  232.     function delete() {
  233.         $this->_action = 'deleted';
  234.     // delete linked user tasks
  235.         $sql = "DELETE FROM user_tasks WHERE task_id = $this->task_id";
  236.         if (!db_exec( $sql )) {
  237.             return db_error();
  238.         }
  239.  
  240.         //load it before deleting it because we need info on it to update the parents later on
  241.         $this->load($this->task_id);
  242.         
  243.         // delete the tasks...what about orphans?
  244.         $sql = "DELETE FROM tasks WHERE task_id = $this->task_id";
  245.         if (!db_exec( $sql )) {
  246.             return db_error();
  247.         } else {
  248.             if ( $this->task_parent != $this->task_id ){
  249.                 // Has parent, run the update sequence, this child will no longer be in the 
  250.                 // database 
  251.                 $this->updateDynamics();
  252.             }
  253.             return NULL;
  254.         }
  255.     }
  256.  
  257.     function updateAssigned( $cslist ) {
  258.     // delete all current entries
  259.         $sql = "DELETE FROM user_tasks WHERE task_id = $this->task_id";
  260.         db_exec( $sql );
  261.  
  262.     // process assignees
  263.         $tarr = explode( ",", $cslist );
  264.         foreach ($tarr as $user_id) {
  265.             if (intval( $user_id ) > 0) {
  266.                 $sql = "REPLACE INTO user_tasks (user_id, task_id) VALUES ($user_id, $this->task_id)";
  267.                 db_exec( $sql );
  268.             }
  269.         }
  270.     }
  271.  
  272.     function updateDependencies( $cslist ) {
  273.     // delete all current entries
  274.         $sql = "DELETE FROM task_dependencies WHERE dependencies_task_id = $this->task_id";
  275.         db_exec( $sql );
  276.  
  277.     // process dependencies
  278.         $tarr = explode( ",", $cslist );
  279.         foreach ($tarr as $task_id) {
  280.             if (intval( $task_id ) > 0) {
  281.                 $sql = "REPLACE INTO task_dependencies (dependencies_task_id, dependencies_req_task_id) VALUES ($this->task_id, $task_id)";
  282.                 db_exec($sql);
  283.             }
  284.         }
  285.     }
  286.     
  287.     /**
  288.     *    Retrieve the tasks dependencies 
  289.     *
  290.     *    @author    handco    <handco@users.sourceforge.net>
  291.     *    @return    string    comma delimited list of tasks id's
  292.     **/
  293.     function getDependencies () {
  294.         // Call the static method for this object
  295.         $result = $this->staticGetDependencies ($this->task_id);
  296.         return $result;
  297.     } // end of getDependencies ()
  298.  
  299.     //}}}
  300.  
  301.     //{{{ staticGetDependencies ()
  302.     /**
  303.     *    Retrieve the tasks dependencies 
  304.     *
  305.     *    @author    handco    <handco@users.sourceforge.net>
  306.     *    @param    integer    ID of the task we want dependencies
  307.     *    @return    string    comma delimited list of tasks id's
  308.     **/
  309.     function staticGetDependencies ($taskId) {
  310.         $sql = "
  311.             SELECT dependencies_req_task_id
  312.             FROM task_dependencies td
  313.             WHERE td.dependencies_task_id = $taskId
  314.         ";
  315.         $hashList = db_loadHashList ($sql);
  316.         $result = implode (',', array_keys ($hashList));
  317.  
  318.         return $result;
  319.     } // end of staticGetDependencies ()
  320.  
  321.     //}}}
  322.  
  323.     function notifyOwner() {
  324.         GLOBAL $AppUI, $locale_char_set;
  325.         
  326.         $sql = "SELECT project_name FROM projects WHERE project_id=$this->task_project";
  327.         $projname = db_loadResult( $sql );
  328.  
  329.         $mail = new Mail;
  330.         
  331.         $mail->Subject( "$projname::$this->task_name ".$AppUI->_($this->_action), $locale_char_set);
  332.  
  333.     // c = creator
  334.     // a = assignee
  335.     // o = owner
  336.         $sql = "SELECT t.task_id,"
  337.         ."\nc.user_email as creator_email,"
  338.         ."\nc.user_first_name as creator_first_name,"
  339.         ."\nc.user_last_name as creator_last_name,"
  340.         ."\no.user_email as owner_email,"
  341.         ."\no.user_first_name as owner_first_name,"
  342.         ."\no.user_last_name as owner_last_name,"
  343.         ."\na.user_id as assignee_id,"
  344.         ."\na.user_email as assignee_email,"
  345.         ."\na.user_first_name as assignee_first_name,"
  346.         ."\na.user_last_name as assignee_last_name"
  347.         ."\nFROM tasks t"
  348.         ."\nLEFT JOIN user_tasks u ON u.task_id = t.task_id"
  349.         ."\nLEFT JOIN users o ON o.user_id = t.task_owner"
  350.         ."\nLEFT JOIN users c ON c.user_id = t.task_creator"
  351.         ."\nLEFT JOIN users a ON a.user_id = u.user_id"
  352.         ."\nWHERE t.task_id = $this->task_id";
  353.         $users = db_loadList( $sql );
  354.  
  355.         if (count( $users )) {
  356.             $body = $AppUI->_('Project').": $projname";
  357.             $body .= "\n".$AppUI->_('Task').":    $this->task_name";
  358.             $body .= "\n".$AppUI->_('URL').":     {$AppUI->cfg['base_url']}/index.php?m=tasks&a=view&task_id=$this->task_id";
  359.             $body .= "\n\n" . $AppUI->_('Description') . ":"
  360.                 . "\n$this->task_description";
  361.             $body .= "\n\n" . $AppUI->_('Creator').":" . $AppUI->user_first_name . " " . $AppUI->user_first_name;
  362.         
  363.             $body .= "\n\n" . $AppUI->_('Progress') . ": " . $this->task_percent_complete . "%";
  364.             $body .= "\n\n" . dPgetParam($_POST, "task_log_description");
  365.             
  366.             
  367.             $mail->Body( $body, isset( $GLOBALS['locale_char_set']) ? $GLOBALS['locale_char_set'] : "" );
  368.             $mail->From ( '"' . $AppUI->user_first_name . " " . $AppUI->user_last_name 
  369.                 . '" <' . $AppUI->user_email . '>'
  370.             );
  371.         }
  372.         
  373.         if ($mail->ValidEmail($users[0]['owner_email'])) {
  374.             $mail->To( $users[0]['owner_email'], true );
  375.             $mail->Send();
  376.         }
  377.         
  378.         return '';
  379.     }
  380.     
  381.     function notify() {
  382.         GLOBAL $AppUI, $locale_char_set;
  383.         
  384.         $sql = "SELECT project_name FROM projects WHERE project_id=$this->task_project";
  385.         $projname = db_loadResult( $sql );
  386.  
  387.         $mail = new Mail;
  388.         
  389.         $mail->Subject( "$projname::$this->task_name ".$AppUI->_($this->_action), $locale_char_set);
  390.  
  391.     // c = creator
  392.     // a = assignee
  393.     // o = owner
  394.         $sql = "SELECT t.task_id,"
  395.         ."\nc.user_email as creator_email,"
  396.         ."\nc.user_first_name as creator_first_name,"
  397.         ."\nc.user_last_name as creator_last_name,"
  398.         ."\no.user_email as owner_email,"
  399.         ."\no.user_first_name as owner_first_name,"
  400.         ."\no.user_last_name as owner_last_name,"
  401.         ."\na.user_id as assignee_id,"
  402.         ."\na.user_email as assignee_email,"
  403.         ."\na.user_first_name as assignee_first_name,"
  404.         ."\na.user_last_name as assignee_last_name"
  405.         ."\nFROM tasks t"
  406.         ."\nLEFT JOIN user_tasks u ON u.task_id = t.task_id"
  407.         ."\nLEFT JOIN users o ON o.user_id = t.task_owner"
  408.         ."\nLEFT JOIN users c ON c.user_id = t.task_creator"
  409.         ."\nLEFT JOIN users a ON a.user_id = u.user_id"
  410.         ."\nWHERE t.task_id = $this->task_id";
  411.         $users = db_loadList( $sql );
  412.  
  413.         if (count( $users )) {
  414.             $body = $AppUI->_('Project').": $projname";
  415.             $body .= "\n".$AppUI->_('Task').":    $this->task_name";
  416.             $body .= "\n".$AppUI->_('URL').":     {$AppUI->cfg['base_url']}/index.php?m=tasks&a=view&task_id=$this->task_id";
  417.             $body .= "\n\n" . $AppUI->_('Description') . ":"
  418.                 . "\n$this->task_description";
  419.             if ($users[0]['creator_email']) {
  420.                 $body .= "\n\n" . $AppUI->_('Creator').":"
  421.                     . "\n" . $users[0]['creator_first_name'] . " " . $users[0]['creator_last_name' ]
  422.                     . ", " . $users[0]['creator_email'];
  423.             }
  424.             $body .= "\n\n" . $AppUI->_('Owner').":"
  425.                 . "\n" . $users[0]['owner_first_name'] . " " . $users[0]['owner_last_name' ]
  426.                 . ", " . $users[0]['owner_email'];
  427.  
  428.             $mail->Body( $body, isset( $GLOBALS['locale_char_set']) ? $GLOBALS['locale_char_set'] : "" );
  429.             $mail->From ( '"' . $AppUI->user_first_name . " " . $AppUI->user_last_name 
  430.                 . '" <' . $AppUI->user_email . '>'
  431.             );
  432.         }
  433.  
  434.         foreach ($users as $row) {
  435.             if ($row['assignee_id'] != $AppUI->user_id) {
  436.                 if ($mail->ValidEmail($row['assignee_email'])) {
  437.                     $mail->To( $row['assignee_email'], true );
  438.                     $mail->Send();
  439.                 }
  440.             }
  441.         }
  442.         return '';
  443.     }
  444. /**
  445. * @param Date Start date of the period
  446. * @param Date End date of the period
  447. * @param integer The target company
  448. */
  449.     function getTasksForPeriod( $start_date, $end_date, $company_id=0 ) {
  450.         GLOBAL $AppUI;
  451.     // convert to default db time stamp
  452.         $db_start = $start_date->format( FMT_DATETIME_MYSQL );
  453.         $db_end = $end_date->format( FMT_DATETIME_MYSQL );
  454.         
  455.         // filter tasks for not allowed projects
  456.         $tasks_filter = '';
  457.         $join = winnow('projects', 'task_project', $tasks_filter);
  458.  
  459.     // assemble where clause
  460.         $where = "task_project = project_id"
  461.             . "\n\tAND ("
  462.             . "\n\t\t(task_start_date <= '$db_end' AND task_end_date >= '$db_start')"
  463.             . "\n\t\tOR task_start_date BETWEEN '$db_start' AND '$db_end'"
  464.             . "\n\t)"
  465.             . "\n\tAND ($tasks_filter)";
  466.     /*
  467.             OR
  468.             task_end_date BETWEEN '$db_start' AND '$db_end'
  469.             OR
  470.             (DATE_ADD(task_start_date, INTERVAL task_duration HOUR)) BETWEEN '$db_start' AND '$db_end'
  471.             OR
  472.             (DATE_ADD(task_start_date, INTERVAL task_duration DAY)) BETWEEN '$db_start' AND '$db_end'
  473.     */
  474.         $where .= $company_id ? "\n\tAND project_company = $company_id" : '';
  475.  
  476.     // exclude read denied projects
  477.         $obj = new CProject();
  478.         $deny = $obj->getDeniedRecords( $AppUI->user_id );
  479.  
  480.         $where .= count($deny) > 0 ? "\n\tAND task_project NOT IN (" . implode( ',', $deny ) . ')' : '';
  481.  
  482.     // get any specifically denied tasks
  483.         $obj = new CTask();
  484.         $deny = $obj->getDeniedRecords( $AppUI->user_id );
  485.  
  486.         $where .= count($deny) > 0 ? "\n\tAND task_id NOT IN (" . implode( ',', $deny ) . ')' : '';
  487.  
  488.     // assemble query
  489.         $sql = "SELECT task_name, task_id, task_start_date, task_end_date,"
  490.             . "\n\ttask_duration, task_duration_type,"
  491.             . "\n\tproject_color_identifier AS color,"
  492.             . "\n\tproject_name"
  493.             . "\nFROM tasks,projects"
  494.             . "\n$join"
  495.             . "\nWHERE $where"
  496.             . "\nORDER BY task_start_date";
  497. //echo "<pre>$sql</pre>";
  498.     // execute and return
  499.         return db_loadList( $sql );
  500.     }
  501.  
  502.     function canAccess( $user_id ) {
  503.         //echo intval($this->task_access);
  504.         switch ($this->task_access) {
  505.             case 0:
  506.                 // public
  507.                 return true;
  508.                 break;
  509.             case 1:
  510.                 // protected
  511.                 $sql = "SELECT user_company FROM users WHERE user_id=$user_id";
  512.                 $user_company = db_loadResult( $sql );
  513.                 $sql = "SELECT user_company FROM users WHERE user_id=$this->task_owner";
  514.                 $owner_company = db_loadResult( $sql );
  515.                 //echo "$user_company,$owner_company";die;
  516.  
  517.                 $sql = "SELECT COUNT(*) FROM user_tasks WHERE user_id=$user_id AND task_id=$this->task_id";
  518.                 $count = db_loadResult( $sql );
  519.                 return (($owner_company == $user_company && $count > 0) || $this->task_owner == $user_id);
  520.                 break;
  521.             case 2:
  522.                 // participant
  523.                 $sql = "SELECT COUNT(*) FROM user_tasks WHERE user_id=$user_id AND task_id=$this->task_id";
  524.                 $count = db_loadResult( $sql );
  525.                 return ($count > 0 || $this->task_owner == $user_id);
  526.                 break;
  527.             case 3:
  528.                 // private
  529.                 return ($this->task_owner == $user_id);
  530.                 break;
  531.         }
  532.     }
  533.     
  534.     /**
  535.     * Function that returns the amount of hours this
  536.     * task consumes per user each day
  537.     */
  538.     function getTaskDurationPerDay(){
  539.         $duration              = $this->task_duration*$this->task_duration_type;
  540.         $task_start_date       = new CDate($this->task_start_date);
  541.         $task_finish_date      = new CDate($this->task_end_date);
  542.         $number_assigned_users = count($this->getAssignedUsers());
  543.         
  544.         $day_diff              = $task_finish_date->dateDiff($task_start_date);
  545.         $number_of_days_worked = 0;
  546.         $actual_date           = $task_start_date;
  547.  
  548.         for($i=0; $i<=$day_diff; $i++){
  549.             if($actual_date->isWorkingDay()){
  550.                 $number_of_days_worked++;
  551.             }
  552.             $actual_date->addDays(1);
  553.         }
  554.         // May be it was a Sunday task
  555.         if($number_of_days_worked == 0) $number_of_days_worked = 1;
  556.         if($number_assigned_users == 0) $number_assigned_users = 1;
  557.         return ($duration/$number_assigned_users) / $number_of_days_worked;
  558.     }
  559.     
  560.     function getAssignedUsers(){
  561.         $sql = "select u.*
  562.                 from users as u, user_tasks as ut
  563.                 where ut.task_id = '$this->task_id'
  564.                       and ut.user_id = u.user_id";
  565.         return db_loadHashList($sql, "user_id");
  566.     }
  567.     
  568.     //Returns task children IDs
  569.     function getChildren() {
  570.         $sql = "select task_id from tasks where task_id != '$this->task_id'
  571.                 and task_parent = '$this->task_id'";
  572.         return db_loadList($sql);
  573.     }
  574.         
  575.     
  576.     /**
  577.     * This function, recursively, updates all tasks status
  578.     * to the one passed as parameter
  579.     */ 
  580.     function updateSubTasksStatus($new_status, $task_id = null){
  581.         if(is_null($task_id)){
  582.             $task_id = $this->task_id;
  583.         }
  584.         
  585.         $sql = "select task_id
  586.                 from tasks
  587.                 where task_parent = '$task_id'";
  588.         
  589.         $tasks_id = db_loadColumn($sql);
  590.         if(count($tasks_id) == 0) return true;
  591.         
  592.         $sql = "update tasks set task_status = '$new_status' where task_parent = '$task_id'";
  593.  
  594.         db_exec($sql);
  595.         foreach($tasks_id as $id){
  596.             if($id != $task_id){
  597.                 $this->updateSubTasksStatus($new_status, $id);
  598.             }
  599.         }
  600.     }
  601. }
  602.  
  603.  
  604. /**
  605. * CTask Class
  606. */
  607. class CTaskLog extends CDpObject {
  608.     var $task_log_id = NULL;
  609.     var $task_log_task = NULL;
  610.     var $task_log_name = NULL;
  611.     var $task_log_description = NULL;
  612.     var $task_log_creator = NULL;
  613.     var $task_log_hours = NULL;
  614.     var $task_log_date = NULL;
  615.     var $task_log_costcode = NULL;
  616.  
  617.     function CTaskLog() {
  618.         $this->CDpObject( 'task_log', 'task_log_id' );
  619.     }
  620.  
  621. // overload check method
  622.     function check() {
  623.         $this->task_log_hours = (float) $this->task_log_hours;
  624.         return NULL;
  625.     }
  626. }
  627. ?>
  628.