[ Index ]
 

Code source de eGroupWare 1.2.106-2

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/projectmanager/inc/ -> class.boprojectelements.inc.php (source)

   1  <?php
   2  /**************************************************************************\
   3  * eGroupWare - ProjectManager - Elements business object                   *
   4  * http://www.egroupware.org                                                *
   5  * Written and (c) 2005 by Ralf Becker <RalfBecker@outdoor-training.de>     *
   6  * --------------------------------------------                             *
   7  *  This program is free software; you can redistribute it and/or modify it *
   8  *  under the terms of the GNU General Public License as published by the   *
   9  *  Free Software Foundation; either version 2 of the License, or (at your  *
  10  *  option) any later version.                                              *
  11  \**************************************************************************/
  12  
  13  /* $Id: class.boprojectelements.inc.php 21518 2006-05-13 06:09:28Z ralfbecker $ */
  14  
  15  include_once (EGW_INCLUDE_ROOT.'/projectmanager/inc/class.soprojectelements.inc.php');
  16  
  17  /**
  18   * Elements business object of the projectmanager
  19   *
  20   * @package projectmanager
  21   * @author RalfBecker-AT-outdoor-training.de
  22   * @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de
  23   * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
  24   */
  25  class boprojectelements extends soprojectelements
  26  {
  27      /**
  28       * @var int/string $debug 0 = no debug-messages, 1 = main, 2 = more, 3 = all, 4 = all incl. so_sql, or string with function-name to debug
  29       */
  30      var $debug=false;
  31      /**
  32       * @var bolink-object $link instance of the link-class
  33       */
  34      var $link;
  35      /**
  36       * @var boprojectmanager-object $link instance of the boprojectmanager-class
  37       */
  38      var $project;
  39      /**
  40       * @var array $project_summary array with summary information of the current project
  41       */
  42      var $project_summary;
  43      /**
  44       * @var soconstraints-object $constraints instance of the soconstraints-class
  45       */
  46      var $constraints;
  47      /**
  48       * @var somilestones-object $milestones instance of the somilestones-class
  49       */
  50      var $milestones;
  51      /**
  52       * @var array $datasources instances of the different datasources
  53       */
  54      var $datasources = array();
  55      /**
  56       * @var array $timestamps timestaps that need to be adjusted to user-time on reading or saving
  57       */
  58      var $timestamps = array(
  59          'pe_synced','pe_modified','pe_planned_start','pe_real_start','pe_planned_end','pe_real_end',
  60      );
  61      /**
  62       * @var int $tz_offset_s offset in secconds between user and server-time,
  63       *    it need to be add to a server-time to get the user-time or substracted from a user-time to get the server-time
  64       */
  65      var $tz_offset_s;
  66      /**
  67       * @var int $now_su is the time as timestamp in user-time
  68       */
  69      var $now_su;
  70      /**
  71       * @var array $status_filter translates filter-values to allowed stati
  72       */
  73      var $status_filter = array(
  74          'all'     => false,
  75          'used'    => array('new','regular'),
  76          'new'     => 'new',
  77          'ignored' => 'ignore',
  78      );
  79      /**
  80       * @var int $updated or'ed id's of the values set by the last call to the updated method
  81       */
  82      var $updated = 0;
  83  
  84      /**
  85       * Constructor, class the constructor of the extended class
  86       * 
  87       * @param int $pm_id pm_id of the project to use, default null
  88       * @param int $pe_id pe_id of the project-element to load, default null
  89       */
  90  	function boprojectelements($pm_id=null,$pe_id=null)
  91      {
  92          if (!is_object($GLOBALS['egw']->datetime))
  93          {
  94              $GLOBALS['egw']->datetime =& CreateObject('phpgwapi.datetime');
  95          }
  96          $this->tz_offset_s = $GLOBALS['egw']->datetime->tz_offset;
  97          $this->now_su = time() + $this->tz_offset_s;
  98          
  99          $this->soprojectelements($pm_id,$pe_id);
 100          
 101          if (!is_object($GLOBALS['egw']->link))
 102          {
 103              $GLOBALS['egw']->link =& CreateObject('phpgwapi.bolink');
 104          }
 105          $this->link =& $GLOBALS['egw']->link;
 106  
 107          $this->project =& CreateObject('projectmanager.boprojectmanager',$pm_id);
 108          $this->config =& $this->project->config;
 109          
 110          $this->project->instanciate('constraints,milestones');
 111          $this->constraints =& $this->project->constraints;
 112          $this->milestones  =& $this->project->milestones;
 113          
 114          $this->project_summary = $this->summary();
 115          
 116          if ((int)$this->debug >= 3 || $this->debug == 'boprojectelements')
 117          {
 118              $this->debug_message(function_backtrace()."\nboprojectelements::boprojectelements($pm_id,$pe_id) data=".print_r($this->data,true));
 119          }
 120          // save us in $GLOBALS['boprojectselements'] for ExecMethod used in hooks
 121          if (!is_object($GLOBALS['boprojectselements']))
 122          {
 123              $GLOBALS['boprojectselements'] =& $this;
 124          }
 125      }
 126      
 127      /**
 128       * receives notifications from the link-class: new, deleted links to pm entries, or updated content of linked entries
 129       *
 130       * We only process link- & update-notifications to parent-projects!
 131       * A project P is the parent of an other project C, if link_id1=P.pm_id and link_id2=C.pm_id !
 132       *
 133       * @param array $data array with keys type, id, target_app, target_id, link_id, data
 134       */
 135  	function notify($data)
 136      {
 137          if ((int) $this->debug >= 2 || $this->debug == 'notify') $this->debug_message("boprojectelements::notify(link_id=$data[link_id], type=$data[type], target=$data[target_app]-$data[target_id])");
 138  
 139          switch($data['type'])
 140          {
 141              case 'link':
 142              case 'update':
 143                  // for projectmanager we need to check the direction of the link
 144                  if ($data['target_app'] == 'projectmanager')
 145                  {
 146                      $link = $this->link->get_link($data['link_id']);
 147                      if ($link['link_id2'] == $data['id'])
 148                      {
 149                          return;    // this is a notification to a child / subproject --> ignore it
 150                      }
 151                      // for new links we need to make sure the new child is not an ancestor of us
 152                      if ($data['type'] == 'link')
 153                      {
 154                          if (($ancestors = $this->project->ancestors($data['id'])) && in_array($data['target_id'],$ancestors))
 155                          {
 156                              if ((int) $this->debug >= 2 || $this->debug == 'notify') $this->debug_message("boprojectelements::notify: cant use pm_id=$data[target_id] as child as it's one of our (pm_id=$data[id]) ancestors=".print_r($ancestors,true));
 157                              return;    // the link is not used as an project-element, thought it's still a regular link
 158                          }
 159                          if ((int) $this->debug >= 3 || $this->debug == 'notify') $this->debug_message("boprojectelements::notify: ancestors($data[id])=".print_r($ancestors,true));
 160                      }
 161                  }
 162                  $this->update($data['target_app'],$data['target_id'],$data['link_id'],$data['id']);
 163                  break;
 164  
 165              case 'unlink':
 166                  $this->delete(array('pm_id' => $data['id'],'pe_id' => $data['link_id']));
 167                  break;
 168                  
 169          }
 170      }
 171  
 172      /**
 173       * Updates / creates a project-element with the data of it's datasource
 174       *
 175       * Sets additionally $this->updated with the or'ed id's of the updated values
 176       *
 177       * ToDo: if end-date changed, update elements which have "us" as start-constrain
 178       *
 179       * @param string $app appname
 180       * @param string $id id of $app as used by the link-class and the datasource
 181       * @param int $pe_id=0 element- / link-id or 0 to only read and return the entry, but not save it!
 182       * @param int $pm_id=null project-id, default $this->pm_id
 183       * @param boolean $update_project=true update the data in the project if necessary
 184       * @return array/boolean the updated project-element or false on error (eg. no read access)
 185       */
 186      function &update($app,$id,$pe_id=0,$pm_id=null,$update_project=true)
 187      {
 188          if (!$pm_id) $pm_id = $this->pm_id;
 189          
 190          if ((int) $this->debug >= 2 || $this->debug == 'update') $this->debug_message("boprojectelements::update(app='$app',id='$id',pe_id=$pe_id,pm_id=$pm_id)");
 191  
 192          if (!$app || !$id || !(int) $pm_id)
 193          {
 194              return false;
 195          }
 196          $this->init();
 197          $need_save_anyway = false;
 198          // check if entry already exists and set basic values if not
 199          if (!$pe_id || ($need_save_anyway = !$this->read(array('pm_id'=>$pm_id,'pe_id'=>$pe_id))))
 200          {
 201              $this->data['pm_id'] = $pm_id;
 202              $this->data['pe_id'] = $pe_id;
 203              $this->data['pe_overwrite'] = 0;        // none set so far
 204              
 205              // only set status if it's not set by the datasource
 206              if (!isset($this->data['pe_status'])) 
 207              {
 208                  $this->data['pe_status']= 'new';
 209              }
 210              // if user linking has no ADD rights, the entry is set to ignored
 211              if (!$this->check_acl(EGW_ACL_ADD,array('pm_id'=>$pm_id)))
 212              {
 213                  $this->data['pe_status']= 'ignore';
 214              }
 215          }
 216          $datasource =& $this->datasource($app);
 217          $this->updated = 0;
 218  
 219          if (!($data = $datasource->read($id,$this->data)))
 220          {
 221              return false;    // eg. no read access, so I cant update
 222          }
 223          foreach($data as $name => $value)
 224          {
 225              if (isset($datasource->name2id[$name]) && !($this->data['pe_overwrite'] & $datasource->name2id[$name]) &&
 226                  $this->data[$name] != $value)
 227              {
 228                  //if ((int) $pe_id) echo "<p>boprojectelements::update($app,$id,$pe_id,$pm_id) $name updated: '{$this->data[$name]}' != '$value'</p>\n";
 229                  $this->data[$name] = $value;
 230                  $this->updated |= $datasource->name2id[$name];
 231              }
 232          }
 233          $this->data['pe_synced'] = $this->now_su;
 234          
 235          if((int) $pe_id && ($need_save_anyway || $this->updated))
 236          {
 237              $this->save(null,false,$update_project ? $this->updated & ~PM_TITLE & ~PM_DETAILS & ~PM_RESOURCES : 0);    // dont set modified, only synced
 238          }
 239          return $this->data;
 240      }
 241  
 242      /**
 243       * sync all project-elements
 244       *
 245       * The sync of the elements is done by calling the update-method for each (not ignored) element
 246       * in the order of their planned starts and after that calling the projects update methode only 
 247       * once if necessary!
 248       *
 249       * @param int $pm_id=null id of project to use, default null=use $this->pm_id
 250       * @return int number of updated elements
 251       */
 252      function &sync_all($pm_id=null)
 253      {
 254          if (!is_array($GLOBALS['egw_info']['flags']['projectmanager']['sync_all_pm_id_visited']))
 255          {
 256              $GLOBALS['egw_info']['flags']['projectmanager']['sync_all_pm_id_visited'] = array();
 257          }
 258          if (!$pm_id && !($pm_id = $this->pm_id)) return 0;
 259          
 260          if ((int) $this->debug >= 2 || $this->debug == 'sync_all') $this->debug_message("boprojectelements::sync_all(pm_id=$pm_id)");
 261  
 262          if ($GLOBALS['egw_info']['flags']['projectmanager']['sync_all_pm_id_visited'][$pm_id])    // project already visited
 263          {
 264              if ((int) $this->debug >= 2 || $this->debug == 'sync_all') $this->debug_message("boprojectelements::sync_all(pm_id=$pm_id) stoped recursion, as pm_id in (".implode(',',array_keys($GLOBALS['egw_info']['flags']['projectmanager']['sync_all_pm_id_visited'])).")");
 265              return 0;                            // no further recursion, might lead to an infinit loop
 266          }
 267          $GLOBALS['egw_info']['flags']['projectmanager']['sync_all_pm_id_visited'][$pm_id] = true;
 268          
 269          $save_project = $this->project->data;
 270          
 271          $updated = $update_project = 0;
 272          ++$GLOBALS['egw_info']['flags']['projectmanager']['pm_ds_ignore_elements'];
 273          foreach((array) $this->search(array('pm_id'=>$pm_id,"pe_status != 'ignore'"),false,'pe_planned_start') as $data)
 274          {
 275              $this->update($data['pe_app'],$data['pe_app_id'],$data['pe_id'],$pm_id,false);
 276              
 277              $update_project |= $this->updated & ~PM_TITLE;
 278              if ($this->updated) $updated++;
 279          }
 280          --$GLOBALS['egw_info']['flags']['projectmanager']['pm_ds_ignore_elements'];
 281          if ($update_project)
 282          {
 283              $this->project->update($pm_id,$update_project);
 284          }
 285          if ($this->project->data['pm_id'] != $save_project['pm_id']) $this->project->data =& $save_project;
 286  
 287          unset($GLOBALS['egw_info']['flags']['projectmanager']['sync_all_pm_id_visited'][$pm_id]);
 288  
 289          return $updated;
 290      }
 291  
 292      /**
 293       * checks if the user has enough rights for a certain operation
 294       *
 295       * The rights on a project-element depend on the rigths on the parent-project:
 296       *    - One can only read an element, if he can read the project (any rights, at least READ on the project)
 297       *    - Adding, editing and deleting of elements require the ADD right of the project (deleting requires the element to exist pe_id!=0)
 298       *    - reading or editing of budgets require the concerned rights of the project
 299       *
 300       * @param int $required EGW_ACL_READ, EGW_ACL_WRITE, EGW_ACL_ADD, EGW_ACL_DELETE, EGW_ACL_BUDGET or EGW_ACL_EDIT_BUDGET
 301       * @param array/int $data=null project-element or pe_id to use, default the project-element in $this->data
 302       * @return boolean true if the rights are ok, false if not
 303       */
 304  	function check_acl($required,$data=0)
 305      {
 306          $pe_id = is_array($data) ? $data['pe_id'] : ($data ? $data : $this->data['pe_id']);
 307          $pm_id = is_array($data) ? $data['pm_id'] : ($data ? 0 : $this->data['pm_id']);
 308          
 309          if (!$pe_id && (!$pm_id || $required == EGW_ACL_DELETE))
 310          {
 311              return false;
 312          }
 313          if (!$pm_id)
 314          {
 315              $data_backup =& $this->data; unset($this->data);
 316              $data =& $this->read($pe_id);
 317              $this->data =& $data_backup; unset($data_backup);
 318          
 319              if (!$data) return false;    // not found ==> no rights
 320              
 321              $pm_id = $data['pm_id'];
 322          }
 323          if ($required == EGW_ACL_EDIT ||$required ==  EGW_ACL_DELETE)
 324          {
 325              $required = EGW_ACL_ADD;    // edit or delete of elements is handled by the ADD right of the project
 326          }
 327          return $this->project->check_acl($required,$pm_id);
 328      }
 329      
 330      /**
 331       * Get reference to instance of the datasource used for $app
 332       *
 333       * The class has to be named datasource_$app and is search first in the App's inc-dir and then in the one of 
 334       * ProjectManager. If it's not found PM's datasource baseclass is used.
 335       *
 336       * @param string $app appname
 337       * @return object
 338       */
 339      function &datasource($app)
 340      {
 341          if (!isset($this->datasources[$app]))
 342          {        
 343              if (!file_exists($classfile = EGW_INCLUDE_ROOT.'/'.$app.'/inc/class.'.($class='datasource_'.$app).'.inc.php') &&
 344                  !file_exists($classfile = EGW_INCLUDE_ROOT.'/projectmanager/inc/class.'.($class='datasource_'.$app).'.inc.php'))
 345              {
 346                  $classfile = EGW_INCLUDE_ROOT.'/projectmanager/inc/class.'.($class='datasource').'.inc.php';
 347              }
 348              include_once($classfile);
 349              $this->datasources[$app] =& new $class($app);
 350              // make the project availible for the datasource
 351              $this->datasources[$app]->project =& $this->project;
 352          }
 353          return $this->datasources[$app];    
 354      }
 355  
 356      /**
 357       * changes the data from the db-format to your work-format
 358       *
 359       * reimplemented to adjust the timezone of the timestamps (adding $this->tz_offset_s to get user-time)
 360       * Please note, we do NOT call the method of the parent or so_sql !!!
 361       *
 362       * @param array $data if given works on that array and returns result, else works on internal data-array
 363       * @return array with changed data
 364       */
 365  	function db2data($data=null)
 366      {
 367          if (!is_array($data))
 368          {
 369              $data = &$this->data;
 370          }
 371          foreach($this->timestamps as $name)
 372          {
 373              if (isset($data[$name]) && $data[$name]) $data[$name] += $this->tz_offset_s;
 374          }
 375          if (is_numeric($data['pe_completion'])) $data['pe_completion'] .= '%';
 376          if ($data['pe_app']) $data['pe_icon'] = $data['pe_app'].'/navbar';
 377          if ($data['pe_resources']) $data['pe_resources'] = explode(',',$data['pe_resources']);
 378  
 379          return $data;
 380      }
 381  
 382      /**
 383       * changes the data from your work-format to the db-format
 384       *
 385       * reimplemented to adjust the timezone of the timestamps (subtraction $this->tz_offset_s to get server-time)
 386       * Please note, we do NOT call the method of the parent or so_sql !!!
 387       *
 388       * @param array $data if given works on that array and returns result, else works on internal data-array
 389       * @return array with changed data
 390       */
 391  	function data2db($data=null)
 392      {
 393          if ($intern = !is_array($data))
 394          {
 395              $data = &$this->data;
 396          }
 397          foreach($this->timestamps as $name)
 398          {
 399              if (isset($data[$name]))
 400              {
 401                  if ($data[$name])
 402                  {
 403                      $data[$name] -= $this->tz_offset_s;
 404                  }
 405                  else
 406                  {
 407                      $data[$name] = null;    // so it's not used for min or max dates
 408                  }
 409              }
 410          }
 411          if (substr($data['pe_completion'],-1) == '%') $data['pe_completion'] = (int) substr($data['pe_completion'],0,-1);
 412  
 413          if (is_array($data['pe_resources']))
 414          {
 415              $data['pe_resources'] = count($data['pe_resources']) ? implode(',',$data['pe_resources']) : null;
 416          }
 417          return $data;
 418      }
 419      
 420      /**
 421       * saves an project-element, reimplemented from SO, to save the remark in the link, if $keys['update_remark']
 422       *
 423       * @param array $keys=null if given $keys are copied to data before saveing => allows a save as
 424       * @param boolean $touch_modified=true should modification date+user be set, default yes
 425       * @param int $update_project=-1 update the data in the project (or'ed PM_ id's), default -1=everything
 426       * @return int 0 on success and errno != 0 else
 427       */
 428  	function save($keys=null,$touch_modified=true,$update_project=-1)
 429      {
 430          if ((int) $this->debug >= 1 || $this->debug == 'save') $this->debug_message("boprojectelements::save(".print_r($keys,true).','.(int)$touch_modified.",$update_project) data=".print_r($this->data,true));
 431  
 432          if ($keys['update_remark'] || $this->data['update_remark'])
 433          {
 434              unset($keys['update_remark']);
 435              unset($this->data['update_remark']);
 436              $this->link->update_remark($this->data['pe_id'],$this->data['pe_remark']);
 437          }
 438          if ($keys) $this->data_merge($keys);
 439          
 440          if ($touch_modified || !$this->data['pe_modified'] || !$this->data['pe_modifier'])
 441          {
 442              $this->data['pe_modified'] = $this->now_su;
 443              $this->data['pe_modifier'] = $GLOBALS['egw_info']['user']['account_id'];
 444          }
 445          if (!$this->data['pm_id']) $this->data['pm_id'] = $this->pm_id;
 446  
 447          if (!($err = parent::save()))
 448          {
 449              if (is_array($this->data['pe_constraints']))
 450              {
 451                  $this->constraints->save(array(
 452                      'pm_id' => $this->data['pm_id'],
 453                      'pe_id' => $this->data['pe_id'],
 454                  ) + $this->data['pe_constraints']);
 455              }
 456              if ($update_project) 
 457              {
 458                  $this->project->update($this->data['pm_id'],$update_project,$this->data);
 459              }
 460          }
 461          return $err;
 462      }
 463  
 464      /**
 465       * deletes a project-element or all project-elements of a project, reimplemented to remove the link too
 466       *
 467       * @param array/int $keys if given array with pm_id and/or pe_id or just an integer pe_id
 468       * @return int affected rows, should be 1 if ok, 0 if an error
 469       */
 470  	function delete($keys=null)
 471      {
 472          if (!is_array($keys) && (int) $keys)
 473          {
 474              $keys = array('pe_id' => (int) $keys);
 475          }
 476          if (!is_null($keys))
 477          {
 478              $pm_id = $keys['pm_id'];
 479              $pe_id = $keys['pe_id'];
 480          }
 481          else
 482          {
 483              $pe_id = $this->data['pe_id'];
 484              $pm_id = $this->data['pm_id'];
 485          }
 486          $ret = parent::delete($keys);
 487          
 488          if ($pe_id)
 489          {
 490              // delete one link
 491              $this->link->unlink($pe_id);
 492              // update the project
 493              $this->project->update($pm_id);
 494              
 495              $this->constraints->delete(array('pe_id' => $pe_id));
 496          }
 497          elseif ($pm_id)
 498          {
 499              // delete all links to project $pm_id
 500              $this->link->unlink(0,'projectmanager',$pm_id);
 501          }    
 502          return $ret;
 503      }
 504      
 505      /**
 506       * reads row matched by key and puts all cols in the data array, reimplemented to also read the constraints
 507       *
 508       * @param array $keys array with keys in form internalName => value, may be a scalar value if only one key
 509       * @param string/array $extra_cols string or array of strings to be added to the SELECT, eg. "count(*) as num"
 510       * @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or 
 511       * @return array/boolean data if row could be retrived else False
 512      */
 513  	function read($keys,$extra_cols='',$join=true)
 514      {
 515          if (!($data = parent::read($keys,$extra_cols,$join)))
 516          {
 517              return false;
 518          }
 519          $this->data['pe_constraints'] = $this->constraints->read(array(
 520              'pm_id' => $this->data['pm_id'],
 521              'pe_id' => $this->data['pe_id'],
 522          ));
 523          return $this->data;
 524      }
 525      
 526      /**
 527       * reads the titles of all project-elements specified by $keys
 528       *
 529       * @param array $keys keys of elements to read, default empty = all of the project the class is instanciated for
 530       * @return array with pe_id => lang(pe_app): pe_title pairs
 531       */
 532      function &titles($keys=array())
 533      {
 534          $titles = array();
 535          foreach((array) $this->search(array(),'pe_id,pe_title','pe_app,pe_title','','',false,'AND',false,$keys) as $element)
 536          {
 537              if ($element) $titles[$element['pe_id']] = lang($element['pe_app']).': '.$element['pe_title'];
 538          }
 539          return $titles;
 540      }
 541  
 542      /**
 543       * echos a (preformatted / no-html) debug-message and evtl. log it to a file
 544       *
 545       * It uses the debug_message method of boprojectmanager
 546       *
 547       * @param string $msg
 548       */
 549  	function debug_message($msg)
 550      {
 551          $this->project->debug_message($msg);
 552      }
 553  
 554      /**
 555       * Copies the elementtree from an other project
 556       *
 557       * This is done by calling the copy method of the datasource (if existent) and then calling update with the (new) app_id
 558       *
 559       * @param int $source
 560       * @return boolean true on success, false otherwise
 561       */
 562  	function copytree($source)
 563      {
 564          if ((int) $this->debug >= 2 || $this->debug == 'copytree') $this->debug_message("boprojectelements::copytree($source) this->pm_id=$this->pm_id");
 565  
 566          $elements =& $this->search(array('pm_id' => $source),false,'pe_planned_start');
 567          if (!$elements) return true;
 568          
 569          foreach($elements as $element)
 570          {
 571              $ds =& $this->datasource($element['pe_app']);
 572              
 573              if (method_exists($ds,'copy'))
 574              {
 575                  if ((int) $this->debug >= 3 || $this->debug == 'copytree') $this->debug_message("copying $element[pe_app]:$element[pe_app_id] $element[pe_title]");
 576                  list($app_id,$link_id) = $ds->copy($element,$this->pm_id,$this->project->data);
 577              }
 578              else    // no copy method, we just link again with that entry
 579              {
 580                  if ((int) $this->debug >= 3 || $this->debug == 'copytree') $this->debug_message("linking $element[pe_app]:$element[pe_app_id] $element[pe_title]");
 581                  $app_id = $element['pe_app_id'];
 582                  $link_id = $this->link->link('projectmanager',$this->pm_id,$element['pe_app'],$app_id,$element['pe_remark'],0,0,1);
 583              }
 584              if ((int) $this->debug >= 3 || $this->debug == 'copytree') $this->debug_message("calling update($element[pe_app],$app_id,$link_id,$this->pm_id,false);");
 585  
 586              if (!$app_id || !$link_id) continue;    // something went wrong, eg. element no longer exists
 587  
 588              $this->update($element['pe_app'],$app_id,$link_id,$this->pm_id,false);    // false=no update of project itself => done once at the end
 589  
 590              // copy evtl. overwriten content from the element
 591              if (($need_save = $element['pe_overwrite'] != 0))
 592              {
 593                  foreach($ds->name2id as $name => $id)
 594                  {
 595                      if ($element['pe_overwrite'] & $id)
 596                      {
 597                          $this->data[$name] = $element[$name];
 598                      }
 599                  }
 600                  $this->data['pe_overwrite'] = $element['pe_overwrite'];
 601              }
 602              // copy other element data
 603              foreach(array('pl_id','pe_cost_per_time','cat_id','pe_share','pe_status') as $name)
 604              {
 605                  if ($name == 'pe_status' && $element['pe_status'] != 'ignore') continue;    // only copy ignored
 606  
 607                  if ($this->data[$name] != $element[$name])
 608                  {
 609                      $this->data[$name] = $element[$name];
 610                      $need_save = true;
 611                  }
 612              }    
 613              if ($need_save) $this->save(null,true,false);
 614          }
 615          // now we do one update of our project
 616          if ((int) $this->debug >= 3 || $this->debug == 'copytree') $this->debug_message("calling project->update() this->pm_id=$this->pm_id");
 617          $this->project->update();
 618  
 619          return true;
 620      }
 621  }


Généré le : Sun Feb 25 17:20:01 2007 par Balluche grâce à PHPXref 0.7