Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
bugzilla
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
bugzilla
Commits
14d7441b
Commit
14d7441b
authored
Aug 07, 2012
by
Julien Heyman
Committed by
Frédéric Buclin
Aug 07, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 319598: Add support for saved tabular and graphical reports
r/a=LpSolit
parent
eb04bb66
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
289 additions
and
13 deletions
+289
-13
Schema.pm
Bugzilla/DB/Schema.pm
+17
-0
Report.pm
Bugzilla/Report.pm
+134
-0
User.pm
Bugzilla/User.pm
+30
-0
report.cgi
report.cgi
+50
-0
messages.html.tmpl
template/en/default/global/messages.html.tmpl
+9
-0
useful-links.html.tmpl
template/en/default/global/useful-links.html.tmpl
+12
-1
user-error.html.tmpl
template/en/default/global/user-error.html.tmpl
+8
-0
report.html.tmpl
template/en/default/reports/report.html.tmpl
+29
-12
No files found.
Bugzilla/DB/Schema.pm
View file @
14d7441b
...
...
@@ -1026,6 +1026,23 @@ use constant ABSTRACT_SCHEMA => {
],
},
reports
=>
{
FIELDS
=>
[
id
=>
{
TYPE
=>
'MEDIUMSERIAL'
,
NOTNULL
=>
1
,
PRIMARYKEY
=>
1
},
user_id
=>
{
TYPE
=>
'INT3'
,
NOTNULL
=>
1
,
REFERENCES
=>
{
TABLE
=>
'profiles'
,
COLUMN
=>
'userid'
,
DELETE
=>
'CASCADE'
}},
name
=>
{
TYPE
=>
'varchar(64)'
,
NOTNULL
=>
1
},
query
=>
{
TYPE
=>
'LONGTEXT'
,
NOTNULL
=>
1
},
],
INDEXES
=>
[
reports_user_id_idx
=>
{
FIELDS
=>
[
qw(user_id name)
],
TYPE
=>
'UNIQUE'
},
],
},
component_cc
=>
{
FIELDS
=>
[
...
...
Bugzilla/Report.pm
0 → 100644
View file @
14d7441b
# 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/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
use
strict
;
package
Bugzilla::
Report
;
use
base
qw(Bugzilla::Object)
;
use
Bugzilla::
CGI
;
use
Bugzilla::
Constants
;
use
Bugzilla::
Error
;
use
Bugzilla::
Util
;
use
constant
DB_TABLE
=>
'reports'
;
# Do not track reports saved by users.
use
constant
AUDIT_CREATES
=>
0
;
use
constant
AUDIT_UPDATES
=>
0
;
use
constant
AUDIT_REMOVES
=>
0
;
use
constant
DB_COLUMNS
=>
qw(
id
user_id
name
query
)
;
use
constant
UPDATE_COLUMNS
=>
qw(
name
query
)
;
use
constant
VALIDATORS
=>
{
name
=>
\&
_check_name
,
query
=>
\&
_check_query
,
};
##############
# Validators #
##############
sub
_check_name
{
my
(
$invocant
,
$name
)
=
@_
;
$name
=
clean_text
(
$name
);
$name
||
ThrowUserError
(
"report_name_missing"
);
$name
!~
/[<>&]/
||
ThrowUserError
(
"illegal_query_name"
);
if
(
length
(
$name
)
>
MAX_LEN_QUERY_NAME
)
{
ThrowUserError
(
"query_name_too_long"
);
}
return
$name
;
}
sub
_check_query
{
my
(
$invocant
,
$query
)
=
@_
;
$query
||
ThrowUserError
(
"buglist_parameters_required"
);
my
$cgi
=
new
Bugzilla::
CGI
(
$query
);
$cgi
->
clean_search_url
;
return
$cgi
->
query_string
;
}
#############
# Accessors #
#############
sub
query
{
return
$_
[
0
]
->
{
'query'
};
}
sub
set_name
{
$_
[
0
]
->
set
(
'name'
,
$_
[
1
]);
}
sub
set_query
{
$_
[
0
]
->
set
(
'query'
,
$_
[
1
]);
}
###########
# Methods #
###########
sub
create
{
my
$class
=
shift
;
my
$param
=
shift
;
Bugzilla
->
login
(
LOGIN_REQUIRED
);
$param
->
{
'user_id'
}
=
Bugzilla
->
user
->
id
;
unshift
@_
,
$param
;
my
$self
=
$class
->
SUPER::
create
(
@_
);
}
sub
check
{
my
$class
=
shift
;
my
$report
=
$class
->
SUPER::
check
(
@_
);
my
$user
=
Bugzilla
->
user
;
if
(
grep
(
$_
->
id
eq
$report
->
id
,
@
{
$user
->
reports
}))
{
return
$report
;
}
else
{
ThrowUserError
(
'report_access_denied'
);
}
}
1
;
__END__
=head1 NAME
Bugzilla::Report - Bugzilla report class.
=head1 SYNOPSIS
use Bugzilla::Report;
my $report = new Bugzilla::Report(1);
my $report = Bugzilla::Report->check({id => $id});
my $name = $report->name;
my $query = $report->query;
my $report = Bugzilla::Report->create({ name => $name, query => $query });
$report->set_name($new_name);
$report->set_query($new_query);
$report->update();
$report->remove_from_db;
=head1 DESCRIPTION
Report.pm represents a Report object. It is an implementation
of L<Bugzilla::Object>, and thus provides all methods that
L<Bugzilla::Object> provides.
=cut
Bugzilla/User.pm
View file @
14d7441b
...
...
@@ -578,6 +578,25 @@ sub save_last_search {
return
$search
;
}
sub
reports
{
my
$self
=
shift
;
return
$self
->
{
reports
}
if
defined
$self
->
{
reports
};
return
[]
unless
$self
->
id
;
my
$dbh
=
Bugzilla
->
dbh
;
my
$report_ids
=
$dbh
->
selectcol_arrayref
(
'SELECT id FROM reports WHERE user_id = ?'
,
undef
,
$self
->
id
);
require
Bugzilla::
Report
;
$self
->
{
reports
}
=
Bugzilla::
Report
->
new_from_list
(
$report_ids
);
return
$self
->
{
reports
};
}
sub
flush_reports_cache
{
my
$self
=
shift
;
delete
$self
->
{
reports
};
}
sub
settings
{
my
(
$self
)
=
@_
;
...
...
@@ -2275,6 +2294,17 @@ Should only be called by C<Bugzilla::Auth::login>, for the most part.
Returns the disable text of the user, if any.
=item C<reports>
Returns an arrayref of the user's own saved reports. The array contains
L<Bugzilla::Reports> objects.
=item C<flush_reports_cache>
Some code modifies the set of stored reports. Because C<Bugzilla::User> does
not handle these modifications, but does cache the result of calling C<reports>
internally, such code must call this method to flush the cached result.
=item C<settings>
Returns a hash of hashes which holds the user's settings. The first key is
...
...
report.cgi
View file @
14d7441b
...
...
@@ -15,6 +15,8 @@ use Bugzilla::Util;
use
Bugzilla::
Error
;
use
Bugzilla::
Field
;
use
Bugzilla::
Search
;
use
Bugzilla::
Report
;
use
Bugzilla::
Token
;
use
List::
MoreUtils
qw(uniq)
;
...
...
@@ -34,6 +36,7 @@ if (grep(/^cmd-/, $cgi->param())) {
Bugzilla
->
login
();
my
$action
=
$cgi
->
param
(
'action'
)
||
'menu'
;
my
$token
=
$cgi
->
param
(
'token'
);
if
(
$action
eq
"menu"
)
{
# No need to do any searching in this case, so bail out early.
...
...
@@ -41,6 +44,52 @@ if ($action eq "menu") {
$template
->
process
(
"reports/menu.html.tmpl"
,
$vars
)
||
ThrowTemplateError
(
$template
->
error
());
exit
;
}
elsif
(
$action
eq
'add'
)
{
my
$user
=
Bugzilla
->
login
(
LOGIN_REQUIRED
);
check_hash_token
(
$token
,
[
'save_report'
]);
my
$name
=
clean_text
(
$cgi
->
param
(
'name'
));
my
$query
=
$cgi
->
param
(
'query'
);
if
(
my
(
$report
)
=
grep
{
lc
(
$_
->
name
)
eq
lc
(
$name
)
}
@
{
$user
->
reports
})
{
$report
->
set_query
(
$query
);
$report
->
update
;
$vars
->
{
'message'
}
=
"report_updated"
;
}
else
{
my
$report
=
Bugzilla::
Report
->
create
({
name
=>
$name
,
query
=>
$query
});
$vars
->
{
'message'
}
=
"report_created"
;
}
$user
->
flush_reports_cache
;
print
$cgi
->
header
();
$vars
->
{
'reportname'
}
=
$name
;
$template
->
process
(
"global/message.html.tmpl"
,
$vars
)
||
ThrowTemplateError
(
$template
->
error
());
exit
;
}
elsif
(
$action
eq
'del'
)
{
my
$user
=
Bugzilla
->
login
(
LOGIN_REQUIRED
);
my
$report_id
=
$cgi
->
param
(
'saved_report_id'
);
check_hash_token
(
$token
,
[
'delete_report'
,
$report_id
]);
my
$report
=
Bugzilla::
Report
->
check
({
id
=>
$report_id
});
$report
->
remove_from_db
();
$user
->
flush_reports_cache
;
print
$cgi
->
header
();
$vars
->
{
'message'
}
=
'report_deleted'
;
$vars
->
{
'reportname'
}
=
$report
->
name
;
$template
->
process
(
"global/message.html.tmpl"
,
$vars
)
||
ThrowTemplateError
(
$template
->
error
());
exit
;
}
# Sanitize the URL, to make URLs shorter.
...
...
@@ -209,6 +258,7 @@ $vars->{'width'} = $width if $width;
$vars
->
{
'height'
}
=
$height
if
$height
;
$vars
->
{
'query'
}
=
$query
;
$vars
->
{
'saved_report_id'
}
=
$cgi
->
param
(
'saved_report_id'
);
$vars
->
{
'debug'
}
=
$cgi
->
param
(
'debug'
);
my
$formatparam
=
$cgi
->
param
(
'format'
);
...
...
template/en/default/global/messages.html.tmpl
View file @
14d7441b
...
...
@@ -795,6 +795,15 @@
or you don't have access to it. The following is a list of the
products you can choose from.
[% ELSIF message_tag == "report_created" %]
OK, you have a new saved report named <em>[% reportname FILTER html %]</em>.
[% ELSIF message_tag == "report_deleted" %]
OK, the <em>[% reportname FILTER html %]</em> report is gone.
[% ELSIF message_tag == "report_updated" %]
The saved report <em>[% reportname FILTER html %]</em> has been updated.
[% ELSIF message_tag == "remaining_time_zeroed" %]
The [% field_descs.remaining_time FILTER html %] field has been
set to zero automatically as part of closing this [% terms.bug %]
...
...
template/en/default/global/useful-links.html.tmpl
View file @
14d7441b
...
...
@@ -56,7 +56,18 @@
</li>
[% END %]
[%# Individual bugs addition %]
[% IF user.reports.size %]
<li id="reports-saved">
<ul class="links">
[% FOREACH r = user.reports %]
<li>[% '<span class="separator">| </span>' IF print_pipe %]
<a href="report.cgi?[% r.query FILTER html %]&saved_report_id=
[%~ r.id FILTER uri %]">[% r.name FILTER html %]</a></li>
[% print_pipe = 1 %]
[% END %]
</ul>
</li>
[% END %]
[%# Sections of links to more things users can do on this installation. %]
[% Hook.process("end") %]
...
...
template/en/default/global/user-error.html.tmpl
View file @
14d7441b
...
...
@@ -1480,6 +1480,14 @@
To reassign [% terms.abug %], you must provide an address for
the new assignee.
[% ELSIF error == "report_name_missing" %]
[% title = "No Report Name Specified" %]
You must enter a name for your report.
[% ELSIF error == "report_access_denied" %]
[% title = "Report Access Denied" %]
You cannot access this report.
[% ELSIF error == "require_component" %]
[% title = "Component Needed" %]
To file this [% terms.bug %], you must first choose a component.
...
...
template/en/default/reports/report.html.tmpl
View file @
14d7441b
...
...
@@ -150,18 +150,35 @@
</tr>
</table>
<p>
[% IF format == "table" %]
<a href="query.cgi?[% switchbase %]&format=report-table">Edit
this report</a>
[% ELSE %]
<a href="query.cgi?[% switchbase %]&chart_format=
[% format %]&format=report-graph&cumulate=[% cumulate %]">
Edit this report
</a>
[% END %]
</p>
<table>
<tr>
<td>
[% IF format == "table" %]
<a href="query.cgi?[% switchbase %]&format=report-table">Edit this report</a>
[% ELSE %]
<a href="query.cgi?[% switchbase %]&chart_format=
[%~ format %]&format=report-graph&cumulate=[% cumulate %]">
Edit this report</a>
[% END %]
</td>
<td> </td>
<td>
[% IF saved_report_id %]
<a href="report.cgi?action=del&saved_report_id=[% saved_report_id FILTER uri %]&token=
[%~ issue_hash_token(['delete_report', saved_report_id]) FILTER uri %]">Forget this report</a>
[% ELSE %]
<form method="get" action="report.cgi">
<input type="submit" id="remember" value="Remember report"> as
<input type="hidden" name="query" value="[% switchbase %]&format=[% format FILTER html %]&action=wrap">
<input type="hidden" name="action" value="add">
<input type="hidden" name="token" value="[% issue_hash_token(['save_report']) FILTER html %]">
<input type="text" id="name" name="name" size="20" value="" maxlength="64">
</form>
[% END %]
</td>
</tr>
</table>
</div>
[% PROCESS global/footer.html.tmpl %]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment