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();
84 // Prepare lists
85 $this->licenseList = new sortableListing();
86 $this->licenseList->setDeleteable(true);
87 $this->licenseList->setEditable(true);
88 $this->licenseList->setWidth("100%");
89 $this->licenseList->setHeight("120px");
90 $this->licenseList->setColspecs(array('200px','*'));
91 $this->licenseList->setHeader(array(_("Section"),_("Description")));
92 $this->licenseList->setDefaultSortColumn(1);
94 }
97 function init()
98 {
99 // Load local Boot Products
100 $res = $this->si->get_local_products();
101 $this->availableProductIds=array();
102 if($this->si->is_error()){
103 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
104 $this->init_successfull = FALSE;
105 return(FALSE);
106 }
107 $this->availableProductIds=array_keys($res);
109 // Load opsi hosts
110 $res = $this->si->list_clients();
111 $this->opsiHosts=array();
112 if($this->si->is_error()){
113 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
114 $this->init_successfull = FALSE;
115 return(FALSE);
116 }
117 $this->opsiHosts=$res;
119 // Load Pool
120 if(!$this->initially_was_account){
121 $this->init_successfull = TRUE;
122 }else{
123 $res = $this->si->getPool($this->cn);
124 if($this->si->is_error()){
125 $this->init_successfull = FALSE;
126 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
127 return(FALSE);
128 }else{
129 $this->data = $this->orig_data = $res;
130 $this->description = $this->data['description'][0];
132 // Load software IDs
133 $this->softwareIds = array();
134 if(isset($this->data['softwareId'])){
135 for($i = 0; $i < $this->data['softwareId']['count']; $i++){
136 $this->softwareIds[] = $this->data['softwareId'][$i];
137 }
138 }
140 // Load product IDs
141 $this->productIds = array();
142 if(isset($this->data['productId'])){
143 for($i = 0; $i < $this->data['productId']['count']; $i++){
144 $this->productIds[] = $this->data['productId'][$i];
145 }
146 }
148 // Load Licences
149 $this->licenses = array();
150 if(isset($this->data['licenses'])){
151 for($i =0; $i< $this->data['licenses']['count']; $i++){
152 $license = $this->data['licenses'][$i];
154 // Do not parse invalid licenses
155 if(!is_array($license) || !isset($license['LICENSEPOOLIDS'])){
156 continue;
157 }
159 // Prepare Software License Key(s)
160 $upper = strtoupper($license['LICENSEPOOLIDS'][0]['VALUE']);
161 $license['LICENSEKEYS'] = $license['LICENSEKEYS'][0][$upper];
163 // Map license attributes to a useable format
164 $entry = array();
165 foreach($this->licenseMap as $source => $target){
166 $entry[$target] = "";
167 if(isset($license[$source])){
168 if(count($license[$source]) >= 2){
169 $entry[$target] = array();
170 foreach($license[$source] as $sub){
171 $entry[$target][] = $sub['VALUE'];
172 }
173 }elseif(isset($license[$source][0]['VALUE'])){
174 $entry[$target] = $license[$source][0]['VALUE'];
175 }
176 }
177 }
179 // Extract contract data
180 $lData= $license['LICENSECONTRACTDATA'][0];
181 foreach($this->licenseContractMap as $source => $target){
182 if(isset($lData[$source])){
183 if(count($lData[$source]) >= 2){
184 $entry[$target] = array();
185 foreach($lData[$source] as $sub){
186 $entry[$target][] = $sub['VALUE'];
187 }
188 }elseif(isset($lData[$source][0]['VALUE'])){
189 $entry[$target] = $lData[$source][0]['VALUE'];
190 }
191 }
192 }
194 // There are some multi value attributes - force them to be of type array.
195 foreach(array("boundToHost","usedByHost","licenseKey") as $attr){
196 if(!is_array($entry[$attr])){
197 $entry[$attr] = array($entry[$attr]);
198 }
199 }
200 $entry['MODIFIED'] = FALSE;
201 $this->licenses[$entry['cn']] = $entry;
202 }
203 }
205 $this->orig_licenses = $this->licenses;
206 $this->init_successfull = TRUE;
207 return;
208 }
209 }
210 }
213 function execute()
214 {
215 plugin::execute();
217 $this->licenseList->setAcl($this->getacl('licenses'));
219 // Handle initialization failures.
220 if(isset($_POST['retry_init'])) $this->init();
221 if(!$this->init_successfull){
222 $smarty = get_smarty();
223 $smarty->assign("init_successfull", $this->init_successfull);
224 return($smarty->fetch(get_template_path('licensePoolGeneric.tpl',TRUE,dirname(__FILE__))));
225 }
227 // Display dialogs!
228 if($this->dialog instanceOf plugin){
229 $this->dialog->save_object();
230 $display = $this->dialog->execute();
231 $display.= "<hr><div class='plugin-actions'>";
232 if($this->acl_is_writeable("licenses")){
233 $display.="<button type='submit' name='license_finish'>".msgPool::okButton()."</button>";
234 }
235 $display.="<button type='submit' name='license_cancel'>".msgPool::cancelButton()."</button>";
236 $display.="</div>";
237 return($display);
238 }
240 $smarty = get_smarty();
242 // Assign ACls
243 $plInfo = $this->plInfo();
244 foreach($plInfo['plProvidedAcls'] as $name => $desc){
245 $smarty->assign("{$name}ACL",$this->getacl($name));
246 }
247 foreach($this->attributes as $attr){
248 $smarty->assign($attr,$this->$attr);
249 }
250 $smarty->assign("init_successfull", $this->init_successfull);
251 $smarty->assign("availableProductIds", array_diff( $this->availableProductIds, $this->productIds));
252 $smarty->assign("productIds", $this->productIds);
253 $smarty->assign("softwareIds", $this->softwareIds);
254 $smarty->assign("licenses", $this->getLicenseList());
255 $smarty->assign("initially_was_account", $this->initially_was_account);
256 return($smarty->fetch(get_template_path('licensePoolGeneric.tpl',TRUE,dirname(__FILE__))));
257 }
260 // Creates a divSelectBox and fills it with license entries
261 function getLicenseList()
262 {
264 $data = $lData = array();
266 if($this->acl_is_readable("licenses")){
267 foreach($this->licenses as $i => $license){
268 $maxInst = "";
269 if($license['maximumInstallations'] == 0){
270 $maxInst = _("unlimited");
271 }else{
272 $maxInst = $license['maximumInstallations'];
273 }
275 $map = array(
276 "VOLUME" => sprintf(_("Volume license (#%s)"), $maxInst),
277 "OEM"=>_("OEM"),
278 "RETAIL"=>_("Retail"),
279 "CONCURRENT"=>_("Concurrent"));
281 $data[$license['cn']] = $license['cn'];
282 $lData[$license['cn']] = array('data' => array($license['cn'],$map[$license['licenseModel']]));
283 }
284 }
285 $this->licenseList->setListData($data,$lData);
286 return($this->licenseList->render());
287 }
290 /* Save HTML inputs
291 */
292 function save_object()
293 {
295 $this->licenseList->save_object();
296 $tmp = $this->licenseList->getAction();
298 // Allow license edit via href links
299 if($tmp['action'] == 'edit'){
300 $id = $this->licenseList->getKey($tmp['targets'][0]);
301 if(isset($this->licenses[$id])){
302 $this->dialog = new licenseGeneric($this->config,$this->dn,$this->licenses[$id], $this->opsiHosts);
303 $this->dialog->set_acl_category('opsi');
304 $this->dialog->set_acl_base($this->config->current['BASE']);
305 }
306 }
307 if($tmp['action'] == 'delete'){
308 $id = $this->licenseList->getKey($tmp['targets'][0]);
309 if(isset($this->licenses[$id])){
310 unset($this->licenses[$id]);
311 }
312 }
314 // Close license edit dialogs.
315 if($this->dialog instanceOf plugin && isset($_POST['license_cancel'])){
316 $this->dialog = NULL;
317 return;
318 }
320 // Save license modifications
321 if($this->dialog instanceOf plugin && isset($_POST['license_finish'])){
322 $this->dialog->save_object();
323 $msgs = $this->dialog->check();
324 if(count($msgs)){
325 msg_dialog::displayChecks($msgs);
326 }else{
327 $attrs = $this->dialog->save();
328 $attrs['MODIFIED'] = TRUE;
329 $this->licenses[$attrs['cn']] = $attrs;
330 $this->dialog = NULL;
331 }
332 return;
333 }
335 if(isset($_POST['opsiLicensePoolPosted'])){
336 plugin::save_object();
338 // Restore license cn, to avoid creating a copy...
339 if($this->initially_was_account) $this->cn = $this->orig_cn;
341 // We've to add prodcuts here
342 if(preg_match("/w/",$this->getacl("productIds"))){
343 if(isset($_POST['availableProduct']) && isset($_POST['addProduct'])){
344 $pro = get_post('availableProduct');
345 if(isset($this->availableProductIds[$pro]) && !in_array($this->availableProductIds[$pro], $this->productIds)){
346 $this->productIds[] =$this->availableProductIds[$pro];
347 }
348 }
349 }
351 // We've to remove products here
352 if(preg_match("/w/",$this->getacl("productIds"))){
353 if(isset($_POST['productIds']) && isset($_POST['removeProduct'])){
354 foreach($_POST['productIds'] as $key){
355 if(isset($this->productIds[$key])){
356 unset($this->productIds[$key]);
357 }
358 }
359 }
360 }
362 // We've to add software here
363 if(preg_match("/w/",$this->getacl("windowsSoftwareIds"))){
364 if(isset($_POST['newSoftwareId']) && isset($_POST['addSoftware'])){
365 $soft = trim(get_post('newSoftwareId'));
366 if(!empty($soft) && !in_array($soft, $this->softwareIds)){
367 $this->softwareIds[] = $soft;
368 }
369 }
370 }
372 // We've to remove software Ids here
373 if(preg_match("/w/",$this->getacl("windowsSoftwareIds"))){
374 if(isset($_POST['softwareIds']) && isset($_POST['removeSoftware'])){
375 foreach($_POST['softwareIds'] as $key){
376 if(isset($this->softwareIds[$key])){
377 unset($this->softwareIds[$key]);
378 }
379 }
380 }
381 }
383 // We've to create a new license
384 if(preg_match("/w/",$this->getacl("licenses"))){
385 if(isset($_POST['addLicense'])){
386 $this->dialog = new licenseGeneric($this->config,$this->dn,array(), $this->opsiHosts);
387 $this->dialog->set_acl_category('opsi');
388 $this->dialog->set_acl_base($this->config->current['BASE']);
389 }
390 }
391 }
392 }
395 /* Check user input and return a list of 'invalid input' messages.
396 */
397 function check()
398 {
399 $message = plugin::check();
400 return($message);
401 }
405 /* Removes the object from the opsi database
406 */
407 function remove_from_parent()
408 {
409 $this->si->deletePool($this->orig_cn);
410 if($this->si->is_error()){
411 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
412 }else{
414 // Trigger remove signal
415 $this->handle_post_events("remove");
416 }
418 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$this->si->get_error());
419 }
422 /* Saves object modifications
423 */
424 function save()
425 {
426 plugin::save();
428 // Send modify/add events
429 $mode = "modify";
430 if($this->orig_dn == "new"){
431 $mode = "add";
432 }
434 // Create or update the pool
435 $this->si->createPool($this->cn, $this->description,$this->productIds,$this->softwareIds);#
436 if($this->si->is_error()){
437 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
438 }else{
439 $this->handle_post_events($mode);
440 }
442 // Create, remove or update licenses
443 $add = array_diff_assoc($this->licenses,$this->orig_licenses);
444 $del = array_diff_assoc($this->orig_licenses,$this->licenses);
445 $update = array_intersect($this->licenses,$this->orig_licenses);
447 // Remove licenses
448 foreach($del as $license){
449 $this->si->removeLicenseFromPool($this->cn, $license['cn']);
450 if($this->si->is_error()){
451 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
452 }
453 }
455 // Add licenses
456 foreach($add as $license){
457 $this->si->createLicense(
458 $this->cn, // Pool id
459 $license['cn'],
460 $license['licenseKey'][0],
461 $license['licenseModel'],
462 $license['partner'],
463 $license['conclusionDate'],
464 $license['notificationDate'],
465 $license['description'],
466 $license['cn'],
467 $license['maximumInstallations'],
468 $license['boundToHost'],
469 $license['expirationDate']);
471 if($this->si->is_error()){
472 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
473 }
474 }
476 // Update licenses
477 foreach($update as $license){
479 // Do not save untouched licenses
480 if(!$license['MODIFIED']){
481 continue;
482 }
484 $this->si->createLicense(
485 $this->cn, // Pool id
486 $license['cn'],
487 $license['licenseKey'][0],
488 $license['licenseModel'],
489 $license['partner'],
490 $license['conclusionDate'],
491 $license['notificationDate'],
492 $license['description'],
493 $license['cn'],
494 $license['maximumInstallations'],
495 $license['boundToHost'],
496 $license['expirationDate']);
498 if($this->si->is_error()){
499 msg_dialog::display(_("Error"),msgPool::siError($this->si->get_error()),ERROR_DIALOG);
500 }
501 }
503 // Log action
504 if($mode == "modify"){
505 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$this->si->get_error());
506 }else{
507 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$this->si->get_error());
508 }
510 return 0;
511 }
513 static function plInfo()
514 {
515 return (array(
516 "plShortName" => _("Pool generic"),
517 "plDescription" => _("License pool generic"),
518 "plSelfModify" => FALSE,
519 "plDepends" => array(),
520 "plPriority" => 7,
521 "plSection" => array("administration"),
522 "plCategory" => array("opsi"),
523 "plProvidedAcls"=> array(
524 "cn" => _("Name"),
525 "description" => _("Description"),
526 "productIds" => _("Applications"),
527 "windowsSoftwareIds" => _("Windows software IDs"),
528 "licenses" => _("Licenses"))
529 ));
530 }
531 }
534 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
535 ?>