9 use Composer\Spdx\SpdxLicenses;
16 use Symfony\Component\HttpFoundation\Response;
18 define(
"TITLE_ADMIN_LICENSE_FILE", _(
"License Administration"));
30 $this->Name =
"admin_license";
31 $this->Title = TITLE_ADMIN_LICENSE_FILE;
32 $this->MenuList =
"Admin::License Admin";
34 $this->vars = array();
35 $this->obligationSelectorName =
"assocObligations";
36 $this->obligationSelectorId =
"assocObligations";
37 parent::__construct();
39 $this->
dbManager = $GLOBALS[
'container']->get(
'db.manager');
40 $this->licenseDao = $GLOBALS[
'container']->get(
'dao.license');
48 if ($this->
State != PLUGIN_STATE_READY) {
52 $URL = $this->Name.
"&add=y";
53 $text = _(
"Add new license");
54 menu_insert(
"Main::".$this->MenuList.
"::Add License",0, $URL, $text);
56 $text = _(
"Select license family");
57 menu_insert(
"Main::".$this->MenuList.
"::Select License",0, $URL, $text);
63 $errorstr =
"License not added";
66 if (@$_POST[
"updateit"]) {
67 $resultstr = $this->
Updatedb($_POST);
68 $this->vars[
'message'] = $resultstr;
69 if (strstr($resultstr, $errorstr)) {
70 return $this->Updatefm(0);
76 if (@$_REQUEST[
'add'] ==
'y') {
77 return $this->Updatefm(0);
81 if (@$_POST[
"addit"]) {
82 $resultstr = $this->
Adddb();
83 $this->vars[
'message'] = $resultstr;
84 if (strstr($resultstr, $errorstr)) {
85 return $this->Updatefm(0);
92 $rf_pk = @$_REQUEST[
'rf_pk'];
94 return $this->Updatefm($rf_pk);
98 if (@$_GET[
"getLicenseText"] && @$_GET[
"licenseID"]) {
99 $licenseText = $this->getLicenseTextForID(@$_GET[
"licenseID"]);
100 if (! $licenseText) {
101 return new Response(
"Error in querying license text.",
102 Response::HTTP_BAD_REQUEST, array(
103 'Content-type' =>
'text/plain'
106 return new Response($licenseText, Response::HTTP_OK,
108 'Content-type' =>
'text/plain'
112 if (@$_POST[
"req_shortname"]) {
113 $licTypeFilter = array_key_exists(
'req_licensetype', $_POST) ?
trim($_POST[
'req_licensetype']) :
'all';
114 $this->vars += $this->
getLicenseListData($_POST[
"req_shortname"], $_POST[
"req_marydone"], $licTypeFilter);
116 $this->vars[
'Inputfm'] = $this->
Inputfm();
117 return $this->
render(
'admin_license_file.html.twig');
128 $V =
"<FORM name='Inputfm' action='?mod=" . $this->Name .
"' method='POST'>";
129 $V.= _(
"What license family do you wish to view:<br>");
135 $V.=
"<select name='req_marydone'>\n";
136 $Selected = (@$_REQUEST[
'req_marydone'] ==
'all') ?
" SELECTED ":
"";
138 $V.=
"<option value='all' $Selected> $text </option>";
139 $Selected = (@$_REQUEST[
'req_marydone'] ==
'done') ?
" SELECTED ":
"";
140 $text = _(
"Checked");
141 $V.=
"<option value='done' $Selected> $text </option>";
142 $Selected = (@$_REQUEST[
'req_marydone'] ==
'notdone') ?
" SELECTED ":
"";
143 $text = _(
"Not Checked");
144 $V.=
"<option value='notdone' $Selected> $text </option>";
146 $V.=
" ";
148 $V.= _(
"License type: ");
149 $V.=
"<select name='req_licensetype'>\n";
150 $Selected = (@$_REQUEST[
'req_licensetype'] ==
'all' || !isset($_REQUEST[
'req_licensetype'])) ?
" SELECTED " :
"";
152 $V.=
"<option value='all' $Selected> $text </option>";
153 $licenseTypesConf = !empty($SysConf[
'SYSCONFIG'][
'LicenseTypes']) ? $SysConf[
'SYSCONFIG'][
'LicenseTypes'] :
'';
154 if (!empty($licenseTypesConf)) {
155 $licenseTypeList = array_filter(array_map(
'trim', explode(
',', $licenseTypesConf)));
156 foreach ($licenseTypeList as $licType) {
157 $Selected = (@$_REQUEST[
'req_licensetype'] === $licType) ?
" SELECTED " :
"";
158 $V.=
"<option value='" . htmlspecialchars($licType) .
"' $Selected> " . htmlspecialchars($licType) .
" </option>";
162 $V.=
" ";
165 $V.= _(
"License family name: ");
166 $Shortnamearray = $this->FamilyNames();
167 $Shortnamearray = array(
"All"=>
"All") + $Shortnamearray;
168 $Selected = @$_REQUEST[
'req_shortname'];
171 $V.=
" ";
173 $V.=
"<INPUT type='submit' value='$text'>\n";
181 private function getLicenseData($where, $params = [])
183 $sql =
"SELECT rf_pk, marydone, rf_shortname, rf_spdx_id, " .
184 "rf_shortname, rf_fullname, rf_url, rf_text, ".
185 "string_agg(ob_topic, ';') AS ob_topic " .
186 "FROM ONLY license_ref " .
187 "LEFT OUTER JOIN obligation_map ON rf_fk = rf_pk " .
188 "LEFT OUTER JOIN obligation_ref ON ob_fk = ob_pk " .
189 "$where GROUP BY rf_pk ORDER BY rf_shortname";
191 return $this->
dbManager->getRows($sql, $params,
'getLicenseData.' . md5($where));
206 if ($namestr ==
"All") {
209 $params[] = $namestr .
'%';
210 $where =
"where rf_shortname like $" . count($params) .
" ";
214 if ($filter !=
"all") {
220 if ($filter ==
"done") {
221 $where .=
" marydone=true";
223 if ($filter ==
"notdone") {
224 $where .=
" marydone=false";
228 if (!empty($licensetype) && $licensetype !=
'all') {
234 $params[] = $licensetype;
235 $where .=
" license_ref.rf_licensetype=$" . count($params);
238 $data = $this->getLicenseData($where, $params);
241 "No licenses matching the filter and name pattern were found");
243 $dataSize =
sizeof($data);
249 $dataMessage = $dataSize . _(
" License$plural found");
254 'dataMessage' => $dataMessage,
259 function Updatefm($rf_pk)
262 return $this->
render(
'admin_license-upload_form.html.twig', $this->vars);
277 if (0 < count($_POST)) {
278 $rf_pk_update = $_POST[
'rf_pk'];
279 if (! empty($rf_pk)) {
280 $rf_pk_update = $rf_pk;
281 }
else if (empty($rf_pk_update)) {
282 $rf_pk_update = $_GET[
'rf_pk'];
286 $vars[
'obligationSelectorName'] = $this->obligationSelectorName .
"[]";
287 $vars[
'obligationSelectorId'] = $this->obligationSelectorId;
289 $vars[
'actionUri'] =
"?mod=" . $this->Name .
"&rf_pk=$rf_pk_update";
290 $vars[
'req_marydone'] = array_key_exists(
'req_marydone', $_POST) ? $_POST[
'req_marydone'] :
'';
291 $vars[
'req_shortname'] = array_key_exists(
'req_shortname', $_POST) ? $_POST[
'req_shortname'] :
'';
292 $vars[
'rf_shortname'] = array_key_exists(
'rf_shortname', $_POST) ? $_POST[
'rf_shortname'] :
'';
293 $vars[
'rf_fullname'] = array_key_exists(
'rf_fullname', $_POST) ? $_POST[
'rf_fullname'] :
'';
294 $vars[
'rf_text'] = array_key_exists(
'rf_text', $_POST) ? $_POST[
'rf_text'] :
'';
295 $vars[
'rf_licensetype'] = array_key_exists(
'rf_licensetype', $_POST) ? $_POST[
'rf_licensetype'] :
'---';
296 $selectedObligations = array_key_exists($this->obligationSelectorName,
297 $_POST) ? $_POST[$this->obligationSelectorName] : [];
300 $parentLicenes = $parentMap->getTopLevelLicenseRefs();
301 $vars[
'parentMap'] = array(0=>
'[self]');
302 foreach ($parentLicenes as $licRef) {
303 $vars[
'parentMap'][$licRef->getId()] = $licRef->getShortName();
307 $reportLicenes = $reportMap->getTopLevelLicenseRefs();
308 $vars[
'reportMap'] = array(0=>
'[self]');
309 foreach ($reportLicenes as $licRef) {
310 $vars[
'reportMap'][$licRef->getId()] = $licRef->getShortName();
314 $obligations = $obligationMap->getObligations();
315 foreach ($obligations as $obligation) {
316 $vars[
'obligationTopics'][$obligation[
'ob_pk']] = $obligation[
'ob_topic'];
318 foreach ($selectedObligations as $obligation) {
319 $row[
'obligationSelected'][$obligation] = $obligationMap->getTopicNameFromId(
325 "SELECT * FROM ONLY license_ref WHERE rf_pk=$1", array($rf_pk),
326 __METHOD__ .
'.forUpdate');
327 if ($row ===
false) {
328 $text = _(
"ERROR: No licenses matching this key");
329 $text1 = _(
"was found");
330 return [
"error" =>
"$text ($rf_pk) $text1."];
332 $row[
'rf_parent'] = $parentMap->getProjectedId($rf_pk);
333 $row[
'rf_report'] = $reportMap->getProjectedId($rf_pk);
335 $obligationsAssigned = $parentMap->getObligationsForLicenseRef($rf_pk);
336 foreach ($obligationsAssigned as $obligation) {
337 $row[
'obligationSelected'][$obligation] = $obligationMap->getTopicNameFromId(
344 'rf_text_updatable' =>
't',
349 'rf_detector_type' => 1,
351 'rf_licensetype' =>
'Unknown'
355 foreach (array_keys($row) as $key) {
356 if (array_key_exists($key, $_POST)) {
357 $row[$key] = $_POST[$key];
361 $vars[
'boolYesNoMap'] = array(
"true"=>
"Yes",
"false"=>
"No");
362 $row[
'rf_active'] = $this->
isTrue($row[
'rf_active']) ?
'true' :
'false';
363 $row[
'marydone'] = $this->
isTrue($row[
'marydone']) ?
'true' :
'false';
364 $row[
'rf_text_updatable'] = $this->
isTrue($row[
'rf_text_updatable']) ?
'true' :
'false';
365 $vars[
'risk_level'] = array_key_exists(
'risk_level', $_POST) ? intval($_POST[
'risk_level']) : $row[
'rf_risk'];
366 $vars[
'isReadOnly'] = !(empty($rf_pk) || $row[
'rf_text_updatable']==
'true');
367 $vars[
'detectorTypes'] = array(
"1"=>
"Reference License",
"2"=>
"Nomos",
"3"=>
"Unconcrete License");
368 $licenseType = $SysConf[
'SYSCONFIG'][
'LicenseTypes'];
369 $licenseType = explode(
',', $licenseType);
370 $licenseType = array_map(
'trim', $licenseType);
371 $vars[
'licenseTypes'] = array_combine($licenseType, $licenseType);
372 $vars[
'rfId'] = $rf_pk?:$rf_pk_update;
374 return array_merge($vars,$row);
383 if (is_bool($value)) {
386 $value = strtolower($value);
387 return ($value ===
't' || $value ===
'true');
394 $sql =
"SELECT count(*) from license_ref where rf_pk <> $1 and (LOWER(rf_shortname) = LOWER($2) or (rf_text <> ''
395 and rf_text = $3 and LOWER(rf_text) NOT LIKE 'license by nomos.'))";
396 $check_count = $this->
dbManager->getSingleRow($sql,
401 ), __METHOD__ .
'.countLicensesByNomos');
402 return (0 < $check_count[
'count']);
408 $sql =
"SELECT LOWER(rf_shortname) AS rf_shortname FROM license_ref WHERE rf_pk=$1";
409 $row = $this->
dbManager->getSingleRow($sql,array($rfId),__METHOD__.
'.DoNotChnageShortName');
410 if ($row[
'rf_shortname'] === strtolower($shortname)) {
424 $spdxLicenses =
new SpdxLicenses();
427 $rfId = intval($_POST[
'rf_pk']);
428 $shortname = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_shortname']));
429 $fullname = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_fullname']));
430 $url = $_POST[
'rf_url'];
431 $notes = $_POST[
'rf_notes'];
432 $text = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_text']));
433 $spdxId = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_spdx_id']));
434 $parent = $_POST[
'rf_parent'];
435 $report = $_POST[
'rf_report'];
436 $licensetype =
trim($_POST[
'rf_licensetype']);
437 $riskLvl = intval($_POST[
'risk_level']);
438 $selectedObligations = array_key_exists($this->obligationSelectorName,
439 $_POST) ? $_POST[$this->obligationSelectorName] : [];
441 if (! empty($spdxId) &&
442 strstr(strtolower($spdxId), strtolower(LicenseRef::SPDXREF_PREFIX)) ===
false) {
443 if (! $spdxLicenses->validate($spdxId)) {
444 $spdxId = LicenseRef::convertToSpdxId($spdxId,
null);
445 $errors[] =
"SPDX ID changed to $spdxId to be compliant with SPDX.";
447 } elseif (empty($spdxId)) {
450 if (! empty($spdxId)) {
451 $spdxId = LicenseRef::replaceSpaces($spdxId);
454 if (empty($shortname)) {
455 $text = _(
"ERROR: The license shortname is empty. License not added.");
456 return "<b>$text</b><p>";
460 $text = _(
"ERROR: The shortname can not be changed. License not added.");
461 return "<b>$text</b><p>";
464 $md5term = (empty($text) || stristr($text,
"License by Nomos")) ?
'null' :
'md5($10)';
466 $sql =
"UPDATE license_ref SET
467 rf_active=$2, marydone=$3, rf_shortname=$4, rf_fullname=$5,
468 rf_url=$6, rf_notes=$7, rf_text_updatable=$8, rf_detector_type=$9, rf_text=$10,
469 rf_md5=$md5term, rf_risk=$11, rf_spdx_id=$12, rf_flag=$13, rf_licensetype=$14
471 $params = array($rfId,
472 $_POST[
'rf_active'],$_POST[
'marydone'],$shortname,$fullname,
473 $url,$notes,$_POST[
'rf_text_updatable'],$_POST[
'rf_detector_type'],$text,
474 $riskLvl,$spdxId,2, $licensetype);
475 $statement = __METHOD__ .
".updateLicense";
476 if ($md5term ==
"null") {
477 $statement .=
".nullMD5";
479 $this->
dbManager->prepare($statement, $sql);
482 $licenseMapDelStatement = __METHOD__ .
'.deleteFromMap';
483 $licenseMapDelSql =
'DELETE FROM license_map WHERE rf_fk=$1 AND usage=$2';
484 $this->
dbManager->prepare($licenseMapDelStatement, $licenseMapDelSql);
489 $this->
dbManager->execute($licenseMapDelStatement,
490 array($rfId, LicenseMap::CONCLUSION));
492 $parentLicenses = $parentMap->getTopLevelLicenseRefs();
493 if (array_key_exists($parent, $parentLicenses) &&
494 $parent != $parentMap->getProjectedId($rfId)) {
495 $this->
dbManager->execute($licenseMapDelStatement,
496 array($rfId, LicenseMap::CONCLUSION));
497 $this->
dbManager->insertTableRow(
'license_map',
498 array(
'rf_fk'=>$rfId,
'rf_parent'=>$parent,
'usage'=>LicenseMap::CONCLUSION));
504 $this->
dbManager->execute($licenseMapDelStatement,
505 array($rfId, LicenseMap::REPORT));
508 $reportLicenses = $parentMap->getTopLevelLicenseRefs();
509 if (array_key_exists($report, $reportLicenses) &&
510 $report != $reportMap->getProjectedId($rfId)) {
511 $this->
dbManager->execute($licenseMapDelStatement,
512 array($rfId, LicenseMap::REPORT));
513 $this->
dbManager->insertTableRow(
'license_map',
514 array(
'rf_fk'=>$rfId,
'rf_parent'=>$report,
'usage'=>LicenseMap::REPORT));
519 foreach ($selectedObligations as $obligation) {
520 $obligationMap->associateLicenseWithObligation($obligation, $rfId);
523 $allObligations = $parentMap->getObligationsForLicenseRef($rfId);
524 $removedObligations = array_diff($allObligations, $selectedObligations);
525 foreach ($removedObligations as $obligation) {
526 $obligationMap->unassociateLicenseFromObligation($obligation, $rfId);
529 return "License $_POST[rf_shortname] updated. " . join(
" ", $errors) .
"<p>";
540 $spdxLicenses =
new SpdxLicenses();
543 $rf_shortname = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_shortname']));
544 $rf_fullname = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_fullname']));
545 $rf_spdx_id = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_spdx_id']));
546 $rf_url = $_POST[
'rf_url'];
547 $rf_notes = $_POST[
'rf_notes'];
548 $rf_text = StringOperation::replaceUnicodeControlChar(
trim($_POST[
'rf_text']));
549 $rf_licensetype =
trim($_POST[
'rf_licensetype']);
550 $parent = $_POST[
'rf_parent'];
551 $report = $_POST[
'rf_report'];
552 $riskLvl = intval($_POST[
'risk_level']);
553 $selectedObligations = array_key_exists($this->obligationSelectorName,
554 $_POST) ? $_POST[$this->obligationSelectorName] : [];
556 if (! empty($rf_spdx_id) &&
557 strstr(strtolower($rf_spdx_id), strtolower(LicenseRef::SPDXREF_PREFIX)) ===
false) {
558 if (! $spdxLicenses->validate($rf_spdx_id)) {
559 $rf_spdx_id = LicenseRef::convertToSpdxId($rf_spdx_id,
null);
560 $errors[] =
"SPDX ID changed to $rf_spdx_id to be compliant with SPDX.";
562 } elseif (empty($rf_spdx_id)) {
565 if (! empty($rf_spdx_id)) {
566 $rf_spdx_id = LicenseRef::replaceSpaces($rf_spdx_id);
569 if (empty($rf_shortname)) {
570 $text = _(
"ERROR: The license shortname is empty. License not added.");
571 return "<b>$text</b><p>";
575 $text = _(
"ERROR: The shortname or license text already exist in the license list. License not added.");
576 return "<b>$text</b><p>";
579 $md5term = (empty($rf_text) || stristr($rf_text,
"License by Nomos")) ?
'null' :
'md5($7)';
580 $stmt = __METHOD__.
'.rf';
581 $sql =
"INSERT into license_ref (
582 rf_active, marydone, rf_shortname, rf_fullname,
583 rf_url, rf_notes, rf_md5, rf_text, rf_text_updatable,
584 rf_detector_type, rf_risk, rf_spdx_id, rf_licensetype)
586 $1, $2, $3, $4, $5, $6, $md5term, $7, $8, $9, $10, $11, $12) RETURNING rf_pk";
597 $_POST[
'rf_text_updatable'],
598 $_POST[
'rf_detector_type'],
603 $row = $this->
dbManager->fetchArray($res);
604 $rfId = $row[
'rf_pk'];
607 $parentLicenses = $parentMap->getTopLevelLicenseRefs();
608 if (array_key_exists($parent, $parentLicenses)) {
609 $this->
dbManager->insertTableRow(
'license_map',
612 'rf_parent' => $parent,
613 'usage' => LicenseMap::CONCLUSION
618 $reportLicenses = $reportMap->getTopLevelLicenseRefs();
619 if (array_key_exists($report, $reportLicenses)) {
620 $this->
dbManager->insertTableRow(
'license_map',
623 'rf_parent' => $report,
624 'usage' => LicenseMap::REPORT
629 foreach ($selectedObligations as $obligation) {
630 $obligationMap->associateLicenseWithObligation($obligation, $rfId);
633 return "License $_POST[rf_shortname] (id=$rfId) added. " .
634 join(
" ", $errors) .
"<p>";
647 function FamilyNames()
649 $familynamearray = array();
650 $Shortnamearray =
DB2KeyValArray(
"license_ref",
"rf_pk",
"rf_shortname",
" order by rf_shortname");
653 foreach ($Shortnamearray as $shortname) {
655 if (($shortname ==
"No_license_found") || ($shortname ==
"Unknown license")) {
656 $familynamearray[$shortname] = $shortname;
658 $tok = strtok($shortname,
" _-([/");
659 $familynamearray[$tok] = $tok;
663 return ($familynamearray);
666 private function getLicenseTextForID($licenseID)
668 $license = $this->licenseDao->getLicenseById($licenseID);
670 if ($license ==
null) {
673 return $license->getText();
This is the Plugin class. All plugins should:
render($templateName, $vars=null)
Wrapper class for license map.
Wrapper class for obligation map.
__construct()
base constructor. Most plugins will just use this
RegisterMenus()
Customize submenus.
Output()
This function is called when user output is requested. This function is responsible for content....
isShortnameBlocked($rfId, $shortname, $text)
check if shortname or license text of this license is existing
Inputfm()
Build the input form.
Updatedb()
Update the database.
getUpdatefmData($rf_pk)
Update forms.
isTrue($value)
Check if a variable is true.
getLicenseListData($namestr, $filter, $licensetype='all')
Build the input form.
Adddb()
Add a new license_ref to the database.
isShortNameExists($rfId, $shortname)
check if shortname is changed
DB2KeyValArray($Table, $KeyCol, $ValCol, $Where="")
Create an associative array by using table rows to source the key/value pairs.
Traceback_uri()
Get the URI without query to this location.
Array2SingleSelect($KeyValArray, $SLName="unnamed", $SelectedVal="", $FirstEmpty=false, $SelElt=true, $Options="", $ReturnKey=true)
Build a single choice select pulldown.
char * trim(char *ptext)
Trimming whitespace.
#define PLUGIN_DB_ADMIN
Plugin requires admin level permission on DB.
fo_dbManager * dbManager
fo_dbManager object