Overhauling the bugtracker project

From: Date: Mon, 03 Aug 2009 22:50:34 +0000
Subject: Overhauling the bugtracker project
Groups: php.pear.dev 
Request: Send a blank email to pear-dev+get-52552@lists.php.net to get a copy of this message
Hi, I've been looking through the Bugtracker project, examining the feasibility of using it for PEAR2, and it seems like a lot of work would need to be done to use it with a site that does not have roots in phpbugs or pearweb. Currently it is difficult to change how the bugtracker interacts with the site/project/package it's collecting bugs for. If I want to customize how my site functions I have to add in if ($site=='pear2') … at every instance where info about a package is gathered. Currently there are quite a few similar checks for if $site=='php', because a lot of pecl/pear package specifics don't apply to php bugs. Within the bug system, there are two main parts that talk to each other. The project site hosting the bugtracker, and the bugs themselves. I've no real problem with the bugs db or the forms, but I do have some problems with the expectations of what the bugtracker considers a site, package, releases etc and would like to handle this all myself. So I'm proposing revamping quite a bit of the functions.inc file. Moving everything related to the bugs to a class Bugtracker, and everything related to the site/project as a class that implements interface Bugtracker_Site. Then we would have one class for each of the sites, PECL, PEAR, PHP, PEAR2, and each of these would have the details of what the site considers a valid package, pseudo package, etc. PEAR and PECL are so similar one could extend the other, and I could supply all the details for PEAR2 as I see fit. I've started some work on this, and I have a patch that just scratches the surface. But, before I go much further I'd like to know if the leads think this is the correct direction to go. Any feedback would be appreciated as well. Basically I want to know if I can make the modifications I need for using the Bugtracker with PEAR2, or if I should start my own project using the same schema. Thanks, -- Brett Bieber

