Current File : //opt/RZphp73/includes/QA/Peardoc/Coverage/Renderer/DeveloperList.php
<?php
require_once 'QA/Peardoc/Coverage/Renderer.php';

/**
* Renders a list with developers, the number of packages
* they maintain and the documented/undocumented ratio
*
* @category QA
* @package  QA_Peardoc_Coverage
* @author   Christian Weiske <cweiske@php.net>
* @license  http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
* @version  CVS: $Id: DeveloperList.php,v 1.10 2007/07/18 18:52:44 cweiske Exp $
* @link     http://pear.php.net/package/QA_Peardoc_Coverage
*/
class QA_Peardoc_Coverage_Renderer_DeveloperList
    implements QA_Peardoc_Coverage_Renderer
{
    public static $colNotDocumented = '#F00';
    public static $colDocumented    = '#0F0';
    public static $arLevels = array(
        100 => 'Well done',
         90 => 'Not bad',
         60 => 'Should be better',
         30 => 'Shame on you'
    );



    /**
    * Returns the color code matching the number.
    *
    * @param float $flNumber Number (x/y), !no! percentage
    *
    * @return string HTML color #0AF
    */
    public static function getColor($flNumber)
    {
        if ($flNumber == 1) {
            return '#0F0';
        } else if ($flNumber >= 0.9) {
            return '#dfff00';
        } else if ($flNumber >= 0.6) {
            return '#FF0';
        } else if ($flNumber >= 0.3) {
            return '#F70';
        } else {
            return '#F00';
        }
    }//public static function getColor($flNumber)



    /**
    * Renders the given coverage array and
    * returns the HTML.
    *
    * @param array $arDoc     Documentation coverage analysis results
    * @param array $arOptions Options
    *
    * @return string HTML
    */
    public function render($arDoc, $arOptions = null)
    {
        $arMaintainer = self::getMaintainers($arDoc);

        $n    = "\n";
        $out  = '';
        $out .= '<?xml version="1.0" encoding="utf-8" ?>' . $n
            . '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
            . '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';

        $out .= '<html><head><title>PEAR Documentation coverage by developer</title></head><body>';
        $out .= '<table border="1"><caption>'
            . 'PEAR documentation coverage by developer '
            . date('Y-m-d H:i:s', $arDoc['*date*'])
            . '</caption>' . $n;


        $arMaintainers = self::getMaintainers($arDoc);
        uasort($arMaintainers, array('self', 'compareMaintainers'));

        $out .= '<thead>'
            . '<tr><th>Place</th><th>Developer</th><th>Docced</th><th>Packages</th><th>Percentage</th>'
            . '<th>Undocumented Packages</th>'
            . '</tr>'
            . '</thead>' . $n;

        $nPlace      = 0;
        $nNextNumber = 101;
        $arCounter   = array();
        reset(self::$arLevels);

        foreach ($arMaintainers as $strUsername => $arMaintainer) {
            if ($strUsername == '???' || $strUsername == '') {
                continue;
            }

            $num = $arMaintainer['docced'] / $arMaintainer['packages'];
            $glatt = intval($num * 100);

            if ($glatt < $nNextNumber) {
                $strLevel = current(self::$arLevels);
                $out .= '<tr><th colspan="6">' . $strLevel . '</th></tr>' . $n;
                next(self::$arLevels);
                $nNextNumber = key(self::$arLevels);
            }

            $arUndocumented = array();
            if ($glatt != 100) {
                foreach ($arMaintainer['packagelist'] as $strPackageName => $arPackage) {
                    if ($arPackage['*docid*'] === null) {
                        $arUndocumented[] = '<a href="http://pear.php.net/package/'
                            . $strPackageName . '">'
                            . $strPackageName
                            . '</a>';
                    }
                }
            }

            if (!isset($arCounter[$strLevel])) {
                $arCounter[$strLevel] = 0;
            } else {
                $arCounter[$strLevel]++;
            }

            $out .= '<tr>'
                . '<td>' . ++$nPlace . '</td>'
                . '<td><a href="http://pear.php.net/user/' . $strUsername . '" name="' . $strUsername . '">' . $strUsername . '</a></td>'
                . '<td>' . $arMaintainer['docced'] . '</td>'
                . '<td>' . $arMaintainer['packages'] . '</td>'
                . '<td style="background-color:' . self::getColor($num) . '">'
                . number_format($num * 100, 2) . '%</td>'
                . '<td>' . implode(', ', $arUndocumented) . '</td>'
                . '</tr>' . $n
            ;
        }

        $out .= '</table>' . $n;

        //now statistics
        $out .= '<table border="1"><caption>Statistics</caption>' . $n
            . '<thead><tr><th>Level</th><th># devs</th><th>Percent</th></tr></thead>'
            . '<tfoot><tr><th>Sum</th><td>' . count($arMaintainers) . '</td><td>100%</td></tr></tfoot>'
            . '<tbody>';
        foreach ($arCounter as $strLevel => $nDevs) {
            $out .= '<tr>'
                . '<td>' . $strLevel . '</td>'
                . '<td>' . $nDevs . '</td>'
                . '<td>' . number_format(100 / count($arMaintainers) * $nDevs, 2) . '%</td>'
                . '</tr>' . $n;
        }
        $out .= '</tbody></table>' . $n;


        $out .= '</body></html>';

        return $out;
    }//public function render($arDoc)



    /**
    * Returns an array of package maintainer usernames,
    * their email address, real name and the packages
    * maintained by them. Also lists which packages are
    * not docced, and which are.
    *
    * @param array $arDoc Array as passed to render() method.
    *
    * @return array   Array with the following data:
    * [username] => array(
    *     [name]      => Real name
    *     [email]     => Email address
    *     [docced]    => # of documented packages
    *     [packages]  => # of packages at all
    *     [packagelist]   => array with package names (key)
    *                     value is reference to doc array
    * )
    */
    public static function getMaintainers($arDoc)
    {
        $arMaintainers = array();
        foreach ($arDoc as $strCategory => &$arPackages) {
            if ($strCategory[0] == '*') {
                continue;
            }

            foreach ($arPackages as $strPackageName => &$arPackage) {
                $strPath = $arPackage['*package*'];
                $strV1 = $strPath . '/package.xml';
                $strV2 = $strPath . '/package2.xml';

                if (file_exists($strV2)) {
                    $strPackageXmlPath = $strV2;
                } else {
                    $strPackageXmlPath = $strV1;
                }

                $arPackageMaintainers = self::getPackageMaintainers(
                    $strPackageXmlPath
                );

                foreach ($arPackageMaintainers as $strUsername => $arMaintainer) {
                    if (!isset($arMaintainers[$strUsername])) {
                        $arMaintainers[$strUsername] = $arMaintainer;
                        $arMaintainers[$strUsername]['packages'] = 0;
                        $arMaintainers[$strUsername]['docced']   = 0;
                        $arMaintainers[$strUsername]['packagelist'] = array();
                    }
                    ++$arMaintainers[$strUsername]['packages'];
                    $arMaintainers[$strUsername]['packagelist'][$strPackageName] = &$arPackage;
                    if ($arPackage['*docid*'] !== null) {
                        ++$arMaintainers[$strUsername]['docced'];
                    }
                }

            }
        }

        return $arMaintainers;
    }//public static function getMaintainers($arDoc)



    /**
    * Reads the package maintainers from a package.xml (v1 and v2)
    * file.
    *
    * @param string $strPackageXmlPath Path to a package.xml file
    *
    * @return array Array with maintainers of following structure:
    * [username] => array(
    *     [name]      => Real name
    *     [email]     => Email address
    * )
    */
    public static function getPackageMaintainers($strPackageXmlPath)
    {
        if (!file_exists($strPackageXmlPath)) {
            throw new Exception('File does not exist: ' . $strPackageXmlPath);
        }

        $doc = new DOMDocument();
        if (!@$doc->load($strPackageXmlPath)) {
            return array();
            throw new Exception('Package xml is broken: ' . $strPackageXmlPath);
        }
        $xpath = new DOMXPath($doc);

        $arMaintainers = array();

        $pack       = $doc->getElementsByTagName('package')->item(0);
        $strVersion = $pack->getAttribute('version');

        if ($strVersion == '') {
            $strVersion = '1.0';
        }

        if ($strVersion != '1.0' && $strVersion != '2.0') {
            throw new Exception(
                'Unsupported package.xml version ' . $strVersion
                . ' in ' . $strPackageXmlPath
            );
        }

        if ($strVersion == '1.0') {
            //get maintainers
            $maintainers = $pack->getElementsByTagName('maintainer');
            foreach ($maintainers as $maintainer) {
                $strUsername = strtolower($maintainer->getElementsByTagName('user')->item(0)->textContent);
                $strRealname = $maintainer->getElementsByTagName('name')->item(0)->textContent;
                $strEmail    = $maintainer->getElementsByTagName('email')->item(0)->textContent;
                $arMaintainers[$strUsername] = array(
                    'username'  => $strUsername,
                    'name'      => $strRealname,
                    'email'     => $strEmail
                );
            }
        } else {
            //v2
            $maintainers = $pack->getElementsByTagName('lead');
            foreach ($maintainers as $maintainer) {
                if ($maintainer->getElementsByTagName('active')->item(0)->textContent != 'yes') {
                    continue;
                }
                $strUsername = strtolower($maintainer->getElementsByTagName('user')->item(0)->textContent);
                $strRealname = $maintainer->getElementsByTagName('name')->item(0)->textContent;
                $strEmail    = $maintainer->getElementsByTagName('email')->item(0)->textContent;
                $arMaintainers[$strUsername] = array(
                    'username'  => $strUsername,
                    'name'      => $strRealname,
                    'email'     => $strEmail
                );
            }
            $maintainers = $pack->getElementsByTagName('developer');
            foreach ($maintainers as $maintainer) {
                if ($maintainer->getElementsByTagName('active')->item(0)->textContent != 'yes') {
                    continue;
                }
                $strUsername = strtolower($maintainer->getElementsByTagName('user')->item(0)->textContent);
                $strRealname = $maintainer->getElementsByTagName('name')->item(0)->textContent;
                $strEmail    = $maintainer->getElementsByTagName('email')->item(0)->textContent;
                $arMaintainers[$strUsername] = array(
                    'username'  => $strUsername,
                    'name'      => $strRealname,
                    'email'     => $strEmail
                );
            }
        }

        return $arMaintainers;
    }//public static function getPackageMaintainers($strPackageXmlPath)



    /**
    * Compares two maintainer arrays for sorting
    *
    * @param array $m1 Maintainer 1
    * @param array $m2 Maintainer 2
    *
    * @return int -1,0,1 depending on sort results
    */
    public static function compareMaintainers($m1, $m2)
    {
        $v1 = $m1['docced'] / $m1['packages'];
        $v2 = $m2['docced'] / $m2['packages'];
        if ($v1 == $v2) {
            return strcasecmp($m1['username'], $m2['username']);
        }
        return ($v1 > $v2) ? -1 : 1;
    }//public static function compareMaintainers($m1, $m2)

}//class QA_Peardoc_Coverage_Renderer_DeveloperList
?>