FOSSology  4.5.0-rc1
Open Source License Compliance by Open Source Software
spdx.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2015-2016,2023 Siemens AG
4  SPDX-FileCopyrightText: © 2017 TNG Technology Consulting GmbH
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
43 namespace Fossology\Spdx;
44 
64 use Twig\Environment;
65 
66 include_once(__DIR__ . "/spdxutils.php");
67 
68 include_once(__DIR__ . "/version.php");
69 include_once(__DIR__ . "/services.php");
70 
75 class SpdxAgent extends Agent
76 {
77 
78  const OUTPUT_FORMAT_KEY = "outputFormat";
79  const DEFAULT_OUTPUT_FORMAT = "spdx2";
80  const AVAILABLE_OUTPUT_FORMATS = "spdx2,spdx2tv,dep5,spdx2csv,spdx3jsonld,spdx3json,spdx3rdf,spdx3tv";
81  const UPLOAD_ADDS = "uploadsAdd";
82  const DATA_LICENSE = "CC0-1.0";
83 
87  private $uploadDao;
91  private $clearingDao;
95  private $licenseDao;
99  protected $dbManager;
103  protected $renderer;
107  private $licenseMap;
127  private $reportutils;
131  protected $agentNames = AgentRef::AGENT_LIST;
135  protected $filebasename = null;
139  protected $uri;
143  protected $filename;
148  private $licensesInDocument = [];
161 
162  function __construct()
163  {
164  // deduce the agent name from the command line arguments
165  $args = getopt("", array(self::OUTPUT_FORMAT_KEY.'::'));
166  $agentName = "";
167  if (array_key_exists(self::OUTPUT_FORMAT_KEY, $args)) {
168  $agentName = trim($args[self::OUTPUT_FORMAT_KEY]);
169  }
170  if (empty($agentName)) {
172  }
173 
174  parent::__construct($agentName, AGENT_VERSION, AGENT_REV);
175 
176  $this->uploadDao = $this->container->get('dao.upload');
177  $this->clearingDao = $this->container->get('dao.clearing');
178  $this->licenseDao = $this->container->get('dao.license');
179  $this->dbManager = $this->container->get('db.manager');
180  $this->renderer = $this->container->get('twig.environment');
181  $this->renderer->setCache(false);
182 
183  $this->agentSpecifLongOptions[] = self::UPLOAD_ADDS.':';
184  $this->agentSpecifLongOptions[] = self::OUTPUT_FORMAT_KEY.':';
185 
186  $this->licenseClearedGetter = new LicenseClearedGetter();
187  $this->licenseMainGetter = new LicenseMainGetter();
188  $this->obligationsGetter = new ObligationsGetter();
189  $this->reportutils = new ReportUtils();
190  }
191 
197  protected function preWorkOnArgs($args)
198  {
199  if ((!array_key_exists(self::OUTPUT_FORMAT_KEY, $args)
200  || $args[self::OUTPUT_FORMAT_KEY] === "")
201  && array_key_exists(self::UPLOAD_ADDS,$args)) {
202  $args = SpdxUtils::preWorkOnArgsFlp($args,self::UPLOAD_ADDS,self::OUTPUT_FORMAT_KEY);
203  } else {
204  if (!array_key_exists(self::UPLOAD_ADDS,$args) || $args[self::UPLOAD_ADDS] === "") {
205  $args = SpdxUtils::preWorkOnArgsFlp($args,self::UPLOAD_ADDS,self::OUTPUT_FORMAT_KEY);
206  }
207  }
208  return $args;
209  }
210 
215  function processUploadId($uploadId)
216  {
217  $args = $this->preWorkOnArgs($this->args);
218 
219  if (array_key_exists(self::OUTPUT_FORMAT_KEY,$args)) {
220  $possibleOutputFormat = trim($args[self::OUTPUT_FORMAT_KEY]);
221  if (in_array($possibleOutputFormat, explode(',',self::AVAILABLE_OUTPUT_FORMATS))) {
222  $this->outputFormat = $possibleOutputFormat;
223  }
224  }
225  $this->licenseMap = new LicenseMap($this->dbManager, $this->groupId, LicenseMap::REPORT, true);
226  $this->computeUri($uploadId);
227 
228  $docLicense = $this->licenseDao->getLicenseByShortName(self::DATA_LICENSE);
229  $docLicenseId = $docLicense->getId() . "-" . md5($docLicense->getText());
230  $this->licensesInDocument[$docLicenseId] = (new SpdxLicenseInfo())
231  ->setLicenseObj($docLicense)
232  ->setListedLicense(true)
233  ->setCustomText(false)
234  ->setTextPrinted(true);
235 
236  $packageNodes = $this->renderPackage($uploadId);
237  $additionalUploadIds = array_key_exists(self::UPLOAD_ADDS,$args) ? explode(',',$args[self::UPLOAD_ADDS]) : array();
238  $packageIds = array($uploadId);
239  foreach ($additionalUploadIds as $additionalId) {
240  $packageNodes .= $this->renderPackage($additionalId);
241  $packageIds[] = $additionalId;
242  }
243 
244  $this->writeReport($packageNodes, $packageIds, $uploadId);
245  return true;
246  }
247 
253  protected function getTemplateFile($partname)
254  {
255  $prefix = $this->outputFormat . "-";
256  $postfix = ".twig";
257  switch ($this->outputFormat) {
258  case "spdx2":
259  $postfix = ".xml" . $postfix;
260  break;
261  case "spdx2csv":
262  case "spdx2tv":
263  break;
264  case "dep5":
265  $prefix .= "copyright-";
266  break;
267  case "spdx3jsonld":
268  break;
269  case "spdx3rdf":
270  $postfix = ".xml" . $postfix;
271  break;
272  case "spdx3json":
273  break;
274  case "spdx3tv":
275  break;
276  }
277  return $prefix . $partname . $postfix;
278  }
279 
287  protected function getFileBasename($packageName)
288  {
289  if ($this->filebasename == null) {
290  $fileName = strtoupper($this->outputFormat)."_".$packageName;
291  switch ($this->outputFormat) {
292  case "spdx2":
293  $fileName .= ".spdx.rdf";
294  break;
295  case "spdx2tv":
296  $fileName .= ".spdx";
297  break;
298  case "spdx2csv":
299  $fileName .= ".csv";
300  break;
301  case "dep5":
302  $fileName .= ".txt";
303  break;
304  case "spdx3jsonld":
305  $fileName = $fileName .".jsonld";
306  break;
307  case "spdx3json":
308  $fileName = $fileName .".json";
309  break;
310  case "spdx3rdf":
311  $fileName = $fileName .".spdx.rdf";
312  break;
313  case "spdx3tv":
314  $fileName = $fileName .".spdx";
315  break;
316  }
317  $this->filebasename = $fileName;
318  }
319  return $this->filebasename;
320  }
321 
327  protected function getFileName($packageName)
328  {
329  global $SysConf;
330  $fileBase = $SysConf['FOSSOLOGY']['path']."/report/";
331  return $fileBase. $this->getFileBasename($packageName);
332  }
333 
339  protected function getUri($packageName)
340  {
341  global $SysConf;
342  $url=$SysConf['SYSCONFIG']['FOSSologyURL'];
343  if (substr( $url, 0, 4 ) !== "http") {
344  $url="http://".$url;
345  }
346 
347  return rtrim($url, '/') . '/' . $this->getFileBasename($packageName);
348  }
349 
355  protected function renderPackage($uploadId)
356  {
357  $uploadTreeTableName = $this->uploadDao->getUploadtreeTableName($uploadId);
358  $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId,$uploadTreeTableName);
359  $this->heartbeat(0);
360 
361  $filesWithLicenses = $this->reportutils
362  ->getFilesWithLicensesFromClearings($itemTreeBounds, $this->groupId,
363  $this, $this->licensesInDocument);
364  $this->heartbeat(0);
365 
366  $this->reportutils->addClearingStatus($filesWithLicenses,$itemTreeBounds, $this->groupId);
367  $this->heartbeat(0);
368 
369  $scannerIDs = $this->reportutils->addScannerResults($filesWithLicenses, $itemTreeBounds, $this->groupId, $this->licensesInDocument);
370  $licenseComment = "";
371  if (!empty($scannerIDs)) {
372  $licenseComment = $this->getLicenseComment($scannerIDs);
373  }
374  $this->heartbeat(0);
375 
376  $this->reportutils->addCopyrightResults($filesWithLicenses, $uploadId);
377  $this->heartbeat(0);
378 
379  $upload = $this->uploadDao->getUpload($uploadId);
380  $fileNodes = $this->generateFileNodes($filesWithLicenses, $upload->getTreeTableName(), $uploadId);
381 
382  $mainLicenseIds = $this->clearingDao->getMainLicenseIds($uploadId, $this->groupId);
383  $mainLicenses = array();
384  foreach ($mainLicenseIds as $licId) {
385  $reportedLicenseId = $this->licenseMap->getProjectedId($licId);
386  $mainLicense = $this->licenseDao->getLicenseById($reportedLicenseId, $this->groupId);
387  $reportLicId = $mainLicense->getId() . "-" . md5($mainLicense->getText());
388  $mainLicenses[] = $reportLicId;
389  if (!array_key_exists($reportLicId, $this->licensesInDocument)) {
390  $listedLicense = stripos($mainLicense->getSpdxId(),
391  LicenseRef::SPDXREF_PREFIX) !== 0;
392  $this->licensesInDocument[$reportLicId] = (new SpdxLicenseInfo())
393  ->setLicenseObj($mainLicense)
394  ->setCustomText(false)
395  ->setListedLicense($listedLicense);
396  }
397  }
398  $mainLicenseString = [];
399  if ($this->outputFormat == "spdx2tv" ||
400  $this->outputFormat == "spdx2csv" ||
401  $this->outputFormat == "spdx3tv") {
402  foreach ($mainLicenses as $mainLicense) {
403  $shortName = $this->licensesInDocument[$mainLicense]
404  ->getLicenseObj()->getShortName();
405  if (StringOperation::stringStartsWith($shortName,
406  LicenseRef::SPDXREF_PREFIX)) {
407  $mainLicenseString[] = $shortName;
408  } else {
409  $mainLicenseString[] = $this->licensesInDocument[$mainLicense]
410  ->getLicenseObj()->getSpdxId();
411  }
412  }
413  $mainLicenseString = SpdxUtils::implodeLicenses(
414  SpdxUtils::removeEmptyLicenses($mainLicenseString));
415  }
416 
417  $hashes = $this->uploadDao->getUploadHashes($uploadId);
418 
419  $reportInfo = $this->uploadDao->getReportInfo($uploadId);
420  $componentId = $reportInfo['ri_component_id'];
421  $componentType = $reportInfo['ri_component_type'];
422  $componentVersion = $reportInfo['ri_version'];
423  $generalAssessment = $reportInfo['ri_general_assesment'];
424  $releaseDate = $reportInfo['ri_release_date'];
425  if ($componentId == "NA") {
426  $componentId = "";
427  }
428  if ($componentVersion == "NA") {
429  $componentVersion = "";
430  }
431  if ($generalAssessment == "NA") {
432  $generalAssessment = "";
433  }
434  if ($releaseDate == "NA") {
435  $releaseDate = "";
436  } else {
437  $timeStamp = strtotime($releaseDate);
438  if ($timeStamp != -1) {
439  $releaseDate = date("Y-m-d\\T00:00:00\\Z", $timeStamp);
440  } else {
441  $releaseDate = "";
442  }
443  }
444  if ($componentType == ComponentType::MAVEN) {
445  $componentType = "maven-central";
446  } elseif ($componentType == ComponentType::PACKAGEURL) {
447  $componentType = "purl";
448  } else {
449  if (!empty($componentType)) {
450  $componentType = ComponentType::TYPE_MAP[$componentType];
451  } else {
453  }
454  }
455  $obligations = $this->getObligations($uploadId, $this->groupId);
456 
457  return $this->renderString($this->getTemplateFile('package'), [
458  'packageId' => $uploadId,
459  'uri' => $this->uri,
460  'packageName' => $upload->getFilename(),
461  'packageVersion' => $componentVersion,
462  'releaseDate' => $releaseDate,
463  'generalAssessment' => $generalAssessment,
464  'uploadName' => $upload->getFilename(),
465  'componentType' => $componentType,
466  'componentId' => htmlspecialchars($componentId),
467  'sha1' => $hashes['sha1'],
468  'md5' => $hashes['md5'],
469  'sha256' => $hashes['sha256'],
470  'verificationCode' => $this->getVerificationCode($upload),
471  'mainLicenses' => $mainLicenses,
472  'mainLicenseString' => $mainLicenseString,
473  'licenseComments' => $licenseComment,
474  'fileNodes' => $fileNodes,
475  'obligations' => $obligations,
476  'licenseList' => $this->licensesInDocument
477  ]);
478  }
479 
484  protected function getLicenseComment($scannerIds)
485  {
487  $func = function($scannerId) use ($agentDao)
488  {
489  return $agentDao->getAgentName($scannerId)." (".$agentDao->getAgentRev($scannerId).")";
490  };
491  $scannerNames = array_map($func, $scannerIds);
492  return "licenseInfoInFile determined by Scanners:\n - ".implode("\n - ",$scannerNames);
493  }
494 
503  protected function toLicensesWithFilesAdder(&$filesWithLicenses, $licenses, $copyrights, $file, $fullPath)
504  {
505  if (!array_key_exists($licenses, $filesWithLicenses)) {
506  $filesWithLicenses[$licenses]['files']=array();
507  $filesWithLicenses[$licenses]['copyrights']=array();
508  }
509  if (empty($copyrights)) {
510  $copyrights = array();
511  }
512  $filesWithLicenses[$licenses]['files'][$file] = $fullPath;
513  foreach ($copyrights as $copyright) {
514  if (!in_array($copyright, $filesWithLicenses[$licenses]['copyrights'])) {
515  $filesWithLicenses[$licenses]['copyrights'][] = $copyright;
516  }
517  }
518  }
519 
526  protected function toLicensesWithFiles(&$filesWithLicenses, $treeTableName)
527  {
528  $licensesWithFiles = array();
529  $treeDao = $this->container->get('dao.tree');
530  $filesProceeded = 0;
531  foreach ($filesWithLicenses as $fileId => $fileNode) {
532  $filesProceeded += 1;
533  if (($filesProceeded&2047)==0) {
534  $this->heartbeat(0);
535  }
536  $fullPath = $treeDao->getFullPath($fileId, $treeTableName, 0);
537  if (! empty($fileNode->getConcludedLicenses())) {
538  $licenses = [];
539  foreach ($fileNode->getConcludedLicenses() as $license) {
540  $licenses[] = $this->licensesInDocument[$license]
541  ->getLicenseObj()->getSpdxId();
542  }
543  $licenses = SpdxUtils::implodeLicenses(
544  SpdxUtils::removeEmptyLicenses(array_unique($licenses)));
545  $this->toLicensesWithFilesAdder($licensesWithFiles,
546  $licenses, $fileNode->getCopyrights(), $fileId, $fullPath);
547  } else {
548  if (! empty($fileNode->getScanners())) {
549  $implodedLicenses = [];
550  foreach ($fileNode->getScanners() as $license) {
551  $implodedLicenses[] = $this->licensesInDocument[$license]
552  ->getLicenseObj()->getSpdxId();
553  }
554  $implodedLicenses = SpdxUtils::implodeLicenses(
555  SpdxUtils::removeEmptyLicenses(array_unique($implodedLicenses)));
556  if ($fileNode->isCleared()) {
557  $msgLicense = "None (scanners found: " . $implodedLicenses . ")";
558  } else {
559  $msgLicense = "NoLicenseConcluded (scanners found: " . $implodedLicenses . ")";
560  }
561  } else {
562  if ($fileNode->isCleared()) {
563  $msgLicense = "None";
564  } else {
565  $msgLicense = "NoLicenseConcluded";
566  }
567  }
568  $this->toLicensesWithFilesAdder($licensesWithFiles, $msgLicense,
569  $fileNode->getCopyrights(), $fileId, $fullPath);
570  }
571  }
572  return $licensesWithFiles;
573  }
574 
579  protected function computeUri($uploadId)
580  {
581  $upload = $this->uploadDao->getUpload($uploadId);
582  $packageName = $upload->getFilename();
583 
584  $this->uri = $this->getUri($packageName);
585  $this->filename = $this->getFileName($packageName);
586  }
587 
594  protected function writeReport(&$packageNodes, $packageIds, $uploadId)
595  {
596  global $SysConf;
597 
598  $fileBase = dirname($this->filename);
599 
600  if (!is_dir($fileBase)) {
601  mkdir($fileBase, 0777, true);
602  }
603  umask(0133);
604 
605  $organizationName = $SysConf['SYSCONFIG']["ReportHeaderText"] ?? 'FOSSology';
606  $version = $SysConf['BUILD']['VERSION'];
607 
608  $uploadTreeTableName = $this->uploadDao->getUploadtreeTableName($uploadId);
609  $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId,$uploadTreeTableName);
610  $this->heartbeat(0);
611 
612  $filesWithLicenses = $this->reportutils
613  ->getFilesWithLicensesFromClearings($itemTreeBounds, $this->groupId,
614  $this, $this->licensesInDocument);
615  $this->heartbeat(0);
616  $upload = $this->uploadDao->getUpload($uploadId);
617  $this->generateFileNodes($filesWithLicenses, $upload->getTreeTableName(), $uploadId);
618  $this->declaredLicenseFileIds = array_unique(array_diff($this->declaredLicenseFileIds, $this->concludedLicenseFileIds));
619  $this->concludedLicenseFileIds = array_unique($this->concludedLicenseFileIds);
620  $message = $this->renderString($this->getTemplateFile('document'),array(
621  'documentName' => $fileBase,
622  'uri' => $this->uri,
623  'userName' => $this->container->get('dao.user')->getUserName($this->userId) . " (" . $this->container->get('dao.user')->getUserEmail($this->userId) . ")",
624  'organisation' => $organizationName,
625  'concludedLicenseFileIds'=>$this->concludedLicenseFileIds,
626  'declaredLicenseFileIds'=>$this->declaredLicenseFileIds,
627  'toolVersion' => 'fossology-' . $version,
628  'packageNodes' => $packageNodes,
629  'packageIds' => $packageIds,
630  'dataLicense' => $this->getSPDXDataLicense(),
631  'licenseList' => $this->licensesInDocument
632  )
633  );
634 
635  // To ensure the file is valid, replace any non-printable characters with a question mark.
636  // 'Non-printable' is ASCII < 0x20 (excluding \r, \n and tab) and 0x7F (delete).
637  $message = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/','?',$message);
638 
639  file_put_contents($this->filename, $message);
640  $this->updateReportTable($uploadId, $this->jobId, $this->filename);
641  }
642 
649  protected function updateReportTable($uploadId, $jobId, $fileName)
650  {
651  $this->reportutils->updateOrInsertReportgenEntry($uploadId, $jobId, $fileName);
652  }
653 
660  protected function renderString($templateName, $vars)
661  {
662  return $this->renderer->load($templateName)->render($vars);
663  }
664 
672  protected function generateFileNodes($filesWithLicenses, $treeTableName, $uploadId)
673  {
674  $this->deduplicateLicenseList();
675  if (strcmp($this->outputFormat, "dep5") !== 0) {
676  return $this->generateFileNodesByFiles($filesWithLicenses, $treeTableName, $uploadId);
677  } else {
678  return $this->generateFileNodesByLicenses($filesWithLicenses, $treeTableName);
679  }
680  }
681 
689  protected function generateFileNodesByFiles($filesWithLicenses, $treeTableName, $uploadId)
690  {
691  /* @var $treeDao TreeDao */
692  $treeDao = $this->container->get('dao.tree');
693  $filesProceeded = 0;
694  $lastValue = 0;
695  $content = '';
696  $textToBePrinted = [];
697  foreach ($filesWithLicenses as $fileId => $fileData) {
698  $filesProceeded += 1;
699  if (($filesProceeded & 2047) == 0) {
700  $this->heartbeat($filesProceeded - $lastValue);
701  $lastValue = $filesProceeded;
702  }
703  $hashes = $treeDao->getItemHashes($fileId);
704  $fileName = $treeDao->getFullPath($fileId, $treeTableName, 0);
705  $stateComment = $this->getSPDXReportConf($uploadId, 0);
706  $stateWoInfos = $this->getSPDXReportConf($uploadId, 1);
707  foreach ($fileData->getConcludedLicenses() as $license) {
708  $this->concludedLicenseFileIds[] = $fileId;
709  if (! $this->licensesInDocument[$license]->isTextPrinted()) {
710  $textToBePrinted[] = $license;
711  }
712  }
713  foreach ($fileData->getScanners() as $license) {
714  $this->declaredLicenseFileIds[] = $fileId;
715  if (! $this->licensesInDocument[$license]->isTextPrinted()) {
716  $textToBePrinted[] = $license;
717  }
718  }
719  $concludedLicensesString = [];
720  if ($this->outputFormat == "spdx2tv" ||
721  $this->outputFormat == "spdx2csv" ||
722  $this->outputFormat == "spdx3tv") {
723  foreach ($fileData->getConcludedLicenses() as $license) {
724  $shortName = $this->licensesInDocument[$license]
725  ->getLicenseObj()->getShortName();
726  if (StringOperation::stringStartsWith($shortName,
727  LicenseRef::SPDXREF_PREFIX)) {
728  $concludedLicensesString[] = $shortName;
729  } else {
730  $concludedLicensesString[] = $this->licensesInDocument[$license]
731  ->getLicenseObj()->getSpdxId();
732  }
733  }
734  $concludedLicensesString = SpdxUtils::implodeLicenses(
735  SpdxUtils::removeEmptyLicenses($concludedLicensesString));
736  }
737  if (!$stateWoInfos ||
738  ($stateWoInfos && (!empty($fileData->getConcludedLicenses()) ||
739  !empty($fileData->getScanners()) || !empty($fileData->getCopyrights())))) {
740  $fileData->setAcknowledgements(
741  SpdxUtils::cleanTextArray($fileData->getAcknowledgements()));
742  $fileData->setComments(
743  SpdxUtils::cleanTextArray($fileData->getComments()));
744  $dataTemplate = array(
745  'fileId' => $fileId,
746  'sha1' => $hashes['sha1'],
747  'md5' => $hashes['md5'],
748  'sha256' => $hashes['sha256'],
749  'uri' => $this->uri,
750  'fileName' => $fileName,
751  'fileDirName' => dirname($fileName),
752  'fileBaseName' => basename($fileName),
753  'fileData' => $fileData,
754  'licenseList' => $this->licensesInDocument,
755  'concludedLicensesString' => $concludedLicensesString,
756  'licenseCommentState' => $stateComment
757  );
758  $content .= $this->renderString($this->getTemplateFile('file'),
759  $dataTemplate);
760  }
761  foreach ($textToBePrinted as $license) {
762  $this->licensesInDocument[$license]->setTextPrinted(true);
763  }
764  }
765  $this->heartbeat($filesProceeded - $lastValue);
766  return $content;
767  }
768 
775  protected function generateFileNodesByLicenses($filesWithLicenses, $treeTableName)
776  {
777  $licensesWithFiles = $this->toLicensesWithFiles($filesWithLicenses, $treeTableName);
778 
779  $content = '';
780  $filesProceeded = 0;
781  $lastStep = 0;
782  $lastValue = 0;
783  foreach ($licensesWithFiles as $licenseId=>$entry) {
784  $filesProceeded += count($entry['files']);
785  if ($filesProceeded&(~2047) > $lastStep) {
786  $this->heartbeat($filesProceeded - $lastValue);
787  $lastStep = $filesProceeded&(~2047) + 2048;
788  $lastValue = $filesProceeded;
789  }
790 
791  $comment = "";
792  if (strrpos($licenseId, "NoLicenseConcluded (scanners found: ", -strlen($licenseId)) !== false) {
793  $comment = substr($licenseId,20,strlen($licenseId)-21);
794  $licenseId = "NoLicenseConcluded";
795  } elseif (strrpos($licenseId, "None (scanners found: ", -strlen($licenseId)) !== false) {
796  $comment = substr($licenseId,6,strlen($licenseId)-7);
797  $licenseId = "None";
798  }
799 
800  $content .= $this->renderString($this->getTemplateFile('file'),array(
801  'fileNames'=>$entry['files'],
802  'license'=>$licenseId,
803  'copyrights'=>$entry['copyrights'],
804  'comment'=>$comment));
805  }
806  $this->heartbeat($filesProceeded - $lastValue);
807  return $content;
808  }
809 
818  protected function getVerificationCode(Upload $upload)
819  {
820  $stmt = __METHOD__;
821  $param = array();
822  if ($upload->getTreeTableName()=='uploadtree_a') {
823  $sql = $upload->getTreeTableName().' WHERE upload_fk=$1 AND';
824  $param[] = $upload->getId();
825  } else {
826  $sql = $upload->getTreeTableName().' WHERE';
827  $stmt .= '.'.$upload->getTreeTableName();
828  }
829 
830  $sql = "SELECT STRING_AGG(lower_sha1,'') concat_sha1 FROM
831  (SELECT LOWER(pfile_sha1) lower_sha1 FROM pfile, $sql pfile_fk=pfile_pk AND parent IS NOT NULL ORDER BY pfile_sha1) templist";
832  $filelistPack = $this->dbManager->getSingleRow($sql,$param,$stmt);
833 
834  return sha1($filelistPack['concat_sha1']);
835  }
836 
843  protected function getSPDXReportConf($uploadId, $key)
844  {
845  $sql = "SELECT ri_spdx_selection FROM report_info WHERE upload_fk = $1";
846  $getCommentState = $this->dbManager->getSingleRow($sql, array($uploadId), __METHOD__.'.SPDX_license_comment');
847  if (!empty($getCommentState['ri_spdx_selection'])) {
848  $getCommentStateSingle = explode(',', $getCommentState['ri_spdx_selection']);
849  if ($getCommentStateSingle[$key] === "checked") {
850  return true;
851  }
852  }
853  return false;
854  }
855 
862  private function getObligations(int $uploadId, int $groupId): array
863  {
864  $licenses = $this->licenseClearedGetter->getCleared($uploadId, $this,
865  $groupId, true, "license", false);
866  $this->heartbeat(0);
867  $licensesMain = $this->licenseMainGetter->getCleared($uploadId, $this,
868  $groupId, true, null, false);
869  $this->heartbeat(0);
870  list($obligations, $_) = $this->obligationsGetter->getObligations(
871  $licenses['statements'], $licensesMain['statements'], $uploadId,
872  $groupId);
873  if (empty($obligations)) {
874  return [];
875  } else {
876  return array_column($obligations, "text");
877  }
878  }
879 
884  protected function getSPDXDataLicense()
885  {
886  $dataLic = $this->licenseDao->getLicenseByShortName(self::DATA_LICENSE);
887  return $dataLic->getId() . "-" . md5($dataLic->getText());
888  }
889 
901  private function deduplicateLicenseList()
902  {
903  $localList = array_values($this->licensesInDocument);
904  usort($localList,
905  function(SpdxLicenseInfo $a, SpdxLicenseInfo $b) {
906  return strcmp(
907  $a->getLicenseObj()->getSpdxId() . $a->getLicenseObj()->getShortName(),
908  $b->getLicenseObj()->getSpdxId() . $b->getLicenseObj()->getShortName());
909  }
910  );
911  for ($i = 0; $i < count($localList) - 1; $i++) {
912  if ((! $localList[$i]->isCustomText() && ! $localList[$i + 1]->isCustomText()) &&
913  $localList[$i]->getLicenseObj()->getSpdxId() ===
914  $localList[$i + 1]->getLicenseObj()->getSpdxId()) {
915  $newShortName = $localList[$i + 1]->getLicenseObj()->getShortName();
917  $localList[$i + 1]->getLicenseObj()->getShortName(),
918  LicenseRef::SPDXREF_PREFIX)) {
919  $newShortName = LicenseRef::SPDXREF_PREFIX .
920  $localList[$i + 1]->getLicenseObj()->getShortName();
921  $newShortName = preg_replace('/\+$/', '-or-later', $newShortName);
922  }
923  $md5 = md5($localList[$i + 1]->getLicenseObj()->getText());
924  $reportedLicenseShortname = "$newShortName-$md5";
925  $licIndex = $localList[$i + 1]->getLicenseObj()->getId() . "-$md5";
926  $oldLicObj = $this->licensesInDocument[$licIndex]->getLicenseObj();
927  $this->licensesInDocument[$licIndex]->setLicenseObj(
928  new License($oldLicObj->getId(), $reportedLicenseShortname,
929  $oldLicObj->getFullName(), $oldLicObj->getRisk(),
930  $oldLicObj->getText(), $oldLicObj->getUrl(),
931  $oldLicObj->getDetectorType(), $oldLicObj->getSpdxId()));
932  }
933  }
934  }
935 }
936 
937 $agent = new SpdxAgent();
938 $agent->scheduler_connect();
939 $agent->run_scheduler_event_loop();
940 $agent->scheduler_disconnect(0);
Structure of an Agent with all required parameters.
Definition: Agent.php:41
heartbeat($newProcessed)
Send hear beat to the scheduler.
Definition: Agent.php:203
Wrapper class for license map.
Definition: LicenseMap.php:19
static stringStartsWith($haystack, $needle)
SPDX2 agent.
Definition: spdx.php:76
const DEFAULT_OUTPUT_FORMAT
Default output format.
Definition: spdx.php:79
getLicenseComment($scannerIds)
Definition: spdx.php:484
getFileName($packageName)
Get absolute path for report.
Definition: spdx.php:327
getVerificationCode(Upload $upload)
Get a unique identifier for a given upload.
Definition: spdx.php:818
getTemplateFile($partname)
Get TWIG template file based on output format.
Definition: spdx.php:253
const UPLOAD_ADDS
Argument for additional uploads.
Definition: spdx.php:81
getObligations(int $uploadId, int $groupId)
Definition: spdx.php:862
processUploadId($uploadId)
Given an upload ID, process the items in it.
Definition: spdx.php:215
const DATA_LICENSE
Data license for SPDX reports.
Definition: spdx.php:82
updateReportTable($uploadId, $jobId, $fileName)
Update the reportgen table with new report path.
Definition: spdx.php:649
preWorkOnArgs($args)
Parse arguments.
Definition: spdx.php:197
renderString($templateName, $vars)
Render a twig template.
Definition: spdx.php:660
const AVAILABLE_OUTPUT_FORMATS
Output formats available.
Definition: spdx.php:80
renderPackage($uploadId)
Given an upload id, render the report string.
Definition: spdx.php:355
getFileBasename($packageName)
Generate report basename based on upload name.
Definition: spdx.php:287
generateFileNodesByLicenses($filesWithLicenses, $treeTableName)
For each file, generate the nodes by licenses.
Definition: spdx.php:775
toLicensesWithFiles(&$filesWithLicenses, $treeTableName)
Map findings to the files.
Definition: spdx.php:526
generateFileNodes($filesWithLicenses, $treeTableName, $uploadId)
Generate report nodes for files.
Definition: spdx.php:672
getSPDXReportConf($uploadId, $key)
Get spdx license comment state for a given upload.
Definition: spdx.php:843
toLicensesWithFilesAdder(&$filesWithLicenses, $licenses, $copyrights, $file, $fullPath)
Map licenses, copyrights, files and full path to filesWithLicenses array.
Definition: spdx.php:503
generateFileNodesByFiles($filesWithLicenses, $treeTableName, $uploadId)
For each file, generate the nodes by files.
Definition: spdx.php:689
writeReport(&$packageNodes, $packageIds, $uploadId)
Write the report the file and update report table.
Definition: spdx.php:594
computeUri($uploadId)
For a given upload, compute the URI and filename for the report.
Definition: spdx.php:579
const OUTPUT_FORMAT_KEY
Argument key for output format.
Definition: spdx.php:78
getUri($packageName)
Get the URI for the given package.
Definition: spdx.php:339
deduplicateLicenseList()
De-duplicate license list by comparing licenses with the same SPDX ID.
Definition: spdx.php:901
static preWorkOnArgsFlp($args, $key1, $key2)
For a given set of arguments assign $args[$key1] and $args[$key2].
Definition: spdxutils.php:28
static implodeLicenses($licenses)
Implode licenses with "AND" or "OR".
Definition: spdxutils.php:96
static removeEmptyLicenses($licenses)
Definition: spdxutils.php:147
static cleanTextArray($texts)
Definition: spdxutils.php:123
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690
int jobId
The id of the job.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
FUNCTION char * strtoupper(char *s)
Helper function to upper case a string.
Definition: utils.c:39
Namespace used by SPDX2 agent.
list_t type structure used to keep various lists. (e.g. there are multiple lists).
Definition: nomos.h:308