[3594] | 1 | <?php |
---|
| 2 | /** |
---|
| 3 | * ProjectManager - Projects user interface |
---|
| 4 | * |
---|
| 5 | * @link http://www.egroupware.org |
---|
| 6 | * @author Ralf Becker <RalfBecker-AT-outdoor-training.de> |
---|
| 7 | * @package projectmanager |
---|
| 8 | * @copyright (c) 2005 by Ralf Becker <RalfBecker-AT-outdoor-training.de> |
---|
| 9 | * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License |
---|
| 10 | * @version $Id: class.uiprojectmanager.inc.php 23741 2007-04-30 10:29:44Z lkneschke $ |
---|
| 11 | */ |
---|
| 12 | |
---|
| 13 | include_once(PHPGW_INCLUDE_ROOT.'/projectmanager/inc/class.boprojectmanager.inc.php'); |
---|
| 14 | //include_once(PHPGW_INCLUDE_ROOT.'/etemplate/inc/class.uietemplate.inc.php'); |
---|
| 15 | |
---|
| 16 | /** |
---|
| 17 | * ProjectManager UI: list and edit projects |
---|
| 18 | */ |
---|
| 19 | class uiprojectmanager extends boprojectmanager |
---|
| 20 | { |
---|
| 21 | /** |
---|
| 22 | * Functions to call via menuaction |
---|
| 23 | * |
---|
| 24 | * @var array |
---|
| 25 | */ |
---|
| 26 | var $public_functions = array( |
---|
| 27 | 'index' => true, |
---|
| 28 | 'edit' => true, |
---|
| 29 | 'view' => true, |
---|
| 30 | ); |
---|
| 31 | /** |
---|
| 32 | * Labels for pm_status, value - label pairs |
---|
| 33 | * |
---|
| 34 | * @var array |
---|
| 35 | */ |
---|
| 36 | var $status_labels; |
---|
| 37 | /** |
---|
| 38 | * Labels for pm_access, value - label pairs |
---|
| 39 | * |
---|
| 40 | * @var array |
---|
| 41 | */ |
---|
| 42 | var $access_labels; |
---|
| 43 | /** |
---|
| 44 | * Labels for mains- & sub-projects filter |
---|
| 45 | * |
---|
| 46 | * @var array |
---|
| 47 | */ |
---|
| 48 | var $filter_labels; |
---|
| 49 | |
---|
| 50 | /** |
---|
| 51 | * Constructor, calls the constructor of the extended class |
---|
| 52 | * |
---|
| 53 | * @return uiprojectmanager |
---|
| 54 | */ |
---|
| 55 | function uiprojectmanager() |
---|
| 56 | { |
---|
| 57 | $this->boprojectmanager(); |
---|
| 58 | |
---|
| 59 | $this->status_labels = array( |
---|
| 60 | 'active' => lang('Active'), |
---|
| 61 | 'nonactive' => lang('Nonactive'), |
---|
| 62 | 'archive' => lang('Archive'), |
---|
| 63 | 'template' => lang('Template'), |
---|
| 64 | ); |
---|
| 65 | $this->access_labels = array( |
---|
| 66 | 'public' => lang('Public'), |
---|
| 67 | 'anonym' => lang('Anonymous public'), |
---|
| 68 | 'private' => lang('Private'), |
---|
| 69 | ); |
---|
| 70 | $this->filter_labels = array( |
---|
| 71 | '' => lang('All'), |
---|
| 72 | 'mains' => lang('Mainprojects'), |
---|
| 73 | 'subs' => lang('Subprojects'), |
---|
| 74 | ); |
---|
| 75 | } |
---|
| 76 | |
---|
| 77 | |
---|
| 78 | /** |
---|
| 79 | * View a project |
---|
| 80 | */ |
---|
| 81 | function view() |
---|
| 82 | { |
---|
| 83 | $this->edit(null,true); |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | /** |
---|
| 87 | * Edit, add or view a project |
---|
| 88 | * |
---|
| 89 | * @var array $content content-array if called by process-exec |
---|
| 90 | * @var boolean $view only view project, default false, only used on first call !is_array($content) |
---|
| 91 | */ |
---|
| 92 | function edit($content=null,$view=false) |
---|
| 93 | { |
---|
| 94 | if ((int) $this->debug >= 1 || $this->debug == 'edit') $this->debug_message("uiprojectmanager::edit(,$view) content=".print_r($content,true)); |
---|
| 95 | |
---|
| 96 | $tpl =& new etemplate('projectmanager.edit'); |
---|
| 97 | |
---|
| 98 | if (is_array($content)) |
---|
| 99 | { |
---|
| 100 | if ($content['cancel']) |
---|
| 101 | { |
---|
| 102 | $tpl->location(array( |
---|
| 103 | 'menuaction' => $content['referer'], |
---|
| 104 | )); |
---|
| 105 | } |
---|
| 106 | if ($content['pm_id']) |
---|
| 107 | { |
---|
| 108 | $this->read($content['pm_id']); |
---|
| 109 | } |
---|
| 110 | else |
---|
| 111 | { |
---|
| 112 | $this->init(); |
---|
| 113 | } |
---|
| 114 | $view = $content['view'] && !$content['edit'] || !$this->check_acl(PHPGW_ACL_EDIT); |
---|
| 115 | |
---|
| 116 | if (!$content['view']) // just changed to edit-mode, still counts as view |
---|
| 117 | { |
---|
| 118 | //echo "content="; _debug_array($content); |
---|
| 119 | $this->data_merge($content); |
---|
| 120 | //echo "after data_merge data="; _debug_array($this->data); |
---|
| 121 | |
---|
| 122 | // set the data of the pe_summary, if the project-value is unset |
---|
| 123 | $pe_summary = $this->pe_summary(); |
---|
| 124 | $datasource =& CreateObject('projectmanager.datasource'); |
---|
| 125 | foreach($datasource->name2id as $pe_name => $id) |
---|
| 126 | { |
---|
| 127 | $pm_name = str_replace('pe_','pm_',$pe_name); |
---|
| 128 | // check if update is necessary, because a field has be set or changed |
---|
| 129 | if (($content[$pm_name] || $pm_name == 'pm_completion' && $content[$pm_name] !== '') && |
---|
| 130 | ($content[$pm_name] != $this->data[$pm_name] || !($this->data['pm_overwrite'] & $id))) |
---|
| 131 | { |
---|
| 132 | //echo "$pm_name set to '".$this->data[$pm_name]."'<br>\n"; |
---|
| 133 | $this->data['pm_overwrite'] |= $id; |
---|
| 134 | } |
---|
| 135 | // or check if a field is no longer set, or the datasource changed => set it from the datasource |
---|
| 136 | elseif ((!$content[$pm_name] || $pm_name == 'pm_completion' && $content[$pm_name] === '') && |
---|
| 137 | ($this->data['pm_overwrite'] & $id) || |
---|
| 138 | !($this->data['pm_overwrite'] & $id) && $this->data[$pm_name] != $pe_summary[$pe_name]) |
---|
| 139 | { |
---|
| 140 | // if we have a change in the datasource, set pe_synced |
---|
| 141 | if ($this->data[$pm_name] != $pe_summary[$name]) |
---|
| 142 | { |
---|
| 143 | $this->data['pm_synced'] = $this->now_su; |
---|
| 144 | } |
---|
| 145 | $this->data[$pm_name] = $pe_summary[$pe_name]; |
---|
| 146 | //echo "$pm_name re-set to default '".$this->data[$pm_name]."'<br>\n"; |
---|
| 147 | $this->data['pm_overwrite'] &= ~$id; |
---|
| 148 | } |
---|
| 149 | } |
---|
| 150 | // process new and changed project-members |
---|
| 151 | foreach((array)$content['member'] as $n => $uid) |
---|
| 152 | { |
---|
| 153 | if (!(int) $content['role'][$n]) |
---|
| 154 | { |
---|
| 155 | unset($this->data['pm_members'][$uid]); |
---|
| 156 | } |
---|
| 157 | elseif ((int) $uid) |
---|
| 158 | { |
---|
| 159 | $this->data['pm_members'][(int)$uid] = array( |
---|
| 160 | 'member_uid' => (int) $uid, |
---|
| 161 | 'member_availibility' => empty($content['availibility'][$n]) ? 100.0 : $content['availibility'][$n], |
---|
| 162 | 'role_id' => (int) $content['role'][$n], |
---|
| 163 | ); |
---|
| 164 | if ($GLOBALS['phpgw_info']['user']['apps']['admin'] && $content['general_avail'][$n]) |
---|
| 165 | { |
---|
| 166 | $this->set_availibility($uid,$content['general_avail'][$n]); |
---|
| 167 | } |
---|
| 168 | } |
---|
| 169 | } |
---|
| 170 | } |
---|
| 171 | //echo "uiprojectmanager::edit(): data="; _debug_array($this->data); |
---|
| 172 | |
---|
| 173 | if (($content['save'] || $content['apply']) && $this->check_acl(PHPGW_ACL_EDIT)) |
---|
| 174 | { |
---|
| 175 | // generate project-number, taking into account a given parent-project |
---|
| 176 | if (empty($this->data['pm_number'])) |
---|
| 177 | { |
---|
| 178 | $parent_number = ''; |
---|
| 179 | if ($content['add_link']) |
---|
| 180 | { |
---|
| 181 | list($app,$app_id) = explode(':',$content['add_link'],2); |
---|
| 182 | if ($app == 'projectmanager' && ($parent = $this->search(array('pm_id'=>$app_id),'pm_number'))) |
---|
| 183 | { |
---|
| 184 | $parent_number = $parent[0]['pm_number']; |
---|
| 185 | } |
---|
| 186 | } |
---|
| 187 | $this->generate_pm_number(true,$parent_number); |
---|
| 188 | } |
---|
| 189 | if ($this->not_unique()) |
---|
| 190 | { |
---|
| 191 | $msg = lang('Error: project-ID already exist, choose an other one or have one generated by leaving it emtpy !!!'); |
---|
| 192 | unset($content['save']); // dont exit |
---|
| 193 | } |
---|
| 194 | elseif ($this->save() != 0) |
---|
| 195 | { |
---|
| 196 | $msg = lang('Error: saving the project (%1) !!!',$this->db->Error); |
---|
| 197 | unset($content['save']); // dont exit |
---|
| 198 | } |
---|
| 199 | else |
---|
| 200 | { |
---|
| 201 | $msg = lang('Project saved'); |
---|
| 202 | |
---|
| 203 | // create project already linked to a parent, in that case param of link-call need to be swaped |
---|
| 204 | // as we want the new project to be the sub of the given project |
---|
| 205 | if ($content['add_link']) |
---|
| 206 | { |
---|
| 207 | list($app,$app_id) = explode(':',$content['add_link'],2); |
---|
| 208 | $this->link->link($app,$app_id,'projectmanager',$this->data['pm_id']); |
---|
| 209 | } |
---|
| 210 | // writing links for new entry, existing ones are handled by the widget itself |
---|
| 211 | if (!$content['pm_id'] && is_array($content['link_to']['to_id'])) |
---|
| 212 | { |
---|
| 213 | $this->link->link('projectmanager',$this->data['pm_id'],$content['link_to']['to_id']); |
---|
| 214 | } |
---|
| 215 | if ($content['template'] && $this->copy($content['template'],2)) |
---|
| 216 | { |
---|
| 217 | $msg = lang('Template including elment-tree saved as new project'); |
---|
| 218 | unset($content['template']); |
---|
| 219 | } |
---|
| 220 | } |
---|
| 221 | } |
---|
| 222 | if ($content['save']) |
---|
| 223 | { |
---|
| 224 | $tpl->location(array( |
---|
| 225 | 'menuaction' => $content['referer'], |
---|
| 226 | 'msg' => $msg, |
---|
| 227 | )); |
---|
| 228 | } |
---|
| 229 | if ($content['delete'] && $this->check_acl(PHPGW_ACL_DELETE)) |
---|
| 230 | { |
---|
| 231 | // all delete are done by index |
---|
| 232 | return $this->index(array('nm'=>array('rows'=>array( |
---|
| 233 | 'delete' => array($this->data['pm_id']=>true) |
---|
| 234 | )))); |
---|
| 235 | } |
---|
| 236 | $referer = $content['referer']; |
---|
| 237 | $template = $content['template']; |
---|
| 238 | } |
---|
| 239 | else |
---|
| 240 | { |
---|
| 241 | $referer = preg_match('/menuaction=([^&]+)/',$_SERVER['HTTP_REFERER'],$matches) ? $matches[1] : 'projectmanager.uiprojectmanager.index'; |
---|
| 242 | |
---|
| 243 | if ((int) $_GET['pm_id']) |
---|
| 244 | { |
---|
| 245 | $this->read((int) $_GET['pm_id']); |
---|
| 246 | } |
---|
| 247 | // for a new sub-project set some data from the parent |
---|
| 248 | elseif ($_GET['link_app'] == 'projectmanager' && (int) $_GET['link_id'] && $this->read((int) $_GET['link_id'])) |
---|
| 249 | { |
---|
| 250 | if (!$this->check_acl(PHPGW_ACL_READ)) // no read-rights for the parent, eg. someone edited the url |
---|
| 251 | { |
---|
| 252 | $tpl->location(array( |
---|
| 253 | 'menuaction' => $referer, |
---|
| 254 | 'msg' => lang('Permission denied !!!'), |
---|
| 255 | )); |
---|
| 256 | } |
---|
| 257 | else |
---|
| 258 | { |
---|
| 259 | $this->generate_pm_number(true,$this->data['pm_number']); |
---|
| 260 | foreach(array('pm_id','pm_title','pm_description','pm_creator','pm_created','pm_modified','pm_modifier','pm_real_start','pm_real_end','pm_completion','pm_status','pm_used_time','pm_planned_time','pm_used_budget','pm_planned_budget') as $key) |
---|
| 261 | { |
---|
| 262 | unset($this->data[$key]); |
---|
| 263 | } |
---|
| 264 | include_once(PHPGW_INCLUDE_ROOT.'/projectmanager/inc/class.datasource.inc.php'); |
---|
| 265 | $this->data['pm_overwrite'] &= PM_PLANNED_START | PM_PLANNED_END; |
---|
| 266 | } |
---|
| 267 | } |
---|
| 268 | elseif((int)$_GET['template'] && $this->read((int) $_GET['template'])) |
---|
| 269 | { |
---|
| 270 | if (!$this->check_acl(PHPGW_ACL_READ)) // no read-rights for the template, eg. someone edited the url |
---|
| 271 | { |
---|
| 272 | $tpl->location(array( |
---|
| 273 | 'menuaction' => $referer, |
---|
| 274 | 'msg' => lang('Permission denied !!!'), |
---|
| 275 | )); |
---|
| 276 | } |
---|
| 277 | // we do only stage 1 of the copy, so if the user hits cancel everythings Ok |
---|
| 278 | $this->copy($template = (int) $_GET['template'],1); |
---|
| 279 | } |
---|
| 280 | if ($this->data['pm_id']) |
---|
| 281 | { |
---|
| 282 | if (!$this->check_acl(PHPGW_ACL_READ)) |
---|
| 283 | { |
---|
| 284 | $tpl->location(array( |
---|
| 285 | 'menuaction' => $referer, |
---|
| 286 | 'msg' => lang('Permission denied !!!'), |
---|
| 287 | )); |
---|
| 288 | } |
---|
| 289 | if (!$this->check_acl(PHPGW_ACL_EDIT)) $view = true; |
---|
| 290 | } |
---|
| 291 | // no pm-number set, generate one |
---|
| 292 | if (!$this->data['pm_number']) $this->generate_pm_number(true); |
---|
| 293 | } |
---|
| 294 | if (!$pe_summary) $pe_summary = $this->pe_summary(); |
---|
| 295 | |
---|
| 296 | if (!isset($content['add_link']) && !$this->data->pm_id && isset($_GET['link_app']) && isset($_GET['link_id']) && |
---|
| 297 | preg_match('/^[a-z_0-9-]+:[:a-z_0-9-]+$/i',$_GET['link_app'].':'.$_GET['link_id'])) // gard against XSS |
---|
| 298 | { |
---|
| 299 | $add_link = $_GET['link_app'].':'.$_GET['link_id']; |
---|
| 300 | } |
---|
| 301 | else |
---|
| 302 | { |
---|
| 303 | $add_link = $content['add_link']; |
---|
| 304 | } |
---|
| 305 | $content = $this->data + array( |
---|
| 306 | 'msg' => $msg, |
---|
| 307 | 'general|description|members|accounting|custom|links' => $content['general|description|members|accounting|custom|links'], |
---|
| 308 | 'view' => $view, |
---|
| 309 | 'ds' => $pe_summary, |
---|
| 310 | 'link_to' => array( |
---|
| 311 | 'to_id' => $content['link_to']['to_id'] ? $content['link_to']['to_id'] : $this->data['pm_id'], |
---|
| 312 | 'to_app' => 'projectmanager', |
---|
| 313 | ), |
---|
| 314 | 'duration_format' => ','.$this->config['duration_format'], |
---|
| 315 | 'no_budget' => !$this->check_acl(PHPGW_ACL_BUDGET,0,true) || in_array($this->data['pm_accounting_type'],array('status','times')), |
---|
| 316 | ); |
---|
| 317 | if ($add_link && !is_array($content['link_to']['to_id'])) |
---|
| 318 | { |
---|
| 319 | list($app,$app_id) = explode(':',$add_link,2); |
---|
| 320 | $this->link->link('projectmanager',$content['link_to']['to_id'],$app,$app_id); |
---|
| 321 | } |
---|
| 322 | $content['links'] = $content['link_to']; |
---|
| 323 | |
---|
| 324 | // empty not explicitly in the project set values |
---|
| 325 | if (!is_object($datasource)) $datasource =& CreateObject('projectmanager.datasource'); |
---|
| 326 | foreach($datasource->name2id as $pe_name => $id) |
---|
| 327 | { |
---|
| 328 | $pm_name = str_replace('pe_','pm_',$pe_name); |
---|
| 329 | if (!($this->data['pm_overwrite'] & $id) && $pm_name != 'pm_title') |
---|
| 330 | { |
---|
| 331 | $content[$pm_name] = $preserv[$pm_name] = ''; |
---|
| 332 | } |
---|
| 333 | } |
---|
| 334 | $readonlys = array( |
---|
| 335 | 'delete' => !$this->data['pm_id'] || !$this->check_acl(PHPGW_ACL_DELETE), |
---|
| 336 | 'edit' => !$view || !$this->check_acl(PHPGW_ACL_EDIT), |
---|
| 337 | 'general|description|members|accounting|custom|links' => array( |
---|
| 338 | 'accounting' => !$this->check_acl(PHPGW_ACL_BUDGET) && // disable the tab, if no budget rights and no owner or coordinator |
---|
| 339 | ($this->config['accounting_types'] && count(explode(',',$this->config['accounting_types'])) == 1 || |
---|
| 340 | !($this->data['pm_creator'] == $this->user || $this->data['pm_members'][$this->user]['role_id'] == 1)), |
---|
| 341 | 'custom' => !count($this->customfields), // only show customfields tab, if there are some |
---|
| 342 | ), |
---|
| 343 | 'customfields' => $view, |
---|
| 344 | 'general_avail[1]' => !$GLOBALS['phpgw_info']['user']['apps']['admin'], |
---|
| 345 | ); |
---|
| 346 | if (!$this->check_acl(PHPGW_ACL_EDIT_BUDGET)) |
---|
| 347 | { |
---|
| 348 | $readonlys['pm_planned_budget'] = $readonlys['pm_used_budget'] = true; |
---|
| 349 | } |
---|
| 350 | $n = 2; |
---|
| 351 | foreach((array)$this->data['pm_members'] as $uid => $data) |
---|
| 352 | { |
---|
| 353 | $content['role'][$n] = $data['role_id']; |
---|
| 354 | $content['member'][$n] = $data['member_uid']; |
---|
| 355 | $content['availibility'][$n] = empty($data['member_availibility']) ? 100.0 : $data['member_availibility']; |
---|
| 356 | if (!is_array($general_avail)) $general_avail = $this->get_availibility(); |
---|
| 357 | $content['general_avail'][$n] = empty($general_avail[$uid]) ? 100.0 : $general_avail[$uid]; |
---|
| 358 | $readonlys["general_avail[$n]"] = $view || !$GLOBALS['phpgw_info']['user']['apps']['admin']; |
---|
| 359 | $readonlys["role[$n]"] = $readonlys["availibility[$n]"] = $view; |
---|
| 360 | ++$n; |
---|
| 361 | } |
---|
| 362 | //_debug_array($content); |
---|
| 363 | $preserv = $this->data + array( |
---|
| 364 | 'view' => $view, |
---|
| 365 | 'add_link' => $add_link, |
---|
| 366 | 'member' => $content['member'], |
---|
| 367 | 'referer' => $referer, |
---|
| 368 | 'template' => $template, |
---|
| 369 | ); |
---|
| 370 | $this->instanciate('roles'); |
---|
| 371 | |
---|
| 372 | $sel_options = array( |
---|
| 373 | 'pm_status' => &$this->status_labels, |
---|
| 374 | 'pm_access' => &$this->access_labels, |
---|
| 375 | 'role' => $this->roles->query_list(array( |
---|
| 376 | 'label' => 'role_title', |
---|
| 377 | 'title' => 'role_description', |
---|
| 378 | ),'role_id',array( |
---|
| 379 | 'pm_id' => array(0,(int)$this->data['pm_id']) |
---|
| 380 | )), |
---|
| 381 | 'pm_accounting_type' => array( |
---|
| 382 | 'status' => 'No accounting, only status', |
---|
| 383 | 'times' => 'No accounting, only times and status', |
---|
| 384 | 'budget' => 'Budget (no pricelist)', |
---|
| 385 | 'pricelist' => 'Budget and pricelist', |
---|
| 386 | ), |
---|
| 387 | ); |
---|
| 388 | if ($this->config['accounting_types']) // only allow the configured types |
---|
| 389 | { |
---|
| 390 | $allowed = explode(',',$this->config['accounting_types']); |
---|
| 391 | foreach($sel_options['pm_accounting_type'] as $key => $label) |
---|
| 392 | { |
---|
| 393 | if (!in_array($key,$allowed)) unset($sel_options['pm_accounting_type'][$key]); |
---|
| 394 | } |
---|
| 395 | if (count($sel_options['pm_accounting_type']) == 1) |
---|
| 396 | { |
---|
| 397 | $readonlys['pm_accounting_type'] = true; |
---|
| 398 | } |
---|
| 399 | } |
---|
| 400 | if ($view) |
---|
| 401 | { |
---|
| 402 | foreach($this->db_cols as $name) |
---|
| 403 | { |
---|
| 404 | $readonlys[$name] = true; |
---|
| 405 | } |
---|
| 406 | $readonlys['save'] = $readonlys['apply'] = true; |
---|
| 407 | |
---|
| 408 | // add fields not stored in the main-table |
---|
| 409 | $readonlys['pm_members'] = $readonlys['edit_roles'] = true; |
---|
| 410 | |
---|
| 411 | $readonlys['links'] = $readonlys['link_to'] = true; |
---|
| 412 | } |
---|
| 413 | $GLOBALS['phpgw_info']['flags']['app_header'] = lang('projectmanager') . ' - ' . |
---|
| 414 | ($this->data['pm_id'] ? ($view ? lang('View project') : lang('Edit project')) : lang('Add project')); |
---|
| 415 | $tpl->exec('projectmanager.uiprojectmanager.edit',$content,$sel_options,$readonlys,$preserv); |
---|
| 416 | } |
---|
| 417 | |
---|
| 418 | /** |
---|
| 419 | * query projects for nextmatch in the projects-list |
---|
| 420 | * |
---|
| 421 | * reimplemented from so_sql to disable action-buttons based on the acl and make some modification on the data |
---|
| 422 | * |
---|
| 423 | * @param array $query |
---|
| 424 | * @param array &$rows returned rows/cups |
---|
| 425 | * @param array &$readonlys eg. to disable buttons based on acl |
---|
| 426 | */ |
---|
| 427 | function get_rows(&$query_in,&$rows,&$readonlys) |
---|
| 428 | { |
---|
| 429 | $GLOBALS['phpgw']->session->appsession('project_list','projectmanager',$query=$query_in); |
---|
| 430 | |
---|
| 431 | // handle nextmatch filters like col_filters |
---|
| 432 | foreach(array('cat_id' => 'cat_id','filter2' => 'pm_status') as $nm_name => $pm_name) |
---|
| 433 | { |
---|
| 434 | unset($query['col_filter'][$pm_name]); |
---|
| 435 | if ($query[$nm_name]) $query['col_filter'][$pm_name] = $query[$nm_name]; |
---|
| 436 | } |
---|
| 437 | $query['col_filter']['subs_or_mains'] = $query['filter']; |
---|
| 438 | |
---|
| 439 | $total = parent::get_rows($query,$rows,$readonlys,true,true); |
---|
| 440 | |
---|
| 441 | $this->instanciate('roles'); |
---|
| 442 | |
---|
| 443 | $readonlys = array(); |
---|
| 444 | foreach($rows as $n => $val) |
---|
| 445 | { |
---|
| 446 | $row =& $rows[$n]; |
---|
| 447 | if (!$this->check_acl(PHPGW_ACL_EDIT,$row)) |
---|
| 448 | { |
---|
| 449 | $readonlys["edit[$row[pm_id]]"] = true; |
---|
| 450 | } |
---|
| 451 | if (!$this->check_acl(PHPGW_ACL_DELETE,$row)) |
---|
| 452 | { |
---|
| 453 | $readonlys["delete[$row[pm_id]]"] = true; |
---|
| 454 | } |
---|
| 455 | $pm_ids[] = $row['pm_id']; |
---|
| 456 | |
---|
| 457 | if (!($row['role_acl'] & PHPGW_ACL_BUDGET)) |
---|
| 458 | { |
---|
| 459 | unset($row['pm_used_budget']); |
---|
| 460 | unset($row['pm_planned_budget']); |
---|
| 461 | } |
---|
| 462 | } |
---|
| 463 | $roles = $this->roles->query_list(); |
---|
| 464 | // query the project-members only, if user choose to display them |
---|
| 465 | if ($pm_ids && @strstr($GLOBALS['phpgw_info']['user']['preferences']['projectmanager']['nextmatch-projectmanager.list.rows'],',role') !== false) |
---|
| 466 | { |
---|
| 467 | $all_members = $this->read_members($pm_ids); |
---|
| 468 | foreach($rows as $n => $val) |
---|
| 469 | { |
---|
| 470 | $row =& $rows[$n]; |
---|
| 471 | $members = $row['pm_members'] = $all_members[$row['pm_id']]; |
---|
| 472 | if (!$members) continue; |
---|
| 473 | |
---|
| 474 | foreach($members as $uid => $data) |
---|
| 475 | { |
---|
| 476 | if (($pos = array_search($data['role_id'],array_keys($roles))) !== false) |
---|
| 477 | { |
---|
| 478 | $row['role'.$pos][] = $uid; |
---|
| 479 | } |
---|
| 480 | } |
---|
| 481 | } |
---|
| 482 | } |
---|
| 483 | //_debug_array($rows); |
---|
| 484 | if ((int) $this->debug >= 2 || $this->debug == 'get_rows') |
---|
| 485 | { |
---|
| 486 | $this->debug_message("uiprojectmanager::get_rows(".print_r($query,true).") total=$total, rows =".print_r($rows,true)."\nreadonlys=".print_r($readonlys,true)); |
---|
| 487 | } |
---|
| 488 | $rows['roles'] = array_values($roles); |
---|
| 489 | for($i = count($roles); $i < 5; ++$i) |
---|
| 490 | { |
---|
| 491 | $rows['no_role'.$i] = true; |
---|
| 492 | } |
---|
| 493 | // disable time & budget columns if pm is configures for status or status and time only |
---|
| 494 | if ($this->config['accounting_types'] == 'status') |
---|
| 495 | { |
---|
| 496 | $rows['no_pm_used_time_pm_planned_time'] = true; |
---|
| 497 | $rows['no_pm_used_budget_pm_planned_budget'] = true; |
---|
| 498 | $query_in['options-selectcols']['pm_used_time'] = $query_in['options-selectcols']['pm_planned_time'] = false; |
---|
| 499 | $query_in['options-selectcols']['pm_used_budget'] = $query_in['options-selectcols']['pm_planned_budget'] = false; |
---|
| 500 | } |
---|
| 501 | if ($this->config['accounting_types'] == 'status,times') |
---|
| 502 | { |
---|
| 503 | $rows['no_pm_used_budget_pm_planned_budget'] = true; |
---|
| 504 | $query_in['options-selectcols']['pm_used_budget'] = $query_in['options-selectcols']['pm_planned_budget'] = false; |
---|
| 505 | } |
---|
| 506 | $rows['duration_format'] = ','.$this->config['duration_format'].',,1'; |
---|
| 507 | |
---|
| 508 | return $total; |
---|
| 509 | } |
---|
| 510 | |
---|
| 511 | /** |
---|
| 512 | * List existing projects |
---|
| 513 | * |
---|
| 514 | * @param array $content=null |
---|
| 515 | * @param string $msg='' |
---|
| 516 | */ |
---|
| 517 | function index($content=null,$msg='') |
---|
| 518 | { |
---|
| 519 | if ((int) $this->debug >= 1 || $this->debug == 'index') $this->debug_message("uiprojectmanager::index(,$msg) content=".print_r($content,true)); |
---|
| 520 | |
---|
| 521 | |
---|
| 522 | |
---|
| 523 | //$tpl =& new etemplate('projectmanager.list'); |
---|
| 524 | |
---|
| 525 | if ($_GET['msg']) $msg = $_GET['msg']; |
---|
| 526 | |
---|
| 527 | if ($content['add']) |
---|
| 528 | { |
---|
| 529 | $tpl->location(array( |
---|
| 530 | 'menuaction' => 'projectmanager.uiprojectmanager.edit', |
---|
| 531 | 'template' => $content['template'], |
---|
| 532 | )); |
---|
| 533 | } |
---|
| 534 | if ($content['delete_checked'] || $content['gantt_checked']) |
---|
| 535 | { |
---|
| 536 | $checked = $content['nm']['rows']['checked']; |
---|
| 537 | if (!is_array($checked) || !count($checked)) |
---|
| 538 | { |
---|
| 539 | $msg = lang('You need to select a project first'); |
---|
| 540 | } |
---|
| 541 | else |
---|
| 542 | { |
---|
| 543 | if ($content['gantt_checked']) |
---|
| 544 | { |
---|
| 545 | $tpl->location(array( |
---|
| 546 | 'menuaction' => 'projectmanager.ganttchart.show', |
---|
| 547 | 'pm_id' => implode(',',$checked), |
---|
| 548 | )); |
---|
| 549 | } |
---|
| 550 | // delete all checked |
---|
| 551 | $deleted = $no_perms = 0; |
---|
| 552 | foreach($checked as $pm_id) |
---|
| 553 | { |
---|
| 554 | if ($this->read($pm_id) && !$this->check_acl(PHPGW_ACL_DELETE)) |
---|
| 555 | { |
---|
| 556 | $no_perms++; |
---|
| 557 | } |
---|
| 558 | else |
---|
| 559 | { |
---|
| 560 | $this->delete($pm_id); |
---|
| 561 | $deleted++; |
---|
| 562 | } |
---|
| 563 | } |
---|
| 564 | $msg = $no_perms ? lang('%1 times permission denied, %2 projects deleted',$no_perms,$deleted) : |
---|
| 565 | lang('%1 projects deleted',$deleted); |
---|
| 566 | } |
---|
| 567 | } |
---|
| 568 | $content = $content['nm']['rows']; |
---|
| 569 | |
---|
| 570 | if ($content['view'] || $content['edit'] || $content['delete'] || $content['ganttchart']) |
---|
| 571 | { |
---|
| 572 | foreach(array('view','edit','delete','ganttchart') as $action) |
---|
| 573 | { |
---|
| 574 | if ($content[$action]) |
---|
| 575 | { |
---|
| 576 | list($pm_id) = each($content[$action]); |
---|
| 577 | break; |
---|
| 578 | } |
---|
| 579 | } |
---|
| 580 | //echo "<p>uiprojectmanger::index() action='$action', pm_id='$pm_id'</p>\n"; |
---|
| 581 | switch($action) |
---|
| 582 | { |
---|
| 583 | case 'ganttchart': |
---|
| 584 | $tpl->location(array( |
---|
| 585 | 'menuaction' => 'projectmanager.ganttchart.show', |
---|
| 586 | 'pm_id' => $pm_id, |
---|
| 587 | )); |
---|
| 588 | break; |
---|
| 589 | case 'view': |
---|
| 590 | case 'edit': |
---|
| 591 | $tpl->location(array( |
---|
| 592 | 'menuaction' => 'projectmanager.uiprojectmanager.'.$action, |
---|
| 593 | 'pm_id' => $pm_id, |
---|
| 594 | )); |
---|
| 595 | break; |
---|
| 596 | |
---|
| 597 | case 'delete': |
---|
| 598 | if ($this->read($pm_id) && !$this->check_acl(PHPGW_ACL_DELETE)) |
---|
| 599 | { |
---|
| 600 | $msg = lang('Permission denied !!!'); |
---|
| 601 | } |
---|
| 602 | else |
---|
| 603 | { |
---|
| 604 | $msg = $this->delete($pm_id) ? lang('Project deleted') : |
---|
| 605 | lang('Error: deleting project !!!'); |
---|
| 606 | } |
---|
| 607 | break; |
---|
| 608 | } |
---|
| 609 | } |
---|
| 610 | $content = array( |
---|
| 611 | 'nm' => $GLOBALS['phpgw']->session->appsession('project_list','projectmanager'), |
---|
| 612 | 'msg' => $msg, |
---|
| 613 | ); |
---|
| 614 | if (!is_array($content['nm'])) |
---|
| 615 | { |
---|
| 616 | $content['nm'] = array( |
---|
| 617 | 'get_rows' => 'projectmanager.uiprojectmanager.get_rows', |
---|
| 618 | 'filter2' => 'active',// I initial value for the filter |
---|
| 619 | 'options-filter2'=> $this->status_labels, |
---|
| 620 | 'filter2_no_lang'=> True,// I set no_lang for filter (=dont translate the options) |
---|
| 621 | 'filter' => 'mains', |
---|
| 622 | 'filter_label' => lang('Filter'),// I label for filter (optional) |
---|
| 623 | 'options-filter' => $this->filter_labels, |
---|
| 624 | 'filter_no_lang' => True,// I set no_lang for filter (=dont translate the options) |
---|
| 625 | // 'bottom_too' => True,// I show the nextmatch-line (arrows, filters, search, ...) again after the rows |
---|
| 626 | 'order' => 'pm_modified',// IO name of the column to sort after (optional for the sortheaders) |
---|
| 627 | 'sort' => 'DESC',// IO direction of the sort: 'ASC' or 'DESC' |
---|
| 628 | 'default_cols' => '!role0,role1,role2,role3,role4', |
---|
| 629 | ); |
---|
| 630 | } |
---|
| 631 | $templates = array(); |
---|
| 632 | foreach((array)$this->search(array( |
---|
| 633 | 'pm_status' => 'template', |
---|
| 634 | ),$this->table_name.'.pm_id AS pm_id,pm_number,pm_title','pm_number','','',False,'OR') as $template) |
---|
| 635 | { |
---|
| 636 | $templates[$template['pm_id']] = array( |
---|
| 637 | 'label' => $template['pm_number'], |
---|
| 638 | 'title' => $template['pm_title'], |
---|
| 639 | ); |
---|
| 640 | } |
---|
| 641 | $GLOBALS['phpgw_info']['flags']['app_header'] = lang('projectmanager').' - '.lang('Projectlist'); |
---|
| 642 | $tpl->exec('projectmanager.uiprojectmanager.index',$content,array( |
---|
| 643 | 'template' => $templates, |
---|
| 644 | )); |
---|
| 645 | } |
---|
| 646 | } |
---|