10 namespace Fossology\Lib\Dao;
36 private $copyrightDao;
38 private $licenseRefCache;
47 $this->logger =
new Logger(self::class);
48 $this->uploadDao = $uploadDao;
49 $this->licenseRefCache = array();
51 $this->copyrightDao = $container->get(
'dao.copyright');
54 private function getRelevantDecisionsCte(
ItemTreeBounds $itemTreeBounds, $groupId, $onlyCurrent, &$statementName, &$params, $condition=
"")
59 $params[] = DecisionTypes::WIP; $p1 =
"$". count($params);
60 $params[] = $groupId; $p2 =
"$". count($params);
63 if (
'uploadtree' === $uploadTreeTable ||
'uploadtree_a' === $uploadTreeTable) {
64 $params[] = $uploadId; $p =
"$". count($params);
65 $sql_upload =
" AND ut.upload_fk=$p";
67 if (!empty($condition)) {
68 $statementName .=
".(".$condition.
")";
69 $condition =
" AND $condition";
72 $filterClause = $onlyCurrent ?
"DISTINCT ON(itemid)" :
"";
73 $sortClause = $onlyCurrent ?
"ORDER BY itemid, id DESC" :
"";
75 $statementName .=
"." . $uploadTreeTable . ($onlyCurrent ?
".current":
"");
77 $globalScope = DecisionScopes::REPO;
78 $localScope = DecisionScopes::ITEM;
80 $applyGlobal = $this->uploadDao->getGlobalDecisionSettingsFromInfo($uploadId);
81 if (!empty($applyGlobal)) {
82 $applyGlobal =
"(ut.pfile_fk = cd.pfile_fk AND cd.scope = $globalScope) OR
83 (ut.uploadtree_pk = cd.uploadtree_fk
84 AND cd.scope = $localScope AND cd.group_fk = $p2)";
85 $statementName .=
"WithGlobal";
87 $applyGlobal =
"(ut.uploadtree_pk = cd.uploadtree_fk
88 AND cd.group_fk = $p2)";
89 $statementName .=
"WithoutGlobal";
92 return "WITH decision AS (
95 cd.clearing_decision_pk AS id,
96 cd.pfile_fk AS pfile_id,
97 ut.uploadtree_pk AS itemid,
98 cd.user_fk AS user_id,
99 cd.decision_type AS type_id,
101 EXTRACT(EPOCH FROM cd.date_added) AS ts_added
102 FROM clearing_decision cd
103 INNER JOIN $uploadTreeTable ut
105 $sql_upload $condition
106 WHERE cd.decision_type != $p1
118 $statementName = __METHOD__;
120 $params = array($itemTreeBounds->
getLeft(), $itemTreeBounds->
getRight());
121 $condition =
"ut.lft BETWEEN $1 AND $2";
123 $decisionsCte = $this->getRelevantDecisionsCte($itemTreeBounds, $groupId, $onlyCurrent=
true, $statementName, $params, $condition);
124 $params[] = DecisionTypes::IRRELEVANT;
125 $sql =
"$decisionsCte
127 lr.rf_pk AS license_id,
128 lr.rf_shortname AS shortname,
129 lr.rf_spdx_id AS spdx_id,
130 lr.rf_fullname AS fullname
132 INNER JOIN clearing_decision_event cde ON cde.clearing_decision_fk = decision.id
133 INNER JOIN clearing_event ce ON
134 (ce.clearing_event_pk = cde.clearing_event_fk AND NOT ce.removed)
135 INNER JOIN license_ref lr ON lr.rf_pk = ce.rf_fk
136 WHERE type_id != $".count($params).
"
137 GROUP BY license_id,shortname,fullname,spdx_id";
139 $this->
dbManager->prepare($statementName, $sql);
141 $res = $this->
dbManager->execute($statementName, $params);
144 while ($row = $this->
dbManager->fetchArray($res)) {
145 $licenses[] =
new LicenseRef($row[
'license_id'], $row[
'shortname'], $row[
'fullname'], $row[
'spdx_id']);
164 $statementName = __METHOD__;
166 $params = array($itemTreeBounds->
getItemId());
167 $condition =
"ut.uploadtree_pk = $1";
169 $decisionsCte = $this->getRelevantDecisionsCte($itemTreeBounds, $groupId, $onlyCurrent, $statementName, $params, $condition);
171 $clearingsWithLicensesArray = $this->
getDecisionsFromCte($decisionsCte, $statementName, $params, $forClearingHistory);
174 return $clearingsWithLicensesArray;
188 $statementName = __METHOD__ . ($includeSubFolders ?
".subfolders" :
".direct");
190 if (!$includeSubFolders) {
191 $params = array($itemTreeBounds->
getItemId());
192 $condition =
"ut.realparent = $1";
194 $params = array($itemTreeBounds->
getLeft(), $itemTreeBounds->
getRight());
195 $condition =
"ut.lft BETWEEN $1 AND $2";
198 $decisionsCte = $this->getRelevantDecisionsCte($itemTreeBounds, $groupId, $onlyCurrent, $statementName, $params, $condition);
200 $clearingsWithLicensesArray = $this->
getDecisionsFromCte($decisionsCte, $statementName, $params);
203 return $clearingsWithLicensesArray;
214 $sql =
"$decisionsCte
217 users.user_name AS user_name,
218 ce.clearing_event_pk as event_id,
219 ce.user_fk as event_user_id,
220 ce.group_fk as event_group_id,
221 lr.rf_pk AS license_id,
222 lr.rf_spdx_id AS spdx_id,
223 lr.rf_shortname AS shortname,
224 lr.rf_fullname AS fullname,
225 ce.removed AS removed,
226 ce.type_fk AS event_type_id,
227 ce.reportinfo AS reportinfo,
228 ce.comment AS comment,
229 ce.acknowledgement AS acknowledgement
231 LEFT JOIN users ON decision.user_id = users.user_pk
232 LEFT JOIN clearing_decision_event cde ON cde.clearing_decision_fk = decision.id
233 LEFT JOIN clearing_event ce ON ce.clearing_event_pk = cde.clearing_event_fk
234 LEFT JOIN license_ref lr ON lr.rf_pk = ce.rf_fk
235 ORDER BY decision.id DESC, itemid, event_id ASC";
237 $this->
dbManager->prepare($statementName, $sql);
239 $result = $this->
dbManager->execute($statementName, $params);
240 $clearingsWithLicensesArray = array();
242 $previousClearingId = -1;
243 $previousItemId = -1;
244 $clearingEvents = array();
245 $clearingEventCache = array();
248 while ($row = $this->
dbManager->fetchArray($result)) {
249 $clearingId = $row[
'id'];
250 $itemId = $row[
'itemid'];
251 $licenseId = $row[
'license_id'];
252 $eventId = $row[
'event_id'];
253 $licenseSpdxId = $row[
'spdx_id'];
254 $licenseShortName = $row[
'shortname'];
255 $licenseName = $row[
'fullname'];
256 $licenseIsRemoved = $row[
'removed'];
258 $eventType = $row[
'event_type_id'];
259 $eventUserId = $row[
'event_user_id'];
260 $eventGroupId = $row[
'event_group_id'];
261 $comment = $row[
'comment'];
262 $reportInfo = $row[
'reportinfo'];
263 $acknowledgement = $row[
'acknowledgement'];
265 if ($clearingId !== $previousClearingId || $itemId !== $previousItemId) {
268 $clearingsWithLicensesArray[] = $clearingDecisionBuilder->setClearingEvents($clearingEvents)->build();
273 $previousClearingId = $clearingId;
274 $previousItemId = $itemId;
275 $clearingEvents = array();
277 ->setClearingId($row[
'id'])
278 ->setUploadTreeId($itemId)
279 ->setPfileId($row[
'pfile_id'])
280 ->setUserName($row[
'user_name'])
281 ->setUserId($row[
'user_id'])
282 ->setType(intval($row[
'type_id']))
283 ->setScope(intval($row[
'scope']))
284 ->setTimeStamp($row[
'ts_added']);
287 if ($licenseId !==
null) {
288 if (!array_key_exists($eventId, $clearingEventCache)) {
289 if (!array_key_exists($licenseId, $this->licenseRefCache)) {
290 $this->licenseRefCache[$licenseId] =
new LicenseRef($licenseId, $licenseShortName, $licenseName, $licenseSpdxId);
292 $licenseRef = $this->licenseRefCache[$licenseId];
293 $clearingEventCache[$eventId] = $this->
buildClearingEvent($eventId, $eventUserId, $eventGroupId, $licenseRef, $licenseIsRemoved, $eventType, $reportInfo, $comment, $acknowledgement);
295 $clearingEvents[] = $clearingEventCache[$eventId];
301 $clearingsWithLicensesArray[] = $clearingDecisionBuilder->setClearingEvents($clearingEvents)->build();
305 return $clearingsWithLicensesArray;
315 if (count($clearingDecisions) > 0) {
316 return $clearingDecisions[0];
327 $sql =
"DELETE FROM clearing_decision WHERE uploadtree_fk=$1 AND group_fk=$2 AND decision_type=$3";
328 $this->
dbManager->prepare($stmt = __METHOD__, $sql);
329 $this->
dbManager->freeResult($this->
dbManager->execute($stmt, array($uploadTreeId, $groupId, DecisionTypes::WIP)));
341 if ( ($scope == DecisionScopes::REPO) &&
343 throw new \Exception( _(
"Cannot add candidate license as global decision\n") );
346 $itemTreeBounds = $this->uploadDao->getItemTreeBounds($uploadTreeId);
348 $uploadTreeTable = $this->uploadDao->getUploadtreeTableName($uploadId);
349 $itemTreeBounds = $this->uploadDao->getItemTreeBounds($uploadTreeId, $uploadTreeTable);
351 if ($this->
isDecisionCheck($uploadTreeId, $groupId, DecisionTypes::IRRELEVANT)) {
352 $this->copyrightDao->updateTable($itemTreeBounds,
'',
'', $userId,
'copyright',
'rollback');
353 }
else if ($decType == DecisionTypes::IRRELEVANT) {
354 $this->copyrightDao->updateTable($itemTreeBounds,
'',
'', $userId,
'copyright',
'delete',
'2');
361 $statementName = __METHOD__;
362 $this->
dbManager->prepare($statementName,
364 INSERT INTO clearing_decision (
373 (SELECT pfile_fk FROM ". $uploadTreeTable .
" WHERE uploadtree_pk=$1),
377 $5) RETURNING clearing_decision_pk
379 $res = $this->
dbManager->execute($statementName,
380 array($uploadTreeId, $userId, $groupId, $decType, $scope));
381 $result = $this->
dbManager->fetchArray($res);
382 $clearingDecisionId = $result[
'clearing_decision_pk'];
385 $statementNameClearingDecisionEventInsert = __METHOD__ .
".insertClearingDecisionEvent";
386 $this->
dbManager->prepare($statementNameClearingDecisionEventInsert,
387 "INSERT INTO clearing_decision_event (clearing_decision_fk, clearing_event_fk) VALUES($1, $2)"
390 foreach ($eventIds as $eventId) {
391 $this->
dbManager->freeResult($this->
dbManager->execute($statementNameClearingDecisionEventInsert, array($clearingDecisionId, $eventId)));
404 $decision = $this->
getFileClearingsFolder($itemTreeBounds, $groupId, $includeSubFolders, $onlyCurrent=
true);
408 if (count($decision)) {
409 foreach ($decision[0]->getClearingEvents() as $event) {
410 $events[$event->getLicenseId()] = $event;
412 $date = $decision[0]->getTimeStamp();
416 $sql =
'SELECT rf_fk,rf_shortname,rf_spdx_id,rf_fullname,clearing_event_pk,comment,type_fk,removed,reportinfo,acknowledgement, EXTRACT(EPOCH FROM date_added) AS ts_added
417 FROM clearing_event LEFT JOIN license_ref ON rf_fk=rf_pk
418 WHERE uploadtree_fk=$1 AND group_fk=$2 AND date_added>to_timestamp($3)
419 ORDER BY clearing_event_pk ASC';
421 $res = $this->
dbManager->execute($stmt,array($itemTreeBounds->
getItemId(),$groupId,$date));
423 while ($row = $this->
dbManager->fetchArray($res)) {
424 $licenseRef =
new LicenseRef($row[
'rf_fk'],$row[
'rf_shortname'],$row[
'rf_fullname'],$row[
'rf_spdx_id']);
425 $events[$row[
'rf_fk']] = ClearingEventBuilder::create()
426 ->setEventId($row[
'clearing_event_pk'])
427 ->setComment($row[
'comment'])
428 ->setTimeStamp($row[
'ts_added'])
429 ->setEventType($row[
'type_fk'])
430 ->setLicenseRef($licenseRef)
431 ->setRemoved($this->
dbManager->booleanFromDb($row[
'removed']))
432 ->setReportinfo($row[
'reportinfo'])
433 ->setAcknowledgement($row[
'acknowledgement'])
434 ->setUploadTreeId($itemTreeBounds->
getItemId())
453 $statementGetOldata =
"SELECT * FROM clearing_event WHERE uploadtree_fk=$1 AND rf_fk=$2 AND group_fk=$3 ORDER BY clearing_event_pk DESC LIMIT 1";
454 $statementName = __METHOD__ .
'getOld';
455 $params = array($uploadTreeId, $licenseId, $groupId);
456 $row = $this->
dbManager->getSingleRow($statementGetOldata, $params, $statementName);
459 $type = ClearingEventTypes::USER;
460 $row[
'type_fk'] = $type;
461 $row[
'comment'] =
"";
462 $row[
'reportinfo'] =
"";
463 $row[
'acknowledgement'] =
"";
467 if ($what ==
'reportinfo') {
468 $reportInfo = $changeTo;
469 $comment = $row[
'comment'];
470 $acknowledgement = $row[
'acknowledgement'];
471 } elseif ($what ==
'comment') {
472 $reportInfo = $row[
'reportinfo'];
473 $comment = $changeTo;
474 $acknowledgement = $row[
'acknowledgement'];
476 $reportInfo = $row[
'reportinfo'];
477 $comment = $row[
'comment'];
478 $acknowledgement = $changeTo;
480 $this->
insertClearingEvent($uploadTreeId, $userId, $groupId, $licenseId,
false, $row[
'type_fk'], $reportInfo, $comment, $acknowledgement);
486 public function copyEventIdTo($eventId, $itemId, $userId, $groupId)
490 "INSERT INTO clearing_event(uploadtree_fk, user_fk, group_fk, type_fk, rf_fk, removed, reportinfo, comment, acknowledgement)
491 SELECT $2, $3, $4, type_fk, rf_fk, removed, reportinfo, comment, acknowledgement FROM clearing_event WHERE clearing_event_pk = $1"
494 $this->
dbManager->freeResult($this->
dbManager->execute($stmt, array($eventId, $itemId, $userId, $groupId)));
509 public function insertClearingEvent($uploadTreeId, $userId, $groupId, $licenseId, $isRemoved, $type = ClearingEventTypes::USER, $reportInfo =
'', $comment =
'', $acknowledgement =
'', $jobId=0)
511 $insertIsRemoved = $this->
dbManager->booleanToDb($isRemoved);
518 $params = array($uploadTreeId, $userId, $groupId, $type, $licenseId, $insertIsRemoved, $reportInfo, $comment, $acknowledgement);
519 $columns =
"uploadtree_fk, user_fk, group_fk, type_fk, rf_fk, removed, reportinfo, comment, acknowledgement";
520 $values =
"$1,$2,$3,$4,$5,$6,$7,$8,$9";
525 $columns .=
", job_fk";
526 $values .=
",$".count($params);
531 $this->
dbManager->prepare($stmt,
"INSERT INTO clearing_event ($columns) VALUES($values) RETURNING clearing_event_pk");
532 $res = $this->
dbManager->execute($stmt, $params);
534 $row = $this->
dbManager->fetchArray($res);
537 return intval($row[
'clearing_event_pk']);
546 $statementName = __METHOD__;
549 "SELECT uploadtree_fk, clearing_event_pk, rf_fk FROM clearing_event WHERE job_fk = $1"
552 $res = $this->
dbManager->execute($statementName, array($jobId));
555 while ($row = $this->
dbManager->fetchArray($res)) {
556 $itemId = intval($row[
'uploadtree_fk']);
557 $eventId = intval($row[
'clearing_event_pk']);
558 $licenseId = intval($row[
'rf_fk']);
560 $events[$itemId][$licenseId] = $eventId;
579 protected function buildClearingEvent($eventId, $userId, $groupId, $licenseRef, $licenseIsRemoved, $type, $reportInfo, $comment, $acknowledgement)
581 $removed = $this->
dbManager->booleanFromDb($licenseIsRemoved);
583 return ClearingEventBuilder::create()
584 ->setEventId($eventId)
586 ->setGroupId($groupId)
587 ->setEventType($type)
588 ->setLicenseRef($licenseRef)
589 ->setRemoved($removed)
590 ->setReportInfo($reportInfo)
591 ->setAcknowledgement($acknowledgement)
592 ->setComment($comment)
603 $statementName = __METHOD__;
605 $this->
dbManager->prepare($statementName,
606 "INSERT INTO clearing_decision (uploadtree_fk,pfile_fk,user_fk,group_fk,decision_type,scope) VALUES (
607 $1, (SELECT pfile_fk FROM uploadtree WHERE uploadtree_pk=$1), $2, $3, $4, $5)");
608 $res = $this->
dbManager->execute($statementName,
609 array($uploadTreeId, $userId, $groupId, DecisionTypes::WIP, DecisionScopes::ITEM));
620 $columns =
"decision_type";
621 if (!in_array($decisionType,
622 [DecisionTypes::WIP, DecisionTypes::TO_BE_DISCUSSED,
623 DecisionTypes::DO_NOT_USE, DecisionTypes::IRRELEVANT,
624 DecisionTypes::NON_FUNCTIONAL])
626 $columns =
"decision_type, scope";
628 $sql =
"SELECT $columns FROM clearing_decision
629 WHERE uploadtree_fk=$1 AND group_fk = $2
630 ORDER BY clearing_decision_pk DESC LIMIT 1";
631 $latestDec = $this->
dbManager->getSingleRow($sql,
632 array($uploadTreeId, $groupId), $sqlLog = __METHOD__);
634 if ($latestDec ===
false) {
636 }
else if ($decisionType !==
"") {
637 return ($latestDec[
'decision_type'] == $decisionType);
654 $left = $itemTreeBound->
getLeft();
656 $params = array($uploadId, $itemId, $left, $groupId);
657 $stmt = __METHOD__ .
"." . $uploadTreeTableName;
659 $triedExpr =
"$3 between ut2.lft and ut2.rgt";
662 $triedFilter =
"and " . $triedExpr;
666 $sql =
"WITH relevant_bulks AS MATERIALIZED (
667 SELECT lr.lrb_pk, $triedExpr AS tried
668 FROM license_ref_bulk lr
669 INNER JOIN $uploadTreeTableName ut2 ON ut2.uploadtree_pk = lr.uploadtree_fk
670 WHERE ut2.upload_fk = $1 AND lr.group_fk = $4
673 SELECT rb.lrb_pk, ce.clearing_event_pk ce_pk, ce.uploadtree_fk, rb.tried
674 FROM relevant_bulks rb
675 LEFT JOIN highlight_bulk h ON h.lrb_fk = rb.lrb_pk
676 LEFT JOIN clearing_event ce ON ce.clearing_event_pk = h.clearing_event_fk
677 ), aggregated_tried AS (
678 SELECT DISTINCT ON(lrb_pk) lrb_pk, ce_pk, tried, matched
680 SELECT DISTINCT ON(lrb_pk) lrb_pk, ce_pk, tried, true AS matched FROM alltried WHERE uploadtree_fk = $2
682 SELECT DISTINCT ON(lrb_pk) lrb_pk, ce_pk, tried, false AS matched FROM alltried WHERE uploadtree_fk != $2 OR uploadtree_fk IS NULL
683 ) AS result ORDER BY lrb_pk, matched DESC)
684 SELECT a.lrb_pk, lr.rf_text AS text, lrf.rf_shortname, lsb.removing, a.tried, a.ce_pk, a.matched
685 FROM aggregated_tried a
686 INNER JOIN license_set_bulk lsb ON lsb.lrb_fk = a.lrb_pk
687 INNER JOIN license_ref lrf ON lsb.rf_fk = lrf.rf_pk
688 INNER JOIN license_ref_bulk lr ON lr.lrb_pk = a.lrb_pk
692 $res = $this->
dbManager->execute($stmt, $params);
695 while ($row = $this->
dbManager->fetchArray($res)) {
696 $bulkRun = $row[
'lrb_pk'];
697 if (!array_key_exists($bulkRun, $bulks)) {
698 $bulks[$bulkRun] = array(
699 "bulkId" => $row[
'lrb_pk'],
700 "id" => $row[
'ce_pk'],
701 "text" => $row[
'text'],
702 "matched" => $this->
dbManager->booleanFromDb($row[
'matched']),
703 "tried" => $this->dbManager->booleanFromDb($row[
'tried']),
704 "removedLicenses" => array(),
705 "addedLicenses" => array());
707 $key = $this->
dbManager->booleanFromDb($row[
'removing']) ?
'removedLicenses' :
'addedLicenses';
708 $bulks[$bulkRun][$key][] = $row[
'rf_shortname'];
716 public function getBulkMatches($bulkId, $groupId)
719 $sql =
"SELECT uploadtree_fk AS itemid
720 FROM clearing_event ce
721 INNER JOIN highlight_bulk h
722 ON ce.clearing_event_pk = h.clearing_event_fk
723 WHERE lrb_fk = $1 AND group_fk = $2";
726 $res = $this->
dbManager->execute($stmt, array($bulkId, $groupId));
728 $result = $this->
dbManager->fetchAll($res);
742 $left = $itemTreeBound->
getLeft();
743 $right = $itemTreeBound->
getRight();
745 $stmt = __METHOD__ .
"." . $uploadTreeTableName;
746 $sql =
"SELECT COUNT(*) FROM clearing_event ce
747 INNER JOIN $uploadTreeTableName ut ON ut.uploadtree_pk = ce.uploadtree_fk
748 WHERE ce.type_fk = " . ClearingEventTypes::KOTOBA .
"
750 AND ut.upload_fk = $2
751 AND ut.lft BETWEEN $3 AND $4";
754 $res = $this->
dbManager->execute($stmt, array($groupId, $uploadId, $left, $right));
755 $row = $this->
dbManager->fetchArray($res);
758 return ($row && intval($row[
'count']) > 0);
772 $left = $itemTreeBound->
getLeft();
773 $right = $itemTreeBound->
getRight();
775 $params = array($uploadId, $itemId, $left, $right, $groupId);
776 $stmt = __METHOD__ .
"." . $uploadTreeTableName;
778 $triedExpr =
"ut2.lft BETWEEN $3 AND $4";
781 $triedFilter =
"AND " . $triedExpr;
785 $kotobaType = ClearingEventTypes::KOTOBA;
786 $sql =
"WITH alltried AS (
787 SELECT ce.reportinfo, ce.clearing_event_pk ce_pk, ce.uploadtree_fk,
789 FROM clearing_event ce
790 INNER JOIN $uploadTreeTableName ut ON ut.uploadtree_pk = ce.uploadtree_fk
791 INNER JOIN $uploadTreeTableName ut2 ON ut2.uploadtree_pk = ce.uploadtree_fk
792 WHERE ce.type_fk = $kotobaType
794 AND ut.upload_fk = $1
795 AND ce.reportinfo IS NOT NULL
796 AND ce.reportinfo != ''
798 ORDER BY ce.reportinfo, ce.clearing_event_pk
799 ), aggregated_tried AS (
800 SELECT DISTINCT ON(reportinfo) reportinfo AS text, ce_pk, tried, matched
802 SELECT DISTINCT ON(reportinfo) reportinfo, ce_pk, tried, true AS matched FROM alltried WHERE uploadtree_fk = $2
804 SELECT DISTINCT ON(reportinfo) reportinfo, ce_pk, tried, false AS matched FROM alltried WHERE uploadtree_fk != $2 OR uploadtree_fk IS NULL
805 ) AS result ORDER BY reportinfo, matched DESC)
806 SELECT aggregated_tried.text, lrf.rf_shortname, ce.removed, aggregated_tried.tried, aggregated_tried.ce_pk, aggregated_tried.matched
807 FROM aggregated_tried
808 INNER JOIN clearing_event ce ON ce.reportinfo = aggregated_tried.text AND ce.type_fk = $kotobaType AND ce.group_fk = $5
809 INNER JOIN license_ref lrf ON ce.rf_fk = lrf.rf_pk
810 INNER JOIN $uploadTreeTableName ut ON ut.uploadtree_pk = ce.uploadtree_fk
811 WHERE ut.upload_fk = $1
812 ORDER BY aggregated_tried.text, ce.clearing_event_pk";
815 $res = $this->
dbManager->execute($stmt, $params);
818 while ($row = $this->
dbManager->fetchArray($res)) {
819 $phraseText = $row[
'text'];
820 $phraseId = md5($phraseText);
822 if (!array_key_exists($phraseId, $phrases)) {
823 $phrases[$phraseId] = array(
824 "phraseId" => $phraseId,
825 "id" => $row[
'ce_pk'],
826 "text" => $phraseText,
827 "matched" => $this->
dbManager->booleanFromDb($row[
'matched']),
828 "tried" => $this->dbManager->booleanFromDb($row[
'tried']),
829 "removedLicenses" => array(),
830 "addedLicenses" => array());
832 $key = $this->
dbManager->booleanFromDb($row[
'removed']) ?
'removedLicenses' :
'addedLicenses';
833 if (!in_array($row[
'rf_shortname'], $phrases[$phraseId][$key])) {
834 $phrases[$phraseId][$key][] = $row[
'rf_shortname'];
849 $statementName = __METHOD__;
851 $params = array($itemTreeBounds->
getLeft(), $itemTreeBounds->
getRight());
852 $condition =
"ut.lft BETWEEN $1 AND $2";
854 $decisionsCte = $this->getRelevantDecisionsCte($itemTreeBounds, $groupId, $onlyCurrent=
true, $statementName, $params, $condition);
855 $params[] = DecisionTypes::IRRELEVANT;
856 $sql =
"$decisionsCte
858 COUNT(DISTINCT itemid) AS count,
859 lr.rf_shortname AS shortname,
860 lr.rf_spdx_id AS spdx_id,
863 LEFT JOIN clearing_decision_event cde ON cde.clearing_decision_fk = decision.id
864 LEFT JOIN clearing_event ce ON ce.clearing_event_pk = cde.clearing_event_fk
865 LEFT JOIN license_ref lr ON lr.rf_pk = ce.rf_fk
866 WHERE (NOT ce.removed OR clearing_event_pk IS NULL) AND type_id!=$".count($params).
"
867 GROUP BY shortname,rf_pk,spdx_id";
869 $this->
dbManager->prepare($statementName, $sql);
870 $res = $this->
dbManager->execute($statementName, $params);
871 $multiplicity = array();
872 while ($row = $this->
dbManager->fetchArray($res)) {
873 $shortname = empty($row[
'rf_pk']) ? LicenseDao::NO_LICENSE_FOUND : $row[
'shortname'];
875 $multiplicity[$shortname] = $row;
879 return $multiplicity;
888 if ($decisionType ==
"doNotUse" || $decisionType ==
"deleteDoNotUse") {
889 return DecisionTypes::DO_NOT_USE;
890 }
else if ($decisionType ==
"irrelevant" || $decisionType ==
"deleteIrrelevant") {
891 return DecisionTypes::IRRELEVANT;
893 return DecisionTypes::NON_FUNCTIONAL;
906 $this->markDirectoryAsDecisionTypeRec($itemTreeBounds, $groupId, $userId,
false, $decisionMark);
918 $this->markDirectoryAsDecisionTypeRec($itemTreeBounds, $groupId, $userId,
true, $decisionMark);
928 protected function markDirectoryAsDecisionTypeRec(
ItemTreeBounds $itemTreeBounds, $groupId, $userId, $removeDecision=
false, $decisionMark=DecisionTypes::IRRELEVANT)
930 $params = array($itemTreeBounds->
getLeft(), $itemTreeBounds->
getRight());
931 $params[] = $groupId;
935 UploadTreeProxy::OPT_SKIP_THESE =>
'nolicensenocopyright',
936 UploadTreeProxy::OPT_ITEM_FILTER =>
' AND (lft BETWEEN $1 AND $2)',
937 UploadTreeProxy::OPT_GROUP_ID =>
'$' . $a
940 if (!$removeDecision) {
941 $sql = $uploadTreeProxy->asCTE() .
942 ' SELECT uploadtree_pk, upload_fk, lft, rgt FROM UploadTreeView;';
943 $itemRows = $this->
dbManager->getRows($sql, $params,
944 __METHOD__ .
".getRevelantItems");
947 $clearingDecisionEventProcessor = $GLOBALS[
'container']->get(
948 'businessrules.clearing_decision_processor');
949 foreach ($itemRows as $itemRow) {
951 $itemRow[
'uploadtree_pk'], $uploadTreeTableName,
952 $itemRow[
'upload_fk'], $itemRow[
'lft'], $itemRow[
'rgt']);
953 $clearingDecisionEventProcessor->makeDecisionFromLastEvents(
954 $itemBounds, $userId, $groupId, $decisionMark, DecisionScopes::ITEM);
958 $params[] = $decisionMark;
959 $sql = $uploadTreeProxy->asCTE() .
960 ' DELETE FROM clearing_decision WHERE clearing_decision_pk IN (
961 SELECT clearing_decision_pk FROM clearing_decision cd
963 SELECT MAX(date_added) AS date_added, uploadtree_fk
964 FROM clearing_decision WHERE uploadtree_fk IN (
965 SELECT uploadtree_pk FROM UploadTreeView)
966 GROUP BY uploadtree_fk) cd2
967 ON cd.uploadtree_fk = cd2.uploadtree_fk
968 AND cd.date_added = cd2.date_added
969 AND decision_type = $' . ($a + 1) .
')
970 RETURNING clearing_decision_pk;';
971 $clearingDecisionRows = $this->
dbManager->getRows($sql, $params,
972 __METHOD__ .
".getRelevantDecisions");
973 $clearingDecisions = array_map(
function($x) {
974 return $x[
'clearing_decision_pk'];
975 }, $clearingDecisionRows);
976 $clearingDecisions =
"{" . join(
",", $clearingDecisions) .
"}";
978 $delEventSql =
"DELETE FROM clearing_event WHERE clearing_event_pk IN (" .
979 "SELECT clearing_event_fk FROM clearing_decision_event " .
980 "WHERE clearing_decision_fk = ANY($1::int[]));";
981 $this->
dbManager->getSingleRow($delEventSql, array($clearingDecisions),
982 __METHOD__ .
".deleteEvent");
984 $delCdEventSql =
"DELETE FROM clearing_decision_event WHERE " .
985 "clearing_decision_fk = ANY($1::int[]);";
986 $this->
dbManager->getSingleRow($delCdEventSql, array($clearingDecisions),
987 __METHOD__ .
".deleteCdEvent");
989 $this->copyrightDao->updateTable($itemTreeBounds,
'',
'', $userId,
990 'copyright',
'rollback');
1002 $sql =
"SELECT rf_fk FROM upload_clearing_license WHERE upload_fk=$1 AND group_fk=$2";
1004 $res = $this->
dbManager->execute($stmt,array($uploadId,$groupId));
1006 while ($row = $this->
dbManager->fetchArray($res)) {
1007 $ids[$row[
'rf_fk']] = $row[
'rf_fk'];
1022 $uploadTreeTableName = $this->uploadDao->getUploadtreeTableName($uploadId);
1023 $statementName = __METHOD__;
1024 $sql =
"SELECT DISTINCT ON (ce.rf_fk)
1025 ce.rf_fk AS license_id,
1027 FROM $uploadTreeTableName ut
1028 INNER JOIN clearing_event ce ON ce.uploadtree_fk = ut.uploadtree_pk
1029 WHERE ut.upload_fk = \$1
1030 AND ce.group_fk = \$2
1032 AND ce.reportinfo IS NOT NULL
1033 AND ce.reportinfo <> ''
1034 ORDER BY ce.rf_fk, ce.date_added DESC, ce.clearing_event_pk DESC";
1035 $this->
dbManager->prepare($statementName, $sql);
1036 $result = $this->
dbManager->execute($statementName, array($uploadId, $groupId));
1037 $reportInfos = array();
1038 while ($row = $this->
dbManager->fetchArray($result)) {
1039 $reportInfos[intval($row[
'license_id'])] = $row[
'reportinfo'];
1042 return $reportInfos;
1052 $this->
dbManager->insertTableRow(
'upload_clearing_license',
1053 array(
'upload_fk'=>$uploadId,
'group_fk'=>$groupId,
'rf_fk'=>$licenseId));
1063 $this->
dbManager->getSingleRow(
'DELETE FROM upload_clearing_license WHERE upload_fk=$1 AND group_fk=$2 AND rf_fk=$3',
1064 array($uploadId,$groupId,$licenseId));
1077 $statementName = __METHOD__;
1079 $decisionsCte = $this->getRelevantDecisionsCte($itemTreeBounds, $groupId, $onlyCurrent, $statementName, $params);
1080 $params[] = $decisionMark;
1081 $sql =
"$decisionsCte
1083 itemid as uploadtree_pk,
1084 lr.rf_shortname AS shortname,
1085 lr.rf_spdx_id AS spdx_id,
1088 LEFT JOIN clearing_decision_event cde ON cde.clearing_decision_fk = decision.id
1089 LEFT JOIN clearing_event ce ON ce.clearing_event_pk = cde.clearing_event_fk
1090 LEFT JOIN license_ref lr ON lr.rf_pk = ce.rf_fk
1091 WHERE type_id=$".count($params);
1092 $this->
dbManager->prepare($statementName, $sql);
1093 $res = $this->
dbManager->execute($statementName, $params);
1094 $irrelevantFiles = $this->
dbManager->fetchAll($res);
1096 return $irrelevantFiles;
1108 $sql =
"SELECT jq_args FROM upload_reuse, jobqueue, job
1109 WHERE upload_fk=$1 AND group_fk=$2
1110 AND EXISTS(SELECT * FROM group_user_member gum WHERE gum.group_fk=upload_reuse.group_fk AND gum.user_fk=$3)
1111 AND jq_type=$4 AND jq_job_fk=job_pk
1112 AND job_upload_fk=reused_upload_fk AND job_group_fk=reused_group_fk";
1114 $res = $this->
dbManager->execute($stmt,array($uploadId, $groupId, $userId,
'monkbulk'));
1115 while ($row= $this->
dbManager->fetchArray($res)) {
1116 $bulkIds = array_merge($bulkIds,explode(
"\n", $row[
'jq_args']));
1119 if (empty($onlyCount)) {
1120 return array_unique($bulkIds);
1122 return count(array_unique($bulkIds));
1133 if (!empty($uploadId)) {
1134 $uploadTreeTableName = $this->uploadDao->getUploadtreeTableName($uploadId);
1135 $itemTreeBounds = $this->uploadDao->getParentItemBounds($uploadId, $uploadTreeTableName);
1136 $params[] = $itemTreeBounds->
getLeft();
1137 $params[] = $itemTreeBounds->
getRight();
1138 $condition =
"UT.lft BETWEEN $1 AND $2";
1139 $uploadtreeStatement =
" uploadtree_fk IN (SELECT uploadtree_pk FROM $uploadTreeTableName UT WHERE $condition)";
1141 $params = array($uploadTreeId);
1142 $uploadtreeStatement =
" uploadtree_fk = $1";
1145 $sql =
"WITH latestEvents AS (
1146 SELECT rf_fk, date_added, removed FROM (
1147 SELECT rf_fk, date_added, removed, row_number()
1148 OVER (PARTITION BY rf_fk ORDER BY date_added DESC) AS ROWNUM
1149 FROM clearing_event WHERE $uploadtreeStatement) SORTABLE
1150 WHERE ROWNUM = 1 ORDER BY rf_fk)
1151 SELECT count(*) FROM license_candidate WHERE license_candidate.rf_pk IN
1152 (SELECT rf_fk FROM latestEvents WHERE removed=false);";
1153 $countCandidate = $this->
dbManager->getSingleRow($sql,
1154 $params, $sqlLog = __METHOD__);
1156 return $countCandidate[
'count'];
1165 $statementName = __METHOD__ . $uploadId;
1167 $sql =
"WITH latestDecisions AS (
1168 SELECT clearing_decision_pk FROM (
1169 SELECT clearing_decision_pk, uploadtree_fk, date_added, row_number()
1170 OVER (PARTITION BY uploadtree_fk ORDER BY date_added DESC) AS ROWNUM
1171 FROM clearing_decision WHERE uploadtree_fk IN
1172 (SELECT uploadtree_pk FROM uploadtree WHERE upload_fk = $1)) SORTABLE
1173 WHERE ROWNUM = $2 ORDER BY uploadtree_fk)
1174 UPDATE clearing_decision SET scope = $2 WHERE clearing_decision_pk IN (
1175 SELECT clearing_decision_pk FROM latestDecisions) RETURNING clearing_decision_pk";
1177 $countUpdated = $this->
dbManager->getRows($sql,
1178 array($uploadId, DecisionScopes::REPO), $statementName);
1180 return count($countUpdated);
Utility functions to process ClearingDecision.
buildClearingEvent($eventId, $userId, $groupId, $licenseRef, $licenseIsRemoved, $type, $reportInfo, $comment, $acknowledgement)
getFileClearings(ItemTreeBounds $itemTreeBounds, $groupId, $onlyCurrent=true, $forClearingHistory=false)
deleteDecisionTypeFromDirectory(ItemTreeBounds $itemTreeBounds, $groupId, $userId, $decisionMark)
getMainLicenseReportInfos($uploadId, $groupId)
getDecisionType($decisionType)
updateClearingEvent($uploadTreeId, $userId, $groupId, $licenseId, $what, $changeTo)
markDirectoryAsDecisionType(ItemTreeBounds $itemTreeBounds, $groupId, $userId, $decisionMark)
createDecisionFromEvents($uploadTreeId, $userId, $groupId, $decType, $scope, $eventIds)
getClearedLicenses(ItemTreeBounds $itemTreeBounds, $groupId)
markDecisionAsWip($uploadTreeId, $userId, $groupId)
removeMainLicense($uploadId, $groupId, $licenseId)
getRelevantClearingDecision(ItemTreeBounds $itemTreeBounds, $groupId)
isDecisionCheck($uploadTreeId, $groupId, $decisionType)
makeMainLicense($uploadId, $groupId, $licenseId)
getRelevantClearingEvents($itemTreeBounds, $groupId, $includeSubFolders=true)
marklocalDecisionsAsGlobal($uploadId)
getMainLicenseIds($uploadId, $groupId)
getPreviousBulkIds($uploadId, $groupId, $userId, $onlyCount=0)
__construct(DbManager $dbManager, UploadDao $uploadDao)
getBulkHistory(ItemTreeBounds $itemTreeBound, $groupId, $onlyTried=true)
getFileClearingsFolder(ItemTreeBounds $itemTreeBounds, $groupId, $includeSubFolders=true, $onlyCurrent=true)
getClearedLicenseIdAndMultiplicities(ItemTreeBounds $itemTreeBounds, $groupId)
getDecisionsFromCte($decisionsCte, $statementName, $params, $forClearingHistory=false)
hasKotobaFindings(ItemTreeBounds $itemTreeBound, $groupId)
getCandidateLicenseCountForCurrentDecisions($uploadTreeId, $uploadId=0)
getFilesForDecisionTypeFolderLevel(ItemTreeBounds $itemTreeBounds, $groupId, $onlyCurrent=true, $decisionMark="")
insertClearingEvent($uploadTreeId, $userId, $groupId, $licenseId, $isRemoved, $type=ClearingEventTypes::USER, $reportInfo='', $comment='', $acknowledgement='', $jobId=0)
removeWipClearingDecision($uploadTreeId, $groupId)
getKotobaHistory(ItemTreeBounds $itemTreeBound, $groupId, $onlyTried=true)
static convertToSpdxId($shortname, $spdxId)
Given a license's shortname and spdx id, give out spdx id to use in reports.
static replaceUnicodeControlChar($input, $replace="")
fo_dbManager * dbManager
fo_dbManager object