c00522e9bd48e86ab5639ba036a62556ab22cf6f
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 received";
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 $this->initTime = microtime(TRUE);
48 /* Include config object */
49 $this->config = $config;
50 $this->ui = &$ui;
51 $this->search_base = $this->config->current['BASE'];
52 $this->year = date("Y");
53 $this->month = date("m");
55 // Get global filter config and set class vars , or create a filter
56 if (!session::is_set("faxreportfilter")){
57 $faxreportfilter = array();
58 foreach($this->attributes_SO as $name){
59 $faxreportfilter[$name] = $this->$name;
60 }
61 session::set("faxreportfilter",$faxreportfilter);
62 }else{
63 $faxreportfilter = session::get("faxreportfilter");
64 foreach($this->attributes_SO as $name){
65 $this->$name = $faxreportfilter[$name];
66 }
67 }
69 // Get ALL valid FAX-Accounts and their dns, this allows us to perform correct
70 // permissions checks later.
71 $filter= "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))(objectClass=goFaxAccount)(uid=*))";
72 $tmp= get_list($filter, "users/viewFaxEntries", $this->search_base,
73 array("uid"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
74 $this->uidToDN = array();
75 foreach($tmp as $attrs){
76 $this->uidToDN[$attrs['uid'][0]] = $attrs['dn'];
77 }
79 // Create statistic table entry
80 stats::log('plugin', $class = get_class($this), $category = array($this->acl_category), $action = 'open',
81 $amount = 1, $duration = (microtime(TRUE) - $this->initTime));
83 }
86 /* Create Filter & Search & Display results */
87 function execute()
88 {
89 /* Call parent execute */
90 plugin::execute();
92 /* Log view */
93 if(!$this->view_logged){
94 $this->view_logged = TRUE;
95 new log("view","users/".get_class($this),$this->dn);
96 }
98 // Variable initialisation
100 /* Create months */
101 $months= array();
102 for($i = 1 ; $i <= 12 ; $i ++ ){
103 $months[$i] = _(date("F",gmmktime(0,0,0,$i,1)));
104 }
106 /* Create years */
107 $current= date("Y");
108 $years= array();
109 for ($y= $current - 5; $y<=$current; $y++){
110 $years[]= $y;
111 }
114 // Set smarty defaults
115 $smarty= get_smarty();
116 $smarty->assign("search_for" , set_post($this->search_for));
117 $smarty->assign("months" , $months);
118 $smarty->assign("month_select" , $this->month);
119 $smarty->assign("years" , $years);
120 $smarty->assign("year_select" , $this->year);
121 $smarty->assign("search_result" , "");
124 // Check database accessibility
125 if(!isset($this->config->data['SERVERS']['FAX'])){
126 msg_dialog::display(_("Error"), _("No FAX server found!"), ERROR_DIALOG);
127 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
128 }elseif(!is_callable("mysql_connect")){
129 msg_dialog::display(_("Configuration error"), sprintf(
130 _("Missing %s PHP extension!"), "mysql"), WARNING_DIALOG);
131 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
132 }else{
133 /* Connecting, selecting database */
134 $cfg = $this->config->data['SERVERS']['FAX'];
135 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
136 if ($link === FALSE){
137 msg_dialog::display(_("Error"), sprintf(
138 _("Cannot connect to %s database!"), "<b>".$cfg['SERVER'].":"."GOfax"."</b>"), ERROR_DIALOG);
139 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
140 }
141 if (! @mysql_select_db("gofax")){
142 msg_dialog::display(_("Error"), sprintf(
143 _("Cannot select %s database!"), "GOfax"), ERROR_DIALOG);
144 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
145 }
147 if (! mysql_query("SELECT * FROM faxlog;")){
148 msg_dialog::display(_("Error"), sprintf(
149 _("Cannot query %s database!"), "GOfax"), ERROR_DIALOG);
150 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
151 }
152 }
155 // Perform a deatil view
156 $detail = -1;
157 foreach($_POST as $name => $desc){
158 if(preg_match("/^detail_/", $name)){
159 $detail = postDecode(preg_replace("/^detail_/","",$name));
160 break;
161 }
162 }
163 if ($detail != -1){
165 // Query for the requested fay entry
166 $query = "SELECT id,uid,date_format(queuing_time, '%Y%m%d%H%i%s') ".
167 "as queuing_time,status,sender_id,sender_msn,receiver_id,".
168 "receiver_msn,pages,status_message,transfer_time FROM faxlog WHERE id=".$detail.";";
170 $cfg= $this->config->data['SERVERS']['FAX'];
171 $result = @mysql_query($query);
172 if ($result === false){
173 msg_dialog::display(_("Error"), sprintf(
174 _("Cannot query %s database!"), "GOfax"), ERROR_DIALOG);
175 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query failed");
176 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
177 }
178 $line = mysql_fetch_array($result, MYSQL_ASSOC);
179 mysql_close($link);
181 // Get dn to check ACLs for
182 // Existing ldap-user -> use its dn
183 // Not existing user -> use ldap base dn
184 $dn = $this->search_base;
185 if(isset($this->uidToDN[$line['uid']])){
186 $dn = $this->uidToDN[$line['uid']];
187 }
189 // We do not have any ACLs for this entry, so continue.
190 $acls = $this->ui->get_permissions($dn,"users/viewFaxEntries","");
191 if(!preg_match("/r/",$acls)){
192 msg_dialog::display(_("Permission error"),
193 _("You have no permission to view this FAX id!"), ERROR_DIALOG);
194 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
195 }
197 // Check permissions for each attribute
198 $parts= array( "id", "uid", "queuing_time", "status", "sender_id", "sender_msn",
199 "receiver_id", "receiver_msn", "pages", "status_message", "transfer_time" );
200 foreach ($parts as $vname) {
201 $final="fax_$vname";
202 $v_acl = $this->ui->get_permissions($dn,"users/viewFaxEntries",preg_replace("/_/","",$vname));
203 if($line[$vname] != "" && preg_match("/r/i", $v_acl)){
204 $smarty->assign("$final", set_post($line[$vname]));
205 } else {
206 $smarty->assign("$final", "-");
207 }
208 }
209 $format= _("Y-M-D");
210 $queuing_time= $line['queuing_time'];
211 $smarty->assign("plug", "?plug=".get_post('plug'));
212 $smarty->assign("detail", set_post(get_post($detail)));
213 $date= preg_replace("/Y/", substr($queuing_time,0,4), $format);
214 $date= preg_replace("/M/", substr($queuing_time,4,2), $date);
215 $date= preg_replace("/D/", substr($queuing_time,6,2), $date);
216 $smarty->assign("date", $date);
217 $smarty->assign("time", substr($queuing_time,8,2).":".
218 substr($queuing_time,10,2).":".
219 substr($queuing_time,12,2));
221 return($smarty->fetch(get_template_path('detail.tpl', TRUE)));
222 }
225 // Convert search filter into useable string
226 $fax_users= array();
227 $s = preg_replace("/\*/","",$this->search_for);
228 if(!empty($s)) $s = "*{$s}*"; else $s="*";
230 // Collect potential 'uid's that match the filter.
231 $filter= "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))".
232 "(objectClass=goFaxAccount)".
233 "(|(uid=$s)(l=$s)(homePhone=$s)".
234 "(telephoneNumber=$s)(facsimileTelephoneNumber=$s)(mobile=$s)".
235 "(pager=$s)(cn=$s)(givenName=$s)(sn=$s)(personalTitle=$s)".
236 "(title=$s)))";
237 $res = get_list($filter, "users/viewFaxEntries", $this->search_base, array("uid"), GL_SUBSEARCH );
238 $fax_users = array();
239 foreach($res as $attrs){
240 $fax_users[ $attrs['dn']]= $attrs["uid"][0];
241 }
243 // Search for entries mathcing the filter
244 $userfilter = "uid like '".preg_replace("/\*/","%%", $s)."' OR ";
245 $userfilter.= "sender_id like '".preg_replace("/\*/","%%", $s)."' OR ";
246 $userfilter.= "receiver_id like '".preg_replace("/\*/","%%", $s)."' OR ";
248 // ... and additionally search for a status value.
249 $id = array_search($this->search_for, $this->status);
250 if($id !== FALSE){
251 $userfilter.= "status = '".$id."' OR ";
252 }
254 // Add collectod users to the query
255 foreach ($fax_users as $user){
256 $userfilter.= "uid = '$user' OR ";
257 }
258 $userfilter= "(".preg_replace("/OR $/", "", $userfilter).")";
260 // Add date settings
261 $desc = ($this->sort_direction == "down")? "": "DESC";
262 $start= date ("YmdHis", mktime(0,0,0,$this->month,1,$this->year));
263 $end= date ("YmdHis", mktime(23,59,59,$this->month+1,0,$this->year));
264 $query_entries = "SELECT id,uid,date_format(queuing_time, '%Y%m%d%H%i%s') as queuing_time,".
265 "status,sender_id,receiver_id,pages FROM faxlog ".
266 "WHERE {$userfilter} AND queuing_time <= {$end} AND ".
267 "queuing_time >= {$start} ".
268 "ORDER BY ".$this->fields[$this->sort].
269 " {$desc } ";
272 $cfg= $this->config->data['SERVERS']['FAX'];
273 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
275 // Get the results
276 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
277 $result =@mysql_query($query_entries);
278 if ($result === false){
279 msg_dialog::display(_("Error"), sprintf(_("Cannot query %s database!"), "GOfax"), ERROR_DIALOG);
280 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
281 }
283 // Restricted attributes will not be displayed, this will be displayed instead */
284 $no_acl = image('images/lists/locked.png','',
285 _("Insufficient permissions to view this attribute"));
287 // Add found entries to result list.
288 $report_list= array();
289 $user_ids = array_flip($fax_users);
290 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
292 // Get dn to check ACLs for
293 // Existing ldap-user -> use its dn
294 // Not existing user -> use ldap base dn
295 $dn = $this->search_base;
296 if(isset($this->uidToDN[$line['uid']])){
297 $dn = $this->uidToDN[$line['uid']];
298 }
300 // We do not have any ACLs for this entry, so continue.
301 $tmp = $this->ui->get_permissions($dn,"users/viewFaxEntries","");
302 if(empty($tmp)) continue;
304 // Hide field for which we have no permissions
305 foreach(array("pages","receiverid","senderid","status","queuingtime","detailedView") as $attr){
306 $var = $attr."ACL";
307 $$var = $this->ui->get_permissions($dn,"users/viewFaxEntries",$attr);
308 }
310 // Create date
311 if((!empty($line["queuing_time"])) && preg_match("/r/",$queuingtimeACL)){
312 $hour= substr($line["queuing_time"], 8, 2);
313 $minute=substr($line["queuing_time"], 10, 2);
314 $format= _("Y-M-D");
315 $date= preg_replace("/Y/", substr($line["queuing_time"], 0, 4), $format);
316 $date= preg_replace("/M/", substr($line["queuing_time"], 4, 2), $date);
317 $date= preg_replace("/D/", substr($line["queuing_time"], 6, 2), $date);
318 $str_date = $date." ".$hour.":".$minute;
319 }else{
320 $str_date = $no_acl;
321 }
323 /* Create entry html str */
324 $str = " \n<td class='list0'>".$line["uid"]."</td>";
325 $str.= " \n<td class='list0'>".$str_date."</td>";
327 /* Add Status td */
328 if(preg_match("/r/",$statusACL)){
329 $str.=" \n<td class='list0'>".$this->status[$line["status"]]."</td>";
330 }else{
331 $str.=" \n<td class='list0'>".$no_acl."</td>";
332 }
334 /* Add sender_id td */
335 if(preg_match("/r/",$senderidACL)){
336 $str.=" \n<td class='list0'>".htmlentities($line["sender_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/",$receiveridACL)){
343 $str.=" \n<td class='list0'>".htmlentities($line["receiver_id"],ENT_COMPAT,'UTF-8')."</td>";
344 }else{
345 $str.=" \n<td class='list0'>".$no_acl."</td>";
346 }
348 /* Add receiver_id td */
349 if(preg_match("/r/",$pagesACL)){
350 $str.=" \n<td class='list0'>".$line["pages"]."</td>";
351 }else{
352 $str.=" \n<td class='list0'>".$no_acl."</td>";
353 }
354 /* Create entry html str */
355 if(preg_match("/r/",$detailedViewACL)){
356 $str.= " \n<td class='list0' style='border-right: 0pt none;'>".
357 image('images/info_small.png', 'detail_'.postEncode($line["id"]))."</td>";
358 }else{
359 $str.= " \n<td class='list0' style='border-right: 0pt none;'> </td>";
360 }
361 $report_list[] = $str;
362 }
363 mysql_close($link);
365 $entry_count = count($report_list);
366 if($this->start >=$entry_count) $this->start =0;
368 /* Generate output */
369 $mod= 0;
370 $output= "";
371 $report_list = array_slice($report_list, $this->start, $this->range);
372 foreach ($report_list as $val){
373 $output.= "\n<tr>{$val}</tr>";
374 }
375 $smarty->assign("search_result", $output);
376 $smarty->assign("range_selector",
377 range_selector($entry_count, $this->start, $this->range,"EntriesPerPage"));
379 // Add sorting links
380 $smarty->assign("plug", "?plug=".validate($_GET['plug']));
381 for($i= 0; $i<7; $i++){
382 $smarty->assign("mode$i", "");
383 }
384 $smarty->assign("mode".$this->sort, image("images/lists/sort-".$this->sort_direction.".png"));
385 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
386 }
389 // Save posted filter settings
390 function save_object()
391 {
392 $faxreportfilter = session::get("faxreportfilter");
393 if(isset($_POST['EntriesPerPage'])){
394 $this->range = get_post('EntriesPerPage');
395 }
397 if (isset($_GET['start'])){
398 $this->start= (int)$_GET['start'];
399 }
401 /* Adapt sorting */
402 if (isset($_GET['sort'])){
403 if ($this->sort == (int)$_GET['sort']){
404 if ($this->sort_direction == "down"){
405 $this->sort_direction= "up";
406 } else {
407 $this->sort_direction= "down";
408 }
409 }
410 $this->sort= (int)$_GET['sort'];
411 if ($this->sort < 0 || $this->sort > 5){
412 $this->sort= 0;
413 }
414 }
415 foreach( array("year", "month", "search_for") as $type){
416 if (isset($_POST[$type])){
417 $faxreportfilter[$type]= get_post($type);
419 /* reset start page, if filter has changed */
420 if(!isset($_GET['start'])){
421 $this->start = 0;
422 }
423 }
424 $this->$type= $faxreportfilter[$type];
426 }
427 foreach($this->attributes_SO as $name){
428 $faxreportfilter[$name] = $this->$name;
429 }
430 session::set("faxreportfilter",$faxreportfilter);
431 }
432 }
435 class viewFaxEntries extends plugin {
437 static function plInfo()
438 {
440 return (array(
441 "plShortName" => _("View FAX reports"),
442 "plDescription" => _("View FAX reports")." <i>"._("All entries are read-only")."</i>",
443 "plRequirements"=> array(
444 'activePlugin' => 'faxreport',
445 'ldapSchema' => array('goFaxAccount' => '>=1.0.4'),
446 'onFailureDisablePlugin' => array('faxreport','gofaxAccount','goFaxServer')
447 ),
448 "plSelfModify" => TRUE,
449 "plDepends" => array(),
450 "plPriority" => 89, // Position in tabs
451 "plSection" => array("administration"), // This belongs to personal
452 "plCategory" => array("users"),
453 "plOptions" => array(),
455 "plProvidedAcls" => array(
456 "detailedView" => _("Detailed view and download"),
457 "id" => _("Fax ID"),
458 "queuingtime" => _("Date")." / "._("Time"),
459 "status" => _("Status"),
460 "senderid" => _("Sender ID"),
461 "sendermsn" => _("Sender MSN"),
462 "receiverid" => _("Receiver ID"),
463 "receivermsn" => _("Receiver MSN"),
464 "pages" => _("Number of pages"),
465 "statusmessage" => _("Status Message"),
466 "transfertime" => _("Transfer time"))
467 ));
468 }
470 }
472 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
473 ?>