aboutsummaryrefslogtreecommitdiff
path: root/extensions/Dashboard/Extension.pm
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/Dashboard/Extension.pm')
-rw-r--r--extensions/Dashboard/Extension.pm326
1 files changed, 326 insertions, 0 deletions
diff --git a/extensions/Dashboard/Extension.pm b/extensions/Dashboard/Extension.pm
new file mode 100644
index 0000000..470496b
--- /dev/null
+++ b/extensions/Dashboard/Extension.pm
@@ -0,0 +1,326 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# The Initial Developer of the Original Code is "Nokia Corporation"
+# Portions created by the Initial Developer are Copyright (C) 2010 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Pami Ketolainen <pami.ketolainen@jollamobile.com>
+# David Wilson <ext-david.3.wilson@nokia.com>
+# Jari Savolainen <ext-jari.a.savolainen@nokia.com>
+# Stephen Jayna <ext-stephen.jayna@nokia.com>
+
+package Bugzilla::Extension::Dashboard;
+use strict;
+use base qw(Bugzilla::Extension);
+
+use POSIX qw(strftime);
+
+use Bugzilla::Config qw(SetParam write_params);
+use Bugzilla::Constants;
+use Bugzilla::Error;
+use Bugzilla::Util;
+use Bugzilla::User;
+
+use Bugzilla::Extension::Dashboard::Util;
+
+use JSON;
+
+our $VERSION = '1.00';
+
+
+# Disable client-side caching of this HTTP request.
+sub cgi_no_cache {
+ my $headers = {
+ -expires => 'Sat, 26 Jul 1997 05:00:00 GMT',
+ -Last_Modified => strftime('%a, %d %b %Y %H:%M:%S GMT', gmtime),
+ -Pragma => 'no-cache',
+ -Cache_Control => join(
+ ', ', qw(
+ private no-cache no-store must-revalidate max-age=0
+ pre-check=0 post-check=0)
+ )
+ };
+
+ while(my ($key, $value) = each(%$headers)) {
+ print Bugzilla->cgi->header($key, $value);
+ }
+}
+
+# Copypasta from colchange.cgi
+# Maps parameters that control columns to the names of columns.
+use constant COLUMN_PARAMS => {
+ 'useclassification' => ['classification'],
+ 'usebugaliases' => ['alias'],
+ 'usetargetmilestone' => ['target_milestone'],
+ 'useqacontact' => ['qa_contact', 'qa_contact_realname'],
+ 'usestatuswhiteboard' => ['status_whiteboard'],
+ 'usevotes' => ['votes'],
+};
+
+# We only show these columns if an object of this type exists in the
+# database.
+use constant COLUMN_CLASSES => {
+ 'Bugzilla::Flag' => 'flagtypes.name',
+ 'Bugzilla::Keyword' => 'keywords',
+};
+
+sub _get_columns {
+
+ my @columns;
+ my @hide;
+ if (BUGZILLA_VERSION =~ /^4\..*/) {
+ use Bugzilla::Search;
+ @columns = keys(%{Bugzilla::Search::COLUMNS()});
+ @hide = qw(relevance);
+ } else {
+ @columns = qw(bug_id opendate changeddate bug_severity priority
+ rep_platform assigned_to assigned_to_realname reporter
+ reporter_realname bug_status resolution classification alias
+ target_milestone qa_contact qa_contact_realname
+ status_whiteboard product component version op_sys short_desc
+ short_short_desc estimated_time remaining_time work_time
+ actual_time percentage_complete deadline);
+ if (Bugzilla->params->{"usevotes"}) {
+ push(@columns, "votes");
+ }
+ my @custom_fields = grep { $_->type != FIELD_TYPE_MULTI_SELECT }
+ Bugzilla->active_custom_fields;
+ push(@columns, map { $_->name } @custom_fields);
+
+ Bugzilla::Hook::process('colchange_columns', {'columns' => \@columns} );
+ }
+ foreach my $param (keys %{ COLUMN_PARAMS() }) {
+ next if Bugzilla->params->{$param};
+ foreach my $column (@{ COLUMN_PARAMS->{$param} }) {
+ push(@hide, $column);
+ }
+ }
+
+ foreach my $class (keys %{ COLUMN_CLASSES() }) {
+ eval("use $class; 1;") || die $@;
+ my $column = COLUMN_CLASSES->{$class};
+ push(@hide, $column) if !$class->any_exist;
+ }
+
+ if (!Bugzilla->user->is_timetracker) {
+ foreach my $column (TIMETRACKING_FIELDS) {
+ push(@hide, $column);
+ }
+ }
+
+ @columns = grep {my $col = $_; !scalar grep(/$col/, @hide)} @columns;
+ @columns = sort @columns;
+ return \@columns;
+}
+
+# Hook for page.cgi and dashboard
+sub page_before_template {
+ my ($self, $args) = @_;
+
+ return if ($args->{page_id} !~ /^dashboard\.html$/);
+ my $user = Bugzilla->login(LOGIN_REQUIRED);
+ user_can_access_dashboard(1);
+
+ cgi_no_cache;
+ my $vars = $args->{vars};
+
+ # Get the same list of columns as used in colchange.cgi
+
+ $vars->{'columns'} = _get_columns;
+
+ my $overlay_id = Bugzilla->cgi->param("overlay_id");
+ if (!defined $overlay_id) {
+ $overlay_id = Bugzilla->dbh->selectrow_array(
+ "SELECT id FROM dashboard_overlays WHERE owner_id = ? ".
+ "ORDER BY modified DESC", {}, Bugzilla->user->id);
+ }
+
+ my $config = {
+ user_id => int($user->id),
+ user_login => $user->login,
+ can_publish => $user->in_group(
+ Bugzilla->params->{dashboard_publish_group}),
+ rss_max_items => int(Bugzilla->params->{dashboard_rss_max_items}),
+ browsers_warn => Bugzilla->params->{"dashboard_browsers_warn"},
+ browsers_block => Bugzilla->params->{"dashboard_browsers_block"},
+ overlay_id => $overlay_id,
+ };
+
+ $vars->{dashboard_config} = JSON->new->utf8->pretty->encode($config);
+}
+
+sub db_schema_abstract_schema {
+ my ($self, $args) = @_;
+ my $schema = $args->{schema};
+
+ $schema->{dashboard_overlays} = {
+ FIELDS => [
+ id => {
+ TYPE => 'MEDIUMSERIAL',
+ NOTNULL => 1,
+ PRIMARYKEY => 1,
+ },
+ name => {
+ TYPE => 'TINYTEXT',
+ NOTNULL => 1,
+ },
+ description => {
+ TYPE => 'TINYTEXT',
+ },
+ columns => {
+ TYPE => 'TINYTEXT',
+ NOTNULL => 1,
+ },
+ created => {
+ TYPE => 'DATETIME',
+ NOTNULL => 1,
+ },
+ modified => {
+ TYPE => 'DATETIME',
+ NOTNULL => 1,
+ },
+ owner_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {
+ TABLE => 'profiles',
+ COLUMN => 'userid',
+ DELETE => 'CASCADE',
+ },
+ },
+ pending => {
+ TYPE => 'BOOLEAN',
+ NOTNULL => 1,
+ DEFAULT => 0,
+ },
+ shared => {
+ TYPE => 'BOOLEAN',
+ NOTNULL => 1,
+ DEFAULT => 0,
+ },
+ workspace => {
+ TYPE => 'BOOLEAN',
+ NOTNULL => 1,
+ DEFAULT => 0,
+ }
+ ]
+ };
+
+ $schema->{dashboard_widgets} = {
+ FIELDS => [
+ id => {
+ TYPE => 'MEDIUMSERIAL',
+ NOTNULL => 1,
+ PRIMARYKEY => 1,
+ },
+ name => {
+ TYPE => 'TINYTEXT',
+ NOTNULL => 1,
+ },
+ type => {
+ TYPE => 'TINYTEXT',
+ NOTNULL => 1,
+ },
+ overlay_id => {
+ TYPE => 'INT3',
+ NOTNULL => 1,
+ REFERENCES => {
+ TABLE => 'dashboard_overlays',
+ COLUMN => 'id',
+ DELETE => 'CASCADE',
+ },
+ },
+ color => {
+ TYPE => 'TINYTEXT',
+ },
+ col => {
+ TYPE => 'INT1',
+ DEFAULT => 0,
+ },
+ pos => {
+ TYPE => 'INT1',
+ DEFAULT => 0,
+ },
+ height => {
+ TYPE => 'INT2',
+ DEFAULT => 100,
+ },
+ minimized => {
+ TYPE => 'BOOLEAN',
+ NOTNULL => 1,
+ DEFAUL => 0,
+ },
+ refresh => {
+ TYPE => 'INT2',
+ NOTNULL => 1,
+ DEFAULT => 0,
+ },
+ data => {
+ TYPE => 'MEDIUMTEXT',
+ }
+ ]
+ };
+}
+
+sub bb_common_links {
+ my ($self, $args) = @_;
+
+ return unless user_can_access_dashboard();
+
+ $args->{links}->{Dashboard} = [
+ {
+ text => 'Dashboard',
+ href => 'page.cgi?id=dashboard.html'
+ }
+ ];
+}
+
+sub bb_group_params {
+ my ($self, $args) = @_;
+ push(@{$args->{group_params}}, 'dashboard_user_group',
+ 'dashboard_publish_group');
+}
+
+sub config_add_panels {
+ my ($self, $args) = @_;
+ my $modules = $args->{panel_modules};
+ $modules->{Dashboard} = "Bugzilla::Extension::Dashboard::Config";
+}
+
+sub object_end_of_update {
+ my ($self, $args) = @_;
+ my ($new_obj, $old_obj, $changes) = @$args{qw(object old_object changes)};
+
+ # Update user group param if group name changes
+ if ($new_obj->isa("Bugzilla::Group") && defined $changes->{name}) {
+ if ($old_obj->name eq Bugzilla->params->{dashboard_user_group}) {
+ SetParam('dashboard_user_group', $new_obj->name);
+ write_params();
+ }
+ }
+}
+
+sub webservice {
+ my ($self, $args) = @_;
+ $args->{dispatch}->{Dashboard} = "Bugzilla::Extension::Dashboard::WebService";
+}
+
+
+sub webservice_error_codes {
+ my ($self, $args) = @_;
+ my $error_map = $args->{error_map};
+ $error_map->{'dashboard_access_denied'} = 10001;
+ $error_map->{'overlay_publish_denied'} = 10002;
+ $error_map->{'overlay_does_not_exist'} = 10003;
+ $error_map->{'widget_does_not_exist'} = 10004;
+ $error_map->{'overlay_access_denied'} = 10005;
+ $error_map->{'overlay_edit_denied'} = 10006;
+ $error_map->{'widget_edit_denied'} = 10007;
+}
+
+__PACKAGE__->NAME;