FOSSology  4.4.0
Open Source License Compliance by Open Source Software
acme_review.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2012 Hewlett-Packard Development Company, L.P.
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 define("TITLE_ACME_REVIEW", _("ACME Review"));
9 
19 function proj_cmp($rowa, $rowb)
20 {
21  $key1 = $rowb['count'] - $rowa['count'];
22  if ($key1) {
23  return $key1;
24  }
25 
26  // secondary key - project_name ascending
27  return (strnatcasecmp($rowa['project_name'], $rowb['project_name']));
28 }
29 
30 class acme_review extends FO_Plugin
31 {
32  var $Name = "acme_review";
33  var $Title = TITLE_ACME_REVIEW;
34  var $Version = "1.0";
35  var $MenuList = "";
36  var $MenuOrder = 110;
37  var $Dependency = array("browse", "view");
38  var $DBaccess = PLUGIN_DB_READ;
39  var $LoginFlag = 0;
40  var $NoHTML = 1; // prevent the http header from being written in case we have to download a file
41 
45  function RegisterMenus()
46  {
47  if (GetParm("mod", PARM_STRING) == $this->Name) {
48  $detail = GetParm("detail", PARM_INTEGER);
49  if ($detail) {
50  $text = _("ACME High Level Review");
51  $URI = $this->Name .
52  Traceback_parm_keep(array("page", "upload", "folic")) . "&detail=0";
53  } else {
54  $text = _("ACME Low Level Review");
55  $URI = $this->Name .
56  Traceback_parm_keep(array("page", "upload", "folic")) . "&detail=1";
57  }
58 
59  // micro menu when in acme_review
60  menu_insert("acme::$text", 1, $URI, $text);
61  } else {
62  // micro menu item when not in acme_review
63  $text2 = _("ACME Review");
64  $URI = $this->Name . Traceback_parm_keep(array( "page", "upload")) . "&detail=0";
65  menu_insert("Browse::$text2", 1, $URI, $text2);
66  }
67  } // RegisterMenus()
68 
69 
76  function FindACMEProjects($uploadtreeRow, &$acme_project_array)
77  {
78  global $PG_CONN;
79 
80  /* See if there is already an acme project for this pfile */
81  $sql = "select acme_project_fk from acme_pfile where pfile_fk='$uploadtreeRow[pfile_fk]' limit 1";
82  $result = pg_query($PG_CONN, $sql);
83  DBCheckResult($result, $sql, __FILE__, __LINE__);
84  if (pg_num_rows($result) > 0) {
85  /* found a project */
86  $acme_pfileRow = pg_fetch_assoc($result);
87 
88  // retrieve the acme_project record to go with the found acme_project_fk
89  $sql = "select * from acme_project where acme_project_pk='$acme_pfileRow[acme_project_fk]'";
90  $projresult = pg_query($PG_CONN, $sql);
91  DBCheckResult($projresult, $sql, __FILE__, __LINE__);
92  if (pg_num_rows($projresult) > 0) {
93  $acme_project_array[$acme_pfileRow['acme_project_fk']] = pg_fetch_assoc(
94  $projresult);
95  $acme_project_array[$acme_pfileRow['acme_project_fk']]['count'] = (($uploadtreeRow['rgt'] -
96  $uploadtreeRow['lft']) + 1) / 2;
97  }
98  return;
99  } else {
100  /* check each child */
101  $sql = "select uploadtree_pk, pfile_fk, lft, rgt from uploadtree where parent= $uploadtreeRow[uploadtree_pk]";
102  $childrenResult = pg_query($PG_CONN, $sql);
103  DBCheckResult($childrenResult, $sql, __FILE__, __LINE__);
104  while ($child = pg_fetch_assoc($childrenResult)) {
105  $this->FindACMEProjects($child, $acme_project_array);
106  }
107  pg_free_result($childrenResult);
108  }
109  pg_free_result($result);
110 
111  return;
112  } // FindACMEProjects()
113 
114 
121  function GetProjectArray0($upload_pk, $nomosAgentpk, $MinCount=1)
122  {
123  global $PG_CONN;
124  $acme_project_array = array(); // acme project array to return
125 
126  $sql = "select uploadtree_pk, pfile_fk, lft, rgt from uploadtree where upload_fk='$upload_pk' and parent is null";
127  $result = pg_query($PG_CONN, $sql);
128  DBCheckResult($result, $sql, __FILE__, __LINE__);
129  $row = pg_fetch_assoc($result);
130  $this->FindACMEProjects($row, $acme_project_array);
131  pg_free_result($result);
132 
133  return $acme_project_array;
134  }
135 
136 
143  function GetProjectArray1($upload_pk, $nomosAgentpk, $MinCount=1)
144  {
145  global $PG_CONN;
146  $acme_project_array = array(); // acme project array to return
147  $idx = 0;
148 
149  $sql = "select distinct(acme_project_fk) as acme_project_fk, count(acme_project_fk) as filecount from acme_pfile
150  right join uploadtree on uploadtree.pfile_fk=acme_pfile.pfile_fk where upload_fk=$upload_pk
151  group by acme_project_fk order by filecount desc";
152  $result = pg_query($PG_CONN, $sql);
153  DBCheckResult($result, $sql, __FILE__, __LINE__);
154  while ($row = pg_fetch_assoc($result)) {
155  if ($row['filecount'] < $MinCount) {
156  break;
157  }
158 
159  // retrieve the acme_project record to go with the found acme_project_fk
160  $sql = "select * from acme_project where acme_project_pk='$row[acme_project_fk]'";
161  $projresult = pg_query($PG_CONN, $sql);
162  DBCheckResult($projresult, $sql, __FILE__, __LINE__);
163  if (pg_num_rows($projresult) > 0) {
164  $acme_project_array[$idx] = pg_fetch_assoc($projresult);
165  $acme_project_array[$idx]['count'] = $row['filecount'];
166  $idx ++;
167  }
168  }
169 
170  return($acme_project_array);
171  } // GetProjectArray1()
172 
173 
180  function HTMLForm($acme_project_array, $upload_pk)
181  {
182  $Outbuf = "";
183  $uploadtreeRec = GetSingleRec("uploadtree", "where upload_fk=$upload_pk and parent is null");
184  $Outbuf .= Dir2Browse($this->Name,$uploadtreeRec['uploadtree_pk'], NULL, 1, "acme");
185  $Outbuf .= "<p>";
186 
187  $URI = "?mod=" . $this->Name . Traceback_parm_keep(array( "page", "upload", "folic", "detail"));
188  $Outbuf .= "<form action='" . $URI . "' method='POST'>\n";
189 
190  $Outbuf .= "<table border=1>";
191  $Outbuf .= "<tr>";
192  $text = _('Include');
193  $Outbuf .= "<th>$text</th>";
194  $text = _('Project');
195  $Outbuf .= "<th>$text</th>";
196  $text = _('Files');
197  $Outbuf .= "<th>$text</th>";
198  $text = _('URL');
199  $Outbuf .= "<th>$text</th>";
200  $text = _('Description');
201  $Outbuf .= "<th>$text</th>";
202  $text = _('License');
203  $Outbuf .= "<th>$text</th>";
204  $text = _('Version');
205  $Outbuf .= "<th>$text</th>";
206  $Outbuf .= "</tr>";
207 
208  /* For alternating row background colors */
209  $RowStyle1 = "style='background-color:lavender'";
210  $RowStyle2 = "style='background-color:lightyellow'";
211  $ColorSpanRows = 1; // Alternate background color every $ColorSpanRows
212  $RowNum = 0;
213 
214  foreach ($acme_project_array as $project) {
215  /*
216  * Set alternating row background color - repeats every $ColorSpanRows
217  * rows
218  */
219  $RowStyle = (($RowNum ++ % (2 * $ColorSpanRows)) < $ColorSpanRows) ? $RowStyle1 : $RowStyle2;
220 
221  $Outbuf .= "<tr $RowStyle>";
222  $Checked = $project['include'] == 't' ? "checked=\"checked\"" : '';
223  $Outbuf .= "<td><input type='checkbox' name='includeproj[$project[acme_project_pk]]' $Checked></td>\n";
224  $Outbuf .= "<td>$project[project_name]</td>";
225  $ProjectListURL = Traceback_uri() . "?mod=" . $this->Name .
226  "&acme_project=$project[acme_project_pk]&upload=$upload_pk";
227  $Outbuf .= "<td><a href='$ProjectListURL'>$project[count]</a></td>";
228  $Outbuf .= "<td><a href='$project[url]'>$project[url]</a></td>";
229  $Outbuf .= "<td>" . htmlentities($project['description'], ENT_HTML5 | ENT_QUOTES) . "</td>";
230  $Outbuf .= "<td>$project[licenses]</td>";
231  $Outbuf .= "<td>$project[version]</td>";
232  $Outbuf .= "</tr>";
233  }
234  $Outbuf .= "</table>";
235 
236  $Outbuf .= "$RowNum rows found<br>";
237 
238  $text = _("Save and Generate SPDX file");
239  $Outbuf .= "<p><input type='submit' value='$text' name='spdxbtn'>\n";
240  $text = _("Save");
241  $Outbuf .= "&nbsp;&nbsp;&nbsp;<input type='submit' value='$text' name='savebtn'>\n";
242  $Outbuf .= "</form>\n";
243  /******* END Input form *******/
244 
245  return $Outbuf;
246  }
247 
248 
256  function Populate_acme_upload($acme_project_array, $upload_pk, $detail)
257  {
258  global $PG_CONN;
259 
260  foreach ($acme_project_array as $project) {
261  $sql = "insert into acme_upload (upload_fk, acme_project_fk, include, detail, count) values ($upload_pk, $project[acme_project_pk], true, $detail, $project[count])";
262  $result = pg_query($PG_CONN, $sql);
263  DBCheckResult($result, $sql, __FILE__, __LINE__);
264  pg_free_result($result);
265  }
266  }
267 
268 
274  function GenerateSPDX($acme_project_array)
275  {
276  global $SysConf;
277 
278  $spdx = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
279  $spdx .='<rdf:RDF' . "\n";
280  $spdx .= ' xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' . "\n";
281  $spdx .= ' xmlns="http://spdx.org/rdf/terms#"' . "\n";
282  $spdx .= ' xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">' . "\n";
283  $spdx .= ' <SpdxDocument rdf:about="http://www.spdx.org/tools#SPDXANALYSIS">' . "\n";
284  $spdx .= ' <specVersion>SPDX-1.1</specVersion>' . "\n";
285  $spdx .= ' <dataLicense rdf:about="http://spdx.org/licenses/PDDL-1.0" />' . "\n";
286  $spdx .= ' <CreationInfo>' . "\n";
287  $spdx .= " <creator>Tool: FOSSology v " . $SysConf['BUILD']['VERSION']
288  . " svn " . $SysConf['BUILD']['COMMIT_HASH'] . "</creator>\n";
289  $spdx .= "<created>" . date('c') . "</created>\n"; // date-time in ISO 8601 format
290  $spdx .= '</CreationInfo>' . "\n";
291 
292  $in_encoding = iconv_get_encoding("input_encoding");
293  foreach ($acme_project_array as $project) {
294  //debugprint($project, "Project");
295  $spdx .= "<Package>\n";
296  $spdx .= '<name>' . str_replace("&", " and ", strip_tags($project['project_name'])) . '</name>' . "\n";
297  $spdx .= "<versionInfo>$project[version]</versionInfo>\n";
298  $spdx .= "<licenseDeclared>$project[licenses]</licenseDeclared>\n";
299  $spdx .= "<sourceInfo>ProjectURL: $project[url]</sourceInfo>\n";
300  $spdx .= '<description>' . str_replace("&", " and ",
301  strip_tags($project['description'])) . '</description>' . "\n";
302  $spdx .= "</Package>\n";
303  }
304  /*
305  <packageSupplier>Organization: FSF (info@fsf.com)</packageSupplier>
306  <packageOriginator>Organization: FSF (info@fsf.com)</packageOriginator>
307  <packageDdownloadLocation>http://ftp.gnu.org/gnu/coreutils/</packageDdownloadLocation>
308  <packageFileName>coreutils-8.12.tar.gz</packageFileName>
309  <sourceInfo>
310  mechanism: git
311  repository: git://git.sv.gnu.org/coreutils
312  branch: master
313  tag: v8.12
314  </sourceInfo>
315  </Package>
316  */
317 
318  $spdx .= " </SpdxDocument> </rdf:RDF>\n";
319  return $spdx;
320  }
321 
322 
326  function Output()
327  {
328  global $Plugins;
329  global $PG_CONN;
330 
331  $CriteriaCount = 0;
332  $V="";
333  $GETvars="";
334  $upload_pk = GetParm("upload",PARM_INTEGER);
335  $detail = GetParm("detail",PARM_INTEGER);
336  $detail = empty($detail) ? 0 : 1;
337  $folic = GetParm("folic",PARM_INTEGER);
338  $savebtn = GetParm("savebtn",PARM_RAW);
339  $spdxbtn = GetParm("spdxbtn",PARM_RAW);
340 
341  $agent_pk = LatestAgentpk($upload_pk, "nomos_ars");
342  if (empty($agent_pk)) {
343  echo "Missing fossology license data. Run a license scan on this upload.<br>";
344  exit();
345  }
346  $uploadtree_tablename = GetUploadtreeTableName($upload_pk);
347 
348  // Check if we have data in the acme_upload table, if not then load it
349  $acme_uploadRec = GetSingleRec("acme_upload", "where upload_fk=$upload_pk ");
350  if (empty($acme_uploadRec)) {
351  // populate acme_upload
352  $MinCount = 1;
353  $nomosAgentpk = LatestAgentpk($upload_pk, "nomos_ars");
354  $acme_project_array = $this->GetProjectArray1($upload_pk, $nomosAgentpk,
355  $MinCount); // low level
356  $this->Populate_acme_upload($acme_project_array, $upload_pk, 1);
357  $acme_project_array = $this->GetProjectArray0($upload_pk, $nomosAgentpk,
358  $MinCount); // high level
359  $this->Populate_acme_upload($acme_project_array, $upload_pk, 0);
360  }
361 
362  $sql = "select * from acme_upload, acme_project "
363  . "where acme_project_pk=acme_project_fk and detail=$detail and upload_fk=$upload_pk";
364  $result = pg_query($PG_CONN, $sql);
365  DBCheckResult($result, $sql, __FILE__, __LINE__);
366  $acme_project_array = pg_fetch_all($result);
367  $acme_project_array_orig = $acme_project_array; // save the original state so we know which records to update
368 
369  /* If the save or spdx buttons were clicked, update $acme_project_array and save the data in the acme_upload table */
370  if (!empty($savebtn) or !empty($spdxbtn)) {
371  /* First set all projects include to false */
372  foreach ($acme_project_array as &$project) {
373  $project['include'] = 'f';
374  }
375  /* Now turn on projects include to match form */
376  if (array_key_exists('includeproj', $_POST)) {
377  $includeArray = $_POST['includeproj'];
378  foreach ($acme_project_array as &$project) {
379  if (array_key_exists($project['acme_project_fk'], $includeArray)) {
380  $project['include'] = "t";
381  }
382  }
383  }
384 
385  /* Finally, update the db with any changed include states */
386  $NumRecs = count($acme_project_array);
387  for ($i = 0; $i < $NumRecs; $i ++) {
388  $project = $acme_project_array[$i];
389  $project_orig = $acme_project_array_orig[$i];
390  if ($project['include'] != $project_orig['include']) {
391  $include = $project['include'] ? "true" : "false";
392  $sql = "update acme_upload set include='$include' where acme_upload_pk='$project[acme_upload_pk]'";
393  $result = pg_query($PG_CONN, $sql);
394  DBCheckResult($result, $sql, __FILE__, __LINE__);
395  pg_free_result($result);
396  }
397  }
398  }
399 
400  /* aggregate the fossology licenses for each pfile and each acme_project */
401  if ($folic) {
402  foreach ($acme_project_array as &$project) {
403  $sql = "select uploadtree_pk from acme_pfile, uploadtree where acme_project_fk=$project[acme_project_fk]
404  and acme_pfile.pfile_fk=uploadtree.pfile_fk and uploadtree.upload_fk=$upload_pk";
405  $result = pg_query($PG_CONN, $sql);
406  DBCheckResult($result, $sql, __FILE__, __LINE__);
407  $LicArray = array();
408  $ItemLicArray = array();
409  while ($acme_pfileRow = pg_fetch_assoc($result)) {
410  $LicArray = GetFileLicenses($agent_pk, '',
411  $acme_pfileRow['uploadtree_pk'], $uploadtree_tablename);
412  foreach ($LicArray as $key => $license) {
413  $ItemLicArray[$key] = $license;
414  }
415  }
416  $project['licenses'] = '';
417  foreach ($ItemLicArray as $license) {
418  if ($license == "No_license_found") {
419  continue;
420  }
421  if (! empty($project['licenses'])) {
422  $project['licenses'] .= ", ";
423  }
424  $project['licenses'] .= $license;
425  }
426  }
427  }
428 
429  /* sort $acme_project_array by count desc */
430  usort($acme_project_array, 'proj_cmp');
431 
432  /* generate and download spdx file */
433  if (! empty($spdxbtn)) {
434  $spdxfile = $this->GenerateSPDX($acme_project_array);
435  $rv = DownloadString2File($spdxfile, "SPDX.rdf file", "xml");
436  if ($rv !== true) {
437  echo $rv;
438  }
439  }
440 
441  switch ($this->OutputType) {
442  case "XML":
443  break;
444  case "HTML":
445  $this->NoHeader = 0;
446  $this->OutputOpen("HTML", 1);
447  $V .= $this->HTMLForm($acme_project_array, $upload_pk);
448  break;
449  case "Text":
450  break;
451  default:
452  break;
453  }
454  if (! $this->OutputToStdout) {
455  return ($V);
456  }
457  print($V);
458  return;
459  } // Output()
460 }
461 
462 return; // prevent anyone from seeing this plugin
463 $NewPlugin = new acme_review();
464 $NewPlugin->Initialize();
465 
This is the Plugin class. All plugins should:
Definition: FO_Plugin.php:57
OutputOpen()
This function is called when user output is requested. This function is responsible for assigning hea...
Definition: FO_Plugin.php:305
HTMLForm($acme_project_array, $upload_pk)
create the HTML to display the form showing the found projects
RegisterMenus()
Customize submenus.
Definition: acme_review.php:45
FindACMEProjects($uploadtreeRow, &$acme_project_array)
Find all the acme projects in a hierarchy, starting with $uploadtree_pk. Once you get an acme hit,...
Definition: acme_review.php:76
GetProjectArray1($upload_pk, $nomosAgentpk, $MinCount=1)
Given an upload , return all the unique projects found.
GenerateSPDX($acme_project_array)
Write and return the SPDX file as a string.
Populate_acme_upload($acme_project_array, $upload_pk, $detail)
Populate the acme_upload table for this upload.
Output()
Display the loaded menu and plugins.
GetProjectArray0($upload_pk, $nomosAgentpk, $MinCount=1)
Given an upload , return all the unique projects found.
LatestAgentpk($upload_pk, $arsTableName, $arsSuccess=false)
Given an upload_pk, find the latest enabled agent_pk with results.
DBCheckResult($result, $sql, $filenm, $lineno)
Check the postgres result for unexpected errors. If found, treat them as fatal.
Definition: common-db.php:187
GetSingleRec($Table, $Where="")
Retrieve a single database record.
Definition: common-db.php:91
Dir2Browse($Mod, $UploadtreePk, $LinkLast=NULL, $ShowBox=1, $ShowMicro=NULL, $Enumerate=-1, $PreText='', $PostText='', $uploadtree_tablename="uploadtree")
Get an html linked string of a file browse path.
Definition: common-dir.php:263
GetFileLicenses($agent, $pfile_pk, $uploadtree_pk, $uploadtree_tablename='uploadtree', $duplicate="")
get all the licenses for a single file or uploadtree
menu_insert($Path, $LastOrder=0, $URI=NULL, $Title=NULL, $Target=NULL, $HTML=NULL)
Given a Path, order level for the last item, and optional plugin name, insert the menu item.
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
Traceback_parm_keep($List)
Create a new URI, keeping only these items.
DownloadString2File($text, $name, $contentType)
Send a string to a user as a download file.
Definition: common-ui.php:198
FUNCTION char * GetUploadtreeTableName(PGconn *pgConn, int upload_pk)
Get the uploadtree table name for this upload_pk If upload_pk does not exist, return "uploadtree".
Definition: libfossagent.c:414
#define PLUGIN_DB_READ
Plugin requires read permission on DB.
Definition: libfossology.h:37
foreach($Options as $Option=> $OptVal) if(0==$reference_flag &&0==$nomos_flag) $PG_CONN