1 <?php
3 class fonreport extends plugin
4 {
5 /* Definitions */
6 var $plHeadline= "Phone Reports";
7 var $plDescription= "This does something";
8 var $plIcon = "plugins/gofon/images/phonereport.png";
10 /* For internal use */
11 var $start = 0;
12 var $search_for = "*";
13 var $search_base = "";
14 var $fields = array("calldate", "src", "dst", "channel", "lastapp", "disposition", "duration");
15 var $year = "";
16 var $month = "";
17 var $sort = 0;
18 var $sort_direction = "down";
19 var $report_list = array();
20 var $userfilter = "";
21 var $ui = NULL;
22 var $range = 20;
23 var $EntryPerPage = 20;
25 /* attribute list for save action */
26 var $attributes_SO = array("start","search_for","search_base","range","month","sort_direction","sort","year");
27 var $objectclasses = array();
28 var $view_logged = FALSE;
30 /* Construct class */
31 function fonreport (&$config, $ui)
32 {
33 /* Include config object */
34 $this->config = $config;
35 $this->ui = $ui;
36 $this->search_base= get_base_from_people($ui->dn);
38 $this->month = date("m");
39 $this->year = date("Y");
41 /* Use filter settings if we have already searched */
42 if (!session::is_set("fonfilter")){
43 $fonfilter = array();
44 foreach($this->attributes_SO as $name){
45 $fonfilter[$name]=$this->$name;
46 }
47 session::set("fonfilter", $fonfilter);
48 }else{
49 $fonfilter = session::get("fonfilter");
50 foreach($this->attributes_SO as $name){
51 $this->$name = $fonfilter[$name];
52 }
53 }
54 }
57 /* Save ui interactions and store results in session,
58 to remember settings */
59 function save_object()
60 {
61 $fonfilter= session::get("fonfilter");
62 if(isset($_POST['EntryPerPage'])){
63 $this->range = $_POST['EntryPerPage'];
64 }
65 if (isset($_GET['start'])){
66 $this->start= (int)$_GET['start'];
67 }
68 foreach( array("year", "month", "search_for", "search_base") as $type){
69 if (isset($_POST[$type])){
70 $this->$type= $_POST[$type];
71 }
72 }
74 /* Adapt sorting */
75 if (isset($_GET['sort'])){
76 if ($this->sort == (int)$_GET['sort']){
77 if ($this->sort_direction == "down"){
78 $this->sort_direction= "up";
79 } else {
80 $this->sort_direction= "down";
81 }
82 }
83 $this->sort= (int)$_GET['sort'];
84 if ($this->sort < 0 || $this->sort > 6){
85 $this->sort= 0;
86 }
87 }
89 /* remove unwanted tags */
90 $this->search_for = stripslashes(preg_replace("/[^0-9a-z\*\+ \-]/i","",$this->search_for));
92 foreach($this->attributes_SO as $name){
93 $fonfilter[$name] = $this->$name;
94 }
95 session::set("fonfilter", $fonfilter);
96 }
99 /* Search & display results */
100 function execute()
101 {
102 /* Call parent execute */
103 plugin::execute();
105 /* GVet template engine */
106 $smarty= get_smarty();
108 /* Log view */
109 if(!$this->view_logged){
110 $this->view_logged = TRUE;
111 new log("view","fonreport/".get_class($this),$this->dn);
112 }
114 /*****************
115 Variable Init
116 *****************/
118 $fields_str = "";
120 $months= array();
121 for($i = 1 ; $i <= 12 ; $i ++ ){
122 $months[$i] = _(date("F",gmmktime(0,0,0,$i)));
123 }
125 /* Prepare template */
126 $current= date("Y");
127 $years= array();
128 for ($y= $current - 5; $y<=$current; $y++){
129 $years[$y]= $y;
130 }
132 /*****************
133 Smarty
134 *****************/
135 $bases = array();
136 $cat_bases = $this->ui->get_module_departments("fonreport");
137 foreach($this->config->idepartments as $dn => $name){
138 if(in_array_ics($dn,$cat_bases)){
139 $bases[$dn] = $name;
140 }
141 }
143 if(!isset($bases[$this->search_base])){
144 $this->search_base = key($bases);
145 }
147 $smarty->assign("plug", "?plug=".validate($_GET['plug']));
148 $smarty->assign("launchimage", get_template_path('images/launch.png'));
149 $smarty->assign("search_image", get_template_path('images/lists/search.png'));
150 $smarty->assign("search_for", $this->search_for);
151 $smarty->assign("bases", $bases);
152 $smarty->assign("base_select", $this->search_base);
153 $smarty->assign("months", $months);
154 $smarty->assign("month_select", $this->month);
155 $smarty->assign("years", $years);
156 $smarty->assign("year_select", $this->year);
157 $smarty->assign("search_result", "");
160 /*****************
161 Check Database , Table , Connection
162 *****************/
164 /* Connecting, selecting database */
165 if (!isset($this->config->data['SERVERS']['FON'][0])){
166 msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
167 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
168 }elseif(!is_callable("mysql_connect")){
169 msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
170 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
171 }else{
173 $cfg= $this->config->data['SERVERS']['FON'][0];
174 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
175 if ($link === FALSE){
176 msg_dialog::display(_("Error"), msgPool::dbconnect(_("GOfon"),@mysql_error(),$cfg['SERVER']),ERROR_DIALOG);
177 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
178 }
179 if (! @mysql_select_db("gophone")){
180 msg_dialog::display(_("Error"), msgPool::dbselect(_("GOfon"),@mysql_error(),$cfg['DB']),ERROR_DIALOG);
181 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
182 }
183 }
186 /*****************
187 Get Query String && Search
188 *****************/
190 $query = $this->CreateQuerySyntax();
191 $cfg = $this->config->data['SERVERS']['FON'][0];
192 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
194 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
196 $result = @mysql_query($query);
197 if ($result === false){
198 msg_dialog::display(_("Error"), msgPool::dbquery(_("GOfon"),@mysql_error(),$cfg['SERVER']),ERROR_DIALOG);
199 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
200 }
202 /*****************
203 Fetch results
204 *****************/
206 $report_list= array();
208 /* Restricted attributes will not be displayed, this will be displayed instead */
209 $no_acl = "<img class='center' src='images/lists/locked.png'
210 title='".msgPool::permView()."' alt='"._("Insufficient permissions")."'>";
212 $no_acl = " ";
214 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
216 foreach($line as $attr => $value){
218 if($attr == "duration") continue;
220 $acl = $this->ui->get_permissions($this->search_base,"fonreport/fonreport",$attr);
221 if(!preg_match("/r/",$acl)){
222 $line[$attr] = $no_acl;
223 }
224 }
226 if($this->ui->get_permissions($this->search_base,"fonreport/fonreport","calldate")){
227 $hour= substr($line["calldate"], 11, 2);
228 $minute=substr($line["calldate"], 14, 2);
229 $format= _("Y-M-D");
230 $date= preg_replace("/Y/", substr($line["calldate"], 0, 4), $format);
231 $date= preg_replace("/M/", substr($line["calldate"], 5, 2), $date);
232 $date= preg_replace("/D/", substr($line["calldate"], 8, 2), $date);
233 $date_str = $date." ".$hour.":".$minute;
234 }else{
235 $date_str = $no_acl;
236 }
238 $append_str = "";
239 $append_str .= "<td>".$date_str."</td>";
241 foreach(array("src","dst","channel","lastapp","disposition") as $atr){
242 if(isset($line[$atr])){
243 $append_str .= "<td>".$line[$atr]."</td>";
244 }
245 }
247 if($this->ui->get_permissions($this->search_base,"fonreport/fonreport","duration")){
248 $append_str .= "<td>".$this->gen_duration($line["duration"])."</td>";
249 }else{
250 $append_str .= "<td>".$no_acl."</td>";
251 }
252 $report_list[] = $append_str;
253 }
255 $this->report_list= $report_list;
256 @mysql_close($link);
259 /*****************
260 Create list of results
261 *****************/
263 /* Generate output */
264 $mod = 0;
265 $output = "";
266 if(count($this->report_list) < $this->start){
267 $this->start = 0;
268 }
269 foreach($this->report_list as $val){
270 if ($mod < $this->start) {
271 $mod++;
272 continue;
273 }
274 if ($mod >= ($this->start + $this->range)){
275 $mod++;
276 break;
277 }
278 if ( ($mod++) & 1){
279 $col= "background-color: #ECECEC;";
280 } else {
281 $col= "background-color: #F5F5F5;";
282 }
283 $output.= "<tr style=\"height:22px; $col\">$val</tr>";
284 }
286 /*****************
287 Tell smarty what we have found
288 *****************/
290 if ($output != ""){
291 $smarty->assign("search_result", $output);
292 $smarty->assign("range_selector", range_selector(count($this->report_list), $this->start,$this->range,"EntryPerPage"));
293 } else {
294 $smarty->assign("search_result", "");
295 }
297 /* Show main page */
298 for($i= 0; $i<7; $i++){
299 $smarty->assign("mode$i", "");
300 }
301 $smarty->assign("mode".$this->sort, "<img alt=\"\" src=\"images/sort_".$this->sort_direction.".png\" border=0 align=middle>");
303 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
304 }
307 /* Create duration string 12'11" */
308 function gen_duration($seconds)
309 {
310 if ($seconds / 60 > 1){
311 $minutes= (int)($seconds / 60);
312 $seconds= $seconds % 60;
313 return ("$minutes’$seconds”");
314 }
315 return ("$seconds”");
316 }
319 /* Create WHERE part for our mysql serach */
320 function GetUidMatchingFilter()
321 {
322 $ldap = $this->config->get_ldap_link();
323 $ldap->cd ($this->search_base);
324 $s = $this->search_for;
326 $s = preg_replace("/\%/","",$s);
327 $s2 = preg_replace("/\*/","%",$s);
329 $filter = "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))".
330 "(|(uid=$s)(l=$s)(homePhone=$s)(telephoneNumber=$s)(facsimileTelephoneNumber=$s)(mobile=$s)".
331 "(pager=$s)(cn=$s)(givenName=$s)(sn=$s)(personalTitle=$s)(title=$s)))";
333 $attrs = array("uid");
334 $res = get_sub_list($filter,"users",get_people_ou(),$this->search_base,$attrs);
336 $str = " AND (";
337 $fields = array("dstchannel","channel");
338 if(count($res)){
339 foreach($res as $attrs){
340 $uid = $attrs["uid"][0];
341 foreach($fields as $name){
342 $str .= $name." like '%".$uid."%' OR ";
343 }
344 }
345 }
346 $str .= " channel like '%".$s."%' OR
347 dstchannel like '%".$s."%' OR
348 dst like '".$s2."' OR
349 src like '".$s2."' OR
350 lastapp like '".$s2."')";
351 return($str);
352 }
355 /* Create query string */
356 function CreateQuerySyntax()
357 {
358 /* Get extended search filter which contain uids and so on */
359 $uidstring = $this->GetUidMatchingFilter();
361 /* Create string with all fields seperated by ,*/
362 $fields_str ="";
363 foreach($this->fields as $field){
364 if($field == "calldate") {
365 continue;
366 }
367 $fields_str .= $field.", ";
368 }
369 $fields_str = preg_replace("/, $/","",$fields_str);
371 /* Create Sort tag */
372 if ($this->sort_direction == "down"){
373 $desc= "DESC";
374 } else {
375 $desc= "ASC";
376 }
377 /* Create times */
378 $start= date ("YmdHis", mktime(0,0,0,$this->month,1,$this->year));
379 $end= date ("YmdHis", mktime(23,59,59,($this->month +1),0,$this->year));
380 $query = "SELECT ".$fields_str.",calldate FROM cdr ".
381 "WHERE
382 calldate <= $end
383 AND
384 calldate >= $start
385 ". $uidstring."
386 ORDER BY ".$this->fields[$this->sort]." $desc;";
387 return($query);
388 }
391 /* Return plugin informations for acl handling
392 #FIXME You can only read attributes within this report plugin */
393 static function plInfo()
394 {
395 return (array(
396 "plShortName" => _("Phone reports"),
397 "plDescription" => _("Phone reports")." <i>"._("All entries are readonly")."</i>",
398 "plSelfModify" => TRUE,
399 "plDepends" => array(),
400 "plPriority" => 0,
401 "plSection" => array("administration"),
402 "plCategory" => array(
403 "fonreport" => array(
404 "description" => _("Phone reports"),
405 "objectClass" => "None")),
408 "plProvidedAcls" => array(
409 "calldate" =>_("Date"),
410 "src" =>_("Source"),
411 "dst" =>_("Destination"),
412 "channel" =>_("Channel"),
413 "lastapp" =>_("Application called"),
414 "disposition" =>_("Disposition"),
415 "duration" =>_("Duration"))
416 ));
417 }
418 }
419 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
420 ?>