Code

update
[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                         if (($fsection) && ($section != "NO_SECTION")){
77                                 if (preg_match("/^\*CloseGroup:*\s+\**$section\/*/", $line)){
78                                         $fsection= false;
79                                         $ret .=$line; 
80                                         continue;
81                                 }
84                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
85                                         $fattribute= true;
86                                         $ret .= $line; 
87                                         continue;
88                                 }
90                                 if ($fattribute){
91                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
92                                                 $fattribute= false;
93                                                 $ret .= $line; 
94                                                 continue;
95                                         }
97                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
98                                                 $line= "*Default$attribute: $value\n";
99                                                 $done =true;
100                                         }
101                                 }
102                         }else{
103                                 if (preg_match("/^\*OpenUI:*\s+\**$attribute\/*/", $line)){
104                                         $fattribute= true;
105                                         $ret .= $line; 
106                                         continue;
107                                 }
109                                 if ($fattribute){
110                                         if (preg_match("/^\*CloseUI:*\s+\**$attribute\/*/", $line)){
111                                                 $fattribute= false;
112                                                 $ret .= $line; 
113                                                 continue;
114                                         }
116                                         if (preg_match("/^\*Default$attribute:*\s+/", $line)){
117                                                 $line= "*Default$attribute: $value\n";
118                                                 $done =true;
119                                         }
120                                 }
121                         }
122                         $ret .=$line; 
123                 }
125                 fwrite($wp,$ret);
126                 
127                 fclose($wp);
128                 fclose($rp);
130                 copy("$file.tmp", "$file");
131                 unlink("$file.tmp");
132         }
135         function saveProperties($ppdFile, $properties)
136         {
137                 if(!is_readable($ppdFile)){
138                         print_red(sprintf(_("Specified ppd file '%s' can't be opened for reading."),$ppdFile));
139                 }elseif(!is_writeable(preg_replace("#(^.*/).*$#","\\1",$ppdFile.".tmp"))){
140                         print_red(sprintf(_("The required tmp file file '%s' can't be opened for writing."),$ppdFile.".tmp"));
141                 }elseif(!is_writeable($ppdFile.".tmp")){
142                         print_red(sprintf(_("The required tmp file file '%s' can't be opened for writing."),$ppdFile.".tmp"));
143                 }else{
144                         foreach ($properties as $name => $section){
145                                 foreach ($section as $attribute => $value){
146                                         if (is_array($value)){
147                                                 $this->updateAttribute($ppdFile, $name, $attribute, $value['_default']);
148                                         }
149                                 }
150                         }
151                 }
152         }
154         function loadProperties($ppdFile)
155         {
156                 $group= "";
157                 $option= "";
158                 $properties= array();
160                 $fh= fopen ($ppdFile, 'r');
161                 while (!feof($fh)) {
163                         /* Read line */
164                         $line= fgets($fh, 256);
165                         if (strlen($line) >= 256){
166                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
167                         }
169                         /* Trigger for option groups */
170                         if (preg_match('/^\*OpenGroup:/i', $line)){
172                                 /* Sanity checks */
173                                 if ($group != ""){
174                                         trigger_error(_('Nested groups are not supported!'), E_USER_WARNING);
175                                         continue;
176                                 }
177                                 if (in_array($group, $properties)){
178                                         trigger_error(_('Group name not unique!'), E_USER_WARNING);
179                                         continue;
180                                 }
182                                 // TODO: Symbol values are not supported yet!
183                                 if (preg_match('/\^/', $line)){
184                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
185                                 }
186                                 $complete= preg_replace('@^\*OpenGroup:\s+(.*)$@i', '\1', $line);
187                                 $complete= trim($complete, '"');
188                                 if (preg_match('@/@', $complete)){
189                                         $group= trim(preg_replace('@^\*OpenGroup:\s+"?([^/]+)/.*$@i', '\1', $line));
190                                         $name = preg_replace('@^\*OpenGroup:\s+"?[^/]+/([^/]+).*$@i', '\1', $line);
191                                 } else {
192                                         $group= $complete;
193                                         $name = $complete;
194                                 }
195                                 $properties[$group]= array('_name' => $name);
196                                 continue;
197                         }
198                         if (preg_match("/^\*CloseGroup:\s+\"?$group\"?/i", $line)){
199                                 $group= "";
200                                 continue;
201                         }
203                         /* Trigger for options */
204                         if (preg_match('/^\*OpenUI\s+/i', $line)){
206                                 /* Sanity check */
207                                 if ($option != ""){
208                                         trigger_error(_('Nested options are not supported!'), E_USER_WARNING);
209                                         continue;
210                                 }
212                                 // TODO: Symbol values are not supported yet!
213                                 if (preg_match('/\^/', $line)){
214                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
215                                 }
216                                 $complete= preg_replace('@^\*OpenUI\s+(.*)$@i', '\1', $line);
217                                 $complete= trim($complete, '"');
218                                 if (preg_match('@/@', $complete)){
219                                         $option= trim(preg_replace('@^\*OpenUI\s+([^/]+)/.*$@i', '\1', $line));
220                                         $name = trim(preg_replace('@^\*OpenUI\s+[^/]+/([^/]+).*$@i', '\1', $line));
221                                 } else {
222                                         $option= trim($complete);
223                                         $name  = trim($complete);
224                                 }
226                                 /* Extract option type */
227                                 $type= trim(preg_replace('/^[^:]+:\s+/', '', $line));
228                                 $name= preg_replace('/:.*$/', '', $name);
229                                 $option= preg_replace('/:.*$/', '', $option);
231                                 // TODO: PickMany is not supported yet!
232                                 if (preg_match('/PickMany/i', $type)){
233                                         trigger_error(_('PickMany is not supported yet!'), E_USER_WARNING);
234                                 }
235                                 if(empty($group)){
236                                         $properties["NO_SECTION"][$option]= array('_name' => $name, '_type' => $type);
237                                 }else{
238                                         $properties[$group][$option]= array('_name' => $name, '_type' => $type);
239                                 }
240                                 continue;
241                         }
242                         /* Show interest for option parsing */
243                         if ($option != ""){
245                                 $eoption= preg_replace('@\*@', '', $option);
247                                 /* Close section? */
248                                 if (preg_match("@^\*CloseUI:\s+\*$eoption@i", $line)){
249                                         $option= "";
250                                         continue;
251                                 }
253                                 /* Default value? */
254                                 if (preg_match("@^\*Default$eoption:@", $line)){
255                                         $c= preg_replace("@^\*Default$eoption:\s+@", "", $line);
256                                         if(empty($group)){
257                                                 $properties["NO_SECTION"][$option]['_default']= trim(trim($c, '"'));
258                                         }else{
259                                                 $properties[$group][$option]['_default']= trim(trim($c, '"'));
260                                         }
261                                         continue;
262                                 }
264                                 /* Possible value? */
265                                 if (preg_match("@^\*$eoption\s+@", $line)){
266 #*PageSize Letter/US Letter: "<>setpagedevice"
267                                         $c= preg_replace("@^\*$eoption\s+([^/]+).*$@", "$1", $line);
268                                         $d= preg_replace("@^\*$eoption\s+[^/]+/([^:]+).*$@", "$1", $line);
269                                         if(empty($group)){
270                                                 $properties["NO_SECTION"][$option][trim($c)]= trim($d);
271                                         }else{
272                                                 $properties[$group][$option][trim($c)]= trim($d);
273                                         }
274                                         continue;
275                                 }
276                         }
277                 }
278                 fclose ($fh);
279                 return ($properties);
280         }
282         function loadDescription($ppdFile)
283         {
284                 $model= "";
285                 $manufacturer= "";
287                 $fh= fopen ($ppdFile, 'r');
288                 while ((!feof($fh))&&($fh)) {
290                         /* Read line */
291                         $line= fgets($fh, 256);
292                         if (strlen($line) >= 256){
293                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
294                         }
296                         /* Extract interesting informations */
297                         if (preg_match('/^\*Manufacturer:/i', $line)){
298                                 $manufacturer= preg_replace('/^\*Manufacturer:\s+"?([^"]+)"?.*$/i', '\1', $line);
299                         }
300                         if (preg_match('/^\*ModelName:/i', $line)){
301                                 $model= preg_replace('/^\*ModelName:\s+"?([^"]+)"?.*$/i', '\1', $line);
302                         }
304                         /* Got everything we need? Skip rest for speed reasons... */
305                         if ($model != '' && $manufacturer != ''){
306                                 break;
307                         }
308                 }
309                 fclose ($fh);
311                 /* Write out a notice that the PPD file seems to be broken if we can't
312                    extract any usefull informations */
313                 if ($model == '' || $manufacturer == ''){
314                         trigger_error(sprintf(_('Parsing PPD file %s failed - no information found.'), $ppdFile), E_USER_WARNING);
315                 }
317                 return ($manufacturer.' - '.$model);
318         }
321         function getPrinterList($reload= false)
322         {
323                 /* Load list of PPD files */
324                 if (count($this->cachedList) == 0 || $reload){
325                         $list= $this->findPPD($this->path);
327                         /* Load descriptive informations to build final printer list */
328                         $this->cachedList= array();
329                         foreach ($list as $ppdFile){
330                                 $this->cachedList[$ppdFile]= $this->loadDescription($ppdFile);
331                         }
333                 }
335                 return ($this->cachedList);
336         }
340 ?>