<?php
/**
 * THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (http://www.eclipse.org/legal/epl-v10.html). 
 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
 * 
 */

 /**
  * 
  */
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/common/xmlwrapper.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/common/release.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/common/blog.class.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/common/ships.class.php");

/**
 * Project Information parsed from projec-info/project-info.xml and the eclipse foundation database.
 * 
 * @license http://www.eclipse.org/legal/epl-v10.html Eclipse Public License - v 1.0
 *  
 * @author Bjorn Freeman-Benson
 * @example project_info.php An Example of the usage of <b>project-info.class.php</b>, using the Eclipse Visual Style, CSS, Layout and Navigation
 * @link /projects/common/doc/examples/project_info.php Working example using Eclipse Visuals & Layout
 * @example simple_project.php A less sophisticated example
 * @link /projects/common/doc/examples/simple_project.php Results of the less sophisticated example 
 */
class ProjectInfo {
	
	var $project_id = "";
	var $xmlArray= array();
	var $XMLWrapper = null;	
	var $DashboardInfo = null;
	/**
	 * Constructor, it takes the Project Key (as in the Foundation Database) as a parameter
	 * 
	 * Create a new ProjectInfo object. 
     * The ProjectInfo object aggregates data from a number of sources 
     * into one convenient object. 
     * 
     * @param string $projectkey    the project's key  as in the Eclipse Foundation's database  
     *                              of projects. These keys are assigned by the EMO. 
     * 
	 * @return ProjectInf A brand new ProjectInfo object
	 * 
	 */ 
	function ProjectInfo($projectkey) {
			
        if(eregi("eclipse.org", $_SERVER['SERVER_NAME']))
        {
		    $url = $_SERVER['DOCUMENT_ROOT'] . "/projects/web-api/project-info-inner.php";
           	ob_start();
            $_REQUEST['project'] = $projectkey;
            include( $url );
          	$contents = ob_get_contents();
			ob_end_clean();
        } else { 
		    $url = "http://www.eclipse.org/projects/web-api/project-info.php?project=" . urlencode($projectkey);
			$lines =  file( $url );
			if( $lines == false ) return;
			$contents = implode( "", $lines );
		}
		
		$contents = preg_replace( "/\<\!--.*?--\>/s", "", $contents );
    	$this->xmlArray= XML_unserialize($contents);
		$this->XMLWrapper = new XMLWrapper($contents);

		$this->project_id = $projectkey;
	}
  
