[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/modules/projects/ -> projects.class.php (source)

   1  <?php /* $Id: projects.class.php 193 2008-07-28 18:25:40Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/projects/projects.class.php $ */
   2  if (!defined('W2P_BASE_DIR')) {
   3      die('You should not access this file directly.');
   4  }
   5  
   6  /**
   7   *    @package web2Project
   8   *    @subpackage modules
   9   *    @version $Revision: 193 $
  10   */
  11  require_once ($AppUI->getSystemClass('libmail'));
  12  require_once ($AppUI->getSystemClass('w2p'));
  13  require_once ($AppUI->getLibraryClass('PEAR/Date'));
  14  require_once ($AppUI->getModuleClass('tasks'));
  15  require_once ($AppUI->getModuleClass('companies'));
  16  require_once ($AppUI->getModuleClass('departments'));
  17  require_once ($AppUI->getModuleClass('files'));
  18  
  19  // project statii
  20  $pstatus = w2PgetSysVal('ProjectStatus');
  21  $ptype = w2PgetSysVal('ProjectType');
  22  
  23  $ppriority_name = w2PgetSysVal('ProjectPriority');
  24  $ppriority_color = w2PgetSysVal('ProjectPriorityColor');
  25  
  26  $priority = array();
  27  foreach ($ppriority_name as $key => $val) {
  28      $priority[$key]['name'] = $val;
  29  }
  30  foreach ($ppriority_color as $key => $val) {
  31      $priority[$key]['color'] = $val;
  32  }
  33  
  34  /*
  35  // kept for reference
  36  $priority = array(
  37  -1 => array(
  38  'name' => 'low',
  39  'color' => '#E5F7FF'
  40  ),
  41  0 => array(
  42  'name' => 'normal',
  43  'color' => ''//#CCFFCA
  44  ),
  45  1 => array(
  46  'name' => 'high',
  47  'color' => '#FFDCB3'
  48  ),
  49  2 => array(
  50  'name' => 'immediate',
  51  'color' => '#FF887C'
  52  )
  53  );
  54  */
  55  
  56  /**
  57   * The Project Class
  58   */
  59  class CProject extends CW2pObject {
  60      var $project_id = null;
  61      var $project_company = null;
  62      var $project_department = null;
  63      var $project_name = null;
  64      var $project_short_name = null;
  65      var $project_owner = null;
  66      var $project_url = null;
  67      var $project_demo_url = null;
  68      var $project_start_date = null;
  69      var $project_end_date = null;
  70      var $project_actual_end_date = null;
  71      var $project_status = null;
  72      var $project_percent_complete = null;
  73      var $project_color_identifier = null;
  74      var $project_description = null;
  75      var $project_target_budget = null;
  76      var $project_actual_budget = null;
  77      var $project_creator = null;
  78      var $project_active = null;
  79      var $project_private = null;
  80      var $project_departments = null;
  81      var $project_contacts = null;
  82      var $project_priority = null;
  83      var $project_type = null;
  84      var $project_parent = null;
  85      var $project_original_parent = null;
  86      var $project_location = null;
  87  
  88  	function CProject() {
  89          $this->CW2pObject('projects', 'project_id');
  90      }
  91  
  92  	function check() {
  93          // ensure changes of state in checkboxes is captured
  94          $this->project_active = intval($this->project_active);
  95          $this->project_private = intval($this->project_private);
  96  
  97          $this->project_target_budget = $this->project_target_budget ? $this->project_target_budget : 0.00;
  98          $this->project_actual_budget = $this->project_actual_budget ? $this->project_actual_budget : 0.00;
  99  
 100          // Make sure project_short_name is the right size (issue for languages with encoded characters)
 101          if (strlen($this->project_short_name) > 10) {
 102              $this->project_short_name = substr($this->project_short_name, 0, 10);
 103          }
 104          if (empty($this->project_end_date)) {
 105              $this->project_end_date = null;
 106          }
 107          return null; // object is ok
 108      }
 109  
 110  	function load($oid = null, $strip = true) {
 111          $result = parent::load($oid, $strip);
 112          if ($result && $oid) {
 113              $working_hours = (w2PgetConfig('daily_working_hours') ? w2PgetConfig('daily_working_hours') : 8);
 114  
 115              $q = new DBQuery;
 116              $q->addTable('projects');
 117              $q->addQuery('SUM(t1.task_duration * t1.task_percent_complete * IF(t1.task_duration_type = 24, ' . $working_hours . ', t1.task_duration_type)) / SUM(t1.task_duration * IF(t1.task_duration_type = 24, ' . $working_hours . ', t1.task_duration_type)) AS project_percent_complete');
 118              $q->addJoin('tasks', 't1', 'projects.project_id = t1.task_project', 'inner');
 119              $q->addWhere('project_id = ' . $oid . ' AND t1.task_id = t1.task_parent');
 120              $this->project_percent_complete = $q->loadResult();
 121          }
 122          return $result;
 123      }
 124      // overload canDelete
 125  	function canDelete(&$msg, $oid = null) {
 126          // TODO: check if user permissions are considered when deleting a project
 127          global $AppUI;
 128          $perms = &$AppUI->acl();
 129  
 130          return $perms->checkModuleItem('projects', 'delete', $oid);
 131  
 132          // NOTE: I uncommented the dependencies check since it is
 133          // very anoying having to delete all tasks before being able
 134          // to delete a project.
 135  
 136          /*
 137          $tables[] = array( 'label' => 'Tasks', 'name' => 'tasks', 'idfield' => 'task_id', 'joinfield' => 'task_project' );
 138          // call the parent class method to assign the oid
 139          return CW2pObject::canDelete( $msg, $oid, $tables );
 140          */
 141      }
 142  
 143  	function delete() {
 144          $this->load($this->project_id);
 145          addHistory('projects', $this->project_id, 'delete', $this->project_name, $this->project_id);
 146          $q = new DBQuery;
 147          $q->addTable('tasks');
 148          $q->addQuery('task_id');
 149          $q->addWhere('task_project = ' . (int)$this->project_id);
 150          $tasks_to_delete = $q->loadColumn();
 151          $q->clear();
 152          foreach ($tasks_to_delete as $task_id) {
 153              $q->setDelete('user_tasks');
 154              $q->addWhere('task_id =' . $task_id);
 155              $q->exec();
 156              $q->clear();
 157              $q->setDelete('task_dependencies');
 158              $q->addWhere('dependencies_req_task_id =' . (int)$task_id);
 159              $q->exec();
 160              $q->clear();
 161          }
 162          $q->setDelete('tasks');
 163          $q->addWhere('task_project =' . (int)$this->project_id);
 164          $q->exec();
 165          $q->clear();
 166          $q = new DBQuery;
 167          $q->addTable('files');
 168          $q->addQuery('file_id');
 169          $q->addWhere('file_project = ' . (int)$this->project_id);
 170          $files_to_delete = $q->loadColumn();
 171          $q->clear();
 172          foreach ($files_to_delete as $file_id) {
 173              $file = new CFile();
 174              $file->file_id = $file_id;
 175              $file->file_project = (int)$this->project_id;
 176              $file->delete();
 177          }
 178          // remove the project-contacts and project-departments map
 179          $q->setDelete('project_contacts');
 180          $q->addWhere('project_id =' . (int)$this->project_id);
 181          $q->exec();
 182          $q->clear();
 183          $q->setDelete('project_departments');
 184          $q->addWhere('project_id =' . (int)$this->project_id);
 185          $q->exec();
 186          $q->clear();
 187          $q->setDelete('projects');
 188          $q->addWhere('project_id =' . (int)$this->project_id);
 189  
 190          if (!$q->exec()) {
 191              $result = db_error();
 192          } else {
 193              $result = null;
 194          }
 195          $q->clear();
 196          return $result;
 197      }
 198  
 199      /**    Import tasks from another project
 200       *
 201       *    @param    int        Project ID of the tasks come from.
 202       *    @return    bool    
 203       **/
 204  	function importTasks($from_project_id) {
 205  
 206          // Load the original
 207          $origProject = new CProject();
 208          $origProject->load($from_project_id);
 209          $q = new DBQuery;
 210          $q->addTable('tasks');
 211          $q->addQuery('task_id');
 212          $q->addWhere('task_project =' . (int)$from_project_id);
 213          $tasks = array_flip($q->loadColumn());
 214          $q->clear();
 215  
 216          $origDate = new CDate($origProject->project_start_date);
 217  
 218          $destDate = new CDate($this->project_start_date);
 219  
 220          $timeOffset = $origDate->dateDiff($destDate);
 221          if ($origDate->compare($origDate, $destDate) > 0) {
 222              $timeOffset = -1 * $timeOffset;
 223          }
 224  
 225          // Dependencies array
 226          $deps = array();
 227  
 228          // Copy each task into this project and get their deps
 229          foreach ($tasks as $orig => $void) {
 230              $objTask = new CTask();
 231              $objTask->load($orig);
 232              $destTask = $objTask->copy($this->project_id);
 233              $tasks[$orig] = $destTask;
 234              $deps[$orig] = $objTask->getDependencies();
 235          }
 236  
 237          // Fix record integrity
 238          foreach ($tasks as $old_id => $newTask) {
 239  
 240              // Fix parent Task
 241              // This task had a parent task, adjust it to new parent task_id
 242              if ($newTask->task_id != $newTask->task_parent)
 243                  $newTask->task_parent = $tasks[$newTask->task_parent]->task_id;
 244  
 245              // Fix task start date from project start date offset
 246              $origDate->setDate($newTask->task_start_date);
 247              //$destDate->setDate ($origDate->getTime() + $timeOffset , DATE_FORMAT_UNIXTIME );
 248              $origDate->addDays($timeOffset);
 249              $destDate = $origDate;
 250              //$destDate = $destDate->next_working_day( );
 251              $newTask->task_start_date = $destDate->format(FMT_DATETIME_MYSQL);
 252  
 253              // Fix task end date from start date + work duration
 254              //$newTask->calc_task_end_date();
 255              if (!empty($newTask->task_end_date) && $newTask->task_end_date != '0000-00-00 00:00:00') {
 256                  $origDate->setDate($newTask->task_end_date);
 257                  //$destDate->setDate ($origDate->getTime() + $timeOffset , DATE_FORMAT_UNIXTIME );
 258                  $origDate->addDays($timeOffset);
 259                  $destDate = $origDate;
 260                  //$destDate = $destDate->next_working_day();
 261                  $newTask->task_end_date = $destDate->format(FMT_DATETIME_MYSQL);
 262              }
 263  
 264              // Dependencies
 265              if (!empty($deps[$old_id])) {
 266                  $oldDeps = explode(',', $deps[$old_id]);
 267                  // New dependencies array
 268                  $newDeps = array();
 269                  foreach ($oldDeps as $dep) {
 270                      $newDeps[] = $tasks[$dep]->task_id;
 271                  }
 272  
 273                  // Update the new task dependencies
 274                  $csList = implode(',', $newDeps);
 275                  $newTask->updateDependencies($csList);
 276              } // end of update dependencies
 277              $newTask->store();
 278          } // end Fix record integrity
 279  
 280      } // end of importTasks
 281  
 282      /**
 283       **    Overload of the w2PObject::getAllowedRecords 
 284       **    to ensure that the allowed projects are owned by allowed companies.
 285       **
 286       **    @author    handco <handco@sourceforge.net>
 287       **    @see    w2PObject::getAllowedRecords
 288       **/
 289  
 290  	function getAllowedRecords($uid, $fields = '*', $orderby = '', $index = null, $extra = null, $table_alias = '') {
 291          $oCpy = new CCompany();
 292  
 293          $aCpies = $oCpy->getAllowedRecords($uid, 'company_id, company_name');
 294          if (count($aCpies)) {
 295              $buffer = '(project_company IN (' . implode(',', array_keys($aCpies)) . '))';
 296  
 297              if (!$extra['from'] && !$extra['join']) {
 298                  $extra['join'] = 'project_departments';
 299                  $extra['on'] = 'projects.project_id = project_departments.project_id';
 300              } elseif ($extra['from'] != 'project_departments' && !$extra['join']) {
 301                  $extra['join'] = 'project_departments';
 302                  $extra['on'] = 'projects.project_id = project_departments.project_id';
 303              }
 304              //Department permissions
 305              $oDpt = new CDepartment();
 306              $aDpts = $oDpt->getAllowedRecords($uid, 'dept_id, dept_name');
 307              if (count($aDpts)) {
 308                  $dpt_buffer = '(department_id IN (' . implode(',', array_keys($aDpts)) . ') OR department_id IS NULL)';
 309              } else {
 310                  // There are no allowed departments, so allow projects with no department.
 311                  $dpt_buffer = '(department_id IS NULL)';
 312              }
 313  
 314              if ($extra['where'] != '') {
 315                  $extra['where'] = $extra['where'] . ' AND ' . $buffer . ' AND ' . $dpt_buffer;
 316              } else {
 317                  $extra['where'] = $buffer . ' AND ' . $dpt_buffer;
 318              }
 319          } else {
 320              // There are no allowed companies, so don't allow projects.
 321              if ($extra['where'] != '') {
 322                  $extra['where'] = $extra['where'] . ' AND 1 = 0 ';
 323              } else {
 324                  $extra['where'] = '1 = 0';
 325              }
 326          }
 327          return parent::getAllowedRecords($uid, $fields, $orderby, $index, $extra, $table_alias);
 328  
 329      }
 330  
 331  	function getAllowedSQL($uid, $index = null) {
 332          $oCpy = new CCompany();
 333          $where = $oCpy->getAllowedSQL($uid, 'project_company');
 334  
 335          $oDpt = new CDepartment();
 336          $where += $oDpt->getAllowedSQL($uid, 'dept_id');
 337  
 338          $project_where = parent::getAllowedSQL($uid, $index);
 339          return array_merge($where, $project_where);
 340      }
 341  
 342  	function setAllowedSQL($uid, &$query, $index = null, $key = null) {
 343          $oCpy = new CCompany;
 344          parent::setAllowedSQL($uid, $query, $index, $key);
 345          $oCpy->setAllowedSQL($uid, $query, ($key ? $key . '.' : '').'project_company');
 346          //Department permissions
 347          $oDpt = new CDepartment();
 348          $query->leftJoin('project_departments', '', 'pr.project_id = project_departments.project_id');
 349          $oDpt->setAllowedSQL($uid, $query, 'project_departments.department_id');
 350      }
 351  
 352      /**
 353       *    Overload of the w2PObject::getDeniedRecords 
 354       *    to ensure that the projects owned by denied companies are denied.
 355       *
 356       *    @author    handco <handco@sourceforge.net>
 357       *    @see    w2PObject::getAllowedRecords
 358       */
 359  	function getDeniedRecords($uid) {
 360          $aBuf1 = parent::getDeniedRecords($uid);
 361  
 362          $oCpy = new CCompany();
 363          // Retrieve which projects are allowed due to the company rules
 364          $aCpiesAllowed = $oCpy->getAllowedRecords($uid, 'company_id,company_name');
 365  
 366          //Department permissions
 367          $oDpt = new CDepartment();
 368          $aDptsAllowed = $oDpt->getAllowedRecords($uid, 'dept_id,dept_name');
 369  
 370          $q = new DBQuery;
 371          $q->addTable('projects');
 372          $q->addQuery('projects.project_id');
 373          $q->addJoin('project_departments', 'pd', 'pd.project_id = projects.project_id');
 374  
 375          if (count($aCpiesAllowed)) {
 376              if ((array_search('0', $aCpiesAllowed)) === false) {
 377                  //If 0 (All Items of a module) are not permited then just add the allowed items only
 378                  $q->addWhere('NOT (project_company IN (' . implode(',', array_keys($aCpiesAllowed)) . '))');
 379              } else {
 380                  //If 0 (All Items of a module) are permited then don't add a where clause so the user is permitted to see all
 381              }
 382          } else {
 383              //if the user is not allowed any company then lets shut him off
 384              $q->addWhere('0=1');
 385          }
 386  
 387          if (count($aDptsAllowed)) {
 388              if ((array_search('0', $aDptsAllowed)) === false) {
 389                  //If 0 (All Items of a module) are not permited then just add the allowed items only
 390                  $q->addWhere('NOT (department_id IN (' . implode(',', array_keys($aDptsAllowed)) . '))');
 391              } else {
 392                  //If 0 (All Items of a module) are permited then don't add a where clause so the user is permitted to see all
 393                  $q->addWhere('NOT (department_id IS NULL)');
 394              }
 395          } else {
 396              //If 0 (All Items of a module) are permited then don't add a where clause so the user is permitted to see all
 397              $q->addWhere('NOT (department_id IS NULL)');
 398          }
 399  
 400          /*If (count($aCpiesAllowed)) {
 401          $q->addWhere('NOT (project_company IN (' . implode (',', array_keys($aCpiesAllowed)) . '))');
 402          }*/
 403          //Department permissions
 404          /*If (count($aDptsAllowed)) {
 405          $q->addWhere('NOT (department_id IN (' . implode (',', array_keys($aDptsAllowed)) . '))');
 406          } else {
 407          $q->addWhere('NOT (department_id IS NULL)');
 408          }*/
 409          $aBuf2 = $q->loadColumn();
 410          $q->clear();
 411  
 412          return array_merge($aBuf1, $aBuf2);
 413  
 414      }
 415  	function getAllowedProjectsInRows($userId) {
 416          $q = new DBQuery;
 417          $q->addQuery('pr.project_id, project_status, project_name, project_description, project_short_name');
 418          $q->addTable('projects', 'pr');
 419          $q->addOrder('project_short_name');
 420          $this->setAllowedSQL($userId, $q, null, 'pr');
 421