Ticket #3291: retrieve_op_conf_from_mysql.4.php

File retrieve_op_conf_from_mysql.4.php, 24.0 kB (added by Nick_Lewis, 2 years ago)
Line 
1 #!/usr/bin/php
2 <?php
3
4 # Retrieves the sip user/peer entries from the database for the flash operator panel
5
6 //include("/var/www/html/admin/functions.inc.php");
7 //include("DB.php");
8 require_once("/var/www/html/admin/functions.inc.php");
9 require_once("DB.php");
10
11 ################### BEGIN OF CONFIGURATION ####################
12
13 global $zapataconfdir;
14 $zapataconfdir = "/etc/asterisk/";
15 $amportalconf = "/etc/amportal.conf";
16 $zapataconf = "zapata.conf";
17
18 if ($argc == 2)
19 {
20   $amportalconf = $argv[0];
21   $zapataconfdir = $argv[1]."/";
22 }
23
24 $zapataconf = $zapataconfdir . $zapataconf;
25
26 ######## LAYOUT INFO #########
27
28 # NOTE - These values may be overwritten by values in a table in the freepbx database named "panel"
29 # NOTE = Currently only one layout is supported. This layout is applied to all panel contexts (amp users).
30 # TODO - add support in this code and in "panel" database for a layout for each panel context (amp user)
31
32 # structure is - ID, Legend, startpos, stoppos, color1, color2
33 $rectangle1 = array("trunk","Trunks", 53, 80, "10ff10", "009900");
34 $rectangle2 = array("extension","Extensions", 1, 40, "1010ff", "99cccc");
35 $rectangle3 = array("parking","Parking lots", 49, 72, "ffff10", "cc9933");
36 $rectangle4 = array("conference","Conferences", 45, 68, "006666", "00a010");
37 $rectangle5 = array("queue","Queues", 41, 64, "ff1010", "a01000");
38 $rectangles = array($rectangle1,$rectangle2,$rectangle3,$rectangle4,$rectangle5);
39
40 $rectmarginx = 1;
41 $rectmarginy = 1;
42 $legendoffsetx = 3;
43 $legendoffsety = 1;
44
45 # $layoutbuttonsonly = 0 : allow display of buttons even if no corresponding layout info
46 # $layoutbuttonsonly = 1 : suppress display of buttons if no corresponding layout info
47 $layoutbuttonsonly = 1;
48
49 ######## BUTTON INFO #########
50 $buttonsizex = 246; # 1+244+1 from information in op_style.cfg
51 $buttonsizey = 28; # 1+26+1 from information in op_style.cfg
52 $numbuttonsx = 4;
53 $numbuttonsy = 20;
54 $buttonsoriginx = -1;
55 $buttonsoriginy = 32;
56
57
58 ######## STYLE INFO #########
59
60 # NOTE - These values may be overwritten by the syleinfo function with values generated from the layout info
61
62 $extenpos="2-40";
63 $trunkpos="53-60,72-80";
64 $parkingpos="50-51,69-71";
65 $confepos="46-48,65-68";
66 $queuepos="42-44,61-64";
67
68
69
70 # Remove or add Zap trunks as needed
71 # Note: ZAP/* will match any ZAP channel that *is not referenced* in another button (ie: extensions)
72 $zaplines=array(); # zap channel, description
73 #array_push($zaplines,array( "Zap/*","PSTN" ));
74 #array_push($zaplines,array( "Zap/1","Zap 1" ));
75 #array_push($zaplines,array( "Zap/2","Zap 2" ));
76 #array_push($zaplines,array( "Zap/3","Zap 3" ));
77 #array_push($zaplines,array( "Zap/4","Zap 4" ));
78
79 if (file_exists($zapataconf)) {
80   parse_zapata($zaplines,$zapataconf);
81 }
82 // Now no need to parse other files as include declarations are followed
83 //if (file_exists($zapataautoconf)) {
84 //  parse_zapata($zaplines,$zapataautoconf);
85 //}
86
87 function parse_zapata(&$zaplines,$conffile) {
88   # LETS PARSE zapata.conf
89   # Allowed format options
90   # %c Zap Channel number
91   # %n Line number
92   # %N Line number, but restart counter
93   # Example:
94   # ;AMPLABEL:Channel %c - Button %n
95
96   global $zapataconfdir;
97   //global $zaplines; passed by reference instead
98   global $ampwildcard;
99   global $zaplabel;
100   global $istrunk;
101   global $lastlabelnum;
102
103   if (!isset($ampwildcard)) {$ampwildcard=0;}
104   if (!isset($zaplabel)) {$zaplabel="Zap %c";}
105   if (!isset($istrunk)) {$istrunk=0;}
106   if (!isset($lastlabelnum)) {$lastlabelnum=0;}
107
108   @$filearray = file($conffile);
109   if ($filearray === false) {die("Cannot open config file: $conffile\n");}
110   foreach ($filearray as $line) {
111     $line = trim($line);
112     if ($line == '') {continue;} //was next in perl version
113
114     $temparray = @explode(";AMPWILDCARDLABEL(",$line,2);
115     if (count($temparray) == 2) {
116       $temparray = @explode("):",$temparray[1],2);
117       if (count($temparray) != 2)  {continue;}
118       array_push($zaplines,array("Zap/*",trim($temparray[1]),($temparray[0])));
119       $ampwildcard=1;
120       continue;
121     }
122
123     $temparray = @explode(";AMPLABEL:",$line,2);
124     if (count($temparray) == 2) {
125       $zaplabel=trim($temparray[1]);
126       $ampwildcard=0;
127       if (strpos($temparray[1],"%N") === false) {continue;}
128       $lastlabelnum=0;
129       continue;
130     }
131
132     # remove comments
133     list($line,$comment) = explode(";",$line,2);
134         $line = trim($line);
135     if ($line == "") {continue;}
136
137     #normalize whitespace
138     $line = str_replace("\t"," ",$line);
139     $line = preg_replace("/(\040)+/", " ", $line);
140
141         # check if an include declaration
142     @list($command,$include) = explode("#include ",$line,2);
143     if (isset($include))  {
144       parse_zapata(&$zaplines,$zapataconfdir.trim($include));
145       continue;
146         }
147
148     #normalize assignment operator
149     $line = str_replace("=>","=",$line);
150     $line = str_replace(" ","",$line);
151
152     //echo "Debug: " . $line . "\n";
153
154         # check if trunk or extension
155         //note that some versions of php do not support !== but only ===
156         if (!(strpos($line,"context=from-pstn") === false)) {
157           $istrunk=1;
158           continue;
159         }
160         if (!(strpos($line,"context=from-zaptel") === false)) {
161           $istrunk=1;
162           continue;
163         }
164         if (!(strpos($line,"context=from-internal") === false)) {
165           $istrunk=0;
166           continue;
167         }
168
169
170     $temparray = @explode("channel=",$line,2);
171     if ((count($temparray) == 2) and ($ampwildcard == 0))  {
172       $temparray = @explode(",",$temparray[1],2);
173       foreach ($temparray as $range) {
174         list($start,$end) = @explode("-",$range,2);
175         $start = intval($start); //crudely maps non-integers to zero
176         if (!isset($end)) {$end = $start;}
177         for ($i = $start; $i <= $end; $i++) {
178           $lastlabelnum++;
179           $newlabel=$zaplabel;
180           $newlabel=str_replace("%c",$i,$newlabel);
181           $newlabel=str_replace("%n",$lastlabelnum,$newlabel);
182           $newlabel=str_replace("%N",$lastlabelnum,$newlabel);
183
184           # only add if A) this is a trunk
185           # and B) we have not already defined any zaplines at the top of the file
186           # (I use this to customize it so instead of saying "Zap 1" it will
187           # say something more useful -- like the phone # of the line)
188
189           if($istrunk == 1) {
190             $inzaplines=false;
191             foreach ($zaplines as $tempvalue) {
192               if($tempvalue[0] == "Zap/$i") {
193                 $inzaplines=true;
194                 break;
195               }
196             }
197             if (!($inzaplines)) {
198               array_push($zaplines,array( "Zap/$i","$newlabel" ));
199             }
200           } //istrunk
201         } //for $i
202       } //foreach $range
203     } // if "channel="
204   } //foreach $line
205   return $zaplines;
206 }
207 #Finished parsing zapata.conf
208
209
210 # Conference Rooms not yet implemented in AMP config
211 $conferences=array();   #### ext#, description
212 #array_push($conferences,array( "810","Conf.10" ));
213 #array_push($conferences,array( "811","Conf.11" ));
214
215 # cool hack by Julien BLACHE <jblache@debian.org>
216 $ampconf = parse_amportal_conf( $amportalconf );
217 # WARNING: this file will be substituted by the output of this program
218 $op_conf = $ampconf["AMPWEBROOT"]."/panel/op_buttons_additional.cfg";
219 # username to connect to the database
220 $username = $ampconf["AMPDBUSER"];
221 # password to connect to the database
222 $password = $ampconf["AMPDBPASS"];
223 # the name of the box the MySQL database is running on
224 $hostname = $ampconf["AMPDBHOST"];
225 # the name of the database our tables are kept
226 $database = $ampconf["AMPDBNAME"];
227 #sort option: extension or lastname
228 $sortoption = $ampconf["FOPSORT"];
229
230 # the engine to be used for the SQL queries,
231 # if none supplied, backfall to mysql
232 $db_engine = "mysql";
233 if (isset($ampconf["AMPDBENGINE"])){
234   $db_engine = $ampconf["AMPDBENGINE"];
235 }
236 ################### END OF CONFIGURATION #######################
237
238 $warning_banner =
239 "; do not edit this file, this is an auto-generated file by freepbx
240 ; all modifications must be done from the web gui
241 ";
242
243 switch ($db_engine)
244 {
245         case "pgsql":
246         case "mysql":
247                 /* datasource in in this style:
248                 dbengine://username:password@host/database */
249
250                 $datasource = $db_engine.'://'.$username.':'.$password.'@'.$hostname.'/'.$database;
251                 $db = DB::connect($datasource); // attempt connection
252                 break;
253
254         case "sqlite":
255                 require_once('DB/sqlite.php');
256
257                 if (!isset($amp_conf["AMPDBFILE"]))
258                         die("You must setup properly AMPDBFILE in /etc/amportal.conf");
259
260                 if (isset($amp_conf["AMPDBFILE"]) == "")
261                         die("AMPDBFILE in /etc/amportal.conf cannot be blank");
262
263                 $DSN = array (
264                         "database" => $amp_conf["AMPDBFILE"],
265                         "mode" => 0666
266                 );
267
268                 $db = new DB_sqlite();
269                 $db->connect( $DSN );
270                 break;
271
272         default:
273                 die( "Unknown SQL engine: [$db_engine]");
274 }
275
276 if(DB::isError($db)) {
277        echo("FAILED\n");
278        echo("Cannot connect to database\n");
279      die($db->getMessage());
280
281 }
282
283 # Get layout-info from a "panel" table in the freepbx database
284 if (table_exists($db,"panel")) {
285
286   $statement = "SELECT id, legend, startpos, stoppos, color1, color2 from panel";
287   $results = $db->getAll($statement);
288   if(DB::IsError($results)) {
289      die($results->getMessage());
290   }
291   if (count($results) < 1) {
292     print "Notice: no panel defined\n";
293   }
294   $rectangles = $results;
295 }
296
297 // pass layout info to function explicitly rather than via globals
298 $layoutinfo = array('rectangles'=>$rectangles,'numbuttonsx'=>$numbuttonsx,'numbuttonsy'=>$numbuttonsy);
299
300 # Automated generation of style-info from layout-info
301 $autoextenpos=get_styleinfo("extension",$layoutinfo);
302 $autotrunkpos=get_styleinfo("trunk",$layoutinfo);
303 $autoparkingpos=get_styleinfo("parking",$layoutinfo);
304 $autoconfepos=get_styleinfo("conference",$layoutinfo);
305 $autoqueuepos=get_styleinfo("queue",$layoutinfo);
306
307 if ($layoutbuttonsonly == 1) {$extenpos = ""; $trunkpos = ""; $parkingpos = ""; $confepos = ""; $queuepos = "";}
308
309 if (isset($autoextenpos)) {$extenpos = $autoextenpos;}
310 if (isset($autotrunkpos)) {$trunkpos = $autotrunkpos;}
311 if (isset($autoparkingpos)) {$parkingpos = $autoparkingpos;}
312 if (isset($autoconfepos)) {$confepos = $autoconfepos;}
313 if (isset($autoqueuepos)) {$queuepos = $autoqueuepos;}
314
315
316 $fhandle = fopen($op_conf,"w" );
317 if ($fhandle === false) {die("Cannot create/overwrite config file: $op_conf \n");}
318 fwrite($fhandle, $warning_banner);
319
320 #First, populate extensions
321
322 $extensionlist=array();
323
324 if (table_exists($db,"devices")) {
325   $statement = "SELECT description,id,dial,tech from devices";
326   $results = $db->getAll($statement);
327   if(DB::IsError($results)) {
328      die($results->getMessage());
329   }
330   if (count($results) < 1) {
331     print "Notice: no Devices defined\n";
332   }
333   $extensionlist = $results;
334 }
335 else { print "Table does not exist: devices\n"; }
336
337 # sort the extensions
338 foreach ($extensionlist as $key=>$extension) {
339   $temparray = explode(" ",$extension[0]);
340   $lastname[$key] = end($temparray);
341   $extnum[$key] = $extension[1];
342 }
343
344 if  (isset($sortoption) && ($sortoption == "lastname")) {
345   array_multisort($lastname,$extensionlist);
346 } else {
347   array_multisort($extnum,SORT_STRING,$extensionlist);
348 }
349
350 #Next, populate queues
351 $queues=array();
352 if (table_exists($db,"queues_config")) {
353   $statement = "SELECT extension,descr from queues_config order by extension";
354   $results = $db->getAll($statement);
355   if(DB::IsError($results)) {
356      die($results->getMessage());
357   }
358   if (count($results) < 1) {
359     print "Notice: no Queues defined\n";
360   }
361   $queues = $results;
362 }
363 else { print "Table does not exist: queues_config\n"; }
364
365
366 ## SME server chnges
367
368 #Next, populate conferences
369 $conferences=array();
370 if(table_exists($db,"meetme")) {
371   $statement = "SELECT exten,description FROM meetme ORDER BY exten";
372   $results = $db->getAll($statement);
373   if(DB::IsError($results)) {
374      die($results->getMessage());
375   }
376   if (count($results) < 1) {
377     print "Notice: no Conferences defined\n";
378   }
379   $conferences = $results;
380 }
381 else { print "Table does not exist: meetme\n"; }
382
383
384 #Next, populate parkings
385 $parkings=array();
386 if(table_exists($db,"parkinglot")) {
387   $statement = "SELECT keyword,data FROM parkinglot";
388   $results = $db->getAll($statement);
389   if(DB::IsError($results)) {
390      die($results->getMessage());
391   }
392   if (count($results) < 1) {
393     print "Notice: no Parking Lots defined\n";
394   }
395   $parkings = $results;
396 }
397 else { print "Table does not exist: parkinglot\n"; }
398
399 ## End of changes
400 #Next, populate trunks (sip and iax)
401 $trunklist=array();
402 $tables = array("sip","iax");
403 foreach ($tables as $table) {
404   if (table_exists($db,$table)) {
405     $statement = "SELECT data,id,'$table' from $table where keyword='account' and flags <> 1 and id>99990 group by data order by id";
406     $results = $db->getAll($statement);
407     if(DB::IsError($results)) {
408        die($results->getMessage());
409     }
410     if (count($results) < 1) {
411       print "Notice: no $table trunks defined\n";
412     }
413     $trunklist = array_merge($trunklist,$results);
414 }
415 else { print "Table does not exist: $table \n"; }
416 }
417
418 #Determine AMP Users
419 $ampusers=array();
420 if (table_exists($db,"ampusers")) {
421   $statement = 'SELECT deptname,extension_low,extension_high from ampusers WHERE NOT extension_low = "" AND NOT extension_high = ""';
422     $results = $db->getAll($statement);
423     if(DB::IsError($results)) {
424        die($results->getMessage());
425     }
426     if (count($results) < 1) {
427       print "Notice: no AMP Users defined\n";
428     }
429     else {
430       $ampusers = $results;
431     }
432 }
433 else { print "Table does not exist: ampusers\n"; }
434 array_push($ampusers,array("default","0","0")); //add a default panelcontext that can see all extensions
435
436 #Write a separate panel context from each AMP User department
437 foreach ($ampusers as $pcontext) {
438   $exten_low = $pcontext[1];
439   $exten_high = $pcontext[2];
440   $panelcontext = $pcontext[0];
441   if ($panelcontext == "") { $panelcontext = $exten_low."to".$exten_high; }
442
443 fwrite($fhandle, "\n\n; Panel Context: " . $panelcontext . "\n");
444
445   # WRITE EXTENSIONS
446
447   $btn=0;
448   if ($exten_low != 0 && $exten_high != 0) {  #display only allowed range of extensions for panel_contexts
449     $extensionrange = array();
450     foreach ($extensionlist as $value) {
451       if (!is_numeric($value[1])) {array_push($extensionrange,$value);}
452       if (($value[1] >= $exten_low) && ($value[1] <= $exten_high))  {array_push($extensionrange,$value);}
453     }
454   } else {
455     $extensionrange = $extensionlist;
456   }
457
458   foreach ( $extensionrange as $row ) {
459     $description = $row[0];
460     $id = $row[1];
461     $dial = $row[2];
462
463
464     # Support for real mailbox settings -
465     $tech = $row[3];
466     # some sensible defaults for voicemail ext and context
467     $vmext = $row[1];
468     $vmcontext = "default";
469     # the device tech table should also have a dial context - if not assume from-internal
470     $context = "from-internal";
471     # database table name for iax2 is just iax but sip and zap are ok
472     if ($tech == "iax2") {$tech = "iax";}
473     # get mailbox setting from relevant tech table and split into ext and content
474     if (table_exists($db,$tech)) {
475       $statement = "SELECT data from $tech WHERE id = '$id' AND keyword = 'mailbox' ";
476       $results = $db->getAll($statement);
477       if(DB::IsError($results)) {
478          die($results->getMessage());
479       }
480       if (count($results) < 1) {
481         print "Notice: no Mailboxes defined\n";
482       }
483       else {
484       $mailbox = $results[0][0];
485       $values = @explode('@', $mailbox,2);
486       if (strlen($values[0]) > 0) {$vmext = $values[0];}
487       if (strlen($values[1]) > 0) {$vmcontext = $values[1];}
488       }
489       #while in this table lets get the dial context as well
490       $statement = "SELECT data from $tech WHERE id = '$id' AND keyword = 'context' ";
491       $results = $db->getAll($statement);
492       if(DB::IsError($results)) {
493          die($results->getMessage());
494       }
495       if (count($results) < 1) {
496         print "Notice: no Context defined\n";
497       }
498       else {
499       $context = $results[0][0];
500       }
501     } else { print "Table does not exist: $tech\n"; }
502     # - Support for real mailbox settings
503
504
505     # Support for real VM_PREFIX -
506     $vmprefix = "*";
507     if (table_exists($db,"globals")) {
508       $statement = "SELECT value from globals WHERE variable = 'VM_PREFIX' ";
509       $results = $db->getAll($statement);
510       if(DB::IsError($results)) {
511          die($results->getMessage());
512       }
513       if (count($results) < 1) {
514         print "Notice: no VM Prefix defined\n";
515       }
516       else {
517       $vmprefix = $results[0][0];
518       }
519     } else { print "Table does not exist: global\n"; }
520     # - Support for real VM_PREFIX
521
522     $btn=get_next_btn($extenpos,$btn);
523     $icon='4';
524     fwrite($fhandle, "\n[$dial]\nPosition=$btn\nLabel=\"$id : $description\"\nExtension=$id\nContext=$context\nIcon=$icon\nVoicemail_Context=$vmcontext\nVoiceMailExt=$vmprefix$vmext@$context\nPanel_Context=$panelcontext\n");
525   }
526
527
528   ### NOW WRITE TRUNKS.. WE START WITH ZAP TRUNKS DEFINED ABOVE
529
530
531
532
533   $btn=0;
534
535   foreach ($zaplines as $row) {
536     $zapdef=$row[0];
537     $zapdesc=$row[1];
538     $icon='3';
539     # zaplines and trunklist share the trunk positions so need to store previous btn on overflow from zaplines
540     $previousbtn = $btn;
541     $btn=get_next_btn($trunkpos,$btn);
542     if ($btn == 0) {$btn = $previousbtn; last;}
543     if ($zapdef == "Zap/*") {
544       $numbuttons=$row[2]-1;
545       fwrite($fhandle, "\n[$zapdef]\nLabel=\"$zapdesc\"\nExtension=-1\nIcon=$icon\nPanel_Context=$panelcontext\nPosition=".$btn);
546       while($numbuttons-->0) {
547         $btn=get_next_btn($trunkpos,$btn);
548         fwrite($fhandle, ",".$btn);
549       }
550
551       fwrite($fhandle, "\n");
552     } else {
553       fwrite($fhandle, "\n[$zapdef]\nPosition=$btn\nLabel=\"$zapdesc\"\nExtension=-1\nIcon=$icon\nPanel_Context=$panelcontext\n");
554     }
555   }
556
557
558   foreach ($trunklist as $row) {
559     $account = $row[0];
560     $id = $row[1];
561     $table = $row[2];
562     if ($account == "") {continue;};
563     $btn=get_next_btn($trunkpos,$btn);
564     if ($btn == 0) {last;}
565     if (table_exists($db,$table)) {
566     $statement = "SELECT keyword,data from $table where id=$id and keyword <> 'account' and flags <> 1 order by keyword";
567       $results = $db->getAll($statement);
568       if(DB::IsError($results)) {
569          die($results->getMessage());
570       }
571       if (count($results) < 1) {
572         print "Notice: no Trunks defined\n";
573       }
574     } else { print "Table does not exist: $table \n"; }
575
576     if ($table == "sip") {$tech="SIP";}
577     if ($table == "iax") {$tech="IAX2";}
578     #if ($table == "zap") {$tech="ZAP";} #no zap trunks in db
579
580     $callerid = $account;  #default callerid to account
581
582     foreach ($results as $drow) {
583       if ( $drow[0] == "callerid" ) {
584         $callerid = $drow[1];
585         $fields = explode("<",$callerid);
586         $callerid=$fields[1] ." ". $fields[0];
587         $callerid = str_replace("\t","",$callerid);
588         $callerid = str_replace("\"","",$callerid);
589         $callerid = str_replace("<","",$callerid);
590         $callerid = str_replace(">","",$callerid);
591       }
592     }
593     $icon='3';
594     fwrite($fhandle, "\n[$tech/$account]\nPosition=$btn\nLabel=\"$callerid\"\nExtension=-1\nIcon=$icon\nPanel_Context=$panelcontext\n");
595   }
596
597
598   ## SME server changes
599
600
601
602         ### Write Parkings lots
603   $btn=0;
604   $parken="" ;
605   $extpark ;
606   $parkcontext ;
607   $numberlots ;
608   $maxparkingslots ;
609
610   foreach ($parkings as $row) {
611     if ($row[0] == "parkingenabled") {
612       $parken = $row[1] ;
613     }
614     if ($row[0] == "parkext") {
615       $extpark = $row[1] ;
616     }
617     if ($row[0] == "parkingcontext") {
618       $parkcontext = $row[1] ;
619     }
620     if ($row[0] == "numslots") {
621       $numberlots = $row[1] ;
622     }
623   }
624   if ($parken == "s") {
625     for ($i = 1 ; $i <= $numberlots ; $i++ ) {
626       $btn=get_next_btn($parkingpos,$btn);
627       if ($btn == 0) {last;}
628       $parknum = $extpark + $i ;
629       $icon='1';
630       fwrite($fhandle, "\n[PARK$parknum]\nPosition=$btn\nLabel=\"Parked ($parknum)\"\nExtension=$parknum\nContext=$parkcontext\nIcon=$icon\nPanel_Context=$panelcontext\n");
631     }
632   }
633
634   ## End of chagnes
635   ### Write conferences (meetme)
636
637   $btn=0;
638   if ($exten_low != 0 && $exten_high != 0) {  #display only allowed range of extensions for panel_contexts
639     $confrange = array();
640     foreach ($conferences as $value) {
641       if (!is_numeric($value)) {array_push($confrange,$value);}
642       if (($value >= $exten_low) && ($value <= $exten_high))  {array_push($confrange,$value);}
643     }
644   } else {
645     $confrange = $conferences;
646   }
647   foreach ($confrange as $row) {
648     $btn=get_next_btn($confepos,$btn);
649     if ($btn == 0) {last;}
650     $confenum=$row[0];
651     $confedesc=$row[1];
652     $icon='6';
653     fwrite($fhandle, "\n[$confenum]\nPosition=$btn\nLabel=\"$confedesc\"\nExtension=$confenum\nContext=from-internal\nIcon=$icon\nPanel_Context=$panelcontext\n");
654   }
655
656   ### Write Queues
657
658   $btn=0;
659   if ($exten_low != 0 && $exten_high != 0) {  #display only allowed range of extensions for panel_contexts
660     $queuerange = array();
661     foreach ($queues as $value) {
662       if (!is_numeric($value)) {array_push($queuerange,$value);}
663       if (($value >= $exten_low) && ($value <= $exten_high))  {array_push($queuerange,$value);}
664     }
665   } else {
666     $queuerange = $queues;
667   }
668   foreach ($queuerange as $row) {
669     $btn=get_next_btn($queuepos,$btn);
670     if ($btn == 0) {last;}
671     $queuename=$row[0];
672     $queuedesc=$row[1];
673     $icon='5';
674     fwrite($fhandle, "\n[QUEUE/$queuename]\nPosition=$btn\nLabel=\"$queuedesc\"\nExtension=-1\nContext=from-internal\nIcon=$icon\nPanel_Context=$panelcontext\n");
675   }
676
677   ### Write rectangles
678
679   foreach ($rectangles as $rect) {
680     $comment = $rect[0];
681     $color1 = $rect[4];
682     $color2 = $rect[5];
683     $start = $rect[2];
684     $stop = $rect[3];
685
686     $xposition = $buttonsoriginx + $buttonsizex * floor(($start-1)/$numbuttonsy);
687     $yposition = $buttonsoriginy + $buttonsizey * (($start-1)%$numbuttonsy);
688     $xsize = $buttonsizex * (1 + floor(($stop-1)/$numbuttonsy) - floor(($start-1)/$numbuttonsy));
689     $ysize = $buttonsizey * (1 + (($stop-1)%$numbuttonsy) - (($start-1)%$numbuttonsy));
690
691     if (($xsize <= 0) || ($ysize <= 0)) {continue;}
692
693     $xposition += $rectmarginx;
694     $yposition += $rectmarginy;
695     $xsize -= 2 * $rectmarginx;
696     $ysize -= 2 * $rectmarginy;
697
698     fwrite($fhandle, "\n; $comment\n[rectangle]\nx=$xposition\ny=$yposition\nwidth=$xsize\nheight=$ysize\nline_width=0\nline_color=$color1\nfade_color1=$color1\nfade_color2=$color2\nrnd_border=2\nalpha=20\nlayer=bottom\nPanel_Context=$panelcontext\n");
699   }
700
701   ### Write legends
702
703   foreach ($rectangles as $legend) {
704     $text = $legend[1];
705     $start = $legend[2];
706     $stop = $legend[3];
707
708     $xposition = $buttonsoriginx + $buttonsizex * floor(($start-1)/$numbuttonsy);
709     $yposition = $buttonsoriginy + $buttonsizey * (($start-1)%$numbuttonsy);
710     $xsize = $buttonsizex * (1 + floor(($stop-1)/$numbuttonsy) - floor(($start-1)/$numbuttonsy));
711     $ysize = $buttonsizey * (1 + (($stop-1)%$numbuttonsy) - (($start-1)%$numbuttonsy));
712
713     if (($xsize <= 0) || ($ysize <= 0)) {continue;}
714
715     $xposition += $legendoffsetx;
716     $yposition += $legendoffsety;
717
718     fwrite($fhandle, "\n[LEGEND]\nx=$xposition\ny=$yposition\ntext=$text\nfont_size=18\nfont_family=Arial\nuse_embed_fonts=1\nPanel_Context=$panelcontext\n");
719   }
720
721 }
722
723 function get_next_btn($data,$last) {
724   $rangelist=explode(",",$data);
725   foreach ($rangelist as $range) {
726     $rangeval=explode("-",$range,2);
727     if ($last < $rangeval[0]) {return $rangeval[0] ;}
728     if (isset($rangeval[1]) && ($last < $rangeval[1])) {return $last+1;}
729     #Need to try another range def...
730   }
731   #If we get here, we ran out of positions :(
732   return 0; #?????
733 }
734 #this sub checks for the existance of a table
735 function table_exists($db,$table) {
736          $result = mysql_query("SHOW TABLES LIKE '" . $table . "'");
737          if(mysql_fetch_row($result) === false) {return(false);}
738          return(true);
739          }
740
741 function get_styleinfo($id,$layoutinfo) {
742 // do not use globals - instead pass layout info into function explicitly
743 //  global $rectangles;
744 //  global $numbuttonsx;
745 //  global $numbuttonsy;
746 $rectangles = $layoutinfo['rectangles'];
747 $numbuttonsx = $layoutinfo['numbuttonsx'];
748 $numbuttonsy = $layoutinfo['numbuttonsy'];
749
750
751   foreach ($rectangles as $rect) {
752     if ($id == $rect[0]) {
753
754       $start = $rect[2];
755       $stop = $rect[3];
756
757       $xposition = floor(($start-1)/$numbuttonsy);
758       $yposition = (($start-1)%$numbuttonsy);
759       $xsize = 1 + floor(($stop-1)/$numbuttonsy) - floor(($start-1)/$numbuttonsy);
760       $ysize = 1 + (($stop-1)%$numbuttonsy) - (($start-1)%$numbuttonsy);
761
762       if (($xsize <= 0) || ($ysize <= 0)) {print "Warning: rectange '$id' has negative area\n"; last;}
763       $styleinfo = "";
764       if ($ysize > 2) {
765         $styleinfo .= ($start + 1) . "-" . ($start + $ysize - 1) . ",";
766       }
767       elseif ($ysize == 2) {
768         $styleinfo .= ($start + 1) . ",";
769       }
770
771       for ($i = 1 ; $i < $xsize ; $i++ ) {
772         if ($ysize > 1) {
773           $styleinfo .= (($i + $xposition) * $numbuttonsy + $yposition + 1) . "-" . (($i + $xposition) * $numbuttonsy + $yposition + $ysize) . ",";
774         }
775         else {
776           $styleinfo .= (($i + $xposition) * $numbuttonsy + $yposition + 1) . ",";
777         }
778       }
779       $retval = $styleinfo;
780       last;
781     }
782   }
783   return $retval;
784 }
785 ?>