  	/**
  	 * The Project Name
  	 * 
	 * Returns the full name of the project.
	 * Source: Foundation database.
	 * 
	 * @access public
	 * @return string The name of the Project as on the Foundation Database
	 */   
	function get_name() {
		return @ html_entity_decode($this->XMLWrapper->getElement(array('project','get-name')));
	}
   /**
    * The Project IP Log URL
    * 
    * Each Eclipse project is required to maintain a current Project IP Log.
    * See http://www.eclipse.org/projects/dev_process/project-log.php
    * 
    * URL to the project's current Project IP Log.
    * An absolute URL of the eclipse.org page (e.g., "/webtools/jst/index.php"),
    * or NULL if there is no current Project IP Log.
    * Source: project-info.xml
    * 
    * @return string The URL of the Project IP Log.
    * @access public
    */
	function ip_log_url() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','ip-log-url')));
	}
	/**
	 * The Project Bug's URL
	 * 
	 * Some Eclipse projects have a separate web page describing how to submit
	 * a bug, how bugs are prioritized, and other useful information.
	 * This is the URL of that page, if there's no such page, it will default to
	 * the first bugzilla product of this project.
	 * 
	 * @return string The URL of the project's bugs
	 * @access public
	 * 
	 */
	function bugs_url() {
		return @ html_entity_decode($this->XMLWrapper->getElement(array('project','bugs-url')));
	}
	/**
	 * The Project Committers URL
	 * 
	 * Committers and non-committer Contributors are the raison d'etre of
	 * an Eclipse project, thus each project should list and acknowledge these 
	 * developers. This is the URL of the project's page listing its committers.
	 * 
	 * @access public
	 * @return string The URL of the project committer list.
	 */
	function committers_url() {
		return @ html_entity_decode($this->XMLWrapper->getElement(array('project','committers-url')));
	}
	/**
	 * The Project Contributors URL
	 * 
	 * Committers and non-committer Contributors are the raison d'etre of
	 * an Eclipse project, thus each project should list and acknowledge these 
	 * developers. This is the URL of the project's page listing its contributors.
	 * 
	 * @access public
	 * @return string The URL of the project contributors list.
	 */
	function contributors_url() {
		return @ html_entity_decode($this->XMLWrapper->getElement(array('project','contributors-url')));
	}
	/**
	 * The Project CVS URL
	 * 
	 * The source code of each Eclipse project is stored in CVS. Eclipse maintains
	 * a number of CVS repositories, this returns the URL this project's
	 * source code.
	 * 
	 * @access public
	 * @return string The Project CVS URL
	 */
	function cvs_url() {
		return @ html_entity_decode($this->XMLWrapper->getElement(array('project','cvs-url')));
	}
	/**
	 * The Project Description URL
	 * 
	 * The URL with the description of this Eclipse project, there you can find the full description
	 * of the project.
	 * 
	 * @access public
	 * @return string The Project Description URL
	 */
	function description_url() {
		return @ html_entity_decode($this->XMLWrapper->getElement(array('project','description-url')));
	}
	/**
	 * The Project's Description-in-a-paragraph URL 
	 * 
	 * The URL with the description of this Eclipse project in just a paragraph
	 * 
	 * @access public
	 * @return string The Project's Description-in-a-paragraph URL
	 */
	function description_paragraph() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','description-paragraph')));
	}
	/**
	 * The Project's Summary URL 
	 * 
	 * The Project Summary in a Paragraph. Each Eclipse project is required to
     * provide an up-to-date status summary. This URL points to a file containing a number of 
     * simple HTML paragraphs with an executive summary of the project status.
	 * 
	 * @access public
	 * @return string The Project's Summary  URL
	 */	
	function summary_paragraph() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','summary-paragraph')));
	}
	/**
	 * The Project Download URL
	 * 
	 * The URL of the project downloads section
	 * 
	 * @access public
	 * @return string The project download URL
	 */
	function downloads_url() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','downloads-url')));
	}
	/**
	 * The Project <i>Getting Started</i> URL
	 * 
	 *  It is important to help new users get started with an Eclipse project
	 *  because most Eclipse projects are solving some difficult technical
	 *  problem and thus are somewhat complex. This URLpoints to a web page on 
	 *  the project's site that describes how to
	 *  get started using and extending the project's tools and frameworks.
	 * 
	 * @access public
	 * @return string The project getting started URL
	 */
	function getting_started_url() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','getting-started-url')));
	}

	/**
	 * The Project Leaders URL
	 * 
	 * Committers and non-committer Contributors are the raison d'etre of
	 * an Eclipse project, thus each project should list and acknowledge these 
	 * developers. Some of the Committers are 'special' in the sense that
	 * they are the project leaders.
	 * This is the URL of the project's leader page.
	 * 
	 * @access public
	 * @return string The URL of the project leader page.
	 */
	function leaders_url() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','leaders-url')));
	}
	/**
	 * The Project Mailing Lists home page
	 * 
	 * Each Eclipse project has one or more mailing lists.
	 * Some projects also have a separate web page describing these lists
	 * while others rely on the main Eclipse mailing lists page. 
	 * If there's no such page, the url will default to the Eclipse mailing lists page.
	 * 
	 * @access public
	 * @return string The project mailinglist home page URL
	 * 
	 */
	function mailing_lists_url() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','mailing-lists-url')));
	}
	/**
	 * The Project Plan URL
	 * 
	 * Each Eclipse project needs to have a plan both for its internal purposes
	 *     (to guide development and resource allocation) and for the larger Eclipse
	 *     community and ecosystem to understand what will be delivered and when
	 *     it will be delivered. This is the URL of the plan.
	 * 
	 * @access public
	 * @return string The URL of the project's plan
	 */
	function project_plan_url() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','project-plan-url')));
	}
    /**
     * @access public
     * @return string The name of the project (from the Foundation DB)
     */
	function getName() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','name')));
	}
	 /**
     * @access public
     * @return string The short name of the project (from the Foundation XML file) or the Project ID if no shortname was found.
     */
	function getShortName() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','short-name')));
	}
	 /**
     * @access public
     * @return string The description of the project (from the Foundation DB)
     */   
	function getDescription() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','description')));
	}
	 /**
	  * Returns the HTML of the project's project-page-paragraph.html This is fetch from
	  * project_index/project-info/project-page-paragraph.html unlike the description_pargraph()
	  * method which gets the one specified in the XML.
	  * 
	  * @access public
	  * @return string The description of the project (from the project-page-paragraph.html)
      */   
	function getParagraph() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','paragraph')));
	}
	 /**
     * @access public
     * @return string The Project ID (from the Foundation DB)
     */
	function getProjectID() {
		$id = $this->XMLWrapper->getElement(array('project','project-id'));
		if(strlen($id) <= 0)
			$id = $this->project_id;
		return @ html_entity_decode ($id) ;
	}
	 /**
     * @access public
     * @return integer The Project Level (from the Foundation DB)
     */	
	function getLevel() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','level')));
	}
	/**
     * @access public
     * @return  string The Project Parent's ID (from the Foundation DB)
     */
	function getParentProjectID() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','parent-project-id')));
	}
	 /**
     * @access public
     * @return string The Project Download URL (from the Foundation DB)
     */	
	function getUrlDownload() {
		return @ $this->downloads_url();
	}
	/**
     * @access public
     * @return string The Project Home Page (from the Foundation DB)
     */
	function getUrlIndex() {
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','url-index')));
	}
	 /**
	 * Returns the isArchived value of the Foundation Database.
	 * 
	 * Projects under the Eclipse Technology Project have limited lifecycles. 
	 * Unlike the major top-level Projects, the Technology Projects are meant to be technology explorations or incubators. 
	 * When these projects have explored, proved, or disproved their associated technologies, the project comes to its 
	 * natural end. For some projects, this end is a paper publishing the research results; for others, this end is to 
	 * be incorporated into the base technology of another top-level project, shuch projects are archived and described
	 * 
	 * 
	 * @access public
	 * @link http://www.eclipse.org/technology/archived.php Archived Technology Projects
	 * @return boolean true if the project is archived, false otherwise;
	 */	
	function isArchived() {
		$exclude = $this->XMLWrapper->getElement(array('project','is-archived'));
		if( isset($exclude))
		{
			return true;
		}
		else
		{
			return false;
		}
		
	}
    /**
     * Returns wether <exclude-from-dashboard/> was found in the XML file or not 
     * 
     * Returns true if the <exclude-from-dashboard/> tag was found in the XML file
     * false otherwise.
     * 
	 * @access public
     * @return boolean true if <exclude-from-dashboard/> was set false otherwise
     */
	function exclude_from_dashboard() {
		$exclude = $this->XMLWrapper->getElement(array('project','exclude-from-dashboard'));
		if( isset($exclude))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
    /**
     * HTML fragment with the project name and a link to
     * to the project's home page.
     * Source: Foundation database.
     * 
	 * @access public
     */
    function linked_name() {
	    $url = $this->getUrlIndex();
		$projectName = $this->getName();
		if( $url != "" ) {
			return "<a href=\"$url\">" . $projectName . "</a>";
		} else {
			return $projectName;
		}
    }  

	/* bjorn recently added functions */

	/**
	 * Returns the team url of the project
	 * 
	 * Committers and non-committer Contributors are the raison d'etre of 
     * an Eclipse project, thus each project should list and acknowledge these
     * developers. Some of the Committers are 'special' in the sense that
     * they are the project leaders.  This function returns the 
     * URL of the project's pages listing these important people.
     * 
     * @return string  the URL of the project's pages listing committers and non-committer contributors.
	 */
	function team_url() {
		$url = @ html_entity_decode($this->XMLWrapper->getElement(array('project','team attr', 'url')));
		if(strlen($url)> 0 && !(stristr("http://", $url)))
			$url = "http://eclipse.org". $url;
		$url = _un_encode_url($url);
		return $url;
	}
	/**
	 * Returns the Legal Information page URL
	 * 
	 * If the project has a legal information web page, this will return it's URL
	 *
	 * @access public
	 * @return string the URL of the project's legal information
	 */
	function legal_url() {
		$url = @ html_entity_decode($this->XMLWrapper->getElement(array('project','legal attr', 'url')));		
		//$url = _getXpathValues($this->dom, "//project/legal/@url");
		if(strlen($url)> 0 && !(stristr("http://", $url)))
			$url = "http://eclipse.org". $url;
		$url = _un_encode_url($url);
		return $url;
	}
	/**
	 * Returns the web page on the project's site that describes how to get started developing on, and contributing to, the project
	 * 
	 * It is also important to help new contributors get started with an Eclipse project.
	 * Most Eclipse projects have interesting/complex development environment
     * setups or to-do lists. This URL points to a web page on the project's site that describes 
     * how to get started developing on, and contributing to, the project.
     * 
	 * @access public
     * @return string the project's URL that describes how to get started developing on, and contributing to, the project
	 */
	function contributing_url() {
		$url = @ html_entity_decode($this->XMLWrapper->getElement(array('project','contributing attr', 'url')));
		//$url = _getXpathValues($this->dom, "//project/contributing/@url");
		if(strlen($url)> 0 && !(stristr("http://", $url)))
			$url = "http://eclipse.org". $url;
		$url = _un_encode_url($url);
		return $url;
	}
	/**
	 * Returns the URL of the newsgroup page describing these lists
	 * 
     * Each Eclipse project has one or more newsgroups.
     * Some projects also have a separate web page describing these lists
     * while others rely on the main Eclipse newsgroups page.
     * 
	 * @access public
     * @return string the URL of the newsgroup page, if none set it will default to the first newsgroup page
	 */
	function newsgroups_url() {
		$url = "";
		$url = @ html_entity_decode($this->XMLWrapper->getElement(array('project','newsgroups attr', 'url')));
		if(strlen($url)> 0 && !(stristr("http://", $url)))
		{
			$url = "http://eclipse.org". $url;
			$url = _un_encode_url($url);
			return $url;
		}
		$name = $this->getNewsgroup(0);
		if( isset($name) ) {
			return "http://dev.eclipse.org/newslists/news." . $name	. "/maillist.html";
		}
		return NULL;
	}    

	/* has things */
	
	/**
	 * The number of Blogs for the Project
	 * @access public
	 * @return integer The number of Blogs this project has
	 */
	function hasBlogs()
	{
		return @ count($this->XMLWrapper->getElement(array('project','blogs', 'blog')));
	}
	
	/**
	 * The number of Articles related to this Project
	 * @access public
	 * @return integer The number of Articles related to this Project
	 */
	function hasArticles()
	{
		return @ count($this->XMLWrapper->getElement(array('project','articles','article')));
	}
	
	 /**
 	 * The number of Bugzilla Products for this project
	 * @access public
	 * @return integer The number of bugzilla products for the project
	 */		 
	function hasBugzilla()
	{
		return @ count($this->XMLWrapper->getElement(array('project','bugzilla','product')));
	}

	/**
	 * The number of Bugzilla Products for this project
	 * @access public
	 * @return integer The number of bugzilla products for the project
	 */	
	function hasBugzillaProducts()
	{
		return @ count($this->XMLWrapper->getElement(array('project','bugzilla','product')));
	}

	/**
	 * The number of Mailing Lists for this project
	 * @access public
	 * @return integer The number of mailing lists for the project
	 */		
	function hasLists()
	{
		return @ count($this->XMLWrapper->getElement(array('project','mailing-lists','list')));
	}
	
	/**
	 * The number of Newsgroups for this project
	 * @access public
	 * @return integer The number of newsgroups for the project
	 */	
	function hasNewsgroups()
	{
		return @ count ($this->XMLWrapper->getElement(array('project','newsgroups','newsgroup')));
	}	

	/**
	 * The number of Planned Releases for this project
	 * @access public
	 * @return integer The number of planned releases for this project
	 */
	function hasReleases()
	{
		$num_releases = 0;
		$releases = $this->XMLWrapper->getElement(array('project','releases', 'release'));
		$total_releases = count($releases);
		if(!@array_key_exists("0", $releases))
			$total_releases = 1;
		for($s=0; $s<$total_releases; $s++)
		{
			$release = $this->XMLWrapper->getElement(array('project','releases', 'release', $s));
			if(@array_key_exists("status", $release) && $release['status'] != "complete")
				$num_releases++;			
		}
		return $num_releases;		
		
	}
	
	function hasShippings()
	{		
		$num_shippings = 0;
		$shippings = $this->XMLWrapper->getElement(array('project','releases', 'release'));
		$total_releases = count($shippings);
		if(!@array_key_exists("0", $shippings))
			$total_releases = 1;
		for($s=0; $s<$total_releases; $s++)
		{
			$shipping = $this->XMLWrapper->getElement(array('project','releases', 'release', $s));
			if(@array_key_exists("status", $shipping) && $shipping['status'] == "complete")
				$num_shippings++;			
		}
		return $num_shippings;
	}

	/**
	 * The number of CVS Modules of this project
	 * @access public
	 * @return integer The number of cvs modules for the project
	 */
	function hasCVSModules()
	{
		return @ count ($this->XMLWrapper->getElement(array('project','cvs','module')));
	}	

    /* get more cool stuff */
	
	/**
	 * Returns the planed releases of this project.
	 * Planed Releases are those where status='scheduled' or status='tentative'  
	 * 
	 * @param integer $n The index of the release
	 * @access public
	 * @return Release The <i>n</i>th planned release of this project
	 */
	function getRelease($index)
	{
		$rel = $this->XMLWrapper->getElement(array('project','releases','release',$index));
		if(isset($rel))
		{
			$name = $rel['name'];
			$date = $rel['date'];
			$status = $rel['status'];
			$url =  $rel['download'];
			$plan = @ $rel['plan'];
			
			$release = new Release($name, $date, $status, $plan , $url);
			return $release;
		}
		else
			return NULL;	
	}

	/**
	 * Returns the releases Currently Shipping, those where status='completed'  
	 * 
	 * @param integer $n The index of the release
	 * @access public
	 * @return Shipping The <i>n</i>th currently shipping release of this project
	 */
	function getShipping($index)
	{
		$num_shipping = 0;
		$num_releases = count($this->XMLWrapper->getElement(array('project','releases', 'release')));
		$shipp = NULL;
		for($s=0; $s<$num_releases; $s++)
		{
			$shipping = $this->XMLWrapper->getElement( array('project','releases','release',$s) );
			if($shipping['status'] == "complete")
			{				
				if($num_shipping == $index)	
				{
					$name = $shipping['name'];
					$date = $shipping['date'];
					$url =  $shipping['download'];

					$shipp = new Shipping($name, $date, $url);
					break;	
				}
				$num_shipping++;		
			}
						
		}
		return $shipp;
	}

	/**
	 * From time to time members of the development team and other members of the eclipse community write Articles,
	 * articles related with this project can be retrieved here.   
	 * 
	 * The URL of an Article related to this project
	 * 
	 * @param integer $n The index of the Blog 
	 * @access public
	 * @return string The URL of the <i>n</i>th Article
	 */	
	function getArticleAt($index)
	{
		return @  html_entity_decode ($this->XMLWrapper->getElement(array('project','articles','article',$index)));
	}	

	/**
	 * Returns the Blog of this project  
	 * 
	 * @param integer $n The index of the Blog 
	 * @access public
	 * @return Blog The <i>n</i>th Blog of the project
	 */	
	function getBlog($index)
	{
		$url = $this->XMLWrapper->getElement(array('project','blogs','blog',$index));
		$blog = new Blog($url);
		return $blog;
	}	
	
	
	/**
	 * Returns the name of the CVS Modules of this project  
	 * 
	 * @param integer $n The index of the CVS Module 
	 * @access public
	 * @return string The name of the <i>n</i>th CVS Module of the project
	 */	
	function getCVSModule($index)
	{
		return @  html_entity_decode ($this->XMLWrapper->getElement(array('project','cvs','module',$index)));
	}		
	
	/**
	 * Returns the name of the Bugzilla Products of this project  
	 * 
	 * @param integer $n The index of the product 
	 * @access public
	 * @return string The name of the <i>n</i>th Bugzilla Product of the project
	 */
	function getBugzillaProduct($index)
	{
			return @  html_entity_decode ($this->XMLWrapper->getElement(array('project','bugzilla','product',$index)));
	}
	
	/**
	 * Returns the URL of the Bugzilla Products of this project  
	 * 
	 * @param integer $n The index of the product 
	 * @access public
	 * @return string The URL of the <i>n</i>th Bugzilla Product of the project
	 */
	function getBugzilla($index)
	{		
		return @ "https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced&product=" . $this->getBugzillaProduct($index) . "&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED";
	}	


	/**
	 * Returns the name of the mailing lists of this project  
	 * 
	 * @param integer $n The index of the mailing list
	 * @access public
	 * @return string The name of the <i>n</i>th mailing list of the project
	 */
	function getList($index)
	{
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','mailing-lists','list',$index)));
	}

	/**
	 * Returns the name of the newsgroups of this project  
	 * 
	 * @param integer $n The index of the newsgroup 
	 * @access public
	 * @return string The name of the <i>n</i>th newsgroup of the project
	 */
	function getNewsgroup($index)
	{
		return @ html_entity_decode ($this->XMLWrapper->getElement(array('project','newsgroups','newsgroup',$index)));
	}
	
	/**
     * This method fetchs the Dashboard information from the database, this is 
     * called by all the dashboard_* methods and shouldn't be used by itself
     * since it may cause unnecessary overhead.
     * 
     * @access private
     */
    function getDashboard($_date = "")
    {
		require_once($_SERVER['DOCUMENT_ROOT'] . "/projects/common/dashboardinfo.class.php");
				
		$this->dashboard_week = $_date;
				
		$this->DashboardInfo = new DashboardInfo( $this->project_id, $_date);
		
		$this->dashboard_fetched = true;
    	$this->timestamps['dashboard'] = time();
    }
	

    /**
     * Returns the Liveness of a project
     * 
     * Returns the liveness of the project, according to the Project Dashboards calculations formula:
     * <pre>
     * 1 * log(last week change in number of bugs) +
     * 1 * log(last week bug fix rate percentage) +
     * 2 * log(last month bug fix rate percentage) +
     * 1 * log(180 day bug fix rate percentage) +
     * 2 * log(last week number of newsgroup postings) +
     * 2 * 1/(last week newsgroup answers times) +
     * 3 * log(last month number of newsgroup postings) +
     * 3 * 1/(last month newsgroup answers times).
     * </pre>
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @example examples/dashboard_lights.php A simple example
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_liveness($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
     	return $this->DashboardInfo->getLiveness();	
     }
     
    /**
     * Returns the number of bugs this project has
     * 
     * 
     * The number of bugs this project has in the Eclipse Bugzilla bug tracking system 
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://bugs.eclipse.org
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_bugs($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched)
     		$this->getDashboard($_week);	

		return $this->DashboardInfo->getBugs();     	
     }
     
     
     /**
     * 
     * How the number number of bugs this project has changed in the past week 
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
      * @access public
    */
     function dashboard_bugs_7_delta($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getBugs7Delta();
     }

     /**
     * 
     * How the number number of bugs this project has changed in the past month 
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_bugs_30_delta($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getBugs30Delta();     	
     }

     /**
     * 
     * How the number number of bugs this project has changed in the past 180 days 
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_bugs_180_delta($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getBugs180Delta();
     }
     
     /**
     * Past 7 days Bug fix rate 
     * 
     * The difference in the number of closed (resolved, closed, and verified) bugs and 
     * enhancements to the number of open and active (P1, P2, P3) bugs for the <i>last week</i>. 
     * The goal is to keep the number positive because then the project is fixing bugs and 
     * implementing features faster than bugs are being reported.   
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_bugs_7_percentage($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getBugs7Percentage();
     }

     /**
     * Past 30 dyas Bug fix rate 
     * 
     * The difference in the number of closed (resolved, closed, and verified) bugs and 
     * enhancements to the number of open and active (P1, P2, P3) bugs for the <i>last month</i>. 
     * The goal is to keep the number positive because then the project is fixing bugs and 
     * implementing features faster than bugs are being reported.   
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_bugs_30_percentage($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getBugs30Percentage();     	
     }

     /**
     * Past 180 days Bug fix rate 
     * 
     * The difference in the number of closed (resolved, closed, and verified) bugs and 
     * enhancements to the number of open and active (P1, P2, P3) bugs for the past<i>180 days</i>. 
     * The goal is to keep the number positive because then the project is fixing bugs and 
     * implementing features faster than bugs are being reported.   
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */
     function dashboard_bugs_180_percentage($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getBugs180Percentage();
     }
     
     
     /**
     * Number of posts in the past 7 days
     *  
     * Total number of posts made in the last 7 days. The number of posts will be -1 when the
     * newsgroup for a project does not exist and it is not possible to compute the statistics. 
     * When the group for the project exists but it is currently empty (no posts) or there are
     * no posts for the last 7 days then it will be 0.
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */     
     function dashboard_news_7_number_posts($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getNews7NumberPosts();     	
     }

     /**
     * Number of posts in the past 30 days
     *  
     * Total number of posts made in the last 30 days. The number of posts will be -1 when the
     * newsgroup for a project does not exist and it is not possible to compute the statistics. 
     * When the group for the project exists but it is currently empty (no posts) or there are
     * no posts for the last 30 days then it will be 0.
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */  
     function dashboard_news_30_number_posts($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getNews30NumberPosts();
     }
     
     
     /**
     * Average time to response a post (past 7 days)
     *  
     * Average time it takes for a post that was answered to be answered in the last 7 days. 
     * The Time To Reply (TTR) is computed as the difference between the time of the original 
     * post and the time of the reply using the NNTP-Posting-Date. If there were no answers for 
     * the specified period then the it will be 0. If the newsgroup does 
     * not exist then it will be -1.
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */      
     function dashboard_news_7_answer_average_time($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getNews7AnswerAverageTime();
     }   

     /**
     * Average time to response a post (past 30 days)
     *  
     * Average time it takes for a post that was answered to be answered in the last 30 days. 
     * The Time To Reply (TTR) is computed as the difference between the time of the original 
     * post and the time of the reply using the NNTP-Posting-Date. If there were no answers for 
     * the specified period then the it will be 0. If the newsgroup does 
     * not exist then it will be -1.
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     */      
     function dashboard_news_30_answer_average_time($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		return $this->DashboardInfo->getNews30AnswerAverageTime();
     }
     
     
    /**
     * HTML dashboard-like Bug Lights
     * <pre>
     *
     * There's 3 lights they represent last week, last month and last 180 days: 
     * 
     * <7> <30> <180>
     *
     * Light 	  			
     * white light		Regular
     * green  light	  	Good
     * red light	  	Bad
     * </pre>
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     * @example examples/dashboard_lights.php A simple example
     * 
     */
     function dashboard_bugs_lights($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		$this->DashboardInfo->PrintBugsLights();
		
     }

    /**
     * HTML dashboard-like News Lights
     * <pre>
     *
     * There's 4 lights they represent number of posts and average response time to a post
     * for the last 7 and 30 days: 
     * 
     * <#posts_7> <#posts_30> <#avg_ttr_7> <#avg_ttr_30>
     *  
     * Light 	  			
     * white light		Regular
     * green  light	  	Good
     * red light	  	Bad
     * </pre>
     * 
     * Optionally you can pass a week in MySQL date format (yyyy-mm-dd) to fetch
     * results for the week starting on that date. If no $_week is given current calculations are used.   
     * 
     * @link http://www.eclipse.org/projects/dashboard/descriptions.php
     * @param string week The week of the calculations
     * @access public
     * @example examples/dashboard_lights.php A simple example
     */     
     function dashboard_news_lights($_week = "")
     {
     	if($this->dashboard_week != $_week || !$this->dashboard_fetched )
     		$this->getDashboard($_week);	
     	
		$this->DashboardInfo->PrintNewsLights();
     }  


	/**
	 * Generate the common left menu navigation menu
	 */
    function generate_common_nav( $thenav, $users = NULL, $integrators = NULL, $contributors = NULL ) {
    	global $Nav;
    	$Nav->setLinkList( array() );
    	$Nav->addNavSeparator( $this->getShortName(), $this->getUrlIndex() );
    	
        $Nav->addCustomNav("About", $this->description_url(), "", 1);
	        if( $this->team_url() != ""
	         || ($this->leaders_url() == "" && $this->committers_url() == "" && $this->contributors_url() == "") ) {
	        $Nav->addCustomNav("Team", $this->team_url(), "", 2);
	        } else { /* old-style */
	        $Nav->addCustomNav("Team", "#", "", 2);
		        $Nav->addCustomNav("Leaders", $this->leaders_url(), "", 3);
		        $Nav->addCustomNav("Committers", $this->committers_url(), "", 3);
		        $Nav->addCustomNav("Contributors", $this->contributors_url(), "", 3);
	        }
	        $Nav->addCustomNav("Plan", $this->project_plan_url(), "", 2);
	        if( $this->legal_url() != "" ) {
	        $Nav->addCustomNav("Legal", $this->legal_url(), "", 2);
	        } else { /* old-style */
	        $Nav->addCustomNav("Legal", $this->ip_log_url(), "", 2);
	        }
        $Nav->addCustomNav("Users", $this->getting_started_url(), "", 1);
 	        $Nav->addCustomNav("Getting Started", $this->getting_started_url(), "", 2);
	        $Nav->addCustomNav("Downloads", $this->downloads_url(), "", 2);
	        $Nav->addCustomNav("Newsgroups", $this->newsgroups_url(), "", 2);
	        $Nav->addCustomNav("Bugs", $this->bugs_url(), "", 2);
	        if( !empty($users) ) {
	        	$users($Nav);
	        }
        $Nav->addCustomNav("Integrators", "", "", 1);
	        $Nav->addCustomNav("API Plan", $this->project_plan_url(), "", 2);
	        if( !empty($integrators) ) {
	        	$integrators($Nav);
	        }
        $Nav->addCustomNav("Contributors", $this->contributing_url(), "", 1);
	        $Nav->addCustomNav("Contributing", $this->contributing_url(), "", 2);
	        $Nav->addCustomNav("Mailing Lists", $this->mailing_lists_url(), "", 2);
	        if( !empty($contributors) ) {
	        	$contributors($Nav);
	        }
    }
}
?>