<?php
/**
 * Copyright (c) 2011 Eclipse Foundation and others.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 */

require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/database.inc");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/common.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/classes/debug.php");

class Bug {
	var $bug_id;
	var $title;
	var $product;
	var $component;
	var $target_milestone;

	function getId() {
		return $this->bug_id;
	}

	function getTitle() {
		return $this->title;
	}

	function getProduct() {
		return $this->product;
	}

	function getComponent() {
		return $this->component;
	}

	function getTargetMilestone() {
		return $this->target_milestone;
	}

	function getLink() {
		return "https://bugs.eclipse.org/$this->bug_id";
	}

	function asHtml() {
		$text = "<a href=\"{$this->getLink()}\">{$this->getId()}</a>  {$this->getProduct()}: {$this->getTitle()}";
		if ($milestone = $this->getTargetMilestone()) {
			$text = "{$text} ({$milestone})";
		}
		return $text;
	}
}

/**
 * This function returns an array containing Bug instances representing
 * bugs that have been flagged as resolutions to 'security' issues.
 *
 * @return Bug[]
 */
function findResolvedSecurityBugs() {
	$sql = "select
			b.bug_id as bug_id,
			p.name as product,
			c.name as component,
			b.short_desc as title,
			b.target_milestone as target_milestone
		from bugs as b
			join products as p on (b.product_id=p.id)
			join components as c on (b.component_id = c.id)
			join keywords as k on (b.bug_id=k.bug_id)
			join keyworddefs as kd on (k.keywordid=kd.id)
		where
			b.bug_id not in (select bg.bug_id from bug_group_map as bg join groups as g on (bg.group_id=g.id and g.name = 'Security_Advisories'))
			and kd.name='security'
			and b.bug_status IN ( 'RESOLVED', 'VERIFIED', 'CLOSED' )
			and b.resolution IN ( 'FIXED' )";

	$bugs = array();
	query('bugzilla', $sql, array(), function($row) use (&$bugs) {
		$bug = new Bug();
		$bug->bug_id = $row['bug_id'];
		$bug->title = $row['title'];
		$bug->product = $row['product'];
		$bug->component = $row['component'];
		$bug->target_milestone = $row['target_milestone'];
		$bugs[] = $bug;
	});

	return $bugs;
}
?>