FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ajax-copyright-hist.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2019, 2022, Siemens AG
4  Author: Daniele Fognini, Johannes Najjar, Steffen Weber, Shaheem Azmal M MD
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
15 use Symfony\Component\HttpFoundation\JsonResponse;
16 use Symfony\Component\HttpFoundation\Response;
17 
18 define("TITLE_COPYRIGHTHISTOGRAMPROCESSPOST", _("Private: Browse post"));
19 
25 {
29  protected $listPage;
33  private $uploadtree_tablename;
37  private $dbManager;
41  private $uploadDao;
45  private $copyrightDao;
46 
50  private $dataTablesUtility;
51 
55  private $textFindingTypes = ["copyFindings"];
56 
57  function __construct()
58  {
59  $this->Name = "ajax-copyright-hist";
60  $this->Title = TITLE_COPYRIGHTHISTOGRAMPROCESSPOST;
61  $this->DBaccess = PLUGIN_DB_READ;
62  $this->OutputType = 'JSON';
63  $this->LoginFlag = 0;
64  $this->NoMenu = 0;
65 
66  parent::__construct();
67  global $container;
68  $this->dataTablesUtility = $container->get('utils.data_tables_utility');
69  $this->uploadDao = $container->get('dao.upload');
70  $this->dbManager = $container->get('db.manager');
71  $this->copyrightDao = $container->get('dao.copyright');
72  }
73 
74 
79  function Output()
80  {
81  $returnValue = 0;
82  if ($this->State != PLUGIN_STATE_READY) {
83  return 0;
84  }
85 
86  $action = GetParm("action", PARM_STRING);
87  $upload = GetParm("upload", PARM_INTEGER);
88  $type = GetParm("type", PARM_STRING);
89 
90  if ($action=="deletedecision" || $action=="undodecision") {
91  $decision = GetParm("decision", PARM_INTEGER);
92  $pfile = GetParm("pfile", PARM_INTEGER);
93  } elseif ($action=="deleteHashDecision" || $action=="undoHashDecision") {
94  $hash = GetParm("hash", PARM_STRING);
95  } elseif ($action=="update" || $action=="delete" || $action=="undo") {
96  $id = GetParm("id", PARM_STRING);
97  $getEachID = array_filter(explode(",", trim($id, ',')), function($var) {
98  return $var !== "";
99  });
100  if (count($getEachID) == 4) {
101  list($upload, $item, $hash, $type) = $getEachID;
102  } else {
103  return new Response('bad request while '.$action,
104  Response::HTTP_BAD_REQUEST,
105  array('Content-type'=>'text/plain')
106  );
107  }
108  }
109 
110  /* check upload permissions */
111  if (!(($action == "getData" || $action == "getDeactivatedData") &&
112  ($this->uploadDao->isAccessible($upload, Auth::getGroupId())) ||
113  ($this->uploadDao->isEditable($upload, Auth::getGroupId())))) {
114  $permDeniedText = _("Permission Denied");
115  $returnValue = "<h2>$permDeniedText</h2>";
116  }
117  $this->uploadtree_tablename = $this->uploadDao->getUploadtreeTableName(
118  $upload);
119 
120  if (in_array($type, $this->textFindingTypes) &&
121  ($action == "getData" || $action == "getDeactivatedData")) {
122  $textFindingsHandler = new TextFindingsAjax($this->uploadtree_tablename);
123  if ($action == "getData") {
124  $returnValue = $textFindingsHandler->doGetData($type, $upload);
125  } elseif ($action == "getDeactivatedData") {
126  $returnValue = $textFindingsHandler->doGetData($type, $upload, false);
127  }
128  } else {
129  switch ($action) {
130  case "getData":
131  $returnValue = $this->doGetData($upload);
132  break;
133  case "getDeactivatedData":
134  $returnValue = $this->doGetData($upload, false);
135  break;
136  case "update":
137  $returnValue = $this->doUpdate($item, $hash, $type);
138  break;
139  case "delete":
140  $returnValue = $this->doDelete($item, $hash, $type);
141  break;
142  case "undo":
143  $returnValue = $this->doUndo($item, $hash, $type);
144  break;
145  case "deletedecision":
146  $returnValue = $this->doDeleteDecision($decision, $pfile, $type);
147  break;
148  case "undodecision":
149  $returnValue = $this->doUndoDecision($decision, $pfile, $type);
150  break;
151  case "deleteHashDecision":
152  $returnValue = $this->doDeleteHashDecision($hash, $upload, $type);
153  break;
154  case "undoHashDecision":
155  $returnValue = $this->doUndoHashDecision($hash, $upload, $type);
156  break;
157  default:
158  $returnValue = "<h2>" . _("Unknown action") . "</h2>";
159  }
160  }
161  return $returnValue;
162  }
163 
173  protected function doGetData($upload, $activated = true)
174  {
175  $item = GetParm("item", PARM_INTEGER);
176  $agent_pk = GetParm("agent", PARM_STRING);
177  $type = GetParm("type", PARM_STRING);
178  $filter = GetParm("filter", PARM_STRING);
179  $listPage = "copyright-list";
180 
181  header('Content-type: text/json');
182  list($aaData, $iTotalRecords, $iTotalDisplayRecords) = $this->getTableData($upload, $item, $agent_pk, $type,$listPage, $filter, $activated);
183  return new JsonResponse(array(
184  'sEcho' => intval($_GET['sEcho']),
185  'aaData' => $aaData,
186  'iTotalRecords' => $iTotalRecords,
187  'iTotalDisplayRecords' => $iTotalDisplayRecords
188  )
189  );
190  }
191 
203  private function getTableData($upload, $item, $agent_pk, $type, $listPage, $filter, $activated = true)
204  {
205  $offset = GetParm('iDisplayStart', PARM_INTEGER);
206  $limit = GetParm('iDisplayLength', PARM_INTEGER);
207  list ($rows, $iTotalDisplayRecords, $iTotalRecords) = $this->getCopyrights($upload, $item, $this->uploadtree_tablename, $agent_pk, $type, $filter, $activated, $offset, $limit);
208  $aaData = array();
209  if (!empty($rows)) {
210  $rw = $this->uploadDao->isEditable($upload, Auth::getGroupId());
211  foreach ($rows as $row) {
212  $aaData [] = $this->fillTableRow($row, $item, $upload, $agent_pk, $type,$listPage, $filter, $activated, $rw);
213  }
214  }
215 
216  return array($aaData, $iTotalRecords, $iTotalDisplayRecords);
217 
218  }
219 
231  public function getCopyrights($upload_pk, $item, $uploadTreeTableName, $agentId, $type, $filter, $activated = true, $offset = null , $limit = null)
232  {
233  $tableName = $this->getTableName($type);
234  $tableNameEvent = $tableName.'_event';
235  $orderString = $this->getOrderString();
236 
237  list($left, $right) = $this->uploadDao->getLeftAndRight($item, $uploadTreeTableName);
238 
239  if ($filter == "") {
240  $filter = "none";
241  }
242 
243  $sql_upload = "";
244  if ('uploadtree_a' == $uploadTreeTableName) {
245  $sql_upload = " AND UT.upload_fk=$5 ";
246  }
247 
248  $join = "";
249  $filterQuery = "";
250  if (($type == 'statement' || $type == 'scancode_statement') && $filter == "nolic") {
251  $noLicStr = "No_license_found";
252  $voidLicStr = "Void";
253  $join = " INNER JOIN license_file AS LF on cp.pfile_fk=LF.pfile_fk ";
254  $filterQuery = " AND LF.rf_fk IN (SELECT rf_pk FROM license_ref WHERE rf_shortname IN ('$noLicStr','$voidLicStr')) ";
255  } else {
256  // No filter, nothing to do
257  }
258  $params = array($left, $right, $type, "{" . $agentId . "}", $upload_pk);
259 
260  $filterParms = $params;
261  $searchFilter = $this->addSearchFilter($filterParms);
262 
263  $activatedClause = "ce.is_enabled = 'false'";
264  if ($activated) {
265  $activatedClause = "ce.is_enabled IS NULL OR ce.is_enabled = 'true'";
266  }
267  $unorderedQuery = "FROM $tableName AS cp " .
268  "INNER JOIN $uploadTreeTableName AS UT ON cp.pfile_fk = UT.pfile_fk " .
269  "LEFT JOIN $tableNameEvent AS ce ON ce.".$tableName."_fk = cp.".$tableName."_pk " .
270  "AND ce.upload_fk = $5 AND ce.uploadtree_fk = UT.uploadtree_pk " .
271  $join .
272  "WHERE cp.content!='' " .
273  "AND ( UT.lft BETWEEN $1 AND $2 ) " .
274  "AND cp.type = $3 " .
275  "AND cp.agent_fk = ANY($4::int[]) " .
276  "AND ($activatedClause)" .
277  $sql_upload;
278  $grouping = " GROUP BY mcontent ";
279 
280  $countQuery = "SELECT count(*) FROM (
281  SELECT mcontent AS content FROM (SELECT
282  (CASE WHEN (ce.content IS NULL OR ce.content = '') THEN cp.content ELSE ce.content END) AS mcontent
283  $unorderedQuery $filterQuery $grouping) AS k $searchFilter) AS cx";
284  $iTotalDisplayRecordsRow = $this->dbManager->getSingleRow($countQuery,
285  $filterParms, __METHOD__.$tableName . ".count" . ($activated ? '' : '_deactivated'));
286  $iTotalDisplayRecords = $iTotalDisplayRecordsRow['count'];
287 
288  $countAllQuery = "SELECT count(*) FROM (SELECT
289 (CASE WHEN (ce.content IS NULL OR ce.content = '') THEN cp.content ELSE ce.content END) AS mcontent
290 $unorderedQuery$grouping) as K";
291  $iTotalRecordsRow = $this->dbManager->getSingleRow($countAllQuery, $params, __METHOD__,$tableName . "count.all" . ($activated ? '' : '_deactivated'));
292  $iTotalRecords = $iTotalRecordsRow['count'];
293 
294  $range = "";
295  $filterParms[] = $offset;
296  $range .= ' OFFSET $' . count($filterParms);
297  $filterParms[] = $limit;
298  $range .= ' LIMIT $' . count($filterParms);
299 
300  $sql = "SELECT mcontent AS content, mhash AS hash, copyright_count FROM (SELECT
301 (CASE WHEN (ce.content IS NULL OR ce.content = '') THEN cp.content ELSE ce.content END) AS mcontent,
302 (CASE WHEN (ce.hash IS NULL OR ce.hash = '') THEN cp.hash ELSE ce.hash END) AS mhash,
303 count(*) AS copyright_count " .
304  "$unorderedQuery $filterQuery GROUP BY mcontent, mhash) AS k $searchFilter $orderString $range";
305  $statement = __METHOD__ . $filter.$tableName . $uploadTreeTableName . ($activated ? '' : '_deactivated');
306  $rows = $this->dbManager->getRows($sql, $filterParms, $statement);
307 
308  return array($rows, $iTotalDisplayRecords, $iTotalRecords);
309  }
310 
324  public function getTableName($type)
325  {
326  switch ($type) {
327  case "ipra" :
328  $tableName = "ipra";
329  break;
330  case "ecc" :
331  $tableName = "ecc";
332  break;
333  case "keyword" :
334  $tableName = "keyword";
335  $filter="none";
336  break;
337  case "statement" :
338  $tableName = "copyright";
339  break;
340  case "scancode_statement":
341  $tableName = "scancode_copyright";
342  break;
343  case "scancode_email":
344  case "scancode_author":
345  case "scancode_url":
346  $tableName = "scancode_author";
347  break;
348  default:
349  $tableName = "author";
350  }
351  return $tableName;
352  }
353 
358  private function getOrderString()
359  {
360  $columnNamesInDatabase = array('copyright_count', 'content');
361 
362  $defaultOrder = HistogramBase::returnSortOrder();
363 
364  return $this->dataTablesUtility->getSortingString($_GET, $columnNamesInDatabase, $defaultOrder);
365  }
366 
373  public function getAgentId($upload_pk,$copyrightType)
374  {
375  return (LatestAgentpk($upload_pk, $copyrightType));
376  }
377 
383  private function addSearchFilter(&$filterParams)
384  {
385  $searchPattern = GetParm('sSearch', PARM_STRING);
386  $isInverseSearch = GetParm('isInverse', PARM_STRING);
387  if (empty($searchPattern)) {
388  return '';
389  }
390  $filterParams[] = "%$searchPattern%";
391  if ($isInverseSearch == 'true') {
392  return 'WHERE mcontent not ilike $'.count($filterParams).' ';
393  }
394  return 'WHERE mcontent ilike $'.count($filterParams).' ';
395  }
396 
407  private function getTableRowAction($hash, $uploadTreeId, $upload, $type, $activated = true, $rw = true)
408  {
409  if ($rw) {
410  $act = "<img";
411  if (!$activated) {
412  $act .= " hidden='true'";
413  }
414  $act .= " id='delete$type$hash' onClick='delete$type($upload,$uploadTreeId,\"$hash\",\"$type\");' class=\"delete\" src=\"images/space_16.png\">";
415  $act .= "<span";
416  if ($activated) {
417  $act .= " hidden='true'";
418  }
419  $act .= " id='update$type$hash'>deactivated [<a href=\"#\" id='undo$type$hash' onClick='undo$type($upload,$uploadTreeId,\"$hash\",\"$type\");return false;'>Undo</a>]</span>";
420  return $act;
421  }
422  if (!$activated) {
423  return "deactivated";
424  }
425  return "";
426  }
427 
441  private function fillTableRow($row, $uploadTreeId, $upload, $agentId, $type,$listPage, $filter = "", $activated = true, $rw = true)
442  {
443  $hash = $row['hash'];
444  $output = array('DT_RowId' => "$upload,$uploadTreeId,$hash,$type", "DT_RowClass" => "row$hash");
445 
446  $link = "<a href='";
447  $link .= Traceback_uri();
448  $urlArgs = "?mod=".$listPage."&agent=$agentId&item=$uploadTreeId&hash=$hash&type=$type";
449  if ((empty($filter) || $filter == "all")) {
450  if ($activated) {
451  $filter = "active";
452  } else {
453  $filter = "inactive";
454  }
455  }
456  if (!empty($filter)) {
457  $urlArgs .= "&filter=$filter";
458  }
459  $link .= $urlArgs . "'>" . $row['copyright_count'] . "</a>";
460  $output['0'] = $link;
461  $output['1'] = convertToUTF8($row['content']);
462  $output['2'] = $this->getTableRowAction($hash, $uploadTreeId, $upload, $type, $activated, $rw);
463  if ($rw && $activated) {
464  $output['3'] = "<input type='checkbox' class='deleteBySelect$type' id='deleteBySelect$type$hash' value='".$upload.",".$uploadTreeId.",".$hash.",".$type."'>";
465  } else {
466  $output['3'] = "<input type='checkbox' class='undoBySelect$type' id='undoBySelect$type$hash' value='".$upload.",".$uploadTreeId.",".$hash.",".$type."'>";
467  }
468  return $output;
469  }
470 
478  protected function doUpdate($itemId, $hash, $type)
479  {
480  $content = GetParm("value", PARM_RAW);
481  if (empty($content)) {
482  return new Response('empty content not allowed',
483  Response::HTTP_BAD_REQUEST ,array('Content-type'=>'text/plain'));
484  }
485 
486  $item = $this->uploadDao->getItemTreeBounds($itemId, $this->uploadtree_tablename);
487  $cpTable = $this->getTableName($type);
488  $this->copyrightDao->updateTable($item, $hash, $content, Auth::getUserId(), $cpTable);
489 
490  return new Response('success', Response::HTTP_OK,array('Content-type'=>'text/plain'));
491  }
492 
500  protected function doDelete($itemId, $hash, $type)
501  {
502  $item = $this->uploadDao->getItemTreeBounds($itemId, $this->uploadtree_tablename);
503  $cpTable = $this->getTableName($type);
504  $this->copyrightDao->updateTable($item, $hash, '', Auth::getUserId(), $cpTable, 'delete');
505  return new Response('Successfully deleted', Response::HTTP_OK, array('Content-type'=>'text/plain'));
506  }
507 
515  protected function doUndo($itemId, $hash, $type)
516  {
517  $item = $this->uploadDao->getItemTreeBounds($itemId, $this->uploadtree_tablename);
518  $cpTable = $this->getTableName($type);
519  $this->copyrightDao->updateTable($item, $hash, '', Auth::getUserId(), $cpTable, 'rollback');
520  return new Response('Successfully restored', Response::HTTP_OK, array('Content-type'=>'text/plain'));
521  }
522 
530  protected function doDeleteDecision($decisionId, $pfileId, $type)
531  {
532  $this->copyrightDao->removeDecision($type."_decision", $pfileId, $decisionId);
533  return new JsonResponse(array("msg" => $decisionId . " .. " . $pfileId . " .. " . $type));
534  }
535 
543  protected function doUndoDecision($decisionId, $pfileId, $type)
544  {
545  $this->copyrightDao->undoDecision($type."_decision", $pfileId, $decisionId);
546  return new JsonResponse(array("msg" => $decisionId . " .. " . $pfileId . " .. " . $type));
547  }
548 
556  protected function doDeleteHashDecision($hash, $upload, $type)
557  {
558  $tableName = $type."_decision";
559  $decisions = $this->copyrightDao->getDecisionsFromHash($tableName, $hash,
560  $upload, $this->uploadtree_tablename);
561  foreach ($decisions as $decision) {
562  $this->copyrightDao->removeDecision($tableName, $decision['pfile_fk'],
563  $decision[$tableName . '_pk']);
564  }
565  return new JsonResponse(array("msg" => "$hash .. $upload .. $type"));
566  }
567 
575  protected function doUndoHashDecision($hash, $upload, $type)
576  {
577  $tableName = $type."_decision";
578  $decisions = $this->copyrightDao->getDecisionsFromHash($tableName, $hash,
579  $upload, $this->uploadtree_tablename);
580  foreach ($decisions as $decision) {
581  $this->copyrightDao->undoDecision($tableName, $decision['pfile_fk'],
582  $decision[$tableName . '_pk']);
583  }
584  return new JsonResponse(array("msg" => "$hash .. $upload .. $type"));
585  }
586 }
587 
588 $NewPlugin = new CopyrightHistogramProcessPost();
589 $NewPlugin->Initialize();
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:100
Handles Ajax requests for copyright.
doUpdate($itemId, $hash, $type)
Update result.
getTableRowAction($hash, $uploadTreeId, $upload, $type, $activated=true, $rw=true)
Helper to create action column for results.
getTableName($type)
Get table name based on statement type.
doDeleteDecision($decisionId, $pfileId, $type)
Disable a decision.
getCopyrights($upload_pk, $item, $uploadTreeTableName, $agentId, $type, $filter, $activated=true, $offset=null, $limit=null)
Get results from database and format for JSON.
doGetData($upload, $activated=true)
Handles GET request and create a JSON response.
doUndoDecision($decisionId, $pfileId, $type)
Rollback a decision.
doDelete($itemId, $hash, $type)
Disable a result.
getTableData($upload, $item, $agent_pk, $type, $listPage, $filter, $activated=true)
Get the copyright data and fill in expected format.
getAgentId($upload_pk, $copyrightType)
Get Agent ID for an upload.
__construct()
base constructor. Most plugins will just use this
fillTableRow($row, $uploadTreeId, $upload, $agentId, $type, $listPage, $filter="", $activated=true, $rw=true)
Fill table content for JSON response.
addSearchFilter(&$filterParams)
Add filter on content.
Output()
Display the loaded menu and plugins.
doUndo($itemId, $hash, $type)
Rollback a result.
doDeleteHashDecision($hash, $upload, $type)
Disable decisions for an upload which matches a hash.
doUndoHashDecision($hash, $upload, $type)
Rollback decisions for an upload which matches a hash.
getOrderString()
Create sorting string for database query.
This is the Plugin class. All plugins should:
Definition: FO_Plugin.php:57
Handles Ajax requests for text findings.
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static returnSortOrder()
Get sorting orders.
Definition: state.hpp:16
LatestAgentpk($upload_pk, $arsTableName, $arsSuccess=false)
Given an upload_pk, find the latest enabled agent_pk with results.
Traceback_uri()
Get the URI without query to this location.
Definition: common-parm.php:97
const PARM_INTEGER
Definition: common-parm.php:14
const PARM_RAW
Definition: common-parm.php:22
const PARM_STRING
Definition: common-parm.php:18
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
Definition: common-parm.php:46
if(! defined('ENT_SUBSTITUTE')) convertToUTF8($content, $toHTML=true)
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690
#define PLUGIN_DB_READ
Plugin requires read permission on DB.
Definition: libfossology.h:37
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16