Code

Added some checks
[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($ppdFile.".tmp")){
140                         print_red(sprintf(_("The required tmp file file '%s' can't be opened for writing."),$ppdFile.".tmp"));
141                 }else{
143                         foreach ($properties as $name => $section){
144                                 foreach ($section as $attribute => $value){
145                                         if (is_array($value)){
146                                                 $this->updateAttribute($ppdFile, $name, $attribute, $value['_default']);
147                                         }
148                                 }
149                         }
150                 }
151         }
153         function loadProperties($ppdFile)
154         {
155                 $group= "";
156                 $option= "";
157                 $properties= array();
159                 $fh= fopen ($ppdFile, 'r');
160                 while (!feof($fh)) {
162                         /* Read line */
163                         $line= fgets($fh, 256);
164                         if (strlen($line) >= 256){
165                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
166                         }
168                         /* Trigger for option groups */
169                         if (preg_match('/^\*OpenGroup:/i', $line)){
171                                 /* Sanity checks */
172                                 if ($group != ""){
173                                         trigger_error(_('Nested groups are not supported!'), E_USER_WARNING);
174                                         continue;
175                                 }
176                                 if (in_array($group, $properties)){
177                                         trigger_error(_('Group name not unique!'), E_USER_WARNING);
178                                         continue;
179                                 }
181                                 // TODO: Symbol values are not supported yet!
182                                 if (preg_match('/\^/', $line)){
183                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
184                                 }
185                                 $complete= preg_replace('@^\*OpenGroup:\s+(.*)$@i', '\1', $line);
186                                 $complete= trim($complete, '"');
187                                 if (preg_match('@/@', $complete)){
188                                         $group= trim(preg_replace('@^\*OpenGroup:\s+"?([^/]+)/.*$@i', '\1', $line));
189                                         $name = preg_replace('@^\*OpenGroup:\s+"?[^/]+/([^/]+).*$@i', '\1', $line);
190                                 } else {
191                                         $group= $complete;
192                                         $name = $complete;
193                                 }
194                                 $properties[$group]= array('_name' => $name);
195                                 continue;
196                         }
197                         if (preg_match("/^\*CloseGroup:\s+\"?$group\"?/i", $line)){
198                                 $group= "";
199                                 continue;
200                         }
202                         /* Trigger for options */
203                         if (preg_match('/^\*OpenUI\s+/i', $line)){
205                                 /* Sanity check */
206                                 if ($option != ""){
207                                         trigger_error(_('Nested options are not supported!'), E_USER_WARNING);
208                                         continue;
209                                 }
211                                 // TODO: Symbol values are not supported yet!
212                                 if (preg_match('/\^/', $line)){
213                                         trigger_error(_('Symbol values are not supported yet!'), E_USER_WARNING);
214                                 }
215                                 $complete= preg_replace('@^\*OpenUI\s+(.*)$@i', '\1', $line);
216                                 $complete= trim($complete, '"');
217                                 if (preg_match('@/@', $complete)){
218                                         $option= trim(preg_replace('@^\*OpenUI\s+([^/]+)/.*$@i', '\1', $line));
219                                         $name = trim(preg_replace('@^\*OpenUI\s+[^/]+/([^/]+).*$@i', '\1', $line));
220                                 } else {
221                                         $option= trim($complete);
222                                         $name  = trim($complete);
223                                 }
225                                 /* Extract option type */
226                                 $type= trim(preg_replace('/^[^:]+:\s+/', '', $line));
227                                 $name= preg_replace('/:.*$/', '', $name);
228                                 $option= preg_replace('/:.*$/', '', $option);
230                                 // TODO: PickMany is not supported yet!
231                                 if (preg_match('/PickMany/i', $type)){
232                                         trigger_error(_('PickMany is not supported yet!'), E_USER_WARNING);
233                                 }
234                                 if(empty($group)){
235                                         $properties["NO_SECTION"][$option]= array('_name' => $name, '_type' => $type);
236                                 }else{
237                                         $properties[$group][$option]= array('_name' => $name, '_type' => $type);
238                                 }
239                                 continue;
240                         }
241                         /* Show interest for option parsing */
242                         if ($option != ""){
244                                 $eoption= preg_replace('@\*@', '', $option);
246                                 /* Close section? */
247                                 if (preg_match("@^\*CloseUI:\s+\*$eoption@i", $line)){
248                                         $option= "";
249                                         continue;
250                                 }
252                                 /* Default value? */
253                                 if (preg_match("@^\*Default$eoption:@", $line)){
254                                         $c= preg_replace("@^\*Default$eoption:\s+@", "", $line);
255                                         if(empty($group)){
256                                                 $properties["NO_SECTION"][$option]['_default']= trim(trim($c, '"'));
257                                         }else{
258                                                 $properties[$group][$option]['_default']= trim(trim($c, '"'));
259                                         }
260                                         continue;
261                                 }
263                                 /* Possible value? */
264                                 if (preg_match("@^\*$eoption\s+@", $line)){
265 #*PageSize Letter/US Letter: "<>setpagedevice"
266                                         $c= preg_replace("@^\*$eoption\s+([^/]+).*$@", "$1", $line);
267                                         $d= preg_replace("@^\*$eoption\s+[^/]+/([^:]+).*$@", "$1", $line);
268                                         if(empty($group)){
269                                                 $properties["NO_SECTION"][$option][trim($c)]= trim($d);
270                                         }else{
271                                                 $properties[$group][$option][trim($c)]= trim($d);
272                                         }
273                                         continue;
274                                 }
275                         }
276                 }
277                 fclose ($fh);
278                 return ($properties);
279         }
281         function loadDescription($ppdFile)
282         {
283                 $model= "";
284                 $manufacturer= "";
286                 $fh= fopen ($ppdFile, 'r');
287                 while ((!feof($fh))&&($fh)) {
289                         /* Read line */
290                         $line= fgets($fh, 256);
291                         if (strlen($line) >= 256){
292                                 trigger_error(_('Parsing PPD file %s failed - line too long. Trailing characters have been ignored'), E_USER_WARNING);
293                         }
295                         /* Extract interesting informations */
296                         if (preg_match('/^\*Manufacturer:/i', $line)){
297                                 $manufacturer= preg_replace('/^\*Manufacturer:\s+"?([^"]+)"?.*$/i', '\1', $line);
298                         }
299                         if (preg_match('/^\*ModelName:/i', $line)){
300                                 $model= preg_replace('/^\*ModelName:\s+"?([^"]+)"?.*$/i', '\1', $line);
301                         }
303                         /* Got everything we need? Skip rest for speed reasons... */
304                         if ($model != '' && $manufacturer != ''){
305                                 break;
306                         }
307                 }
308                 fclose ($fh);
310                 /* Write out a notice that the PPD file seems to be broken if we can't
311                    extract any usefull informations */
312                 if ($model == '' || $manufacturer == ''){
313                         trigger_error(sprintf(_('Parsing PPD file %s failed - no information found.'), $ppdFile), E_USER_WARNING);
314                 }
316                 return ($manufacturer.' - '.$model);
317         }
320         function getPrinterList($reload= false)
321         {
322                 /* Load list of PPD files */
323                 if (count($this->cachedList) == 0 || $reload){
324                         $list= $this->findPPD($this->path);
326                         /* Load descriptive informations to build final printer list */
327                         $this->cachedList= array();
328                         foreach ($list as $ppdFile){
329                                 $this->cachedList[$ppdFile]= $this->loadDescription($ppdFile);
330                         }
332                 }
334                 return ($this->cachedList);
335         }
339 ?>