1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id: class_opsiLicenses.inc 13520 2009-03-09 14:54:13Z hickert $$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
24 class licensePoolGeneric extends plugin
25 {
27 var $cn = "";
28 var $orig_cn = "";
29 var $description = "";
30 var $orig_dn = "";
32 var $data = array();
33 var $orig_data = array();
34 var $productIds = array();
35 var $softwareIds= array();
36 var $licenses = array();
37 var $orig_licenses = array();
39 var $availableProductIds = array();
40 var $attributes =array("cn","description");
41 var $si = NULL;
43 var $opsiHosts = array();
45 var $licenseMap = array(
46 "BOUNDTOHOST"=> "boundToHost",
47 "HOSTIDS"=> "usedByHost",
48 "LICENSEPOOLIDS"=> "licensePoolId",
49 "LICENSETYPE"=> "licenseModel",
50 "LICENSEKEYS"=> "licenseKey",
51 "MAXINSTALLATIONS"=> "maximumInstallations",
52 "EXPIRATIONDATE"=> "expirationDate",
53 "SOFTWARELICENSEID"=> "cn"
54 );
56 var $licenseContractMap = array(
57 "CONCLUSIONDATE"=> "conclusionDate",
58 "NOTIFICATIONDATE"=> "notificationDate",
59 "NOTES"=> "description",
60 "PARTNER"=> "partner"
61 );
63 function __construct(&$config,$dn)
64 {
65 $this->config = $config;
66 $this->dn = $this->orig_dn = $dn;
68 // initialize gosa-si handle for opsi licenses
69 $this->si = new opsiLicenceHandler($this->config);
71 // Detect if this is a new or existings license
72 $this->is_account=TRUE;
73 if($this->dn == "new"){
74 $this->initially_was_account = FALSE;
75 }else{
76 $this->initially_was_account = TRUE;
78 // Extract pool name out of the fake dn.
79 $this->cn = $this->orig_cn = preg_replace("/^opsi:cn=([^,]*),.*$/","\\1",$dn);
80 }
82 $this->init();
83 }
86 function init()
87 {
88 // Load local Boot Products
89 $res = $this->si->get_local_products();
90 $this->availableProductIds=array();
91 if($this->si->is_error()){
92 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
93 $this->init_successfull = FALSE;
94 return(FALSE);
95 }
96 $this->availableProductIds=array_keys($res);
98 // Load opsi hosts
99 $res = $this->si->list_clients();
100 $this->opsiHosts=array();
101 if($this->si->is_error()){
102 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
103 $this->init_successfull = FALSE;
104 return(FALSE);
105 }
106 $this->opsiHosts=$res;
108 // Load Pool
109 if(!$this->initially_was_account){
110 $this->init_successfull = TRUE;
111 }else{
112 $res = $this->si->getPool($this->cn);
113 if($this->si->is_error()){
114 $this->init_successfull = FALSE;
115 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
116 return(FALSE);
117 }else{
118 $this->data = $this->orig_data = $res;
119 $this->description = $this->data['description'][0];
121 // Load software IDs
122 $this->softwareIds = array();
123 if(isset($this->data['softwareId'])){
124 for($i = 0; $i < $this->data['softwareId']['count']; $i++){
125 $this->softwareIds[] = $this->data['softwareId'][$i];
126 }
127 }
129 // Load product IDs
130 $this->productIds = array();
131 if(isset($this->data['productId'])){
132 for($i = 0; $i < $this->data['productId']['count']; $i++){
133 $this->productIds[] = $this->data['productId'][$i];
134 }
135 }
137 // Load Licences
138 $this->licenses = array();
139 if(isset($this->data['licenses'])){
140 for($i =0; $i< $this->data['licenses']['count']; $i++){
141 $license = $this->data['licenses'][$i];
143 // Do not parse invalid licenses
144 if(!is_array($license) || !isset($license['LICENSEPOOLIDS'])){
145 continue;
146 }
148 // Prepare Software License Key(s)
149 $upper = strtoupper($license['LICENSEPOOLIDS'][0]['VALUE']);
150 $license['LICENSEKEYS'] = $license['LICENSEKEYS'][0][$upper];
152 // Map license attributes to a useable format
153 $entry = array();
154 foreach($this->licenseMap as $source => $target){
155 $entry[$target] = "";
156 if(isset($license[$source])){
157 if(count($license[$source]) >= 2){
158 $entry[$target] = array();
159 foreach($license[$source] as $sub){
160 $entry[$target][] = $sub['VALUE'];
161 }
162 }elseif(isset($license[$source][0]['VALUE'])){
163 $entry[$target] = $license[$source][0]['VALUE'];
164 }
165 }
166 }
168 // Extract contract data
169 $lData= $license['LICENSECONTRACTDATA'][0];
170 foreach($this->licenseContractMap as $source => $target){
171 if(isset($lData[$source])){
172 if(count($lData[$source]) >= 2){
173 $entry[$target] = array();
174 foreach($lData[$source] as $sub){
175 $entry[$target][] = $sub['VALUE'];
176 }
177 }elseif(isset($lData[$source][0]['VALUE'])){
178 $entry[$target] = $lData[$source][0]['VALUE'];
179 }
180 }
181 }
183 // There are some multi value attributes - force them to be of type array.
184 foreach(array("boundToHost","usedByHost","licenseKey") as $attr){
185 if(!is_array($entry[$attr])){
186 $entry[$attr] = array($entry[$attr]);
187 }
188 }
189 $entry['MODIFIED'] = FALSE;
190 $this->licenses[$entry['cn']] = $entry;
191 }
192 }
194 $this->orig_licenses = $this->licenses;
195 $this->init_successfull = TRUE;
196 return;
197 }
198 }
199 }
202 function execute()
203 {
204 plugin::execute();
205 // Handle initialization failures.
206 if(isset($_POST['retry_init'])) $this->init();
207 if(!$this->init_successfull){
208 $smarty = get_smarty();
209 $smarty->assign("init_successfull", $this->init_successfull);
210 return($smarty->fetch(get_template_path('licensePoolGeneric.tpl',TRUE,dirname(__FILE__))));
211 }
213 // Display dialogs!
214 if($this->dialog instanceOf plugin){
215 $this->dialog->save_object();
216 $display = $this->dialog->execute();
217 $display.= "<p style=\"text-align:right\">";
219 if($this->acl_is_writeable("licenses")){
220 $display.="<input type=submit name=\"license_finish\" style=\"width:80px\"
221 value=\"".msgPool::okButton(). "\"> ";
222 }
224 $display.="<input type=submit name=\"license_cancel\" value=\"".msgPool::cancelButton()."\"></p>";
225 return($display);
226 }
228 $smarty = get_smarty();
230 // Assign ACls
231 $plInfo = $this->plInfo();
232 foreach($plInfo['plProvidedAcls'] as $name => $desc){
233 $smarty->assign("{$name}ACL",$this->getacl($name));
234 }
235 foreach($this->attributes as $attr){
236 $smarty->assign($attr,$this->$attr);
237 }
238 $smarty->assign("init_successfull", $this->init_successfull);
239 $smarty->assign("availableProductIds", array_diff( $this->availableProductIds, $this->productIds));
240 $smarty->assign("productIds", $this->productIds);
241 $smarty->assign("softwareIds", $this->softwareIds);
242 $smarty->assign("licenses", $this->getLicenseList());
243 $smarty->assign("initially_was_account", $this->initially_was_account);
244 return($smarty->fetch(get_template_path('licensePoolGeneric.tpl',TRUE,dirname(__FILE__))));
245 }
248 // Creates a divSelectBox and fills it with license entries
249 function getLicenseList()
250 {
251 $list = new divSelectBox("test");
252 $list->setHeight(100);
253 if($this->acl_is_readable("licenses")){
254 $editlink = "<a href='?plug=".$_GET['plug']."&act=edit&id=%s'>%s</a>";
255 foreach($this->licenses as $i => $license){
256 $link = image("images/lists/edit.png","editLicense_{$i}");
257 if(preg_match("/w/", $this->getacl("licenses"))){
258 $link.= image("images/lists/trash.png","removeLicense_{$i}");
259 }
261 $maxInst = "";
262 if($license['maximumInstallations'] == 0){
263 $maxInst = _("unlimited");
264 }else{
265 $maxInst = $license['maximumInstallations'];
266 }
269 $map = array(
270 "VOLUME" => sprintf(_("Volume license (#%s)"), $maxInst),
271 "OEM"=>_("OEM"),
272 "RETAIL"=>_("Retail"),
273 "CONCURRENT"=>_("Concurrent"));
275 $f1 = array("string" => sprintf($editlink,$i,$license['cn']));
276 $f2 = array("string" => sprintf($editlink,$i,$map[$license['licenseModel']]));
277 $f6 = array("string" => $link, "attach" => "style='border-right: 0px; width:32px;'");
278 $list->addEntry(array($f1,$f2,$f6));
279 }
280 }
281 return($list->DrawList());
282 }
285 /* Save HTML inputs
286 */
287 function save_object()
288 {
289 // Allow license edit via href links
290 if(isset($_GET['act']) && $_GET['act'] == 'edit' && isset($_GET['id'])){
291 $id = trim($_GET['id']);
292 if(isset($this->licenses[$id])){
293 $this->dialog = new licenseGeneric($this->config,$this->dn,$this->licenses[$id], $this->opsiHosts);
294 $this->dialog->set_acl_category('opsi');
295 $this->dialog->set_acl_base($this->config->current['BASE']);
296 }
297 }
299 // Close license edit dialogs.
300 if($this->dialog instanceOf plugin && isset($_POST['license_cancel'])){
301 $this->dialog = NULL;
302 return;
303 }
305 // Save license modifications
306 if($this->dialog instanceOf plugin && isset($_POST['license_finish'])){
307 $this->dialog->save_object();
308 $msgs = $this->dialog->check();
309 if(count($msgs)){
310 msg_dialog::displayChecks($msgs);
311 }else{
312 $attrs = $this->dialog->save();
313 $attrs['MODIFIED'] = TRUE;
314 $this->licenses[$attrs['cn']] = $attrs;
315 $this->dialog = NULL;
316 }
317 return;
318 }
320 if(isset($_POST['opsiLicensePoolPosted'])){
321 plugin::save_object();
323 // Restore license cn, to avoid creating a copy...
324 if($this->initially_was_account) $this->cn = $this->orig_cn;
326 // We've to add prodcuts here
327 if(preg_match("/w/",$this->getacl("productIds"))){
328 if(isset($_POST['availableProduct']) && isset($_POST['addProduct'])){
329 $pro = get_post('availableProduct');
330 if(isset($this->availableProductIds[$pro]) && !in_array($this->availableProductIds[$pro], $this->productIds)){
331 $this->productIds[] =$this->availableProductIds[$pro];
332 }
333 }
334 }
336 // We've to remove products here
337 if(preg_match("/w/",$this->getacl("productIds"))){
338 if(isset($_POST['productIds']) && isset($_POST['removeProduct'])){
339 foreach($_POST['productIds'] as $key){
340 if(isset($this->productIds[$key])){
341 unset($this->productIds[$key]);
342 }
343 }
344 }
345 }
347 // We've to add software here
348 if(preg_match("/w/",$this->getacl("windowsSoftwareIds"))){
349 if(isset($_POST['newSoftwareId']) && isset($_POST['addSoftware'])){
350 $soft = trim(get_post('newSoftwareId'));
351 if(!empty($soft) && !in_array($soft, $this->softwareIds)){
352 $this->softwareIds[] = $soft;
353 }
354 }
355 }
357 // We've to remove software Ids here
358 if(preg_match("/w/",$this->getacl("windowsSoftwareIds"))){
359 if(isset($_POST['softwareIds']) && isset($_POST['removeSoftware'])){
360 foreach($_POST['softwareIds'] as $key){
361 if(isset($this->softwareIds[$key])){
362 unset($this->softwareIds[$key]);
363 }
364 }
365 }
366 }
368 // We've to create a new license
369 if(preg_match("/w/",$this->getacl("licenses"))){
370 if(isset($_POST['addLicense'])){
371 $this->dialog = new licenseGeneric($this->config,$this->dn,array(), $this->opsiHosts);
372 $this->dialog->set_acl_category('opsi');
373 $this->dialog->set_acl_base($this->config->current['BASE']);
374 }
375 }
377 // Search post for image button clicks.
378 if(preg_match("/r/",$this->getacl("licenses"))){
379 foreach($_POST as $name => $value){
380 if(preg_match("/^editLicense_/",$name)){
381 $id = preg_replace("/^editLicense_(.*)$/","\\1",$name);
382 if(isset($this->licenses[$id])){
383 $this->dialog = new licenseGeneric($this->config,$this->dn,$this->licenses[$id], $this->opsiHosts);
384 $this->dialog->set_acl_category('opsi');
385 $this->dialog->set_acl_base($this->config->current['BASE']);
386 }
387 break;
388 }
389 if(preg_match("/^removeLicense_/",$name)){
390 $id = preg_replace("/^removeLicense_(.*)$/","\\1",$name);
391 if(isset($this->licenses[$id])){
392 unset($this->licenses[$id]);
393 }
394 break;
395 }
396 }
397 }
398 }
399 }
402 /* Check user input and return a list of 'invalid input' messages.
403 */
404 function check()
405 {
406 $message = plugin::check();
407 return($message);
408 }
412 /* Removes the object from the opsi database
413 */
414 function remove_from_parent()
415 {
416 $this->si->deletePool($this->orig_cn);
417 if($this->si->is_error()){
418 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
419 }else{
421 // Trigger remove signal
422 $this->handle_post_events("remove");
423 }
425 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$this->si->get_error());
426 }
429 /* Saves object modifications
430 */
431 function save()
432 {
433 plugin::save();
435 // Send modify/add events
436 $mode = "modify";
437 if($this->orig_dn == "new"){
438 $mode = "add";
439 }
441 // Create or update the pool
442 $this->si->createPool($this->cn, $this->description,$this->productIds,$this->softwareIds);#
443 if($this->si->is_error()){
444 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
445 }else{
446 $this->handle_post_events($mode);
447 }
449 // Create, remove or update licenses
450 $add = array_diff_assoc($this->licenses,$this->orig_licenses);
451 $del = array_diff_assoc($this->orig_licenses,$this->licenses);
452 $update = array_intersect($this->licenses,$this->orig_licenses);
454 // Remove licenses
455 foreach($del as $license){
456 $this->si->removeLicenseFromPool($this->cn, $license['cn']);
457 if($this->si->is_error()){
458 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
459 }
460 }
462 // Add licenses
463 foreach($add as $license){
464 $this->si->createLicense(
465 $this->cn, // Pool id
466 $license['cn'],
467 $license['licenseKey'][0],
468 $license['licenseModel'],
469 $license['partner'],
470 $license['conclusionDate'],
471 $license['notificationDate'],
472 $license['description'],
473 $license['cn'],
474 $license['maximumInstallations'],
475 $license['boundToHost'],
476 $license['expirationDate']);
478 if($this->si->is_error()){
479 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
480 }
481 }
483 // Update licenses
484 foreach($update as $license){
486 // Do not save untouched licenses
487 if(!$license['MODIFIED']){
488 continue;
489 }
491 $this->si->createLicense(
492 $this->cn, // Pool id
493 $license['cn'],
494 $license['licenseKey'][0],
495 $license['licenseModel'],
496 $license['partner'],
497 $license['conclusionDate'],
498 $license['notificationDate'],
499 $license['description'],
500 $license['cn'],
501 $license['maximumInstallations'],
502 $license['boundToHost'],
503 $license['expirationDate']);
505 if($this->si->is_error()){
506 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
507 }
508 }
510 // Log action
511 if($mode == "modify"){
512 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$this->si->get_error());
513 }else{
514 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$this->si->get_error());
515 }
517 return 0;
518 }
520 static function plInfo()
521 {
522 return (array(
523 "plShortName" => _("Pool generic"),
524 "plDescription" => _("License pool generic"),
525 "plSelfModify" => FALSE,
526 "plDepends" => array(),
527 "plPriority" => 7,
528 "plSection" => array("administration"),
529 "plCategory" => array("opsi"),
530 "plProvidedAcls"=> array(
531 "cn" => _("Name"),
532 "description" => _("Description"),
533 "productIds" => _("Applications"),
534 "windowsSoftwareIds" => _("Windows software IDs"),
535 "licenses" => _("Licenses"))
536 ));
537 }
538 }
541 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
542 ?>