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