FOSSology  4.7.1
Open Source License Compliance by Open Source Software
ui-report-conf.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2019 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
18 
20 {
21 
23  private $dbManager;
24 
28  private $uploadDao;
29 
32  private $userDao;
33 
37  private $licenseDao;
38 
42  private $clearingDao;
43 
47  private $mapDBColumns = array(
48  "reviewedBy" => "ri_reviewed",
49  "department" => "ri_department",
50  "reportRel" => "ri_report_rel",
51  "community" => "ri_community",
52  "component" => "ri_component",
53  "version" => "ri_version",
54  "relDate" => "ri_release_date",
55  "sw360Link" => "ri_sw360_link",
56  "componentType" => "ri_component_type",
57  "componentId" => "ri_component_id",
58  "footerNote" => "ri_footer",
59  "generalAssesment" => "ri_general_assesment",
60  "gaAdditional" => "ri_ga_additional",
61  "gaRisk" => "ri_ga_risk",
62  "dependencyBinarySource" => "ri_depnotes",
63  "exportRestrictionText" => "ri_exportnotes",
64  "copyrightRestrictionText" => "ri_copyrightnotes",
65  "criticalFilesText" => "ri_criticalnotes"
66  );
67 
71  private $radioListUR = array(
72  "nonCritical" => "critical",
73  "critical" => "critical",
74  "noDependency" => "dependencySourceBinary",
75  "dependencySource" => "dependencySourceBinary",
76  "dependencyBinary" => "dependencySourceBinary",
77  "noExportRestriction" => "exportRestriction",
78  "exportRestriction" => "exportRestriction",
79  "noRestriction" => "restrictionForUse",
80  "restrictionForUse" => "restrictionForUse"
81  );
82 
86  private $checkBoxListSPDX = array(
87  "spdxLicenseComment" => "spdxLicenseComment",
88  "ignoreFilesWOInfo" => "ignoreFilesWOInfo",
89  "osselotExport" => "osselotExport"
90  );
91 
92 
93  function __construct()
94  {
95  $this->Name = "report_conf";
96  $this->Title = _("Report Configuration");
97  $this->Dependency = array("browse");
98  $this->DBaccess = PLUGIN_DB_READ;
99  $this->LoginFlag = 0;
100  parent::__construct();
101  $this->uploadDao = $GLOBALS['container']->get('dao.upload');
102  $this->dbManager = $GLOBALS['container']->get('db.manager');
103  $this->userDao = $GLOBALS['container']->get('dao.user');
104  $this->clearingDao = $GLOBALS['container']->get('dao.clearing');
105  $this->licenseDao = $GLOBALS['container']->get('dao.license');
106  }
107 
111  function RegisterMenus()
112  {
113  $tooltipText = _("Report Configuration");
114  menu_insert("Browse-Pfile::Conf",5,$this->Name,$tooltipText);
115  // For the Browse menu, permit switching between detail and summary.
116  $Parm = Traceback_parm_keep(array("upload","item","format"));
117  $URI = $this->Name . $Parm;
118 
119  $menuPosition = 60;
120  $menuText = "Conf";
121  if (GetParm("mod", PARM_STRING) == $this->Name) {
122  menu_insert("View::[BREAK]", 61);
123  menu_insert("View::[BREAK]", 50);
124  menu_insert("View::{$menuText}", $menuPosition);
125  menu_insert("View-Meta::[BREAK]", 61);
126  menu_insert("View-Meta::[BREAK]", 50);
127  menu_insert("View-Meta::{$menuText}", $menuPosition);
128 
129  menu_insert("Browse::Conf",-3);
130  } else {
131  $tooltipText = _("Report Configuration");
132  menu_insert("View::[BREAK]", 61);
133  menu_insert("View::[BREAK]", 50);
134  menu_insert("View::{$menuText}", $menuPosition, $URI, $tooltipText);
135  menu_insert("View-Meta::[BREAK]", 61);
136  menu_insert("View-Meta::[BREAK]", 50);
137  menu_insert("View-Meta::{$menuText}", $menuPosition, $URI, $tooltipText);
138 
139  menu_insert("Browse::Conf", -3, $URI, $tooltipText);
140  }
141  } // RegisterMenus()
142 
149  function allReportConfiguration($uploadId, $groupId)
150  {
151  $vars = [];
152  $row = $this->uploadDao->getReportInfo($uploadId);
153  foreach ($this->mapDBColumns as $key => $value) {
154  $vars[$key] = $row[$value];
155  }
156  foreach (["dependencyBinarySource", "exportRestrictionText",
157  "copyrightRestrictionText", "criticalFilesText"] as $noteField) {
158  if ($vars[$noteField] == 'NA') {
159  $vars[$noteField] = '';
160  }
161  }
162  $textAreaNoneStyle = ' style="display:none;overflow:auto;width:98%;height:80px;"';
163  $textAreaStyle = ' style="overflow:auto;width:98%;height:80px;"';
164  $vars['styleDependencyTA'] = $vars['styleExportTA'] = $vars['styleRestrictionTA'] = $textAreaStyle;
165  $vars['styleCriticalTA'] = $textAreaStyle;
166  if ($row['ri_criticalnotes'] == 'NA' || empty($row['ri_criticalnotes'])) {
167  $vars['styleCriticalTA'] = $textAreaNoneStyle;
168  }
169  if ($row['ri_depnotes'] == 'NA' || empty($row['ri_depnotes'])) {
170  $vars['styleDependencyTA'] = $textAreaNoneStyle;
171  }
172 
173  if ($row['ri_exportnotes'] == 'NA' || empty($row['ri_exportnotes'])) {
174  $vars['styleExportTA'] = $textAreaNoneStyle;
175  }
176 
177  if ($row['ri_copyrightnotes'] == 'NA' || empty($row['ri_copyrightnotes'])) {
178  $vars['styleRestrictionTA'] = $textAreaNoneStyle;
179  }
180 
181  if (!empty($row['ri_ga_checkbox_selection'])) {
182  $listURCheckbox = explode(',', $row['ri_ga_checkbox_selection']);
183  foreach (array_keys($this->radioListUR) as $key => $value) {
184  $vars[$value] = $listURCheckbox[$key];
185  }
186  }
187 
188  if (!empty($row['ri_spdx_selection'])) {
189  $listSPDXCheckbox = explode(',', $row['ri_spdx_selection']);
190  foreach (array_keys($this->checkBoxListSPDX) as $key => $value) {
191  $vars[$value] = $listSPDXCheckbox[$key];
192  }
193  } else {
194  foreach (array_keys($this->checkBoxListSPDX) as $key) {
195  $vars[$key] = 'unchecked';
196  }
197  }
198 
199  $uploadTreeTableName = $this->uploadDao->getUploadtreeTableName($uploadId);
200  $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId, $uploadTreeTableName);
201  $allClearingDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBounds, $groupId);
202 
203  $tableRows = "";
204  $excludedObligations = array();
205  $excludedObligations = (array) json_decode($row['ri_excluded_obligations'], true);
206  foreach ($this->getAllObligationsForGivenUploadId($groupId, $allClearingDecisions) as $obTopic => $obData) {
207  $tableRows .= '<tr><td style="width:35%">'.$obTopic.'</td>';
208  $tableRows .= '<td><textarea readonly="readonly" style="overflow:auto;width:98%;height:80px;">'.
209  $obData['text'].'</textarea></td><td>';
210  foreach ($obData['license'] as $value) {
211  if (!empty($excludedObligations[$obTopic]) && in_array($value, $excludedObligations[$obTopic])) {
212  $tableRows .= '<input class="browse-upload-checkbox view-license-rc-size" type="checkbox" name="obLicenses['.urlencode($obTopic).'][]" value="'.$value.'" checked> '.$value.'<br />';
213  } else {
214  $tableRows .= '<input class="browse-upload-checkbox view-license-rc-size" type="checkbox" name="obLicenses['.urlencode($obTopic).'][]" value="'.$value.'"> '.$value.'<br />';
215  }
216  }
217  $tableRows .= '</td></tr>';
218  }
219  $tableRowsUnifiedReport = "";
220  $unifiedColumns = array();
221  if (!empty($row['ri_unifiedcolumns'])) {
222  $unifiedColumns = (array) json_decode($row['ri_unifiedcolumns'], true);
223  } else {
224  $unifiedColumns = UploadDao::UNIFIED_REPORT_HEADINGS;
225  }
226  foreach ($unifiedColumns as $name => $unifiedReportColumns) {
227  foreach ($unifiedReportColumns as $columnName => $isenabled) {
228  $tableRowsUnifiedReport .= '<tr>';
229  $tableRowsUnifiedReport .= '<td><input class="form-control" type="text" style="width:95%" name="'.$name.'[]" value="'.$columnName.'"></td>';
230  $checked = '';
231  if ($isenabled) {
232  $checked = 'checked';
233  }
234  $tableRowsUnifiedReport .= '<td style="vertical-align:middle"><input class="browse-upload-checkbox view-license-rc-size" type="checkbox" style="width:95%" name="'.$name.'[]" '.$checked.'></td>';
235  $tableRowsUnifiedReport .= '</tr>';
236  }
237  }
238 
239  $tableRowsClixmlReport = "";
240  $clixmlColumns = array();
241  if (!empty($row['ri_clixmlcolumns'])) {
242  $clixmlColumns = (array) json_decode($row['ri_clixmlcolumns'], true);
243  } else {
244  $clixmlColumns = UploadDao::CLIXML_REPORT_HEADINGS;
245  }
246  foreach ($clixmlColumns as $name => $clixmlReportColumns) {
247  foreach ($clixmlReportColumns as $columnName => $isenabled) {
248  $tableRowsClixmlReport .= '<tr>';
249  $tableRowsClixmlReport .= '<td><input class="form-control" type="text" style="width:95%" name="'.$name.'[]" value="'.$columnName.'" readonly></td>';
250  $checked = '';
251  if ($isenabled) {
252  $checked = 'checked';
253  }
254  $tableRowsClixmlReport .= '<td style="vertical-align:middle"><input class="browse-upload-checkbox view-license-rc-size" type="checkbox" style="width:95%" name="'.$name.'[]" '.$checked.'></td>';
255  $tableRowsClixmlReport .= '</tr>';
256  }
257  }
258 
259  if (!empty($row['ri_globaldecision'])) {
260  $vars['applyGlobal'] = "checked";
261  }
262  $vars['tableRows'] = $tableRows;
263  $vars['tableRowsUnifiedReport'] = $tableRowsUnifiedReport;
264  $vars['tableRowsClixmlReport'] = $tableRowsClixmlReport;
265  $vars['ackRows'] = $this->buildAcknowledgementRows($uploadId, $allClearingDecisions);
266  $vars['scriptBlock'] = $this->createScriptBlock();
267 
268  return $vars;
269  }
270 
276  function getAllAcknowledgementsForUpload(array $clearingDecisions)
277  {
278  $ackData = array();
279  foreach ($clearingDecisions as $clearingDecision) {
280  if ($clearingDecision->getType() == DecisionTypes::IRRELEVANT) {
281  continue;
282  }
283  $uploadTreeId = $clearingDecision->getUploadTreeId();
284  foreach ($clearingDecision->getClearingLicenses() as $clearingLicense) {
285  if ($clearingLicense->isRemoved()) {
286  continue;
287  }
288  $ack = $clearingLicense->getAcknowledgement();
289  if (empty(trim($ack))) {
290  continue;
291  }
292  if (!isset($ackData[$ack])) {
293  $ackData[$ack] = array('files' => array(), 'licenses' => array());
294  }
295  $ackData[$ack]['files'][$uploadTreeId] = true;
296  $ackData[$ack]['licenses'][$clearingLicense->getShortName()] = true;
297  }
298  }
299  $result = array();
300  foreach ($ackData as $ack => $data) {
301  $result[$ack] = array(
302  'count' => count($data['files']),
303  'licenses' => array_keys($data['licenses'])
304  );
305  }
306  return $result;
307  }
308 
315  function buildAcknowledgementRows($uploadId, array $clearingDecisions)
316  {
317  $acknowledgements = $this->getAllAcknowledgementsForUpload($clearingDecisions);
318  $rows = "";
319  foreach ($acknowledgements as $ackText => $ackData) {
320  $ackHtml = htmlspecialchars($ackText, ENT_QUOTES);
321  $licensesHtml = htmlspecialchars(implode(', ', $ackData['licenses']));
322  $rows .= '<tr>';
323  $rows .= '<td style="width:5%;text-align:center">'
324  . '<a href="#" class="ack-count-link" data-upload="' . $uploadId
325  . '" data-ack="' . $ackHtml . '">' . $ackData['count'] . '</a></td>';
326  $rows .= '<td style="width:60%"><textarea class="ack-text-area" readonly="readonly"'
327  . ' data-original-ack="' . $ackHtml . '"'
328  . ' style="overflow:auto;width:98%;height:60px;">'
329  . $ackHtml . '</textarea></td>';
330  $rows .= '<td style="width:25%">' . $licensesHtml . '</td>';
331  $rows .= '<td style="width:10%;text-align:center">'
332  . '<button type="button" class="btn btn-danger btn-sm delete-ack-btn"'
333  . ' data-upload="' . $uploadId . '" data-ack="' . $ackHtml . '">'
334  . 'Delete</button></td>';
335  $rows .= '</tr>';
336  }
337  return $rows;
338  }
339 
346  function getAllObligationsForGivenUploadId($groupId, array $clearingDecisions)
347  {
348  $allClearedLicenses = array();
349  $licenseMap = new LicenseMap($this->dbManager, $groupId, LicenseMap::REPORT);
350  foreach ($clearingDecisions as $clearingDecision) {
351  if ($clearingDecision->getType() == DecisionTypes::IRRELEVANT) {
352  continue;
353  }
354  foreach ($clearingDecision->getClearingLicenses() as $clearingLicense) {
355  if ($clearingLicense->isRemoved()) {
356  continue;
357  }
358  $allClearedLicenses[$licenseMap->getProjectedId($clearingLicense->getLicenseId())] = true;
359  }
360  }
361  $uniqueLicenseIds = array_keys($allClearedLicenses);
362  $allObligations = array_merge(
363  $this->licenseDao->getLicenseObligations($uniqueLicenseIds) ?: array(),
364  $this->licenseDao->getLicenseObligations($uniqueLicenseIds, true) ?: array()
365  );
366  $groupedObligations = array();
367  foreach ($allObligations as $obligation) {
368  $groupBy = $obligation['ob_topic'];
369  $licenseName = LicenseRef::convertToSpdxId($obligation['rf_shortname'],
370  $obligation['rf_spdx_id']);
371  if (array_key_exists($groupBy, $groupedObligations)) {
372  $groupedObligations[$groupBy]['license'][$licenseName] = true;
373  } else {
374  $groupedObligations[$groupBy] = array(
375  "topic" => $obligation['ob_topic'],
376  "text" => $obligation['ob_text'],
377  "license" => array($licenseName => true)
378  );
379  }
380  }
381  foreach ($groupedObligations as &$ob) {
382  $ob['license'] = array_keys($ob['license']);
383  }
384  return $groupedObligations;
385  }
386 
391  protected function getCheckBoxSelectionList($listParams)
392  {
393  foreach ($listParams as $listkey => $listValue) {
394  $ret = GetParm($listValue, PARM_STRING);
395  if ($ret != $listkey) {
396  $cbList[] = "unchecked";
397  } else {
398  $cbList[] = "checked";
399  }
400  }
401  $cbSelectionList = implode(",", $cbList);
402 
403  return $cbSelectionList;
404  }
405 
406  public function Output()
407  {
408  $uploadId = GetParm("upload", PARM_INTEGER);
409  $groupId = Auth::getGroupId();
410  $userId = Auth::getUserId();
411  if (!$this->uploadDao->isAccessible($uploadId, $groupId)) {
412  return;
413  }
414 
415  $itemId = GetParm("item",PARM_INTEGER);
416  $this->vars['micromenu'] = Dir2Browse("browse", $itemId, NULL, $showBox=0, "View-Meta");
417  $this->vars['globalClearingAvailable'] = Auth::isClearingAdmin();
418 
419  $submitReportConf = GetParm("submitReportConf", PARM_STRING);
420 
421  if (isset($submitReportConf)) {
422  $applyGlobal = @$_POST["applyGlobal"];
423  $applyGlobal = !empty($applyGlobal) ? 1 : 0;
424  $parms = array();
425  $obLicensesEncoded = @$_POST["obLicenses"];
426  $obLicensesEncoded = !empty($obLicensesEncoded) ? $obLicensesEncoded : array();
427  $obLicenses = array();
428  array_walk($obLicensesEncoded,
429  function (&$licArray, $obTopic) use (&$obLicenses) {
430  $obLicenses[urldecode($obTopic)] = $licArray;
431  }
432  );
433  $i = 1;
434  $columns = "";
435  foreach ($this->mapDBColumns as $key => $value) {
436  $columns .= $value." = $".$i.", ";
437  $parms[] = GetParm($key, PARM_RAW);
438  $i++;
439  }
440  $parms[] = $this->getCheckBoxSelectionList($this->radioListUR);
441 
442  $unifiedReportColumnsForJson = array();
443  foreach (UploadDao::UNIFIED_REPORT_HEADINGS as $columnName => $columnValue) {
444  $columnResult = @$_POST[$columnName];
445  $unifiedReportColumnsForJson[$columnName] = array($columnResult[0] => isset($columnResult[1]) ? $columnResult[1] : null);
446  }
447  $clixmlColumnsForJson = array();
448  foreach (UploadDao::CLIXML_REPORT_HEADINGS as $columnName => $columnValue) {
449  $columnResult = @$_POST[$columnName];
450  $clixmlColumnsForJson[$columnName] = array($columnResult[0] => isset($columnResult[1]) ? $columnResult[1] : null);
451  }
452  $checkBoxUrPos = count($parms);
453  $parms[] = $this->getCheckBoxSelectionList($this->checkBoxListSPDX);
454  $checkBoxSpdxPos = count($parms);
455  $parms[] = json_encode($obLicenses);
456  $excludeObligationPos = count($parms);
457  $parms[] = json_encode($unifiedReportColumnsForJson);
458  $unifiedColumnsPos = count($parms);
459  $parms[] = json_encode($clixmlColumnsForJson);
460  $clixmlColumnsPos = count($parms);
461  $parms[] = $applyGlobal;
462  $applyGlobalPos = count($parms);
463  $parms[] = $uploadId;
464  $uploadIdPos = count($parms);
465 
466  $SQL = "UPDATE report_info SET $columns" .
467  "ri_ga_checkbox_selection = $$checkBoxUrPos, " .
468  "ri_spdx_selection = $$checkBoxSpdxPos, " .
469  "ri_excluded_obligations = $$excludeObligationPos, " .
470  "ri_unifiedcolumns = $$unifiedColumnsPos, " .
471  "ri_clixmlcolumns = $$clixmlColumnsPos, " .
472  "ri_globaldecision = $$applyGlobalPos " .
473  "WHERE upload_fk = $$uploadIdPos;";
474  $this->dbManager->getSingleRow($SQL, $parms,
475  __METHOD__ . "updateReportInfoData");
476 
477  if (@$_POST['markGlobal']) {
478  $upload = $this->uploadDao->getUpload($uploadId);
479  $uploadName = $upload->getFilename();
480  $jobId = JobAddJob($userId, $groupId, $uploadName, $uploadId);
482  $deciderPlugin = plugin_find("agent_deciderjob");
483  $conflictStrategyId = "global";
484  $errorMsg = "";
485  $deciderPlugin->AgentAdd($jobId, $uploadId, $errorMsg, array(), $conflictStrategyId);
486  $schedulerMsg = empty(GetRunnableJobList()) ? _("Is the scheduler running? ") : '';
487  $url = Traceback_uri() . "?mod=showjobs&upload=$uploadId";
488  $text = _("Your jobs have been added to job queue.");
489  $linkText = _("View Jobs");
490  $this->vars['message'] = "$schedulerMsg" . "$text <a href=\"$url\">$linkText</a>";
491  }
492  }
493  $this->vars += $this->allReportConfiguration($uploadId, $groupId);
494  $this->vars['typemap'] = [];
495  foreach (ComponentType::TYPE_MAP as $key => $name) {
496  if ($key == ComponentType::PACKAGEURL) {
497  continue;
498  }
499  $this->vars['typemap'][] = ['key' => $key, 'name' => $name];
500  }
501  }
502 
503  public function getTemplateName()
504  {
505  return "ui-report-conf.html.twig";
506  }
507 
512  protected function createScriptBlock()
513  {
514  return "
515 
516  var reportTabCookie = 'stickyReportTab';
517 
518  $(document).ready(function() {
519  $(\"#confTabs\").tabs({
520  active: ($.cookie(reportTabCookie) || 0),
521  activate: function(e, ui){
522  // Get active tab index and update cookie
523  var idString = $(e.currentTarget).attr('id');
524  idString = parseInt(idString.slice(-1)) - 1;
525  $.cookie(reportTabCookie, idString);
526  // Hide submit button on acknowledgements tab (AJAX-only tab)
527  if (ui.newPanel.attr('id') === 'acknowledgementsConfTab') {
528  $('#reportConfSubmit').hide();
529  } else {
530  $('#reportConfSubmit').show();
531  }
532  }
533  });
534 
535  var activeIdx = $.cookie(reportTabCookie) || 0;
536  if ($(\"#confTabs .ui-tabs-panel\").eq(activeIdx).attr('id') === 'acknowledgementsConfTab') {
537  $('#reportConfSubmit').hide();
538  }
539  $(\"input[name='critical']\").change(function(){
540  var val = $(\"input[name='critical']:checked\").val();
541  if (val == 'nonCritical') {
542  $('#criticalFilesText').hide();
543  $('#criticalFilesText').val('');
544  } else {
545  $('#criticalFilesText').css('display', 'block');
546  }
547  });
548  $(\"input[name='dependencySourceBinary']\").change(function(){
549  var val = $(\"input[name='dependencySourceBinary']:checked\").val();
550  if (val == 'noDependency') {
551  $('#dependencyBinarySource').hide();
552  $('#dependencyBinarySource').val('');
553  } else {
554  $('#dependencyBinarySource').css('display', 'block');
555  }
556  });
557  $(\"input[name='exportRestriction']\").change(function(){
558  var val = $(\"input[name='exportRestriction']:checked\").val();
559  if (val == 'noExportRestriction') {
560  $('#exportRestrictionText').hide();
561  $('#exportRestrictionText').val('');
562  } else {
563  $('#exportRestrictionText').css('display', 'block');
564  }
565  });
566  $(\"input[name='restrictionForUse']\").change(function(){
567  var val = $(\"input[name='restrictionForUse']:checked\").val();
568  if (val == 'noRestriction') {
569  $('#copyrightRestrictionText').hide();
570  $('#copyrightRestrictionText').val('');
571  } else {
572  $('#copyrightRestrictionText').css('display', 'block');
573  }
574  });
575 
576  $('#osselotExportCheckbox').change(function() {
577  if ($(this).is(':checked')) {
578  $('#spdxLicenseCommentCheckbox').prop('checked', true);
579  }
580  });
581  $(\"[data-toggle='tooltip']\").tooltip();
582  $('#spdxLicenseCommentCheckbox').change(function() {
583  if (!this.checked) {
584  $('#osselotExportCheckbox').prop('checked', false);
585  }
586  });
587 
588  var ackAjaxUrl = '?mod=ajax-acknowledgement-conf';
589 
590  $(document).on('click', '.ack-count-link', function(e) {
591  e.preventDefault();
592  var upload = $(this).data('upload');
593  var ack = $(this).data('ack');
594  $('#ackFilesModalBody').html('<p>Loading...</p>');
595  $('#ackFilesModalCount').text('');
596  $('#ackFilesModal').modal('show');
597  $.get(ackAjaxUrl, {action: 'getFiles', upload: upload, ack: ack},
598  function(data) {
599  if (!data || data.length === 0) {
600  $('#ackFilesModalCount').text('');
601  $('#ackFilesModalBody').html('<p>No files found.</p>');
602  return;
603  }
604  $('#ackFilesModalCount').text('(' + data.length + ' files)');
605  var html = '<table class=\"table table-condensed table-hover\" style=\"margin:0;\">'
606  + '<thead><tr><th>#</th><th>File</th></tr></thead><tbody>';
607  $.each(data, function(i, file) {
608  html += '<tr><td>' + (i + 1) + '</td>'
609  + '<td><a href=\"' + file.url + '\" target=\"_blank\">'
610  + $('<span/>').text(file.name).html()
611  + '</a></td></tr>';
612  });
613  html += '</tbody></table>';
614  $('#ackFilesModalBody').html(html);
615  }
616  ).fail(function() {
617  $('#ackFilesModalCount').text('');
618  $('#ackFilesModalBody').html('<p>Error loading files.</p>');
619  });
620  });
621 
622  $(document).on('dblclick', '.ack-text-area', function() {
623  if (!$(this).prop('readonly')) {
624  return;
625  }
626  var ta = $(this);
627  var td = ta.closest('td');
628  ta.prop('readonly', false).css('border', '2px solid #337ab7').focus();
629  td.append('<div class=\"ack-edit-actions\" style=\"margin-top:4px;\">'
630  + '<button type=\"button\" class=\"btn btn-primary btn-xs ack-save-btn\">Save</button> '
631  + '<button type=\"button\" class=\"btn btn-light btn-xs ack-cancel-btn\">Cancel</button>'
632  + '</div>');
633  });
634 
635  $(document).on('click', '.ack-save-btn', function() {
636  var row = $(this).closest('tr');
637  var td = $(this).closest('td');
638  var ta = td.find('.ack-text-area');
639  var newAck = ta.val();
640  var oldAck = ta.data('original-ack');
641  if (newAck === oldAck) {
642  ta.prop('readonly', true).css('border', '');
643  td.find('.ack-edit-actions').remove();
644  return;
645  }
646  var upload = row.find('.ack-count-link').data('upload');
647  $.post(ackAjaxUrl,
648  {action: 'updateAcknowledgement', upload: upload, oldAck: oldAck, newAck: newAck},
649  function(data) {
650  if (data && data.status === 'success') {
651  $('#acknowledgementsConfTab tbody tr').each(function() {
652  if ($(this).find('.ack-text-area').data('original-ack') === newAck
653  && this !== row[0]) {
654  $(this).remove();
655  }
656  });
657  ta.val(newAck)
658  .data('original-ack', newAck)
659  .prop('readonly', true)
660  .css('border', '');
661  row.find('.ack-count-link').text(data.count).data('ack', newAck);
662  row.find('.delete-ack-btn').data('ack', newAck);
663  td.find('.ack-edit-actions').remove();
664  } else {
665  alert('Failed to update acknowledgement.');
666  }
667  }
668  ).fail(function() {
669  alert('Error communicating with server.');
670  });
671  });
672 
673  $(document).on('click', '.ack-cancel-btn', function() {
674  var td = $(this).closest('td');
675  var ta = td.find('.ack-text-area');
676  ta.val(ta.data('original-ack'))
677  .prop('readonly', true)
678  .css('border', '');
679  td.find('.ack-edit-actions').remove();
680  });
681 
682  $(document).on('click', '.delete-ack-btn', function() {
683  var upload = $(this).data('upload');
684  var ack = $(this).data('ack');
685  if (!confirm('Are you sure you want to clear this acknowledgement from all files?')) {
686  return;
687  }
688  var row = $(this).closest('tr');
689  $.post(ackAjaxUrl,
690  {action: 'deleteAcknowledgement', upload: upload, ack: ack},
691  function(data) {
692  if (data && data.status === 'success') {
693  row.fadeOut(400, function() { row.remove(); });
694  } else {
695  alert('Failed to delete acknowledgement.');
696  }
697  }
698  ).fail(function() {
699  alert('Error communicating with server.');
700  });
701  });
702  });
703  ";
704  }
705 }
706 
707 $NewPlugin = new ui_report_conf();
708 $NewPlugin->Initialize();
This is the Plugin class. All plugins should:
Definition: FO_Plugin.php:57
Output()
This function is called when user output is requested. This function is responsible for content....
Definition: FO_Plugin.php:399
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
Wrapper class for license map.
Definition: LicenseMap.php:19
getAllObligationsForGivenUploadId($groupId, array $clearingDecisions)
get all the obligations for cleared licenses
createScriptBlock()
Create Script block for conf.
buildAcknowledgementRows($uploadId, array $clearingDecisions)
Build HTML table rows for acknowledgements tab.
getAllAcknowledgementsForUpload(array $clearingDecisions)
Get acknowledgements for cleared licenses grouped by text.
allReportConfiguration($uploadId, $groupId)
list all the options for Report Configuration
RegisterMenus()
Customize submenus.
getCheckBoxSelectionList($listParams)
__construct()
base constructor. Most plugins will just use this
Dir2Browse($Mod, $UploadtreePk, $LinkLast=NULL, $ShowBox=1, $ShowMicro=NULL, $Enumerate=-1, $PreText='', $PostText='', $uploadtree_tablename="uploadtree")
Get an html linked string of a file browse path.
Definition: common-dir.php:263
menu_insert($Path, $LastOrder=0, $URI=NULL, $Title=NULL, $Target=NULL, $HTML=NULL)
Given a Path, order level for the last item, and optional plugin name, insert the menu item.
Traceback_uri()
Get the URI without query to this location.
Definition: common-parm.php:97
const PARM_INTEGER
Definition: common-parm.php:14
const PARM_RAW
Definition: common-parm.php:22
const PARM_STRING
Definition: common-parm.php:18
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
Definition: common-parm.php:46
Traceback_parm_keep($List)
Create a new URI, keeping only these items.
plugin_find($pluginName)
Given the official name of a plugin, return the $Plugins object.
GetRunnableJobList()
Get runnable job list, the process is below:
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690
#define PLUGIN_DB_READ
Plugin requires read permission on DB.
Definition: libfossology.h:37
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16