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