00001 <?php if(!function_exists('startedIndexPhp')) { header("location:../index.php"); exit();}
00002
00003 # streber - a php based project management system
00004 # Copyright (c) 2005 Thomas Mann - thomas@pixtur.de
00005 # Distributed under the terms and conditions of the GPL as stated in docs/license.txt
00006
00014 require_once(confGet('DIR_STREBER') . "db/class_task.inc.php");
00015 require_once(confGet('DIR_STREBER') . "db/class_project.inc.php");
00016 require_once(confGet('DIR_STREBER') . "db/class_projectperson.inc.php");
00017 require_once(confGet('DIR_STREBER') . "db/class_person.inc.php");
00018 require_once(confGet('DIR_STREBER') . "db/db_itemperson.inc.php");
00019 require_once(confGet('DIR_STREBER') . "render/render_list.inc.php");
00020 require_once(confGet('DIR_STREBER') . "lists/list_taskfolders.inc.php");
00021 require_once(confGet('DIR_STREBER') . "lists/list_comments.inc.php");
00022 require_once(confGet('DIR_STREBER') . "lists/list_tasks.inc.php");
00023 require_once(confGet('DIR_STREBER') . "lists/list_project_team.inc.php");
00024
00025
00029 function projList()
00030 {
00031 require_once(confGet('DIR_STREBER') . "lists/list_projects.inc.php");
00032
00033 global $PH;
00034 global $auth;
00035
00036
00037 ### create from handle ###
00038 $PH->defineFromHandle();
00039
00040 ### set up page and write header ####
00041 {
00042 $page= new Page();
00043 $page->cur_tab='projects';
00044 $page->title=__("Your Active Projects");
00045 if(!($auth->cur_user->user_rights & RIGHT_PROJECT_EDIT)) {
00046 $page->title_minor=sprintf(__("relating to %s"), $page->title_minor=$auth->cur_user->name);
00047 }
00048 else {
00049 $page->title_minor=__("admin view");
00050 }
00051 $page->type=__('List','page type');
00052
00053 $page->options=build_projList_options();
00054
00055 ### page functions ###
00056 $page->add_function(new PageFunction(array(
00057 'target'=>'projNew',
00058 'icon'=>'new',
00059 )));
00060
00061 ### render title ###
00062 echo(new PageHeader);
00063
00064
00065
00066 }
00067 echo (new PageContentOpen);
00068
00069 #--- list projects --------------------------------------------------------
00070 {
00071
00072 #$projects=Project::getActive($order_str);
00073 $list= new ListBlock_projects();
00074 $list->reduced_header= true;
00075
00076 $format = get('format');
00077 if($format == FORMAT_HTML|| $format == ''){
00078 $list->footer_links[]= $PH->getCSVLink();
00079 }
00080
00081
00082 unset($list->functions['projNewFromTemplate']);
00083
00084 $list->title= $page->title;
00085 $list->query_options['status_min']= STATUS_UNDEFINED;
00086 $list->query_options['status_max']= STATUS_OPEN;
00087
00088
00089 if($auth->cur_user->user_rights & RIGHT_VIEWALL) {
00090 $warning="";
00091 if(! ($auth->cur_user->user_rights & RIGHT_VIEWALL)) {
00092 $warning=__("<b>NOTE</b>: Some projects are hidden from your view. Please ask an administrator to adjust you rights to avoid double-creation of projects");
00093 }
00094
00095 $list->no_items_html= $PH->getLink('projNew',__('create new project'),array()). $warning;
00096 }
00097 else {
00098 $list->no_items_html= __("not assigned to a project");
00099 }
00100
00101 $list->print_automatic();
00102
00103 }
00104
00105 echo(new PageContentClose);
00106 echo(new PageHtmlEnd);
00107 }
00108
00109
00113 function ProjListClosed()
00114 {
00115 require_once(confGet('DIR_STREBER') . "lists/list_projects.inc.php");
00116
00117 global $PH;
00118 global $auth;
00119
00120
00121 ### create from handle ###
00122 $PH->defineFromHandle();
00123
00124 ### set up page and write header ####
00125 {
00126 $page= new Page();
00127 $page->cur_tab='projects';
00128 $page->title=__("Your Closed Projects");
00129 if(!($auth->cur_user->user_rights & RIGHT_VIEWALL)) {
00130 $page->title_minor=sprintf(__("relating to %s"), $page->title_minor=$auth->cur_user->name);
00131 }
00132 else {
00133 $page->title_minor=__("admin view");
00134 }
00135 $page->type=__('List','page type');
00136
00137 $page->options = build_projList_options();
00138
00139 ### render title ###
00140 echo(new PageHeader);
00141 }
00142 echo (new PageContentOpen);
00143
00144 #--- list projects --------------------------------------------------------
00145 {
00146 $list= new ListBlock_projects();
00147 $list->reduced_header=true;
00148
00149 ## Link to start cvs export ##
00150 $format = get('format');
00151 if($format == FORMAT_HTML || $format == ''){
00152 $list->footer_links[]= $PH->getCSVLink();
00153 }
00154
00155
00156 unset($list->functions['effortNew']);
00157 unset($list->functions['projNew']);
00158 unset($list->functions['projNewFromTemplate']);
00159
00160 $list->title= $page->title;
00161 $list->query_options['status_min']= STATUS_BLOCKED;
00162 $list->query_options['status_max']= STATUS_CLOSED;
00163
00164 $list->no_items_html= __("not assigned to a closed project");
00165
00166 $list->print_automatic();
00167
00168 }
00169
00170 echo(new PageContentClose);
00171 echo(new PageHtmlEnd);
00172
00173 }
00174
00175
00179 function ProjListTemplates()
00180 {
00181 require_once(confGet('DIR_STREBER') . "lists/list_projects.inc.php");
00182
00183 global $PH;
00184 global $auth;
00185
00186 ### create from handle ###
00187 $PH->defineFromHandle();
00188
00189 ### set up page and write header ####
00190 {
00191 $page= new Page();
00192 $page->cur_tab='projects';
00193 $page->title=__("Project Templates");
00194 if(!($auth->cur_user->user_rights & RIGHT_PROJECT_EDIT)) {
00195 $page->title_minor= sprintf(__("relating to %s"), $page->title_minor=$auth->cur_user->name);
00196 }
00197 else {
00198 $page->title_minor= __("admin view");
00199 }
00200 $page->type=__('List','page type');
00201
00202 $page->options= build_projList_options();
00203
00204 ### render title ###
00205 echo(new PageHeader);
00206 }
00207 echo (new PageContentOpen);
00208
00209 #--- list projects --------------------------------------------------------
00210 {
00211 $list= new ListBlock_projects();
00212 $list->reduced_header=true;
00213
00214 ## Link to start cvs export ##
00215 $format = get('format');
00216 if($format == FORMAT_HTML|| $format == ''){
00217 $list->footer_links[]= $PH->getCSVLink();
00218 }
00219
00220 unset($list->functions['effortNew']);
00221 unset($list->functions['projNew']);
00222 unset($list->functions['projCreateTemplate']);
00223 unset($list->functions['projOpenClose']);
00224
00225 $list->title= $page->title;
00226 $list->query_options['status_min']= STATUS_TEMPLATE;
00227 $list->query_options['status_max']= STATUS_TEMPLATE;
00228
00229 $list->no_items_html= __("no project templates");
00230
00231 $list->print_automatic();
00232
00233 }
00234
00235
00236 echo(new PageContentClose);
00237 echo(new PageHtmlEnd);
00238 }
00239
00240
00241
00242
00246 function ProjViewChanges()
00247 {
00248 global $PH;
00249 global $auth;
00250
00251 ### get current project ###
00252 $id=getOnePassedId('prj','projects_*');
00253 if(!$project= Project::getVisibleById($id)) {
00254 $PH->abortWarning(__("invalid project-id"));
00255 return;
00256 }
00257
00258 ### sets the presets ###
00259 $presets= array(
00260 ### all ###
00261 'all_changes' => array(
00262 'name'=> __('all'),
00263 'filters'=> array(
00264 'task_status' => array(
00265 'id' => 'task_status',
00266 'visible' => true,
00267 'active' => true,
00268 'min' => STATUS_UNDEFINED,
00269 'max' => STATUS_CLOSED,
00270 ),
00271 ),
00272 'list_settings' => array(
00273 'changes' =>array(
00274 'hide_columns' => array(''),
00275 'style'=> 'list',
00276 )
00277 )
00278 ),
00279 ## modified by me ##
00280 'modified_by_me' => array(
00281 'name'=> __('modified by me'),
00282 'filters'=> array(
00283 'task_status' => array(
00284 'id' => 'task_status',
00285 'visible' => true,
00286 'active' => true,
00287 'min' => STATUS_UNDEFINED,
00288 'max' => STATUS_CLOSED,
00289 ),
00290 'modified_by' => array(
00291 'id' => 'modified_by',
00292 'visible' => true,
00293 'active' => true,
00294 'value' => $auth->cur_user->id,
00295 ),
00296 ),
00297 'list_settings' => array(
00298 'changes' =>array(
00299 'hide_columns' => array(''),
00300 'style'=> 'list',
00301 )
00302 ),
00303 ),
00304 ## modified by others ##
00305 'modified_by_others' => array(
00306 'name'=> __('modified by others'),
00307 'filters'=> array(
00308 'task_status' => array(
00309 'id' => 'task_status',
00310 'visible' => true,
00311 'active' => true,
00312 'min' => STATUS_UNDEFINED,
00313 'max' => STATUS_CLOSED,
00314 ),
00315 'not_modified_by' => array(
00316 'id' => 'not_modified_by',
00317 'visible' => true,
00318 'active' => true,
00319 'value' => $auth->cur_user->id,
00320 ),
00321 ),
00322 'list_settings' => array(
00323 'changes' =>array(
00324 'hide_columns' => array(''),
00325 'style'=> 'list',
00326 )
00327 ),
00328 ),
00329 ## last logout ##
00330 'last_logout' => array(
00331 'name'=> __('last logout'),
00332 'filters'=> array(
00333 'last_logout' => array(
00334 'id' => 'last_logout',
00335 'visible' => true,
00336 'active' => true,
00337 'value' => $auth->cur_user->id,
00338 ),
00339 ),
00340 'list_settings' => array(
00341 'changes' =>array(
00342 'hide_columns' => array(''),
00343 'style'=> 'list',
00344 )
00345 ),
00346 ),
00347 ## 1 week ##
00348 'last_week' => array(
00349 'name'=> __('1 week'),
00350 'filters'=> array(
00351 'last_week' => array(
00352 'id' => 'last_week',
00353 'visible' => true,
00354 'active' => true,
00355 'factor' => 7,
00356 'value' => $auth->cur_user->id,
00357 ),
00358 ),
00359 'list_settings' => array(
00360 'changes' =>array(
00361 'hide_columns' => array(''),
00362 'style'=> 'list',
00363 )
00364 ),
00365 ),
00366 ## 2 week ##
00367 'last_two_weeks' => array(
00368 'name'=> __('2 weeks'),
00369 'filters'=> array(
00370 'last_two_weeks' => array(
00371 'id' => 'last_two_weeks',
00372 'visible' => true,
00373 'active' => true,
00374 'factor' => 14,
00375 'value' => $auth->cur_user->id,
00376 ),
00377 ),
00378 'list_settings' => array(
00379 'changes' =>array(
00380 'hide_columns' => array(''),
00381 'style'=> 'list',
00382 )
00383 ),
00384 ),
00385 ## prior ##
00386 );
00387
00388 ## set preset location ##
00389 $preset_location = 'projViewChanges';
00390
00391 ### get preset-id ###
00392 {
00393 $preset_id= 'last_two_weeks'; # default value
00394 if($tmp_preset_id= get('preset')) {
00395 if(isset($presets[$tmp_preset_id])) {
00396 $preset_id= $tmp_preset_id;
00397 }
00398
00399 ### set cookie
00400 setcookie(
00401 'STREBER_projViewChanges_preset',
00402 $preset_id,
00403 time()+60*60*24*30,
00404 '',
00405 '',
00406 0);
00407 }
00408 else if($tmp_preset_id= get('STREBER_projViewChanges_preset')) {
00409 if(isset($presets[$tmp_preset_id])) {
00410 $preset_id= $tmp_preset_id;
00411 }
00412 }
00413 }
00414
00415 ### create from handle ###
00416 $PH->defineFromHandle(array('prj'=>$project->id, 'preset_id'=>$preset_id));
00417
00418 ## init known filters for preset ##
00419 require_once(confGet('DIR_STREBER') . './lists/list_changes.inc.php');
00420 $page= new Page();
00421 $list = new ListBlock_changes();
00422 $list->query_options['project']= $project->id;
00423
00424 $list->filters[] = new ListFilter_changes();
00425 {
00426 $preset = $presets[$preset_id];
00427 foreach($preset['filters'] as $f_name=>$f_settings) {
00428 switch($f_name) {
00429 case 'task_status':
00430 $list->filters[]= new ListFilter_status_min(array(
00431 'value'=>$f_settings['min'],
00432 ));
00433 #$list->filters[]= new ListFilter_status_max(array(
00434 # 'value'=>$f_settings['max'],
00435 #));
00436 break;
00437 case 'modified_by':
00438 $list->filters[]= new ListFilter_modified_by(array(
00439 'value'=>$f_settings['value'],
00440 ));
00441 break;
00442 case 'not_modified_by':
00443 $list->filters[]= new ListFilter_not_modified_by(array(
00444 'value'=>$f_settings['value'],
00445 ));
00446 break;
00447 case 'last_logout':
00448 $list->filters[]= new ListFilter_last_logout(array(
00449 'value'=>$f_settings['value'],
00450 ));
00451 break;
00452 case 'last_week':
00453 $list->filters[]= new ListFilter_min_week(array(
00454 'value'=>$f_settings['value'], 'factor'=>$f_settings['factor']
00455 ));
00456 #$list->filters[]= new ListFilter_max_week(array(
00457 # 'value'=>$f_settings['value'],
00458 #));
00459 break;
00460 case 'last_two_weeks':
00461 $list->filters[]= new ListFilter_min_week(array(
00462 'value'=>$f_settings['value'], 'factor'=>$f_settings['factor']
00463 ));
00464 #$list->filters[]= new ListFilter_max_week(array(
00465 # 'value'=>$f_settings['value'],
00466 #));
00467 break;
00468 default:
00469 trigger_error("Unknown filter setting $f_name", E_USER_WARNING);
00470 break;
00471 }
00472 }
00473
00474 $filter_empty_folders = (isset($preset['filter_empty_folders']) && $preset['filter_empty_folders'])
00475 ? true
00476 : NULL;
00477 }
00478
00479 ### set up page ####
00480 {
00481 $page->cur_tab = 'projects';
00482
00483 $page->crumbs= build_project_crumbs($project);
00484 $page->options= build_projView_options($project);
00485
00486 $page->title_minor = __("Changes");
00487 $page->title= $project->name;
00488
00489 if($project->status == STATUS_TEMPLATE) {
00490 $page->type=__("Project Template");
00491 }
00492 else if ($project->status >= STATUS_COMPLETED){
00493 $page->type=__("Inactive Project");
00494 }
00495 else {
00496 $page->type=__("Project","Page Type");
00497 }
00498
00499 ### render title ###
00500 echo(new PageHeader);
00501 }
00502 echo (new PageContentOpen);
00503
00504 $page->print_presets(array(
00505 'target' => $preset_location,
00506 'project_id' => $project->id,
00507 'preset_id' => $preset_id,
00508 'presets' => $presets,
00509 'person_id' => ''));
00510
00511 #echo(new PageContentNextCol);
00512
00513 #--- list changes --------------------------------------------------------------------------
00514 {
00515 $list->print_automatic($project);
00516 }
00517
00518
00519
00520 ### HACKING: 'add new task'-field ###
00521 $PH->go_submit='taskNew';
00522 echo '<input type="hidden" name="prj" value="'.$id.'">';
00523
00524 #echo "<a href=\"javascript:document.my_form.go.value='tasksMoveToFolder';document.my_form.submit();\">move to task-folder</a>";
00525 echo (new PageContentClose);
00526 echo (new PageHtmlEnd());
00527 }
00528
00529
00533 function projViewTasks()
00534 {
00535 global $PH;
00536 global $auth;
00537
00538 ### get current project ###
00539 $id=getOnePassedId('prj','projects_*');
00540 if(!$project=Project::getVisibleById($id)) {
00541 $PH->abortWarning("invalid project-id");
00542 return;
00543 }
00544
00545 ### get upcoming or selected milestone ###
00546 $for_milestone= 0;
00547 $milestone= NULL;
00548 if(!$for_milestone=get('for_milestone')) {
00549 if($milestone= $project->getNextMilestone()) {
00550 $for_milestone= $milestone->id;
00551 }
00552 }
00553 else {
00554 $milestone= Task::getVisibleById($for_milestone);
00555 }
00556
00557 $presets= array(
00558 ### all ###
00559 'all_tasks' => array(
00560 'name'=> __('all'),
00561 'filters'=> array(
00562 'task_status'=> array(
00563 'id' => 'task_status',
00564 'visible' => true,
00565 'active' => true,
00566 'min' => STATUS_NEW,
00567 'max' => STATUS_CLOSED,
00568 ),
00569 ),
00570 'list_settings' => array(
00571 'tasks' =>array(
00572 'hide_columns' => array(
00573 ''
00574 ),
00575 'style'=> 'tree',
00576 )
00577 )
00578 ),
00579
00580 ### open tasks ###
00581 'open_tasks' => array(
00582 'name'=> __('open'),
00583 'filters'=> array(
00584 'task_status'=> array(
00585 'id' => 'task_status',
00586 'visible' => true,
00587 'active' => true,
00588 'values' => array(STATUS_NEW, STATUS_OPEN,STATUS_BLOCKED, STATUS_COMPLETED),
00589 'min' => STATUS_NEW,
00590 'max' => STATUS_COMPLETED,
00591 ),
00592 ),
00593 'list_settings' => array(
00594 'tasks' =>array(
00595 'hide_columns' => array(
00596 ''
00597 ),
00598 'style'=> 'list',
00599 )
00600 )
00601 ),
00602 ### my open tasks ###
00603 'my_open_tasks' => array(
00604 'name'=> __('my open'),
00605 'filter_empty_folders'=>true,
00606 'filters'=> array(
00607 'task_status'=> array(
00608 'id' => 'task_status',
00609 'visible' => true,
00610 'active' => true,
00611 'values' => array( STATUS_NEW, STATUS_OPEN,STATUS_BLOCKED),
00612 'min' => STATUS_NEW,
00613 'max' => STATUS_BLOCKED,
00614 ),
00615 'assigned_to' => array(
00616 'id' => 'assigned_to',
00617 'visible' => true,
00618 'active' => true,
00619 'value' => $auth->cur_user->id,
00620 ),
00621 ),
00622 'list_settings' => array(
00623 'tasks' =>array(
00624 'hide_columns' => array(
00625 ''
00626 ),
00627 'style'=> 'list',
00628 )
00629 ),
00630 'new_task_options'=> array(
00631 'task_assign_to_0'=> $auth->cur_user->id,
00632 ),
00633
00634 ),
00635
00636
00637
00638 ### next milestone ###
00639 'next_milestone' => array(
00640 'name'=> __('for milestone'),
00641 'filter_empty_folders'=>true,
00642 'filters'=> array(
00643 'task_status'=> array(
00644 'id' => 'task_status',
00645 'visible' => false,
00646 'active' => true,
00647 'values' => array( STATUS_NEW, STATUS_OPEN,STATUS_BLOCKED, STATUS_COMPLETED),
00648 'min' => STATUS_NEW,
00649 'max' => STATUS_COMPLETED,
00650 ),
00651 'for_milestone' => array(
00652 'id' => 'for_milestone',
00653 'visible' => true,
00654 'active' => true,
00655 'value' => $for_milestone,
00656 ),
00657 ),
00658 'list_settings' => array(
00659 'tasks' =>array(
00660 'hide_columns' => array(
00661 ''
00662 ),
00663 'style'=> 'list',
00664 )
00665 ),
00666 'new_task_options'=> array(
00667 'for_milestone'=> $for_milestone,
00668 ),
00669 ),
00670
00671 ### need Feedback ###
00672 'needs_feedback' => array(
00673 'name'=> __('modified'),
00674 'filter_empty_folders'=>true,
00675 'filters'=> array(
00676 'task_status'=> array(
00677 'id' => 'task_status',
00678 'visible' => true,
00679 'active' => true,
00680 'values' => array( STATUS_COMPLETED),
00681 'min' => STATUS_NEW,
00682 'max' => STATUS_COMPLETED,
00683 ),
00684 'not_modified_by'=> $auth->cur_user->id,
00685 ),
00686 'list_settings' => array(
00687 'tasks' =>array(
00688 'hide_columns' => array(
00689 ''
00690 ),
00691 'style'=> 'list',
00692 )
00693 )
00694 ),
00695
00696
00697 ### to be approved ###
00698 'approve_tasks' => array(
00699 'name'=> __('needs approval'),
00700 'filter_empty_folders'=>true,
00701 'filters'=> array(
00702 'task_status'=> array(
00703 'id' => 'task_status',
00704 'visible' => true,
00705 'active' => true,
00706 'values' => array( STATUS_COMPLETED),
00707 'min' => STATUS_COMPLETED,
00708 'max' => STATUS_COMPLETED,
00709 ),
00710 ),
00711 'list_settings' => array(
00712 'tasks' =>array(
00713 'hide_columns' => array(
00714 ''
00715 ),
00716 'style'=> 'list',
00717 )
00718 )
00719 ),
00720
00721 ### without milestone ###
00722 'without_milestone' => array(
00723 'name'=> __('without milestone'),
00724 'filter_empty_folders'=>true,
00725 'filters'=> array(
00726 'task_status'=> array(
00727 'id' => 'task_status',
00728 'visible' => true,
00729 'active' => true,
00730 'values' => array( STATUS_COMPLETED),
00731 'min' => STATUS_NEW,
00732 'max' => STATUS_COMPLETED,
00733 ),
00734 'for_milestone' => array(
00735 'id' => 'for_milestone',
00736 'visible' => true,
00737 'active' => true,
00738 'value' => 0,
00739 ),
00740 ),
00741 'list_settings' => array(
00742 'tasks' =>array(
00743 'hide_columns' => array(
00744 ''
00745 ),
00746 'style'=> 'list',
00747 )
00748 )
00749 ),
00750
00751 ### closed tasks ###
00752 'closed_tasks' => array(
00753 'name'=> __('closed'),
00754 'filter_empty_folders'=>false,
00755 'filters'=> array(
00756 'task_status'=> array(
00757 'id' => 'task_status',
00758 'visible' => true,
00759 'active' => true,
00760 'values' => array( STATUS_APPROVED, STATUS_CLOSED),
00761 'min' => STATUS_APPROVED,
00762 'max' => STATUS_CLOSED,
00763 ),
00764 ),
00765 'list_settings' => array(
00766 'tasks' =>array(
00767 'hide_columns' => array(
00768 ''
00769 ),
00770 'style'=> 'list',
00771 )
00772 )
00773 ),
00774 );
00775
00776 ## set preset location ##
00777 $preset_location = 'projViewTasks';
00778
00779 ### get preset-id ###
00780 {
00781 $preset_id= 'open_tasks'; # default value
00782 if($tmp_preset_id= get('preset')) {
00783 if(isset($presets[$tmp_preset_id])) {
00784 $preset_id= $tmp_preset_id;
00785 }
00786
00787 ### set cookie
00788 setcookie(
00789 'STREBER_projViewTasks_preset',
00790 $preset_id,
00791 time()+60*60*24*30,
00792 '',
00793 '',
00794 0);
00795 }
00796 else if($tmp_preset_id= get('STREBER_projViewTasks_preset')) {
00797 if(isset($presets[$tmp_preset_id])) {
00798 $preset_id= $tmp_preset_id;
00799 }
00800 }
00801 }
00802
00803 if($ms=get('for_milestone')) {
00804 ### create from handle ###
00805 $PH->defineFromHandle(array(
00806 'prj' =>$project->id,
00807 'peset_id' =>$preset_id,
00808 'for_milestone'=>$ms
00809 ));
00810
00811 }
00812 else {
00813 ### create from handle ###
00814 $PH->defineFromHandle(array(
00815 'prj' =>$project->id,
00816 'peset_id' =>$preset_id
00817 ));
00818 }
00819
00820 $page= new Page();
00821
00822 ### init known filters for preset ###
00823 $list= new ListBlock_tasks(array(
00824 'active_block_function'=>'tree',
00825
00826 ));
00827 $list->filters[]=new ListFilter_for_milestone();
00828 $list->filters[]=new ListFilter_category_in(array(
00829 'value'=> array(TCATEGORY_TASK,TCATEGORY_BUG)
00830
00831 ));
00832 {
00833
00834 $preset= $presets[$preset_id];
00835 foreach($preset['filters'] as $f_name=>$f_settings) {
00836 switch($f_name) {
00837
00838 case 'task_status':
00839 $list->filters[]= new ListFilter_status_min(array(
00840 'value'=>$f_settings['min'],
00841 ));
00842 $list->filters[]= new ListFilter_status_max(array(
00843 'value'=>$f_settings['max'],
00844 ));
00845 break;
00846
00847 case 'assigned_to':
00848 $list->filters[]= new ListFilter_assigned_to(array(
00849 'value'=>$f_settings['value'],
00850 ));
00851 break;
00852
00853 case 'for_milestone':
00854 $list->filters[]= new ListFilter_for_milestone(array(
00855 'value'=>$f_settings['value'],
00856 ));
00857 break;
00858
00859 case 'not_modified_by':
00860 $list->filters[]= new ListFilter_not_modified_by(array(
00861 'value'=>$f_settings['value'],
00862 ));
00863 break;
00864
00865
00866 default:
00867 trigger_error("Unknown filter setting $f_name", E_USER_WARNING);
00868 break;
00869 }
00870 }
00871
00872 $filter_empty_folders= (isset($preset['filter_empty_folders']) && $preset['filter_empty_folders'])
00873 ? true
00874 : NULL;
00875 }
00876
00877
00878
00879 ### set up page ####
00880 {
00881 $page->cur_tab='projects';
00882
00883 $page->crumbs= build_project_crumbs($project);
00884 $page->options= build_projView_options($project);
00885
00886 $page->title= $project->name;
00887
00888 if(isset($preset['name'])) {
00889 $page->title_minor= $preset['name'];
00890 if($preset_id == 'next_milestone' && isset($milestone) && isset($milestone->name)) {
00891 $page->title_minor = __('Milestone') .' '. $milestone->name;
00892 }
00893 }
00894 else {
00895 $page->title_minor= __("Tasks");
00896 }
00897
00898
00899 if($project->status == STATUS_TEMPLATE) {
00900 $page->type=__("Project Template");
00901 }
00902 else if ($project->status >= STATUS_COMPLETED){
00903 $page->type=__("Inactive Project");
00904 }
00905 else {
00906 $page->type=__("Project","Page Type");
00907 }
00908
00909 ### page functions ###
00910 $new_task_options = isset($preset['new_task_options'])
00911 ? $preset['new_task_options']
00912 : array();
00913
00914
00915 $page->add_function(new PageFunctionGroup(array(
00916 'name'=>__('new:'),
00917 )));
00918 if($preset_id != 'next_milestone') {
00919 $page->add_function(new PageFunction(array(
00920 'target' =>'taskNewFolder',
00921 'params' =>array('prj'=>$project->id)+ $new_task_options,
00922 'icon' =>'new',
00923 'tooltip' =>__('Create a new folder for tasks and files'),
00924 'name' =>__('Folder')
00925 )));
00926 }
00927
00928 $page->add_function(new PageFunction(array(
00929 'target'=>'taskNew',
00930 'params'=>array('prj'=>$project->id)+ $new_task_options,
00931 'icon'=>'new',
00932 'tooltip'=>__('new subtask for this folder'),
00933 'name'=>__('Task'),
00934 )));
00935
00936 $page->add_function(new PageFunction(array(
00937 'target' =>'taskNewBug',
00938 'params' =>array('prj'=>$project->id,'add_issue'=>1)+ $new_task_options,
00939 'icon' =>'new',
00940 'tooltip' =>__('Create task with issue-report'),
00941 'name' =>__('Bug')
00942 )));
00943
00944
00945 ### render title ###
00946 echo(new PageHeader);
00947 }
00948 echo (new PageContentOpen);
00949
00950 ### list available presets ###
00951 if($page->format != FORMAT_CSV){
00952 $page->print_presets(array(
00953 'target'=> $preset_location,
00954 'project_id'=> $project->id,
00955 'preset_id'=> $preset_id,
00956 'presets'=> $presets,
00957 'person_id' => ''));
00958 }
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 #echo(new PageContentNextCol);
00974
00975
00976
00977 if($page->format == FORMAT_HTML) {
00978 $PH->go_submit='taskNew';
00979 echo '<input type="hidden" name="prj" value="'.$id.'">';
00980
00986 foreach($new_task_options as $name=>$value) {
00987 echo "<input type=hidden name='$name' value='$value'>";
00988 }
00989
00990 ### Link to start cvs export ###
00991 $format = get('format');
00992 if($format == FORMAT_HTML || $format == ''){
00993 $list->footer_links[]= $PH->getCSVLink();
00994 }
00995 }
00996
00997
00998
00999 #--- list tasks --------------------------------------------------------------------------
01000 {
01001 $list->reduced_header= true;
01002 #$list->filters[]= new ListFilter_status_max(array('value'=>STATUS_COMPLETED));
01003
01004 #if($for_milestone=get('for_milestone')) {
01005 # $list->filters['for_milestone']= intval($for_milestone);
01006 #}
01007
01008
01009 unset($list->columns['project']);
01010 unset($list->columns['planned_start']);
01011
01017 if(confGet('TASKDETAILS_IN_SIDEBOARD')) {
01018 unset($list->columns['assigned_to']);
01019 unset($list->columns['for_milestone']);
01020 unset($list->columns['estimate_complete']);
01021 unset($list->columns['pub_level']);
01022 #unset($list->columns['_select_col_']);
01023 unset($list->columns['label']);
01024 }
01025 if(!confGet('TASK_LIST_EFFORT_COLUMN')) {
01026 unset($list->columns['efforts']);
01027 }
01028
01029 $list->no_items_html=__('No tasks');
01030 $list->print_automatic($project, NULL, $filter_empty_folders);
01031
01032
01033
01034 }
01035
01036
01037
01038 #echo "<a href=\"javascript:document.my_form.go.value='tasksMoveToFolder';document.my_form.submit();\">move to task-folder</a>";
01039 echo (new PageContentClose);
01040 echo (new PageHtmlEnd());
01041 }
01042
01043
01047 function ProjViewDocu()
01048 {
01049 global $PH;
01050 global $auth;
01051
01052 ### get current project ###
01053 $id=getOnePassedId('prj','projects_*');
01054 if(!$project=Project::getVisibleById($id)) {
01055 $PH->abortWarning("invalid project-id");
01056 return;
01057 }
01058
01059 ### create from handle ###
01060 $PH->defineFromHandle(array(
01061 'prj' =>$project->id,
01062 ));
01063
01064 ### set up page ####
01065 {
01066 $page= new Page();
01067 $page->cur_tab='projects';
01068
01069 $page->crumbs= build_project_crumbs($project);
01070 $page->options= build_projView_options($project);
01071
01072 $page->title= $project->name;
01073 $page->title_minor= __("Documentation");
01074
01075 if($project->status == STATUS_TEMPLATE) {
01076 $page->type=__("Project Template");
01077 }
01078 else if ($project->status >= STATUS_COMPLETED){
01079 $page->type=__("Inactive Project");
01080 }
01081 else {
01082 $page->type=__("Project","Page Type");
01083 }
01084
01085 ### page functions ###
01086 $page->add_function(new PageFunctionGroup(array(
01087 'name'=>__('new:'),
01088 )));
01089 $page->add_function(new PageFunction(array(
01090 'target' =>'taskNew',
01091 'params' =>array('prj'=>$project->id, 'task_category'=>TCATEGORY_DOCU),
01092 'icon' =>'new',
01093 'tooltip' =>__('Create a new page'),
01094 'name' =>__('Page')
01095 )));
01096
01097 ### render title ###
01098 echo(new PageHeader);
01099 }
01100 echo (new PageContentOpen);
01101
01102
01103
01104
01105 #--- list documentation pages --------------------------------------------------------------------------
01106 {
01107 ### init known filters for preset ###
01108 $list= new ListBlock_tasks(array(
01109 'active_block_function'=>'tree'
01110 ));
01111
01112 $list->reduced_header= true;
01113 #$list->filters[]= new ListFilter_status_max(array('value'=>STATUS_COMPLETED));
01114
01115 #if($for_milestone=get('for_milestone')) {
01116 # $list->filters['for_milestone']= intval($for_milestone);
01117 #}
01118 $list->query_options['category']= TCATEGORY_DOCU;
01119 $list->query_options['status_min']= 0;
01120 $list->query_options['status_max']= 10;
01121 $list->query_options['order_by']= 'order_id';
01122
01123 ### redefine columns ###
01124 $c_new = array();
01125 foreach($list->columns as $cname => $c) {
01126 if($cname == '_select_col_') {
01127 $c_new[$cname] = $c;
01128 }
01129 }
01130 $list->columns= $c_new;
01131 $list->add_col( new ListBlockCol_TaskAsDocu());
01132
01133 unset($list->functions['taskNew']);
01134 unset($list->functions['taskNewBug']);
01135 unset($list->functions['tasksCompleted']);
01136 unset($list->functions['tasksApproved']);
01137 unset($list->functions['tasksClosed']);
01138 #unset($list->functions['effortNew']);
01139 #unset($list->functions['commentNew']);
01140
01141
01142 $list->no_items_html=__('No tasks');
01143 $list->print_automatic($project, NULL, true);
01144 }
01145
01146 $PH->go_submit='taskNew';
01147 echo '<input type="hidden" name="prj" value="'.$id.'">';
01148
01149
01150 #echo "<a href=\"javascript:document.my_form.go.value='tasksMoveToFolder';document.my_form.submit();\">move to task-folder</a>";
01151 echo (new PageContentClose);
01152 echo (new PageHtmlEnd());
01153 }
01154
01155
01156
01157
01161 function ProjViewFiles()
01162 {
01163 global $PH;
01164
01165 ### get current project ###
01166 $id=getOnePassedId('prj','projects_*');
01167 if(!$project=Project::getVisibleById($id)) {
01168 $PH->abortWarning("invalid project-id");
01169 return;
01170 }
01171
01172 ### create from handle ###
01173 $PH->defineFromHandle(array('prj'=>$project->id));
01174
01175 ### set up page ####
01176 {
01177 $page= new Page();
01178 $page->cur_tab='projects';
01179
01180 $page->crumbs= build_project_crumbs($project);
01181 $page->options= build_projView_options($project);
01182
01183 $page->title_minor= __("Uploaded Files");
01184 $page->title=$project->name;
01185 $page->type= $project->getStatusType();
01186 $PH->go_submit= $PH->getValidPage('filesUpload')->id;
01187
01188
01189 ### page functions ###
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199 ### render title ###
01200 echo(new PageHeader);
01201 }
01202 echo (new PageContentOpen);
01203
01204 # echo(new PageContentNextCol);
01205
01206
01207 ### upload files ###
01208 {
01209 $block=new PageBlock(array('title'=>__('Upload file','block title'),'id'=>'summary'));
01210 $block->render_blockStart();
01211
01212 echo "<div class=text>";
01213 echo '<input type="hidden" name="MAX_FILE_SIZE" value="'. confGet('FILE_UPLOAD_SIZE_MAX'). '" />';
01214 echo '<input id="userfile" name="userfile" type="file" size="40" accept="*" />';
01215 echo '<input type="submit" value="'.__('Upload').'" />';
01216 echo '</div>';
01217
01218 $block->render_blockEnd();
01219 echo '<br />';
01220 }
01221
01222 ### list files ###
01223 {
01224 require_once(confGet('DIR_STREBER') . "lists/list_files.inc.php");
01225 $list= new ListBlock_files();
01226 $list->reduced_header= true;
01227 #$list->query_options['visible_only']= false;
01228 unset($list->columns['summary']);
01229
01230
01231 $list->print_automatic($project);
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241 # echo "<a href=\"javascript:document.my_form.go.value='tasksMoveToFolder';document.my_form.submit();\">move to task-folder</a>";
01242
01243
01244
01245 echo '<input type="hidden" name="prj" value="'.$id.'">';
01246
01247 echo (new PageContentClose);
01248 echo (new PageHtmlEnd());
01249 }
01250
01251
01252
01253
01258 function ProjViewMilestones()
01259 {
01260 global $PH;
01261 global $auth;
01262
01263 ### get current project ###
01264 $id=getOnePassedId('prj','projects_*');
01265 if(!$project=Project::getVisibleById($id)) {
01266 $PH->abortWarning("invalid project-id");
01267 return;
01268 }
01269
01270 ### create from handle ###
01271 $PH->defineFromHandle(array(
01272 'prj'=>$project->id,
01273 'preset'=> get('preset'),
01274 ));
01275
01276 ### set up page ####
01277 {
01278 $page= new Page();
01279 $page->cur_tab='projects';
01280
01281 $page->crumbs= build_project_crumbs($project);
01282 $page->options= build_projView_options($project);
01283
01284 $page->type= $project->getStatusType();
01285 $page->title=$project->name;
01286 $page->title_minor= __("Milestones");
01287
01288
01289 ### page functions ###
01290 if($auth->cur_user->id != confGet('ANONYMOUS_USER')) {
01291 $page->add_function(new PageFunction(array(
01292 'target'=>'taskNewMilestone',
01293 'params'=>array('prj'=>$project->id),
01294 'icon'=>'new',
01295 'name'=>__('new Milestone'),
01296 )));
01297 }
01298
01299
01300 ### render title ###
01301 echo(new PageHeader);
01302 }
01303 echo (new PageContentOpen);
01304
01305 # echo(new PageContentNextCol);
01306
01307
01308 #--- list milestones --------------------------------------------------------------------------
01309 {
01310 require_once(confGet('DIR_STREBER') . "lists/list_milestones.inc.php");
01311 $list= new ListBlock_milestones();
01312
01313 $list->query_options['is_milestone']= 1;
01314 echo "<div class=milestone_views>";
01315 if(get('preset') == 'completed') {
01316 $list->query_options['status_min']= STATUS_COMPLETED;
01317 $list->query_options['status_max']= STATUS_CLOSED;
01318
01319 echo $PH->getLink(
01320 'projViewMilestones',
01321 __('View open milestones'),
01322 array('prj'=>$project->id));
01323 }
01324 else {
01325 echo $PH->getLink(
01326 'projViewMilestones',
01327 __('View closed milestones'),
01328 array('prj'=>$project->id, 'preset'=>'completed'));
01329 }
01330 echo "</div>";
01331
01332 $list->reduced_header= true;
01333
01334 $list->print_automatic($project);
01335 }
01336 echo '<input type="hidden" name="prj" value="'.$id.'">';
01337
01338 echo (new PageContentClose);
01339 echo (new PageHtmlEnd());
01340 }
01341
01342
01343
01347 function ProjViewEfforts()
01348 {
01349 global $PH;
01350
01351 require_once(confGet('DIR_STREBER') . "lists/list_efforts.inc.php");
01352 require_once(confGet('DIR_STREBER') . "lists/list_effortsperson.inc.php");
01353 require_once(confGet('DIR_STREBER') . "lists/list_effortstask.inc.php");
01354
01355 ### get current project ###
01356 $id=getOnePassedId('prj','projects_*');
01357 if(!$project=Project::getVisibleById($id)) {
01358 $PH->abortWarning("invalid project-id");
01359 return;
01360 }
01361
01362 $presets= array(
01363 ### all ###
01364 'all_efforts' => array(
01365 'name'=> __('all'),
01366 'filters'=> array(
01367 'effort_status'=> array(
01368 'id' => 'effort_status',
01369 'visible' => true,
01370 'active' => true,
01371 'min' => EFFORT_STATUS_NEW,
01372 'max' => EFFORT_STATUS_BALANCED,
01373 ),
01374 ),
01375 'list_settings' => array(
01376 'tasks' =>array(
01377 'hide_columns' => array(''),
01378 'style'=> 'list',
01379 )
01380 )
01381 ),
01382
01383 ### new efforts ###
01384 'new_efforts' => array(
01385 'name'=> __('new'),
01386 'filters'=> array(
01387 'effort_status'=> array(
01388 'id' => 'effort_status',
01389 'visible' => true,
01390 'active' => true,
01391 'min' => EFFORT_STATUS_NEW,
01392 'max' => EFFORT_STATUS_NEW,
01393 ),
01394 ),
01395 'list_settings' => array(
01396 'tasks' =>array(
01397 'hide_columns' => array(''),
01398 'style'=> 'list',
01399 )
01400 )
01401 ),
01402
01403 ### open efforts ###
01404 'open_efforts' => array(
01405 'name'=> __('open'),
01406 'filters'=> array(
01407 'effort_status'=> array(
01408 'id' => 'effort_status',
01409 'visible' => true,
01410 'active' => true,
01411 'min' => EFFORT_STATUS_OPEN,
01412 'max' => EFFORT_STATUS_OPEN,
01413 ),
01414 ),
01415 'list_settings' => array(
01416 'tasks' =>array(
01417 'hide_columns' => array(''),
01418 'style'=> 'list',
01419 )
01420 )
01421 ),
01422
01423 ### discounted efforts ###
01424 'discounted_efforts' => array(
01425 'name'=> __('discounted'),
01426 'filters'=> array(
01427 'effort_status'=> array(
01428 'id' => 'effort_status',
01429 'visible' => true,
01430 'active' => true,
01431 'min' => EFFORT_STATUS_DISCOUNTED,
01432 'max' => EFFORT_STATUS_DISCOUNTED,
01433 ),
01434 ),
01435 'list_settings' => array(
01436 'tasks' =>array(
01437 'hide_columns' => array(''),
01438 'style'=> 'list',
01439 )
01440 )
01441 ),
01442
01443 ### not chargeable efforts ###
01444 'notchargeable_efforts' => array(
01445 'name'=> __('not chargeable'),
01446 'filters'=> array(
01447 'effort_status'=> array(
01448 'id' => 'effort_status',
01449 'visible' => true,
01450 'active' => true,
01451 'min' => EFFORT_STATUS_NOTCHARGEABLE,
01452 'max' => EFFORT_STATUS_NOTCHARGEABLE,
01453 ),
01454 ),
01455 'list_settings' => array(
01456 'tasks' =>array(
01457 'hide_columns' => array(''),
01458 'style'=> 'list',
01459 )
01460 )
01461 ),
01462
01463 ### balanced efforts ###
01464 'balanced_efforts' => array(
01465 'name'=> __('balanced'),
01466 'filters'=> array(
01467 'effort_status'=> array(
01468 'id' => 'effort_status',
01469 'visible' => true,
01470 'active' => true,
01471 'min' => EFFORT_STATUS_BALANCED,
01472 'max' => EFFORT_STATUS_BALANCED,
01473 ),
01474 ),
01475 'list_settings' => array(
01476 'tasks' =>array(
01477 'hide_columns' => array(''),
01478 'style'=> 'list',
01479 )
01480 )
01481 ),
01482 );
01483
01484 ## set preset location ##
01485 $preset_location = 'projViewEfforts';
01486
01487 ### get preset-id ###
01488 {
01489 $preset_id= 'all_efforts'; # default value
01490 if($tmp_preset_id= get('preset')) {
01491 if(isset($presets[$tmp_preset_id])) {
01492 $preset_id= $tmp_preset_id;
01493 }
01494
01495 ### set cookie
01496 setcookie(
01497 'STREBER_projViewEfforts_preset',
01498 $preset_id,
01499 time()+60*60*24*30,
01500 '',
01501 '',
01502 0);
01503 }
01504 else if($tmp_preset_id= get('STREBER_projViewEfforts_preset')) {
01505 if(isset($presets[$tmp_preset_id])) {
01506 $preset_id= $tmp_preset_id;
01507 }
01508 }
01509 }
01510
01511 ### create from handle ###
01512 $PH->defineFromHandle(array(
01513 'prj' =>$project->id,
01514 'preset_id' =>$preset_id
01515 ));
01516
01517 ### set up page ####
01518 {
01519 $page= new Page();
01520 $page->cur_tab='projects';
01521
01522 $page->crumbs= build_project_crumbs($project);
01523 $page->options= build_projView_options($project);
01524
01525 $page->title_minor= __("Project Efforts");
01526 $page->title=$project->name;
01527
01528 if($project->status == STATUS_TEMPLATE) {
01529 $page->type=__("Project Template");
01530 }
01531 else if ($project->status >= STATUS_COMPLETED){
01532 $page->type=__("Inactive Project");
01533 }
01534 else {
01535 $page->type=__("Project","Page Type");
01536 }
01537
01538 ### page functions ###
01539 $page->add_function(new PageFunction(array(
01540 'target'=>'effortNew',
01541 'params'=>array('prj'=>$project->id),
01542 'icon'=>'new',
01543 'name'=>__('new Effort'),
01544 )));
01545
01546
01547 ### render title ###
01548 echo(new PageHeader);
01549 }
01550 echo (new PageContentOpen);
01551
01552 #--- list efforts --------------------------------------------------------------------------
01553 {
01554
01555
01556 $order_by=get('sort_'.$PH->cur_page->id."_efforts");
01557
01558 require_once(confGet('DIR_STREBER') . "db/class_effort.inc.php");
01559 $efforts= Effort::getAll(array(
01560 'project'=> $project->id,
01561 'order_by'=> $order_by,
01562
01563 ));
01564 $list= new ListBlock_efforts();
01565
01566
01567 $list->filters[] = new ListFilter_efforts();
01568 {
01569 $preset = $presets[$preset_id];
01570 foreach($preset['filters'] as $f_name=>$f_settings) {
01571 switch($f_name) {
01572 case 'effort_status':
01573 $list->filters[]= new ListFilter_effort_status_min(array(
01574 'value'=>$f_settings['min'],
01575 ));
01576 $val1 = $f_settings['min'];
01577 $list->filters[]= new ListFilter_effort_status_max(array(
01578 'value'=>$f_settings['max'],
01579 ));
01580 $val2 = $f_settings['max'];
01581 break;
01582 default:
01583 trigger_error("Unknown filter setting $f_name", E_USER_WARNING);
01584 break;
01585 }
01586 }
01587
01588 $filter_empty_folders = (isset($preset['filter_empty_folders']) && $preset['filter_empty_folders'])
01589 ? true
01590 : NULL;
01591 }
01592
01593
01594
01595
01596
01597 ### Link to start cvs export ###
01598 $format = get('format');
01599 if($format == FORMAT_HTML || $format == ''){
01600 $list->footer_links[]= $PH->getCSVLink();
01601 }
01602
01603
01604 unset($list->columns['p.name']);
01605
01606 $page->print_presets(array(
01607 'target' => $preset_location,
01608 'project_id' => $project->id,
01609 'preset_id' => $preset_id,
01610 'presets' => $presets,
01611 'person_id' => ''));
01612
01613
01614 $list->query_options['order_by'] = $order_by;
01615 $list->query_options['project'] = $project->id;
01616 $list->print_automatic();
01617
01618
01619 }
01620
01621
01622 #--- list effort summary on team members --------------------------------------------------------------------
01623 {
01624 $list_effort_person = new ListBlock_effortsPerson();
01625 $list_effort_person->query_options['project'] = &$project->id;
01626 if($val1) $list_effort_person->query_options['effort_status_min'] = $val1;
01627 if($val2) $list_effort_person->query_options['effort_status_max'] = $val2;
01628 $list_effort_person->print_automatic();
01629 }
01630
01631 #--- list effort summary on tasks --------------------------------------------------------------------
01632 {
01633 $list_effort_tasks = new ListBlock_effortsTask();
01634 $list_effort_tasks->query_options['project'] = &$project->id;
01635 if($val1) $list_effort_tasks->query_options['effort_status_min'] = $val1;
01636 if($val2) $list_effort_tasks->query_options['effort_status_max'] = $val2;
01637 $list_effort_tasks->print_automatic();
01638 }
01639
01640
01641 ### 'add new task'-field ###
01642 $PH->go_submit='taskNew';
01643 echo '<input type="hidden" name="prj" value="'.$id.'">';
01644
01645 echo (new PageContentClose);
01646 echo (new PageHtmlEnd());
01647 }
01648
01649
01653 function ProjViewVersions()
01654 {
01655 global $PH;
01656 global $auth;
01657
01658 require_once(confGet('DIR_STREBER') . "lists/list_versions.inc.php");
01659
01660 ### get current project ###
01661 $id =getOnePassedId('prj','projects_*');
01662 if(!$project=Project::getVisibleById($id)) {
01663 $PH->abortWarning("invalid project-id");
01664 return;
01665 }
01666
01667 ### create from handle ###
01668 $PH->defineFromHandle(array('prj'=>$project->id));
01669
01670 ### set up page ####
01671 {
01672 $page= new Page();
01673 $page->cur_tab='projects';
01674
01675 $page->crumbs= build_project_crumbs($project);
01676 $page->options= build_projView_options($project);
01677
01678 $page->title_minor= __("Released Versions");
01679 $page->title=$project->name;
01680
01681 if($project->status == STATUS_TEMPLATE) {
01682 $page->type=__("Project Template");
01683 }
01684 else if ($project->status >= STATUS_COMPLETED){
01685 $page->type=__("Inactive Project");
01686 }
01687 else {
01688 $page->type=__("Project","Page Type");
01689 }
01690
01691 ### page functions ###
01692 if($auth->cur_user->id != confGet('ANONYMOUS_USER')) {
01693 $page->add_function(new PageFunction(array(
01694 'target'=>'taskNewVersion',
01695 'params'=>array('prj'=>$project->id),
01696 'icon'=>'new',
01697 'name'=>__('New released Milestone'),
01698 )));
01699 }
01700
01701
01702 ### render title ###
01703 echo(new PageHeader);
01704 }
01705 echo (new PageContentOpen);
01706
01707
01708 ### list versions ###
01709 {
01710
01711 $list= new ListBlock_versions();
01712 $list->reduced_header= true;
01713
01714 $list->query_options['project']= $project->id;
01715
01716
01717 $list->print_automatic($project);
01718 }
01719
01720
01721 ### list changes for upcomming version ###
01722 {
01723
01724 if($tasks= Task::getAll(array(
01725 'project' => $project->id,
01726 'status_min' => STATUS_COMPLETED,
01727 'status_max' => STATUS_CLOSED,
01728 'resolved_version' => RESOLVED_IN_NEXT_VERSION,
01729 'resolve_reason_min'=> RESOLVED_DONE, # @@@ this is not the best solution (should be IS NOT)
01730 ))) {
01731
01732 $block=new PageBlock(array(
01733 'title'=>__("Tasks resolved in upcomming version"),
01734 'id'=>'resolved_tasks',
01735 ));
01736 $block->render_blockStart();
01737 echo "<div class=text>";
01738 echo '<ul>';
01739 foreach($tasks as $t) {
01740 global $g_resolve_reason_names;
01741 if($t->resolve_reason && isset($g_resolve_reason_names[$t->resolve_reason])) {
01742 $reason= $g_resolve_reason_names[$t->resolve_reason] .": ";
01743 }
01744 else {
01745 $reason= "";
01746 }
01747
01748 echo '<li>' . $reason . $t->getLink(false) . '</li>';
01749 }
01750 echo '</ul>';
01751
01752 $block->render_blockEnd();
01753 }
01754 }
01755
01756 echo (new PageContentClose);
01757 echo (new PageHtmlEnd());
01758 }
01759
01760
01761
01765 function projNew() {
01766 global $PH;
01767
01768 $company=get('company');
01769
01770 ### build dummy form ###
01771 $newproject= new Project(array(
01772 'id' => 0,
01773 'name' => __('New Project'),
01774 'state' => 1,
01775 'company' => $company,
01776 'pub_level' => 100,
01777 )
01778 );
01779
01780 $PH->show('projEdit',array('prj'=>$newproject->id),$newproject);
01781 }
01782
01783
01787 function projEdit($project=NULL)
01788 {
01789 global $PH;
01790 global $auth;
01791 require_once ("./db/class_company.inc.php");
01792
01793 if(!$project) {
01794
01795 $prj=getOnePassedId('prj','projects_*');
01796
01797 ### get project ####
01798 if(!$project= Project::getEditableById($prj)) {
01799 $PH->abortWarning("could not get Project");
01800 return;
01801 }
01802 }
01803
01804 ### set up page and write header ####
01805 {
01806 $page= new Page(array('use_jscalendar'=>true,'autofocus_field'=>'project_name'));
01807 $page->cur_tab='projects';
01808 $page->type= __("Edit Project");
01809 $page->title=$project->name;
01810 $page->title_minor=$project->short;
01811
01812 $page->crumbs= build_project_crumbs($project);
01813 $page->options[]= new NaviOption(array(
01814 'target_id' => 'projEdit',
01815 ));
01816
01817 echo(new PageHeader);
01818 }
01819 echo (new PageContentOpen);
01820
01821 ### write form #####
01822 {
01823 global $g_status_names;
01824 global $g_prio_names;
01825 require_once(confGet('DIR_STREBER') . "render/render_form.inc.php");
01826
01827 ### form background ###
01828 $block=new PageBlock(array(
01829 'id' =>'project_edit',
01830 'reduced_header' => true,
01831 ));
01832 $block->render_blockStart();
01833
01834 $form=new PageForm();
01835 $form->button_cancel=true;
01836
01837
01838 $form->add($project->fields['name']->getFormElement(&$project));
01839
01840
01841 $form->add($tab_group=new Page_TabGroup());
01842
01843 ### main attributes ###
01844 {
01845 $tab_group->add($tab=new Page_Tab("project",__("Project")));
01846 $tab->add(new Form_Dropdown('project_status', "Status",array_flip($g_status_names),$project->status));
01847
01848 ### build company-list ###
01849 $companies=Company::getAll();
01850 $cl_options= array('undefined'=>0);
01851 foreach($companies as $c) {
01852 $cl_options[$c->name]= $c->id;
01853 }
01854 $tab->add(new Form_Dropdown('project_company',__('Company','form label'),$cl_options,$project->company));
01855
01856 $tab->add(new Form_Dropdown('project_prio', "Prio",array_flip($g_prio_names),$project->prio));
01857
01858 $tab->add($project->fields['projectpage']->getFormElement(&$project));
01859 $tab->add($project->fields['date_start']->getFormElement(&$project));
01860 $tab->add($project->fields['date_closed']->getFormElement(&$project));
01861
01862 }
01863
01864 ### description ###
01865 {
01866 $tab_group->add($tab=new Page_Tab("description",__("Description")));
01867
01868 $e= $project->fields['description']->getFormElement(&$project);
01869 $e->rows=20;
01870 $tab->add($e);
01871
01872 }
01873
01874 ### Display ###
01875 {
01876 global $g_project_setting_names;
01877 $tab_group->add($tab=new Page_Tab("tab3",__("Display")));
01878 $tab->add($project->fields['short']->getFormElement(&$project));
01879 $tab->add($project->fields['status_summary']->getFormElement(&$project));
01880
01881 $tab->add(new Form_checkbox('project_setting_efforts', $g_project_setting_names[PROJECT_SETTING_EFFORTS], $project->settings & PROJECT_SETTING_EFFORTS));
01882 $tab->add(new Form_checkbox('project_setting_milestones', $g_project_setting_names[PROJECT_SETTING_MILESTONES], $project->settings & PROJECT_SETTING_MILESTONES));
01883 $tab->add(new Form_checkbox('project_setting_versions', $g_project_setting_names[PROJECT_SETTING_VERSIONS], $project->settings & PROJECT_SETTING_VERSIONS));
01884 #$tab->add(new Form_checkbox('project_setting_only_pm_may_close', $g_project_setting_names[PROJECT_SETTING_ONLY_PM_MAY_CLOSE], $project->settings & PROJECT_SETTING_ONLY_PM_MAY_CLOSE));
01885
01886 }
01887
01888
01889 #$form->add($project->fields['prio']->getFormElement(&$project));
01890
01891
01892 #$form->add($project->fields['show_in_home']->getFormElement(&$project));
01893 #$form->add($project->fields['color']->getFormElement(&$project));
01894 #$form->add($project->fields['wikipage']->getFormElement(&$project));
01895
01896
01897
01898 #$form->add(new Form_Dropdown('status', "Status",array(),0));
01899
01900 #$form->add(new Form_Date('prj_date_start', 'Started',$project->fields['date_start']->db2value($project->date_start)));
01901 #$form->add(new Form_Date('prj_date_closed','Closed',$project->fields['date_closed']->db2value($project->date_closed)));
01902 #$form->add(new Form_Edit('prj_description', 'Description', $project->description));
01903
01904
01905
01906
01907
01908 ### create another one ###
01909 if($auth->cur_user->user_rights & RIGHT_PROJECT_CREATE && $project->id == 0) {
01910 $checked= get('create_another')
01911 ? 'checked'
01912 : '';
01913
01914 $form->form_options[]="<span class=option><input name='create_another' class='checker' type=checkbox $checked>".__("Create another project after submit")."</span>";
01915 }
01916
01917
01918 #echo "<input type=hidden name='prj' value='$project->id'>";
01919 $form->add(new Form_Hiddenfield('prj','',$project->id));
01920
01921
01922 echo($form);
01923
01924 $block->render_blockEnd();
01925
01926 $PH->go_submit='projEditSubmit';
01927
01928 if($return=get('return')) {
01929 echo "<input type=hidden name='return' value='$return'>";
01930 }
01931 }
01932 echo (new PageContentClose);
01933 echo (new PageHtmlEnd());
01934
01935 }
01936
01937
01938
01939
01943 function projEditSubmit()
01944 {
01945 global $PH;
01946 global $auth;
01947
01948 ### cancel ###
01949 if(get('form_do_cancel')) {
01950 if(!$PH->showFromPage()) {
01951 $PH->show('projView',array('prj'=>$project->id));
01952 }
01953 exit();
01954 }
01955
01956 log_message("projEditSubmit()", LOG_MESSAGE_DEBUG);
01957
01958 if(!validateFormCrc()) {
01959 $PH->abortWarning(__('Invalid checksum for hidden form elements'));
01960 }
01961
01962
01963 ### get project ####
01964 $project_id = getOnePassedId('prj');
01965 if($project_id == 0) {
01966 $project= new Project(array());
01967 }
01968 else {
01969 if(!$project= Project::getEditableById($project_id)) {
01970 $PH->abortWarning("Could not get project");
01971 return;
01972 }
01973 }
01974
01975 $project->validateEditRequestTime();
01976
01977 log_message(" :edit request time validated()", LOG_MESSAGE_DEBUG);
01978
01979
01980 # retrieve all possible values from post-data
01981 # NOTE:
01982 # - this could be an security-issue.
01983 # - TODO: as some kind of form-edit-behaviour to field-definition
01984 foreach($project->fields as $f) {
01985 $name=$f->name;
01986 $f->parseForm(&$project);
01987 }
01988
01989 ### project company ###
01990 if(!is_null(get('project_company'))) {
01991 $project->company = intval(get('project_company'));
01992 }
01993
02000 {
02001 foreach( array(
02002 'project_setting_efforts' => PROJECT_SETTING_EFFORTS,
02003 'project_setting_milestones' => PROJECT_SETTING_MILESTONES,
02004 'project_setting_versions' => PROJECT_SETTING_VERSIONS,
02005 'project_setting_only_pm_may_close' => PROJECT_SETTING_ONLY_PM_MAY_CLOSE,
02006 ) as $form_name => $setting) {
02007 if(!is_null(get($form_name))) {
02008 $project->settings |= $setting;
02009 }
02010 else {
02011 $project->settings &= $setting ^ PROJECT_SETTING_ALL;
02012 }
02013 }
02014 }
02015
02016
02017 log_message(" :validated", LOG_MESSAGE_DEBUG);
02018
02019
02020 ### write to db ###
02021 if($project->id ==0) {
02022 $project->insert();
02023
02024 ### if new project add creator to team ###
02025 if($person= Person::getVisibleById($project->created_by)) {
02026
02027 ### effort-style
02028 $adjust_effort_style= ($person->settings & USER_SETTING_EFFORTS_AS_DURATION)
02029 ? EFFORT_STYLE_DURATION
02030 : EFFORT_STYLE_TIMES;
02031
02032 $pp_new= new ProjectPerson(array(
02033 'id' => 0,
02034 'person' => $person->id,
02035 'project' => $project->id,
02036 'adjust_effort_style' => $adjust_effort_style,
02037 'pub_level' =>PUB_LEVEL_CLIENT, # the creator should be visible to client
02038 ));
02039
02040 ### add project-right ###
02041 $pp_new->initWithUserProfile(PROFILE_ADMIN);
02042
02043 log_message(" :inserting...", LOG_MESSAGE_DEBUG);
02044 $pp_new->insert();
02045 log_message(" :inserted", LOG_MESSAGE_DEBUG);
02046 }
02047 else {
02048 trigger_error("creator of person not visible?",E_USER_WARNING);
02049 }
02050
02051 }
02052 else {
02053 log_message(" :updating...", LOG_MESSAGE_DEBUG);
02054 $project->update();
02055 log_message(" :updated", LOG_MESSAGE_DEBUG);
02056 }
02057
02058 ### notify on change ###
02059 $project->nowChangedByUser();
02060
02061 ### automatically view new project ###
02062 if($project_id == 0) {
02063 ### create another person ###
02064 if(get('create_another')) {
02065 $PH->show('projNew');
02066 exit();
02067 }
02068 else {
02069 $PH->show('projView',array('prj'=>$project->id));
02070 exit();
02071 }
02072 }
02073 ### otherwise return to from-page
02074 else {
02075 ### display taskView ####
02076 if(!$PH->showFromPage()) {
02077 $PH->show('projView',array('prj'=>$project->id));
02078 }
02079 }
02080 }
02081
02082
02086 function projDelete()
02087 {
02088 global $PH;
02089
02090 $ids= getPassedIds('prj','projects_*');
02091
02092 if(!$ids) {
02093 $PH->abortWarning(__("Select some projects to delete"));
02094 return;
02095 }
02096
02097 $counter=0;
02098 $errors=0;
02099 foreach($ids as $id) {
02100 if(!$p= Project::getEditableById($id)) {
02101 $errors++;
02102 }
02103 else {
02104 if($p->delete()) {
02105 $counter++;
02106 }
02107 else {
02108 $errors++;
02109 }
02110 }
02111 }
02112 if($errors) {
02113 new FeedbackWarning(sprintf(__("Failed to delete %s projects"), $errors));
02114 }
02115 else {
02116 new FeedbackMessage(sprintf(__("Moved %s projects to trash"),$counter));
02117 }
02118
02119 ### display projList ####
02120 $PH->show('projList');
02121
02122 }
02123
02129 function projChangeStatus()
02130 {
02131 global $PH;
02132
02133 $ids= getPassedIds('prj','projects_*');
02134
02135 if(!$ids) {
02136 $PH->abortWarning(__("Select some projects..."));
02137 return;
02138 }
02139
02140 $count_opened=0;
02141 $count_closed=0;
02142 $errors=0;
02143 foreach($ids as $id) {
02144 $e= Project::getEditableById($id);
02145 if(!$e || $e->state ==-1) {
02146 $PH->abortWarning(__("Invalid project-id!"));
02147 }
02148
02149 if($e->status <= STATUS_OPEN) {
02150 $e->status= STATUS_CLOSED;
02151 $e->date_closed= date(__("Y-m-d"),time());
02152 $count_closed++;
02153 }
02154 else if($e->status > STATUS_OPEN) {
02155 $e->status= STATUS_OPEN;
02156 $count_opened++;
02157 }
02158 $e->update();
02159 }
02160 if($errors) {
02161 new FeedbackWarning(sprintf(__("Failed to change %s projects"),$errors));
02162 }
02163 else {
02164 if($count_closed) {
02165 new FeedbackMessage(sprintf(__("Closed %s projects"),$count_closed));
02166 }
02167 else if($count_opened) {
02168 new FeedbackMessage(sprintf(__("Reactivated %s projects"),$count_opened));
02169 }
02170 }
02171
02172 ### display taskView ####
02173 if(!$PH->showFromPage()) {
02174 $PH->show('projList');
02175 }
02176 }
02177
02185 function projAddPerson()
02186 {
02187 global $PH;
02188
02189 $id= getOnePassedId('prj',''); # WARNS if multiple; ABORTS if no id found
02190 if(!$project= Project::getEditableById($id)) {
02191 $PH->abortWarning("ERROR: could not get Project");
02192 }
02193
02194
02195
02196 ### set up page and write header ####
02197 {
02198 $page= new Page(array('use_jscalendar'=>false, 'autofocus_field'=>'company_name'));
02199 $page->cur_tab='projects';
02200 $page->type= __("Edit Project");
02201 $page->title="$project->name";
02202 $page->title_minor=__("Select new team members");
02203
02204 $page->crumbs= build_project_crumbs($project);
02205
02206 $page->options[]= new NaviOption(array(
02207 'target_id' =>'projAddPerson',
02208
02209 ));
02210
02211 echo(new PageHeader);
02212 }
02213 echo (new PageContentOpen);
02214
02215 ### write form #####
02216 {
02217 require_once(confGet('DIR_STREBER') . "pages/person.inc.php");
02218 require_once(confGet('DIR_STREBER') . "render/render_form.inc.php");
02219
02220 ### write list of persons ###
02221 {
02222 ### build hash of already added person ###
02223 $pps= $project->getProjectPersons('', true,false);
02224 $pp_hash=array();
02225 foreach($pps as $pp) {
02226 $pp_hash[$pp->person]= true;
02227 }
02228
02229 ### filter already added persons ###
02230 $persons = array();
02231 if($pers = Person::getPersons())
02232 {
02233 foreach($pers as $p) {
02234 if(!isset($pp_hash[$p->id])) {
02235 $persons[]=$p;
02236 }
02237 }
02238 }
02239
02240 $list= new ListBlock_persons();
02241
02242 unset($list->columns['personal_phone']);
02243 unset($list->columns['office_phone']);
02244 unset($list->columns['mobile_phone']);
02245 unset($list->columns['companies']);
02246 unset($list->columns['changes']);
02247 unset($list->columns['last_login']);
02248 $list->functions=array();
02249 $list->no_items_html=__("Found no persons to add. Go to `People` to create some.");
02250
02251 $list->render_list(&$persons);
02252 }
02253
02254
02255
02256 #@@@ probably add dropdown-list with new project-role here
02257
02258 $PH->go_submit='projAddPersonSubmit';
02259 echo "<input type=hidden name='project' value='$project->id'>";
02260 echo "<div class=formbuttons>";
02261 $name=__('Add');
02262 echo "<input class=button type=submit value='$name'>";
02263 echo "</div>";
02264 }
02265 echo (new PageContentClose);
02266 echo (new PageHtmlEnd());
02267 }
02268
02269
02273 function projAddPersonSubmit()
02274 {
02275 global $PH;
02276
02277 require_once(confGet('DIR_STREBER') . "db/class_person.inc.php");
02278
02279 $id= getOnePassedId('project','');
02280 if(!$project= Project::getEditableById($id)) {
02281 $PH->abortWarning("Could not get object...",ERROR_FATAL);
02282 }
02283
02284 ### get persons ###
02285 $person_ids= getPassedIds('person','persons*');
02286 if(!$person_ids) {
02287 $PH->abortWarning(__("No persons selected..."),ERROR_NOTE);
02288 }
02289
02290 ### get team (including inactive members) ###
02291 $ppersons= $project->getProjectPersons('',false,false); # also PP with state !=1
02292
02293 ### go through selected people ###
02294 foreach($person_ids as $pid) {
02295 if(!$person= Person::getVisibleById($pid)) {
02296 $PH->abortWarning(__("Could not access person by id"));
02297 return;
02298 }
02299
02300 #### person already employed? ###
02301 $already_in=false;
02302 $pp=NULL;
02303 foreach($ppersons as $pp) {
02304 if($pp->person == $person->id) {
02305 $already_in= true;
02306 break;
02307 }
02308 }
02309
02310 ### effort-style
02311 $adjust_effort_style= ($person->settings & USER_SETTING_EFFORTS_AS_DURATION)
02312 ? EFFORT_STYLE_DURATION
02313 : EFFORT_STYLE_TIMES;
02314
02315 ### add ###
02316 if(!$already_in) {
02317 $pp_new= new ProjectPerson(array(
02318 'id' => 0,
02319 'person' => $person->id,
02320 'project' => $project->id,
02321 'adjust_effort_style' => $adjust_effort_style,
02322 ));
02323
02324 ### add project-right ###
02325 global $g_user_profile_names;
02326 if($g_user_profile_names[$person->profile]) {
02327 $profile_id= $person->profile;
02328
02329 $pp_new->initWithUserProfile($profile_id);
02330 }
02331 else {
02332 trigger_error("person '$person->name' has undefined profile", E_USER_WARNING);
02333 }
02334
02335
02336 $pp_new->insert();
02337 }
02338 ### reanimate ###
02339 else if($pp->state != 1) {
02340 $pp->state=1;
02341 $pp->update();
02342 new FeedbackMessage(__("Reanimated person as team-member"));
02343 }
02344 ### skip ###
02345 else {
02346 new FeedbackMessage(__("Person already in project"));
02347 }
02348 }
02349 ### display taskView ####
02350 if(!$PH->showFromPage()) {
02351 $PH->show('projView',array('prj'=>$project->id));
02352 }
02353 }
02354
02355
02364 function projCreateTemplate() {
02365
02366 global $PH;
02367 global $auth;
02368
02369 $count_items=0;
02370
02371 $project_id= getOnePassedId('prj','projects_*'); # aborts on failure
02372
02376 if(!$org_project= Project::getVisibleById($project_id)) {
02377 $PH->abortWarning("could not get Project");
02378 return;
02379 }
02380
02381 if(!$new_project = projDuplicate($project_id)) {
02382 $PH->abortWarning("duplicating project failed.", ERROR_DATASTRUCTURE);
02383 return;
02384 }
02385 $new_project->status= STATUS_TEMPLATE;
02386 $new_project->name= "- ".$new_project->name." - ". __("Template","as addon to project-templates");
02387 $new_project->update(array('status','name'),false);
02388
02389 $PH->show('projEdit',array('prj'=>$new_project->id),$new_project);
02390 }
02391
02392
02393
02402 function projNewFromTemplate() {
02403
02404 global $PH;
02405 global $auth;
02406
02407 $count_items=0;
02408
02409 $project_id= getOnePassedId('prj','projects_*'); # aborts on failure
02410
02414 if(!$org_project= Project::getVisibleById($project_id)) {
02415
02416 $PH->abortWarning("could not get Project");
02417 return;
02418 }
02419
02420 if(!$new_project = projDuplicate($project_id)) {
02421 $PH->abbortWarning("duplicating project failed.", ERROR_DATASTRUCTURE);
02422 return;
02423 }
02424 $new_project->status= STATUS_NEW;
02425
02426
02427 ### remove template-string ###
02428 $matches= array();
02429 if(preg_match("/- (.*) ".__("Template","as addon to project-templates")."/", $new_project->name,$matches)) {
02430 if(count($matches)==2) {
02431 $new_project->name = $matches[1];
02432 }
02433 }
02434
02435 $PH->show('projEdit',array('prj'=>$new_project->id),$new_project);
02436 }
02437
02438
02455 function projDuplicate($org_project_id=NULL)
02456 {
02457 require_once(confGet('DIR_STREBER') . "db/class_effort.inc.php");
02458 require_once(confGet('DIR_STREBER') . "db/class_file.inc.php");
02459 require_once(confGet('DIR_STREBER') . "db/class_issue.inc.php");
02460
02461 global $PH;
02462 global $auth;
02463
02464 $count_items=0;
02465
02466 if(!$org_project_id) {
02467 trigger_error("projDuplicate() called without project-id",E_USER_WARNING);
02468 return;
02469 }
02470
02474 if(!$org_project= Project::getEditableById($org_project_id)) {
02475 trigger_error("could not get Project",E_USER_NOTICE);
02476 return;
02477 }
02478
02484 if(!$new_project= Project::getEditableById($org_project_id)) {
02485 trigger_error("could not get Project", E_USER_NOTICE);
02486 return;
02487 }
02488
02489
02490 ### duplicate project ###
02491 $new_project->id=0;
02492
02493 $new_project->created_by= $auth->cur_user->id;
02494 $new_project->modified_by= $auth->cur_user->id;
02495 $new_project->date_start= getGMTString();
02496 $new_project->status= 3; #@@@ avoid majic numbers
02497
02498 $new_project->state=1; # be sure project is no deleted
02499 if(!$new_project->insert()) {
02500 trigger_error("Failed to insert new project. Datastructure might have been corrupted", E_USER_WARNING);
02501 return;
02502 }
02503
02504
02505 $flag_cur_user_in_project=false;
02506
02507 ### copy projectpersons ###
02508 if($org_ppersons= $org_project->getProjectPersons(
02509 NULL, # $order_by=NULL,
02510 false, # $alive_only=true,
02511 false # $visible_only= true
02512 )){
02513 foreach($org_ppersons as $pp){
02514 $pp->id=0;
02515 $pp->project= $new_project->id;
02516
02517 ### make current user project admin ###
02518 if($pp->person == $auth->cur_user->id) {
02519
02520 $pp->initWithUserProfile(PROFILE_ADMIN);
02521 $flag_cur_user_in_project= true;
02522 }
02523
02524 if(!$pp->insert()) {
02525 trigger_error(__("Failed to insert new project person. Data structure might have been corrupted"),E_USER_WARNING);
02526 return;
02527 }
02528 $count_items++;
02529 }
02530 }
02531
02532
02533 ### be sure, current user is admin ###
02534 if(!$flag_cur_user_in_project) {
02535 $pp_new= new ProjectPerson(array(
02536 'id' =>0,
02537 'person' =>$auth->cur_user->id,
02538 'project' =>$new_project->id,
02539 ));
02540 $pp_new->initWithUserProfile(PROFILE_ADMIN);
02541 if(!$pp_new->insert()) {
02542 trigger_error(__("Failed to insert new project person. Data structure might have been corrupted"),E_USER_WARNING);
02543 return;
02544 }
02545 }
02546
02547
02548 ### copy issues ###
02549 $dict_issues=array(0=>0);
02550
02551 $org_issues= $org_project->getIssues(NULL,false,false);
02552
02553 foreach($org_issues as $i) {
02554
02555 $org_issue_id= $i->id;
02556
02557 $i->project= $new_project->id;
02558 $i->id =0;
02559 if(!$i->insert()) {
02560 trigger_error(__("Failed to insert new issue. DB structure might have been corrupted."),E_USER_WARNING);
02561 return;
02562 }
02563
02564 $count_items++;
02565 $dict_issues[$org_issue_id]= $i->id;
02566 }
02567
02568
02569 ### copy tasks
02570 {
02571 ### pass1 ###
02572 $dict_tasks=array(0=>0); # assoc array of old / new task-ids
02573
02574 $new_tasks=array();
02575
02576 if($org_tasks= $org_project->getTasks(array(
02577 'show_folders' =>true,
02578 'status_min' =>0,
02579 'status_max' =>10,
02580 'visible_only' =>false,
02581 'alive_only' =>false,
02582 ))) {
02583 foreach($org_tasks as $t) {
02584
02585 $org_task_id= $t->id;
02586 $t->id= 0;
02587 $t->project= $new_project->id;
02588 if(!isset($dict_issues[$t->issue_report])) {
02589 trigger_error("undefined issue-id $t->issue_report. DB structure might have been corrupted.", E_USER_NOTICE);
02590 }
02591 else {
02592 $t->issue_report = $dict_issues[$t->issue_report];
02593 }
02594
02595 if(!$t->insert()) {
02596 trigger_error("Failed to insert new task. DB structure might have been corrupted.",E_USER_WARNING);
02597 return;
02598 }
02599
02600 $count_items++;
02601 $dict_tasks[$org_task_id]= $t->id;
02602 $new_tasks[]=$t;
02603 }
02604 }
02605
02606 ### pass2: tasks / parent_task ###
02607 foreach($new_tasks as $nt) {
02608 if(isset($dict_tasks[$nt->parent_task])) {
02609 $nt->parent_task= $dict_tasks[$nt->parent_task];
02610 }
02611 else {
02612 trigger_error("undefined task-id $nt->parent_task",E_USER_WARNING);
02613 }
02614 if(!$nt->update()) {
02615 trigger_error(__("Failed to update new task. DB structure might have been corrupted."),E_USER_WARNING);
02616 return;
02617 }
02618 }
02619 }
02620
02621
02622 ### copy efforts ###
02623 $dict_efforts=array(0 => 0);
02624
02625 if($org_efforts= Effort::getAll(array(
02626 'project' => $org_project->id,
02627 'visible_only' => false,
02628 'alive_only' => false
02629 ))) {
02630 foreach($org_efforts as $e) {
02631
02632 $org_effort_id= $e->id;
02633
02634 if(isset($dict_tasks[$e->task])) {
02635 $e->task= $dict_tasks[$e->task];
02636 }
02637 else {
02638 trigger_error("undefined task-id $e->task", E_USER_NOTICE);
02639 }
02640 $e->id= 0;
02641 $e->project= $new_project->id;
02642 if(!$e->insert()) {
02643 trigger_error("Failed to insert new effort. DB structure might have been corrupted.",E_USER_WARNING);
02644 return;
02645 }
02646
02647 $count_items++;
02648 $dict_efforts[$org_effort_id]= $e->id;
02649 }
02650 }
02651
02652 ### copy task_assigments ###
02653 $dict_taskpersons=array(0 => 0); # this hash is not required
02654
02655 if($org_taskpersons= $org_project->getTaskPersons(
02656 "", # $order_by=NULL,
02657 false, # $visible_only=true,
02658 false # $alive_only=true
02659 )) {
02660 foreach($org_taskpersons as $tp) {
02661
02662 $org_taskperson_id= $tp->id;
02663
02664 if(isset($dict_tasks[$tp->task])) {
02665 $tp->task= $dict_tasks[$tp->task];
02666 }
02667 else {
02668 trigger_error("undefined task-id $e->task", E_USER_WARNING);
02669 }
02670
02671 $tp->id= 0;
02672 $tp->project= $new_project->id;
02673 if(!$tp->insert()) {
02674 trigger_error("Failed to insert new taskperson. DB structure might have been corrupted.",E_USER_WARNING);
02675 return;
02676 }
02677
02678 $count_items++;
02679 $dict_taskpersons[$org_taskperson_id]= $tp->id;
02680 }
02681 }
02682
02683 ### copy comments ###
02684 {
02685 $dict_comments=array(0 => 0);
02686 $new_comments=array();
02687
02688 if($org_comments= $org_project->getComments(
02689 "", # $order_by=NULL,
02690 false, # $visible_only=true,
02691 false # $alive_only=true
02692 )) {
02693 foreach($org_comments as $c) {
02694
02695 $org_comment_id= $c->id;
02696
02697
02698 if(isset($dict_tasks[$c->task])) {
02699 $c->task= $dict_tasks[$c->task];
02700 }
02701 if(isset($dict_efforts[$c->effort])) {
02702 $c->effort= $dict_efforts[$c->effort];
02703 }
02704 if(isset($dict_effort[$c->effort])){
02705 $c->effort= $dict_efforts[$c->effort];
02706 }
02707
02708 $c->id= 0;
02709 $c->project = $new_project->id;
02710
02711 if(!$c->insert()) {
02712 trigger_error(__("Failed to insert new comment. DB structure might have been corrupted."),E_USER_WARNING);
02713 return;
02714 }
02715
02716 $count_items++;
02717
02718 $dict_comments[$org_comment_id]= $c->id;
02719 $new_comments[]=$c;
02720 }
02721 }
02722
02723 ### pass2: comment / on comment ###
02724 foreach($new_comments as $nc) {
02725 $nc->comment= $dict_comments[$nc->comment];
02726 if(!$nc->update()) {
02727 trigger_error("Failed to update new comment. DB structure might have been corrupted.",E_USER_WARNING);
02728 return;
02729 }
02730 }
02731 }
02732
02733 #new FeedbackMessage(sprintf(__("Project duplicated (including %s items)"), $count_items));
02734 #if(!$new_project->insert()) {
02735 # trigger_error("Inserting new project failed. DB structure might have been corrupted.", E_USER_WARNING);
02736 # return;
02737 #}
02738 return $new_project;
02739 #$PH->show('projEdit',array('prj'=>$new_project->id),$new_project);
02740 }
02741
02742
02743
02747 function projViewAsRSS()
02748 {
02749 require_once(confGet('DIR_STREBER') . "std/class_rss.inc.php");
02750
02751 global $PH;
02752 global $auth;
02753
02754 $project_id= getOnePassedId('prj','projects_*'); # aborts on failure
02755
02756 if(!$project= Project::getVisibleById($project_id)) {
02757 echo "Project is not readable. Anonymous user active?";
02758 exit();
02759 }
02760
02761
02762 ### used cached? ###
02763 $filepath = "_rss/proj_$project->id.xml";
02764 if(file_exists($filepath) || getGMTString(filemtime($filepath)) ."<". $project->modified) {
02765 RSS::updateRSS($project);
02766 }
02767 readfile_chunked($filepath);
02768
02769 exit();
02770 }
02771
02772
02773
02774
02775 ?>