FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
ui-export-list.php
Go to the documentation of this file.
1 <?php
2 /***********************************************************
3  * Copyright (C) 2014-2017,2020 Siemens AG
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  **********************************************************/
18 
37 
42 class UIExportList extends FO_Plugin
43 {
46  private $uploadDao;
47 
50  private $licenseDao;
51 
54  private $clearingDao;
55 
58  private $copyrightDao;
59 
62  private $clearingFilter;
63 
66  private $treeDao;
67 
70  protected $delimiter = ',';
71 
74  protected $enclosure = '"';
75 
76  function __construct()
77  {
78  $this->Name = "export-list";
79  $this->Title = _("Export Lists");
80  $this->Dependency = array("browse");
81  $this->DBaccess = PLUGIN_DB_READ;
82  $this->LoginFlag = 0;
83  $this->NoHeader = 0;
84  parent::__construct();
85  $this->uploadDao = $GLOBALS['container']->get('dao.upload');
86  $this->licenseDao = $GLOBALS['container']->get('dao.license');
87  $this->clearingDao = $GLOBALS['container']->get('dao.clearing');
88  $this->copyrightDao = $GLOBALS['container']->get('dao.copyright');
89  $this->treeDao = $GLOBALS['container']->get('dao.tree');
90  $this->clearingFilter = $GLOBALS['container']->get('businessrules.clearing_decision_filter');
91  }
92 
97  public function setDelimiter($delimiter=',')
98  {
99  $this->delimiter = substr($delimiter, 0, 1);
100  }
101 
106  public function setEnclosure($enclosure='"')
107  {
108  $this->enclosure = substr($enclosure, 0, 1);
109  }
110 
114  function RegisterMenus()
115  {
116  // For all other menus, permit coming back here.
117  $URI = $this->Name . Traceback_parm_keep(array(
118  "show",
119  "format",
120  "page",
121  "upload",
122  "item",
123  ));
124  $MenuDisplayString = _("Export List");
125  $Item = GetParm("item", PARM_INTEGER);
126  $Upload = GetParm("upload", PARM_INTEGER);
127  if (empty($Item) || empty($Upload)) {
128  return;
129  }
130  if (GetParm("mod", PARM_STRING) == $this->Name) {
131  menu_insert("Browse::$MenuDisplayString", 1);
132  } else {
133  menu_insert("Browse::$MenuDisplayString", 1, $URI, $MenuDisplayString);
134  /* bobg - This is to use a select list in the micro menu to replace the above List
135  and Download, but put this select list in a form
136  $LicChoices = array("Lic Download" => "Download", "Lic display" => "Display");
137  $LicChoice = Array2SingleSelect($LicChoices, $SLName="LicDL");
138  menu_insert("Browse::Nomos License List Download2", 1, $URI . "&output=dltext", NULL,NULL, $LicChoice);
139  */
140  }
141  }
142 
149  function getAgentPksFromRequest($upload_pk)
150  {
151  $agents = array_keys(AgentRef::AGENT_LIST);
152  $agent_pks = array();
153 
154  foreach ($agents as $agent) {
155  if (GetParm("agentToInclude_".$agent, PARM_STRING)) {
156  /* get last nomos agent_pk that has data for this upload */
157  $AgentRec = AgentARSList($agent."_ars", $upload_pk, 1);
158  if ($AgentRec !== false) {
159  $agent_pks[$agent] = $AgentRec[0]["agent_fk"];
160  } else {
161  $agent_pks[$agent] = false;
162  }
163  }
164  }
165  return $agent_pks;
166  }
167 
180  public function createListOfLines($uploadtreeTablename, $uploadtree_pk,
181  $agent_pks, $NomostListNum, $includeSubfolder, $exclude, $ignore)
182  {
183  $licensesPerFileName = array();
185  $itemTreeBounds = $this->uploadDao->getItemTreeBounds($uploadtree_pk,
186  $uploadtreeTablename);
187  $allDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBounds,
188  Auth::getGroupId());
189  $editedMappedLicenses = $this->clearingFilter->filterCurrentClearingDecisionsForLicenseList($allDecisions);
190  $licensesPerFileName = $this->licenseDao->getLicensesPerFileNameForAgentId($itemTreeBounds,
191  $agent_pks, $includeSubfolder, $exclude, $ignore, $editedMappedLicenses);
192  /* how many lines of data do you want to display */
193  $currentNum = 0;
194  $lines = [];
195  foreach ($licensesPerFileName as $fileName => $licenseNames) {
196  if ($licenseNames !== false && count($licenseNames) > 0) {
197  if ($NomostListNum > -1 && ++$currentNum > $NomostListNum) {
198  $lines["warn"] = _("<br><b>Warning: Only the first $NomostListNum " .
199  "lines are displayed. To see the whole list, run " .
200  "fo_nomos_license_list from the command line.</b><br>");
201  // TODO: the following should be done using a "LIMIT" statement in the sql query
202  break;
203  }
204 
205  $row = array();
206  $row['filePath'] = $fileName;
207  $row['agentFindings'] = $licenseNames['scanResults'];
208  $row['conclusions'] = null;
209  if (array_key_exists('concludedResults', $licenseNames) && !empty($licenseNames['concludedResults'])) {
210  $row['conclusions'] = $this->consolidateConclusions($licenseNames['concludedResults']);
211  $lines[] = $row;
212  } else {
213  $lines[] = $row;
214  }
215  }
216  if (!$ignore && $licenseNames === false) {
217  $row = array();
218  $row['filePath'] = $fileName;
219  $row['agentFindings'] = null;
220  $row['conclusions'] = null;
221  $lines[] = $row;
222  }
223  }
224  return $lines;
225  }
226 
231  public function getTemplateName()
232  {
233  return "ui-export-list.html.twig";
234  }
235 
239  function Output()
240  {
241  global $PG_CONN;
242  global $SysConf;
243  $formVars = array();
244  if (!$PG_CONN) {
245  echo _("NO DB connection");
246  }
247 
248  if ($this->State != PLUGIN_STATE_READY) {
249  return (0);
250  }
251  $uploadtree_pk = GetParm("item", PARM_INTEGER);
252  if (empty($uploadtree_pk)) {
253  return;
254  }
255 
256  $upload_pk = GetParm("upload", PARM_INTEGER);
257  if (empty($upload_pk)) {
258  return;
259  }
260  if (!$this->uploadDao->isAccessible($upload_pk, Auth::getGroupId())) {
261  $text = _("Permission Denied");
262  return "<h2>$text</h2>";
263  }
264  $uploadtreeTablename = GetUploadtreeTableName($upload_pk);
265 
266  $warnings = array();
267  $exportCopyright = GetParm('export_copy', PARM_STRING);
268  if (!empty($exportCopyright) && $exportCopyright == "yes") {
269  $exportCopyright = true;
270  $copyrightType = GetParm('copyright_type', PARM_STRING);
271  $formVars["export_copy"] = "1";
272  if ($copyrightType == "all") {
273  $formVars["copy_type_all"] = 1;
274  } else {
275  $formVars["copy_type_nolic"] = 1;
276  }
277  } else {
278  $exportCopyright = false;
279  $agent_pks_dict = $this->getAgentPksFromRequest($upload_pk);
280  $agent_pks = array();
281  foreach ($agent_pks_dict as $agent_name => $agent_pk) {
282  if ($agent_pk === false) {
283  $warnings[] = _("No information for agent: $agent_name");
284  } else {
285  $agent_pks[] = $agent_pk;
286  $formVars["agentToInclude_".$agent_name] = "1";
287  }
288  }
289  }
290 
291  // Make sure all copyrights is selected in the form be default
292  if (!(array_key_exists('copy_type_all', $formVars) ||
293  array_key_exists('copy_type_nolic', $formVars))) {
294  $formVars["copy_type_all"] = 1;
295  }
296 
297  $dltext = (GetParm("output", PARM_STRING) == 'dltext');
298  $formVars["dltext"] = $dltext;
299 
300  $NomostListNum = @$SysConf['SYSCONFIG']['NomostListNum'];
301  $formVars["NomostListNum"] = $NomostListNum;
302 
303  $includeSubfolder = (GetParm("doNotIncludeSubfolder", PARM_STRING) !== "yes");
304  $formVars["includeSubfolder"] = $includeSubfolder;
305 
306  $ignore = (GetParm("showContainers", PARM_STRING) !== "yes");
307  $formVars["showContainers"] = !$ignore;
308  $exclude = GetParm("exclude", PARM_STRING);
309  $formVars["exclude"] = $exclude;
310 
311  $this->vars = array_merge($this->vars, $formVars);
312 
313  if ($exportCopyright) {
314  $lines = $this->getCopyrights($upload_pk, $uploadtree_pk,
315  $uploadtreeTablename, $NomostListNum, $exclude, $copyrightType);
316  } else {
317  $lines = $this->createListOfLines($uploadtreeTablename, $uploadtree_pk,
318  $agent_pks, $NomostListNum, $includeSubfolder, $exclude, $ignore);
319  }
320 
321  $this->vars['warnings'] = array();
322  if (array_key_exists("warn",$lines)) {
323  $warnings[] = $lines["warn"];
324  unset($lines["warn"]);
325  }
326  foreach ($warnings as $warning) {
327  $this->vars['warnings'][] = "<br><b>$warning</b><br>";
328  }
329  if (empty($lines)) {
330  $this->vars['warnings'][] = "<br /><b>Result empty</b><br />";
331  }
332 
333  if ($dltext) {
334  return $this->printCSV($lines, $uploadtreeTablename, $exportCopyright);
335  } else {
336  $this->vars['listoutput'] = $this->printLines($lines, $exportCopyright);
337  return;
338  }
339  }
340 
354  public function getCopyrights($uploadId, $uploadtree_pk, $uploadTreeTableName,
355  $NomostListNum, $exclude, $copyrightType = "all")
356  {
357  $agentName = "copyright";
358  $scanJobProxy = new ScanJobProxy($GLOBALS['container']->get('dao.agent'),
359  $uploadId);
360  $scanJobProxy->createAgentStatus([$agentName]);
361  $selectedScanners = $scanJobProxy->getLatestSuccessfulAgentIds();
362  if (!array_key_exists($agentName, $selectedScanners)) {
363  return array();
364  }
365  $latestAgentId = $selectedScanners[$agentName];
366  $agentFilter = ' AND C.agent_fk='.$latestAgentId;
367 
368  $itemTreeBounds = $this->uploadDao->getItemTreeBounds($uploadtree_pk,
369  $uploadTreeTableName);
370  $extrawhere = "UT.lft BETWEEN " . $itemTreeBounds->getLeft() . " AND " .
371  $itemTreeBounds->getRight();
372  if (! empty($exclude)) {
373  $extrawhere .= " AND UT.ufile_name NOT LIKE '%$exclude%'";
374  }
375  $lines = [];
376 
377  $copyrights = $this->copyrightDao->getScannerEntries($agentName,
378  $uploadTreeTableName, $uploadId, null, $extrawhere . $agentFilter);
379  $this->updateCopyrightList($lines, $copyrights, $NomostListNum,
380  $uploadTreeTableName, "content");
381 
382  $copyrights = $this->copyrightDao->getEditedEntries('copyright_decision',
383  $uploadTreeTableName, $uploadId, [], $extrawhere);
384  $this->updateCopyrightList($lines, $copyrights, $NomostListNum,
385  $uploadTreeTableName, "textfinding");
386 
387  if ($copyrightType != "all") {
388  $agentList = [];
389  foreach (AgentRef::AGENT_LIST as $agentname => $value) {
390  $AgentRec = AgentARSList($agentname."_ars", $uploadId, 1);
391  if (!empty($AgentRec)) {
392  $agentList[] = $AgentRec[0]["agent_fk"];
393  }
394  }
395  $this->removeCopyrightWithLicense($lines, $itemTreeBounds, $agentList,
396  $exclude);
397  }
398  return $this->reduceCopyrightLines($lines);
399  }
400 
409  private function updateCopyrightList(&$list, $newCopyrights, $NomostListNum,
410  $uploadTreeTableName, $key)
411  {
412  foreach ($newCopyrights as $copyright) {
413  if ($NomostListNum > -1 && count($list) >= $NomostListNum) {
414  $lines["warn"] = _("<br><b>Warning: Only the first $NomostListNum lines
415  are displayed. To see the whole list, run fo_nomos_license_list from the
416  command line.</b><br>");
417  break;
418  }
419  $row = [];
420  $row["content"] = $copyright[$key];
421  $row["filePath"] = $this->treeDao->getFullPath($copyright["uploadtree_pk"],
422  $uploadTreeTableName);
423  $list[$row["filePath"]][] = $row;
424  }
425  }
426 
435  private function removeCopyrightWithLicense(&$lines, $itemTreeBounds,
436  $agentList, $exclude)
437  {
438  $licensesPerFileName = array();
439  $allDecisions = $this->clearingDao->getFileClearingsFolder($itemTreeBounds,
440  Auth::getGroupId());
441  $editedMappedLicenses = $this->clearingFilter->filterCurrentClearingDecisionsForCopyrightList(
442  $allDecisions);
443  $licensesPerFileName = $this->licenseDao->getLicensesPerFileNameForAgentId(
444  $itemTreeBounds, $agentList, true, $exclude, true, $editedMappedLicenses);
445  foreach ($licensesPerFileName as $fileName => $licenseNames) {
446  if ($licenseNames !== false && count($licenseNames) > 0) {
447  if (array_key_exists('concludedResults', $licenseNames)) {
448  $conclusions = $this->consolidateConclusions($licenseNames['concludedResults']);
449  if (in_array("Void", $conclusions)) {
450  // File has all licenses removed or irrelevant decision
451  continue;
452  }
453  // File has license conclusions
454  $this->removeIfKeyExists($lines, $fileName);
455  }
456  if ((! empty($licenseNames['scanResults'])) &&
457  ! (in_array("No_license_found", $licenseNames['scanResults']) ||
458  in_array("Void", $licenseNames['scanResults']))) {
459  $this->removeIfKeyExists($lines, $fileName);
460  }
461  }
462  }
463  }
464 
470  private function consolidateConclusions($conclusions)
471  {
472  $consolidatedConclusions = array();
473  foreach ($conclusions as $conclusion) {
474  $consolidatedConclusions = array_merge($consolidatedConclusions,
475  $conclusion);
476  }
477  return array_unique($consolidatedConclusions);
478  }
479 
487  private function removeIfKeyExists(&$lines, $key)
488  {
489  foreach (array_keys($lines) as $file) {
490  if (strpos($file, $key) !== false) {
491  unset($lines[$file]);
492  break;
493  }
494  }
495  }
496 
503  private function printLines($lines, $copyright=false)
504  {
505  $V = '';
506  if ($copyright) {
507  foreach ($lines as $row) {
508  $V .= $row['filePath'] . ": " . htmlentities($row['content']) . "\n";
509  }
510  } else {
511  foreach ($lines as $row) {
512  $V .= $row['filePath'];
513  if ($row['agentFindings'] !== null) {
514  $V .= ": " . implode(' ', $row['agentFindings']);
515  if ($row['conclusions'] !== null) {
516  $V .= ", " . implode(' ', $row['conclusions']);
517  }
518  }
519  $V .= "\n";
520  }
521  }
522  return $V;
523  }
524 
532  private function printCSV($lines, $uploadtreeTablename, $copyright = false)
533  {
534  $request = $this->getRequest();
535  $itemId = intval($request->get('item'));
536  $path = Dir2Path($itemId, $uploadtreeTablename);
537  $fileName = $path[count($path) - 1]['ufile_name']."-".date("Ymd");
538  if ($copyright) {
539  $fileName .= "-copyrights";
540  } else {
541  $fileName .= "-licenses";
542  }
543 
544  $out = fopen('php://output', 'w');
545  ob_start();
546  if (!$copyright) {
547  $head = array('file path', 'scan results', 'concluded results');
548  } else {
549  $head = array('file path', 'copyright');
550  }
551  fputcsv($out, $head, $this->delimiter, $this->enclosure);
552  foreach ($lines as $row) {
553  $newRow = array();
554  $newRow[] = $row['filePath'];
555  if ($copyright) {
556  $newRow[] = $row['content'];
557  } else {
558  if ($row['agentFindings'] !== null) {
559  $newRow[] = implode(' ', $row['agentFindings']);
560  } else {
561  $newRow[] = "";
562  }
563  if ($row['conclusions'] !== null) {
564  $newRow[] = implode(' ', $row['conclusions']);
565  } else {
566  $newRow[] = "";
567  }
568  }
569  fputcsv($out, $newRow, $this->delimiter, $this->enclosure);
570  }
571  $content = ob_get_contents();
572  ob_end_clean();
573 
574  $headers = array(
575  'Content-type' => 'text/csv, charset=UTF-8',
576  'Content-Disposition' => 'attachment; filename='.$fileName.'.csv',
577  'Pragma' => 'no-cache',
578  'Cache-Control' => 'no-cache, must-revalidate, maxage=1, post-check=0, pre-check=0',
579  'Expires' => 'Expires: Thu, 19 Nov 1981 08:52:00 GMT'
580  );
581 
582  return new Response($content, Response::HTTP_OK, $headers);
583  }
584 
590  private function reduceCopyrightLines($lines)
591  {
592  $reducedLines = array();
593  foreach ($lines as $line) {
594  foreach ($line as $copyright) {
595  $reducedLines[] = $copyright;
596  }
597  }
598  return $reducedLines;
599  }
600 }
601 
602 $NewPlugin = new UIExportList();
603 $NewPlugin->Initialize();
FUNCTION char * GetUploadtreeTableName(PGconn *pgConn, int upload_pk)
Get the uploadtree table name for this upload_pk If upload_pk does not exist, return "uploadtree"...
Definition: libfossagent.c:421
printCSV($lines, $uploadtreeTablename, $copyright=false)
getCopyrights($uploadId, $uploadtree_pk, $uploadTreeTableName, $NomostListNum, $exclude, $copyrightType="all")
setEnclosure($enclosure='"')
Dir2Path($uploadtree_pk, $uploadtree_tablename='uploadtree')
Return the path (without artifacts) of an uploadtree_pk.
Definition: common-dir.php:233
setDelimiter($delimiter=',')
reduceCopyrightLines($lines)
#define PLUGIN_DB_READ
Plugin requires read permission on DB.
Definition: libfossology.h:49
removeCopyrightWithLicense(&$lines, $itemTreeBounds, $agentList, $exclude)
printLines($lines, $copyright=false)
Definition: state.hpp:26
updateCopyrightList(&$list, $newCopyrights, $NomostListNum, $uploadTreeTableName, $key)
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
Definition: common-parm.php:57
Output()
This function returns the scheduler status.
removeIfKeyExists(&$lines, $key)
const PARM_STRING
Definition: common-parm.php:29
getAgentPksFromRequest($upload_pk)
const PARM_INTEGER
Definition: common-parm.php:25
This is the Plugin class. All plugins should:
Definition: FO_Plugin.php:67
RegisterMenus()
Customize submenus.
consolidateConclusions($conclusions)
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...
foreach($Options as $Option=> $OptVal) if(0==$reference_flag &&0==$nomos_flag) $PG_CONN
Traceback_parm_keep($List)
Create a new URI, keeping only these items.