1ed3ecfa7bfe78478fea8aa9920cf1dec1a384a2
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 var $selected_server = "";
27 /* attribute list for save action */
28 var $attributes_SO = array("start","search_for","search_base","range","month","sort_direction","sort","year");
29 var $objectclasses = array();
30 var $view_logged = FALSE;
32 /* Construct class */
33 function fonreport (&$config, $ui)
34 {
35 /* Include config object */
36 $this->config = $config;
37 $this->ui = $ui;
38 $this->search_base= get_base_from_people($ui->dn);
40 $this->month = date("m");
41 $this->year = date("Y");
43 /* Use filter settings if we have already searched */
44 if (!session::is_set("fonfilter")){
45 $fonfilter = array();
46 foreach($this->attributes_SO as $name){
47 $fonfilter[$name]=$this->$name;
48 }
49 session::set("fonfilter", $fonfilter);
50 }else{
51 $fonfilter = session::get("fonfilter");
52 foreach($this->attributes_SO as $name){
53 $this->$name = $fonfilter[$name];
54 }
55 }
56 }
59 /* Save ui interactions and store results in session,
60 to remember settings */
61 function save_object()
62 {
63 $fonfilter= session::get("fonfilter");
64 if(isset($_POST['EntryPerPage'])){
65 $this->range = $_POST['EntryPerPage'];
66 }
67 if (isset($_GET['start'])){
68 $this->start= (int)$_GET['start'];
69 }
70 foreach( array("year", "month", "search_for", "search_base","selected_server") as $type){
71 if (isset($_POST[$type])){
72 $this->$type= get_post($type);
73 }
74 }
76 /* Adapt sorting */
77 if (isset($_GET['sort'])){
78 if ($this->sort == (int)$_GET['sort']){
79 if ($this->sort_direction == "down"){
80 $this->sort_direction= "up";
81 } else {
82 $this->sort_direction= "down";
83 }
84 }
85 $this->sort= (int)$_GET['sort'];
86 if ($this->sort < 0 || $this->sort > 6){
87 $this->sort= 0;
88 }
89 }
91 /* remove unwanted tags */
92 $this->search_for = stripslashes(preg_replace("/[^0-9a-z\*\+ \-\/]/i","",$this->search_for));
94 foreach($this->attributes_SO as $name){
95 $fonfilter[$name] = $this->$name;
96 }
97 session::set("fonfilter", $fonfilter);
98 }
101 /* Search & display results */
102 function execute()
103 {
104 /* Call parent execute */
105 plugin::execute();
107 /* GVet template engine */
108 $smarty= get_smarty();
110 /* Log view */
111 if(!$this->view_logged){
112 $this->view_logged = TRUE;
113 new log("view","fonreport/".get_class($this),$this->dn);
114 }
116 /*****************
117 Variable Init
118 *****************/
120 $fields_str = "";
122 $months= array();
123 for($i = 1 ; $i <= 12 ; $i ++ ){
124 $months[$i] = _(date("F",gmmktime(0,0,0,$i)));
125 }
127 /* Prepare template */
128 $current= date("Y");
129 $years= array();
130 for ($y= $current - 5; $y<=$current; $y++){
131 $years[$y]= $y;
132 }
134 /*****************
135 Smarty
136 *****************/
137 $bases = array();
138 $cat_bases = $this->ui->get_module_departments("fonreport");
139 foreach($this->config->idepartments as $dn => $name){
140 if(in_array_ics($dn,$cat_bases)){
141 $bases[$dn] = $name;
142 }
143 }
145 if(!isset($bases[$this->search_base])){
146 $this->search_base = key($bases);
147 }
149 $smarty->assign("plug", "?plug=".validate($_GET['plug']));
150 $smarty->assign("launchimage", get_template_path('images/launch.png'));
151 $smarty->assign("search_image", get_template_path('images/lists/search.png'));
152 $smarty->assign("search_for", htmlentities($this->search_for));
153 $smarty->assign("bases", $bases);
154 $smarty->assign("base_select", $this->search_base);
155 $smarty->assign("months", $months);
156 $smarty->assign("month_select", $this->month);
157 $smarty->assign("years", $years);
158 $smarty->assign("year_select", $this->year);
159 $smarty->assign("search_result", "");
162 /*****************
163 Check Database , Table , Connection
164 *****************/
166 // Collect servers and allow to select the server in the ui.
167 $servers = array();
168 foreach($this->config->data['SERVERS']['FON'] as $key => $server){
169 $servers[$server['SERVER']] = $server['SERVER'];
170 }
171 $smarty->assign("servers", $servers);
172 $smarty->assign("selected_server", $this->selected_server);
174 /* Connecting, selecting database */
175 if (!isset($this->config->data['SERVERS']['FON'][0])){
176 msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
177 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
178 }elseif(!is_callable("mysql_connect")){
179 msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
180 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
181 }else{
183 // Get CFG for the selected server, if empty use first.
184 if($this->selected_server == ""){
185 $cfg= $this->config->data['SERVERS']['FON'][0];
186 }else{
187 foreach($this->config->data['SERVERS']['FON'] as $server){
188 if($server['SERVER'] == $this->selected_server){
189 $cfg = $server;
190 }
191 }
192 }
194 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
195 if ($link === FALSE){
196 msg_dialog::display(_("Error"), msgPool::dbconnect(_("GOfon"),@mysql_error(),$cfg['SERVER']),ERROR_DIALOG);
197 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
198 }
199 if (! @mysql_select_db("gophone")){
200 msg_dialog::display(_("Error"), msgPool::dbselect(_("GOfon"),@mysql_error(),$cfg['DB']),ERROR_DIALOG);
201 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
202 }
203 }
206 /*****************
207 Get Query String && Search
208 *****************/
210 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
212 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
214 // Get all matching entries to be able to fill the pager
215 $query = $this->CreateQuerySyntax($limit = FALSE);
216 $count = @mysql_query($query);
217 if ($count === false){
218 msg_dialog::display(_("Error"), msgPool::dbquery(_("GOfon"),@mysql_error(),$cfg['SERVER']),ERROR_DIALOG);
219 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
220 }
221 $tmp = mysql_fetch_array($count, MYSQL_ASSOC);
222 $res_count = $tmp['count'];
223 if($res_count < $this->start){
224 $this->start = 0;
225 }
227 // Get entries for the selected range only.
228 $query = $this->CreateQuerySyntax($limit = TRUE);
229 $result = @mysql_query($query);
230 if ($result === false){
231 msg_dialog::display(_("Error"), msgPool::dbquery(_("GOfon"),@mysql_error(),$cfg['SERVER']),ERROR_DIALOG);
232 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
233 }
235 /*****************
236 Fetch results
237 *****************/
239 $report_list= array();
241 /* Restricted attributes will not be displayed, this will be displayed instead */
242 $no_acl = "<img class='center' src='images/lists/locked.png'
243 title='".msgPool::permView()."' alt='"._("Insufficient permissions")."'>";
245 $no_acl = " ";
247 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
249 // Check attribute permissions
250 foreach($line as $attr => $value){
251 if($attr == "duration") continue;
252 $acl = $this->ui->get_permissions($this->search_base,"fonreport/fonreport",$attr);
253 if(!preg_match("/r/",$acl)){
254 $line[$attr] = $no_acl;
255 }
256 }
258 // Check date permissions
259 if($this->ui->get_permissions($this->search_base,"fonreport/fonreport","calldate")){
260 $hour= substr($line["calldate"], 11, 2);
261 $minute=substr($line["calldate"], 14, 2);
262 $format= _("Y-M-D");
263 $date= preg_replace("/Y/", substr($line["calldate"], 0, 4), $format);
264 $date= preg_replace("/M/", substr($line["calldate"], 5, 2), $date);
265 $date= preg_replace("/D/", substr($line["calldate"], 8, 2), $date);
266 $date_str = $date." ".$hour.":".$minute;
267 }else{
268 $date_str = $no_acl;
269 }
271 $append_str = "<td class='list1'>".$date_str."</td>";
272 foreach(array("src","dst","channel","lastapp","disposition") as $atr){
273 if(isset($line[$atr])){
274 $append_str .= "<td class='list1'>".$line[$atr]."</td>";
275 }
276 }
277 if($this->ui->get_permissions($this->search_base,"fonreport/fonreport","duration")){
278 $append_str .= "<td class='list1'>".$this->gen_duration($line["duration"])."</td>";
279 }else{
280 $append_str .= "<td class='list1'>".$no_acl."</td>";
281 }
282 $report_list[] = $append_str;
283 }
285 $this->report_list= $report_list;
286 @mysql_close($link);
289 /*****************
290 Create list of results
291 *****************/
293 /* Generate output */
294 $mod = 0;
295 $output = "";
296 foreach($this->report_list as $val){
297 $output.= "<tr>$val</tr>";
298 }
300 /*****************
301 Tell smarty what we have found
302 *****************/
304 if ($output != ""){
305 $smarty->assign("search_result", $output);
306 $smarty->assign("range_selector", range_selector($res_count, $this->start,$this->range,"EntryPerPage"));
307 } else {
308 $smarty->assign("search_result", "");
309 }
311 /* Show main page */
312 for($i= 0; $i<7; $i++){
313 $smarty->assign("mode$i", "");
314 }
315 $smarty->assign("mode".$this->sort, "<img alt=\"\" src=\"images/sort_".$this->sort_direction.".png\" border=0 align=middle>");
317 return($smarty->fetch(get_template_path('contents.tpl', TRUE)));
318 }
321 /* Create duration string 12'11" */
322 function gen_duration($seconds)
323 {
324 if ($seconds / 60 > 1){
325 $minutes= (int)($seconds / 60);
326 $seconds= $seconds % 60;
327 return ("$minutes’$seconds”");
328 }
329 return ("$seconds”");
330 }
333 /* Create WHERE part for our mysql serach */
334 function GetUidMatchingFilter()
335 {
336 $ldap = $this->config->get_ldap_link();
337 $ldap->cd ($this->search_base);
338 $s = $this->search_for;
340 $s = preg_replace("/\%/","",$s);
341 $s2 = preg_replace("/\*/","%",$s);
343 $filter = "(&(objectClass=gosaAccount)(!(objectClass=gosaUserTemplate))".
344 "(|(uid=$s)(l=$s)(homePhone=$s)(telephoneNumber=$s)(facsimileTelephoneNumber=$s)(mobile=$s)".
345 "(pager=$s)(cn=$s)(givenName=$s)(sn=$s)(personalTitle=$s)(title=$s)))";
347 $attrs = array("uid");
348 $res = get_sub_list($filter,"fonreport/fonreport",get_people_ou(),$this->search_base,$attrs);
350 $str = " AND (";
351 $fields = array("dstchannel","channel");
352 if(count($res)){
353 foreach($res as $attrs){
354 $uid = $attrs["uid"][0];
355 foreach($fields as $name){
356 $str .= $name." like '%".$uid."%' OR ";
357 }
358 }
359 }
360 $str .= " channel like '%".$s."%' OR
361 dstchannel like '%".$s."%' OR
362 dst like '".$s2."' OR
363 src like '".$s2."' OR
364 lastapp like '".$s2."')";
365 return($str);
366 }
369 /* Create query string */
370 function CreateQuerySyntax($limit = TRUE)
371 {
372 /* Get extended search filter which contain uids and so on */
373 $uidstring = $this->GetUidMatchingFilter();
375 /* Create string with all fields seperated by ,*/
376 $fields_str ="";
377 foreach($this->fields as $field){
378 if($field == "calldate") {
379 continue;
380 }
381 $fields_str .= $field.", ";
382 }
383 $fields_str = preg_replace("/, $/","",$fields_str);
385 /* Create Sort tag */
386 if ($this->sort_direction == "down"){
387 $desc= "DESC";
388 } else {
389 $desc= "ASC";
390 }
391 /* Create times */
392 $start= date ("YmdHis", mktime(0,0,0,$this->month,1,$this->year));
393 $end= date ("YmdHis", mktime(23,59,59,($this->month +1),0,$this->year));
395 if(!$limit){
396 $fieldset = "count(dst) as `count`";
397 }else{
399 /* Create string with all fields seperated by ,*/
400 $fields_str ="";
401 foreach($this->fields as $field){
402 if($field == "calldate") continue;
403 $fields_str .= $field.", ";
404 }
405 $fields_str = preg_replace("/, $/","",$fields_str);
406 $fieldset = $fields_str.",calldate";
407 }
409 $query = "SELECT {$fieldset} FROM cdr ".
410 "WHERE
411 calldate <= $end
412 AND
413 calldate >= $start
414 ". $uidstring."
415 ORDER BY ".$this->fields[$this->sort]." $desc";
417 // Set limitations
418 if($limit){
419 $query.=" LIMIT ".($this->start).", ".$this->range;
420 }
421 $query.=";";
422 return($query);
423 }
426 /* Return plugin informations for acl handling
427 #FIXME You can only read attributes within this report plugin */
428 static function plInfo()
429 {
430 return (array(
431 "plShortName" => _("Phone reports"),
432 "plDescription" => _("Phone reports")." <i>"._("All entries are readonly")."</i>",
433 "plSelfModify" => TRUE,
434 "plDepends" => array(),
435 "plPriority" => 0,
436 "plSection" => array("administration"),
437 "plCategory" => array(
438 "fonreport" => array(
439 "description" => _("Phone reports"),
440 "objectClass" => "None")),
443 "plProvidedAcls" => array(
444 "calldate" =>_("Date"),
445 "src" =>_("Source"),
446 "dst" =>_("Destination"),
447 "channel" =>_("Channel"),
448 "lastapp" =>_("Application called"),
449 "disposition" =>_("Disposition"),
450 "duration" =>_("Duration"))
451 ));
452 }
453 }
454 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
455 ?>