Code

Added picture
[gosa.git] / include / class_ppdManager.inc
1 <?php
3 class ppdManager
4 {
5         var $path= "";
6         var $cachedList= array();
8         function ppdManager($path)
9         {
10                 if(is_dir($path)){
11                 $this->path= $path;
12                 }else{
13                         print_red(sprintf(_("PPD manager : The specified path '%s' doesn't exists."),$path));
14                         return (false);
15                 }
16         }
19         function findPPD($path)
20         {
21                 $list= array();
22                 $currentDir= getcwd();
24                 $dh = opendir($path);
25                 while(false !== ($file = readdir($dh))){
27                         /* Skip well known files */
28                         if( $file == '.' || $file == '..'){
29                                 continue;
30                         }
32                         /* Recurse through all "common" directories */
33                         if(is_dir($path.'/'.$file)){
34                                 $list= array_merge($list, $this->findPPD($path.'/'.$file));
35                                 continue;
36                         }
38                         /* Check for PPD extension */
39                         if (preg_match('/\.ppd$/i', $file)){
40                                 $list[]= $path.'/'.$file;
41                         }
42                 }
44                 closedir($dh);
45                 chdir ($currentDir);
46                 return ($list);
47         }
50         function updateAttribute($file, $section, $attribute, $value)
51         {
52                 $fsection= false;
53                 $fattribute= false;
54                 $section= preg_replace('/^\*/', '', $section);
55                 $attribute= preg_replace('/^\*/', '', $attribute);
57                 $rp= @fopen($file, "r");
58                 $wp= @fopen("$file.tmp", "w");
60                 
62                 while (!feof($rp)){
63                         $lines[]= fgets($rp, 1024);
64                 }
66                 $ret = "";
67                 $done =false;
68                 foreach($lines as $nr => $line){
69         
70                         if (preg_match("/\*OpenGroup:*\s+\**$section\/*/", $line)){
71                 $fsection= true;
72                                 $ret .=$line; 
73                 continue;
74             }
76                         /* Change model name .. */
77                         if ((preg_match("/^\*".$attribute.":*\s+/",$line)) && ($attribute == "ModelName")){
78                                 $line= "*$attribute: \"$value\"\n";
79                                 $done =true;
80                         }
82                         if (($fsection) && ($section != "NO_SECTION")){
83                                 if (preg_match("/^\*CloseGroup:*\s+\**$section\/*/", $line)){
84                                         $fsection= false;
85                                         $ret .=$line; 
86                                         continue;
87                                 }
90                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
91                                         $fattribute= true;
92                                         $ret .= $line; 
93                                         continue;
94                                 }
96                                 if ($fattribute){
97                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
98                                                 $fattribute= false;
99                                                 $ret .= $line; 
100                                                 continue;
101                                         }
103                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
104                                                 $line= "*Default$attribute: $value\n";
105                                                 $done =true;
106                                         }
107                                 }
108                         }else{
109                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
110                                         $fattribute= true;
111                                         $ret .= $line; 
112                                         continue;
113                                 }
115                                 if ($fattribute){
116                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
117                                                 $fattribute= false;
118                                                 $ret .= $line; 
119                                                 continue;
120                                         }
122                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
123                                                 $line= "*Default$attribute: $value\n";
124                                                 $done =true;
125                                         }
126                                 }
127                         }
128                         $ret .=$line; 
129                 }
131                 fwrite($wp,$ret);
132                 
133                 fclose($wp);
134                 fclose($rp);
136                 copy("$file.tmp", "$file");
137                 unlink("$file.tmp");
138         }
141         function saveProperties($ppdFile, $properties)
142         {
143                 if(!is_readable($ppdFile)){
144                         print_red(sprintf(_("Specified ppd file '%s' can't be opened for reading."),$ppdFile));
145                 }elseif(!is_writeable(preg_replace("#(^.*/).*$#","\\1",$ppdFile.".tmp"))){
146                         print_red(sprintf(_("The required tmp file file '%s' can't be opened for writing."),$ppdFile.".tmp"));
147                 }else{
148                         foreach ($properties as $name => $section){
149                                 foreach ($section as $attribute => $value){
150                                         if (is_array($value)){
151                                                 $this->updateAttribute($ppdFile, $name, $attribute, $value['_default']);
152                                         }
153                                 }
154                         }
155                 }
156         }
158         function loadProperties($ppdFile)
159         {
160                 $group= "";
161                 $option= "";
162                 $properties= array();
164                 $fh= fopen ($ppdFile, 'r');
165                 while (!feof($fh)) {
167                         /* Read line */
168                         $line= fgets($fh, 256);
169                         if (strlen($line) >= 256){
170                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
171                         }
173                         /* Trigger for option groups */
174                         if (preg_match('/^\*OpenGroup:/i', $line)){
176                                 /* Sanity checks */
177                                 if ($group != ""){
178                                         trigger_error(_('Nested groups are not supported!'), E_USER_WARNING);
179                                         continue;
180                                 }
181                                 if (in_array($group, $properties)){
182                                         trigger_error(_('Group name not unique!'), E_USER_WARNING);
183                                         continue;
184                                 }
186                                 // TODO: Symbol values are not supported yet!
187                                 if (preg_match('/\^/', $line)){
188                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
189                                 }
190                                 $complete= preg_replace('@^\*OpenGroup:\s+(.*)$@i', '\1', $line);
191                                 $complete= trim($complete, '"');
192                                 if (preg_match('@/@', $complete)){
193                                         $group= trim(preg_replace('@^\*OpenGroup:\s+"?([^/]+)/.*$@i', '\1', $line));
194                                         $name = preg_replace('@^\*OpenGroup:\s+"?[^/]+/([^/]+).*$@i', '\1', $line);
195                                 } else {
196                                         $group= $complete;
197                                         $name = $complete;
198                                 }
199                                 $properties[$group]= array('_name' => $name);
200                                 continue;
201                         }
202                         if (preg_match("/^\*CloseGroup:\s+\"?$group\"?/i", $line)){
203                                 $group= "";
204                                 continue;
205                         }
207                         /* Trigger for options */
208                         if (preg_match('/^\*OpenUI\s+/i', $line)){
210                                 /* Sanity check */
211                                 if ($option != ""){
212                                         trigger_error(_('Nested options are not supported!'), E_USER_WARNING);
213                                         continue;
214                                 }
216                                 // TODO: Symbol values are not supported yet!
217                                 if (preg_match('/\^/', $line)){
218                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
219                                 }
220                                 $complete= preg_replace('@^\*OpenUI\s+(.*)$@i', '\1', $line);
221                                 $complete= trim($complete, '"');
222                                 if (preg_match('@/@', $complete)){
223                                         $option= trim(preg_replace('@^\*OpenUI\s+([^/]+)/.*$@i', '\1', $line));
224                                         $name = trim(preg_replace('@^\*OpenUI\s+[^/]+/([^/]+).*$@i', '\1', $line));
225                                 } else {
226                                         $option= trim($complete);
227                                         $name  = trim($complete);
228                                 }
230                                 /* Extract option type */
231                                 $type= trim(preg_replace('/^[^:]+:\s+/', '', $line));
232                                 $name= preg_replace('/:.*$/', '', $name);
233                                 $option= preg_replace('/:.*$/', '', $option);
235                                 // TODO: PickMany is not supported yet!
236                                 if (preg_match('/PickMany/i', $type)){
237                                         trigger_error(_('PickMany is not supported yet!'), E_USER_WARNING);
238                                 }
239                                 if(empty($group)){
240                                         $properties["NO_SECTION"][$option]= array('_name' => $name, '_type' => $type);
241                                 }else{
242                                         $properties[$group][$option]= array('_name' => $name, '_type' => $type);
243                                 }
244                                 continue;
245                         }
246                         /* Show interest for option parsing */
247                         if ($option != ""){
249                                 $eoption= preg_replace('@\*@', '', $option);
251                                 /* Close section? */
252                                 if (preg_match("@^\*CloseUI:\s+\*$eoption@i", $line)){
253                                         $option= "";
254                                         continue;
255                                 }
257                                 /* Default value? */
258                                 if (preg_match("@^\*Default$eoption:@", $line)){
259                                         $c= preg_replace("@^\*Default$eoption:\s+@", "", $line);
260                                         if(empty($group)){
261                                                 $properties["NO_SECTION"][$option]['_default']= trim(trim($c, '"'));
262                                         }else{
263                                                 $properties[$group][$option]['_default']= trim(trim($c, '"'));
264                                         }
265                                         continue;
266                                 }
268                                 /* Possible value? */
269                                 if (preg_match("@^\*$eoption\s+@", $line)){
270 #*PageSize Letter/US Letter: "<>setpagedevice"
271                                         $c= preg_replace("@^\*$eoption\s+([^/]+).*$@", "$1", $line);
272                                         $d= preg_replace("@^\*$eoption\s+[^/]+/([^:]+).*$@", "$1", $line);
273                                         if(empty($group)){
274                                                 $properties["NO_SECTION"][$option][trim($c)]= trim($d);
275                                         }else{
276                                                 $properties[$group][$option][trim($c)]= trim($d);
277                                         }
278                                         continue;
279                                 }
280                         }
281                 }
282                 fclose ($fh);
283                 return ($properties);
284         }
286         function loadDescription($ppdFile)
287         {
288                 $model= "";
289                 $manufacturer= "";
291                 $fh= fopen ($ppdFile, 'r');
292                 while ((!feof($fh))&&($fh)) {
294                         /* Read line */
295                         $line= fgets($fh, 256);
296                         if (strlen($line) >= 256){
297                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
298                         }
300                         /* Extract interesting informations */
301                         if (preg_match('/^\*Manufacturer:/i', $line)){
302                                 $manufacturer= preg_replace('/^\*Manufacturer:\s+"?([^"]+)"?.*$/i', '\1', $line);
303                         }
304                         if (preg_match('/^\*ModelName:/i', $line)){
305                                 $model= preg_replace('/^\*ModelName:\s+"?([^"]+)"?.*$/i', '\1', $line);
306                         }
308                         /* Got everything we need? Skip rest for speed reasons... */
309                         if ($model != '' && $manufacturer != ''){
310                                 break;
311                         }
312                 }
313                 fclose ($fh);
315                 /* Write out a notice that the PPD file seems to be broken if we can't
316                    extract any usefull informations */
317                 if ($model == '' || $manufacturer == ''){
318                         trigger_error(sprintf(_('Parsing PPD file %s failed - no information found.'), $ppdFile), E_USER_WARNING);
319                 }
321                 return ($manufacturer.' - '.$model);
322         }
325         function getPrinterList($reload= false)
326         {
327                 /* Load list of PPD files */
328                 if (count($this->cachedList) == 0 || $reload){
329                         $list= $this->findPPD($this->path);
331                         /* Load descriptive informations to build final printer list */
332                         $this->cachedList= array();
333                         foreach ($list as $ppdFile){
334                                 $this->cachedList[$ppdFile]= $this->loadDescription($ppdFile);
335                         }
337                 }
339                 return ($this->cachedList);
340         }
344 ?>