diff options
-rw-r--r-- | Bugzilla/Attachment.pm | 1 | ||||
-rw-r--r-- | Bugzilla/Config/Attachment.pm | 5 | ||||
-rw-r--r-- | Bugzilla/DB/Schema.pm | 2 | ||||
-rwxr-xr-x | attachment.cgi | 47 | ||||
-rwxr-xr-x | checksetup.pl | 4 | ||||
-rw-r--r-- | template/en/default/admin/params/attachment.html.tmpl | 5 | ||||
-rw-r--r-- | template/en/default/attachment/create.html.tmpl | 76 | ||||
-rw-r--r-- | template/en/default/attachment/edit.html.tmpl | 30 | ||||
-rw-r--r-- | template/en/default/attachment/list.html.tmpl | 2 |
9 files changed, 151 insertions, 21 deletions
diff --git a/Bugzilla/Attachment.pm b/Bugzilla/Attachment.pm index 4a61154b7..c4e7580ae 100644 --- a/Bugzilla/Attachment.pm +++ b/Bugzilla/Attachment.pm @@ -91,6 +91,7 @@ sub _retrieve { '%Y.%m.%d %H:%i') . " AS attached", 'attachments.filename AS filename', 'attachments.ispatch AS ispatch', + 'attachments.isurl AS isurl', 'attachments.isobsolete AS isobsolete', 'attachments.isprivate AS isprivate' ); diff --git a/Bugzilla/Config/Attachment.pm b/Bugzilla/Config/Attachment.pm index 8192d5f9f..449908528 100644 --- a/Bugzilla/Config/Attachment.pm +++ b/Bugzilla/Config/Attachment.pm @@ -41,6 +41,11 @@ sub get_param_list { my $class = shift; my @param_list = ( { + name => 'allow_attach_url', + type => 'b', + default => 0 + }, + { name => 'maxpatchsize', type => 't', default => '1000', diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm index 6abe41cdd..8379f0b12 100644 --- a/Bugzilla/DB/Schema.pm +++ b/Bugzilla/DB/Schema.pm @@ -313,6 +313,8 @@ use constant ABSTRACT_SCHEMA => { DEFAULT => 'FALSE'}, isprivate => {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'}, + isurl => {TYPE => 'BOOLEAN', NOTNULL => 1, + DEFAULT => 'FALSE'}, ], INDEXES => [ attachments_bug_id_idx => ['bug_id'], diff --git a/attachment.cgi b/attachment.cgi index 3aa1a68d6..964e6cbbc 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -911,13 +911,31 @@ sub insert ValidateBugID($bugid); validateCanChangeBug($bugid); ValidateComment(scalar $cgi->param('comment')); - my $filename = validateFilename(); + my $attachurl = $cgi->param('attachurl') || ''; + my $data; + my $filename; + my $contenttype; + my $isurl; validateIsPatch(); validateDescription(); - # need to validate content type before data as - # we now check the content type for image/bmp in validateData() - validateContentType() unless $cgi->param('ispatch'); - my $data = validateData(); + + if (($attachurl =~ /^(http|https|ftp):\/\/\S+/) + && !(defined $cgi->upload('data'))) { + $filename = ''; + $data = $attachurl; + $isurl = 1; + $contenttype = SqlQuote('text/plain'); + $cgi->param('ispatch', 0); + $cgi->delete('bigfile'); + } else { + $filename = validateFilename(); + # need to validate content type before data as + # we now check the content type for image/bmp in validateData() + validateContentType() unless $cgi->param('ispatch'); + $data = validateData(); + $contenttype = SqlQuote($cgi->param('contenttype')); + $isurl = 0; + } my @obsolete_ids = (); @obsolete_ids = validateObsolete() if $cgi->param('obsolete'); @@ -946,7 +964,6 @@ sub insert # Escape characters in strings that will be used in SQL statements. my $sql_filename = SqlQuote($filename); my $description = SqlQuote($cgi->param('description')); - my $contenttype = SqlQuote($cgi->param('contenttype')); my $isprivate = $cgi->param('isprivate') ? 1 : 0; # Figure out when the changes were made. @@ -956,10 +973,10 @@ sub insert # Insert the attachment into the database. my $sth = $dbh->prepare("INSERT INTO attachments (bug_id, creation_ts, filename, description, - mimetype, ispatch, isprivate, submitter_id) + mimetype, ispatch, isurl, isprivate, submitter_id) VALUES ($bugid, $sql_timestamp, $sql_filename, $description, $contenttype, " . $cgi->param('ispatch') . ", - $isprivate, $userid)"); + $isurl, $isprivate, $userid)"); $sth->execute(); # Retrieve the ID of the newly created attachment record. my $attachid = $dbh->bz_last_key('attachments', 'attach_id'); @@ -1096,14 +1113,20 @@ sub edit my ($attach_id) = validateID(); # Retrieve the attachment from the database. - SendSQL("SELECT description, mimetype, filename, bug_id, ispatch, isobsolete, isprivate, LENGTH(thedata) + SendSQL("SELECT description, mimetype, filename, bug_id, ispatch, isurl, + isobsolete, isprivate, LENGTH(thedata) FROM attachments INNER JOIN attach_data ON id = attach_id WHERE attach_id = $attach_id"); - my ($description, $contenttype, $filename, $bugid, $ispatch, $isobsolete, $isprivate, $datasize) = FetchSQLData(); + my ($description, $contenttype, $filename, $bugid, $ispatch, $isurl, $isobsolete, $isprivate, $datasize) = FetchSQLData(); - my $isviewable = isViewable($contenttype); + my $isviewable = !$isurl && isViewable($contenttype); + my $thedata; + if ($isurl) { + SendSQL("SELECT thedata FROM attach_data WHERE id = $attach_id"); + ($thedata) = FetchSQLData(); + } # Retrieve a list of attachments for this bug as well as a summary of the bug # to use in a navigation bar across the top of the screen. @@ -1135,9 +1158,11 @@ sub edit $vars->{'bugid'} = $bugid; $vars->{'bugsummary'} = $bugsummary; $vars->{'ispatch'} = $ispatch; + $vars->{'isurl'} = $isurl; $vars->{'isobsolete'} = $isobsolete; $vars->{'isprivate'} = $isprivate; $vars->{'datasize'} = $datasize; + $vars->{'thedata'} = $thedata; $vars->{'isviewable'} = $isviewable; $vars->{'attachments'} = \@bugattachments; $vars->{'GetBugLink'} = \&GetBugLink; diff --git a/checksetup.pl b/checksetup.pl index 372d4ff87..e3c5a4af5 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -1742,6 +1742,7 @@ AddFDef("content", "Content", 0); $dbh->do("DELETE FROM fielddefs WHERE name='attachments.thedata'"); AddFDef("attach_data.thedata", "Attachment data", 0); +AddFDef("attachments.isurl", "Attachment is a URL", 0); ########################################################################### # Detect changed local settings @@ -4033,6 +4034,9 @@ if ($dbh->bz_column_info("series", "public")) { $dbh->bz_rename_column('series', 'public', 'is_public'); } +# 2005-09-28 bugreport@peshkin.net Bug 149504 +$dbh->bz_add_column('attachments', 'isurl', + {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 0}); # If you had to change the --TABLE-- definition in any way, then add your # differential change code *** A B O V E *** this comment. diff --git a/template/en/default/admin/params/attachment.html.tmpl b/template/en/default/admin/params/attachment.html.tmpl index 963d89e08..ef89c4af0 100644 --- a/template/en/default/admin/params/attachment.html.tmpl +++ b/template/en/default/admin/params/attachment.html.tmpl @@ -25,6 +25,9 @@ %] [% param_descs = { + allow_attach_url => "If this option is on, it will be possible to " _ + "specify a URL when creating an attachment and " _ + "treat the URL itself as if it were an attachment.", maxpatchsize => "The maximum size (in kilobytes) of patches. $terms.Bugzilla will not " _ "accept patches greater than this number of kilobytes in size. " _ "To accept patches of any size (subject to the limitations of " _ @@ -44,4 +47,4 @@ convert_uncompressed_images => "If this option is on, attachments with content type image/bmp " _ "will be converted to image/png and compressed before uploading to " _ "the database to conserve disk space." } -%]
\ No newline at end of file +%] diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl index 43af6e638..ba725eae7 100644 --- a/template/en/default/attachment/create.html.tmpl +++ b/template/en/default/attachment/create.html.tmpl @@ -17,6 +17,8 @@ # Rights Reserved. # # Contributor(s): Myk Melez <myk@mozilla.org> + # Joel Peshkin <bugreport@peshkin.net> + # Erik Stambaugh <erik@dasbistro.com> #%] [% PROCESS global/variables.none.tmpl %] @@ -53,6 +55,58 @@ onload="setContentTypeDisabledState();" %] +[% IF Param("allow_attach_url") %] + <script type="text/javascript"> + + function URLFieldHandler() { + var field_attachurl = document.getElementById("attachurl"); + var greyfields = new Array("data", "ispatch", "autodetect", + "list", "manual", "bigfile", + "contenttypeselection", + "contenttypeentry"); + var i; + if (field_attachurl.value.match(/^\s*$/)) { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.removeAttribute("disabled"); + } + } + } else { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.setAttribute("disabled", "disabled"); + } + } + } + } + + function DataFieldHandler() { + var field_data = document.getElementById("data"); + var greyfields = new Array("attachurl"); + if (field_data.value.match(/^\s*$/)) { + var i; + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.removeAttribute("disabled"); + } + } + } else { + for (i = 0; i < greyfields.length; i++) { + thisfield = document.getElementById(greyfields[i]); + if (thisfield) { + thisfield.setAttribute("disabled", "disabled"); + } + } + } + } + + </script> +[% END %] + + <form name="entryform" method="post" action="attachment.cgi" enctype="multipart/form-data"> <input type="hidden" name="bugid" value="[% bugid %]"> <input type="hidden" name="action" value="insert"> @@ -62,7 +116,11 @@ <th><label for="data">File:</label></th> <td> <em>Enter the path to the file on your computer.</em><br> - <input type="file" id="data" name="data" size="50"> + <input type="file" id="data" name="data" size="50" + [% IF Param("allow_attach_url") %] + onchange="DataFieldHandler()" + [% END %] + > </td> </tr> [% IF Param("maxlocalattachment") %] @@ -77,6 +135,17 @@ </td> </tr> [% END %] + [% IF Param("allow_attach_url") %] + <tr> + <th><label for="attachurl">AttachURL:</label></th> + <td> + <em>URL to be attached instead.</em><br> + <input type="text" id="attachurl" name="attachurl" size="60" + maxlength="2000" + onkeyup="URLFieldHandler()" onblur="URLFieldHandler()"> + </td> + </tr> + [% END %] <tr> <th><label for="description">Description:</label></th> <td> @@ -104,14 +173,15 @@ <input type="radio" id="list" name="contenttypemethod" value="list"> <label for="list">select from list:</label> - <select name="contenttypeselection" + <select name="contenttypeselection" id="contenttypeselection" onchange="this.form.contenttypemethod[1].checked = true;"> [% PROCESS "attachment/content-types.html.tmpl" %] </select><br> <input type="radio" id="manual" name="contenttypemethod" value="manual"> <label for="manual">enter manually:</label> - <input type="text" name="contenttypeentry" size="30" maxlength="200" + <input type="text" name="contenttypeentry" id="contenttypeentry" + size="30" maxlength="200" onchange="if (this.value) this.form.contenttypemethod[2].checked = true;"> </td> </tr> diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl index e46d5e552..7addd3278 100644 --- a/template/en/default/attachment/edit.html.tmpl +++ b/template/en/default/attachment/edit.html.tmpl @@ -209,16 +209,21 @@ <b>Description:</b><br> <textarea rows="3" cols="25" name="description" wrap="soft">[% description FILTER html %]</textarea><br> - <b>Filename:</b><br> - <input type="text" size="20" name="filename" value="[% filename FILTER html %]"><br> - <b>Size: </b>[% datasize FILTER unitconvert %]<br> + [% IF isurl %] + <input type="hidden" name="filename" value="[% filename FILTER html %]"><br> + <input type="hidden" name="contenttypeentry" value="[% contenttype FILTER html %]"><br> + [% ELSE %] + <b>Filename:</b><br> + <input type="text" size="20" name="filename" value="[% filename FILTER html %]"><br> + <b>Size: </b>[% datasize FILTER unitconvert %]<br> - <b>MIME Type:</b><br> - <input type="text" size="20" name="contenttypeentry" value="[% contenttype FILTER html %]"><br> + <b>MIME Type:</b><br> + <input type="text" size="20" name="contenttypeentry" value="[% contenttype FILTER html %]"><br> <input type="checkbox" id="ispatch" name="ispatch" value="1" [% 'checked="checked"' IF ispatch %]> <label for="ispatch">patch</label> + [% END %] <input type="checkbox" id="isobsolete" name="isobsolete" value="1" [% 'checked="checked"' IF isobsolete %]> <label for="isobsolete">obsolete</label><br> @@ -237,7 +242,8 @@ </div> <input type="submit" value="Submit"><br><br> - <strong>Actions:</strong> <a href="attachment.cgi?id=[% attachid %]">View</a> + <strong>Actions:</strong> + <a href="attachment.cgi?id=[% attachid %]">View</a> [% IF ispatch && patchviewerinstalled %] | <a href="attachment.cgi?id=[% attachid %]&action=diff">Diff</a> [% END %] @@ -268,6 +274,18 @@ //--> </script> </td> + [% ELSIF isurl %] + <td width="75%"> + <a href="[% thedata FILTER html %]"> + [% IF datasize < 120 %] + [% thedata FILTER html %] + [% ELSE %] + [% thedata FILTER truncate(80) FILTER html %] + ... + [% thedata.match(".*(.{20})$").0 FILTER html %] + [% END %] + </a> + </td> [% ELSE %] <td id="noview" width="50%"> <p><b> diff --git a/template/en/default/attachment/list.html.tmpl b/template/en/default/attachment/list.html.tmpl index 61b68ee53..7de5fb371 100644 --- a/template/en/default/attachment/list.html.tmpl +++ b/template/en/default/attachment/list.html.tmpl @@ -43,6 +43,8 @@ <td valign="top"> [% IF attachment.ispatch %] <i>patch</i> + [% ELSIF attachment.isurl %] + <i>url</i> [% ELSE %] [% attachment.contenttype FILTER html %] [% END %] |