5 * Functions for the interface to the voicemail recordings
14 * rank (for prioritizing modules)
29 * Adds menu item to nav menu
34 function navMenu($args) {
39 if ($_SESSION['ari_user'] && !$ARI_NO_LOGIN) {
44 $ret .= "<p><small><small><a href='" . $_SESSION['ARI_ROOT'] . "?m=Voicemail&f=display'>" . _("Voicemail") . "</a></small></small></p>";
51 * Deletes selected voicemails and updates page
56 function navSubMenu($args) {
58 global $ASTERISK_VOICEMAIL_PATH;
59 global $ASTERISK_VOICEMAIL_FOLDERS;
62 $m = getArgument($args,'m');
63 $q = getArgument($args,'q');
64 $current_folder = getArgument($args,'folder');
66 $context = $_SESSION['ari_user']['context'];
67 $extension = $_SESSION['ari_user']['extension'];
69 // check for voicemail enabled or admin
70 if ($_SESSION['ari_user']['voicemail_enabled']!=1 ||
71 $extension=='admin') {
76 $paths = split(';',$ASTERISK_VOICEMAIL_PATH);
78 while ($ASTERISK_VOICEMAIL_FOLDERS[$i]) {
80 $f = $ASTERISK_VOICEMAIL_FOLDERS[$i]['folder'];
81 $fn = $ASTERISK_VOICEMAIL_FOLDERS[$i]['name'];
83 foreach($paths as $key => $path) {
85 $path = appendPath($path,$context);
86 $path = appendPath($path,$extension);
88 if (is_dir($path) && is_readable($path)) {
90 while (false!== ($folder = readdir($dh))) {
92 $folder_path = AppendPath($path,$folder);
94 if($folder!="." && $folder!=".." &&
95 filetype($folder_path)=='dir') {
100 $indexes = $this->getVoicemailIndex($folder_path,$q,$order,$sort);
102 $record_count += $this->getVoicemailCount($indexes);
104 // set current folder color
106 if ($current_folder==$folder ||
107 ($current_folder=='' && $ASTERISK_VOICEMAIL_FOLDERS[0]['folder']==$folder)) {
108 $class = "class='current'";
111 // add folder to list
112 $ret .= "<p><small><small>
113 <a " . $class . " href='" . $_SESSION['ARI_ROOT'] . "?m=Voicemail&q=" . $q . "&folder=" . $f. "'>
114 " . $fn . " (" . $record_count . ")" . "
116 </small></small></p>";
129 * Acts on the selected voicemails in the method indicated by the action and updates page
134 function msgAction($args) {
136 global $ASTERISK_VOICEMAIL_FOLDERS;
139 $m = getArgument($args,'m');
140 $a = getArgument($args,'a');
141 $folder = getArgument($args,'folder');
142 $q = getArgument($args,'q');
143 $start = getArgument($args,'start');
144 $span = getArgument($args,'span');
145 $order = getArgument($args,'order');
146 $sort = getArgument($args,'sort');
150 foreach($_REQUEST as $key => $value) {
151 if (preg_match('/selected/',$key)) {
152 array_push($files, $value);
157 $this->deleteVoicemailData($files);
159 else if ($a=='move_to') {
160 $folder_rx = getArgument($args,'folder_rx');
161 if ($folder_rx=='') {
162 $_SESSION['ari_error']
163 = _("A folder must be selected before the message can be moved.");
166 $context = $_SESSION['ari_user']['context'];
167 $extension = $_SESSION['ari_user']['extension'];
168 $this->moveVoicemailData($files, $context, $extension, $folder_rx);
171 else if ($a=='forward_to') {
173 $mailbox_rx = getArgument($args,'mailbox_rx');
174 list($context_rx,$extension_rx) = split('/',$mailbox_rx);
175 if ($extension_rx=='') {
176 $_SESSION['ari_error']
177 = _("An extension must be selected before the message can be forwarded.");
180 $folder_rx = $ASTERISK_VOICEMAIL_FOLDERS[0]['folder'];
181 $this->moveVoicemailData($files, $context_rx, $extension_rx, $folder_rx);
185 // redirect to see updated page
190 window.location = \"" . $_SESSION['ARI_ROOT'] . "?m=" . $m . "&folder=" . $folder . "&q=" . $q . "&start=" . $start . "&span=" . $span . "&order=" . $order . "&sort=" . $sort . "\"
199 * Displays stats page
204 function display($args) {
206 global $ASTERISK_VOICEMAIL_CONF;
207 global $ASTERISK_VOICEMAIL_PATH;
208 global $ASTERISK_VOICEMAIL_FOLDERS;
209 global $AJAX_PAGE_REFRESH_ENABLE;
211 $voicemail_audio_format = $_COOKIE['ari_voicemail_audio_format'];
213 $display = new DisplaySearch();
216 $m = getArgument($args,'m');
217 $f = getArgument($args,'f');
218 $q = getArgument($args,'q');
219 $start = getArgument($args,'start');
220 $span = getArgument($args,'span');
221 $order = getArgument($args,'order');
222 $sort = getArgument($args,'sort');
224 $start = $start=='' ? 0 : $start;
225 $span = $span=='' ? 15 : $span;
226 $order = $order=='' ? 'calldate' : $order;
227 $sort = $sort=='' ? 'desc' : $sort;
229 $paths = split(';',$ASTERISK_VOICEMAIL_PATH);
231 $displayname = $_SESSION['ari_user']['displayname'];
232 $extension = $_SESSION['ari_user']['extension'];
233 $context = $_SESSION['ari_user']['context'];
234 $folder = getArgument($args,'folder');
236 $folder = $ASTERISK_VOICEMAIL_FOLDERS[0]['folder'];
241 foreach($paths as $key => $path) {
242 $path = fixPathSlash($path);
243 $vm_path = $path . "$context/$extension/$folder";
244 $indexes = $this->getVoicemailIndex($vm_path,$q,$order,$sort);
245 $record_count += $this->getVoicemailCount($indexes);
246 $data = array_merge($data,$this->getVoicemailData($indexes,$start,$span));
251 // get the recordings from the asterisk server
256 foreach($paths as $key => $path) {
257 $path_files = GetFiles($path,$filter,$recursiveMax,$recursiveCount);
258 $files = array_merge($files,$path_files);
263 while ($ASTERISK_VOICEMAIL_FOLDERS[$i]) {
264 $cf = $ASTERISK_VOICEMAIL_FOLDERS[$i]['folder'];
265 $fn = $ASTERISK_VOICEMAIL_FOLDERS[$i]['name'];
267 $move_options .= "<option VALUE='" . $cf . "'> " . $fn;
273 if (is_readable($ASTERISK_VOICEMAIL_CONF)) {
274 $lines = file($ASTERISK_VOICEMAIL_CONF);
275 $ext_array = array();
276 foreach ($lines as $key => $line) {
278 // get context for forward to mailbox
279 if (preg_match("/\[.*\]/i",$line)) {
280 $forwardContext = trim(preg_replace('/\[|\]/', '', $line));
283 // get username and add to options
284 if (preg_match("/\=\>/i",$line)) {
285 list($username,$value) = split('=>',$line);
286 $username = trim($username);
287 if ($username!=$_SESSION['ari_user']['extension']) {
288 //$ext_array[] = $username . "|" . $forwardContext;
289 list(,$real_name,) = split(",",$value,3);
290 $ext_array[] = $real_name . "|" . $username . "|" . $forwardContext;
297 //get the size of the array
298 $array_size = count($ext_array) - 1;
300 //loop through the array and build the drop down list
301 foreach ($ext_array as $item)
303 //split the values apart
304 list($real_name,$username,$context) = explode("|",$item);
306 //add it to the drop down
307 $forward_options .= "<option VALUE='" . $context . "/" . $username . "'>" . substr($real_name,0,15) . " <" . $username . ">";
311 $_SESSION['ari_error'] = "File not readable: " . $ASTERISK_VOICEMAIL_CONF;
317 <button class='infobar' type='submit' onclick=\"document.voicemail_form.a.value='delete'\">
320 <button class='infobar' type='submit' onclick=\"document.voicemail_form.a.value='move_to'\">
323 <select name='folder_rx' style='width:124px;'>
324 <option VALUE=''>" . _("Folder") . "
325 " . $move_options . "
327 <button class='infobar' type='submit' onclick=\"document.voicemail_form.a.value='forward_to'\">
328 " . _("forward_to") . "
330 <select name='mailbox_rx'>
332 " . $forward_options . "
336 $recording_delete_header = "<th></th>";
338 $fields[0]['field'] = "calldate";
339 $fields[0]['text'] = _("Date");
340 $fields[1]['field'] = "calldate";
341 $fields[1]['text'] = _("Time");
342 $fields[2]['field'] = "clid";
343 $fields[2]['text'] = _("Caller ID");
344 $fields[3]['field'] = "priority";
345 $fields[3]['text'] = _("Priority");
346 $fields[4]['field'] = "origmailbox";
347 $fields[4]['text'] = _("Orig Mailbox");
348 $fields[5]['field'] = "duration";
349 $fields[5]['text'] = _("Duration");
351 while ($fields[$i]) {
353 $field = $fields[$i]['field'];
354 $text = $fields[$i]['text'];
355 if ($order==$field) {
357 $currentSort = 'desc';
358 $arrowImg = "<img src='theme/images/arrow-asc.gif' alt='sort'>";
361 $currentSort = 'asc';
362 $arrowImg = "<img src='theme/images/arrow-desc.gif' alt='sort'>";
371 $currentSort = 'desc';
374 $unicode_q = urlencode($q);
375 $recording_header .= "<th><a href=" . $_SESSION['ARI_ROOT'] . "?m=" . $m . "&f=" . $f . "&q=" . $unicode_q . "&order=" . $field . "&sort=" . $currentSort . ">" . $text . $arrowImg . "</a></th>";
379 $recording_header .= "<th>" . _("Message") . "</th>";
383 foreach($data as $file=>$value) {
385 // recording popup link
386 $voicemail_audio_format = $voicemail_audio_format=='' ? '.wav' : $voicemail_audio_format;
387 $recording = preg_replace('/.txt/', $voicemail_audio_format, $file);
388 if (is_file($recording)) {
389 $recordingLink = "<a href='#' onClick=\"javascript:popUp('misc/recording_popup.php?recording=" . $recording . "&date=" . $date . "&time=" . $time . "'); return false;\">
394 $_SESSION['ari_error'] = _("Voicemail recording(s) was not found.") . "<br>" .
395 sprintf(_("On settings page, change voicemail audio format. It is currently set to %s"),$voicemail_audio_format);
400 <td class='checkbox'><input type=checkbox name='selected" . ++$i . "' value=" . $file . "></td>
401 <td width=68>" . GetDateFormat($value['origtime']) . "</td>
402 <td>" . GetTimeFormat($value['origtime']) . "</td>
403 <td width=100>" . $value[callerid] . "</td>
404 <td>" . $value[priority] . "</td>
405 <td width=90>" . $value[origmailbox] . "</td>
406 <td>" . $value[duration] . " sec</td>
407 <td>" . $recordingLink . "</td>
414 $url_opts['folder'] = $folder;
415 $url_opts['sort'] = $sort;
416 $url_opts['order'] = $order;
420 // check for voicemail enabled
421 if ($_SESSION['ari_user']['voicemail_enabled']!=1) {
422 $_SESSION['ari_error'] = _("Voicemail Login not found.") . "<br>" .
423 _("No access to voicemail");
428 if ($extension=='admin') {
429 $_SESSION['ari_error'] = _("No Voicemail Recordings for Admin");
433 // build page content
434 $ret .= checkErrorMessage();
439 // ajax page refresh script
440 if ($AJAX_PAGE_REFRESH_ENABLE) {
441 // $ret .= ajaxRefreshScript($args);
445 $ret .= $display->displayHeaderText(sprintf(_("Voicemail for %s (%s)"),$displayname,$extension));
446 $ret .= $display->displaySearchBlock('left',$m,$q,$url_opts,true);
450 <form name='voicemail_form' action='" . $_SESSION['ARI_ROOT'] . "' method='GET'>
451 <input type=hidden name=m value=" . $m . ">
452 <input type=hidden name=f value=msgAction>
453 <input type=hidden name=a value=''>
454 <input type=hidden name=q value=" . $q . ">
455 <input type=hidden name=folder value=" . $folder . ">
456 <input type=hidden name=start value=" . $start . ">
457 <input type=hidden name=span value=" . $span . ">
458 <input type=hidden name=order value=" . $order . ">
459 <input type=hidden name=sort value=" . $sort . ">";
461 $ret .= $display->displayInfoBarBlock($controls,$q,$start,$span,$record_count);
463 // add javascript for popup and message actions
465 <SCRIPT LANGUAGE='JavaScript'>
467 function popUp(URL) {
468 popup = window.open(URL, 'play', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=1,width=324,height=110');
471 function checkAll(form,set) {
474 while (elem = form.elements[i]) {
478 elem.checked = false;
487 // voicemail delete recording controls
492 <small>" . _("select") . ": </small>
493 <small><a href='' OnClick=\"checkAll(document.voicemail_form,true); return false;\">" . _("all") . "</a></small>
494 <small><a href='' OnClick=\"checkAll(document.voicemail_form,false); return false;\">" . _("none") . "</a></small>
501 <table class='voicemail'>
503 " . $recording_delete_header . "
504 " . $recording_header . "
512 $ret .= $display->displaySearchBlock('center',$m,$q,$url_opts,false);
513 $ret .= $display->displayNavigationBlock($m,$q,$url_opts,$start,$span,$record_count);
519 * Gets voicemail data
522 * Reference to the variable to store the data in
526 function getVoicemailIndex($path,$q,$order,$sort) {
533 $files = getFiles($path,$filter,$recursiveMax,$recursiveCount);
537 // ugly, but sorts array by time stamp
538 foreach ($files as $file) {
540 if (is_file($file)) {
542 $lines = file($file);
543 foreach ($lines as $key => $line) {
545 list($key,$value) = split('=',$line);
548 if ($key=="origtime") {
550 $date = GetDateFormat($value);
551 $time = GetTimeFormat($value);
553 if ($key=="callerid") {
556 if ($key=="priority") {
559 if ($key=="origmailbox") {
560 $origmailbox = $value;
562 if ($key=="duration") {
563 $duration = (int)$value;
574 if (preg_match("/" . $q . "/", $origmailbox) ||
575 preg_match("/" . $q . "/", $callerid) ||
576 preg_match("/" . $q . "/", $date) ||
577 preg_match("/" . $q . "/", $time)) {
585 $indexes[$file] = $$order;
589 if (count($indexes)) {
603 * Deletes selected voicemails
606 * Array of files to delete
608 function deleteVoicemailData($files) {
610 foreach($files as $key => $path) {
612 // get file parts for search
613 $path_parts = pathinfo($path);
614 $path = fixPathSlash($path_parts['dirname']);
616 list($name,$ext) = split("\.",$path_parts['basename']);
618 // delete all related files using a wildcard
620 $hdl = opendir($path);
621 while ($fn = readdir($hdl)) {
622 if (preg_match("/" . $name ."/",$fn)) {
633 * Moves selected voicemails to a specified folder
636 * Array of files to delete
637 * @param $extension_rx
638 * Mailbox to move message to
640 * Folder to move the messages to
642 function moveVoicemailData($files,$context_rx,$extension_rx,$folder_rx) {
644 global $ASTERISK_VOICEMAIL_PATH;
646 $perm = fileperms($ASTERISK_VOICEMAIL_PATH);
647 $uid = fileowner($ASTERISK_VOICEMAIL_PATH);
648 $gid = filegroup($ASTERISK_VOICEMAIL_PATH);
651 $paths = split(';',$ASTERISK_VOICEMAIL_PATH);
652 $path_rx = appendPath($paths[0],$context_rx);
653 if (!is_dir($path_rx)) {
654 mkdir($path_rx, $perm);
655 chown($path_rx,intval($uid));
656 chgrp($path_rx,intval($gid));
658 $path_rx = appendPath($path_rx,$extension_rx);
659 if (!is_dir($path_rx)) {
660 mkdir($path_rx, $perm);
661 chown($path_rx,intval($uid));
662 chgrp($path_rx,intval($gid));
664 $path_rx = appendPath($path_rx,$folder_rx);
665 if (!is_dir($path_rx)) {
666 mkdir($path_rx, $perm);
667 chown($path_rx,intval($uid));
668 chgrp($path_rx,intval($gid));
671 // get recieving folder last message number
672 if (is_dir($path_rx)) {
677 $dh = opendir($path_rx);
678 while (false != ($filename = readdir($dh))) {
679 if($filename!="." && $filename!="..") {
681 $msg_path = $path_rx;
682 $msg_path = appendPath($msg_path,$filename);
683 if (is_file($msg_path)) {
684 $path_parts = pathinfo($msg_path);
685 $num = preg_replace("/[a-zA-Z]|\./",'', $path_parts['basename']);
686 if ($num > $lastNum) {
688 $lastNumLen = strlen($lastNum);
695 $_SESSION['ari_error'] = sprintf(_("Could not create mailbox folder %s on the server"),$folder_rx);
699 // copy files to new location, incrementing each message number
701 foreach($files as $key => $path) {
703 // get file parts for search
704 $path_parts = pathinfo($path);
705 $path = $path_parts['dirname'];
706 $path = fixPathSlash($path);
707 list($name,$ext) = split("\.",$path_parts['basename']);
711 $hdl = opendir($path);
712 while ($fn = readdir($hdl)) {
713 if (preg_match("/" . $name . "/",$fn)) {
715 $path_parts = pathinfo($src);
716 $folder_rx = preg_replace("/\d+/",sprintf("%0" . $lastNumLen . "d",$lastNum),$path_parts['basename']);
717 $dst = appendPath($path_rx,$folder_rx);
718 if (is_writable($src) && is_writable($path_rx)) {
720 $perm = fileperms($src);
721 $uid = fileowner($src);
722 $gid = filegroup($src);
726 if (is_writable($dst)) {
728 chown($dst,intval($uid));
729 chgrp($dst,intval($gid));
735 $_SESSION['ari_error'] = sprintf(_("Permission denied on folder %s or %s"),$src,$path_rx);
746 * Gets voicemail record count
749 * array of files to be counted
751 * number of cdr records counted
753 function getVoicemailCount($indexes) {
755 $count = count($indexes);
761 * Gets voicemail data
764 * array of voicemail files
766 * message number to start page with
768 * number of messages to display on page
770 * Reference to the variable to store the data in
772 function getVoicemailData($indexes,$start,$span) {
776 if (!isset($indexes)) {
782 foreach ($indexes as $file => $index) {
783 if ($i>$start-1+$span) {
786 elseif ($i>$start-1 && $i<$start+$span) {
787 $lines = file($file);
788 foreach ($lines as $key => $line) {
790 list($key,$value) = split('=',$line);
792 $data[$file][$key] = $value;