FOSSology  4.7.0-rc1
Open Source License Compliance by Open Source Software
BulkTextExport.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2026 Kaushlendra Pratap <kaushlendra-pratap.singh@siemens.com>
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
9 
11 
22 {
25  protected $dbManager;
28  protected $delimiter = ',';
31  protected $enclosure = '"';
32 
37  public function __construct(DbManager $dbManager)
38  {
39  $this->dbManager = $dbManager;
40  }
41 
46  public function setDelimiter($delimiter=',')
47  {
48  if (!is_string($delimiter) || strlen($delimiter) !== 1) {
49  throw new \InvalidArgumentException("CSV delimiter must be a non-empty single-byte character.");
50  }
51  if ($delimiter === $this->enclosure) {
52  throw new \InvalidArgumentException("CSV delimiter and enclosure must be different characters.");
53  }
54  $this->delimiter = $delimiter;
55  }
56 
61  public function setEnclosure($enclosure='"')
62  {
63  if (!is_string($enclosure) || strlen($enclosure) !== 1) {
64  throw new \InvalidArgumentException("CSV enclosure must be a non-empty single-byte character.");
65  }
66  if ($enclosure === $this->delimiter) {
67  throw new \InvalidArgumentException("CSV delimiter and enclosure must be different characters.");
68  }
69  $this->enclosure = $enclosure;
70  }
71 
79  public function exportBulkText($user_pk=0, $group_pk=0, $generateJson=false, $includeLicenseText=false)
80  {
81  $whereClause = "";
82  $params = array();
83 
84  if ($user_pk > 0) {
85  $whereClause = "WHERE lrb.user_fk = $1";
86  $params[] = $user_pk;
87  } elseif ($group_pk > 0) {
88  $whereClause = "WHERE lrb.group_fk = $1";
89  $params[] = $group_pk;
90  }
91 
92  $licenseTextColumn = $includeLicenseText ? ",\n lr.rf_text AS license_text" : "";
93 
94  $sql = "SELECT DISTINCT
95  lrb.rf_text,
96  lr.rf_shortname,
97  lsb.removing,
98  lsb.comment,
99  lsb.acknowledgement,
100  lr.rf_active$licenseTextColumn
101  FROM license_ref_bulk lrb
102  LEFT JOIN license_set_bulk lsb ON lsb.lrb_fk = lrb.lrb_pk
103  LEFT JOIN license_ref lr ON lr.rf_pk = lsb.rf_fk
104  $whereClause
105  ORDER BY lrb.rf_text, lr.rf_shortname";
106 
107  $result = $this->dbManager->getRows($sql, $params);
108 
109  if ($generateJson) {
110  return $this->createJson($result, $includeLicenseText);
111  } else {
112  return $this->createCsvContent($result, $includeLicenseText);
113  }
114  }
115 
121  private function groupResultsByText($result, $includeLicenseText=false)
122  {
123  $grouped = array();
124  foreach ($result as $row) {
125  $text = $row['rf_text'] ?: '';
126  if (!isset($grouped[$text])) {
127  $grouped[$text] = array(
128  'licenses_to_add' => array(),
129  'licenses_to_remove' => array(),
130  'comments' => array(),
131  'acknowledgements' => array(),
132  'is_active_values' => array(),
133  'license_texts' => array()
134  );
135  }
136  if (!empty($row['rf_shortname'])) {
137  if ($row['removing'] === 't' || $row['removing'] === true) {
138  $grouped[$text]['licenses_to_remove'][] = $row['rf_shortname'];
139  } else {
140  $grouped[$text]['licenses_to_add'][] = $row['rf_shortname'];
141  if ($includeLicenseText && !empty($row['license_text'])) {
142  $grouped[$text]['license_texts'][$row['rf_shortname']] = $row['license_text'];
143  }
144  }
145  }
146 
147  if (!empty($row['comment'])) {
148  $grouped[$text]['comments'][] = $row['comment'];
149  }
150 
151  if (!empty($row['acknowledgement'])) {
152  $grouped[$text]['acknowledgements'][] = $row['acknowledgement'];
153  }
154 
155  if ($row['rf_active'] !== null) {
156  $isActive = ($row['rf_active'] === 't' || $row['rf_active'] === true ||
157  $row['rf_active'] === 1 || $row['rf_active'] === '1');
158  $grouped[$text]['is_active_values'][] = $isActive;
159  }
160  }
161 
162  foreach ($grouped as $text => $values) {
163  $grouped[$text]['licenses_to_add'] = array_values(array_unique($values['licenses_to_add']));
164  $grouped[$text]['licenses_to_remove'] = array_values(array_unique($values['licenses_to_remove']));
165  $grouped[$text]['comments'] = array_values(array_unique($values['comments']));
166  $grouped[$text]['acknowledgements'] = array_values(array_unique($values['acknowledgements']));
167  $grouped[$text]['license_texts'] = array_values($values['license_texts']);
168 
169  if (empty($values['is_active_values'])) {
170  $grouped[$text]['is_active'] = null;
171  } else {
172  $grouped[$text]['is_active'] = !in_array(false, $values['is_active_values'], true);
173  }
174 
175  unset($grouped[$text]['is_active_values']);
176  }
177 
178  return $grouped;
179  }
180 
186  private function createCsvContent($result, $includeLicenseText=false)
187  {
188  $headers = array('text', 'licenses_to_add', 'licenses_to_remove', 'comments', 'acknowledgements', 'is_active');
189  if ($includeLicenseText) {
190  $headers[] = 'license_text';
191  }
192  $out = fopen('php://output', 'w');
193  ob_start();
194  fputs($out, $bom =( chr(0xEF) . chr(0xBB) . chr(0xBF) ));
195  fputcsv($out, $headers, $this->delimiter, $this->enclosure);
196 
197  foreach ($this->groupResultsByText($result, $includeLicenseText) as $text => $licenses) {
198  $csvRow = array(
199  $this->normalizeNewlinesForCsv($text),
200  implode('|', array_map(array($this, 'normalizeNewlinesForCsv'), $licenses['licenses_to_add'])),
201  implode('|', array_map(array($this, 'normalizeNewlinesForCsv'), $licenses['licenses_to_remove'])),
202  implode('|', array_map(array($this, 'normalizeNewlinesForCsv'), $licenses['comments'])),
203  implode('|', array_map(array($this, 'normalizeNewlinesForCsv'), $licenses['acknowledgements'])),
204  $licenses['is_active'] === null ? '' : ($licenses['is_active'] ? 'true' : 'false')
205  );
206  if ($includeLicenseText) {
207  $csvRow[] = implode('|', array_map(array($this, 'normalizeNewlinesForCsv'), $licenses['license_texts']));
208  }
209  fputcsv($out, $csvRow, $this->delimiter, $this->enclosure);
210  }
211 
212  $content = ob_get_contents();
213  ob_end_clean();
214  return $content;
215  }
216 
222  private function normalizeNewlinesForCsv($value)
223  {
224  if ($value === null) {
225  return '';
226  }
227  return str_replace(array("\r\n", "\r", "\n"), '\\n', (string)$value);
228  }
229 
235  private function createJson($result, $includeLicenseText=false)
236  {
237  $data = array();
238 
239  foreach ($this->groupResultsByText($result, $includeLicenseText) as $text => $licenses) {
240  $entry = array(
241  'text' => $text,
242  'licenses_to_add' => $licenses['licenses_to_add'],
243  'licenses_to_remove' => $licenses['licenses_to_remove'],
244  'comments' => $licenses['comments'],
245  'acknowledgements' => $licenses['acknowledgements'],
246  'is_active' => $licenses['is_active']
247  );
248  if ($includeLicenseText) {
249  $entry['license_text'] = $licenses['license_texts'];
250  }
251  $data[] = $entry;
252  }
253 
254  return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
255  }
256 }
Helper class to export license reference bulk data as CSV or JSON from the DB.
setDelimiter($delimiter=',')
Update the delimiter.
exportBulkText($user_pk=0, $group_pk=0, $generateJson=false, $includeLicenseText=false)
Export license reference bulk data from the DB as CSV or JSON.
createJson($result, $includeLicenseText=false)
Create JSON content from result array.
normalizeNewlinesForCsv($value)
Convert CR/LF variants to literal for line-safe CSV rows.
groupResultsByText($result, $includeLicenseText=false)
Group flat DB rows by bulk text, splitting licenses into add/remove buckets.
createCsvContent($result, $includeLicenseText=false)
Create CSV content from result array.
setEnclosure($enclosure='"')
Update the enclosure.
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
Utility functions for specific applications.