1: <?php
2: 3: 4: 5: 6: 7: 8: 9:
10: class Whups_Api extends Horde_Registry_Api
11: {
12: 13: 14: 15: 16: 17: 18:
19: public function browse($path = '')
20: {
21: global $whups_driver, $registry;
22:
23: if (substr($path, 0, 5) == 'whups') {
24: $path = substr($path, 5);
25: }
26: $path = trim($path, '/');
27:
28: if (empty($path)) {
29: $results = array(
30: 'whups/queue' => array(
31: 'name' => _("Queues"),
32: 'icon' => Horde_Themes::img('whups.png'),
33: 'browseable' => count(
34: Whups::permissionsFilter($whups_driver->getQueues(),
35: 'queue', Horde_Perms::READ))));
36: } else {
37: $path = explode('/', $path);
38: Horde::logMessage(var_export($path, true), 'INFO');
39: $results = array();
40:
41: switch ($path[0]) {
42: case 'queue':
43: $queues = Whups::permissionsFilter($whups_driver->getQueues(),
44: 'queue', Horde_Perms::SHOW);
45: if (count($path) == 1) {
46: foreach ($queues as $queue => $name) {
47: $results['whups/queue/' . $queue] = array(
48: 'name' => $name,
49: 'browseable' => true);
50: }
51: } else {
52: if (!Whups::hasPermission($queues[$path[1]], 'queue',
53: Horde_Perms::READ)) {
54: throw new Horde_Exception_PermissionDenied();
55: }
56:
57: $tickets = $whups_driver->getTicketsByProperties(
58: array('queue' => $path[1]));
59: foreach ($tickets as $ticket) {
60: $results['whups/queue/' . $path[1] . '/' . $ticket['id']] = array(
61: 'name' => $ticket['summary'],
62: 'browseable' => false);
63: }
64: }
65: break;
66: }
67: }
68:
69: return $results;
70: }
71:
72: 73: 74: 75: 76: 77: 78:
79: public function addQueue($name)
80: {
81: if ($GLOBALS['registry']->isAdmin(array('permission' => 'whups:admin'))) {
82: return $GLOBALS['whups_driver']->addQueue($name, '');
83: }
84: throw new Horde_Exception_PermissionDenied('You must be an administrator to perform this action.');
85: }
86:
87: 88: 89: 90: 91:
92: public function getAssignedTicketIds()
93: {
94: global $whups_driver;
95:
96: $info = array('owner' => 'user:' . $GLOBALS['registry']->getAuth(), 'nores' => true);
97: $tickets = $whups_driver->getTicketsByProperties($info);
98: $result = array();
99: foreach ($tickets as $ticket) {
100: $result[] = $ticket['id'];
101: }
102: return $result;
103: }
104:
105: 106: 107: 108: 109:
110: public function getRequestedTicketIds()
111: {
112: global $whups_driver;
113:
114: $info = array('requester' => $GLOBALS['registry']->getAuth(), 'nores' => true);
115: $tickets = $whups_driver->getTicketsByProperties($info);
116: $result = array();
117: foreach ($tickets as $ticket) {
118: $result[] = (int) $ticket['id'];
119: }
120: return $result;
121: }
122:
123: 124: 125: 126: 127: 128: 129: 130: 131:
132: public function addTicket($ticket_info)
133: {
134: global $whups_driver;
135:
136: if (!is_array($ticket_info)) {
137: throw new Whups_Exception('Invalid arguments');
138: }
139:
140: $vars = new Horde_Variables($ticket_info);
141:
142: $form1 = new Whups_Form_Ticket_CreateStepOne($vars);
143: $form2 = new Whups_Form_Ticket_CreateStepTwo($vars);
144: $form3 = new Whups_Form_Ticket_CreateStepThree($vars);
145:
146:
147:
148: $form1->useToken(false);
149: $form2->useToken(false);
150: $form3->useToken(false);
151:
152:
153: if (!$form1->validate($vars, true)) {
154: $f1 = var_export($form1->getErrors(), true);
155: throw new Whups_Exception("Invalid arguments ($f1)");
156: }
157: if (!$form2->validate($vars, true)) {
158: $f2 = var_export($form2->getErrors(), true);
159: throw new Whups_Exception("Invalid arguments ($f2)");
160: }
161: if (!$form3->validate($vars, true)) {
162: $f3 = var_export($form3->getErrors(), true);
163: throw new Whups_Exception("Invalid arguments ($f3)");
164: }
165:
166: $form1->getInfo($vars, $info);
167: $form2->getInfo($vars, $info);
168: $form3->getInfo($vars, $info);
169:
170:
171: if ($GLOBALS['registry']->getAuth() && $whups_driver->isCategory('assigned', $vars->get('state'))) {
172: $form4 = new Whups_Form_Ticket_CreateStep4Form($vars);
173: }
174: if ($GLOBALS['registry']->getAuth() && $whups_driver->isCategory('assigned', $vars->get('state'))) {
175: $form4 = new Whups_Form_Ticket_CreateStep4Form($vars);
176: $form4->useToken(false);
177: if (!$form4->validate($vars, true)) {
178: throw new Whups_Exception('Invalid arguments (' . var_export($form4->getErrors(), true) . ')');
179: }
180:
181: $form4->getInfo($vars, $info);
182: }
183:
184: $ticket = Whups_Ticket::newTicket($info, $GLOBALS['registry']->getAuth());
185:
186: return $ticket->getId();
187: }
188:
189: 190: 191: 192: 193: 194: 195: 196:
197: public function updateTicket($ticket_id, $ticket_info)
198: {
199: global $whups_driver;
200:
201:
202: $ticket = Whups_Ticket::makeTicket((int)$ticket_id);
203:
204:
205: if (!$GLOBALS['registry']->getAuth() ||
206: !Whups::hasPermission($ticket->get('queue'), 'queue', 'update')) {
207: throw new Whups_Exception_PermissionDenied(_('You do not have permission to update this ticket.'));
208: }
209:
210:
211: $vars = new Horde_Variables();
212: $ticket->setDetails($vars);
213:
214:
215: foreach ($ticket_info as $detail => $newval) {
216: $vars->set($detail, $newval);
217: }
218:
219:
220:
221:
222: $editform = new Whups_Form_Ticket_Edit($vars, null, $ticket);
223: $editform->useToken(false);
224: $editform->setSubmitted(true);
225:
226:
227: if (!$editform->validate($vars)) {
228: $form_errors = var_export($editform->getErrors(), true);
229: throw new Whups_Exception(sprintf(_("Invalid ticket data supplied: %s"), $form_errors));
230: }
231:
232: $editform->getInfo($vars, $info);
233:
234: $ticket->change('summary', $info['summary']);
235: $ticket->change('state', $info['state']);
236: $ticket->change('priority', $info['priority']);
237: if (!empty($info['newcomment'])) {
238: $ticket->change('comment', $info['newcomment']);
239: }
240:
241:
242: $whups_driver->setAttributes($info);
243:
244:
245: if (!empty($info['newattachment']['name'])) {
246: $ticket->change('attachment',
247: array('name' => $info['newattachment']['name'],
248: 'tmp_name' => $info['newattachment']['tmp_name']));
249: }
250:
251:
252:
253: if (!empty($info['group'])) {
254: $ticket->change('comment-perms', $info['group']);
255: }
256: $ticket->commit();
257:
258:
259: return true;
260: }
261:
262: 263: 264: 265: 266: 267: 268: 269: 270:
271: public function ($ticket_id, $comment, $group = null)
272: {
273: $ticket_id = (int)$ticket_id;
274: if (empty($ticket_id)) {
275: throw new Whups_Exception('Invalid ticket id');
276: }
277:
278: $ticket = Whups_Ticket::makeTicket($ticket_id);
279: if (empty($comment)) {
280: throw new Whups_Exception('Empty comments are not allowed');
281: }
282:
283:
284: $ticket->change('comment', $comment);
285:
286:
287:
288: if (!empty($group)) {
289: $ticket->change('comment-perms', $group);
290: }
291: $ticket->commit();
292:
293: return true;
294: }
295:
296: 297: 298: 299: 300: 301: 302: 303: 304:
305: public function addAttachment($ticket_id, $name, $data)
306: {
307: $ticket_id = (int)$ticket_id;
308: if (empty($ticket_id)) {
309: throw new Whups_Exception(_("Invalid Ticket Id"));
310: }
311:
312: $ticket = Whups_Ticket::makeTicket($ticket_id);
313: if (!strlen($name) || !strlen($data)) {
314: throw new Whups_Exception(_("Empty attachment"));
315: }
316:
317: $tmp_name = Horde_Util::getTempFile('whups', true, $GLOBALS['conf']['tmpdir']);
318: $fp = fopen($tmp_name, 'wb');
319: fwrite($fp, $data);
320: fclose($fp);
321:
322: $ticket->change('attachment', array('name' => $name, 'tmp_name' => $tmp_name));
323: $ticket->commit();
324: }
325:
326: 327: 328: 329: 330:
331: public function setTicketAttributes($info)
332: {
333: global $whups_driver;
334:
335: if (!isset($info['ticket_id']) || !isset($info['attributes'])) {
336: throw new Whups_Exception(_("Invalid arguments: Must supply a ticket number and new attributes."));
337: }
338:
339: $ticket = $whups_driver->getTicketDetails($info['ticket_id']);
340:
341:
342:
343: $ainfo = array();
344: foreach ($info['attributes'] as $attrib) {
345: if (!isset($attrib['id']) || !isset($attrib['value'])) {
346: throw new InvalidArgumentException(_("Invalid argument: Missing attribute name or value."));
347: }
348: $ainfo['a' . $attrib['id']] = $attrib['value'];
349: }
350: $ainfo['id'] = $info['ticket_id'];
351:
352: return $whups_driver->setAttributes($ainfo);
353: }
354:
355: 356: 357: 358: 359:
360: public function getListTypes()
361: {
362: return array('taskHash' => true);
363: }
364:
365: 366: 367: 368: 369: 370: 371:
372: public function listAs($type)
373: {
374: switch ($type) {
375: case 'taskHash':
376: global $whups_driver;
377: $info = array(
378: 'owner' => 'user:' . $GLOBALS['registry']->getAuth(),
379: 'nores' => true);
380: $tickets = $whups_driver->getTicketsByProperties($info);
381: $result = array();
382: foreach ($tickets as $ticket) {
383: $view_link = Whups::urlFor('ticket', $ticket['id'], true);
384: $delete_link = Whups::urlFor('ticket_action', array('delete', $ticket['id']), true);
385: $complete_link = Whups::urlFor('ticket_action', array('update', $ticket['id']), true);
386:
387: $result['whups/' . $ticket['id']] = array(
388: 'task_id' => $ticket['id'],
389: 'priority' => $ticket['priority_name'],
390: 'tasklist_id' => '**EXTERNAL**',
391: 'completed' => ($ticket['state_category'] == 'resolved'),
392: 'name' => '[#' . $ticket['id'] . '] ' . $ticket['summary'],
393: 'desc' => null,
394: 'due' => null,
395: 'category' => null,
396: 'view_link' => $view_link,
397: 'delete_link' => $delete_link,
398: 'edit_link' => $view_link,
399: 'complete_link' => $complete_link
400: );
401: }
402: break;
403:
404: default:
405: $result = array();
406: break;
407: }
408:
409: return $result;
410: }
411:
412: 413: 414: 415: 416:
417: public function listQueues()
418: {
419: return Whups::permissionsFilter($GLOBALS['whups_driver']->getQueuesInternal(), 'queue', Horde_Perms::SHOW);
420: }
421:
422: 423: 424: 425: 426:
427: public function listSlugs()
428: {
429: return Whups::permissionsFilter($GLOBALS['whups_driver']->getSlugs(), 'queue', Horde_Perms::SHOW);
430: }
431:
432: 433: 434: 435: 436: 437: 438:
439: public function getQueueDetails($queue)
440: {
441: if (is_array($queue)) {
442: $queues = Whups::permissionsFilter($queue, 'queue_id');
443: $details = array();
444: foreach ($queues as $id) {
445: $details[$id] = $GLOBALS['whups_driver']->getQueueInternal($id);
446: }
447: return $details;
448: }
449:
450: $queues = Whups::permissionsFilter(array($queue), 'queue_id');
451: if ($queues) {
452: return $GLOBALS['whups_driver']->getQueueInternal($queue);
453: }
454:
455: return array();
456: }
457:
458: 459: 460: 461: 462: 463: 464:
465: public function listVersions($queue)
466: {
467: $queues = Whups::permissionsFilter(array($queue), 'queue_id');
468: if (!$queues) {
469: return array();
470: }
471:
472: $versions = array();
473: $version_list = $GLOBALS['whups_driver']->getVersionInfoInternal($queue);
474: foreach ($version_list as $version) {
475: $versions[] = array('id' => $version['version_id'],
476: 'name' => $version['version_name'],
477: 'description' => $version['version_description'],
478: 'active' => !empty($version['version_active']),
479: 'readonly' => false);
480: }
481:
482: usort($versions, array($this, '_sortVersions'));
483:
484: return $versions;
485: }
486:
487: private function _sortVersions($a, $b)
488: {
489: $a_number = (string)(int)$a['name'][0] === $a['name'][0];
490: $b_number = (string)(int)$b['name'][0] === $b['name'][0];
491:
492: if ($a_number && $b_number) {
493: return version_compare($b['name'], $a['name']);
494: }
495: if (!$a_number && !$b_number) {
496: return strcoll($b['name'], $a['name']);
497: }
498: return $a_number ? 1 : -1;
499: }
500:
501: 502: 503: 504: 505: 506: 507: 508:
509: public function addVersion($queue, $name, $description, $active = true)
510: {
511: return $GLOBALS['whups_driver']->addVersion($queue, $name, $description, $active);
512: }
513:
514: 515: 516: 517: 518: 519: 520:
521: public function getVersionDetails($version_id)
522: {
523: return $GLOBALS['whups_driver']->getVersionInternal($version_id);
524: }
525:
526: 527: 528: 529: 530: 531: 532: 533:
534: public function getTicketDetails($queue_id, $state = null)
535: {
536: global $whups_driver;
537:
538: $info['queue_id'] = $queue_id;
539: if (!empty($state)) {
540: $info['category'] = $state;
541: }
542: $tickets = $whups_driver->getTicketsByProperties($info);
543:
544: for ($i = 0; $i < count($tickets); $i++) {
545: $view_link = Whups::urlFor('ticket', $tickets[$i]['id'], true);
546: $delete_link = Whups::urlFor('ticket_action', array('delete', $tickets[$i]['id']), true);
547: $complete_link = Whups::urlFor('ticket_action', array('update', $tickets[$i]['id']), true);
548:
549: $tickets[$i] = array(
550: 'ticket_id' => $tickets[$i]['id'],
551: 'completed' => ($tickets[$i]['state_category'] == 'resolved'),
552: 'assigned' => ($tickets[$i]['state_category'] == 'assigned'),
553: 'name' => $tickets[$i]['queue_name'] . ' #' .
554: $tickets[$i]['id'] . ' - ' . $tickets[$i]['summary'],
555: 'state' => $tickets[$i]['state_name'],
556: 'type' => $tickets[$i]['type_name'],
557: 'priority' => $tickets[$i]['priority_name'],
558: 'desc' => null,
559: 'due' => null,
560: 'category' => null,
561: 'view_link' => $view_link,
562: 'delete_link' => $delete_link,
563: 'edit_link' => $view_link,
564: 'complete_link' => $complete_link
565: );
566: }
567:
568: return $tickets;
569: }
570:
571: 572: 573: 574: 575: 576: 577:
578: public function listCostObjects($criteria)
579: {
580: global $whups_driver;
581:
582: $info = array();
583: if (!empty($criteria['user'])) {
584: $info['owner'] = 'user:' . $GLOBALS['registry']->getAuth();
585: }
586: if (!empty($criteria['active'])) {
587: $info['nores'] = true;
588: }
589: if (!empty($criteria['id'])) {
590: $info['id'] = $criteria['id'];
591: }
592:
593: $tickets = $whups_driver->getTicketsByProperties($info);
594: $result = array();
595: foreach ($tickets as $ticket) {
596: $result[$ticket['id']] = array(
597: 'id' => $ticket['id'],
598: 'active' => ($ticket['state_category'] != 'resolved'),
599: 'name' => sprintf(
600: _("Ticket %s - %s"), $ticket['id'], $ticket['summary']));
601:
602: 603:
604: $attributes = $whups_driver->getTicketAttributesWithNames($ticket['id']);
605: foreach ($attributes as $k => $v) {
606: if (strtolower($k) == _("estimated time")) {
607: if (!empty($v)) {
608: $result[$ticket['id']]['estimate'] = (double) $v;
609: }
610: }
611: }
612: }
613: ksort($result);
614: if (count($result) == 0) {
615: return array();
616: } else {
617: return array(
618: array(
619: 'category' => _("Tickets"),
620: 'objects' => array_values($result)));
621: }
622: }
623:
624: 625: 626: 627: 628:
629: public function listTimeObjectCategories()
630: {
631: return array('created' => _("My tickets by creation date"),
632: 'assigned' => _("My tickets by assignment date"),
633: 'due' => _("My tickets by due date"),
634: 'resolved' => _("My tickets by resolution date"));
635: }
636:
637: 638: 639: 640: 641: 642: 643:
644: public function listTimeObjects($categories, $start, $end)
645: {
646: global $whups_driver;
647:
648: $start = new Horde_Date($start);
649: $start_ts = $start->timestamp();
650: $end = new Horde_Date($end);
651: $end_ts = $end->timestamp();
652:
653: $criteria['owner'] = Whups::getOwnerCriteria($GLOBALS['registry']->getAuth());
654:
655:
656: $category = 'due';
657: switch ($category) {
658: case 'assigned':
659: $label = _("Assigned");
660: $criteria['ass'] = true;
661: break;
662:
663: case 'created':
664: $label = _("Created");
665: break;
666:
667: case 'due':
668: $label = _("Due");
669: $criteria['nores'] = true;
670: break;
671:
672: case 'resolved':
673: $label = _("Resolved");
674: $criteria['res'] = true;
675: break;
676: }
677:
678: try {
679: $tickets = $whups_driver->getTicketsByProperties($criteria);
680: } catch (Whups_Exception $e) {
681: return array();
682: }
683: $objects = array();
684: foreach ($tickets as $ticket) {
685: switch ($category) {
686: case 'assigned':
687: $t_start = $ticket['date_assigned'];
688: break;
689:
690: case 'created':
691: $t_start = $ticket['timestamp'];
692: break;
693:
694: case 'due':
695: if (empty($ticket['due'])) {
696: continue 2;
697: }
698: $t_start = $ticket['due'];
699: break;
700:
701: case 'resolved':
702: $t_start = $ticket['date_resolved'];
703: break;
704: }
705:
706: if ($t_start + 1 < $start_ts || $t_start > $end_ts) {
707: continue;
708: }
709: $t = new Whups_Ticket($ticket['id'], $ticket);
710: $objects[$ticket['id']] = array(
711: 'title' => sprintf('%s: [#%s] %s', $label, $ticket['id'], $ticket['summary']),
712: 'description' => $t->toString(),
713: 'id' => $ticket['id'],
714: 'start' => date('Y-m-d\TH:i:s', $t_start),
715: 'end' => date('Y-m-d\TH:i:s', $t_start + 1),
716: 'params' => array('id' => $ticket['id']),
717: 'link' => Whups::urlFor('ticket', $ticket['id'], true));
718: }
719:
720: return $objects;
721: }
722:
723: }
724: