Code

Moved folder images
[gosa.git] / gosa-plugins / goto / admin / systems / ppd / class_ppdManager.inc
1 <?php
3 class ppdManager
4 {
5         var $path= "";
6         var $cachedList= array();
7         var $timestamps = array();
9         function ppdManager($path)
10         {
11                 if(is_dir($path)){
12                         $this->path= $path;
13                 }else{
14                         msg_dialog::display(_("PPD manager error"), sprintf(_("The specified path '%s' does not exist."),$path), ERROR_DIALOG);
15                         return (false);
16                 }
17         }
20         function findPPD($path)
21         {
22                 $list= array();
23                 $currentDir= getcwd();
25                 $dh = opendir($path);
26                 while(false !== ($file = readdir($dh))){
28                         /* Skip well known files */
29                         if( $file == '.' || $file == '..'){
30                                 continue;
31                         }
33                         /* Recurse through all "common" directories */
34                         if(is_dir($path.'/'.$file)){
35                                 $list= array_merge($list, $this->findPPD($path.'/'.$file));
36                                 continue;
37                         }
39                         /* Check for PPD extension */
40                         if (preg_match('/\.ppd$/i', $file)){
41                                 $list[]= $path.'/'.$file;
42                         }
43                 }
45                 closedir($dh);
46                 chdir ($currentDir);
47                 return ($list);
48         }
51         function updateAttribute($file, $section, $attribute, $value)
52         {
53                 $fsection= false;
54                 $fattribute= false;
55                 $section= preg_replace('/^\*/', '', $section);
56                 $attribute= preg_replace('/^\*/', '', $attribute);
58                 $rp= @fopen($file, "r");
59                 $wp= @fopen("$file.tmp", "w");
61                 
63                 while (!feof($rp)){
64                         $lines[]= fgets($rp, 1024);
65                 }
67                 $ret = "";
68                 $done =false;
69                 foreach($lines as $nr => $line){
70         
71                         if (preg_match("/\*OpenGroup:*\s+\**$section\/*/", $line)){
72                 $fsection= true;
73                                 $ret .=$line; 
74                 continue;
75             }
77                         /* Change model name .. */
78                         if ((preg_match("/^\*".$attribute.":*\s+/",$line)) && ($attribute == "ModelName")){
79                                 $line= "*$attribute: \"$value\"\n";
80                                 $done =true;
81                         }
83                         if (($fsection) && ($section != "NO_SECTION")){
84                                 if (preg_match("/^\*CloseGroup:*\s+\**$section\/*/", $line)){
85                                         $fsection= false;
86                                         $ret .=$line; 
87                                         continue;
88                                 }
91                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
92                                         $fattribute= true;
93                                         $ret .= $line; 
94                                         continue;
95                                 }
97                                 if ($fattribute){
98                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
99                                                 $fattribute= false;
100                                                 $ret .= $line; 
101                                                 continue;
102                                         }
104                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
105                                                 $line= "*Default$attribute: $value\n";
106                                                 $done =true;
107                                         }
108                                 }
109                         }else{
110                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
111                                         $fattribute= true;
112                                         $ret .= $line; 
113                                         continue;
114                                 }
116                                 if ($fattribute){
117                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
118                                                 $fattribute= false;
119                                                 $ret .= $line; 
120                                                 continue;
121                                         }
123                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
124                                                 $line= "*Default$attribute: $value\n";
125                                                 $done =true;
126                                         }
127                                 }
128                         }
129                         $ret .=$line; 
130                 }
132                 fwrite($wp,$ret);
133                 
134                 fclose($wp);
135                 fclose($rp);
137                 copy("$file.tmp", "$file");
138                 unlink("$file.tmp");
139         }
142         function saveProperties($ppdFile, $properties)
143         {
144                 if(!is_readable($ppdFile)){
145                         msg_dialog::display(_("PPD manager error"), sprintf(_("Specified PPD file '%s' cannot be opened for reading."),$ppdFile), ERROR_DIALOG);
146                 }elseif(!is_writeable(preg_replace("#(^.*/).*$#","\\1",$ppdFile.".tmp"))){
147                         msg_dialog::display(_("PPD manager error"), sprintf(_("The temporary file '%s' cannot be opened for writing."),$ppdFile.".tmp"), ERROR_DIALOG);
148                 }else{
149                         if(is_array($properties)){
150                                 foreach ($properties as $name => $section){
151                                         foreach ($section as $attribute => $value){
152                                                 if (is_array($value)){
153                                                         $this->updateAttribute($ppdFile, $name, $attribute, $value['_default']);
154                                                 }
155                                         }
156                                 }
157                         }
158                 }
159         }
161         function loadProperties($ppdFile)
162         {
163                 $group= "";
164                 $option= "";
165                 $properties= array();
167                 $fh= fopen ($ppdFile, 'r');
168                 while (!feof($fh)) {
170                         /* Read line */
171                         $line= fgets($fh, 256);
172                         if (strlen($line) >= 256){
173                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
174                         }
176                         /* Trigger for option groups */
177                         if (preg_match('/^\*OpenGroup:/i', $line)){
179                                 /* Sanity checks */
180                                 if ($group != ""){
181                                         trigger_error(_('Nested groups are not supported!'), E_USER_WARNING);
182                                         continue;
183                                 }
184                                 if (in_array($group, $properties)){
185                                         trigger_error(_('Group name not unique!'), E_USER_WARNING);
186                                         continue;
187                                 }
189                                 // TODO: Symbol values are not supported yet!
190                                 if (preg_match('/\^/', $line)){
191                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
192                                 }
193                                 $complete= preg_replace('@^\*OpenGroup:\s+(.*)$@i', '\1', $line);
194                                 $complete= trim($complete, '"');
195                                 if (preg_match('@/@', $complete)){
196                                         $group= trim(preg_replace('@^\*OpenGroup:\s+"?([^/]+)/.*$@i', '\1', $line));
197                                         $name = preg_replace('@^\*OpenGroup:\s+"?[^/]+/([^/]+).*$@i', '\1', $line);
198                                 } else {
199                                         $group= $complete;
200                                         $name = $complete;
201                                 }
202                                 $properties[$group]= array('_name' => $name);
203                                 continue;
204                         }
205                         if (preg_match("/^\*CloseGroup:\s+\"?$group\"?/i", $line)){
206                                 $group= "";
207                                 continue;
208                         }
210                         /* Trigger for options */
211                         if (preg_match('/^\*OpenUI\s+/i', $line)){
213                                 /* Sanity check */
214                                 if ($option != ""){
215                                         trigger_error(_('Nested options are not supported!'), E_USER_WARNING);
216                                         continue;
217                                 }
219                                 // TODO: Symbol values are not supported yet!
220                                 if (preg_match('/\^/', $line)){
221                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
222                                 }
223                                 $complete= preg_replace('@^\*OpenUI\s+(.*)$@i', '\1', $line);
224                                 $complete= trim($complete, '"');
225                                 if (preg_match('@/@', $complete)){
226                                         $option= trim(preg_replace('@^\*OpenUI\s+([^/]+)/.*$@i', '\1', $line));
227                                         $name = trim(preg_replace('@^\*OpenUI\s+[^/]+/([^/]+).*$@i', '\1', $line));
228                                 } else {
229                                         $option= trim($complete);
230                                         $name  = trim($complete);
231                                 }
233                                 /* Extract option type */
234                                 $type= trim(preg_replace('/^[^:]+:\s+/', '', $line));
235                                 $name= preg_replace('/:.*$/', '', $name);
236                                 $option= preg_replace('/:.*$/', '', $option);
238                                 // TODO: PickMany is not supported yet!
239                                 if (preg_match('/PickMany/i', $type)){
240                                         trigger_error(_('PickMany is not supported yet!'), E_USER_WARNING);
241                                 }
242                                 if(empty($group)){
243                                         $properties["NO_SECTION"][$option]= array('_name' => $name, '_type' => $type);
244                                 }else{
245                                         $properties[$group][$option]= array('_name' => $name, '_type' => $type);
246                                 }
247                                 continue;
248                         }
249                         /* Show interest for option parsing */
250                         if ($option != ""){
252                                 $eoption= preg_replace('@\*@', '', $option);
254                                 /* Close section? */
255                                 if (preg_match("@^\*CloseUI:\s+\*$eoption@i", $line)){
256                                         $option= "";
257                                         continue;
258                                 }
260                                 /* Default value? */
261                                 if (preg_match("@^\*Default$eoption:@", $line)){
262                                         $c= preg_replace("@^\*Default$eoption:\s+@", "", $line);
263                                         if(empty($group)){
264                                                 $properties["NO_SECTION"][$option]['_default']= trim(trim($c, '"'));
265                                         }else{
266                                                 $properties[$group][$option]['_default']= trim(trim($c, '"'));
267                                         }
268                                         continue;
269                                 }
271                                 /* Possible value? */
272                                 if (preg_match("@^\*$eoption\s+@", $line)){
273 #*PageSize Letter/US Letter: "<>setpagedevice"
274                                         $c= preg_replace("@^\*$eoption\s+([^/]+).*$@", "$1", $line);
275                                         $d= preg_replace("@^\*$eoption\s+[^/]+/([^:]+).*$@", "$1", $line);
276                                         if(empty($group)){
277                                                 $properties["NO_SECTION"][$option][trim($c)]= trim($d);
278                                         }else{
279                                                 $properties[$group][$option][trim($c)]= trim($d);
280                                         }
281                                         continue;
282                                 }
283                         }
284                 }
285                 fclose ($fh);
286                 return ($properties);
287         }
289         function loadDescription($ppdFile)
290         {
291                 $model= "";
292                 $manufacturer= "";
294                 
295                 /* Only parse complete PPD file again, if it was changed */
296                 $modified = filemtime($ppdFile);
297                 if(isset($this->cachedList[$ppdFile]) && isset($this->timestamps[$ppdFile]) && $modified == $this->timestamps[$ppdFile]){
298                         return($this->cachedList[$ppdFile]);
299                 }
301                 /* Remember modified timestamp, to speed up next request */
302                 $this->timestamps[$ppdFile] = filemtime($ppdFile);
304                 $fh= fopen ($ppdFile, 'r');
305                 while ((!feof($fh))&&($fh)) {
307                         /* Read line */
308                         $line= fgets($fh, 256);
309                         if (strlen($line) >= 256){
310                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
311                         }
313                         /* Extract interesting informations */
314                         if (preg_match('/^\*Manufacturer:/i', $line)){
315                                 $manufacturer= preg_replace('/^\*Manufacturer:\s+"?([^"]+)"?.*$/i', '\1', $line);
316                         }
317                         if (preg_match('/^\*ModelName:/i', $line)){
318                                 $model= preg_replace('/^\*ModelName:\s+"?([^"]+)"?.*$/i', '\1', $line);
319                         }
321                         /* Got everything we need? Skip rest for speed reasons... */
322                         if ($model != '' && $manufacturer != ''){
323                                 break;
324                         }
325                 }
326                 fclose ($fh);
328                 /* Write out a notice that the PPD file seems to be broken if we can't
329                    extract any usefull informations */
330                 if ($model == '' || $manufacturer == ''){
331                         trigger_error(sprintf(_('Parsing PPD file %s failed - no information found.'), $ppdFile), E_USER_WARNING);
332                 }
334                 return ($manufacturer.' - '.$model);
335         }
338         function getPrinterList($reload= false)
339         {
340                 /* Load list of PPD files */
341                 if (count($this->cachedList) == 0 || $reload){
342                         $list= $this->findPPD($this->path);
344                         /* Load descriptive informations to build final printer list */
345                         $new = array();
346                         foreach ($list as $ppdFile){
347                                 $new[$ppdFile] = $this->loadDescription($ppdFile); 
348                         }
349                         $this->cachedList= $new ;
351                 }
353                 return ($this->cachedList);
354         }
357 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
358 ?>