FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
AdminLicenseCandidate.php
1 <?php
2 /***********************************************************
3  * Copyright (C) 2014-2017 Siemens AG
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  ***********************************************************/
18 
19 namespace Fossology\UI\Page;
20 
30 
32 {
33  const NAME = "admin_license_candidate";
34 
36  private $highlightProcessor;
38  private $highlightRenderer;
40  private $textRenderer;
42  private $licenseDao;
44  private $treeDao;
45 
46 
47  function __construct()
48  {
49  parent::__construct(self::NAME, array(
50  self::TITLE => "Admin License Candidates",
51  self::MENU_LIST => "Admin::License Admin::Candidates",
52  self::REQUIRES_LOGIN => true,
53  self::PERMISSION => Auth::PERM_ADMIN
54  ));
55 
56  $this->highlightProcessor = $this->getObject('view.highlight_processor');
57  $this->highlightRenderer = $this->getObject('view.highlight_renderer');
58  $this->textRenderer = $this->getObject('view.text_renderer');
59  $this->licenseDao = $this->getObject('dao.license');
60  $this->treeDao = $this->getObject('dao.tree');
61  }
62 
68  protected function handle(Request $request)
69  {
70 
71  $rf = intval($request->get('rf'));
72  if ($rf<1) {
73  $vars = array(
74  'aaData' => json_encode($this->getArrayArrayData())
75  );
76  return $this->render('admin_license_candidate.html.twig', $this->mergeWithDefault($vars));
77  }
78 
79  $vars = $this->getDataRow($rf);
80  if ($vars === false) {
81  throw new \Exception('invalid license candidate');
82  }
83  $shortname = $request->get('shortname') ?: $vars['rf_shortname'];
84  $vars['shortname'] = $shortname;
85  $rfText = $vars['rf_text'];
86  $vars['rf_text'] = $rfText;
87 
88  $suggest = intval($request->get('suggest_rf'));
89  $suggestLicense = false;
90  if ($suggest>0) {
91  $suggestLicense = $this->getDataRow($suggest, 'ONLY license_ref');
92  }
93  if (! $suggestLicense) {
94  list ($suggestIds, $rendered) = $this->suggestLicenseId($rfText);
95  if (! empty($suggestIds)) {
96  $suggest = $suggestIds[0];
97  $suggestLicense = $this->getDataRow($suggest, 'ONLY license_ref');
98  $vars['rf_text'] = $rendered;
99  }
100  }
101  if ($suggestLicense !== false) {
102  $vars['suggest_rf'] = $suggest;
103  $vars['suggest_shortname'] = $suggestLicense['rf_shortname'];
104  $vars['suggest_fullname'] = $suggestLicense['rf_fullname'];
105  $vars['suggest_text'] = $suggestLicense['rf_text'];
106  $vars['suggest_url'] = $suggestLicense['rf_url'];
107  $vars['suggest_notes'] = $suggestLicense['rf_notes'];
108  $vars['suggest_risk'] = $suggestLicense['rf_risk'];
109  }
110 
111  /* @var $licenseDao LicenseDao */
112  $licenseDao = $this->getObject('dao.license');
113  $vars['licenseArray'] = $licenseDao->getLicenseArray(0);
114  $vars['scripts'] = js_url();
115 
116  $ok = true;
117  switch ($request->get('do')) {
118  case 'verify':
119  case 'variant':
120  $rfParent = ($request->get('do')=='verify') ? $rf : $suggest;
121  try{
122  $ok = $this->verifyCandidate($rf,$shortname,$rfParent);
123  } catch (\Throwable $th) {
124  $vars['message'] = 'The license text already exists.';
125  break;
126  }
127  if ($ok) {
128  $with = $rfParent ? '' : " as variant of <i>$vars[suggest_shortname]</i> ($rfParent)";
129  $vars = array(
130  'aaData' => json_encode($this->getArrayArrayData()),
131  'message' => 'Successfully verified candidate '.$shortname.$with);
132  return $this->render('admin_license_candidate.html.twig', $this->mergeWithDefault($vars));
133  }
134  $vars['message'] = 'Short name must be unique';
135  break;
136  case 'merge':
137  try {
138  $ok = $this->mergeCandidate($rf,$suggest,$vars);
139  } catch (\Throwable $th) {
140  $vars['message'] = 'The license text already exists.';
141  break;
142  }
143  if ($ok) {
144  $vars = array(
145  'aaData' => json_encode($this->getArrayArrayData()),
146  'message' => "Successfully merged candidate <i>$vars[suggest_shortname]</i> ($suggest) into <i>$vars[rf_shortname]</i> ($rf)");
147  return $this->render('admin_license_candidate.html.twig', $this->mergeWithDefault($vars));
148  }
149  $vars['message'] = 'Sorry, this feature is not ready yet.';
150  break;
151  case 'deletecandidate':
152  return $this->doDeleteCandidate($rf);
153  break;
154  }
155 
156  return $this->render('admin_license_candidate-merge.html.twig', $this->mergeWithDefault($vars));
157  }
158 
159  private function getArrayArrayData()
160  {
161  $sql = "SELECT rf_pk,rf_shortname,rf_fullname,rf_text,group_name,group_pk "
162  . "FROM license_candidate, groups "
163  . "WHERE group_pk=group_fk AND marydone";
164  /* @var $dbManager DbManager */
165  $dbManager = $this->getObject('db.manager');
166  $dbManager->prepare($stmt = __METHOD__, $sql);
167  $res = $dbManager->execute($stmt);
168  $aaData = array();
169  $delete = "";
170  while ($row = $dbManager->fetchArray($res)) {
171  $link = Traceback_uri() . '?mod=' . self::NAME . '&rf=' . $row['rf_pk'];
172  $edit = '<a href="' . $link . '"><img border="0" src="images/button_edit.png"></a>';
173  $delete = '<img border="0" id="deletecandidate'.$row['rf_pk'].'" onClick="deleteCandidate('.$row['rf_pk'].')" src="images/icons/close_16.png">';
174 
175  $aaData[] = array($edit, htmlentities($row['rf_shortname']),
176  htmlentities($row['rf_fullname']),
177  '<div style="overflow-y:scroll;max-height:150px;margin:0;">' . nl2br(htmlentities($row['rf_text'])) . '</div>',
178  htmlentities($row['group_name']),$delete
179  );
180  }
181  $dbManager->freeResult($res);
182  return $aaData;
183  }
184 
185 
186  private function getDataRow($licId,$table='license_candidate')
187  {
188  $sql = "SELECT rf_pk,rf_shortname,rf_fullname,rf_text,rf_url,rf_notes,rf_notes,rf_risk";
189  if ($table == 'license_candidate') {
190  $sql .= ',group_name,group_pk FROM license_candidate LEFT JOIN groups ON group_pk=group_fk '
191  . 'WHERE rf_pk=$1 AND marydone';
192  } else {
193  $sql .= " FROM $table WHERE rf_pk=$1";
194  }
195  /* @var $dbManager DbManager */
196  $dbManager = $this->getObject('db.manager');
197  $row = $dbManager->getSingleRow($sql, array($licId), __METHOD__.".$table");
198  return $row;
199  }
200 
201  private function suggestLicenseId($str)
202  {
203  /* @var $monkOneShotPlugin \Fossology\Monk\UI\Oneshot */
204  $monkOneShotPlugin = plugin_find("oneshot-monk");
205 
206  if (null !== $monkOneShotPlugin) {
207  return $monkOneShotPlugin->scanMonkRendered($str);
208  } else {
209  return array(array(), $str);
210  }
211  }
212 
219  private function verifyCandidate($rf, $shortname, $rfParent)
220  {
221  /* @var $licenseDao LicenseDao */
222  $licenseDao = $this->getObject('dao.license');
223  if (!$licenseDao->isNewLicense($shortname, 0)) {
224  return false;
225  }
226 
227  /* @var $dbManager DbManager */
228  $dbManager = $this->getObject('db.manager');
229  $dbManager->begin();
230  $dbManager->getSingleRow('INSERT INTO license_ref (rf_pk, rf_shortname, rf_text, rf_url, rf_add_date, rf_copyleft,
231  "rf_OSIapproved", rf_fullname, "rf_FSFfree", "rf_GPLv2compatible", "rf_GPLv3compatible", rf_notes, "rf_Fedora",
232  marydone, rf_active, rf_text_updatable, rf_md5 , rf_detector_type, rf_risk)
233  (SELECT rf_pk, $2 as rf_shortname, rf_text, rf_url, now() as rf_add_date, rf_copyleft,
234  "rf_OSIapproved", rf_fullname, "rf_FSFfree", "rf_GPLv2compatible", "rf_GPLv3compatible", rf_notes, "rf_Fedora",
235  false AS marydone, rf_active, rf_text_updatable, md5(rf_text) rf_md5 , 1 rf_detector_type, rf_risk
236  FROM license_candidate WHERE rf_pk=$1)',array($rf,$shortname),__METHOD__.'.insert');
237  $dbManager->insertTableRow('license_map',array('rf_fk'=>$rf,'rf_parent'=>$rfParent,'usage'=>LicenseMap::CONCLUSION));
238  $dbManager->getSingleRow('DELETE FROM license_candidate WHERE rf_pk=$1',array($rf),__METHOD__.'.delete');
239  $dbManager->commit();
240  return true;
241  }
242 
243  private function mergeCandidate($candidate, $suggest, $vars)
244  {
246  $dbManager = $this->getObject('db.manager');
247  $tableColumnMap = array("license_file"=>"rf_fk",
248  "license_set_bulk"=>"rf_fk",
249  "clearing_event"=>"rf_fk");
250  foreach ($tableColumnMap as $table=>$column) {
251  $dbManager->prepare($stmt=__METHOD__.".$table","UPDATE $table SET $column=$1 WHERE $column=$2");
252  $dbManager->freeResult( $dbManager->execute($stmt,array($suggest,$candidate)) );
253  }
254  $updates = array();
255  if (empty($vars['suggest_url']) && $vars['rf_url']) {
256  $updates[$vars['rf_url']] = 'rf_url=$' . (count($updates)+1);
257  }
258  if (!$vars['rf_notes']) {
259  $updates[$vars['suggest_notes']."\n".$vars['rf_notes']] = 'rf_notes=$' . (count($updates)+1);
260  }
261  if (count($updates)) {
262  $sql = 'UPDATE license_ref SET '.implode(',', $updates).' WHERE rf_pk=$'.(count($updates)+1);
263  $dbManager->prepare($stmt=__METHOD__.'.update',$sql);
264  $params = array_keys($updates);
265  $params[] = $suggest;
266  $dbManager->freeResult( $dbManager->execute($stmt,$params) );
267  }
268  $dbManager->prepare($stmt=__METHOD__.'.delete','DELETE FROM license_candidate WHERE rf_pk=$1');
269  $dbManager->freeResult( $dbManager->execute($stmt,array($candidate)) );
270  return true;
271  }
272 
273  protected function doDeleteCandidate($rfPk)
274  {
275  $dbManager = $this->getObject('db.manager');
276  $stmt = __METHOD__.".getUploadtreeFkForUsedCandidates";
277  $dbManager->prepare($stmt, "SELECT uploadtree_fk
278  FROM clearing_event
279  WHERE removed=false
280  AND date_added IN(SELECT max(date_added)
281  FROM clearing_event
282  WHERE rf_fk=$1
283  GROUP BY uploadtree_fk)");
284  $result = $dbManager->execute($stmt, array($rfPk));
285  $dataFetch = $dbManager->fetchAll($result);
286  $dbManager->freeResult($result);
287  if (empty($dataFetch)) {
288  $dbManager->getSingleRow('DELETE FROM license_candidate WHERE rf_pk=$1', array($rfPk), __METHOD__.".delete");
289  return new Response('true', Response::HTTP_OK, array('Content-type'=>'text/plain'));
290  } else {
291  $treeDao = $this->getObject('dao.tree');
292  $message = "<div class='candidateFileList'><ol>";
293  foreach ($dataFetch as $cnt => $uploadTreeFk) {
294  $message .= "<li>".$treeDao->getFullPath($uploadTreeFk['uploadtree_fk'], 'uploadtree')."</li>";
295  }
296  $message .= "</ol></div>";
297  return new Response($message, Response::HTTP_OK, array('Content-type'=>'text/plain'));
298  }
299  }
300 }
301 
302 register_plugin(new AdminLicenseCandidate());
Traceback_uri()
Get the URI without query to this location.
render($templateName, $vars=null, $headers=null)
plugin_find($pluginName)
Given the official name of a plugin, return the $Plugins object.
list_t type structure used to keep various lists. (e.g. there are multiple lists).
Definition: nomos.h:321
js_url()
Load a new url.