14 namespace Fossology\Reuser;
20 use Symfony\Component\HttpFoundation\Request;
21 use Symfony\Component\HttpFoundation\Response;
31 const NAME =
"reusecompare";
39 function __construct()
41 parent::__construct(self::NAME, [
42 self::TITLE => _(
"Reuse Compare"),
43 self::DEPENDENCIES => [
"browse",
"view"],
45 self::REQUIRES_LOGIN =>
true,
48 $this->uploadDao = $this->
getObject(
'dao.upload');
53 menu_insert(
"Browse-Pfile::Reuse Compare", 3, self::NAME,
54 _(
"Compare files with reused upload source."));
61 protected function handle(Request $request)
63 $uploadId = (int)$request->get(
'upload', 0);
64 $item = (int)$request->get(
'item', 0);
66 if (empty($uploadId) || empty($item)) {
67 return $this->flushContent(
68 "<h3>" . _(
"Missing upload or item parameter.") .
"</h3>");
72 if (!$this->uploadDao->isAccessible($uploadId, $groupId)) {
73 return $this->flushContent(
74 "<h2>" . _(
"Permission Denied") .
"</h2>");
77 $tableName = $this->uploadDao->getUploadtreeTableName($uploadId);
80 $reusedUploads = $this->uploadDao->getReusedUpload($uploadId, $groupId);
81 if (empty($reusedUploads)) {
82 return $this->flushContent(
83 "<h3>" . _(
"No reused upload sources found for this upload.") .
"</h3>");
86 $selectedReuseId = (int)$request->get(
'reuse', 0);
90 foreach ($reusedUploads as $ru) {
91 $rid = intval($ru[
'reused_upload_fk']);
92 $ruUpload = $this->uploadDao->getUpload($rid);
93 $ruName = $ruUpload ? $ruUpload->getFilename() :
"unknown";
94 $ruMode = intval($ru[
'reuse_mode']);
100 if ($reuseUploadId === 0 ||
101 ($selectedReuseId > 0 && $rid === $selectedReuseId) ||
102 ($selectedReuseId === 0 && $reuseUploadId === 0)) {
103 $reuseUploadId = $rid;
107 $reuseTableName = $this->uploadDao->getUploadtreeTableName($reuseUploadId);
108 $reuseRootPk = $this->uploadDao->getUploadParent($reuseUploadId);
111 $itemRow = $this->uploadDao->getUploadEntry($item, $tableName);
112 if (empty($itemRow)) {
113 return $this->flushContent(
"<h3>" . _(
"Item not found.") .
"</h3>");
118 $reuseRootRow = $this->uploadDao->getUploadEntry($reuseRootPk, $reuseTableName);
120 if (!empty($reuseRootRow)) {
130 'IDENTICAL' => 0,
'MODIFIED' => 0,
'NEW' => 0,
'REMOVED' => 0
134 $reuseRootLft = $reuseRootRow[
'lft'] ?? 0;
135 $reuseRootRgt = $reuseRootRow[
'rgt'] ?? 0;
136 $licenseMapReusePfiles = !empty($reuseRootRow) ?
140 $licenseMapUpload = [];
141 $licenseMapReuse = [];
143 foreach ($master as $idx => $pair) {
144 $child1 = !empty($pair[1]) ? $pair[1] :
null;
145 $child2 = !empty($pair[2]) ? $pair[2] :
null;
147 $row = $this->
buildDiffRow($child1, $child2, $uploadId, $reuseUploadId,
148 $tableName, $reuseTableName, $uploadPathUri);
150 $stats[$row[
'classification']]++;
154 if ($child1 && !empty($child1[
'pfile_fk'])) {
155 $lics1 = $licenseMapUploadPfiles[(int)$child1[
'pfile_fk']] ?? [];
156 foreach ($lics1 as $lic) {
157 $licenseMapUpload[$lic] = isset($licenseMapUpload[$lic]) ?
158 $licenseMapUpload[$lic] + 1 : 1;
161 if ($child2 && !empty($child2[
'pfile_fk'])) {
162 $lics2 = $licenseMapReusePfiles[(int)$child2[
'pfile_fk']] ?? [];
163 foreach ($lics2 as $lic) {
164 $licenseMapReuse[$lic] = isset($licenseMapReuse[$lic]) ?
165 $licenseMapReuse[$lic] + 1 : 1;
171 $allLicenses = array_unique(array_merge(
172 array_keys($licenseMapUpload), array_keys($licenseMapReuse)));
175 $licenseSummary = [
'new' => 0,
'deleted' => 0,
'modified' => 0,
'unchanged' => 0];
176 $licenseCategories = [
'new' => [],
'deleted' => [],
'modified' => [],
'unchanged' => []];
178 foreach ($allLicenses as $lic) {
179 $upCount = $licenseMapUpload[$lic] ?? 0;
180 $reCount = $licenseMapReuse[$lic] ?? 0;
181 if ($upCount > 0 && $reCount == 0) {
182 $licenseSummary[
'new']++;
183 $licenseCategories[
'new'][] = $lic;
184 } elseif ($upCount == 0 && $reCount > 0) {
185 $licenseSummary[
'deleted']++;
186 $licenseCategories[
'deleted'][] = $lic;
187 } elseif ($upCount != $reCount) {
188 $licenseSummary[
'modified']++;
189 $licenseCategories[
'modified'][] = $lic;
191 $licenseSummary[
'unchanged']++;
192 $licenseCategories[
'unchanged'][] = $lic;
195 $licenseFilter = $request->get(
'license_filter',
'');
196 if (!in_array($licenseFilter, [
'new',
'deleted',
'modified',
'unchanged',
''])) {
201 $searchQuery = $request->get(
'search',
'');
202 $statusFilterQuery = $request->get(
'statusFilter',
'');
203 $queryParams = $request->query->all();
204 $queryParams[
'search'] = $searchQuery;
205 $queryParams[
'statusFilter'] = $statusFilterQuery;
206 unset($queryParams[
'page']);
208 $filteredDiffTree = [];
209 foreach ($diffTree as $row) {
210 if (!empty($statusFilterQuery) && $row[
'classification'] !== $statusFilterQuery) {
213 if (!empty($searchQuery)) {
215 if (stripos($row[
'upload_file_name'], $searchQuery) !==
false ||
216 stripos($row[
'reuse_file_name'], $searchQuery) !==
false) {
223 $filteredDiffTree[] = $row;
225 $diffTree = $filteredDiffTree;
228 $page = (int)$request->get(
'page', 0);
233 $totalDiffRows = count($diffTree);
234 $totalPages = $totalDiffRows > 0 ? (int)ceil($totalDiffRows / $perPage) - 1 : 0;
235 if ($page > $totalPages) {
238 $offset = $page * $perPage;
239 $pagedDiffTree = array_slice($diffTree, $offset, $perPage);
240 $pageUri =
'?' . http_build_query($queryParams);
243 'uploadId' => $uploadId,
245 'reuseUploadId' => $reuseUploadId,
246 'reuseSources' => $reuseSources,
248 'diffTree' => $pagedDiffTree,
249 'pageUri' => $pageUri,
250 'currentPage' => $page + 1,
251 'totalPagesView' => $totalPages + 1,
252 'perPage' => $perPage,
253 'totalDiffRows' => $totalDiffRows,
254 'licenseSummary' => $licenseSummary,
255 'licenseCategories'=> $licenseCategories,
256 'licenseFilter' => $licenseFilter,
257 'totalUpload' => count($children1),
258 'totalReuse' => count($children2),
259 'searchQuery' => $searchQuery,
260 'statusFilterQuery'=> $statusFilterQuery,
263 $defaultVars = $this->mergeWithDefault([]);
264 $defaultVars[
'styles'] .=
"<link rel='stylesheet' href='css/highlights.css'>\n";
265 $vars = array_merge($defaultVars, $vars);
267 return $this->
render(
'reusecompare.html.twig', $vars);
273 private function buildDiffRow($child1, $child2, $uploadId, $reuseUploadId,
274 $tableName, $reuseTableName, $uri)
277 'upload_file_name' =>
'',
278 'reuse_file_name' =>
'',
279 'classification' =>
'',
280 'upload_pfile_fk' => 0,
281 'reused_pfile_fk' => 0,
286 if ($child1 && $child2) {
287 $row[
'upload_file_name'] = $child1[
'ufile_name'];
288 $row[
'reuse_file_name'] = $child2[
'ufile_name'];
289 $row[
'upload_pfile_fk'] = intval($child1[
'pfile_fk']);
290 $row[
'reused_pfile_fk'] = intval($child2[
'pfile_fk']);
292 $upPk = $child1[
'uploadtree_pk'];
293 $rePk = $child2[
'uploadtree_pk'];
294 $row[
'upload_href'] = $uri .
"?mod=view-license&upload=$uploadId&item=$upPk";
295 $row[
'reuse_href'] = $uri .
"?mod=view-license&upload=$reuseUploadId&item=$rePk";
297 if ($child1[
'pfile_fk'] == $child2[
'pfile_fk']) {
298 $row[
'classification'] =
'IDENTICAL';
300 $row[
'classification'] =
'MODIFIED';
303 $row[
'upload_file_name'] = $child1[
'ufile_name'];
304 $row[
'upload_pfile_fk'] = intval($child1[
'pfile_fk']);
305 $row[
'classification'] =
'NEW';
306 $upPk = $child1[
'uploadtree_pk'];
307 $row[
'upload_href'] = $uri .
"?mod=view-license&upload=$uploadId&item=$upPk";
309 $row[
'reuse_file_name'] = $child2[
'ufile_name'];
310 $row[
'reused_pfile_fk'] = intval($child2[
'pfile_fk']);
311 $row[
'classification'] =
'REMOVED';
312 $rePk = $child2[
'uploadtree_pk'];
313 $row[
'reuse_href'] = $uri .
"?mod=view-license&upload=$reuseUploadId&item=$rePk";
324 $sql =
"SELECT ut.pfile_fk, lr.rf_shortname
326 JOIN license_file lf ON lf.pfile_fk = ut.pfile_fk
327 JOIN license_ref lr ON lf.rf_fk = lr.rf_pk
328 WHERE ut.upload_fk = $1
329 AND ut.lft BETWEEN $2 AND $3
330 AND ut.ufile_mode & (3<<28) = 0
331 AND ut.pfile_fk IS NOT NULL
332 AND lr.rf_shortname IS NOT NULL
333 AND lr.rf_shortname NOT IN ('Void')
334 ORDER BY lr.rf_shortname";
335 $stmtName = __METHOD__ .
'_' . $tableName;
336 $this->
dbManager->prepare($stmtName, $sql);
337 $res = $this->
dbManager->execute($stmtName, [$uploadFk, $lft, $rgt]);
339 while ($row = $this->
dbManager->fetchArray($res)) {
340 $pid = (int)$row[
'pfile_fk'];
341 if (!isset($map[$pid])) {
344 $map[$pid][] = $row[
'rf_shortname'];
361 $lft = (int)$itemRow[
'lft'];
362 $rgt = (int)$itemRow[
'rgt'];
363 $pk = (int)$itemRow[
'uploadtree_pk'];
364 $uploadFk = (int)$itemRow[
'upload_fk'];
366 $sql =
"SELECT ut.*, pfile_size, pfile_mimetypefk
368 LEFT JOIN pfile ON (pfile_pk = ut.pfile_fk)
369 WHERE ut.upload_fk = $1
370 AND ut.lft BETWEEN $2 AND $3
371 AND ut.uploadtree_pk != $4
372 AND ut.ufile_mode & (3<<28) = 0
374 $this->
dbManager->prepare($stmt = __METHOD__ .
".$tableName", $sql);
375 $res = $this->
dbManager->execute($stmt, [$uploadFk, $lft, $rgt, $pk]);
377 while ($row = $this->
dbManager->fetchArray($res)) {
385 register_plugin(
new ReuseComparePlugin());
Contains the constants and helpers for authentication of user.
static getGroupId()
Get the current user's group id.
render($templateName, $vars=null, $headers=null)
Compare files in the current upload against their counterparts from the reused upload source....
getAllNonArtifactDescendants($itemRow, $tableName)
batchGetLicensesForUpload($uploadFk, $lft, $rgt, $tableName)
buildDiffRow($child1, $child2, $uploadId, $reuseUploadId, $tableName, $reuseTableName, $uri)
MakeMaster($Children1, $Children2)
Generate the master array with aligned children.
FuzzyName(&$Children)
Add fuzzyname and fuzzynameext to $Children.
Traceback_uri()
Get the URI without query to this location.
fo_dbManager * dbManager
fo_dbManager object