php8
[web.mtrack] / MTrackWeb / TicketEdit.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3  
4 //require_once 'MTrack/Captcha.php';
5
6  
7 require_once 'MTrackWeb.php';
8 class MTrackWeb_TicketEdit extends MTrackWeb 
9 {
10     var $id; // 0 = new
11     var $issue;
12     var $preview;
13     var $error;
14     var $editable;
15     var $tid = 0; // or the MD5 rep.
16     
17      
18     
19     function getAuth() 
20     {
21         parent::getAuth();
22         //require_once 'MTrack/ACL.php';
23      //   MTrackACL::requireAllRights('Browser', 'read');
24         return true;
25   
26     }
27     
28     function get($pi= 0)
29     {
30     
31         if (!isset($_REQUEST['ajax_body'])) {
32             return;
33         }
34         
35         
36         $this->masterTemplate = 'ticket_edit.html';
37         $this->id = $pi ?  $pi : (isset($_GET['id']) ? $_GET['id'] : 0);
38         $this->id  = $this->id  == 'new' ? 0 : $this->id;
39         $this->id  = (int) $this->id;
40        // var_dump($this->id);
41         $ret = $this->loadIssue();
42         $this->initEditForm();
43         
44         
45         return $ret;
46     }
47     
48     function loadIssue() { 
49         // -- load issue..
50
51         $this->issue = DB_DataObject::factory('mtrack_ticket');
52
53         if ($this->id) {
54             if (!$this->issue->get($this->id)) {
55                 throw new Exception("Invalid ticket $this->id");
56             }
57             if ($this->id && $this->currentProject() != $this->issue->project_id) {
58                 throw new Exception("Project and ticket do not match..");
59             }
60             
61         } 
62         
63         
64         
65         //$this->issue->augmentFormFields($this->fieldset());
66
67
68         $this->preview = false;
69         $this->error = array();
70        
71        
72         if (!$this->id && !$this->hasPerm('MTrack.Issue','A')) {
73             $this->jerr('Permission denied = no rights to create tickets', array('noperm' => true));
74             //return HTML_FlexyFramework::run('Noperm');
75         }
76         
77         
78         if ($this->id &&  (
79                 !$this->hasPerm('MTrack.Issue','E')
80             )) {
81             $this->jerr('Permission denied = no rights to edit tickets', array('noperm' => true));
82             return HTML_FlexyFramework::run('Noperm');
83         }
84         
85         
86         
87         
88         
89         
90         
91         // new is always editable..????
92         $this->editable = true; //$this->id ?
93             //$this->ticket->hasPerm($this->authUser,'E')  : true;
94          
95         $this->issue->milestoneURL = $this->baseURL.'/Milestone'; // fix me later..
96     
97         $this->showEditBar = false;
98          
99         if ($this->editable && $this->id   && !$this->preview) {
100             $this->showEditBar = true;
101         }
102         
103          
104         
105  
106         
107       
108     }
109    
110     function post() // handle the post...
111     {
112        
113         $this->id = $_REQUEST['id'];
114         $ret = $this->loadIssue();
115         if (!empty($ret)) {
116             $this->jerr("load issue failed");
117             exit;
118         }
119         //echo '<PRE>';print_R($this);exit;
120         /// $this->preview = isset($_POST['preview']) ? true : false;
121
122         // hopefull get has sorted out permissions..
123          
124         //    $CS = MTrackChangeset::begin("ticket:X", $comment);
125         
126         $old = clone($this->issue);
127         
128         if (!$this->issue->id) {
129             // set some defaults.
130             $en = DB_DataObject::factory('core_enum');
131             $en->setFrom(array('etype' => 'ticketstate', 'name' => 'new'));
132             $en->find(true);
133             $this->issue->status = $en->id;
134         }
135         
136         
137         //  VALIDATE POST!??!
138         
139         
140         if (!empty($_REQUEST['act_now'])) { //=+ adding act now..
141             // check project / assigned person / !closed for more than 3 'act_now'
142             //DB_DataObject::DebugLevel(1);
143             $xx = DB_DataObject::factory('mtrack_ticket');
144             $xx->owner_id = $this->issue->owner_id;
145             $xx->project_id  = $this->issue->project_id;
146             $xx->act_now = 1;
147             $xx->resolution_id = 0;
148             $xx->whereAdd('id != ' . ((int) $this->issue->id)); // just in case we are double setting...
149             if ($xx->count() > 2) {
150                 $this->jerr("To many act-now tasks assigned to that person, wait until the have completed some");
151             }
152             
153             
154             
155         }
156         
157         
158         
159         
160         $this->issue->setFrom($_POST); 
161         
162         /*
163         $kw = $this->issue->getKeywords();
164           $kill = array_values($kw);
165           foreach (preg_split('/[ \t,]+/', $_POST['keywords']) as $w) {
166             if (!strlen($w)) {
167               continue;
168             }
169             $x = array_search($w, $kw);
170             if ($x === false) {
171               $k = MTrackKeyword::loadByWord($w);
172               if ($k === null) {
173                 $k = new MTrackKeyword;
174                 $k->keyword = $w;
175                 $k->save($CS);
176               }
177               $this->issue->assocKeyword($k);
178             } else {
179               $w = array_search($w, $kill);
180               if ($w !== false) {
181                 unset($kill[$w]);
182               }
183             }
184           }
185           foreach ($kill as $w) {
186             $this->issue->dissocKeyword($w);
187           }
188      
189         
190           $ms = $this->issue->getMilestones();
191           $kill = $ms;
192           if (isset($_POST['milestone']) && is_array($_POST['milestone'])) {
193             foreach ($_POST['milestone'] as $mid) {
194               $this->issue->assocMilestone($mid);
195               unset($kill[$mid]);
196             }
197           }
198           foreach ($kill as $mid) {
199             $this->issue->dissocMilestone($mid);
200           }
201         
202           $ms = $this->issue->getComponents();
203           $kill = $ms;
204           if (isset($_POST['component']) && is_array($_POST['component'])) {
205             foreach ($_POST['component'] as $mid) {
206               $this->issue->assocComponent($mid);
207               unset($kill[$mid]);
208             }
209           }
210           foreach ($kill as $mid) {
211             $this->issue->dissocComponent($mid);
212           }
213           
214             if (!empty($_POST['comment'])) {
215                $this->issue->addComment($_POST['comment']);
216             }
217           
218           $this->issue->addEffort(
219             empty($_POST['spent']) ? 0 : $_POST['spent'], 
220             empty($_POST['estimate']) ? 0 : $_POST['estimate']
221         );
222         */
223         
224         
225         
226         
227         $this->issue->project_id = $this->currentProject();
228         
229         
230         $CS = DB_DataObject::factory('mtrack_change');
231         
232        
233         
234         if ($this->issue->id) {
235             if (0 === $this->issue->update($old)) {
236                 $this->jerr("nothing changed?");
237             
238             }
239         } else {
240             $this->issue->insert();
241             $old = false;
242         }
243         
244         $CS->begin($this->issue, $old ? 'Changed' : 'Created');
245         if (!$old) {
246             $this->issue->created = $CS->id;
247             $this->issue->update();
248         }
249         $CS->add($this->issue, $old);
250         
251         // issue ticket... - add watches etc... 
252         
253         
254         
255          
256         
257         $notify_query = "
258                 (ontable='mtrack_ticket' and onid = {$this->issue->id})
259                  OR
260                  (ontable='Projects' and onid = {$this->issue->project_id})
261                  ";
262          $w = DB_DataObject::factory('core_watch');
263         $w->ensureNotify(  'mtrack_ticket' ,
264                             $this->issue->id,
265                             $this->authUser->id,
266                         $notify_query
267             );
268         
269         $w->ensureNotify(  'mtrack_ticket' ,
270                             $this->issue->id,
271                             $this->issue->owner_id,
272                         $notify_query
273             );
274         
275          $w->ensureNotify(  'mtrack_ticket' ,
276                             $this->issue->id,
277                             $this->issue->developer_id,
278                         $notify_query
279             );
280         //DB_DataObject::debugLevel(1);
281         // who to notify.. -- originall did not send to issuer..
282         // we should probably make this configurable..
283        
284         $w->notify( 'mtrack_ticket' , $this->issue->id,
285                    $notify_query 
286                    /*
287                  " ( $notify_query )
288                     AND
289                     (person_id != {$this->authUser->id})   "  */
290         );
291         
292         
293         /*
294         //$this->issue->save($CS);
295         
296           if (!count($this->error)) {
297             try {
298               $this->issue->save($CS);
299               
300               // make sure everyone is watching it!!!!
301                 if($this->issue->owner && $this->issue->tid) {
302                   // make sure owner is tracking it...
303                     MTrackWatch::watch_object('ticket', $this->issue->tid,  $this->issue->owner);
304                 }
305                 
306                 if ($this->id == 'new') {
307                     MTrackWatch::watch_object('ticket', $this->issue->tid,  MTrackAuth::whoami());
308                 }
309               
310               
311               $CS->setObject("ticket:" . $this->issue->tid);
312             } catch (Exception $e) {
313               $this->error[] = $e->getMessage();
314             }
315         }
316         */
317         /*
318         if (!count($this->error)) {
319             if (!empty($_FILES['attachments'])) {
320                 require_once 'MTrack/Attachment.php';
321                 foreach ($_FILES['attachments']['name'] as $fileid => $name) {
322                       
323                     MTrackAttachment::add("ticket:{$this->issue->tid}",
324                         $_FILES['attachments']['tmp_name'][$fileid],
325                         $_FILES['attachments']['name'][$fileid],
326                         $CS
327                     );
328                 }
329             }
330         }
331         if (!count($this->error) && $this->id != 'new') {
332             require_once 'MTrack/Attachment.php';
333             MTrackAttachment::process_delete("ticket:{$this->issue->tid}", $CS);
334         }
335
336         if (isset($_POST['apply']) && !count($this->error)) {
337           $CS->commit();
338           header("Location: {$this->baseURL}/Ticket/{$this->issue->nsident}");
339           exit;
340         }
341         */
342         $this->jok($this->issue->id);
343     }
344       
345          
346     function initEditForm($params = array())
347     {
348         require_once 'HTML/Template/Flexy/Element.php';
349         require_once 'HTML/Template/Flexy/Factory.php';
350         
351         
352         
353         foreach(array( 'classification', 'priority', 'severity' ) as $c)  {
354             $d = DB_DataObject::factory('core_enum');
355             $d->etype = $c;
356             $d->orderBy('seqid ASC, name ASC');
357             if (!$d->count()) {
358                 $d->createBaseEntries();
359                 
360             }
361             $ar = $d->fetchAll('id','name');
362             
363             // mid point..
364             $ak = array_keys($ar);
365             $mid = floor(count($ak) / 2 );
366             $def = $ak[$mid];
367             
368             //var_dump($ar[$def]);
369             
370             $this->elements[$c.'_id'] = new HTML_Template_Flexy_Element('select');
371             $this->elements[$c.'_id']->setOptions($ar);
372             if (!$this->id) {
373                 $this->elements[$c.'_id']->setValue($def);
374             }
375             
376             
377         }
378        // DB_DAtaObject::DebugLevel(1);
379         
380         $pd = DB_DataObject::factory('ProjectDirectory');
381         $pd->project_id = $this->currentProject();
382         $pd->whereAdd("ProjectDirectory.role != ''");
383         $pd->joinAdd(DB_DataObject::factory('core_person'), 'LEFT');
384         $pd->selectAdd();
385         $pd->selectAdd("distinct(Person.id) as id ,  CONCAT(Person.name , '<', Person.email , '>') as name");
386         $pd->groupBy('Person.id, Person.name');
387         $pd->orderBy('Person.name');
388         $users = $pd->fetchAll('id', 'name');
389         $users = array('' => '--select--') + $users;
390         
391         //$users = array();
392          
393         $this->elements['owner_id'] = new HTML_Template_Flexy_Element('select');
394         $this->elements['owner_id']->setOptions($users);
395         
396         $this->elements['developer_id'] = new HTML_Template_Flexy_Element('select');
397         $this->elements['developer_id']->setOptions($users);
398         
399           
400         if ($this->currentProject()) {
401             /*
402             $d = DB_DataObject::factory('mtrack_project_component');
403             $d->project_id = $this->currentProject();
404             $d->orderBy('name');
405             $d->whereAdd('deleted != 1');
406             $this->elements['component[]'] = new HTML_Template_Flexy_Element('select');
407             $this->elements['component[]']->setOptions($d->fetchAll('id', 'name'));
408             $ar = $this->issue->components();
409             $this->elements['component[]']->setValue(array_keys($ar));
410             */
411             //DB_DataObject::debugLevel(1);
412             $d = DB_DataObject::factory('mtrack_milestone');
413             $d->project_id = $this->currentProject();
414             $d->orderBy('(case when duedate is null then 1 else 0 end), duedate, name');
415             $d->whereAdd('completed != 1');
416             $d->whereAdd('deleted != 1');
417             $this->elements['milestone_id'] = new HTML_Template_Flexy_Element('select');
418             $this->elements['milestone_id']->setOptions(array(''=>'--select--') + $d->fetchAll('id', 'name'));
419             //$ar = $this->issue->milestone();
420             //$this->elements['milestone_id']->setValue(array_keys($ar));
421         }
422         
423         // FIX ME - need to determine who the owner is..
424         // for a new issue it's the person who created it.
425         // later on it's an assignement???
426         
427        
428         
429         if ($this->id) {
430             $this->elements = HTML_Template_Flexy_Factory::fromArray($this->issue->toArray(), $this->elements);
431         }
432
433         
434         // keywords -- in toArray...
435         // milestone 
436           
437           
438         
439
440           
441     }
442    
443      
444     function eq($a,$b) {
445         return $a == $b;
446     }
447     
448 }