FOSSology  4.4.0
Open Source License Compliance by Open Source Software
ObligationCsvImport.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014-2017 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
9 
12 
23 {
26  protected $dbManager;
29  protected $delimiter = ',';
32  protected $enclosure = '"';
35  protected $headrow = null;
38  protected $alias = array(
39  'type'=>array('type','Type'),
40  'topic'=>array('topic','Obligation or Risk topic'),
41  'text'=>array('text','Full Text'),
42  'classification'=>array('classification','Classification'),
43  'modifications'=>array('modifications','Apply on modified source code'),
44  'comment'=>array('comment','Comment'),
45  'licnames'=>array('licnames','Associated Licenses'),
46  'candidatenames'=>array('candidatenames','Associated candidate Licenses')
47  );
48 
53  public function __construct(DbManager $dbManager)
54  {
55  $this->dbManager = $dbManager;
56  $this->obligationMap = $GLOBALS['container']->get('businessrules.obligationmap');
57  }
58 
63  public function setDelimiter($delimiter=',')
64  {
65  $this->delimiter = substr($delimiter,0,1);
66  }
67 
72  public function setEnclosure($enclosure='"')
73  {
74  $this->enclosure = substr($enclosure,0,1);
75  }
76 
83  public function handleFile($filename, $fileExtension)
84  {
85  if (!is_file($filename) || ($handle = fopen($filename, 'r')) === false) {
86  return _('Internal error');
87  }
88  $cnt = -1;
89  $msg = '';
90  try {
91  if ($fileExtension == 'csv') {
92  while (($row = fgetcsv($handle,0,$this->delimiter,$this->enclosure)) !== false) {
93  $log = $this->handleCsv($row);
94  if (!empty($log)) {
95  $msg .= "$log\n";
96  }
97  $cnt++;
98  }
99  $msg .= _('Read csv').(": $cnt ")._('obligations');
100  } else {
101  $jsonContent = fread($handle, filesize($filename));
102  $data = json_decode($jsonContent, true);
103  if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
104  $msg .= "Error decoding JSON: " . json_last_error_msg()."\n";
105  }
106  foreach ($data as $row) {
107  $log = $this->handleCsvObligation($this->handleRowJson($row));
108  if (!empty($log)) {
109  $msg .= "$log\n";
110  }
111  }
112  $msg .= _('Read json').(":". count($data) ." ")._('obligations');
113  }
114  } catch(\Exception $e) {
115  fclose($handle);
116  return $msg .= _('Error while parsing file').': '.$e->getMessage();
117  }
118  fclose($handle);
119  return $msg;
120  }
121 
128  function handleRowJson($row)
129  {
130  $newArray = array();
131  foreach ($row as $key => $value) {
132  $newKey = $key;
133  foreach ($this->alias as $aliasKey => $aliasValues) {
134  if (in_array($key, $aliasValues)) {
135  $newKey = $aliasKey;
136  break;
137  }
138  }
139  $newArray[$newKey] = $value;
140  }
141  return $newArray;
142  }
143 
150  private function handleCsv($row)
151  {
152  if ($this->headrow===null) {
153  $this->headrow = $this->handleHeadCsv($row);
154  return 'head okay';
155  }
156 
157  $mRow = array();
158  foreach (array('type','topic','text','classification','modifications','comment','licnames','candidatenames') as $needle) {
159  $mRow[$needle] = $row[$this->headrow[$needle]];
160  }
161 
162  return $this->handleCsvObligation($mRow);
163  }
164 
171  private function handleHeadCsv($row)
172  {
173  $headrow = array();
174  foreach (array('type','topic','text','classification','modifications','comment','licnames','candidatenames') as $needle) {
175  $col = ArrayOperation::multiSearch($this->alias[$needle], $row);
176  if (false === $col) {
177  throw new \Exception("Undetermined position of $needle");
178  }
179  $headrow[$needle] = $col;
180  }
181  return $headrow;
182  }
183 
189  private function getKeyFromTopicAndText($row)
190  {
191  $req = array($row['topic'], $row['text']);
192  $row = $this->dbManager->getSingleRow('SELECT ob_pk FROM obligation_ref WHERE ob_topic=$1 AND ob_md5=md5($2)',$req);
193  return ($row === false) ? false : $row['ob_pk'];
194  }
195 
204  private function compareLicList($exists, $listFromCsv, $candidate, $row)
205  {
206  $getList = $this->obligationMap->getLicenseList($exists, $candidate);
207  $listFromDb = $this->reArrangeString($getList);
208  $listFromCsv = $this->reArrangeString($listFromCsv);
209  return strcmp($listFromDb, $listFromCsv);
210  }
211 
218  private function reArrangeString($string)
219  {
220  $string = explode(";", $string);
221  sort($string);
222  return implode(",", $string);
223  }
224 
231  private function clearListFromDb($exists, $candidate)
232  {
233  $licId = 0;
234  $this->obligationMap->unassociateLicenseFromObligation($exists, $licId, $candidate);
235  return true;
236  }
237 
246  private function handleCsvObligation($row)
247  {
248  /* @var $dbManager DbManager */
250  $exists = $this->getKeyFromTopicAndText($row);
251  $associatedLicenses = "";
252  $candidateLicenses = "";
253  $msg = "";
254  if ($exists !== false) {
255  $msg = "Obligation topic '$row[topic]' already exists in DB (id=".$exists."),";
256  if ( $this->compareLicList($exists, $row['licnames'], false, $row) === 0 ) {
257  $msg .=" No Changes in AssociateLicense";
258  } else {
259  $this->clearListFromDb($exists, false);
260  if (!empty($row['licnames'])) {
261  $associatedLicenses .= $this->AssociateWithLicenses($row['licnames'], $exists, false);
262  }
263  $msg .=" Updated AssociatedLicense license";
264  }
265  if ($this->compareLicList($exists, $row['candidatenames'], true, $row) === 0) {
266  $msg .=" No Changes in CandidateLicense";
267  } else {
268  $this->clearListFromDb($exists, true);
269  if (!empty($row['candidatenames'])) {
270  $associatedLicenses .= $this->AssociateWithLicenses($row['candidatenames'], $exists, true);
271  }
272  $msg .=" Updated CandidateLicense";
273  }
274  $this->updateOtherFields($exists, $row);
275  return $msg . "\n" . $associatedLicenses . "\n";
276  }
277 
278  $stmtInsert = __METHOD__.'.insert';
279  $dbManager->prepare($stmtInsert,'INSERT INTO obligation_ref (ob_type,ob_topic,ob_text,ob_classification,ob_modifications,ob_comment,ob_md5)'
280  . ' VALUES ($1,$2,$3,$4,$5,$6,md5($3)) RETURNING ob_pk');
281  $resi = $dbManager->execute($stmtInsert,array($row['type'],$row['topic'],$row['text'],$row['classification'],$row['modifications'],$row['comment']));
282  $new = $dbManager->fetchArray($resi);
283  $dbManager->freeResult($resi);
284 
285  if (!empty($row['licnames'])) {
286  $associatedLicenses .= $this->AssociateWithLicenses($row['licnames'], $new['ob_pk']);
287  }
288  if (!empty($row['candidatenames'])) {
289  $candidateLicenses = $this->AssociateWithLicenses($row['candidatenames'], $new['ob_pk'], true);
290  }
291 
292  $message = "License association results for obligation '$row[topic]':\n";
293  $message .= "$associatedLicenses";
294  $message .= "$candidateLicenses";
295  $message .= "Obligation with id=$new[ob_pk] was added successfully.\n";
296  return $message;
297  }
298 
307  function AssociateWithLicenses($licList, $obPk, $candidate=False)
308  {
309  $associatedLicenses = "";
310  $message = "";
311 
312  $licenses = explode(";",$licList);
313  foreach ($licenses as $license) {
314  $licIds = $this->obligationMap->getIdFromShortname($license, $candidate);
315  $updated = false;
316  if (empty($licIds)) {
317  $message .= "License $license could not be found in the DB.\n";
318  } else {
319  $updated = $this->obligationMap->associateLicenseFromLicenseList($obPk,
320  $licIds, $candidate);
321  }
322  if ($updated) {
323  if ($associatedLicenses == "") {
324  $associatedLicenses = "$license";
325  } else {
326  $associatedLicenses .= ";$license";
327  }
328  }
329  }
330 
331  if (!empty($associatedLicenses)) {
332  $message .= "$associatedLicenses were associated.\n";
333  } else {
334  $message .= "No ";
335  $message .= $candidate ? "candidate": "";
336  $message .= "licenses were associated.\n";
337  }
338  return $message;
339  }
340 
351  function updateOtherFields($exists, $row)
352  {
353  $this->dbManager->getSingleRow('UPDATE obligation_ref SET ob_classification=$2, ob_modifications=$3, ob_comment=$4 where ob_pk=$1',
354  array($exists, $row['classification'], $row['modifications'], $row['comment']),
355  __METHOD__ . '.updateOtherOb');
356  }
357 }
Helper class for Obligation CSV Import.
setDelimiter($delimiter=',')
Update the delimiter.
setEnclosure($enclosure='"')
Update the enclosure.
clearListFromDb($exists, $candidate)
Clear all license maps for given obligation.
getKeyFromTopicAndText($row)
Get the Obligation key from obligation topic and obligation text.
handleCsvObligation($row)
Handle a single row from CSV.
updateOtherFields($exists, $row)
Update other fields of the obligation.
AssociateWithLicenses($licList, $obPk, $candidate=False)
Associate selected licenses to the obligation.
handleFile($filename, $fileExtension)
Read the CSV line by line and import it.
compareLicList($exists, $listFromCsv, $candidate, $row)
Compare licenses from Database and CSV.
Fossology exception.
Definition: Exception.php:15
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
Utility functions for specific applications.