1 <?php
3 class faxreport extends plugin
4 {
5 /* Definitions */
6 var $plHeadline = "FAX Reports";
7 var $plDescription = "View the FAX report or single documents that have been recieved";
8 var $plIcon = "plugins/gofax/images/reports.png";
10 /* For internal use */
11 var $start = 0;
12 var $search_for = "*";
13 var $search_base = "";
14 var $year = "";
15 var $month = "";
16 var $sort = 1;
17 var $sort_direction = "down";
18 var $ui = NULL;
19 var $range = 20;
20 var $view_logged = FALSE;
22 /* Constant stuff */
23 var $status= array( "SENT", "MAILED", "SERROR", "RERROR", "SBLOCK", "RBLOCK",
24 "DELETED", "REQUEUED", "DISABLED", "PRINTED", "DIVERTED",
25 "UNDEFINED", "UNDEFINED", "UNDEFINED", "UNDEFINED",
26 "UNDEFINED");
27 var $fields= array("uid", "queuing_time", "status", "sender_id", "receiver_id", "pages");
29 /* these vars will be stored in session to be able to remember last search config */
30 var $attributes_SO= array("search_for","month","year",
31 "start","year","month","sort","sort_direction","range");
33 var $objectclasses= array();
34 var $fax_users = array();
36 // An array containing all valid fax accounts (uid => dn)
37 // This enables us to perform correct ACL checks later.
38 // We require "users/viewFaxEntries" acls for to users dn, if he exists.
39 // and "users/viewFaxEntries" acls for the LDAP-Base if the uid is
40 // unknown (The uid is not represented by a valid FAX account).
41 var $uidToDN = array();
43 /* Create class */
44 function faxreport (&$config, &$ui)
45 {
46 /* Include config object */
47 $this->config = $config;
48 $this->ui = &$ui;
49 $this->search_base = $this->config->current['BASE'];
50 $this->year = date("Y");
51 $this->month = date("m");
53 // Get global filter config and set class vars , or create a filter
54 if (!session::is_set("faxreportfilter")){
55 $faxreportfilter = array();
56 foreach($this->attributes_SO as $name){
57 $faxreportfilter[$name] = $this->$name;
58 }
59 session::set("faxreportfilter",$faxreportfilter);
60 }else{
61 $faxreportfilter = session::get("faxreportfilter");
62 foreach($this->attributes_SO as $name){
63 $this->$name = $faxreportfilter[$name];
64 }
65 }
67 // Get ALL valid FAX-Accounts and their dns, this allows us to perform correct
68 // permissions checks later.
69 $filter= "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))(objectClass=goFaxAccount)(uid=*))";
70 $tmp= get_list($filter, "users/viewFaxEntries", $this->search_base,
71 array("uid"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
72 $this->uidToDN = array();
73 foreach($tmp as $attrs){
74 $this->uidToDN[$attrs['uid'][0]] = $attrs['dn'];
75 }
76 }
79 /* Create Filter & Search & Display results */
80 function execute()
81 {
82 /* Call parent execute */
83 plugin::execute();
85 /* Log view */
86 if(!$this->view_logged){
87 $this->view_logged = TRUE;
88 new log("view","users/".get_class($this),$this->dn);
89 }
91 // Variable initialisation
93 /* Create months */
94 $months= array();
95 for($i = 1 ; $i <= 12 ; $i ++ ){
96 $months[$i] = _(date("F",gmmktime(0,0,0,$i,1)));
97 }
99 /* Create years */
100 $current= date("Y");
101 $years= array();
102 for ($y= $current - 5; $y<=$current; $y++){
103 $years[]= $y;
104 }
107 // Set smarty defaults
108 $smarty= get_smarty();
109 $smarty->assign("search_for" , set_post($this->search_for));
110 $smarty->assign("months" , $months);
111 $smarty->assign("month_select" , $this->month);
112 $smarty->assign("years" , $years);
113 $smarty->assign("year_select" , $this->year);
114 $smarty->assign("search_result" , "");
117 // Check database accessibility
118 if(!isset($this->config->data['SERVERS']['FAX'])){
119 msg_dialog::display(_("Error"), _("No fax server found!"), ERROR_DIALOG);
120 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
121 }elseif(!is_callable("mysql_connect")){
122 msg_dialog::display(_("Configuration error"), sprintf(
123 _("Missing %s PHP extension!"), "mysql"), WARNING_DIALOG);
124 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
125 }else{
126 /* Connecting, selecting database */
127 $cfg = $this->config->data['SERVERS']['FAX'];
128 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
129 if ($link === FALSE){
130 msg_dialog::display(_("Error"), sprintf(
131 _("Cannot connect to %s database!"), "GOfax"), ERROR_DIALOG);
132 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
133 }
134 if (! @mysql_select_db("gofax")){
135 msg_dialog::display(_("Error"), sprintf(
136 _("Cannot select %s database!"), "GOfax"), ERROR_DIALOG);
137 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
138 }
140 if (! mysql_query("SELECT * FROM faxlog;")){
141 msg_dialog::display(_("Error"), sprintf(
142 _("Cannot query %s database!"), "GOfax"), ERROR_DIALOG);
143 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
144 }
145 }
148 // Perform a deatil view
149 $detail = -1;
150 foreach($_POST as $name => $desc){
151 if(preg_match("/^detail_/", $name)){
152 $detail = postDecode(preg_replace("/^detail_/","",$name));
153 break;
154 }
155 }
156 if ($detail != -1){
158 // Query for the requested fay entry
159 $query = "SELECT id,uid,date_format(queuing_time, '%Y%m%d%H%i%s') ".
160 "as queuing_time,status,sender_id,sender_msn,receiver_id,".
161 "receiver_msn,pages,status_message,transfer_time FROM faxlog WHERE id=".$detail.";";
163 $cfg= $this->config->data['SERVERS']['FAX'];
164 $result = @mysql_query($query);
165 if ($result === false){
166 msg_dialog::display(_("Error"), sprintf(
167 _("Cannot query %s database!"), "GOfax"), ERROR_DIALOG);
168 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query failed");
169 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
170 }
171 $line = mysql_fetch_array($result, MYSQL_ASSOC);
172 mysql_close($link);
174 // Get dn to check ACLs for
175 // Existing ldap-user -> use its dn
176 // Not existing user -> use ldap base dn
177 $dn = $this->search_base;
178 if(isset($this->uidToDN[$line['uid']])){
179 $dn = $this->uidToDN[$line['uid']];
180 }
182 // We do not have any ACLs for this entry, so continue.
183 $acls = $this->ui->get_permissions($dn,"users/viewFaxEntries","");
184 if(!preg_match("/r/",$acls)){
185 msg_dialog::display(_("Permission error"),
186 _("You have no permission to view this fax id!"), ERROR_DIALOG);
187 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
188 }
190 // Check permissions for each attribute
191 $parts= array( "id", "uid", "queuing_time", "status", "sender_id", "sender_msn",
192 "receiver_id", "receiver_msn", "pages", "status_message", "transfer_time" );
193 foreach ($parts as $vname) {
194 $final="fax_$vname";
195 $v_acl = $this->ui->get_permissions($dn,"users/viewFaxEntries",preg_replace("/_/","",$vname));
196 if($line[$vname] != "" && preg_match("/r/i", $v_acl)){
197 $smarty->assign("$final", set_post($line[$vname]));
198 } else {
199 $smarty->assign("$final", "-");
200 }
201 }
202 $format= _("Y-M-D");
203 $queuing_time= $line['queuing_time'];
204 $smarty->assign("plug", "?plug=".get_post('plug'));
205 $smarty->assign("detail", set_post(get_post($detail)));
206 $date= preg_replace("/Y/", substr($queuing_time,0,4), $format);
207 $date= preg_replace("/M/", substr($queuing_time,4,2), $date);
208 $date= preg_replace("/D/", substr($queuing_time,6,2), $date);
209 $smarty->assign("date", $date);
210 $smarty->assign("time", substr($queuing_time,8,2).":".
211 substr($queuing_time,10,2).":".
212 substr($queuing_time,12,2));
214 return($smarty->fetch(get_template_path('detail.tpl', TRUE)));
215 }
218 // Convert search filter into useable string
219 $fax_users= array();
220 $s = preg_replace("/\*/","",$this->search_for);
221 if(!empty($s)) $s = "*{$s}*"; else $s="*";
223 // Collect potential 'uid's that match the filter.
224 $filter= "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))".
225 "(objectClass=goFaxAccount)".
226 "(|(uid=$s)(l=$s)(homePhone=$s)".
227 "(telephoneNumber=$s)(facsimileTelephoneNumber=$s)(mobile=$s)".
228 "(pager=$s)(cn=$s)(givenName=$s)(sn=$s)(personalTitle=$s)".
229 "(title=$s)))";
230 $res = get_list($filter, "users/viewFaxEntries", $this->search_base, array("uid"), GL_SUBSEARCH );
231 $fax_users = array();
232 foreach($res as $attrs){
233 $fax_users[ $attrs['dn']]= $attrs["uid"][0];
234 }
236 // Search for entries mathcing the filter
237 $userfilter = "uid like '".preg_replace("/\*/","%%", $s)."' OR ";
238 $userfilter.= "sender_id like '".preg_replace("/\*/","%%", $s)."' OR ";
239 $userfilter.= "receiver_id like '".preg_replace("/\*/","%%", $s)."' OR ";
241 // ... and additionally search for a status value.
242 $id = array_search($this->search_for, $this->status);
243 if($id !== FALSE){
244 $userfilter.= "status = '".$id."' OR ";
245 }
247 // Add collectod users to the query
248 foreach ($fax_users as $user){
249 $userfilter.= "uid = '$user' OR ";
250 }
251 $userfilter= "(".preg_replace("/OR $/", "", $userfilter).")";
253 // Add date settings
254 $desc = ($this->sort_direction == "down")? "": "DESC";
255 $start= date ("YmdHis", mktime(0,0,0,$this->month,1,$this->year));
256 $end= date ("YmdHis", mktime(23,59,59,$this->month+1,0,$this->year));
257 $query_entries = "SELECT id,uid,date_format(queuing_time, '%Y%m%d%H%i%s') as queuing_time,".
258 "status,sender_id,receiver_id,pages FROM faxlog ".
259 "WHERE {$userfilter} AND queuing_time <= {$end} AND ".
260 "queuing_time >= {$start} ".
261 "ORDER BY ".$this->fields[$this->sort].
262 " {$desc } ";
265 $cfg= $this->config->data['SERVERS']['FAX'];
266 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
268 // Get the results
269 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
270 $result =@mysql_query($query_entries);
271 if ($result === false){
272 msg_dialog::display(_("Error"), sprintf(_("Cannot query %s database!"), "GOfax"), ERROR_DIALOG);
273 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
274 }
276 // Restricted attributes will not be displayed, this will be displayed instead */
277 $no_acl = image('images/lists/locked.png','',
278 _("Insufficient permissions to view this attribute"));
280 // Add found entries to result list.
281 $report_list= array();
282 $user_ids = array_flip($fax_users);
283 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
285 // Get dn to check ACLs for
286 // Existing ldap-user -> use its dn
287 // Not existing user -> use ldap base dn
288 $dn = $this->search_base;
289 if(isset($this->uidToDN[$line['uid']])){
290 $dn = $this->uidToDN[$line['uid']];
291 }
293 // We do not have any ACLs for this entry, so continue.
294 $tmp = $this->ui->get_permissions($dn,"users/viewFaxEntries","");
295 if(empty($tmp)) continue;
297 // Hide field for which we have no permissions
298 foreach(array("pages","receiverid","senderid","status","queuingtime","detailedView") as $attr){
299 $var = $attr."ACL";
300 $$var = $this->ui->get_permissions($dn,"users/viewFaxEntries",$attr);
301 }
303 // Create date
304 if((!empty($line["queuing_time"])) && preg_match("/r/",$queuingtimeACL)){
305 $hour= substr($line["queuing_time"], 8, 2);
306 $minute=substr($line["queuing_time"], 10, 2);
307 $format= _("Y-M-D");
308 $date= preg_replace("/Y/", substr($line["queuing_time"], 0, 4), $format);
309 $date= preg_replace("/M/", substr($line["queuing_time"], 4, 2), $date);
310 $date= preg_replace("/D/", substr($line["queuing_time"], 6, 2), $date);
311 $str_date = $date." ".$hour.":".$minute;
312 }else{
313 $str_date = $no_acl;
314 }
316 /* Create entry html str */
317 $str = " \n<td class='list0'>".$line["uid"]."</td>";
318 $str.= " \n<td class='list0'>".$str_date."</td>";
320 /* Add Status td */
321 if(preg_match("/r/",$statusACL)){
322 $str.=" \n<td class='list0'>".$this->status[$line["status"]]."</td>";
323 }else{
324 $str.=" \n<td class='list0'>".$no_acl."</td>";
325 }
327 /* Add sender_id td */
328 if(preg_match("/r/",$senderidACL)){
329 $str.=" \n<td class='list0'>".htmlentities($line["sender_id"],ENT_COMPAT,'UTF-8')."</td>";
330 }else{
331 $str.=" \n<td class='list0'>".$no_acl."</td>";
332 }
334 /* Add receiver_id td */
335 if(preg_match("/r/",$receiveridACL)){
336 $str.=" \n<td class='list0'>".htmlentities($line["receiver_id"],ENT_COMPAT,'UTF-8')."</td>";
337 }else{
338 $str.=" \n<td class='list0'>".$no_acl."</td>";
339 }
341 /* Add receiver_id td */
342 if(preg_match("/r/",$pagesACL)){
343 $str.=" \n<td class='list0'>".$line["pages"]."</td>";
344 }else{
345 $str.=" \n<td class='list0'>".$no_acl."</td>";
346 }
347 /* Create entry html str */
348 if(preg_match("/r/",$detailedViewACL)){
349 $str.= " \n<td class='list0' style='border-right: 0pt none;'>".
350 image('images/info_small.png', 'detail_'.postEncode($line["id"]))."</td>";
351 }else{
352 $str.= " \n<td class='list0' style='border-right: 0pt none;'> </td>";
353 }
354 $report_list[] = $str;
355 }
356 mysql_close($link);
358 $entry_count = count($report_list);
359 if($this->start >=$entry_count) $this->start =0;
361 /* Generate output */
362 $mod= 0;
363 $output= "";
364 $report_list = array_slice($report_list, $this->start, $this->range);
365 foreach ($report_list as $val){
366 $output.= "\n<tr>{$val}</tr>";
367 }
368 $smarty->assign("search_result", $output);
369 $smarty->assign("range_selector",
370 range_selector($entry_count, $this->start, $this->range,"EntriesPerPage"));
372 // Add sorting links
373 $smarty->assign("plug", "?plug=".validate($_GET['plug']));
374 for($i= 0; $i<7; $i++){
375 $smarty->assign("mode$i", "");
376 }
377 $smarty->assign("mode".$this->sort, image("images/lists/sort-".$this->sort_direction.".png"));
378 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
379 }
382 // Save posted filter settings
383 function save_object()
384 {
385 $faxreportfilter = session::get("faxreportfilter");
386 if(isset($_POST['EntriesPerPage'])){
387 $this->range = get_post('EntriesPerPage');
388 }
390 if (isset($_GET['start'])){
391 $this->start= (int)$_GET['start'];
392 }
394 /* Adapt sorting */
395 if (isset($_GET['sort'])){
396 if ($this->sort == (int)$_GET['sort']){
397 if ($this->sort_direction == "down"){
398 $this->sort_direction= "up";
399 } else {
400 $this->sort_direction= "down";
401 }
402 }
403 $this->sort= (int)$_GET['sort'];
404 if ($this->sort < 0 || $this->sort > 5){
405 $this->sort= 0;
406 }
407 }
408 foreach( array("year", "month", "search_for") as $type){
409 if (isset($_POST[$type])){
410 $faxreportfilter[$type]= get_post($type);
412 /* reset start page, if filter has changed */
413 if(!isset($_GET['start'])){
414 $this->start = 0;
415 }
416 }
417 $this->$type= $faxreportfilter[$type];
419 }
420 foreach($this->attributes_SO as $name){
421 $faxreportfilter[$name] = $this->$name;
422 }
423 session::set("faxreportfilter",$faxreportfilter);
424 }
425 }
428 class viewFaxEntries extends plugin {
430 static function plInfo()
431 {
433 return (array(
434 "plShortName" => _("View fax reports"),
435 "plDescription" => _("View fax reports")." <i>"._("All entries are readonly")."</i>",
436 "plRequirements"=> array(
437 'activePlugin' => 'faxreport',
438 'ldapSchema' => array('goFaxAccount' => '>=1.0.4'),
439 'onFailureDisablePlugin' => array('faxreport','gofaxAccount','goFaxServer')
440 ),
441 "plSelfModify" => TRUE,
442 "plDepends" => array(),
443 "plPriority" => 89, // Position in tabs
444 "plSection" => array("administration"), // This belongs to personal
445 "plCategory" => array("users"),
446 "plOptions" => array(),
448 "plProvidedAcls" => array(
449 "detailedView" => _("Detailed view and download"),
450 "id" => _("Fax ID"),
451 "queuingtime" => _("Date")." / "._("Time"),
452 "status" => _("Status"),
453 "senderid" => _("Sender ID"),
454 "sendermsn" => _("Sender MSN"),
455 "receiverid" => _("Receiver ID"),
456 "receivermsn" => _("Receiver MSN"),
457 "pages" => _("Number of pages"),
458 "statusmessage" => _("Status Message"),
459 "transfertime" => _("Transfer time"))
460 ));
461 }
463 }
465 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
466 ?>