1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11:
12: 13: 14: 15: 16: 17: 18: 19:
20: class Whups
21: {
22: 23: 24:
25: const VFS_ATTACH_PATH = '.horde/whups/attachments';
26:
27: 28: 29: 30: 31: 32:
33: static protected $_sortBy;
34:
35: 36: 37: 38: 39: 40:
41: static protected $_sortDir;
42:
43: 44: 45: 46: 47: 48:
49: static protected $_users = array();
50:
51: 52: 53: 54: 55: 56: 57:
58: static protected $_fieldTypes = array();
59:
60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71:
72: static public function urlFor($controller, $data, $full = false,
73: $append_session = 0)
74: {
75: $rewrite = isset($GLOBALS['conf']['urls']['pretty']) &&
76: $GLOBALS['conf']['urls']['pretty'] == 'rewrite';
77:
78: switch ($controller) {
79: case 'queue':
80: if ($rewrite) {
81: if (is_array($data)) {
82: if (empty($data['slug'])) {
83: $slug = (int)$data['id'];
84: } else {
85: $slug = $data['slug'];
86: }
87: } else {
88: $slug = (int)$data;
89: }
90: return Horde::url('queue/' . $slug, $full, $append_session);
91: } else {
92: if (is_array($data)) {
93: $id = $data['id'];
94: } else {
95: $id = $data;
96: }
97: return Horde::url('queue/?id=' . $id, $full, $append_session);
98: }
99: break;
100:
101: case 'ticket':
102: $id = (int)$data;
103: if ($rewrite) {
104: return Horde::url('ticket/' . $id, $full, $append_session);
105: } else {
106: return Horde::url('ticket/?id=' . $id, $full, $append_session);
107: }
108: break;
109:
110: case 'ticket_rss':
111: $id = (int)$data;
112: if ($rewrite) {
113: return Horde::url('ticket/' . $id . '/rss', $full, $append_session);
114: } else {
115: return Horde::url('ticket/rss.php?id=' . $id, $full, $append_session);
116: }
117: break;
118:
119: case 'ticket_action':
120: list($controller, $id) = $data;
121: if ($rewrite) {
122: return Horde::url('ticket/' . $id . '/' . $controller, $full, $append_session = 0);
123: } else {
124: return Horde::url('ticket/' . $controller . '.php?id=' . $id, $full, $append_session = 0);
125: }
126:
127: case 'query':
128: case 'query_rss':
129: if ($rewrite) {
130: if (is_array($data)) {
131: if (isset($data['slug'])) {
132: $slug = $data['slug'];
133: } else {
134: $slug = $data['id'];
135: }
136: } else {
137: $slug = (int)$data;
138: }
139: $url = 'query/' . $slug;
140: if ($controller == 'query_rss') {
141: $url .= '/rss';
142: }
143: return Horde::url($url, $full, $append_session);
144: } else {
145: if (is_array($data)) {
146: if (isset($data['slug'])) {
147: $param = array('slug' => $data['slug']);
148: } else {
149: $param = array('query' => $data['id']);
150: }
151: } else {
152: $param = array('query' => $data);
153: }
154: $url = $controller == 'query' ? 'query/run.php' : 'query/rss.php';
155: $url = Horde_Util::addParameter($url, $param);
156: return Horde::url($url, $full, $append_session);
157: }
158: break;
159: }
160: }
161:
162: 163: 164: 165: 166: 167: 168: 169: 170:
171: static public function sortTickets(&$tickets, $by = null, $dir = null)
172: {
173: if (is_null($by)) {
174: $by = $GLOBALS['prefs']->getValue('sortby');
175: }
176: if (is_null($dir)) {
177: $dir = $GLOBALS['prefs']->getValue('sortdir');
178: }
179:
180: self::sortBy($by);
181: self::sortDir($dir);
182:
183:
184: $tickets = array_map(array('Whups', '_prepareSort'), $tickets);
185:
186: usort($tickets, array('Whups', '_sort'));
187: }
188:
189: 190: 191: 192: 193: 194: 195:
196: static public function sortBy($b = null)
197: {
198: if (!is_null($b)) {
199: self::$_sortBy = $b;
200: } else {
201: return self::$_sortBy;
202: }
203: }
204:
205: 206: 207: 208: 209: 210: 211:
212: static public function sortDir($d = null)
213: {
214: if (!is_null($d)) {
215: self::$_sortDir = $d;
216: } else {
217: return self::$_sortDir;
218: }
219: }
220:
221: 222: 223: 224: 225: 226: 227: 228: 229: 230:
231: static protected function _prepareSort(array $ticket)
232: {
233: $by = self::sortBy();
234: $ticket['sort_by'] = array();
235: if (is_array($by)) {
236: foreach ($by as $field) {
237: if (!isset($ticket[$field])) {
238: $ticket['sort_by'][$field] = '';
239: } else {
240: $ticket['sort_by'][$field] = Horde_String::lower($ticket[$field], true, 'UTF-8');
241: }
242: }
243: } else {
244: if (!isset($ticket[$by])) {
245: $ticket['sort_by'][$by] = '';
246: } elseif (is_array($ticket[$by])) {
247: natcasesort($ticket[$by]);
248: $ticket['sort_by'][$by] = implode('', $ticket[$by]);
249: } else {
250: $ticket['sort_by'][$by] = Horde_String::lower($ticket[$by], true, 'UTF-8');
251: }
252: }
253: return $ticket;
254: }
255:
256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269:
270: static protected function _sort($a, $b, $sortby = null, $sortdir = null)
271: {
272: if (is_null($sortby)) {
273: $sortby = self::$_sortBy;
274: }
275: if (is_null($sortdir)) {
276: $sortdir = self::$_sortDir;
277: }
278:
279: if (is_array($sortby)) {
280: if (!isset($a[$sortby[0]])) {
281: $a[$sortby[0]] = null;
282: }
283: if (!isset($b[$sortby[0]])) {
284: $b[$sortby[0]] = null;
285: }
286:
287: if (!count($sortby)) {
288: return 0;
289: }
290: if ($a['sort_by'][$sortby[0]] > $b['sort_by'][$sortby[0]]) {
291: return $sortdir[0] ? -1 : 1;
292: }
293: if ($a['sort_by'][$sortby[0]] === $b['sort_by'][$sortby[0]]) {
294: array_shift($sortby);
295: array_shift($sortdir);
296: return self::_sort($a, $b, $sortby, $sortdir);
297: }
298: return $sortdir[0] ? 1 : -1;
299: }
300:
301: $a_val = isset($a['sort_by'][$sortby]) ? $a['sort_by'][$sortby] : null;
302: $b_val = isset($b['sort_by'][$sortby]) ? $b['sort_by'][$sortby] : null;
303:
304:
305: if ($a_val === $b_val) {
306: return 0;
307: }
308:
309: if ((is_numeric($a_val) || is_null($a_val)) &&
310: (is_numeric($b_val) || is_null($b_val))) {
311:
312: return (int)($sortdir ? ($b_val > $a_val) : ($a_val > $b_val));
313: }
314:
315:
316: if (is_array($a_val) || is_array($b_val)) {
317: $a_val = implode('', $a_val);
318: $b_val = implode('', $b_val);
319: }
320:
321:
322: return $sortdir ? strcoll($b_val, $a_val) : strcoll($a_val, $b_val);
323: }
324:
325: 326: 327: 328: 329: 330: 331: 332:
333: static public function getCAPTCHA($new = false)
334: {
335: global $session;
336:
337: if ($new || !$session->get('whups', 'captcha')) {
338: $captcha = '';
339: for ($i = 0; $i < 5; ++$i) {
340: $captcha .= chr(rand(65, 90));
341: }
342: $session->set('whups', 'captcha', $captcha);
343: }
344:
345: return $session->get('whups', 'captcha');
346: }
347:
348: 349: 350: 351: 352: 353: 354: 355:
356: static public function listTemplates($type)
357: {
358: $templates = array();
359:
360: $_templates = Horde::loadConfiguration('templates.php', '_templates', 'whups');
361: foreach ($_templates as $name => $info) {
362: if ($info['type'] == $type) {
363: $templates[$name] = $info['name'];
364: }
365: }
366:
367: return $templates;
368: }
369:
370: 371: 372: 373: 374: 375: 376: 377: 378:
379: static public function getCurrentTicket()
380: {
381: $default = Horde::url($GLOBALS['prefs']->getValue('whups_default_view') . '.php', true);
382:
383: $id = preg_replace('|\D|', '', Horde_Util::getFormData('id'));
384: if (!$id) {
385: $GLOBALS['notification']->push(_("Invalid Ticket Id"), 'horde.error');
386: $default->redirect();
387: }
388:
389: try {
390: return Whups_Ticket::makeTicket($id);
391: } catch (Whups_Exception $e) {
392: if ($ticket->code === 0) {
393:
394: $GLOBALS['notification']->push($e->getMessage(), 'horde.warning');
395: $default->redirect();
396: }
397: } catch (Exception $e) {
398: $GLOBALS['notification']->push($e);
399: $default->redirect();
400: }
401: }
402:
403: 404: 405:
406: static public function getTicketTabs(&$vars, $id)
407: {
408: $tabs = new Horde_Core_Ui_Tabs(null, $vars);
409: $queue = $vars->get('queue');
410:
411: $tabs->addTab(_("_History"), self::urlFor('ticket', $id), 'history');
412: if (self::hasPermission($queue, 'queue', 'update')) {
413: $tabs->addTab(_("_Update"),
414: self::urlFor('ticket_action', array('update', $id)),
415: 'update');
416: } else {
417: $tabs->addTab(_("_Comment"),
418: self::urlFor('ticket_action', array('comment', $id)),
419: 'comment');
420: }
421: $tabs->addTab(_("_Watch"),
422: self::urlFor('ticket_action', array('watch', $id)),
423: 'watch');
424: if (self::hasPermission($queue, 'queue', Horde_Perms::DELETE)) {
425: $tabs->addTab(_("S_et Queue"),
426: self::urlFor('ticket_action', array('queue', $id)),
427: 'queue');
428: }
429: if (self::hasPermission($queue, 'queue', 'update')) {
430: $tabs->addTab(_("Set _Type"),
431: self::urlFor('ticket_action', array('type', $id)),
432: 'type');
433: }
434: if (self::hasPermission($queue, 'queue', Horde_Perms::DELETE)) {
435: $tabs->addTab(_("_Delete"),
436: self::urlFor('ticket_action', array('delete', $id)),
437: 'delete');
438: }
439:
440: return $tabs;
441: }
442:
443: 444: 445: 446: 447: 448: 449: 450: 451: 452: 453: 454: 455:
456: static public function hasPermission($in, $filter, $permission, $user = null)
457: {
458: if (is_null($user)) {
459: $user = $GLOBALS['registry']->getAuth();
460: }
461:
462: if ($permission == 'update' ||
463: $permission == 'assign' ||
464: $permission == 'requester') {
465: $admin_perm = Horde_Perms::EDIT;
466: } else {
467: $admin_perm = $permission;
468: }
469:
470: $admin = $GLOBALS['registry']->isAdmin(array('permission' => 'whups:admin', 'permlevel' => $admin_perm, 'user' => $user));
471: $perms = $GLOBALS['injector']->getInstance('Horde_Perms');
472:
473: switch ($filter) {
474: case 'queue':
475: if ($admin) {
476: return true;
477: }
478: switch ($permission) {
479: case Horde_Perms::SHOW:
480: case Horde_Perms::READ:
481: case Horde_Perms::EDIT:
482: case Horde_Perms::DELETE:
483: if ($perms->hasPermission('whups:queues:' . $in, $user,
484: $permission)) {
485: return true;
486: }
487: break;
488:
489: default:
490: if ($perms->exists('whups:queues:' . $in . ':' . $permission)) {
491: if (($permission == 'update' ||
492: $permission == 'assign' ||
493: $permission == 'requester') &&
494: $perms->getPermissions(
495: 'whups:queues:' . $in . ':' . $permission, $user)) {
496: return true;
497: }
498: } else {
499:
500:
501: if ($permission != 'requester' &&
502: $GLOBALS['registry']->getAuth() &&
503: $perms->hasPermission('whups:queues:' . $in, $user,
504: Horde_Perms::EDIT)) {
505: return true;
506: }
507: }
508: break;
509: }
510: break;
511: }
512:
513: return false;
514: }
515:
516: 517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530:
531: static public function permissionsFilter($in, $filter,
532: $permission = Horde_Perms::READ,
533: $user = null, $creator = null)
534: {
535: if (is_null($user)) {
536: $user = $GLOBALS['registry']->getAuth();
537: }
538:
539: $admin = $GLOBALS['registry']->isAdmin(array('permission' => 'whups:admin', 'permlevel' => $permission, 'user' => $user));
540: $perms = $GLOBALS['injector']->getInstance('Horde_Perms');
541: $out = array();
542:
543: switch ($filter) {
544: case 'queue':
545: if ($admin) {
546: return $in;
547: }
548: foreach ($in as $queueID => $name) {
549: if ($perms->hasPermission('whups:queues:' . $queueID, $user,
550: $permission, $creator)) {
551: $out[$queueID] = $name;
552: }
553: }
554: break;
555:
556: case 'queue_id':
557: if ($admin) {
558: return $in;
559: }
560: foreach ($in as $queueID) {
561: if ($perms->hasPermission('whups:queues:' . $queueID, $user,
562: $permission, $creator)) {
563: $out[] = $queueID;
564: }
565: }
566: break;
567:
568: case 'reply':
569: if ($admin) {
570: return $in;
571: }
572: foreach ($in as $replyID => $name) {
573: if (!$perms->exists('whups:replies:' . $replyID) ||
574: $perms->hasPermission('whups:replies:' . $replyID,
575: $user, $permission, $creator)) {
576: $out[$replyID] = $name;
577: }
578: }
579: break;
580:
581: case 'comment':
582: foreach ($in as $key => $row) {
583: foreach ($row as $rkey => $rval) {
584: if ($rkey != 'changes') {
585: $out[$key][$rkey] = $rval;
586: continue;
587: }
588: foreach ($rval as $i => $change) {
589: if ($change['type'] != 'comment' ||
590: !$perms->exists('whups:comments:' . $change['value'])) {
591: $out[$key][$rkey][$i] = $change;
592: if (isset($change['comment'])) {
593: $out[$key]['comment_text'] = $change['comment'];
594: }
595: } elseif ($perms->exists('whups:comments:' . $change['value'])) {
596: $change['private'] = true;
597: $out[$key][$rkey][$i] = $change;
598: if (isset($change['comment'])) {
599: if ($admin ||
600: $perms->hasPermission('whups:comments:' . $change['value'],
601: $user, Horde_Perms::READ, $creator)) {
602: $out[$key]['comment_text'] = $change['comment'];
603: } else {
604: $out[$key][$rkey][$i]['comment'] = _("[Hidden]");
605: }
606: }
607: }
608: }
609: }
610: }
611: break;
612:
613: default:
614: $out = $in;
615: break;
616: }
617:
618: return $out;
619: }
620:
621: 622: 623: 624: 625: 626: 627: 628: 629: 630:
631: static public function getOwnerCriteria($user)
632: {
633: $criteria = array('user:' . $user);
634: $mygroups = $GLOBALS['injector']
635: ->getInstance('Horde_Group')
636: ->listGroups($GLOBALS['registry']->getAuth());
637: foreach ($mygroups as $id => $group) {
638: $criteria[] = 'group:' . $id;
639: }
640: return $criteria;
641: }
642:
643: 644: 645: 646: 647: 648: 649: 650:
651: static public function getUserAttributes($user = null)
652: {
653: if (is_null($user)) {
654: $user = $GLOBALS['registry']->getAuth();
655: } elseif (empty($user)) {
656: return array('user' => '',
657: 'name' => '',
658: 'email' => '');
659: }
660:
661: if (isset(self::$_users[$user])) {
662: return self::$_users[$user];
663: }
664:
665: if (strpos($user, ':') !== false) {
666: list($type, $user) = explode(':', $user, 2);
667: } else {
668: $type = 'user';
669: }
670:
671:
672: self::$_users[$user]['user'] = $user;
673: self::$_users[$user]['type'] = $type;
674:
675: switch ($type) {
676: case 'user':
677: if (substr($user, 0, 2) == '**') {
678: unset(self::$_users[$user]);
679: $user = substr($user, 2);
680:
681: self::$_users[$user]['user'] = $user;
682: self::$_users[$user]['name'] = '';
683: self::$_users[$user]['email'] = '';
684:
685: try {
686: $addr_arr = Horde_Mime_Address::parseAddressList($user);
687: if (isset($addr_arr[0])) {
688: self::$_users[$user]['name'] = isset($addr_arr[0]['personal'])
689: ? $addr_arr[0]['personal'] : '';
690: self::$_users[$user]['email'] = $addr_arr[0]['mailbox'] . '@'
691: . $addr_arr[0]['host'];
692: }
693: } catch (Horde_Mime_Exception $e) {
694: }
695: } elseif ($user < 0) {
696: global $whups_driver;
697:
698: self::$_users[$user]['user'] = '';
699: self::$_users[$user]['name'] = '';
700: self::$_users[$user]['email'] = $whups_driver->getGuestEmail($user);
701:
702: try {
703: $addr_arr = Horde_Mime_Address::parseAddressList(self::$_users[$user]['email']);
704: if (isset($addr_arr[0])) {
705: self::$_users[$user]['name'] = isset($addr_arr[0]['personal'])
706: ? $addr_arr[0]['personal'] : '';
707: self::$_users[$user]['email'] = $addr_arr[0]['mailbox'] . '@'
708: . $addr_arr[0]['host'];
709: }
710: } catch (Horde_Mime_Exception $e) {
711: }
712: } else {
713: $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($user);
714:
715: self::$_users[$user]['name'] = $identity->getValue('fullname');
716: self::$_users[$user]['email'] = $identity->getValue('from_addr');
717: }
718: break;
719:
720: case 'group':
721: try {
722: $group = $GLOBALS['injector']
723: ->getInstance('Horde_Group')
724: ->getData($user);
725: self::$_users[$user]['user'] = $group['name'];
726: self::$_users[$user]['name'] = $group['name'];
727: self::$_users[$user]['email'] = $group['email'];
728: } catch (Horde_Exception $e) {
729: self::$_users['user']['name'] = '';
730: self::$_users['user']['email'] = '';
731: }
732: break;
733: }
734:
735: return self::$_users[$user];
736: }
737:
738: 739: 740: 741: 742: 743: 744: 745: 746: 747: 748: 749:
750: static public function formatUser($user = null, $showemail = true,
751: $showname = true, $html = false)
752: {
753: if (!is_null($user) && empty($user)) {
754: return '';
755: }
756:
757: if (is_array($user)) {
758: $details = $user;
759: } else {
760: $details = self::getUserAttributes($user);
761: }
762: if (!empty($details['name'])) {
763: $name = $details['name'];
764: } else {
765: $name = $details['user'];
766: }
767: if (($showemail || empty($name) || !$showname) &&
768: !empty($details['email'])) {
769: if ($html && strpos($details['email'], '@') !== false) {
770: $details['email'] = str_replace(array('@', '.'),
771: array(' (at) ', ' (dot) '),
772: $details['email']);
773: }
774:
775: if (!empty($name) && $showname) {
776: $name .= ' <' . $details['email'] . '>';
777: } else {
778: $name = $details['email'];
779: }
780: }
781:
782: if ($html) {
783: $name = htmlspecialchars($name);
784: if ($details['type'] == 'group') {
785: $name = Horde::img('group.png',
786: !empty($details['name'])
787: ? $details['name']
788: : $details['user'])
789: . $name;
790: }
791: }
792:
793: return $name;
794: }
795:
796: 797: 798: 799: 800: 801: 802: 803: 804: 805:
806: static public function getSearchResultColumns($search_type = null)
807: {
808: if ($search_type == 'block') {
809: return array(
810: _("Id") => 'id',
811: _("Summary") => 'summary',
812: _("Priority") => 'priority_name',
813: _("State") => 'state_name');
814: }
815:
816: return array(
817: _("Id") => 'id',
818: _("Summary") => 'summary',
819: _("State") => 'state_name',
820: _("Type") => 'type_name',
821: _("Priority") => 'priority_name',
822: _("Queue") => 'queue_name',
823: _("Requester") => 'user_id_requester',
824: _("Owners") => 'owners',
825: _("Created") => 'timestamp',
826: _("Updated") => 'date_updated',
827: _("Assigned") => 'date_assigned',
828: _("Resolved") => 'date_resolved',
829: );
830: }
831:
832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845:
846: static public function sendReminders($vars)
847: {
848: global $whups_driver;
849:
850: if ($vars->get('id')) {
851: $info = array('id' => $vars->get('id'));
852: } elseif ($vars->get('queue')) {
853: $info['queue'] = $vars->get('queue');
854: if ($vars->get('category')) {
855: $info['category'] = $vars->get('category');
856: } else {
857:
858: $info['category'] = array('unconfirmed', 'new', 'assigned');
859: }
860: } else {
861: throw new Whups_Exception(_("You must select at least one queue to send reminders for."));
862: }
863:
864: $tickets = $whups_driver->getTicketsByProperties($info);
865: self::sortTickets($tickets);
866: if (!count($tickets)) {
867: throw new Whups_Exception(_("No tickets matched your search criteria."));
868: }
869:
870: $unassigned = $vars->get('unassigned');
871: $remind = array();
872: foreach ($tickets as $info) {
873: $info['link'] = self::urlFor('ticket', $info['id'], true, -1);
874: $owners = current($whups_driver->getOwners($info['id']));
875: if (!empty($owners)) {
876: foreach ($owners as $owner) {
877: $remind[$owner][] = $info;
878: }
879: } elseif (!empty($unassigned)) {
880: $remind['**' . $unassigned][] = $info;
881: }
882: }
883:
884:
885: $view = new Horde_View(array('templatePath' => WHUPS_BASE . '/config'));
886: $view->date = strftime($GLOBALS['prefs']->getValue('date_format'));
887:
888:
889: $message_file = WHUPS_BASE . '/config/reminder_email.plain';
890: if (file_exists($message_file . '.local.php')) {
891: $message_file .= '.local.php';
892: } else {
893: $message_file .= '.php';
894: }
895: $message_file = basename($message_file);
896:
897: foreach ($remind as $user => $utickets) {
898: if (empty($user) || !count($utickets)) {
899: continue;
900: }
901: $view->tickets = $utickets;
902: $subject = _("Reminder: Your open tickets");
903: $whups_driver->mail(array('recipients' => array($user => 'owner'),
904: 'subject' => $subject,
905: 'view' => $view,
906: 'template' => $message_file,
907: 'from' => $user));
908: }
909: }
910:
911: 912: 913: 914: 915: 916: 917: 918: 919: 920: 921: 922:
923: static public function getAttachments($ticket, $name = null)
924: {
925: if (empty($GLOBALS['conf']['vfs']['type'])) {
926: return;
927: }
928:
929: try {
930: $vfs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Vfs')->create();
931: } catch (Horde_Vfs_Exception $e) {
932: throw new Whups_Exception($e);
933: }
934:
935: if (!$vfs->isFolder(self::VFS_ATTACH_PATH, $ticket)) {
936: return;
937: }
938:
939: try {
940: $files = $vfs->listFolder(self::VFS_ATTACH_PATH . '/' . $ticket);
941: } catch (Horde_Vfs_Exception $e) {
942: $files = array();
943: }
944: if (is_null($name)) {
945: return $files;
946: }
947: foreach ($files as $file) {
948: if ($file['name'] == $name) {
949: return $file;
950: }
951: }
952: }
953:
954: 955: 956: 957: 958: 959: 960:
961: static public function attachmentUrl($ticket, $file, $queue)
962: {
963: $link = '';
964:
965:
966: $mime_part = new Horde_Mime_Part();
967: $mime_part->setType(Horde_Mime_Magic::extToMime($file['type']));
968: $viewer = $GLOBALS['injector']->getInstance('Horde_Core_Factory_MimeViewer')->create($mime_part);
969: if ($viewer && !($viewer instanceof Horde_Mime_Viewer_Default)) {
970: $url = Horde_Util::addParameter(Horde::url('view.php'),
971: array('actionID' => 'view_file',
972: 'type' => $file['type'],
973: 'file' => $file['name'],
974: 'ticket' => $ticket));
975: $link .= Horde::link($url, $file['name'], null, '_blank') . $file['name'] . '</a>';
976: } else {
977: $link .= $file['name'];
978: }
979:
980:
981: $url_params = array('actionID' => 'download_file',
982: 'file' => $file['name'],
983: 'ticket' => $ticket);
984: $link .= ' ' . Horde::link(Horde::downloadUrl($file['name'], $url_params), $file['name']) . Horde::img('download.png', _("Download")) . '</a>';
985:
986:
987: if (self::hasPermission($queue, 'queue', Horde_Perms::DELETE)) {
988: $url = Horde_Util::addParameter(
989: Horde::url('ticket/delete_attachment.php'),
990: array('file' => $file['name'],
991: 'id' => $ticket,
992: 'url' => Horde::selfUrl(true, false, true)));
993: $link .= ' ' . Horde::link($url, sprintf(_("Delete %s"), $file['name']), '', '', 'return window.confirm(\'' . addslashes(sprintf(_("Permanently delete %s?"), $file['name'])) . '\');') .
994: Horde::img('delete.png', sprintf(_("Delete %s"), $file['name'])) . '</a>';
995: }
996:
997: return $link;
998: }
999:
1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013:
1014: static public function getOwners($ticket, $showemail = true,
1015: $showname = true, $owners = null)
1016: {
1017: if (is_null($owners)) {
1018: $owners = $GLOBALS['whups_driver']->getOwners($ticket);
1019: }
1020:
1021: $results = array();
1022: $owners = reset($owners);
1023: if ($owners !== false) {
1024: foreach ($owners as $owner) {
1025: $results[] = self::formatUser($owner, $showemail, $showname);
1026: }
1027: }
1028: return implode(', ', $results);
1029: }
1030:
1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038:
1039: static public function fieldTypes()
1040: {
1041: if (!empty(self::$_fieldTypes)) {
1042: return self::$_fieldTypes;
1043: }
1044:
1045:
1046: $classes = get_declared_classes();
1047:
1048:
1049: $blacklist = array('invalid', 'addresslink', 'spacer', 'description',
1050: 'captcha', 'figlet', 'header');
1051: foreach ($classes as $class) {
1052: if (stripos($class, 'horde_form_type_') !== false) {
1053: $field_type = substr($class, 16);
1054: 1055:
1056: if (in_array($field_type, $blacklist)) {
1057: continue;
1058: }
1059: self::$_fieldTypes[$field_type] = @call_user_func(
1060: array('Horde_Form_Type_' . $field_type, 'about'));
1061: }
1062: }
1063:
1064: return self::$_fieldTypes;
1065: }
1066:
1067: 1068: 1069: 1070: 1071:
1072: static public function fieldTypeNames()
1073: {
1074:
1075: $fields = self::fieldTypes();
1076:
1077:
1078: $available_fields = array();
1079: foreach ($fields as $field_type => $info) {
1080: $available_fields[$field_type] = $info['name'];
1081: }
1082:
1083:
1084: asort($available_fields);
1085:
1086: return $available_fields;
1087: }
1088:
1089: 1090: 1091: 1092: 1093: 1094: 1095:
1096: static public function fieldTypeParams($field_type)
1097: {
1098: $fields = self::fieldTypes();
1099:
1100: return isset($fields[$field_type]['params'])
1101: ? $fields[$field_type]['params']
1102: : array();
1103: }
1104:
1105: 1106: 1107: 1108: 1109:
1110: static public function getAddressbookSearchParams()
1111: {
1112: $src = json_decode($GLOBALS['prefs']->getValue('search_sources'));
1113: if (!is_array($src)) {
1114: $src = array();
1115: }
1116:
1117: $fields = json_decode($GLOBALS['prefs']->getValue('search_fields'), true);
1118: if (!is_array($fields)) {
1119: $fields = array();
1120: }
1121:
1122: return array(
1123: 'fields' => $fields,
1124: 'sources' => $src
1125: );
1126: }
1127: }
1128: