Permalink
Browse files

Fix support for jquery tables, add the ability to specify fields,

refactor templates, add support for a simple HTML list output type, add
some CSS classes for bugs in various states, ignore all sorts of
swap files in the .gitignore
  • Loading branch information...
1 parent 9258963 commit 674b44ed4179cad8933d402481256589285183ee @LegNeato committed Apr 13, 2012
View
@@ -1 +1 @@
-*.swp
+*.sw*
View
@@ -74,31 +74,42 @@ function BugzillaCreateCache( $updater ) {
function BugzillaIncludeHTML( &$out, &$sk ) {
global $wgScriptPath;
+ global $wgBugzillaJqueryTable;
- // Use remote jquery
- $out->addScript('<script type="text/javascript" src="$wgScriptPath/extensions/Bugzilla/web/jquery/1.6.2/jquery.min.js"></script>');
+ if( $wgBugzillaJqueryTable ) {
+ // Use local jquery
+ $out->addScript("<script type='text/javascript' src='$wgScriptPath/extensions/Bugzilla/web/jquery/1.6.2/jquery.min.js'></script>");
- // Use remote jquery ui
- $out->addScript('<script type="text/javascript" src="$wgScriptPath/extensions/Bugzilla/web/jqueryui/1.8.14/jquery-ui.min.js"></script>');
+ // Use local jquery ui
+ $out->addScript("<script type='text/javascript' src='$wgScriptPath/extensions/Bugzilla/web/jqueryui/1.8.14/jquery-ui.min.js'></script>");
- // Add a local script file for the datatable
- $out->addScriptFile("$wgScriptPath/extensions/Bugzilla/web/js/jquery.dataTables.js" );
+ // Add a local script file for the datatable
+ $out->addScriptFile("$wgScriptPath/extensions/Bugzilla/web/js/jquery.dataTables.js" );
- // Add a remote jquery css file
- $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/jqueryui/1.8.14/themes/base/jquery-ui.css");
+ // Add a local jquery css file
+ $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/jqueryui/1.8.14/themes/base/jquery-ui.css");
- // Add a remote jquery UI theme css file
- $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/jqueryui/1.8.14/themes/smoothness/jquery-ui.css");
+ // Add a local jquery UI theme css file
+ $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/jqueryui/1.8.14/themes/smoothness/jquery-ui.css");
- // Add local datatable styles
- $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/css/demo_page.css");
- $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/css/demo_table.css");
+ // Add local datatable styles
+ $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/css/demo_page.css");
+ $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/css/demo_table.css");
- // Add the script to do table magic
- $out->addInlineScript('$(document).ready(function() {
- $(".bugzilla").dataTable({
- "bJQueryUI": true
- })});');
+ // Add the script to do table magic
+ $out->addInlineScript('$(document).ready(function() {
+ $("table.bugzilla").dataTable({
+ "bJQueryUI": true
+ })});');
+ }
+
+ // Add local bugzilla extension styles
+ $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/css/bugzilla.css");
+
+ // Let the user optionally override bugzilla extension styles
+ if( file_exists("$wgScriptPath/extensions/Bugzilla/web/css/custom.css") ) {
+ $out->addStyle("$wgScriptPath/extensions/Bugzilla/web/css/custom.css");
+ }
// Let the other hooks keep processing
return TRUE;
@@ -123,6 +134,12 @@ function BugzillaRender($input, array $args, Parser $parser ) {
// TODO: Not sure if we need this
$parser->disableCache();
+ // TODO: Figure out to have the parser not do anything to our output
+ // mediawiki docs are wrong :-(
+ // error_log(print_r($parser->mStripState, true));
+ // $parser->mStripState->addItem( 'nowiki', 'NOWIKI', true);
+ // 'noparse' => true, 'isHTML' => true, 'markerType' => 'nowiki' );
+
// Create a new bugzilla object
$bz = Bugzilla::create($args, $input, $parser->getTitle());
@@ -135,16 +152,22 @@ function BugzillaRender($input, array $args, Parser $parser ) {
// Default configuration
// -----------------------------------------------------------------------------
-$wgBugzillaRESTURL = 'https://api-dev.bugzilla.mozilla.org/latest';
-$wgBugzillaURL = 'https://bugzilla.mozilla.org';
-$wgBugzillaTagName = 'bugzilla';
-$wgBugzillaMethod = 'REST'; // XML-RPC and JSON-RPC may be supported later
-$wgBugzillaUseCache = TRUE;
-$wgBugzillaCacheMins = 5;
+$wgBugzillaRESTURL = 'https://api-dev.bugzilla.mozilla.org/latest';
+$wgBugzillaURL = 'https://bugzilla.mozilla.org';
+$wgBugzillaTagName = 'bugzilla';
+$wgBugzillaMethod = 'REST'; // XML-RPC and JSON-RPC aren't supported yet
+$wgBugzillaDefaultFields = array(
+ 'id',
+ 'summary',
+ 'priority',
+ 'status',
+);
$wgBugzillaJqueryTable = FALSE;
// Cache settings
-$wgCacheObject = 'BugzillaCacheDummy';
+$wgBugzillaUseCache = TRUE;
+$wgCacheObject = 'BugzillaCacheDummy';
+$wgBugzillaCacheMins = 10;
$wgBugzillaChartStorage = realpath($cwd . '/charts');
$wgBugzillaFontStorage = $cwd . '/pchart/fonts';
@@ -64,20 +64,53 @@ protected function _getCache()
return $this->cache;
}
-
- abstract public function _setup_template_data();
+
+ abstract protected function _setup_template_data();
}
-class BugzillaTable extends BugzillaOutput {
+class BugzillaBugListing extends BugzillaOutput {
+
+ protected function _setup_template_data() {
- public function _setup_template_data() {
- if(count($this->query->data->bugs) > 0) {
- $this->response->bugs = $this->query->data->bugs;
- } else {
- $this->response->bugs = array();
+ global $wgBugzillaDefaultFields;
+
+ $this->response->bugs = array();
+ $this->response->fields = array();
+
+ // Set the bug data for the templates
+ if(count($this->query->data['bugs']) > 0) {
+ $this->response->bugs = $this->query->data['bugs'];
+ }
+
+ // Set the field data for the templates
+ if( isset($this->query->options['include_fields']) &&
+ !empty($this->query->options['include_fields']) ) {
+ // User specified some fields
+ $tmp = @explode(',', $this->query->options['include_fields']);
+ foreach( $tmp as $tmp_field ) {
+ $field = trim($tmp_field);
+ // Catch if the user specified the same field multiple times
+ if( !empty($field) &&
+ !in_array($field, $this->response->fields) ) {
+ array_push($this->response->fields, $field);
+ }
+ }
+ }else {
+ // If the user didn't specify any fields in the query config use
+ // default fields
+ $this->response->fields = $wgBugzillaDefaultFields;
}
}
+
+}
+
+class BugzillaList extends BugzillaBugListing {
+
+}
+
+class BugzillaTable extends BugzillaBugListing {
+
}
abstract class BugzillaGraph extends BugzillaOutput {
@@ -94,9 +127,9 @@ public function generate_chart($chart_name)
{
global $wgBugzillaChartStorage, $wgBugzillaFontStorage;
$pData = new pData();
- $pData->addPoints($this->query->data->data, 'Counts');
+ $pData->addPoints($this->query->data['data'], 'Counts');
$pData->setAxisName(0, 'Bugs');
- $pData->addPoints($this->query->data->x_labels, "Bugs");
+ $pData->addPoints($this->query->data['x_labels'], "Bugs");
$pData->setSerieDescription("Bugs", "Bugs");
$pData->setAbscissa("Bugs");
@@ -21,14 +21,15 @@ public function create($type, $options, $title) {
abstract class BugzillaBaseQuery {
public function __construct($type, $options, $title) {
- $this->type = $type;
- $this->title = $title;
- $this->url = FALSE;
- $this->id = FALSE;
- $this->fetched_at = FALSE;
- $this->error = FALSE;
- $this->data = array();
- $this->cache = FALSE;
+ $this->type = $type;
+ $this->title = $title;
+ $this->url = FALSE;
+ $this->id = FALSE;
+ $this->fetched_at = FALSE;
+ $this->error = FALSE;
+ $this->data = array();
+ $this->synthetic_fields = array();
+ $this->cache = FALSE;
$this->_set_options($options);
}
@@ -59,10 +60,43 @@ protected function _generate_id() {
// Sort it so the keys are always in the same order
ksort($this->options);
+
+ // Treat include_fields special because we don't want to query multiple
+ // times if the same fields were requested in a different order
+ $saved_include_fields = array();
+ if( isset($this->options['include_fields']) &&
+ !empty($this->options['include_fields']) ) {
+
+ $saved_include_fields = $this->options['include_fields'];
+
+ // This is important. If a user asks for a subset of the default
+ // fields and another user has the same query w/ a subset,
+ // it is silly to cache the queries separately. We know the
+ // defaults will always be pulled, so anything asking for
+ // any combination of the defaults (or any combined subset) are
+ // esentially the same
+ $include_fields = $this->synthetic_fields;
+
+ $tmp = @explode(',', $this->options['include_fields']);
+ foreach( $tmp as $tmp_field ) {
+ $field = trim($tmp_field);
+ // Catch if the user specified the same field multiple times
+ if( !empty($field) && !in_array($field, $include_fields) ) {
+ array_push($include_fields, $field);
+ }
+ }
+ sort($include_fields);
+ $this->options['include_fields'] = @implode(',', $include_fields);
+ }
// Get a string representation of the array
$id_string = serialize($this->options);
+ // Restore the include_fields to what the user wanted
+ if( $saved_include_fields ) {
+ $this->options['include_fields'] = $saved_include_fields;
+ }
+
// Hash it
$this->id = sha1($id_string);
@@ -108,13 +142,11 @@ public function fetch() {
protected function _set_options($query_options_raw) {
// Make sure query options are valid JSON
- $this->options = json_decode($query_options_raw);
+ $this->options = json_decode($query_options_raw, TRUE);
if( !$query_options_raw || !$this->options ) {
$this->error = 'Query options must be valid json';
return;
}
- // Object is kinda useless, make it an array
- $this->options = get_object_vars($this->options);
}
abstract public function _fetch_by_options();
@@ -131,21 +163,25 @@ class BugzillaRESTQuery extends BugzillaBaseQuery {
function __construct($type, $options, $title='') {
global $wgBugzillaRESTURL;
+ global $wgBugzillaDefaultFields;
parent::__construct($type, $options, $title);
// See what sort of REST query we are going to
switch( $type ) {
// Whitelist
- case 'bug':
case 'count':
$this->url = $wgBugzillaRESTURL . '/' . urlencode($type);
+ // Note there are no synthetic fields for count
break;
// Default to a bug query
+ case 'bug':
default:
$this->url = $wgBugzillaRESTURL . '/bug';
+ // Even if the user didn't specify, we need these
+ $this->synthetic_fields = $wgBugzillaDefaultFields;
}
$this->fetch();
@@ -165,15 +201,28 @@ public function _fetch_by_options() {
$request->setHeader('Accept', 'application/json');
$request->setHeader('Content-Type', 'application/json');
- // Add in the requested query options
+ // Save the real options
+ $saved_options = $this->options;
+
+ // Add any synthetic fields to the options
+ if( !empty($this->synthetic_fields) ) {
+ $this->options['include_fields'] =
+ @array_merge((array)$this->options['include_fields'],
+ $this->synthetic_fields);
+ }
+
+ // Add the requested query options to the request
$url = $request->getUrl();
$url->setQueryVariables($this->options);
+ // Retore the real options, removing anything we synthesized
+ $this->options = $saved_options;
+
// This is basically straight from the HTTP/Request2 docs
try {
$response = $request->send();
if (200 == $response->getStatus()) {
- $this->data = json_decode($response->getBody());
+ $this->data = json_decode($response->getBody(), TRUE);
} else {
$this->error = 'Server returned unexpected HTTP status: ' .
$response->getStatus() . ' ' .
@@ -0,0 +1,36 @@
+<ul class="bugzilla ui-helper-reset">
+ <?php
+ $base = dirname(__FILE__) . '/../../templates/fields/';
+
+ foreach( $response->bugs as $bug ) {
+ echo "<li class='bugzilla-status-${bug['status']}'>";
+ $count = 0;
+ foreach( $response->fields as $field ) {
+ if( $count ) {
+ echo " - ";
+ }
+ echo "<span class='bugzilla-data-$field'>";
+
+ // Get our template path
+ $subtemplate = $base .
+ escapeshellcmd(str_replace('..',
+ 'DOTS',
+ $field)) .
+ '.tpl';
+
+ // Make sure a template is there
+ if( !file_exists($subtemplate) ) {
+ $subtemplate = $base . '_default.tpl';
+ }
+
+ // Print out the data
+ $data = $bug[$field];
+ require($subtemplate);
+
+ echo "</span>";
+ $count++;
+ }
+ echo "</li>\n";
+ }
+ ?>
+</ul>
Oops, something went wrong.

0 comments on commit 674b44e

Please sign in to comment.