### Eclipse Workspace Patch 1.0 #P pear2.php.net Index: bugtracker/site/stats.php =================================================================== --- bugtracker/site/stats.php (revision 286736) +++ bugtracker/site/stats.php (working copy) @@ -52,7 +52,7 @@ $pkg_names = array(); $all = array(); $pseudo = true; -$pseudo_pkgs = get_pseudo_packages($site); +$pseudo_pkgs = $bugtracker->site->getPseudoPackages(); if (!array_key_exists($sort_by, $titles)) { $sort_by = 'Open'; Index: bugtracker/include/Bugtracker/Site/PHP.php =================================================================== --- bugtracker/include/Bugtracker/Site/PHP.php (revision 0) +++ bugtracker/include/Bugtracker/Site/PHP.php (revision 0) @@ -0,0 +1,35 @@ +<?php +class Bugtracker_Site_PHP implements Bugtracker_Site +{ + /** + * Determine if the given package name is legitimate + * + * @param string $package_name the name of the package + * + * @return bool + */ + function packageExists($package_name) + { + global $dbh, $pseudo_pkgs; + + if (empty($package_name)) { + return false; + } + if (isset($pseudo_pkgs[$package_name])) { + return true; + } + $found = $dbh->prepare('SELECT count(name) FROM packages WHERE name = ?')->execute(array($package_name))->fetchOne(); + return ($found == 1) ? true : false; + } + + function getReleases($package) + { + return array(); + } + + function getPseudoReleases($read_only = true) + { + return array(); + } +} +?> \ No newline at end of file Index: bugtracker/include/Bugtracker.php =================================================================== --- bugtracker/include/Bugtracker.php (revision 0) +++ bugtracker/include/Bugtracker.php (revision 0) @@ -0,0 +1,48 @@ +<?php +class Bugtracker +{ + /** + * The site for this bugtracker + * + * @var Bugtracker_Site + */ + public $site; + + protected $config = array( + 'url' => 'pear.php.net', + 'basedir' => '/bugs', + 'email' => 'pear-bugs@lists.php.net', + 'security_email' => 'pear-group@php.net', + 'db' => 'pear', + 'db_driver' => 'mysqli', + 'db_user' => 'nobody', + 'db_pass' => '', + 'db_host' => 'localhost', + 'patch_tmp' => '/tmp/patches/', + ); + + function __construct($config) + { + $this->config = array_merge($this->config, $config); + } + + public static function factory($site, $options) + { + $bugtracker = new self($options); + $class = 'Bugtracker_Site_'.$site; + if (!class_exists($class)) { + include_once 'Bugtracker/Site/'.$site.'.php'; + } + $site = new $class($options); + $bugtracker->setSite($site); + return $bugtracker; + } + + + function setSite(Bugtracker_Site $site) + { + $this->site = $site; + } + +} +?> \ No newline at end of file Index: bugtracker/include/auth.php =================================================================== --- bugtracker/include/auth.php (revision 286736) +++ bugtracker/include/auth.php (working copy) @@ -18,8 +18,6 @@ $Id$ */ -include_once 'pear-database-user.php'; - function auth_reject($realm = null, $message = null) { global $format; Index: bugtracker/include/Bugtracker/Site/PEAR2.php =================================================================== --- bugtracker/include/Bugtracker/Site/PEAR2.php (revision 0) +++ bugtracker/include/Bugtracker/Site/PEAR2.php (revision 0) @@ -0,0 +1,45 @@ +<?php +class Bugtracker_Site_PEAR2 implements Bugtracker_Site +{ + public $webfrontend; + + function __construct($options) + { + require_once dirname(__FILE__).'/../../../../config.inc.php'; + function pyrus_autoload($class) + { + $class = str_replace('_', '\\', $class); + include implode('/', explode('\\', $class)) . '.php'; + + } + spl_autoload_register("pyrus_autoload"); + require_once 'PEAR2/Autoload.php'; + require_once 'WebFrontend.php'; + require_once 'Internet.php'; + require_once 'Channel.php'; + + $channel = new Channel(realpath(dirname(__FILE__).'/../../../../channel.xml')); + $this->webfrontend = new WebFrontend($channel, $_GET); + } + + function setWebFrontend($frontend) + { + $this->webfrontend = $frontend; + } + + function packageExists($package) + { + return true; + } + + function getReleases($package) + { + return array(); + } + + function getPseudoPackages($read_only = true) + { + return array('Web Site', 'Documentation'); + } +} +?> \ No newline at end of file Index: bugtracker/site/bug.php =================================================================== --- bugtracker/site/bug.php (revision 286736) +++ bugtracker/site/bug.php (working copy) @@ -37,7 +37,7 @@ require_once '../include/prepend.inc'; // Set pseudo_pkgs array -$pseudo_pkgs = get_pseudo_packages($site, false); // false == no read-only packages included +$pseudo_pkgs = $bugtracker->site->getPseudoPackages(false); // false == no read-only packages included // Set edit mode $edit = isset($_REQUEST['edit']) ? (int) $_REQUEST['edit'] : 0; Index: bugtracker/templates/index_pear2.php =================================================================== --- bugtracker/templates/index_pear2.php (revision 286736) +++ bugtracker/templates/index_pear2.php (working copy) @@ -10,7 +10,7 @@ <form action="report.php" method="get"> <select name="package"> <?php - $package_list = $webfrontend->listPackages(); + $package_list = $bugtracker->site->webfrontend->listPackages(); foreach ($package_list->packages as $package) { echo '<option>'.$package.'</option>'; } Index: bugtracker/include/Bugtracker/Site/PEAR.php =================================================================== --- bugtracker/include/Bugtracker/Site/PEAR.php (revision 0) +++ bugtracker/include/Bugtracker/Site/PEAR.php (revision 0) @@ -0,0 +1,100 @@ +<?php +class Bugtracker_Site_PEAR implements Bugtracker_Site +{ + + /** + * Determine if the given package name is legitimate + * + * @param string $package_name the name of the package + * + * @return bool + */ + function packageExists($package_name) + { + global $dbh, $pseudo_pkgs; + + if (empty($package_name)) { + return false; + } + if (isset($pseudo_pkgs[$package_name])) { + return true; + } + $found = $dbh->prepare('SELECT count(name) FROM packages WHERE name = ?')->execute(array($package_name))->fetchOne(); + return ($found == 1) ? true : false; + } + + /** + * Just guessing at a name here. + * + * @return unknown_type + */ + function authCheck() + { + include_once 'pear-database-user.php'; + } + + /** + * Get the releases for a given package. + * + * @param string $package_name The package name + * @return array + */ + function getReleases($package_name) + { + if (!class_exists('package')) { + include_once 'pear-database-package.php'; + } + return package::info($package_name, 'releases'); + } + + /** + * Fetches pseudo packages from database + * + * @param string $project define what project pseudo packages are returned + * @param bool $return_disabled whether to return read-only items, defaults to true + * + * @return array array of pseudo packages + */ + function getPseudoPackages($read_only = true) + { + require_once 'Tree/Tree.php'; + + $where = "project IN ('', '$project')"; + if (!$return_disabled) + $where.= " AND disabled = 0"; + + $pseudo_pkgs = array(); + $tree = Tree::factoryMemory ( + array( + 'type'=>'simple', + 'storage'=>array('name'=>'MDB2', 'dsn'=>PEAR_DATABASE_DSN), + 'options'=>array ( + 'order' => 'id', + 'whereAddOn' => $where, + 'table' => 'bugdb_pseudo_packages', + 'columnNameMaps' => array ( + 'parentId' => 'parent', + ), + ) + ) + ); + $tree->setup(); + + foreach ($tree->data as $data) + { + if (isset($data['children'])) + { + $pseudo_pkgs[$data['name']] = array($data['long_name'], $data['disabled']); + foreach ($data['children'] as $child) + { + $pseudo_pkgs[$child['name']] = array("&nbsp;&nbsp;&nbsp;&nbsp;{$child['long_name']}", $child['disabled']); + } + } else if (!isset($pseudo_pkgs[$data['name']])) + $pseudo_pkgs[$data['name']] = array($data['long_name'], $data['disabled']); + } + + return $pseudo_pkgs; + } + +} +?> \ No newline at end of file Index: bugtracker/site/patch-display.php =================================================================== --- bugtracker/site/patch-display.php (revision 286736) +++ bugtracker/site/patch-display.php (working copy) @@ -31,7 +31,7 @@ exit; } -$pseudo_pkgs = get_pseudo_packages($site); +$pseudo_pkgs = $bugtracker->site->getPseudoPackages(); if (isset($patch) && isset($revision)) { if ($revision == 'latest') { Index: bugtracker/include/Bugtracker/Site/PECL.php =================================================================== --- bugtracker/include/Bugtracker/Site/PECL.php (revision 0) +++ bugtracker/include/Bugtracker/Site/PECL.php (revision 0) @@ -0,0 +1,7 @@ +<?php +require_once 'Bugtracker/Site/PEAR.php'; +class Bugtracker_Site_PECL extends Bugtracker_Site_PEAR +{ + +} +?> \ No newline at end of file Index: bugtracker/include/Bugtracker/Site.php =================================================================== --- bugtracker/include/Bugtracker/Site.php (revision 0) +++ bugtracker/include/Bugtracker/Site.php (revision 0) @@ -0,0 +1,8 @@ +<?php +interface Bugtracker_Site +{ + function packageExists($package); + function getReleases($package); + function getPseudoPackages($read_only = true); +} +?> \ No newline at end of file Index: bugtracker/site/report.php =================================================================== --- bugtracker/site/report.php (revision 286736) +++ bugtracker/site/report.php (working copy) @@ -33,7 +33,7 @@ // Init variables $errors = array(); $ok_to_submit_report = false; -$pseudo_pkgs = get_pseudo_packages($site, false); // false == no read-only packages included +$pseudo_pkgs = $bugtracker->site->getPseudoPackages(false); // false == no read-only packages included // Authenticate bugs_authenticate($user, $pw, $logged_in, $is_trusted_developer); Index: bugtracker/include/prepend.inc =================================================================== --- bugtracker/include/prepend.inc (revision 286736) +++ bugtracker/include/prepend.inc (working copy) @@ -35,8 +35,12 @@ define ('PEAR_CHANNELNAME', 'pear.php.net'); } + $logged_in = false; $siteBig = strtoupper($site); +require_once 'Bugtracker.php'; +require_once 'Bugtracker/Site.php'; +$bugtracker = Bugtracker::factory($siteBig, $site_data[$site]); $site_url = $site_data[$site]['url']; $bugEmail = $site_data[$site]['email']; $basedir = $site_data[$site]['basedir']; Index: bugtracker/include/query.php =================================================================== --- bugtracker/include/query.php (revision 286736) +++ bugtracker/include/query.php (working copy) @@ -18,7 +18,7 @@ ); // Fetch pseudo packages -$pseudo_pkgs = get_pseudo_packages($site); +$pseudo_pkgs = $bugtracker->site->getPseudoPackages(); // Setup input variables.. $boolean_search = isset($_GET['boolean']) ? (int) $_GET['boolean'] : 0; Index: bugtracker/include/functions.inc =================================================================== --- bugtracker/include/functions.inc (revision 286736) +++ bugtracker/include/functions.inc (working copy) @@ -167,53 +167,6 @@ } } -/** - * Fetches pseudo packages from database - * - * @param string $project define what project pseudo packages are returned - * @param bool $return_disabled whether to return read-only items, defaults to true - * - * @return array array of pseudo packages - */ -function get_pseudo_packages ($project, $return_disabled = true) -{ - require_once 'Tree/Tree.php'; - - $where = "project IN ('', '$project')"; - if (!$return_disabled) - $where.= " AND disabled = 0"; - - $pseudo_pkgs = array(); - $tree = Tree::setup ( - 'Memory_MDB2simple', - PEAR_DATABASE_DSN, - array ( - 'order' => 'id', - 'whereAddOn' => $where, - 'table' => 'bugdb_pseudo_packages', - 'columnNameMaps' => array ( - 'parentId' => 'parent', - ), - ) - ); - $tree->setup(); - - foreach ($tree->data as $data) - { - if (isset($data['children'])) - { - $pseudo_pkgs[$data['name']] = array($data['long_name'], $data['disabled']); - foreach ($data['children'] as $child) - { - $pseudo_pkgs[$child['name']] = array("&nbsp;&nbsp;&nbsp;&nbsp;{$child['long_name']}", $child['disabled']); - } - } else if (!isset($pseudo_pkgs[$data['name']])) - $pseudo_pkgs[$data['name']] = array($data['long_name'], $data['disabled']); - } - - return $pseudo_pkgs; -} - /** * Obfuscates email addresses to hinder spammer's spiders @@ -519,22 +472,13 @@ function show_package_version_options($package_name, $current) { - global $pseudo_pkgs, $dbh; + global $pseudo_pkgs, $dbh, $bugtracker; if (isset($pseudo_pkgs[$package_name])) { echo '<input type="text" size="20" maxlength="100" name="in[package_version]" value="' . htmlspecialchars($current) . '" />'; return; } - $pid = $dbh->prepare('SELECT id from packages where name = ?')->execute(array($package_name))->fetchOne(); - if (!$pid) { - echo '<input type="text" size="20" maxlength="100" name="in[package_version]" - value="' . htmlspecialchars($current) . '" />'; - return; - } - $candidates = $dbh->prepare(' - SELECT releases.version, releases.state - FROM releases, packages - WHERE packages.name = ? and releases.package = packages.id ORDER BY releases.releasedate DESC')->execute(array($package_name))->fetchAll(MDB2_FETCHMODE_ASSOC); + $candidates = $bugtracker->site->getReleases($package_name); $newest = count($candidates) ? $candidates[0] : false; if ($newest) { $stable = null; @@ -1114,16 +1058,8 @@ */ function package_exists($package_name) { - global $dbh, $pseudo_pkgs; - - if (empty($package_name)) { - return false; - } - if (isset($pseudo_pkgs[$package_name])) { - return true; - } - $found = $dbh->prepare('SELECT count(name) FROM packages WHERE name = ?')->execute(array($package_name))->fetchOne(); - return ($found == 1) ? true : false; + global $bugtracker; + return $bugtracker->site->packageExists($package_name); } /** @@ -1311,7 +1247,7 @@ */ function show_bugs_menu($pkgname, $status = null, $fulllink = false) { - global $dbh, $pseudo_pkgs, $site, $basedir; + global $dbh, $pseudo_pkgs, $site, $basedir, $bugtracker; if (empty($pkgname) && !$fulllink) { return; @@ -1371,11 +1307,8 @@ echo make_link("{$fulllink}&amp;status=All", 'All', '', $style['All']); if ($site != 'php') { - if (!class_exists('package')) { - include_once 'pear-database-package.php'; - } if (count($pkgname) == 1) { - $releases = package::info($pkgname[0], 'releases'); + $releases = $bugtracker->site->getReleases($pkgname[0]); if (count($releases)) { echo delim(); echo make_link("{$fulllink}&amp;status=CRSLR", 'Closed Since Version ' . key($releases), '', $style['CRSLR'], 'Closed bugs since last release');
« previous php.pear.dev (#52552) next »