FOSSology  4.4.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 
20 use Monolog\Logger;
21 use DateTime;
22 
23 require_once(dirname(dirname(__FILE__)) . "/common-dir.php");
24 
25 class UploadDao
26 {
27 
28  const REUSE_NONE = 0;
29  const REUSE_ENHANCED = 2;
30  const REUSE_MAIN = 4;
31  const REUSE_CONF = 16;
32  const REUSE_COPYRIGHT = 128;
33  const UNIFIED_REPORT_HEADINGS = array(
34  "assessment" => array("Assessment Summary" => true),
35  "compliancetasks" => array("Required license compliance tasks" => true),
36  "acknowledgements" => array("Acknowledgements" => true),
37  "exportrestrictions" => array("Export Restrictions" => true),
38  "intellectualProperty" => array("Patent Relevant Statements" => true),
39  "notes" => array("Notes" => true),
40  "scanresults" => array("Results of License Scan" => true),
41  "mainlicenses" => array("Main Licenses" => true),
42  "redlicense" => array("Other OSS Licenses (red) - Do not Use Licenses" => true),
43  "yellowlicense" => array("Other OSS Licenses (yellow) - additional obligations to common rules (e.g. copyleft)" => true),
44  "whitelicense" => array("Other OSS Licenses (white) - only common rules" => true),
45  "overviewwithwithoutobligations" => array("Overview of All Licenses with or without Obligations" => true),
46  "copyrights" => array("Copyrights" => true),
47  "copyrightsuf" => array("Copyrights (User Findings)" => true),
48  "bulkfindings" => array("Bulk Findings" => true),
49  "licensenf" => array("Non-Functional Licenses" => true),
50  "irrelevantfiles" => array("Irrelevant Files" => true),
51  "dnufiles" => array("Do not use Files" => true),
52  "changelog" => array("Clearing Protocol Change Log" => true)
53  );
54  const CLIXML_REPORT_HEADINGS = array(
55  "mainlicensesclixml" => array("Main Licenses" => true),
56  "licensepath" => array("License File Path" => true),
57  "licensehash" => array("License File Hash" => true),
58  "copyrightsclixml" => array("Copyrights" => true),
59  "copyrightpath" => array("Copyright File Path" => true),
60  "copyrighthash" => array("Copyright File Hash" => true),
61  "exportrestrictionsclixml" => array("Export Restrictions(ECC)" => true),
62  "eccpath" => array("ECC File Path" => true),
63  "ecchash" => array("ECC File Hash" => true),
64  "intellectualPropertyclixml" => array("Identified Patent Relevant Analysis(IPRA)" => true),
65  "iprapath" => array("IPRA File Path" => true),
66  "iprahash" => array("IPRA File Hash" => true),
67  "allobligations" => array("All Obligations" => true),
68  "acknowledgementsclixml" => array("Acknowledgements" => true),
69  "irrelevantfilesclixml" => array("Irrelevant Files" => true),
70  "dnufilesclixml" => array("Do not use Files" => true),
71  "notesclixml" => array("Additional Notes" => true)
72  );
74  private $dbManager;
76  private $logger;
78  private $permissionDao;
79 
80  public function __construct(DbManager $dbManager, Logger $logger, UploadPermissionDao $uploadPermissionDao)
81  {
82  $this->dbManager = $dbManager;
83  $this->logger = $logger;
84  $this->permissionDao = $uploadPermissionDao;
85  }
86 
87 
93  public function getUploadEntry($uploadTreeId, $uploadTreeTableName = "uploadtree")
94  {
95  $stmt = __METHOD__ . ".$uploadTreeTableName";
96  $uploadEntry = $this->dbManager->getSingleRow("SELECT * FROM $uploadTreeTableName WHERE uploadtree_pk = $1",
97  array($uploadTreeId), $stmt);
98  if ($uploadEntry) {
99  $uploadEntry['tablename'] = $uploadTreeTableName;
100  }
101  return $uploadEntry;
102  }
103 
110  public function getUploadtreeIdFromPfile($uploadFk, $pfileFk)
111  {
112  $uploadTreeTableName = $this->getUploadtreeTableName($uploadFk);
113  $stmt = __METHOD__ . ".$uploadTreeTableName";
114  $uploadEntry = $this->dbManager->getSingleRow("SELECT uploadtree_pk " .
115  "FROM $uploadTreeTableName " .
116  "WHERE upload_fk = $1 AND pfile_fk = $2",
117  array($uploadFk, $pfileFk), $stmt);
118  return intval($uploadEntry['uploadtree_pk']);
119  }
120 
125  public function getUpload($uploadId)
126  {
127  $stmt = __METHOD__;
128  $row = $this->dbManager->getSingleRow("SELECT * FROM upload WHERE upload_pk = $1",
129  array($uploadId), $stmt);
130 
131  return $row ? Upload::createFromTable($row) : null;
132  }
133 
134  public function getActiveUploadsArray()
135  {
136  $stmt = __METHOD__;
137  $queryResult = $this->dbManager->getRows("SELECT * FROM upload where pfile_fk IS NOT NULL",
138  array(), $stmt);
139 
140  $results = array();
141  foreach ($queryResult as $row) {
142  $results[] = Upload::createFromTable($row);
143  }
144 
145  return $results;
146  }
147 
153  public function getItemTreeBounds($itemId, $uploadTreeTableName = "uploadtree")
154  {
155  $uploadEntryData = $this->getUploadEntry($itemId, $uploadTreeTableName);
156  return $this->createItemTreeBounds($uploadEntryData, $uploadTreeTableName);
157  }
158 
164  public function getItemTreeBoundsFromUploadId($uploadTreeId, $uploadId)
165  {
166  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
167  return $this->getItemTreeBounds($uploadTreeId, $uploadTreeTableName);
168  }
169 
176  public function getParentItemBounds($uploadId, $uploadTreeTableName = null)
177  {
178  if ($uploadTreeTableName === null) {
179  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
180  }
181 
182  $stmt = __METHOD__ . ".$uploadTreeTableName";
183  $parameters = array();
184  $uploadCondition = $this->handleUploadIdForTable($uploadTreeTableName, $uploadId, $parameters);
185 
186  $uploadEntryData = $this->dbManager->getSingleRow("SELECT * FROM $uploadTreeTableName
187  WHERE parent IS NULL
188  $uploadCondition
189  ",
190  $parameters, $stmt);
191 
192  return $uploadEntryData ? $this->createItemTreeBounds($uploadEntryData, $uploadTreeTableName) : false;
193  }
194 
199  public function countPlainFiles(ItemTreeBounds $itemTreeBounds)
200  {
201  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
202 
203  $stmt = __METHOD__ . ".$uploadTreeTableName";
204  $parameters = array($itemTreeBounds->getLeft(), $itemTreeBounds->getRight());
205  $uploadCondition = $this->handleUploadIdForTable($uploadTreeTableName, $itemTreeBounds->getUploadId(), $parameters);
206 
207  $row = $this->dbManager->getSingleRow("SELECT count(*) as count FROM $uploadTreeTableName
208  WHERE lft BETWEEN $1 AND $2
209  $uploadCondition
210  AND ((ufile_mode & (3<<28))=0)
211  AND pfile_fk != 0",
212  $parameters, $stmt);
213  return intval($row["count"]);
214  }
215 
216  private function handleUploadIdForTable($uploadTreeTableName, $uploadId, &$parameters)
217  {
218  if ($uploadTreeTableName === "uploadtree" || $uploadTreeTableName === "uploadtree_a") {
219  $parameters[] = $uploadId;
220  return " AND upload_fk = $" . count($parameters) . " ";
221  } else {
222  return "";
223  }
224  }
225 
229  public function getStatusTypeMap()
230  {
231  global $container;
233  $uploadStatus = $container->get('upload_status.types');
234  return $uploadStatus->getMap();
235  }
236 
244  public function getStatus($uploadId, $groupId)
245  {
246  if ($this->isAccessible($uploadId, $groupId)) {
247  $row = $this->dbManager->getSingleRow("SELECT status_fk " .
248  "FROM upload_clearing WHERE upload_fk=$1 AND group_fk=$2;",
249  array($uploadId, $groupId));
250  if (false === $row) {
251  return 1;
252  }
253  return $row['status_fk'];
254  } else {
255  throw new \Exception("permission denied");
256  }
257  }
258 
259 
267  public function getAssignee($uploadId, $groupId)
268  {
269  if ($this->isAccessible($uploadId, $groupId)) {
270  $row = $this->dbManager->getSingleRow("SELECT assignee FROM upload_clearing WHERE upload_fk=$1 AND group_fk=$2;",
271  array($uploadId, $groupId));
272  if (false === $row) {
273  return 1;
274  }
275  return $row['assignee'];
276  } else {
277  throw new \Exception("permission denied");
278  }
279  }
280 
288  public function getAssigneeDate(int $uploadId): ?string
289  {
290  $sql = "SELECT event_ts FROM upload_events WHERE upload_fk = $1 " .
291  "AND event_type = " . UploadEvents::ASSIGNEE_EVENT;
292  $row = $this->dbManager->getSingleRow($sql, [$uploadId], __METHOD__);
293  if (empty($row) || empty($row["event_ts"])) {
294  return null;
295  }
296  return $row["event_ts"];
297  }
298 
305  public function getClosedDate(int $uploadId): ?string
306  {
307  $sql = "SELECT event_ts FROM upload_events WHERE upload_fk = $1 " .
308  "AND event_type = " . UploadEvents::UPLOAD_CLOSED_EVENT;
309  $row = $this->dbManager->getSingleRow($sql, [$uploadId], __METHOD__);
310  if (empty($row) || empty($row["event_ts"])) {
311  return null;
312  }
313  return $row["event_ts"];
314  }
315 
322  public function getClearingDuration(int $uploadId): ?array
323  {
324  $duration = "NA";
325  $assignDate = $this->getAssigneeDate($uploadId);
326  $closingDate = $this->getClosedDate($uploadId);
327  $durationSort = 0;
328  if ($assignDate != null && $closingDate != null) {
329  try {
330  $closingDate = new DateTime($closingDate);
331  $assignDate = new DateTime($assignDate);
332  if ($assignDate < $closingDate) {
333  $duration = HumanDuration($closingDate->diff($assignDate));
334  $durationSort = $closingDate->getTimestamp() - $assignDate->getTimestamp();
335  }
336  } catch (Exception $_) {
337  }
338  }
339  return array($duration, $durationSort);
340  }
349  public function getUploadtreeTableName($uploadId)
350  {
351  if (!empty($uploadId)) {
352  $statementName = __METHOD__;
353  $row = $this->dbManager->getSingleRow(
354  "SELECT uploadtree_tablename FROM upload WHERE upload_pk=$1",
355  array($uploadId),
356  $statementName
357  );
358  if (!empty($row['uploadtree_tablename'])) {
359  return $row['uploadtree_tablename'];
360  }
361  }
362  return "uploadtree";
363  }
364 
370  public function getNextItem($uploadId, $itemId, $options = null)
371  {
372  return $this->getItemByDirection($uploadId, $itemId, self::DIR_FWD, $options);
373  }
374 
381  public function getPreviousItem($uploadId, $itemId, $options = null)
382  {
383  return $this->getItemByDirection($uploadId, $itemId, self::DIR_BCK, $options);
384  }
385 
386  const DIR_FWD = 1;
387  const DIR_BCK = -1;
388  const NOT_FOUND = null;
389 
390 
398  public function getItemByDirection($uploadId, $itemId, $direction, $options)
399  {
400  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
401  $originItem = $this->getUploadEntry($itemId, $uploadTreeTableName);
402  $originLft = $originItem['lft'];
403 
404  $options[UploadTreeProxy::OPT_ITEM_FILTER] = " AND ut.ufile_mode & (3<<28) = 0";
405  $uploadTreeViewName = 'items2care';
406 
407  if ($direction == self::DIR_FWD) {
408  $uploadTreeViewName .= 'fwd';
409  $options[UploadTreeProxy::OPT_ITEM_FILTER] .= " AND lft>$1";
410  $order = 'ASC';
411  } else {
412  $uploadTreeViewName .= 'bwd';
413  $options[UploadTreeProxy::OPT_ITEM_FILTER] .= " AND lft<$1";
414  $order = 'DESC';
415  }
416 
417  $uploadTreeView = new UploadTreeProxy($uploadId, $options, $uploadTreeTableName, $uploadTreeViewName);
418  $statementName = __METHOD__ . ".$uploadTreeViewName.";
419  $query = $uploadTreeView->getDbViewQuery()." ORDER BY lft $order";
420 
421  $newItemRow = $this->dbManager->getSingleRow("$query LIMIT 1", array($originLft), $statementName);
422  if ($newItemRow) {
423  return $this->createItem($newItemRow, $uploadTreeTableName);
424  } else {
425  return self::NOT_FOUND;
426  }
427  }
428 
429 
434  public function getUploadParent($uploadId)
435  {
436  $uploadTreeTableName = $this->getUploadtreeTableName($uploadId);
437  $statementname = __METHOD__ . $uploadTreeTableName;
438 
439  $parent = $this->dbManager->getSingleRow(
440  "SELECT uploadtree_pk
441  FROM $uploadTreeTableName
442  WHERE upload_fk=$1 AND parent IS NULL", array($uploadId), $statementname);
443  if (false === $parent) {
444  throw new \Exception("Missing upload tree parent for upload");
445  }
446  return $parent['uploadtree_pk'];
447  }
448 
449  public function getLeftAndRight($uploadtreeID, $uploadTreeTableName = "uploadtree")
450  {
451  $statementName = __METHOD__ . $uploadTreeTableName;
452  $leftRight = $this->dbManager->getSingleRow(
453  "SELECT lft,rgt FROM $uploadTreeTableName WHERE uploadtree_pk = $1",
454  array($uploadtreeID), $statementName
455  );
456 
457  return array($leftRight['lft'], $leftRight['rgt']);
458  }
459 
465  public function getContainingFileCount(ItemTreeBounds $itemTreeBounds, UploadTreeProxy $uploadTreeView)
466  {
467  $sql = "SELECT count(*) FROM " . $uploadTreeView->getDbViewName() . " WHERE lft BETWEEN $1 AND $2";
468  $result = $this->dbManager->getSingleRow($sql
469  , array($itemTreeBounds->getLeft(), $itemTreeBounds->getRight()), __METHOD__ . $uploadTreeView->asCTE());
470  return $result['count'];
471  }
472 
479  public function getContainedItems(ItemTreeBounds $itemTreeBounds, $addCondition = "", $addParameters = array())
480  {
481  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
482 
483  $statementName = __METHOD__ . ".$uploadTreeTableName";
484 
485  $view = new UploadTreeViewProxy($itemTreeBounds, array(UploadTreeViewProxy::CONDITION_PLAIN_FILES));
486 
487  $this->dbManager->prepare($statementName,
488  $view->asCTE() . " SELECT * FROM " . $view->getDbViewName() ." ut ".
489  ($addCondition ? " WHERE " . $addCondition : ''));
490  $res = $this->dbManager->execute($statementName, $addParameters);
491  $items = array();
492 
493  while ($row = $this->dbManager->fetchArray($res)) {
494  $items[] = $this->createItem($row, $uploadTreeTableName);
495  }
496  $this->dbManager->freeResult($res);
497  return $items;
498  }
499 
507  public function addReusedUpload($uploadId, $reusedUploadId, $groupId, $reusedGroupId, $reuseMode=0)
508  {
509  $this->dbManager->insertTableRow('upload_reuse',
510  array('upload_fk'=>$uploadId, 'group_fk'=> $groupId, 'reused_upload_fk'=>$reusedUploadId, 'reused_group_fk'=>$reusedGroupId,'reuse_mode'=>$reuseMode));
511  }
512 
519  public function getReusedUpload($uploadId, $groupId)
520  {
521  $statementName = __METHOD__;
522 
523  $this->dbManager->prepare($statementName,
524  "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");
525  $res = $this->dbManager->execute($statementName, array($uploadId, $groupId));
526  $reusedPairs = $this->dbManager->fetchAll($res);
527  $this->dbManager->freeResult($res);
528  return $reusedPairs;
529  }
530 
536  protected function createItem($uploadEntry, $uploadTreeTableName)
537  {
538  $itemTreeBounds = new ItemTreeBounds(
539  intval($uploadEntry['uploadtree_pk']),
540  $uploadTreeTableName,
541  intval($uploadEntry['upload_fk']),
542  intval($uploadEntry['lft']), intval($uploadEntry['rgt']));
543 
544  $parent = $uploadEntry['parent'];
545  return new Item(
546  $itemTreeBounds, $parent !== null ? intval($parent) : null, intval($uploadEntry['pfile_fk']), intval($uploadEntry['ufile_mode']), $uploadEntry['ufile_name']
547  );
548  }
549 
556  protected function createItemTreeBounds($uploadEntryData, $uploadTreeTableName)
557  {
558  if ($uploadEntryData === false) {
559  throw new Exception("did not find uploadTreeId in $uploadTreeTableName");
560  }
561  return new ItemTreeBounds(intval($uploadEntryData['uploadtree_pk']), $uploadTreeTableName, intval($uploadEntryData['upload_fk']), intval($uploadEntryData['lft']), intval($uploadEntryData['rgt']));
562  }
563 
569  public function countNonArtifactDescendants(ItemTreeBounds $itemTreeBounds, $isFlat=true)
570  {
571  $stmt=__METHOD__;
572  $sql = "SELECT count(*) FROM ".$itemTreeBounds->getUploadTreeTableName()." ut "
573  . "WHERE ut.upload_fk=$1";
574  $params = array($itemTreeBounds->getUploadId());
575  if (!$isFlat) {
576  $stmt = __METHOD__.'.parent';
577  $params[] = $itemTreeBounds->getItemId();
578  $sql .= " AND ut.ufile_mode & (1<<28) = 0 AND ut.realparent = $2";
579  } else {
580  $params[] = $itemTreeBounds->getLeft();
581  $params[] = $itemTreeBounds->getRight();
582  $sql .= " AND ut.ufile_mode & (3<<28) = 0 AND (ut.lft BETWEEN $2 AND $3)";
583  }
584 
585  $descendants = $this->dbManager->getSingleRow($sql,$params);
586  return $descendants['count'];
587  }
588 
589 
590  public function isAccessible($uploadId, $groupId)
591  {
592  return $this->permissionDao->isAccessible($uploadId, $groupId);
593  }
594 
595  public function isEditable($uploadId, $groupId)
596  {
597  return $this->permissionDao->isEditable($uploadId, $groupId);
598  }
599 
600  public function makeAccessibleToGroup($uploadId, $groupId, $perm=null)
601  {
602  $this->permissionDao->makeAccessibleToGroup($uploadId, $groupId, $perm);
603  }
604 
605  public function makeAccessibleToAllGroupsOf($uploadId, $userId, $perm=null)
606  {
607  $this->permissionDao->makeAccessibleToAllGroupsOf($uploadId, $userId, $perm);
608  }
609 
614  public function getUploadHashes($uploadId)
615  {
616  $pfile = $this->dbManager->getSingleRow('SELECT pfile.* FROM upload, pfile WHERE upload_pk=$1 AND pfile_fk=pfile_pk',
617  array($uploadId), __METHOD__);
618  return array('sha1'=>$pfile['pfile_sha1'],'md5'=>$pfile['pfile_md5'],'sha256'=>$pfile['pfile_sha256']);
619  }
620 
627  public function getFatItemArray($itemId,$uploadId,$uploadtreeTablename)
628  {
629  $sqlChildrenOf = "SELECT COUNT(*) FROM $uploadtreeTablename s
630  WHERE ufile_mode&(1<<28)=0 and s.upload_fk=$2 AND s.realparent=";
631  $sql="WITH RECURSIVE item_path (item_id,num_children,depth,ufile_mode,ufile_name) AS (
632  SELECT uploadtree_pk item_id, ($sqlChildrenOf $1) num_children, 0 depth, ufile_mode, ufile_name
633  FROM $uploadtreeTablename WHERE upload_fk=$2 AND uploadtree_pk=$1
634  UNION
635  SELECT uploadtree_pk item_id, ($sqlChildrenOf ut.uploadtree_pk) num_children,
636  item_path.depth+1 depth, ut.ufile_mode, item_path.ufile_name||'/'||ut.ufile_name ufile_name
637  FROM $uploadtreeTablename ut INNER JOIN item_path ON item_id=ut.realparent
638  WHERE upload_fk=$2 AND ut.ufile_mode&(1<<28)=0 AND num_children<2
639  )
640  SELECT * FROM item_path WHERE num_children!=1 OR ufile_mode&(1<<29)=0 ORDER BY depth DESC LIMIT 1";
641  return $this->dbManager->getSingleRow($sql,array($itemId, $uploadId),__METHOD__.$uploadtreeTablename);
642  }
643 
650  public function getFatItemId($itemId,$uploadId,$uploadtreeTablename)
651  {
652  $itemRow = $this->getFatItemArray($itemId,$uploadId,$uploadtreeTablename);
653  return $itemRow['item_id'];
654  }
655 
660  public function getPFileDataPerFileName(ItemTreeBounds $itemTreeBounds)
661  {
662  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
663  $statementName = __METHOD__ . '.' . $uploadTreeTableName;
664  $param = array();
665 
666  $param[] = $itemTreeBounds->getLeft();
667  $param[] = $itemTreeBounds->getRight();
668  $condition = " lft BETWEEN $1 AND $2";
669  $condition .= " AND (ufile_mode & (1<<28)) = 0";
670 
671  if ('uploadtree_a' == $uploadTreeTableName) {
672  $param[] = $itemTreeBounds->getUploadId();
673  $condition .= " AND upload_fk=$".count($param);
674  }
675 
676  $sql = "
677 SELECT ufile_name, uploadtree_pk, lft, rgt, ufile_mode,
678  pfile_pk, pfile_md5, pfile_sha1, pfile_sha256
679 FROM $uploadTreeTableName
680  LEFT JOIN pfile
681  ON pfile_fk = pfile_pk
682 WHERE $condition
683 ORDER BY lft asc
684 ";
685 
686  $this->dbManager->prepare($statementName, $sql);
687  $result = $this->dbManager->execute($statementName, $param);
688  $pfilePerFileName = array();
689 
690  $row = $this->dbManager->fetchArray($result);
691  $pathStack = array($row['ufile_name']);
692  $rgtStack = array($row['rgt']);
693  $lastLft = $row['lft'];
694  $this->addToPFilePerFileName($pfilePerFileName, $pathStack, $row);
695  while ($row = $this->dbManager->fetchArray($result)) {
696  if ($row['lft'] < $lastLft) {
697  continue;
698  }
699 
700  $this->updateStackState($pathStack, $rgtStack, $lastLft, $row);
701  $this->addToPFilePerFileName($pfilePerFileName, $pathStack, $row);
702  }
703  $this->dbManager->freeResult($result);
704  return $pfilePerFileName;
705  }
706 
707  private function updateStackState(&$pathStack, &$rgtStack, &$lastLft, $row)
708  {
709  if ($row['lft'] >= $lastLft) {
710  while (count($rgtStack) > 0 && $row['lft'] > $rgtStack[count($rgtStack)-1]) {
711  array_pop($pathStack);
712  array_pop($rgtStack);
713  }
714  if ($row['lft'] > $lastLft) {
715  $pathStack[] = $row['ufile_name'];
716  $rgtStack[] = $row['rgt'];
717  $lastLft = $row['lft'];
718  }
719  }
720  }
721 
722  private function addToPFilePerFileName(&$pfilePerFileName, $pathStack, $row)
723  {
724  if (($row['ufile_mode'] & (1 << 29)) == 0) {
725  $path = implode('/', $pathStack);
726  $pfilePerFileName[$path]['pfile_pk'] = $row['pfile_pk'];
727  $pfilePerFileName[$path]['uploadtree_pk'] = $row['uploadtree_pk'];
728  $pfilePerFileName[$path]['md5'] = $row['pfile_md5'];
729  $pfilePerFileName[$path]['sha1'] = $row['pfile_sha1'];
730  $pfilePerFileName[$path]['sha256'] = $row['pfile_sha256'];
731  }
732  }
733 
739  public function getPFilesDataPerHashAlgo(ItemTreeBounds $itemTreeBounds, $hashAlgo="sha1")
740  {
741  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
742  $statementName = __METHOD__ . '.' . $uploadTreeTableName;
743  $param = array();
744 
745  $param[] = $itemTreeBounds->getLeft();
746  $param[] = $itemTreeBounds->getRight();
747  $condition = " lft BETWEEN $1 AND $2";
748  $condition .= " AND (ufile_mode & (1<<28)) = 0";
749 
750  if ('uploadtree_a' == $uploadTreeTableName) {
751  $param[] = $itemTreeBounds->getUploadId();
752  $condition .= " AND upload_fk=$".count($param);
753  }
754  $condition .= " AND pfile_$hashAlgo IS NOT NULL";
755 
756  $sql = "
757 SELECT pfile_fk, uploadtree_pk, ufile_mode, pfile_$hashAlgo as hash
758 FROM $uploadTreeTableName
759  LEFT JOIN pfile
760  ON pfile_fk = pfile_pk
761 WHERE $condition
762 ORDER BY lft asc
763 ";
764 
765  $this->dbManager->prepare($statementName, $sql);
766  $result = $this->dbManager->execute($statementName, $param);
767 
768  $pfilePerHashAlgo = array();
769  while ($row = $this->dbManager->fetchArray($result)) {
770  if (($row['ufile_mode']&(1<<29)) == 0) {
771  $pfilePerHashAlgo[strtolower($row['hash'])][] = array('pfile_pk' => $row['pfile_fk'],
772  'uploadtree_pk' => $row['uploadtree_pk']);
773  }
774  }
775  $this->dbManager->freeResult($result);
776  return $pfilePerHashAlgo;
777  }
778 
779 
780  /* @param int $uploadId
781  * @return array
782  */
783  public function getReportInfo($uploadId)
784  {
785  $stmt = __METHOD__;
786  $sql = "SELECT * FROM report_info WHERE upload_fk = $1";
787  $row = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
788 
789  if (empty($row)) {
790  $this->dbManager->begin();
791  $stmt = __METHOD__.'ifempty';
792  $sql = "INSERT INTO report_info (upload_fk) VALUES ($1) RETURNING *";
793  $row = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
794  $this->dbManager->commit();
795  }
796  return $row;
797  }
798 
806  public function updateReportInfo($uploadId, $column, $value)
807  {
808  if ($column === "ri_unifiedcolumns") {
809  $value = json_decode($value, true);
810  $oldValues = $this->getReportInfo($uploadId)["ri_unifiedcolumns"];
811  if (!empty($oldValues)) {
812  $oldValues = json_decode($oldValues, true);
813  } else {
814  $oldValues = self::UNIFIED_REPORT_HEADINGS;
815  }
816  foreach ($value as $key => $val) {
817  $newValText = array_keys($val)[0];
818  $newValValue = array_values($val)[0];
819  $newValValue = ($newValValue === true || $newValValue == "true") ? "on" : null;
820  $oldValues[$key] = [$newValText => $newValValue];
821  }
822  $value = json_encode($oldValues);
823  } elseif ($column === "ri_excluded_obligations") {
824  $value = json_decode($value, true);
825  $oldValues = $this->getReportInfo($uploadId)["ri_excluded_obligations"];
826  if (!empty($oldValues)) {
827  $oldValues = json_decode($oldValues, true);
828  } else {
829  $oldValues = [];
830  }
831  foreach ($value as $key => $newValue) {
832  $oldValues[$key] = $newValue;
833  }
834  $value = json_encode($oldValues);
835  } elseif ($column === "ri_globaldecision") {
836  $value = filter_var($value, FILTER_VALIDATE_BOOL);
837  }
838 
839  $sql = "UPDATE report_info SET $column = $2 WHERE upload_fk = $1;";
840  $stmt = __METHOD__ . "updateReportInfo" . $column;
841  $this->dbManager->getSingleRow($sql, [$uploadId, $value], $stmt);
842  return true;
843  }
844 
845  /* @param int $uploadId
846  * @return int
847  */
848  public function getGlobalDecisionSettingsFromInfo($uploadId, $setGlobal=null)
849  {
850  $stmt = __METHOD__ . 'get';
851  $sql = "SELECT ri_globaldecision FROM report_info WHERE upload_fk = $1";
852  $row = $this->dbManager->getSingleRow($sql, array($uploadId), $stmt);
853  if (empty($row)) {
854  if ($setGlobal === null) {
855  // Old upload, set default value to enable
856  $setGlobal = 1;
857  }
858  $stmt = __METHOD__ . 'ifempty';
859  $sql = "INSERT INTO report_info (upload_fk, ri_globaldecision) VALUES ($1, $2) RETURNING ri_globaldecision";
860  $row = $this->dbManager->getSingleRow($sql, array($uploadId, $setGlobal), $stmt);
861  }
862 
863  if (!empty($setGlobal)) {
864  $stmt = __METHOD__ . 'update';
865  $sql = "UPDATE report_info SET ri_globaldecision = $2 WHERE upload_fk = $1 RETURNING ri_globaldecision";
866  $row = $this->dbManager->getSingleRow($sql, array($uploadId, $setGlobal), $stmt);
867  }
868 
869  return $row['ri_globaldecision'];
870  }
871 
877  public function getUploadHashesFromPfileId($pfilePk)
878  {
879  $stmt = __METHOD__."getUploadHashesFromPfileId";
880  $sql = "SELECT * FROM pfile WHERE pfile_pk = $1";
881  $row = $this->dbManager->getSingleRow($sql, array($pfilePk), $stmt);
882 
883  return ["sha1" => $row["pfile_sha1"], "md5" => $row["pfile_md5"], "sha256" => $row["pfile_sha256"]];
884  }
885 
891  public function insertReportConfReuse($uploadId, $reusedUploadId)
892  {
893  $stmt = __METHOD__ . ".checkReused";
894  $sql = "SELECT 1 AS exists FROM report_info WHERE upload_fk = $1 LIMIT 1;";
895  $row = $this->dbManager->getSingleRow($sql, array($reusedUploadId), $stmt);
896 
897  if (empty($row['exists'])) {
898  return false;
899  }
900 
901  $this->dbManager->begin();
902 
903  $stmt = __METHOD__ . ".removeExists";
904  $sql = "DELETE FROM report_info WHERE upload_fk = $1;";
905  $this->dbManager->getSingleRow($sql, [$uploadId], $stmt);
906 
907  $stmt = __METHOD__ . ".getAllColumns";
908  $sql = "SELECT string_agg(column_name, ',') AS columns
909  FROM information_schema.columns
910  WHERE table_name = 'report_info'
911  AND column_name != 'ri_pk'
912  AND column_name != 'upload_fk';";
913  $row = $this->dbManager->getSingleRow($sql, [], $stmt);
914  $columns = $row['columns'];
915 
916  $stmt = __METHOD__."CopyinsertReportConfReuse";
917  $this->dbManager->prepare($stmt,
918  "INSERT INTO report_info(upload_fk, $columns)
919  SELECT $1, $columns
920  FROM report_info WHERE upload_fk = $2"
921  );
922  $this->dbManager->freeResult($this->dbManager->execute(
923  $stmt, array($uploadId, $reusedUploadId)
924  ));
925 
926  $this->dbManager->commit();
927  return true;
928  }
929 }
getUploadtreeIdFromPfile($uploadFk, $pfileFk)
Definition: UploadDao.php:110
getParentItemBounds($uploadId, $uploadTreeTableName=null)
Definition: UploadDao.php:176
getReusedUpload($uploadId, $groupId)
Definition: UploadDao.php:519
createItem($uploadEntry, $uploadTreeTableName)
Definition: UploadDao.php:536
addReusedUpload($uploadId, $reusedUploadId, $groupId, $reusedGroupId, $reuseMode=0)
Definition: UploadDao.php:507
countNonArtifactDescendants(ItemTreeBounds $itemTreeBounds, $isFlat=true)
Definition: UploadDao.php:569
getClearingDuration(int $uploadId)
Definition: UploadDao.php:322
createItemTreeBounds($uploadEntryData, $uploadTreeTableName)
Definition: UploadDao.php:556
getUploadHashesFromPfileId($pfilePk)
Get Pfile hashes from the pfile id.
Definition: UploadDao.php:877
getPFileDataPerFileName(ItemTreeBounds $itemTreeBounds)
Definition: UploadDao.php:660
getContainingFileCount(ItemTreeBounds $itemTreeBounds, UploadTreeProxy $uploadTreeView)
Definition: UploadDao.php:465
getFatItemId($itemId, $uploadId, $uploadtreeTablename)
Definition: UploadDao.php:650
getItemTreeBoundsFromUploadId($uploadTreeId, $uploadId)
Definition: UploadDao.php:164
getAssigneeDate(int $uploadId)
Definition: UploadDao.php:288
getPFilesDataPerHashAlgo(ItemTreeBounds $itemTreeBounds, $hashAlgo="sha1")
Definition: UploadDao.php:739
getItemByDirection($uploadId, $itemId, $direction, $options)
Definition: UploadDao.php:398
getFatItemArray($itemId, $uploadId, $uploadtreeTablename)
Definition: UploadDao.php:627
countPlainFiles(ItemTreeBounds $itemTreeBounds)
Definition: UploadDao.php:199
getNextItem($uploadId, $itemId, $options=null)
Definition: UploadDao.php:370
getClosedDate(int $uploadId)
Definition: UploadDao.php:305
updateReportInfo($uploadId, $column, $value)
Update report info for upload.
Definition: UploadDao.php:806
getPreviousItem($uploadId, $itemId, $options=null)
Definition: UploadDao.php:381
getItemTreeBounds($itemId, $uploadTreeTableName="uploadtree")
Definition: UploadDao.php:153
getUploadtreeTableName($uploadId)
Get the uploadtree table name for this upload_pk If upload_pk does not exist, return "uploadtree".
Definition: UploadDao.php:349
getAssignee($uploadId, $groupId)
Get the upload assignee id.
Definition: UploadDao.php:267
getUploadEntry($uploadTreeId, $uploadTreeTableName="uploadtree")
Definition: UploadDao.php:93
insertReportConfReuse($uploadId, $reusedUploadId)
Definition: UploadDao.php:891
getStatus($uploadId, $groupId)
Get the upload status.
Definition: UploadDao.php:244
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