c63a68a1d6b8af77398954e14feb1a6df1d70c6f
1 <?php
3 class printerPPDDialog extends plugin
4 {
5 /* CLI vars */
6 var $cli_summary = "Manage server basic objects";
7 var $cli_description = "Some longer text\nfor help";
8 var $cli_parameters = array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10 /* attribute list for save action */
11 var $ignore_account = TRUE;
12 var $attributes = array("cn");
13 var $objectclasses = array("whatever");
15 /* PPD Handling */
16 var $selectedPPD = false; // e.g. /vendor/device.ppd
17 var $ppdManager = false; // new ppdManager;
18 var $ppdConfig = false; // $this->ppdManager->loadProperties($this->selectedPPD['link']);
19 var $ppdList = array(); // Contains all Printer models
20 var $ppdListHeader = array(); // Contains all printer vendors
22 /* Paths */
23 var $pathToPPD = ""; // Base path, defined in gosa.conf e.g. "/var/spool/ppd/"
24 var $pathToModified = "modified/"; // used to store the modified ppds
26 /* Object Info */
27 var $cn = "" ; // Used to tag the ppds modified by the printer object,
28 var $dialog = NULL; // Contains sub dialogs
30 function printerPPDDialog ($config, $dn= NULL,$ppdfile=NULL )
31 {
32 plugin::plugin ($config, $dn);
33 $this->depselect = $this->config->current['BASE'];
35 /* Get PPD path and remove double //, and add trailing / */
36 if(isset($_SESSION['config']->data['MAIN']['PPD_PATH'])){
37 $this->pathToPPD = $_SESSION['config']->data['MAIN']['PPD_PATH'];
38 $this->pathToPPD= preg_replace("/\/\//", "/", $this->pathToPPD);
39 if(!preg_match("/\/$/",$this->pathToPPD)){
40 $this->pathToPPD = $this->pathToPPD."/";
41 }
42 }else{
43 $this->pathToPPD = "";
44 }
46 /* It seams that we have an existing PPD path, so go on */
47 if(!((!is_dir($this->pathToPPD))||(empty($this->pathToPPD)))){
49 /* Load all available PPD files and sort them into an array */
50 require_once ("class_ppdManager.inc");
51 $this->ppdManager= new ppdManager($this->pathToPPD);
52 $this->getPrinterReload ();
54 /* The user has already a valid PPD assigned
55 * Get some informations about this PPD
56 * and set it as selected.
57 * The ppdpath ['link'] should be relative from .../ppd/modified/
58 * e.g. "/Compaq/Compaq-J1200.ppd" */
59 if(($ppdfile!= NULL)&&(strlen($ppdfile)>0)){
60 $ppdfile = preg_replace("#".$this->pathToModified."#","",$ppdfile);
61 if(!file_exists($this->pathToPPD.$this->pathToModified.$ppdfile)){
62 print_red(sprintf(_("Can't open '%s', ppd settings resetted."),$ppdfile));
63 }else{
64 $res = $this->ppdManager->loadDescription($this->pathToPPD.$this->pathToModified.$ppdfile);
65 if($res){
66 $tmp = split("\n",$res);
67 $tmp3 = array();
68 $tmp3['name'] = trim(preg_replace("/^\-/","",trim($tmp[1])));
69 $tmp3['link'] = $ppdfile;
70 $tmp3['ppd'] = $res;
71 }
72 $this->selectedPPD = $tmp3;
73 }
74 }
75 }
76 }
79 function execute()
80 {
81 /* Call parent execute */
82 plugin::execute();
84 /* Fill templating stuff */
85 $display= "";
86 $smarty= get_smarty();
87 $smarty->assign("ppdString", _("Can't get ppd informations."));
88 $smarty->assign("showOptions", "");
90 /* Check these paths */
91 $paths = array($this->pathToPPD, $this->pathToPPD.$this->pathToModified);
93 /* If one of our required paths is not available, stop here and display some info */
94 foreach($paths as $path){
96 /* Check if path is write/readable*/
97 $is_r = @is_readable($path);
98 if((!is_dir($path))||(empty($path)) || (!$is_r)){
99 print_red(sprintf(_("The specified path '%s' which results from PPD_PATH in your gosa.conf is invalid,".
100 " can't read/write any ppd informations."),$path));
101 /* Print out template */
102 $display.= $smarty->fetch(get_template_path('printerPPDDialog.tpl', TRUE,dirname(__FILE__)));
103 return($display);
104 }
105 }
107 // PPD selection / upload / dialog handling
109 /* Is there a new PPD file uploaded ? */
110 if((isset($_FILES['NewPPDFile']))&&(isset($_POST['SubmitNewPPDFile']))){
111 $file = ($_FILES['NewPPDFile']);
112 if($file['size'] != 0 ){
113 if($name = $this->AddPPD($file['tmp_name'])){
114 $this->SelectPPD($name);
115 }
116 }else{
117 print_red(_("Please specify a valid ppd file."));
118 }
119 }
121 /* Open a dialog that allow us to select different PPDs */
122 if(isset($_POST['SelectPPD'])){
123 $this->dialog= new printerPPDSelectionDialog($this->config,$this->dn,$this->ppdList,$this->ppdListHeader,$this->selectedPPD);
124 }
126 /* The selection dialog fpr PPDs is canceled */
127 if(isset($_POST['ClosePPDSelection'])){
128 unset($this->dialog);
129 $this->dialog=NULL;
130 }
132 /* Div Selection */
133 if((isset($_GET['act']))&&($_GET['act']=="use")){
134 $this->SelectPPD(base64_decode($_GET['id']));
135 unset($this->dialog);
136 $this->dialog=NULL;
138 }
140 /* if a dialog is open, print the dialog instead of this class */
141 if($this->dialog!=NULL){
142 $display = $this->dialog->execute();
143 return($display);
144 }
146 // ENDE PPD selection / upload / dialog handling
148 /* Give smarty the information it needs */
149 $smarty->assign("ppdString" ,$this->getPPDInformation());
150 $tmp= $this->generateProperties();
151 if ($tmp == ""){
152 $smarty->assign("showOptions", 0);
153 } else {
154 $smarty->assign("showOptions", 1);
155 $smarty->assign("properties",$this->generateProperties());
156 }
158 /* Print out template */
159 $display.= $smarty->fetch(get_template_path('printerPPDDialog.tpl', TRUE,dirname(__FILE__)));
160 return($display);
161 }
164 /* Select PPD */
165 function SelectPPD($name)
166 {
167 /* Replace base path we don't need it here
168 The path we need looks like this : "/Vendor/ModellName.ppd";
169 thats all */
170 $name = preg_replace("#".$this->pathToPPD."#","",$name);
172 /* Intialise some base vars */
173 $AbsoluteSourceName = $this->pathToPPD.$name;
174 $AbsoluteDestinationPath = $this->pathToPPD.$this->pathToModified;
175 $Vendor = ""; // Vendor
176 $Name = ""; // Name
177 $Modell = ""; // Modell
178 $PrinterName = ""; // The new name of the printer
179 $PPDName = "";
181 /* Force reload of config dialog */
182 $this->ppdConfig = false;
183 $this->selectedPPD['link'] = false;
185 /* Get PPD informations and set vendor / modell / name */
186 if((!file_exists($AbsoluteSourceName)) || (!is_readable($AbsoluteSourceName))){
187 print_red(sprintf(_("Can't select PPD file '%s', the file is not readable"),$AbsoluteSourceName));
188 return;
189 }
190 $res = $this->ppdManager->loadDescription($AbsoluteSourceName);
191 if($res){
192 $tmp = split("\n",$res);
193 $Name = trim(preg_replace("/^\-/","",trim($tmp[1])));
194 $Vendor = trim($tmp[0]);
195 $Model = trim(preg_replace("/".$Vendor."/","",$Name));
196 }
198 $PrinterName = $this->cn."-".$Name;
199 $PPDName = $Vendor."/".$PrinterName.".ppd";
201 /* Create the vendors path, if it doesn't exists already */
202 if(!is_dir($AbsoluteDestinationPath.$Vendor)){
203 if(!(@mkdir($AbsoluteDestinationPath.$Vendor))){
204 print_red(sprintf(_("Can't create folder '%s' for the uploaded ppd file."),$AbsoluteDestinationPath.$Vendor));
205 return(false);
206 }
207 }
209 /* Create destination file handle */
210 $fp = @fopen($AbsoluteDestinationPath.$PPDName,"w+");
211 if(!$fp){
212 print_red(sprintf(_("Can't create file '%s' to store modifed ppd informations."),$AbsoluteDestinationPath.$PPDName));
213 return(false);
214 }
216 $str = file_get_contents($AbsoluteSourceName);
217 fputs($fp,$str);
218 @fclose($fp);
220 //$this->ppdManager->updateAttribute($filename,"NO_SECTION","ModelName",$printerName);
222 $tmp3['link'] =$PPDName;
223 $this->selectedPPD = $tmp3;
224 $this->getPrinterReload();
225 return($PPDName);
226 }
229 /* This function adds a new ppd file to the list of available ppds.
230 All required paths and files will be created
231 $_PathOnHdd e.g. = /tmp/PHP_tmpfile213452 */
232 function AddPPD($_PathOnHdd)
233 {
234 /* Check if file exists && is readable */
235 if((!is_file($_PathOnHdd)) || (!is_readable($_PathOnHdd))){
236 print_red(sprintf(_("Can't add new ppd file, the source file '%s' is not accessible."),$_PathOnHdd));
237 return(false);
238 }
240 /* Reload list to detect changes e.g. a file has been deleted */
241 $this->getPrinterReload();
243 /* Get Description from ppd, & parse out some informations */
244 $res = @$this->ppdManager->loadDescription($_PathOnHdd);
245 if($res){
246 $tmp = split("\n",$res);
247 $name = trim(preg_replace("/^\-/","",trim($tmp[1])));
248 $vendor = trim($tmp[0]);
249 $model = trim(preg_replace("/".$vendor."/","",$name));
250 }
252 /* Check if parse was successfull */
253 if(empty($name) || empty($vendor)){
254 print_red(sprintf(_("The given ppd file '%s' seams to be invalid, can't get any modell or vendor informations."),$_PathOnHdd));
255 return(false);
256 }
258 /* Prepare list of ppds */
259 if(!isset($this->ppdList[$vendor])){
260 $this->ppdList[$vendor] = array();
261 }
263 /* Check if this ppd already exists */
264 $found = false;
265 foreach($this->ppdList[$vendor] as $key => $val){
266 if(preg_match("/".$model.".*/i",$key)){
267 $found = true;
268 print_red(sprintf(_("There is already a ppd file for this kind of printer.")));
269 return;
270 }
271 }
273 /* Create the vendors path, if it doesn't exists already */
274 if(!is_dir($this->pathToPPD.$vendor)){
275 if(!(@mkdir($this->pathToPPD.$vendor))){
276 print_red(sprintf(_("Can't create folder '%s' for the uploaded ppd file."),$this->pathToPPD.$vendor));
277 return(false);
278 }
279 }
281 /* Create ppd file and fill in the source contents */
282 $ppdname = $vendor."/".$name.".ppd";
283 $filename = $this->pathToPPD.$ppdname;
284 $fp = fopen($filename,"w+");
285 $contents = file_get_contents($_PathOnHdd);
287 /* Check file handle & contents */
288 if(!$fp){
289 print_red(sprintf(_("Can't save file '%s'."),$filename));
290 return;
291 }
292 if(empty($contents)){
293 print_red(_("Uploaded ppd file is empty, can't create new ppd file."));
294 return;
295 }
297 /* Fille file with data */
298 fputs($fp,$contents);
299 @fclose($fp);
301 /* Our job is done here */
302 return($ppdname);
303 }
306 /* This function reloads the list of available printers/vendors
307 $this->ppdListHeader
308 Compaq => 1
309 $this->ppdList
310 Compaq => Compaq IJ1200 => name => Compaq IJ1200
311 link => /var/spool/ppd/Compaq/Compaq-J1200.ppd
312 ppd => Compaq - Co
313 */
314 function getPrinterReload()
315 {
316 $tmp = $this->ppdManager->getPrinterList(true);
318 $this->ppdListHeader = $this->ppdList = array();
320 /* Sort all available files, and create header (Vendor index) */
321 foreach($tmp as $file=>$ppd){
323 if(preg_match("#".$this->pathToModified."#",$file)) continue;
325 $tmp2 = split("\n",$ppd);
326 if(!isset($this->ppdListHeader[$tmp2[0]])){
327 $this->ppdListHeader[$tmp2[0]]=0;
328 }
329 $tmp3['name'] =preg_replace("/^ -/","",$tmp2[1]." - ".$tmp2[2]);
330 $tmp3['link'] =$file;
331 $tmp3['ppd'] =$ppd;
332 $this->ppdListHeader[$tmp2[0]]++;
333 $this->ppdList[$tmp2[0]][preg_replace("/^ -/","",$tmp2[1]." - ".$tmp2[2])]=$tmp3;
334 }
335 }
338 /* Save all options posted from ppd dialog */
339 function save_object()
340 {
341 if(!((isset($_POST['PPDDisSubmitted'])) && (is_array($this->ppdConfig)))){
342 return;
343 }
345 foreach($this->ppdConfig as $cat => $obj){
346 foreach($obj as $attr => $attributes){
347 if(isset($_POST[base64_encode($attributes['_name'])])){
348 $this->ppdConfig[$cat][$attr]['_default'] = $_POST[base64_encode($attributes['_name'])];
349 }
350 }
351 }
352 }
355 /* Save modified ppd */
356 function save_ppd(){
357 if($this->ppdManager){
358 $this->ppdManager->saveProperties($this->pathToPPD.$this->pathToModified.$this->selectedPPD['link'],$this->ppdConfig);
359 }
360 }
363 /* Return selected ppd path, if none is selected then false */
364 function save()
365 {
366 /* return the selected PPD, and in future the selected options too */
367 return($this->pathToModified.$this->selectedPPD['link']);
368 }
371 /* Get Information for a single PPD entry
372 * This will be shown on top of template
373 */
374 function getPPDInformation()
375 {
376 $str = "none";
377 if(!empty($this->selectedPPD)){
378 $str = $this->ppdManager->loadDescription($this->pathToPPD.$this->pathToModified.$this->selectedPPD['link']);
379 }
380 return($str) ;
381 }
384 /* Display all options from the selected ppd file */
385 function generateProperties()
386 {
387 /* Set Headline */
388 $str = "";
389 $feed= "";
391 $s_ppd = $this->pathToPPD.$this->pathToModified.$this->selectedPPD['link'];
393 /* If ppd exists and is readable */
394 if((!empty($this->selectedPPD['link']))&&(file_exists($s_ppd))){
396 /* If there is no initial Configuration, load it */
397 if($this->ppdConfig == false){
398 $this->ppdConfig = $this->ppdManager->loadProperties($s_ppd);
399 }
401 /* Create a table */
402 $str .= "<div style='padding-left:30px;'><table summary=''>";
404 /* Input all data to the table */
405 foreach($this->ppdConfig as $cat => $obj){
407 /* Add new category */
408 $str .= "<tr><td colspan='2'>$feed";
409 if ($feed == ""){
410 $feed= "<br>";
411 }
412 $str .= "<b>"._("Section")." '".$cat."' </b><br>";
413 $str .= "</td></tr>";
415 /* Add attributes of the current category */
416 foreach($obj as $attr => $settings){
418 /* Skip all entries beginning with _ */
419 if($attr[0] == "_") continue;
421 /* Prepare data */
422 $values = array();
423 $name = $settings['_name'];
424 $default = $settings['_default'];
425 $type = $settings['_type'];
427 /* Add name to table */
428 $str .= "<tr><td style='padding-left:40px;'>\n";
429 $str .= $name."<br>\n";
430 $str .= "</td><td>\n";
432 /* Get all values */
433 foreach( $settings as $vname => $value){
434 if($vname[0] != "_"){
435 $values[$vname]= $value;
436 }
437 }
439 /* preparing Html output
440 * Supported types are PickOne/Boolean
441 */
443 /* If type is PickOne, create a select box */
444 if(($type == "PickOne")||(($type=="Boolean")&&(count($values)>1))){
446 $str .= "<select name='".base64_encode($name)."'>\n";
447 foreach($values as $optionKey => $value){
448 $selected = "";
449 if($optionKey == $default){
450 $selected = " selected ";
451 }
452 $str .= "<option value='".$optionKey."' ".$selected.">".$value."</option>\n";
453 }
454 $str .= "</select>\n";
456 }elseif($type == "Boolean"){
458 /* If type is Boolean & no values are given */
459 $str .= "<select name='".base64_encode($name)."'>\n";
460 if($default == "False"){
461 $str .= "<option value='True' >"._("True")."</option>\n";
462 $str .= "<option value='False' selected>"._("False")."</option>\n";
463 }else{
464 $str .= "<option value='True' selected>"._("True")."</option>\n";
465 $str .= "<option value='False' >"._("False")."</option>\n";
466 }
467 $str .= "</select>\n";
469 }else{
470 print_red(sprintf(_("Unsupported ppd type '%s' used for '%s' "),$type,$name));
471 }
472 $str .= "</td></tr>\n";
473 }
474 }
475 $str .= "</table></div>\n";
476 }
477 return($str);
478 }
480 function check(){ return(plugin::check()); }
481 }
482 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
483 ?>