Code

Updated printGeneric.
[gosa.git] / plugins / admin / systems / class_printerPPDDialog.inc
1 <?php
3 class printerPPDDialog extends plugin
4 {
5   /* attribute list for save action */
6   var $ignore_account       = TRUE;
7   var $attributes           = array("cn");
8   var $objectclasses        = array("whatever");
10   /* PPD Handling */
11   var $selectedPPD          = false;        // e.g. /vendor/device.ppd 
12   var $ppdManager           = false;        // new ppdManager;
13   var $ppdConfig            = false;        // $this->ppdManager->loadProperties($this->selectedPPD['link']);
14   var $ppdList              = array();      // Contains all Printer models
15   var $ppdListHeader        = array();      // Contains all printer vendors
17   /* Paths */
18   var $pathToPPD            = "";           // Base path, defined in gosa.conf e.g. "/var/spool/ppd/"
19   var $pathToModified       = "modified/";  // used to store the modified ppds  
20       
21   /* Object Info */
22   var $cn                   = "" ;          // Used to tag the ppds modified by the printer object, 
23   var $dialog               = NULL;         // Contains sub dialogs 
25   function printerPPDDialog ($config, $dn= NULL,$ppdfile=NULL )
26   {
27     plugin::plugin ($config, $dn);
28     $this->depselect = $this->config->current['BASE'];
30     /* Get PPD path and remove double //, and add trailing /  */
31     if(isset($_SESSION['config']->data['MAIN']['PPD_PATH'])){
32       $this->pathToPPD = $_SESSION['config']->data['MAIN']['PPD_PATH'];
33       $this->pathToPPD= preg_replace("/\/\//", "/", $this->pathToPPD);
34       if(!preg_match("/\/$/",$this->pathToPPD)){
35         $this->pathToPPD = $this->pathToPPD."/";
36       }
37     }else{
38       $this->pathToPPD = "";
39     }
41     /* It seams that we have an existing PPD path, so go on */
42     if(!((!is_dir($this->pathToPPD))||(empty($this->pathToPPD)))){ 
44       /* Load all available PPD files and sort them into an array */
45       require_once ("class_ppdManager.inc");
46       $this->ppdManager= new ppdManager($this->pathToPPD);
47       $this->getPrinterReload ();
49       /* The user has already a valid PPD assigned
50        * Get some informations about this PPD
51        * and set it as selected. 
52        * The ppdpath ['link'] should be relative from .../ppd/modified/ 
53        *     e.g. "/Compaq/Compaq-J1200.ppd" */
54       if(($ppdfile!= NULL)&&(strlen($ppdfile)>0)){
55         $ppdfile = preg_replace("#".$this->pathToModified."#","",$ppdfile);
56         if(!file_exists($this->pathToPPD.$this->pathToModified.$ppdfile)){
57           print_red(sprintf(_("Can't open '%s', ppd settings resetted."),$ppdfile));
58         }else{
59           $res  = $this->ppdManager->loadDescription($this->pathToPPD.$this->pathToModified.$ppdfile);
60           if($res){
61             $tmp = split("\n",$res);
62             $tmp3 = array(); 
63             $tmp3['name']   = trim(preg_replace("/^\-/","",trim($tmp[1])));
64             $tmp3['link']   = $ppdfile;
65             $tmp3['ppd']    = $res;
66           }    
67           $this->selectedPPD = $tmp3;
68         }
69       }
70     }
71   }
74   function execute()
75   {
76     /* Call parent execute */
77     plugin::execute();
79     /* Fill templating stuff */
80     $display= "";
81     $smarty= get_smarty();
82     $smarty->assign("ppdString", _("Can't get ppd informations."));
83     $smarty->assign("showOptions", "");
85     /* Check these paths */
86     $paths = array($this->pathToPPD, $this->pathToPPD.$this->pathToModified);
88     /* If one of our required paths is not available, stop here and display some info */
89     foreach($paths as $path){
90     
91       /* Check if path is write/readable*/
92       $is_r = @is_readable($path);  
93       if(((!is_dir($path))||(empty($path)) || (!$is_r)) && (!@mkdir($path))){
94         print_red(sprintf(_("The specified path '%s' which results from PPD_PATH in your gosa.conf is invalid, can't read/write any ppd informations."),$path));
95         /* Print out template */
96         $display.= $smarty->fetch(get_template_path('printerPPDDialog.tpl', TRUE,dirname(__FILE__)));
97         return($display);
98       }
99     }
101     // PPD selection / upload / dialog handling 
103     /* Is there a new PPD file uploaded ? */
104     if((isset($_FILES['NewPPDFile']))&&(isset($_POST['SubmitNewPPDFile']))){
105       $file = ($_FILES['NewPPDFile']);
106       if($file['size'] != 0 ){
107         if($name = $this->AddPPD($file['tmp_name'])){
108           $this->SelectPPD($name); 
109         }
110       }else{
111         print_red(_("Please specify a valid ppd file."));
112       }
113     }
115     /* Open a dialog that allow us to select different PPDs */
116     if(isset($_POST['SelectPPD'])){
117       $this->dialog= new printerPPDSelectionDialog($this->config,$this->dn,$this->ppdList,$this->ppdListHeader,$this->selectedPPD);
118     }
120     /* The selection dialog fpr PPDs is canceled */
121     if(isset($_POST['ClosePPDSelection'])){
122       unset($this->dialog);
123       $this->dialog=NULL;
124     }
126     /* Div Selection */ 
127     if((isset($_GET['act']))&&($_GET['act']=="use")){
128       $this->SelectPPD(base64_decode($_GET['id']));
129       unset($this->dialog);
130       $this->dialog=NULL;
132     }
134     /* if a dialog is open, print the dialog instead of this class */
135     if($this->dialog!=NULL){
136       $display = $this->dialog->execute();
137       return($display);
138     }
140     // ENDE  PPD selection / upload / dialog handling 
142     /* Give smarty the information it needs */
143     $smarty->assign("ppdString" ,$this->getPPDInformation());
144     $tmp= $this->generateProperties();
145     if ($tmp == ""){
146       $smarty->assign("showOptions", 0);
147     } else {
148       $smarty->assign("showOptions", 1);
149       $smarty->assign("properties",$this->generateProperties());
150     }
152     /* Print out template */
153     $display.= $smarty->fetch(get_template_path('printerPPDDialog.tpl', TRUE,dirname(__FILE__)));
154     return($display);
155   }
158   /* Select PPD */
159   function SelectPPD($name)
160   {
161     /* Replace base path we don't need it here 
162        The path we need looks like this : "/Vendor/ModellName.ppd"; 
163        thats all */
164     $name = preg_replace("#".$this->pathToPPD."#","",$name);
166     /* Intialise some base vars */
167     $AbsoluteSourceName       = $this->pathToPPD.$name;   
168     $AbsoluteDestinationPath  = $this->pathToPPD.$this->pathToModified;
169     $Vendor                   = ""; // Vendor 
170     $Name                     = ""; // Name 
171     $Modell                   = ""; // Modell
172     $PrinterName              = ""; // The new name of the printer 
173     $PPDName                  = "";
174  
175     /* Force reload of config dialog */ 
176     $this->ppdConfig            = false;
177     $this->selectedPPD['link']  = false;
179     /* Get PPD informations and set vendor / modell / name */ 
180     if((!file_exists($AbsoluteSourceName)) || (!is_readable($AbsoluteSourceName))){
181       print_red(sprintf(_("Can't select PPD file '%s', the file is not readable"),$AbsoluteSourceName));   
182       return;
183     }
184     $res  = $this->ppdManager->loadDescription($AbsoluteSourceName);
185     if($res){
186       $tmp = split("\n",$res);
187       $Name   = trim(preg_replace("/^\-/","",trim($tmp[1])));
188       $Vendor = trim($tmp[0]);
189       $Model  = trim(preg_replace("/".$Vendor."/","",$Name));
190     }    
192     $PrinterName  = $this->cn."-".preg_replace("/[^a-z0-9-_\.]/i","_",$Name); 
193     $PPDName      = $Vendor."/".$PrinterName.".ppd";
194     
195     /* Create the vendors path, if it doesn't exists already */
196     if(!is_dir($AbsoluteDestinationPath.$Vendor)){
197       if(!(@mkdir($AbsoluteDestinationPath.$Vendor))){
198         print_red(sprintf(_("Can't create folder '%s' for the uploaded ppd file."),$AbsoluteDestinationPath.$Vendor));
199         return(false);
200       }
201     }
203     /* Create destination file handle */
204     $fp = @fopen($AbsoluteDestinationPath.$PPDName,"w+");
205     if(!$fp){
206       print_red(sprintf(_("Can't create file '%s' to store modifed ppd informations."),$AbsoluteDestinationPath.$PPDName));
207       return(false);
208     }
210     $str = file_get_contents($AbsoluteSourceName);
211     fputs($fp,$str);
212     @fclose($fp);
214     //$this->ppdManager->updateAttribute($filename,"NO_SECTION","ModelName",$printerName);
216     $tmp3['link']   =$PPDName;
217     $this->selectedPPD = $tmp3;
218     $this->getPrinterReload(); 
219     return($PPDName);
220   }
223   /* This function adds a new ppd file to the list of available ppds. 
224      All required paths and files will be created 
225       $_PathOnHdd e.g. = /tmp/PHP_tmpfile213452 */
226   function AddPPD($_PathOnHdd)
227   {
228     /* Check if file exists && is readable */
229     if((!is_file($_PathOnHdd)) || (!is_readable($_PathOnHdd))){
230       print_red(sprintf(_("Can't add new ppd file, the source file '%s' is not accessible."),$_PathOnHdd));
231       return(false);
232     }
233     
234     /* Reload list to detect changes e.g. a file has been deleted */
235     $this->getPrinterReload();
237     /* Get Description from ppd, & parse out some informations */   
238     $res  = @$this->ppdManager->loadDescription($_PathOnHdd);
239     if($res){
240       $tmp = split("\n",$res);
241       $name   = trim(preg_replace("/^\-/","",trim($tmp[1])));
242       $vendor = trim($tmp[0]);
243       $model  = trim(preg_replace("/".$vendor."/","",$name));
244     }    
246     /* Check if parse was successfull */
247     if(empty($name) || empty($vendor)){
248       print_red(sprintf(_("The given ppd file '%s' seams to be invalid, can't get any model or vendor informations."),$_PathOnHdd));
249       return(false);
250     }
252     /* Prepare list of ppds */
253     if(!isset($this->ppdList[$vendor])){
254       $this->ppdList[$vendor] = array();
255     }
257     /* Create ppd file and fill in the source contents */
258     $ppdname      = $vendor."/".$name.".ppd";
259     $filename     = $this->pathToPPD.preg_replace("/[^a-z0-9-_\.\/]/i","_",$ppdname);
260     $filename     = $this->pathToPPD.$ppdname;
261     $contents     = file_get_contents($_PathOnHdd);
263     /* Create the vendors path, if it doesn't exists already */
264     if(!is_dir($this->pathToPPD.$vendor)){
265       if(!(@mkdir($this->pathToPPD.$vendor))){
266         print_red(sprintf(_("Can't create folder '%s' for the uploaded ppd file."),$this->pathToPPD.$vendor));
267         return(false);
268       }
269     }
270   
271     /* Open file handle */
272     $fp           = fopen($filename,"w+");
274     /* Check file handle & contents */
275     if(!$fp){
276       print_red(sprintf(_("Can't save file '%s'."),$filename));
277       return;
278     }
279     if(empty($contents)){
280       print_red(_("Uploaded ppd file is empty, can't create new ppd file."));
281       return;
282     }
283     
284     /* Fille file with data */
285     fputs($fp,$contents);
286     @fclose($fp);
288     /* Our job is done here */
289     return($ppdname);
290   }
293   /* This function reloads the list of available printers/vendors 
294      $this->ppdListHeader 
295      Compaq        => 1
296      $this->ppdList
297      Compaq => Compaq IJ1200 => name => Compaq IJ1200 
298      link => /var/spool/ppd/Compaq/Compaq-J1200.ppd
299      ppd  => Compaq - Co    
300    */
301   function getPrinterReload()
302   {
303     if(is_readable($this->pathToPPD)){
304       $tmp = @$this->ppdManager->getPrinterList(true);
306       $this->ppdListHeader = $this->ppdList = array();
308       /* Sort all available files, and create header (Vendor index) */
309       foreach($tmp as $file=>$ppd){
311         if(preg_match("#".$this->pathToModified."#",$file)) continue;
313         $tmp2 = split("\n",$ppd);
314         if(!isset($this->ppdListHeader[$tmp2[0]])){
315           $this->ppdListHeader[$tmp2[0]]=0;
316         }
317         $tmp3['name']   =preg_replace("/^ -/","",$tmp2[1]." - ".$tmp2[2]);
318         $tmp3['link']   =$file;
319         $tmp3['ppd']    =$ppd;
320         $this->ppdListHeader[$tmp2[0]]++;
321         $this->ppdList[$tmp2[0]][preg_replace("/^ -/","",$tmp2[1]." - ".$tmp2[2])]=$tmp3;
322       }
323     }
324   }
327   /* Save all options posted from ppd dialog */
328   function save_object()
329   {
330     if(!((isset($_POST['PPDDisSubmitted'])) && (is_array($this->ppdConfig)))){
331       return;
332     }
334     foreach($this->ppdConfig as $cat => $obj){
335       foreach($obj as $attr => $attributes){
336         if(isset($_POST[base64_encode($attributes['_name'])])){
337           $this->ppdConfig[$cat][$attr]['_default'] = $_POST[base64_encode($attributes['_name'])];
338         }
339       }
340     }
341   }
344   /* Save modified ppd */
345   function save_ppd()
346   {
347     if($this->ppdManager){
348       $this->ppdManager->saveProperties($this->pathToPPD.$this->pathToModified.$this->selectedPPD['link'],$this->ppdConfig);
349     }
350   }
353   /* Return selected ppd path, if none is selected then false */
354   function save()
355   {
356     /* return the selected PPD, and in future the selected options too */
357     return($this->pathToModified.$this->selectedPPD['link']);
358   }
361   /* Get Information for a single PPD entry 
362    * This will be shown on top of template
363    */
364   function getPPDInformation()
365   {
366     $str = "none";
367     if(!empty($this->selectedPPD)){
368       $str = $this->ppdManager->loadDescription($this->pathToPPD.$this->pathToModified.$this->selectedPPD['link']);
369     }
370     return($str) ; 
371   }
374   /* Display all options from the selected ppd file */
375   function generateProperties()
376   { 
377     /* Set Headline */
378     $str = "";
379     $feed= "";
381     $s_ppd = $this->pathToPPD.$this->pathToModified.$this->selectedPPD['link'];
383     /* If ppd exists and is readable */
384     if((!empty($this->selectedPPD['link']))&&(file_exists($s_ppd))){
386       /* If there is no initial Configuration, load it */
387       if($this->ppdConfig == false){
388         $this->ppdConfig = $this->ppdManager->loadProperties($s_ppd);
389       }
391       /* Create a table */
392       $str .= "<div style='padding-left:30px;'><table summary=''>";
394       /* Input all data to the table */
395       foreach($this->ppdConfig as $cat => $obj){
397         /* Add new category */
398         $str .= "<tr><td colspan='2'>$feed";
399         if ($feed == ""){
400           $feed= "<br>";
401         }
402         $str .= "<b>"._("Section")." '".$cat."'&nbsp;</b><br>";
403         $str .= "</td></tr>";       
405         /* Add attributes of the current category */
406         foreach($obj as $attr => $settings){
408           /* Skip all entries beginning with _ */
409           if($attr[0] == "_") continue;  
411           /* Prepare data */
412           $values   = array();
413           $name     = $settings['_name'];
414           if (!isset($settings['_default'])){
415             $default  = "";
416           } else {
417             $default  = $settings['_default'];
418           }
419           $type     = $settings['_type'];
421           /* Add name to table */ 
422           $str .= "<tr><td style='padding-left:40px;'>\n";
423           $str .= $name."<br>\n";
424           $str .= "</td><td>\n";
426           /* Get all values */ 
427           foreach( $settings as $vname => $value){
428             if($vname[0] != "_"){
429               $values[$vname]= $value;
430             }
431           }
433           /* preparing Html output
434            * Supported types are PickOne/Boolean
435            */
437           /* If type is PickOne, create a select box */
438           if(($type == "PickOne")||(($type=="Boolean")&&(count($values)>1))){
440             $str  .=  "<select name='".base64_encode($name)."'>\n";
441             foreach($values as $optionKey => $value){
442               $selected = "";
443               if($optionKey == $default){
444                 $selected = " selected ";
445               }
446               $str  .=  "<option value='".$optionKey."' ".$selected.">".$value."</option>\n";
447             }
448             $str  .=  "</select>\n";
450           }elseif($type == "Boolean"){
452             /* If type is Boolean & no values are given */
453             $str  .=  "<select name='".base64_encode($name)."'>\n";
454             if($default == "False"){
455               $str  .=    "<option value='True' >"._("True")."</option>\n";
456               $str  .=    "<option value='False' selected>"._("False")."</option>\n";
457             }else{
458               $str  .=    "<option value='True' selected>"._("True")."</option>\n";
459               $str  .=    "<option value='False' >"._("False")."</option>\n";
460             }          
461             $str  .=  "</select>\n";
463           }else{
464             print_red(sprintf(_("Unsupported ppd type '%s' used for '%s' "),$type,$name));
465           }
466           $str .= "</td></tr>\n";
467         }
468       }
469       $str .= "</table></div>\n";
470     }
471     return($str);
472   }
474   function removeModifiedPPD()
475   {
476     $path = $this->pathToPPD.$this->pathToModified.$this->selectedPPD['link'];
478     if(file_exists($path)){
479       if(is_writeable($path)){
480         if(!@unlink($path)){
481           print_red(sprintf(_("Removing old ppd file '%s' failed."),$path));
482         }
483       }else{
484         print_red(sprintf(_("Removing old ppd file '%s' failed. File is not accessible."),$path));
485       }
486     }else{
487       print_red(sprintf(_("Removing old ppd file '%s' failed. File does not exists or is not accessible."),$path));
488     }
489   }
491   function update_ppd_url()
492   {
493     $this->SelectPPD("modified/".$this->selectedPPD['link']);
494     return("modified/".$this->selectedPPD['link']);
495   }
496   
497   function check()
498   {  
499     $message = plugin::check();
500     if(empty($this->selectedPPD['link'])){
501       $message[] = _("Please select a valid ppd file or use 'Cancel' to go back to printer configuration.");
502     }
503     return($message); 
504   }
506 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
507 ?>