FOSSology  4.6.0
Open Source License Compliance by Open Source Software
UploadDao.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2018 Siemens AG
4  Authors: Andreas Würl, Steffen Weber
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 namespace Fossology\Lib\Dao;
10 
21 use Monolog\Logger;
22 use DateTime;
23 
24 require_once(dirname(dirname(__FILE__)) . "/common-dir.php");
25 
26 class UploadDao
27 {
28 
29  const REUSE_NONE = 0;
30  const REUSE_ENHANCED = 2;
31  const REUSE_MAIN = 4;
32  const REUSE_CONF = 16;
33  const REUSE_COPYRIGHT = 128;
34  const UNIFIED_REPORT_HEADINGS = array(
35  "assessment" => array("Assessment Summary" => true),
36  "compliancetasks" => array("Required license compliance tasks" => true),
37  "acknowledgements" => array("Acknowledgements" => true),
38  "exportrestrictions" => array("Export Restrictions" => true),
39  "intellectualProperty" => array("Patent Relevant Statements" => true),
40  "notes" => array("Notes" => true),
41  "scanresults" => array("Results of License Scan" => true),
42  "mainlicenses" => array("Main Licenses" => true),
43  "redlicense" => array("Other OSS Licenses (red) - Do not Use Licenses" => true),
44  "yellowlicense" => array("Other OSS Licenses (yellow) - additional obligations to common rules (e.g. copyleft)" => true),
45  "whitelicense" => array("Other OSS Licenses (white) - only common rules" => true),
46  "overviewwithwithoutobligations" => array("Overview of All Licenses with or without Obligations" => true),
47  "copyrights" => array("Copyrights" => true),
48  "copyrightsuf" => array("Copyrights (User Findings)" => true),
49  "bulkfindings" => array("Bulk Findings" => true),
50  "licensenf" => array("Non-Functional Licenses" => true),
51  "irrelevantfiles" => array("Irrelevant Files" => true),
52  "dnufiles" => array("Do not use Files" => true),
53  "changelog" => array("Clearing Protocol Change Log" => true)
54  );
55  const CLIXML_REPORT_HEADINGS = array(
56  "mainlicensesclixml" => array("Main Licenses" => true),
57  "licensepath" => array("License File Path" => true),
58  "licensehash" => array("License File Hash" => true),
59  "copyrightsclixml" => array("Copyrights" => true),
60  "copyrightpath" => array("Copyright File Path" => true),
61  "copyrighthash" => array("Copyright File Hash" => true),
62  "exportrestrictionsclixml" => array("Export Restrictions(ECC)" => true),
63  "eccpath" => array("ECC File Path" => true),
64  "ecchash" => array("ECC File Hash" => true),
65  "intellectualPropertyclixml" => array("Identified Patent Relevant Analysis(IPRA)" => true),
66  "iprapath" => array("IPRA File Path" => true),
67  "iprahash" => array("IPRA File Hash" => true),
68  "allobligations" => array("All Obligations" => true),
69  "acknowledgementsclixml" => array("Acknowledgements" => true),
70  "irrelevantfilesclixml" => array("Irrelevant Files" => true),
71  "dnufilesclixml" => array("Do not use Files" => true),
72  "notesclixml" => array("Additional Notes" => true)
73  );
75  private $dbManager;
77  private $logger;
79  private $permissionDao;
80 
81  public function __construct(DbManager $dbManager, Logger $logger, UploadPermissionDao $uploadPermissionDao)
82  {
83  $this->dbManager = $dbManager;
84  $this->logger = $logger;
85  $this->permissionDao = $uploadPermissionDao;
86  }
87 
88 
94  public function getUploadEntry($uploadTreeId, $uploadTreeTableName = "uploadtree")
95  {
96  $stmt = __METHOD__ . ".$uploadTreeTableName";
97  $uploadEntry = $this->dbManager->getSingleRow("SELECT * FROM $uploadTreeTableName WHERE uploadtree_pk = $1",
98  array($uploadTreeId), $stmt);
99  if ($uploadEntry) {
100  $uploadEntry['tablename'] = $uploadTreeTableName;
101  }
102  return $uploadEntry;
103  }
104 
111  public function getUploadtreeIdFromPfile($uploadFk, $pfileFk)
112  {
113  $uploadTreeTableName = $this->getUploadtreeTableName($uploadFk);
114  $stmt = __METHOD__ . ".$uploadTreeTableName";
115  $uploadEntry = $this->dbManager->getSingleRow("SELECT uploadtree_pk " .
116  "FROM $uploadTreeTableName " .
117  "WHERE upload_fk = $1 AND pfile_fk = $2",
118  array($uploadFk, $pfileFk), $stmt);
119  return intval($uploadEntry['uploadtree_pk']);
120  }
121 
126  public function getUpload($uploadId)
127  {
128  $stmt = __METHOD__;
129  $row = $this->dbManager->getSingleRow("SELECT * FROM upload WHERE upload_pk = $1",
130  array($uploadId), $stmt);
131 
132  return $row ? Upload::createFromTable($row) : null;
133  }
134 
135  public function getActiveUploadsArray()
136  {
137  $stmt = __METHOD__;
138  $queryResult = $this->dbManager->getRows("SELECT * FROM upload where pfile_fk IS NOT NULL",
139  array(), $stmt);
140 
141  $results = array();
142  foreach ($queryResult as $row) {
143  $results[] = Upload::createFromTable($row);
144  }
145 
146  return $results;
147  }
148 
154  public function getAccessibleUploads($groupId)
155  {
156  $stmt = __METHOD__;
157  $permNone = Auth::PERM_NONE;
158  $sql = "SELECT u.* FROM upload u
159  LEFT JOIN perm_upload p ON p.upload_fk = u.upload_pk AND p.group_fk = $1
160  WHERE u.pfile_fk IS NOT NULL
161  AND (p.perm > $permNone OR u.public_perm > $permNone)";
162 
163  $queryResult = $this->dbManager->getRows($sql, array($groupId), $stmt);
164 
165  $results = array();
166  foreach ($queryResult as $row) {
167  $results[] = Upload::createFromTable($row);
168  }
169 
170  return $results;
171  }
172 
178  public function getItemTreeBounds($itemId, $uploadTreeTableName = "uploadtree")
179  {
180  $uploadEntryData = $this->getUploadEntry($itemId, $uploadTreeTableName);
181  return $this->createItemTreeBounds($uploadEntryData, $uploadTreeTableName);
182  }
183 
189  public function getItemTreeBoundsFromUploadId($uploadTreeId, $uploadId)
190  {
191  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
192  return $this->getItemTreeBounds($uploadTreeId, $uploadTreeTableName);
193  }
194 
201  public function getParentItemBounds($uploadId, $uploadTreeTableName = null)
202  {
203  if ($uploadTreeTableName === null) {
204  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
205  }
206 
207  $stmt = __METHOD__ . ".$uploadTreeTableName";
208  $parameters = array();
209  $uploadCondition = $this->handleUploadIdForTable($uploadTreeTableName, $uploadId, $parameters);
210 
211  $uploadEntryData = $this->dbManager->getSingleRow("SELECT * FROM $uploadTreeTableName
212  WHERE parent IS NULL
213  $uploadCondition
214  ",
215  $parameters, $stmt);
216 
217  return $uploadEntryData ? $this->createItemTreeBounds($uploadEntryData, $uploadTreeTableName) : false;
218  }
219 
224  public function countPlainFiles(ItemTreeBounds $itemTreeBounds)
225  {
226  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
227 
228  $stmt = __METHOD__ . ".$uploadTreeTableName";
229  $parameters = array($itemTreeBounds->getLeft(), $itemTreeBounds->getRight());
230  $uploadCondition = $this->handleUploadIdForTable($uploadTreeTableName, $itemTreeBounds->getUploadId(), $parameters);
231 
232  $row = $this->dbManager->getSingleRow("SELECT count(*) as count FROM $uploadTreeTableName
233  WHERE lft BETWEEN $1 AND $2
234  $uploadCondition
235  AND ((ufile_mode & (3<<28))=0)
236  AND pfile_fk != 0",
237  $parameters, $stmt);
238  return intval($row["count"]);
239  }
240 
241  private function handleUploadIdForTable($uploadTreeTableName, $uploadId, &$parameters)
242  {
243  if ($uploadTreeTableName === "uploadtree" || $uploadTreeTableName === "uploadtree_a") {
244  $parameters[] = $uploadId;
245  return " AND upload_fk = $" . count($parameters) . " ";
246  } else {
247  return "";
248  }
249  }
250 
254  public function getStatusTypeMap()
255  {
256  global $container;
258  $uploadStatus = $container->get('upload_status.types');
259  return $uploadStatus->getMap();
260  }
261 
269  public function getStatus($uploadId, $groupId)
270  {
271  if ($this->isAccessible($uploadId, $groupId)) {
272  $row = $this->dbManager->getSingleRow("SELECT status_fk " .
273  "FROM upload_clearing WHERE upload_fk=$1 AND group_fk=$2;",
274  array($uploadId, $groupId));
275  if (false === $row) {
276  return 1;
277  }
278  return $row['status_fk'];
279  } else {
280  throw new \Exception("permission denied");
281  }
282  }
283 
284 
292  public function getAssignee($uploadId, $groupId)
293  {
294  if ($this->isAccessible($uploadId, $groupId)) {
295  $row = $this->dbManager->getSingleRow("SELECT assignee FROM upload_clearing WHERE upload_fk=$1 AND group_fk=$2;",
296  array($uploadId, $groupId));
297  if (false === $row) {
298  return 1;
299  }
300  return $row['assignee'];
301  } else {
302  throw new \Exception("permission denied");
303  }
304  }
305 
313  public function getAssigneeDate(int $uploadId): ?string
314  {
315  $sql = "SELECT event_ts FROM upload_events WHERE upload_fk = $1 " .
316  "AND event_type = " . UploadEvents::ASSIGNEE_EVENT;
317  $row = $this->dbManager->getSingleRow($sql, [$uploadId], __METHOD__);
318  if (empty($row) || empty($row["event_ts"])) {
319  return null;
320  }
321  return $row["event_ts"];
322  }
323 
330  public function getClosedDate(int $uploadId): ?string
331  {
332  $sql = "SELECT event_ts FROM upload_events WHERE upload_fk = $1 " .
333  "AND event_type = " . UploadEvents::UPLOAD_CLOSED_EVENT;
334  $row = $this->dbManager->getSingleRow($sql, [$uploadId], __METHOD__);
335  if (empty($row) || empty($row["event_ts"])) {
336  return null;
337  }
338  return $row["event_ts"];
339  }
340 
347  public function getClearingDuration(int $uploadId): ?array
348  {
349  $duration = "NA";
350  $assignDate = $this->getAssigneeDate($uploadId);
351  $closingDate = $this->getClosedDate($uploadId);
352  $durationSort = 0;
353  if ($assignDate != null && $closingDate != null) {
354  try {
355  $closingDate = new DateTime($closingDate);
356  $assignDate = new DateTime($assignDate);
357  if ($assignDate < $closingDate) {
358  $duration = HumanDuration($closingDate->diff($assignDate));
359  $durationSort = $closingDate->getTimestamp() - $assignDate->getTimestamp();
360  }
361  } catch (Exception $_) {
362  }
363  }
364  return array($duration, $durationSort);
365  }
374  public function getUploadtreeTableName($uploadId)
375  {
376  if (!empty($uploadId)) {
377  $statementName = __METHOD__;
378  $row = $this->dbManager->getSingleRow(
379  "SELECT uploadtree_tablename FROM upload WHERE upload_pk=$1",
380  array($uploadId),
381  $statementName
382  );
383  if (!empty($row['uploadtree_tablename'])) {
384  return $row['uploadtree_tablename'];
385  }
386  }
387  return "uploadtree";
388  }
389 
395  public function getNextItem($uploadId, $itemId, $options = null)
396  {
397  return $this->getItemByDirection($uploadId, $itemId, self::DIR_FWD, $options);
398  }
399 
406  public function getPreviousItem($uploadId, $itemId, $options = null)
407  {
408  return $this->getItemByDirection($uploadId, $itemId, self::DIR_BCK, $options);
409  }
410 
411  const DIR_FWD = 1;
412  const DIR_BCK = -1;
413  const NOT_FOUND = null;
414 
415 
423  public function getItemByDirection($uploadId, $itemId, $direction, $options)
424  {
425  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
426  $originItem = $this->getUploadEntry($itemId, $uploadTreeTableName);
427  $originLft = $originItem['lft'];
428 
429  $options[UploadTreeProxy::OPT_ITEM_FILTER] = " AND ut.ufile_mode & (3<<28) = 0";
430  $uploadTreeViewName = 'items2care';
431 
432  if ($direction == self::DIR_FWD) {
433  $uploadTreeViewName .= 'fwd';
434  $options[UploadTreeProxy::OPT_ITEM_FILTER] .= " AND lft>$1";
435  $order = 'ASC';
436  } else {
437  $uploadTreeViewName .= 'bwd';
438  $options[UploadTreeProxy::OPT_ITEM_FILTER] .= " AND lft<$1";
439  $order = 'DESC';
440  }
441 
442  $uploadTreeView = new UploadTreeProxy($uploadId, $options, $uploadTreeTableName, $uploadTreeViewName);
443  $statementName = __METHOD__ . ".$uploadTreeViewName.";
444  $query = $uploadTreeView->getDbViewQuery()." ORDER BY lft $order";
445 
446  $newItemRow = $this->dbManager->getSingleRow("$query LIMIT 1", array($originLft), $statementName);
447  if ($newItemRow) {
448  return $this->createItem($newItemRow, $uploadTreeTableName);
449  } else {
450  return self::NOT_FOUND;
451  }
452  }
453 
454 
459  public function getUploadParent($uploadId)
460  {
461  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
462  $statementname = __METHOD__ . $uploadTreeTableName;
463 
464  $parent = $this->dbManager->getSingleRow(
465  "SELECT uploadtree_pk
466  FROM $uploadTreeTableName
467  WHERE upload_fk=$1 AND parent IS NULL", array($uploadId), $statementname);
468  if (false === $parent) {
469  throw new \Exception("Missing upload tree parent for upload");
470  }
471  return $parent['uploadtree_pk'];
472  }
473 
474  public function getLeftAndRight($uploadtreeID, $uploadTreeTableName = "uploadtree")
475  {
476  $statementName = __METHOD__ . $uploadTreeTableName;
477  $leftRight = $this->dbManager->getSingleRow(
478  "SELECT lft,rgt FROM $uploadTreeTableName WHERE uploadtree_pk = $1",
479  array($uploadtreeID), $statementName
480  );
481 
482  return array($leftRight['lft'], $leftRight['rgt']);
483  }
484 
490  public function getContainingFileCount(ItemTreeBounds $itemTreeBounds, UploadTreeProxy $uploadTreeView)
491  {
492  $sql = "SELECT count(*) FROM " . $uploadTreeView->getDbViewName() . " WHERE lft BETWEEN $1 AND $2";
493  $result = $this->dbManager->getSingleRow($sql
494  , array($itemTreeBounds->getLeft(), $itemTreeBounds->getRight()), __METHOD__ . $uploadTreeView->asCTE());
495  return $result['count'];
496  }
497 
504  public function getContainedItems(ItemTreeBounds $itemTreeBounds, $addCondition = "", $addParameters = array())
505  {
506  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
507 
508  $statementName = __METHOD__ . ".$uploadTreeTableName";
509 
510  $view = new UploadTreeViewProxy($itemTreeBounds, array(UploadTreeViewProxy::CONDITION_PLAIN_FILES));
511 
512  $this->dbManager->prepare($statementName,
513  $view->asCTE() . " SELECT * FROM " . $view->getDbViewName() ." ut ".
514  ($addCondition ? " WHERE " . $addCondition : ''));
515  $res = $this->dbManager->execute($statementName, $addParameters);
516  $items = array();
517 
518  while ($row = $this->dbManager->fetchArray($res)) {
519  $items[] = $this->createItem($row, $uploadTreeTableName);
520  }
521  $this->dbManager->freeResult($res);
522  return $items;
523  }
524 
532  public function addReusedUpload($uploadId, $reusedUploadId, $groupId, $reusedGroupId, $reuseMode=0)
533  {
534  $this->dbManager->insertTableRow('upload_reuse',
535  array('upload_fk'=>$uploadId, 'group_fk'=> $groupId, 'reused_upload_fk'=>$reusedUploadId, 'reused_group_fk'=>$reusedGroupId,'reuse_mode'=>$reuseMode));
536  }
537 
544  public function getReusedUpload($uploadId, $groupId)
545  {
546  $statementName = __METHOD__;
547 
548  $this->dbManager->prepare($statementName,
549  "SELECT reused_upload_fk, reused_group_fk, reuse_mode FROM upload_reuse WHERE upload_fk = $1 AND group_fk=$2 ORDER BY date_added DESC");
550  $res = $this->dbManager->execute($statementName, array($uploadId, $groupId));
551  $reusedPairs = $this->dbManager->fetchAll($res);
552  $this->dbManager->freeResult($res);
553  return $reusedPairs;
554  }
555 
561  protected function createItem($uploadEntry, $uploadTreeTableName)
562  {
563  $itemTreeBounds = new ItemTreeBounds(
564  intval($uploadEntry['uploadtree_pk']),
565  $uploadTreeTableName,
566  intval($uploadEntry['upload_fk']),
567  intval($uploadEntry['lft']), intval($uploadEntry['rgt']));
568 
569  $parent = $uploadEntry['parent'];
570  return new Item(
571  $itemTreeBounds, $parent !== null ? intval($parent) : null, intval($uploadEntry['pfile_fk']), intval($uploadEntry['ufile_mode']), $uploadEntry['ufile_name']
572  );
573  }
574 
581  protected function createItemTreeBounds($uploadEntryData, $uploadTreeTableName)
582  {
583  if ($uploadEntryData === false) {
584  throw new Exception("did not find uploadTreeId in $uploadTreeTableName");
585  }
586  return new ItemTreeBounds(intval($uploadEntryData['uploadtree_pk']), $uploadTreeTableName, intval($uploadEntryData['upload_fk']), intval($uploadEntryData['lft']), intval($uploadEntryData['rgt']));
587  }
588 
594  public function countNonArtifactDescendants(ItemTreeBounds $itemTreeBounds, $isFlat=true)
595  {
596  $stmt=__METHOD__;
597  $sql = "SELECT count(*) FROM ".$itemTreeBounds->getUploadTreeTableName()." ut "
598  . "WHERE ut.upload_fk=$1";
599  $params = array($itemTreeBounds->getUploadId());
600  if (!$isFlat) {
601  $stmt = __METHOD__.'.parent';
602  $params[] = $itemTreeBounds->getItemId();
603  $sql .= " AND ut.ufile_mode & (1<<28) = 0 AND ut.realparent = $2";
604  } else {
605  $params[] = $itemTreeBounds->getLeft();
606  $params[] = $itemTreeBounds->getRight();
607  $sql .= " AND ut.ufile_mode & (3<<28) = 0 AND (ut.lft BETWEEN $2 AND $3)";
608  }
609 
610  $descendants = $this->dbManager->getSingleRow($sql,$params);
611  return $descendants['count'];
612  }
613 
614 
615  public function isAccessible($uploadId, $groupId)
616  {
617  return $this->permissionDao->isAccessible($uploadId, $groupId);
618  }
619 
620  public function isEditable($uploadId, $groupId)
621  {
622  return $this->permissionDao->isEditable($uploadId, $groupId);
623  }
624 
625  public function makeAccessibleToGroup($uploadId, $groupId, $perm=null)
626  {
627  $this->permissionDao->makeAccessibleToGroup($uploadId, $groupId, $perm);
628  }
629 
630  public function makeAccessibleToAllGroupsOf($uploadId, $userId, $perm=null)
631  {
632  $this->permissionDao->makeAccessibleToAllGroupsOf($uploadId, $userId, $perm);
633  }
634 
635  public function filterAccessibleUploads(array $uploadIds, $groupId)
636  {
637  return $this->permissionDao->filterAccessibleUploads($uploadIds, $groupId);
638  }
639 
644  public function getUploadHashes($uploadId)
645  {
646  $pfile = $this->dbManager->getSingleRow('SELECT pfile.* FROM upload, pfile WHERE upload_pk=$1 AND pfile_fk=pfile_pk',
647  array($uploadId), __METHOD__);
648  return array('sha1'=>$pfile['pfile_sha1'],'md5'=>$pfile['pfile_md5'],'sha256'=>$pfile['pfile_sha256']);
649  }
650 
657  public function getFatItemArray($itemId,$uploadId,$uploadtreeTablename)
658  {
659  $sqlChildrenOf = "SELECT COUNT(*) FROM $uploadtreeTablename s
660  WHERE ufile_mode&(1<<28)=0 and s.upload_fk=$2 AND s.realparent=";
661  $sql="WITH RECURSIVE item_path (item_id,num_children,depth,ufile_mode,ufile_name) AS (
662  SELECT uploadtree_pk item_id, ($sqlChildrenOf $1) num_children, 0 depth, ufile_mode, ufile_name
663  FROM $uploadtreeTablename WHERE upload_fk=$2 AND uploadtree_pk=$1
664  UNION
665  SELECT uploadtree_pk item_id, ($sqlChildrenOf ut.uploadtree_pk) num_children,
666  item_path.depth+1 depth, ut.ufile_mode, item_path.ufile_name||'/'||ut.ufile_name ufile_name
667  FROM $uploadtreeTablename ut INNER JOIN item_path ON item_id=ut.realparent
668  WHERE upload_fk=$2 AND ut.ufile_mode&(1<<28)=0 AND num_children<2
669  )
670  SELECT * FROM item_path WHERE num_children!=1 OR ufile_mode&(1<<29)=0 ORDER BY depth DESC LIMIT 1";
671  return $this->dbManager->getSingleRow($sql,array($itemId, $uploadId),__METHOD__.$uploadtreeTablename);
672  }
673 
680  public function getFatItemId($itemId,$uploadId,$uploadtreeTablename)
681  {
682  $itemRow = $this->getFatItemArray($itemId,$uploadId,$uploadtreeTablename);
683  return $itemRow['item_id'];
684  }
685 
690  public function getPFileDataPerFileName(ItemTreeBounds $itemTreeBounds)
691  {
692  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
693  $statementName = __METHOD__ . '.' . $uploadTreeTableName;
694  $param = array();
695 
696  $param[] = $itemTreeBounds->getLeft();
697  $param[] = $itemTreeBounds->getRight();
698  $condition = " lft BETWEEN $1 AND $2";
699  $condition .= " AND (ufile_mode & (1<<28)) = 0";
700 
701  if ('uploadtree_a' == $uploadTreeTableName) {
702  $param[] = $itemTreeBounds->getUploadId();
703  $condition .= " AND upload_fk=$".count($param);
704  }
705 
706  $sql = "
707 SELECT ufile_name, uploadtree_pk, lft, rgt, ufile_mode,
708  pfile_pk, pfile_md5, pfile_sha1, pfile_sha256
709 FROM $uploadTreeTableName
710  LEFT JOIN pfile
711  ON pfile_fk = pfile_pk
712 WHERE $condition
713 ORDER BY lft asc
714 ";
715 
716  $this->dbManager->prepare($statementName, $sql);
717  $result = $this->dbManager->execute($statementName, $param);
718  $pfilePerFileName = array();
719 
720  $row = $this->dbManager->fetchArray($result);
721  $pathStack = array($row['ufile_name']);
722  $rgtStack = array($row['rgt']);
723  $lastLft = $row['lft'];
724  $this->addToPFilePerFileName($pfilePerFileName, $pathStack, $row);
725  while ($row = $this->dbManager->fetchArray($result)) {
726  if ($row['lft'] < $lastLft) {
727  continue;
728  }
729 
730  $this->updateStackState($pathStack, $rgtStack, $lastLft, $row);
731  $this->addToPFilePerFileName($pfilePerFileName, $pathStack, $row);
732  }
733  $this->dbManager->freeResult($result);
734  return $pfilePerFileName;
735  }
736 
737  private function updateStackState(&$pathStack, &$rgtStack, &$lastLft, $row)
738  {
739  if ($row['lft'] >= $lastLft) {
740  while (count($rgtStack) > 0 && $row['lft'] > $rgtStack[count($rgtStack)-1]) {
741  array_pop($pathStack);
742  array_pop($rgtStack);
743  }
744  if ($row['lft'] > $lastLft) {
745  $pathStack[] = $row['ufile_name'];
746  $rgtStack[] = $row['rgt'];
747  $lastLft = $row['lft'];
748  }
749  }
750  }
751 
752  private function addToPFilePerFileName(&$pfilePerFileName, $pathStack, $row)
753  {
754  if (($row['ufile_mode'] & (1 << 29)) == 0) {
755  $path = implode('/', $pathStack);
756  $pfilePerFileName[$path]['pfile_pk'] = $row['pfile_pk'];
757  $pfilePerFileName[$path]['uploadtree_pk'] = $row['uploadtree_pk'];
758  $pfilePerFileName[$path]['md5'] = $row['pfile_md5'];
759  $pfilePerFileName[$path]['sha1'] = $row['pfile_sha1'];
760  $pfilePerFileName[$path]['sha256'] = $row['pfile_sha256'];
761  }
762  }
763 
769  public function getPFilesDataPerHashAlgo(ItemTreeBounds $itemTreeBounds, $hashAlgo="sha1")
770  {
771  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
772  $statementName = __METHOD__ . '.' . $uploadTreeTableName;
773  $param = array();
774 
775  $param[] = $itemTreeBounds->getLeft();
776  $param[] = $itemTreeBounds->getRight();
777  $condition = " lft BETWEEN $1 AND $2";
778  $condition .= " AND (ufile_mode & (1<<28)) = 0";
779 
780  if ('uploadtree_a' == $uploadTreeTableName) {
781  $param[] = $itemTreeBounds->getUploadId();
782  $condition .= " AND upload_fk=$".count($param);
783  }
784  $condition .= " AND pfile_$hashAlgo IS NOT NULL";
785 
786  $sql = "
787 SELECT pfile_fk, uploadtree_pk, ufile_mode, pfile_$hashAlgo as hash
788 FROM $uploadTreeTableName
789  LEFT JOIN pfile
790  ON pfile_fk = pfile_pk
791 WHERE $condition
792 ORDER BY lft asc
793 ";
794 
795  $this->dbManager->prepare($statementName, $sql);
796  $result = $this->dbManager->execute($statementName, $param);
797 
798  $pfilePerHashAlgo = array();
799  while ($row = $this->dbManager->fetchArray($result)) {
800  if (($row['ufile_mode']&(1<<29)) == 0) {
801  $pfilePerHashAlgo[strtolower($row['hash'])][] = array('pfile_pk' => $row['pfile_fk'],
802  'uploadtree_pk' => $row['uploadtree_pk']);
803  }
804  }
805  $this->dbManager->freeResult($result);
806  return $pfilePerHashAlgo;
807  }
808 
809 
810  /* @param int $uploadId
811  * @return array
812  */
813  public function getReportInfo($uploadId)
814  {
815  $stmt = __METHOD__;
816  $sql = "SELECT * FROM report_info WHERE upload_fk = $1";
817  $row = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
818 
819  if (empty($row)) {
820  $this->dbManager->begin();
821  $stmt = __METHOD__.'ifempty';
822  $sql = "INSERT INTO report_info (upload_fk) VALUES ($1) RETURNING *";
823  $row = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
824  $this->dbManager->commit();
825  }
826  return $row;
827  }
828 
834  private function getUserSPDXDefaultsForUpload($uploadId)
835  {
836  $stmt = __METHOD__ . '.getOwner';
837  $sql = "SELECT user_fk FROM upload WHERE upload_pk = $1";
838  $uploadOwner = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
839 
840  if (empty($uploadOwner)) {
841  return "unchecked,unchecked,unchecked";
842  }
843 
844  $userId = $uploadOwner['user_fk'];
845 
846  $stmt = __METHOD__ . '.getUserDefaults';
847  $sql = "SELECT spdx_settings FROM users WHERE user_pk = $1";
848  $userDefaults = $this->dbManager->getSingleRow($sql, array($userId), $stmt);
849 
850  if (empty($userDefaults) || empty($userDefaults['spdx_settings'])) {
851  return "unchecked,unchecked,unchecked";
852  }
853 
854  $settings = explode(',', $userDefaults['spdx_settings']);
855  if (count($settings) < 3) {
856  $settings = array_pad($settings, 3, 'unchecked');
857  }
858 
859  $osselotExport = $settings[0];
860  $spdxLicenseComment = $settings[1];
861  $ignoreFilesWOInfo = $settings[2];
862 
863  $result = "$spdxLicenseComment,$ignoreFilesWOInfo,$osselotExport";
864 
865  return $result;
866  }
867 
875  public function updateReportInfo($uploadId, $column, $value)
876  {
877  if ($column === "ri_unifiedcolumns") {
878  $value = json_decode($value, true);
879  $oldValues = $this->getReportInfo($uploadId)["ri_unifiedcolumns"];
880  if (!empty($oldValues)) {
881  $oldValues = json_decode($oldValues, true);
882  } else {
883  $oldValues = self::UNIFIED_REPORT_HEADINGS;
884  }
885  foreach ($value as $key => $val) {
886  $newValText = array_keys($val)[0];
887  $newValValue = array_values($val)[0];
888  $newValValue = ($newValValue === true || $newValValue == "true") ? "on" : null;
889  $oldValues[$key] = [$newValText => $newValValue];
890  }
891  $value = json_encode($oldValues);
892  } elseif ($column === "ri_excluded_obligations") {
893  $value = json_decode($value, true);
894  $oldValues = $this->getReportInfo($uploadId)["ri_excluded_obligations"];
895  if (!empty($oldValues)) {
896  $oldValues = json_decode($oldValues, true);
897  } else {
898  $oldValues = [];
899  }
900  foreach ($value as $key => $newValue) {
901  $oldValues[$key] = $newValue;
902  }
903  $value = json_encode($oldValues);
904  } elseif ($column === "ri_globaldecision") {
905  $value = filter_var($value, FILTER_VALIDATE_BOOL);
906  }
907 
908  $sql = "UPDATE report_info SET $column = $2 WHERE upload_fk = $1;";
909  $stmt = __METHOD__ . "updateReportInfo" . $column;
910  $this->dbManager->getSingleRow($sql, [$uploadId, $value], $stmt);
911  return true;
912  }
913 
914  /* @param int $uploadId
915  * @return int
916  */
917  public function getGlobalDecisionSettingsFromInfo($uploadId, $setGlobal=null)
918  {
919  $stmt = __METHOD__ . 'get';
920  $sql = "SELECT ri_globaldecision, ri_spdx_selection FROM report_info WHERE upload_fk = $1";
921  $row = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
922  if (empty($row)) {
923  if ($setGlobal === null) {
924  // Old upload, set default value to enable
925  $setGlobal = 1;
926  }
927  $stmt = __METHOD__ . 'ifempty';
928  $userSPDXDefaults = $this->getUserSPDXDefaultsForUpload($uploadId);
929  $sql = "INSERT INTO report_info (upload_fk, ri_globaldecision, ri_spdx_selection) VALUES ($1, $2, $3) RETURNING ri_globaldecision";
930  $row = $this->dbManager->getSingleRow($sql, array($uploadId, $setGlobal, $userSPDXDefaults), $stmt);
931 
932  }
933 
934  if (!empty($setGlobal)) {
935  $stmt = __METHOD__ . 'update';
936  $sql = "UPDATE report_info SET ri_globaldecision = $2 WHERE upload_fk = $1 RETURNING ri_globaldecision";
937  $row = $this->dbManager->getSingleRow($sql, array($uploadId, $setGlobal), $stmt);
938  }
939 
940  return $row['ri_globaldecision'];
941  }
942 
948  public function getUploadHashesFromPfileId($pfilePk)
949  {
950  $stmt = __METHOD__."getUploadHashesFromPfileId";
951  $sql = "SELECT * FROM pfile WHERE pfile_pk = $1";
952  $row = $this->dbManager->getSingleRow($sql, array($pfilePk), $stmt);
953 
954  return ["sha1" => $row["pfile_sha1"], "md5" => $row["pfile_md5"], "sha256" => $row["pfile_sha256"]];
955  }
956 
962  public function insertReportConfReuse($uploadId, $reusedUploadId)
963  {
964  $stmt = __METHOD__ . ".checkReused";
965  $sql = "SELECT 1 AS exists FROM report_info WHERE upload_fk = $1 LIMIT 1;";
966  $row = $this->dbManager->getSingleRow($sql, array($reusedUploadId), $stmt);
967 
968  if (empty($row['exists'])) {
969  return false;
970  }
971 
972  $this->dbManager->begin();
973 
974  $stmt = __METHOD__ . ".removeExists";
975  $sql = "DELETE FROM report_info WHERE upload_fk = $1;";
976  $this->dbManager->getSingleRow($sql, [$uploadId], $stmt);
977 
978  $stmt = __METHOD__ . ".getAllColumns";
979  $sql = "SELECT string_agg(column_name, ',') AS columns
980  FROM information_schema.columns
981  WHERE table_name = 'report_info'
982  AND column_name != 'ri_pk'
983  AND column_name != 'upload_fk';";
984  $row = $this->dbManager->getSingleRow($sql, [], $stmt);
985  $columns = $row['columns'];
986 
987  $stmt = __METHOD__."CopyinsertReportConfReuse";
988  $this->dbManager->prepare($stmt,
989  "INSERT INTO report_info(upload_fk, $columns)
990  SELECT $1, $columns
991  FROM report_info WHERE upload_fk = $2"
992  );
993  $this->dbManager->freeResult($this->dbManager->execute(
994  $stmt, array($uploadId, $reusedUploadId)
995  ));
996 
997  $this->dbManager->commit();
998  return true;
999  }
1000 }
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
getUploadtreeIdFromPfile($uploadFk, $pfileFk)
Definition: UploadDao.php:111
getParentItemBounds($uploadId, $uploadTreeTableName=null)
Definition: UploadDao.php:201
getReusedUpload($uploadId, $groupId)
Definition: UploadDao.php:544
createItem($uploadEntry, $uploadTreeTableName)
Definition: UploadDao.php:561
addReusedUpload($uploadId, $reusedUploadId, $groupId, $reusedGroupId, $reuseMode=0)
Definition: UploadDao.php:532
countNonArtifactDescendants(ItemTreeBounds $itemTreeBounds, $isFlat=true)
Definition: UploadDao.php:594
getClearingDuration(int $uploadId)
Definition: UploadDao.php:347
createItemTreeBounds($uploadEntryData, $uploadTreeTableName)
Definition: UploadDao.php:581
getUploadHashesFromPfileId($pfilePk)
Get Pfile hashes from the pfile id.
Definition: UploadDao.php:948
getPFileDataPerFileName(ItemTreeBounds $itemTreeBounds)
Definition: UploadDao.php:690
getContainingFileCount(ItemTreeBounds $itemTreeBounds, UploadTreeProxy $uploadTreeView)
Definition: UploadDao.php:490
getFatItemId($itemId, $uploadId, $uploadtreeTablename)
Definition: UploadDao.php:680
getItemTreeBoundsFromUploadId($uploadTreeId, $uploadId)
Definition: UploadDao.php:189
getAssigneeDate(int $uploadId)
Definition: UploadDao.php:313
getPFilesDataPerHashAlgo(ItemTreeBounds $itemTreeBounds, $hashAlgo="sha1")
Definition: UploadDao.php:769
getItemByDirection($uploadId, $itemId, $direction, $options)
Definition: UploadDao.php:423
getFatItemArray($itemId, $uploadId, $uploadtreeTablename)
Definition: UploadDao.php:657
countPlainFiles(ItemTreeBounds $itemTreeBounds)
Definition: UploadDao.php:224
getNextItem($uploadId, $itemId, $options=null)
Definition: UploadDao.php:395
getClosedDate(int $uploadId)
Definition: UploadDao.php:330
updateReportInfo($uploadId, $column, $value)
Update report info for upload.
Definition: UploadDao.php:875
getPreviousItem($uploadId, $itemId, $options=null)
Definition: UploadDao.php:406
getItemTreeBounds($itemId, $uploadTreeTableName="uploadtree")
Definition: UploadDao.php:178
getUploadtreeTableName($uploadId)
Get the uploadtree table name for this upload_pk If upload_pk does not exist, return "uploadtree".
Definition: UploadDao.php:374
getAssignee($uploadId, $groupId)
Get the upload assignee id.
Definition: UploadDao.php:292
getUploadEntry($uploadTreeId, $uploadTreeTableName="uploadtree")
Definition: UploadDao.php:94
insertReportConfReuse($uploadId, $reusedUploadId)
Definition: UploadDao.php:962
getUserSPDXDefaultsForUpload($uploadId)
Definition: UploadDao.php:834
getStatus($uploadId, $groupId)
Get the upload status.
Definition: UploadDao.php:269
This class contains the events for the upload_events table.
Fossology exception.
Definition: Exception.php:15
asCTE()
Common Table Expressions.
Definition: DbViewProxy.php:69
HumanDuration(DateInterval $duration)
Convert DateInterval to Human readable format.
Definition: common-ui.php:120
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16