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
2addcaad
Commit
2addcaad
authored
Jul 18, 2010
by
Frédéric Buclin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug 119703: Create an attachment by pasting it into a text field
r/a=mkanat
parent
aef5cb18
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
93 additions
and
186 deletions
+93
-186
Attachment.pm
Bugzilla/Attachment.pm
+7
-49
Attachment.pm
Bugzilla/Config/Attachment.pm
+0
-5
Schema.pm
Bugzilla/DB/Schema.pm
+0
-2
Field.pm
Bugzilla/Field.pm
+0
-1
DB.pm
Bugzilla/Install/DB.pm
+15
-4
Bug.pm
Bugzilla/WebService/Bug.pm
+11
-24
Constants.pm
Bugzilla/WebService/Constants.pm
+2
-2
attachment.cgi
attachment.cgi
+2
-3
bugzilla.dtd
bugzilla.dtd
+0
-1
using.xml
docs/en/xml/using.xml
+8
-2
attachment.js
js/attachment.js
+6
-6
post_bug.cgi
post_bug.cgi
+3
-4
attachment.html.tmpl
template/en/default/admin/params/attachment.html.tmpl
+0
-4
create.html.tmpl
template/en/default/attachment/create.html.tmpl
+7
-1
createformcontents.html.tmpl
template/en/default/attachment/createformcontents.html.tmpl
+14
-16
edit.html.tmpl
template/en/default/attachment/edit.html.tmpl
+12
-32
list.html.tmpl
template/en/default/attachment/list.html.tmpl
+1
-4
create.html.tmpl
template/en/default/bug/create/create.html.tmpl
+2
-1
show.xml.tmpl
template/en/default/bug/show.xml.tmpl
+0
-1
code-error.html.tmpl
template/en/default/global/code-error.html.tmpl
+1
-5
field-descs.none.tmpl
template/en/default/global/field-descs.none.tmpl
+0
-1
user-error.html.tmpl
template/en/default/global/user-error.html.tmpl
+2
-12
Constants.pm
xt/lib/Bugzilla/Test/Search/Constants.pm
+0
-6
No files found.
Bugzilla/Attachment.pm
View file @
2addcaad
...
@@ -83,7 +83,6 @@ sub DB_COLUMNS {
...
@@ -83,7 +83,6 @@ sub DB_COLUMNS {
isobsolete
isobsolete
ispatch
ispatch
isprivate
isprivate
isurl
mimetype
mimetype
modification_time
modification_time
submitter_id)
,
submitter_id)
,
...
@@ -107,14 +106,13 @@ use constant UPDATE_COLUMNS => qw(
...
@@ -107,14 +106,13 @@ use constant UPDATE_COLUMNS => qw(
use
constant
VALIDATORS
=>
{
use
constant
VALIDATORS
=>
{
bug
=>
\&
_check_bug
,
bug
=>
\&
_check_bug
,
description
=>
\&
_check_description
,
description
=>
\&
_check_description
,
filename
=>
\&
_check_filename
,
ispatch
=>
\&
Bugzilla::Object::
check_boolean
,
ispatch
=>
\&
Bugzilla::Object::
check_boolean
,
isprivate
=>
\&
_check_is_private
,
isprivate
=>
\&
_check_is_private
,
isurl
=>
\&
_check_is_url
,
mimetype
=>
\&
_check_content_type
,
mimetype
=>
\&
_check_content_type
,
};
};
use
constant
UPDATE_VALIDATORS
=>
{
use
constant
UPDATE_VALIDATORS
=>
{
filename
=>
\&
_check_filename
,
isobsolete
=>
\&
Bugzilla::Object::
check_boolean
,
isobsolete
=>
\&
Bugzilla::Object::
check_boolean
,
};
};
...
@@ -268,21 +266,6 @@ sub ispatch {
...
@@ -268,21 +266,6 @@ sub ispatch {
=over
=over
=item C<isurl>
whether or not the attachment is a URL
=back
=cut
sub
isurl
{
my
$self
=
shift
;
return
$self
->
{
isurl
};
}
=over
=item C<isobsolete>
=item C<isobsolete>
whether or not the attachment is obsolete
whether or not the attachment is obsolete
...
@@ -527,7 +510,7 @@ sub _check_bug {
...
@@ -527,7 +510,7 @@ sub _check_bug {
sub
_check_content_type
{
sub
_check_content_type
{
my
(
$invocant
,
$content_type
)
=
@_
;
my
(
$invocant
,
$content_type
)
=
@_
;
$content_type
=
'text/plain'
if
(
ref
$invocant
&&
(
$invocant
->
isurl
||
$invocant
->
ispatch
)
);
$content_type
=
'text/plain'
if
(
ref
$invocant
&&
$invocant
->
ispatch
);
my
$legal_types
=
join
(
'|'
,
LEGAL_CONTENT_TYPES
);
my
$legal_types
=
join
(
'|'
,
LEGAL_CONTENT_TYPES
);
if
(
!
$content_type
or
$content_type
!~
/^($legal_types)\/.+$/
)
{
if
(
!
$content_type
or
$content_type
!~
/^($legal_types)\/.+$/
)
{
ThrowUserError
(
"invalid_content_type"
,
{
contenttype
=>
$content_type
});
ThrowUserError
(
"invalid_content_type"
,
{
contenttype
=>
$content_type
});
...
@@ -541,17 +524,8 @@ sub _check_data {
...
@@ -541,17 +524,8 @@ sub _check_data {
my
(
$invocant
,
$params
)
=
@_
;
my
(
$invocant
,
$params
)
=
@_
;
my
$data
=
$params
->
{
data
};
my
$data
=
$params
->
{
data
};
if
(
$params
->
{
isurl
})
{
$params
->
{
filesize
}
=
ref
$data
?
-
s
$data
:
length
(
$data
);
(
$data
&&
$data
=~
m
#^(http|https|ftp)://\S+#)
||
ThrowUserError
(
'attachment_illegal_url'
,
{
url
=>
$data
});
$params
->
{
mimetype
}
=
'text/plain'
;
$params
->
{
ispatch
}
=
0
;
$params
->
{
filesize
}
=
length
(
$data
);
}
else
{
$params
->
{
filesize
}
=
ref
$data
?
-
s
$data
:
length
(
$data
);
}
Bugzilla::Hook::
process
(
'attachment_process_data'
,
{
data
=>
\
$data
,
Bugzilla::Hook::
process
(
'attachment_process_data'
,
{
data
=>
\
$data
,
attributes
=>
$params
});
attributes
=>
$params
});
...
@@ -576,11 +550,7 @@ sub _check_description {
...
@@ -576,11 +550,7 @@ sub _check_description {
}
}
sub
_check_filename
{
sub
_check_filename
{
my
(
$invocant
,
$filename
,
$is_url
)
=
@_
;
my
(
$invocant
,
$filename
)
=
@_
;
$is_url
=
$invocant
->
isurl
if
ref
$invocant
;
# No file is attached, so it has no name.
return
''
if
$is_url
;
$filename
=
trim
(
$filename
);
$filename
=
trim
(
$filename
);
$filename
||
ThrowUserError
(
'file_not_specified'
);
$filename
||
ThrowUserError
(
'file_not_specified'
);
...
@@ -612,15 +582,6 @@ sub _check_is_private {
...
@@ -612,15 +582,6 @@ sub _check_is_private {
return
$is_private
;
return
$is_private
;
}
}
sub
_check_is_url
{
my
(
$invocant
,
$is_url
)
=
@_
;
if
(
$is_url
&&
!
Bugzilla
->
params
->
{
'allow_attach_url'
})
{
ThrowCodeError
(
'attachment_url_disabled'
);
}
return
$is_url
?
1
:
0
;
}
=pod
=pod
=head2 Class Methods
=head2 Class Methods
...
@@ -783,8 +744,6 @@ Params: takes a hashref with the following keys:
...
@@ -783,8 +744,6 @@ Params: takes a hashref with the following keys:
attachment is a patch.
attachment is a patch.
C<isprivate> - boolean (optional, default false) - true if
C<isprivate> - boolean (optional, default false) - true if
the attachment is private.
the attachment is private.
C<isurl> - boolean (optional, default false) - true if the
attachment is a URL pointing to some external ressource.
Returns: The new attachment object.
Returns: The new attachment object.
...
@@ -852,7 +811,6 @@ sub run_create_validators {
...
@@ -852,7 +811,6 @@ sub run_create_validators {
$params
->
{
data
}
=
$class
->
_check_data
(
$params
);
$params
->
{
data
}
=
$class
->
_check_data
(
$params
);
$params
=
$class
->
SUPER::
run_create_validators
(
$params
);
$params
=
$class
->
SUPER::
run_create_validators
(
$params
);
$params
->
{
filename
}
=
$class
->
_check_filename
(
$params
->
{
filename
},
$params
->
{
isurl
});
$params
->
{
creation_ts
}
||=
Bugzilla
->
dbh
->
selectrow_array
(
'SELECT LOCALTIMESTAMP(0)'
);
$params
->
{
creation_ts
}
||=
Bugzilla
->
dbh
->
selectrow_array
(
'SELECT LOCALTIMESTAMP(0)'
);
$params
->
{
modification_time
}
=
$params
->
{
creation_ts
};
$params
->
{
modification_time
}
=
$params
->
{
creation_ts
};
$params
->
{
submitter_id
}
=
Bugzilla
->
user
->
id
||
ThrowCodeError
(
'invalid_user'
);
$params
->
{
submitter_id
}
=
Bugzilla
->
user
->
id
||
ThrowCodeError
(
'invalid_user'
);
...
@@ -917,8 +875,8 @@ sub remove_from_db {
...
@@ -917,8 +875,8 @@ sub remove_from_db {
$dbh
->
bz_start_transaction
();
$dbh
->
bz_start_transaction
();
$dbh
->
do
(
'DELETE FROM flags WHERE attach_id = ?'
,
undef
,
$self
->
id
);
$dbh
->
do
(
'DELETE FROM flags WHERE attach_id = ?'
,
undef
,
$self
->
id
);
$dbh
->
do
(
'DELETE FROM attach_data WHERE id = ?'
,
undef
,
$self
->
id
);
$dbh
->
do
(
'DELETE FROM attach_data WHERE id = ?'
,
undef
,
$self
->
id
);
$dbh
->
do
(
'UPDATE attachments SET mimetype = ?, ispatch = ?, is
url = ?, is
obsolete = ?
$dbh
->
do
(
'UPDATE attachments SET mimetype = ?, ispatch = ?, isobsolete = ?
WHERE attach_id = ?'
,
undef
,
(
'text/plain'
,
0
,
0
,
1
,
$self
->
id
));
WHERE attach_id = ?'
,
undef
,
(
'text/plain'
,
0
,
1
,
$self
->
id
));
$dbh
->
bz_commit_transaction
();
$dbh
->
bz_commit_transaction
();
}
}
...
@@ -930,7 +888,7 @@ sub remove_from_db {
...
@@ -930,7 +888,7 @@ sub remove_from_db {
sub
get_content_type
{
sub
get_content_type
{
my
$cgi
=
Bugzilla
->
cgi
;
my
$cgi
=
Bugzilla
->
cgi
;
return
'text/plain'
if
(
$cgi
->
param
(
'ispatch'
)
||
$cgi
->
param
(
'attach
url
'
));
return
'text/plain'
if
(
$cgi
->
param
(
'ispatch'
)
||
$cgi
->
param
(
'attach
_text
'
));
my
$content_type
;
my
$content_type
;
if
(
!
defined
$cgi
->
param
(
'contenttypemethod'
))
{
if
(
!
defined
$cgi
->
param
(
'contenttypemethod'
))
{
...
...
Bugzilla/Config/Attachment.pm
View file @
2addcaad
...
@@ -58,11 +58,6 @@ sub get_param_list {
...
@@ -58,11 +58,6 @@ sub get_param_list {
type
=>
'b'
,
type
=>
'b'
,
default
=>
0
default
=>
0
},
},
{
name
=>
'allow_attach_url'
,
type
=>
'b'
,
default
=>
0
},
{
{
name
=>
'maxattachmentsize'
,
name
=>
'maxattachmentsize'
,
...
...
Bugzilla/DB/Schema.pm
View file @
2addcaad
...
@@ -453,8 +453,6 @@ use constant ABSTRACT_SCHEMA => {
...
@@ -453,8 +453,6 @@ use constant ABSTRACT_SCHEMA => {
DEFAULT
=>
'FALSE'
},
DEFAULT
=>
'FALSE'
},
isprivate
=>
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
isprivate
=>
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
'FALSE'
},
DEFAULT
=>
'FALSE'
},
isurl
=>
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
'FALSE'
},
],
],
INDEXES
=>
[
INDEXES
=>
[
attachments_bug_id_idx
=>
[
'bug_id'
],
attachments_bug_id_idx
=>
[
'bug_id'
],
...
...
Bugzilla/Field.pm
View file @
2addcaad
...
@@ -238,7 +238,6 @@ use constant DEFAULT_FIELDS => (
...
@@ -238,7 +238,6 @@ use constant DEFAULT_FIELDS => (
buglist
=>
1
},
buglist
=>
1
},
{
name
=>
'content'
,
desc
=>
'Content'
},
{
name
=>
'content'
,
desc
=>
'Content'
},
{
name
=>
'attach_data.thedata'
,
desc
=>
'Attachment data'
},
{
name
=>
'attach_data.thedata'
,
desc
=>
'Attachment data'
},
{
name
=>
'attachments.isurl'
,
desc
=>
'Attachment is a URL'
},
{
name
=>
"owner_idle_time"
,
desc
=>
"Time Since Assignee Touched"
},
{
name
=>
"owner_idle_time"
,
desc
=>
"Time Since Assignee Touched"
},
{
name
=>
'see_also'
,
desc
=>
"See Also"
,
{
name
=>
'see_also'
,
desc
=>
"See Also"
,
type
=>
FIELD_TYPE_BUG_URLS
},
type
=>
FIELD_TYPE_BUG_URLS
},
...
...
Bugzilla/Install/DB.pm
View file @
2addcaad
...
@@ -429,10 +429,6 @@ sub update_table_definitions {
...
@@ -429,10 +429,6 @@ sub update_table_definitions {
# PUBLIC is a reserved word in Oracle.
# PUBLIC is a reserved word in Oracle.
$dbh
->
bz_rename_column
(
'series'
,
'public'
,
'is_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
});
# 2005-10-21 LpSolit@gmail.com - Bug 313020
# 2005-10-21 LpSolit@gmail.com - Bug 313020
$dbh
->
bz_add_column
(
'namedqueries'
,
'query_type'
,
$dbh
->
bz_add_column
(
'namedqueries'
,
'query_type'
,
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
0
});
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
0
});
...
@@ -630,6 +626,9 @@ sub update_table_definitions {
...
@@ -630,6 +626,9 @@ sub update_table_definitions {
$dbh
->
bz_alter_column
(
'products'
,
'allows_unconfirmed'
,
$dbh
->
bz_alter_column
(
'products'
,
'allows_unconfirmed'
,
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
'TRUE'
});
{
TYPE
=>
'BOOLEAN'
,
NOTNULL
=>
1
,
DEFAULT
=>
'TRUE'
});
# 2010-07-18 LpSolit@gmail.com - Bug 119703
_remove_attachment_isurl
();
################################################################
################################################################
# New --TABLE-- changes should go *** A B O V E *** this point #
# New --TABLE-- changes should go *** A B O V E *** this point #
################################################################
################################################################
...
@@ -3401,6 +3400,18 @@ sub _fix_series_creator_fk {
...
@@ -3401,6 +3400,18 @@ sub _fix_series_creator_fk {
}
}
}
}
sub
_remove_attachment_isurl
{
my
$dbh
=
Bugzilla
->
dbh
;
if
(
$dbh
->
bz_column_info
(
'attachments'
,
'isurl'
))
{
# Now all attachments must have a filename.
$dbh
->
do
(
'UPDATE attachments SET filename = ? WHERE isurl = 1'
,
undef
,
'url.txt'
);
$dbh
->
bz_drop_column
(
'attachments'
,
'isurl'
);
$dbh
->
do
(
"DELETE FROM fielddefs WHERE name='attachments.isurl'"
);
}
}
1
;
1
;
__END__
__END__
...
...
Bugzilla/WebService/Bug.pm
View file @
2addcaad
...
@@ -623,7 +623,6 @@ sub add_attachment {
...
@@ -623,7 +623,6 @@ sub add_attachment {
mimetype
=>
$params
->
{
content_type
},
mimetype
=>
$params
->
{
content_type
},
ispatch
=>
$params
->
{
is_patch
},
ispatch
=>
$params
->
{
is_patch
},
isprivate
=>
$params
->
{
is_private
},
isprivate
=>
$params
->
{
is_private
},
isurl
=>
$params
->
{
is_url
},
});
});
my
$comment
=
$params
->
{
comment
}
||
''
;
my
$comment
=
$params
->
{
comment
}
||
''
;
$attachment
->
bug
->
add_comment
(
$comment
,
$attachment
->
bug
->
add_comment
(
$comment
,
...
@@ -846,7 +845,6 @@ sub _attachment_to_hash {
...
@@ -846,7 +845,6 @@ sub _attachment_to_hash {
content_type
=>
$self
->
type
(
'string'
,
$attach
->
contenttype
),
content_type
=>
$self
->
type
(
'string'
,
$attach
->
contenttype
),
is_private
=>
$self
->
type
(
'int'
,
$attach
->
isprivate
),
is_private
=>
$self
->
type
(
'int'
,
$attach
->
isprivate
),
is_obsolete
=>
$self
->
type
(
'int'
,
$attach
->
isobsolete
),
is_obsolete
=>
$self
->
type
(
'int'
,
$attach
->
isobsolete
),
is_url
=>
$self
->
type
(
'int'
,
$attach
->
isurl
),
is_patch
=>
$self
->
type
(
'int'
,
$attach
->
ispatch
),
is_patch
=>
$self
->
type
(
'int'
,
$attach
->
ispatch
),
creator
=>
$self
->
type
(
'string'
,
$attach
->
attacher
->
login
),
creator
=>
$self
->
type
(
'string'
,
$attach
->
attacher
->
login
),
attacher
=>
$self
->
type
(
'string'
,
$attach
->
attacher
->
login
),
attacher
=>
$self
->
type
(
'string'
,
$attach
->
attacher
->
login
),
...
@@ -1231,13 +1229,6 @@ group called the "insidergroup"), False otherwise.
...
@@ -1231,13 +1229,6 @@ group called the "insidergroup"), False otherwise.
C<boolean> True if the attachment is obsolete, False otherwise.
C<boolean> True if the attachment is obsolete, False otherwise.
=item C<is_url>
C<boolean> True if the attachment is a URL instead of actual data,
False otherwise. Note that such attachments only happen when the
Bugzilla installation has at some point had the C<allow_attach_url>
parameter enabled.
=item C<is_patch>
=item C<is_patch>
C<boolean> True if the attachment is a patch, False otherwise.
C<boolean> True if the attachment is a patch, False otherwise.
...
@@ -1279,6 +1270,9 @@ C<creator>.
...
@@ -1279,6 +1270,9 @@ C<creator>.
=item In Bugzilla B<4.0>, the C<description> return value was renamed to
=item In Bugzilla B<4.0>, the C<description> return value was renamed to
C<summary>.
C<summary>.
=item In Bugzilla B<4.2>, the C<is_url> return value was removed
(this attribute no longer exists for attachments).
=back
=back
=back
=back
...
@@ -2163,13 +2157,6 @@ to the "insidergroup"), False if the attachment should be public.
...
@@ -2163,13 +2157,6 @@ to the "insidergroup"), False if the attachment should be public.
Defaults to False if not specified.
Defaults to False if not specified.
=item C<is_url>
C<boolean> True if the attachment is just a URL, pointing to data elsewhere.
If so, the C<data> item should just contain the URL.
Defaults to False if not specified.
=back
=back
=item B<Returns>
=item B<Returns>
...
@@ -2193,11 +2180,6 @@ You tried to attach a file that was larger than Bugzilla will accept.
...
@@ -2193,11 +2180,6 @@ You tried to attach a file that was larger than Bugzilla will accept.
You specified a C<content_type> argument that was blank, not a valid
You specified a C<content_type> argument that was blank, not a valid
MIME type, or not a MIME type that Bugzilla accepts for attachments.
MIME type, or not a MIME type that Bugzilla accepts for attachments.
=item 602 (Illegal URL)
You specified C<is_url> as True, but the data that you attempted
to attach was not a valid URL.
=item 603 (File Name Not Specified)
=item 603 (File Name Not Specified)
You did not specify a valid for the C<file_name> argument.
You did not specify a valid for the C<file_name> argument.
...
@@ -2206,10 +2188,15 @@ You did not specify a valid for the C<file_name> argument.
...
@@ -2206,10 +2188,15 @@ You did not specify a valid for the C<file_name> argument.
You did not specify a value for the C<summary> argument.
You did not specify a value for the C<summary> argument.
=item 605 (URL Attaching Disabled)
=back
=item B<History>
=over
=item Added in Bugzilla B<4.0>.
You attempted to attach a URL, setting C<is_url> to True,
=item The C<is_url> parameter was removed in Bugzilla B<4.2>.
but this Bugzilla does not support attaching URLs.
=back
=back
...
...
Bugzilla/WebService/Constants.pm
View file @
2addcaad
...
@@ -124,10 +124,10 @@ use constant WS_ERROR_CODE => {
...
@@ -124,10 +124,10 @@ use constant WS_ERROR_CODE => {
# Attachment errors are 600-700.
# Attachment errors are 600-700.
file_too_large
=>
600
,
file_too_large
=>
600
,
invalid_content_type
=>
601
,
invalid_content_type
=>
601
,
attachment_illegal_url
=>
602
,
# Error 602 attachment_illegal_url no longer exists.
file_not_specified
=>
603
,
file_not_specified
=>
603
,
missing_attachment_description
=>
604
,
missing_attachment_description
=>
604
,
attachment_url_disabled
=>
605
,
# Error 605 attachment_url_disabled no longer exists.
# Errors thrown by the WebService itself. The ones that are negative
# Errors thrown by the WebService itself. The ones that are negative
# conform to http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
# conform to http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
...
...
attachment.cgi
View file @
2addcaad
...
@@ -478,12 +478,11 @@ sub insert {
...
@@ -478,12 +478,11 @@ sub insert {
my
$attachment
=
Bugzilla::
Attachment
->
create
(
my
$attachment
=
Bugzilla::
Attachment
->
create
(
{
bug
=>
$bug
,
{
bug
=>
$bug
,
creation_ts
=>
$timestamp
,
creation_ts
=>
$timestamp
,
data
=>
scalar
$cgi
->
param
(
'attach
url
'
)
||
$cgi
->
upload
(
'data'
),
data
=>
scalar
$cgi
->
param
(
'attach
_text
'
)
||
$cgi
->
upload
(
'data'
),
description
=>
scalar
$cgi
->
param
(
'description'
),
description
=>
scalar
$cgi
->
param
(
'description'
),
filename
=>
$cgi
->
param
(
'attach
url'
)
?
'
'
:
scalar
$cgi
->
upload
(
'data'
),
filename
=>
$cgi
->
param
(
'attach
_text'
)
?
'attachment.txt
'
:
scalar
$cgi
->
upload
(
'data'
),
ispatch
=>
scalar
$cgi
->
param
(
'ispatch'
),
ispatch
=>
scalar
$cgi
->
param
(
'ispatch'
),
isprivate
=>
scalar
$cgi
->
param
(
'isprivate'
),
isprivate
=>
scalar
$cgi
->
param
(
'isprivate'
),
isurl
=>
scalar
$cgi
->
param
(
'attachurl'
),
mimetype
=>
$content_type
,
mimetype
=>
$content_type
,
});
});
...
...
bugzilla.dtd
View file @
2addcaad
...
@@ -64,7 +64,6 @@
...
@@ -64,7 +64,6 @@
isobsolete (0|1) #IMPLIED
isobsolete (0|1) #IMPLIED
ispatch (0|1) #IMPLIED
ispatch (0|1) #IMPLIED
isprivate (0|1) #IMPLIED
isprivate (0|1) #IMPLIED
isurl (0|1) #IMPLIED
>
>
<!ELEMENT attachid (#PCDATA)>
<!ELEMENT attachid (#PCDATA)>
<!ELEMENT date (#PCDATA)>
<!ELEMENT date (#PCDATA)>
...
...
docs/en/xml/using.xml
View file @
2addcaad
...
@@ -862,14 +862,20 @@
...
@@ -862,14 +862,20 @@
</para>
</para>
<para>
<para>
Also, if the administrator turned on the
<quote>
allow_attach_url
</quote>
Also, you can enter the URL pointing to the attachment instead of
parameter, you can enter the URL pointing to the attachment instead of
uploading the attachment itself. For example, this is useful if you want to
uploading the attachment itself. For example, this is useful if you want to
point to an external application, a website or a very large file. Note that
point to an external application, a website or a very large file. Note that
there is no guarantee that the source file will always be available, nor
there is no guarantee that the source file will always be available, nor
that its content will remain unchanged.
that its content will remain unchanged.
</para>
</para>
<para>
Another way to attach data is to paste text directly in the text field,
and Bugzilla will convert it into an attachment. This is pretty useful
when you do copy and paste, and you don't want to put the text in a temporary
file first.
</para>
<section
id=
"patchviewer"
>
<section
id=
"patchviewer"
>
<title>
Patch Viewer
</title>
<title>
Patch Viewer
</title>
...
...
js/attachment.js
View file @
2addcaad
...
@@ -53,13 +53,13 @@ function setContentTypeDisabledState(form)
...
@@ -53,13 +53,13 @@ function setContentTypeDisabledState(form)
form
.
contenttypeentry
.
disabled
=
isdisabled
;
form
.
contenttypeentry
.
disabled
=
isdisabled
;
}
}
function
URL
FieldHandler
()
{
function
Text
FieldHandler
()
{
var
field_
attachurl
=
document
.
getElementById
(
"attachurl
"
);
var
field_
text
=
document
.
getElementById
(
"attach_text
"
);
var
greyfields
=
new
Array
(
"data"
,
"ispatch"
,
"autodetect"
,
var
greyfields
=
new
Array
(
"data"
,
"ispatch"
,
"autodetect"
,
"list"
,
"manual"
,
"contenttypeselection"
,
"list"
,
"manual"
,
"contenttypeselection"
,
"contenttypeentry"
);
"contenttypeentry"
);
var
i
,
thisfield
;
var
i
,
thisfield
;
if
(
field_
attachurl
.
value
.
match
(
/^
\s
*$/
))
{
if
(
field_
text
.
value
.
match
(
/^
\s
*$/
))
{
for
(
i
=
0
;
i
<
greyfields
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
greyfields
.
length
;
i
++
)
{
thisfield
=
document
.
getElementById
(
greyfields
[
i
]);
thisfield
=
document
.
getElementById
(
greyfields
[
i
]);
if
(
thisfield
)
{
if
(
thisfield
)
{
...
@@ -78,7 +78,7 @@ function URLFieldHandler() {
...
@@ -78,7 +78,7 @@ function URLFieldHandler() {
function
DataFieldHandler
()
{
function
DataFieldHandler
()
{
var
field_data
=
document
.
getElementById
(
"data"
);
var
field_data
=
document
.
getElementById
(
"data"
);
var
greyfields
=
new
Array
(
"attach
url
"
);
var
greyfields
=
new
Array
(
"attach
_text
"
);
var
i
,
thisfield
;
var
i
,
thisfield
;
if
(
field_data
.
value
.
match
(
/^
\s
*$/
))
{
if
(
field_data
.
value
.
match
(
/^
\s
*$/
))
{
for
(
i
=
0
;
i
<
greyfields
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
greyfields
.
length
;
i
++
)
{
...
@@ -102,9 +102,9 @@ function clearAttachmentFields() {
...
@@ -102,9 +102,9 @@ function clearAttachmentFields() {
document
.
getElementById
(
'data'
).
value
=
''
;
document
.
getElementById
(
'data'
).
value
=
''
;
DataFieldHandler
();
DataFieldHandler
();
if
((
element
=
document
.
getElementById
(
'attach
url
'
)))
{
if
((
element
=
document
.
getElementById
(
'attach
_text
'
)))
{
element
.
value
=
''
;
element
.
value
=
''
;
URL
FieldHandler
();
Text
FieldHandler
();
}
}
document
.
getElementById
(
'description'
).
value
=
''
;
document
.
getElementById
(
'description'
).
value
=
''
;
/* Fire onchange so that the disabled state of the content-type
/* Fire onchange so that the disabled state of the content-type
...
...
post_bug.cgi
View file @
2addcaad
...
@@ -183,7 +183,7 @@ if (defined $cgi->param('version')) {
...
@@ -183,7 +183,7 @@ if (defined $cgi->param('version')) {
# after the bug is filed.
# after the bug is filed.
# Add an attachment if requested.
# Add an attachment if requested.
if
(
defined
(
$cgi
->
upload
(
'data'
))
||
$cgi
->
param
(
'attach
url
'
))
{
if
(
defined
(
$cgi
->
upload
(
'data'
))
||
$cgi
->
param
(
'attach
_text
'
))
{
$cgi
->
param
(
'isprivate'
,
$cgi
->
param
(
'commentprivacy'
));
$cgi
->
param
(
'isprivate'
,
$cgi
->
param
(
'commentprivacy'
));
# Must be called before create() as it may alter $cgi->param('ispatch').
# Must be called before create() as it may alter $cgi->param('ispatch').
...
@@ -198,12 +198,11 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
...
@@ -198,12 +198,11 @@ if (defined($cgi->upload('data')) || $cgi->param('attachurl')) {
$attachment
=
Bugzilla::
Attachment
->
create
(
$attachment
=
Bugzilla::
Attachment
->
create
(
{
bug
=>
$bug
,
{
bug
=>
$bug
,
creation_ts
=>
$timestamp
,
creation_ts
=>
$timestamp
,
data
=>
scalar
$cgi
->
param
(
'attach
url
'
)
||
$cgi
->
upload
(
'data'
),
data
=>
scalar
$cgi
->
param
(
'attach
_text
'
)
||
$cgi
->
upload
(
'data'
),
description
=>
scalar
$cgi
->
param
(
'description'
),
description
=>
scalar
$cgi
->
param
(
'description'
),
filename
=>
$cgi
->
param
(
'attach
url'
)
?
'
'
:
scalar
$cgi
->
upload
(
'data'
),
filename
=>
$cgi
->
param
(
'attach
_text'
)
?
'attachment.txt
'
:
scalar
$cgi
->
upload
(
'data'
),
ispatch
=>
scalar
$cgi
->
param
(
'ispatch'
),
ispatch
=>
scalar
$cgi
->
param
(
'ispatch'
),
isprivate
=>
scalar
$cgi
->
param
(
'isprivate'
),
isprivate
=>
scalar
$cgi
->
param
(
'isprivate'
),
isurl
=>
scalar
$cgi
->
param
(
'attachurl'
),
mimetype
=>
$content_type
,
mimetype
=>
$content_type
,
});
});
};
};
...
...
template/en/default/admin/params/attachment.html.tmpl
View file @
2addcaad
...
@@ -60,10 +60,6 @@
...
@@ -60,10 +60,6 @@
allow_attachment_deletion => "If this option is on, administrators will be able to delete " _
allow_attachment_deletion => "If this option is on, administrators will be able to delete " _
"the content of attachments.",
"the content of attachments.",
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.",
maxattachmentsize => "The maximum size (in kilobytes) of attachments to be stored " _
maxattachmentsize => "The maximum size (in kilobytes) of attachments to be stored " _
"in the database. If a file larger than this size is attached " _
"in the database. If a file larger than this size is attached " _
"to ${terms.abug}, $terms.Bugzilla will look at the " _
"to ${terms.abug}, $terms.Bugzilla will look at the " _
...
...
template/en/default/attachment/create.html.tmpl
View file @
2addcaad
...
@@ -34,10 +34,16 @@
...
@@ -34,10 +34,16 @@
header = header
header = header
subheader = subheader
subheader = subheader
style_urls = [ 'skins/standard/attachment.css' ]
style_urls = [ 'skins/standard/attachment.css' ]
javascript_urls = [ "js/attachment.js", "js/util.js" ]
javascript_urls = [ "js/attachment.js", "js/util.js"
, "js/TUI.js"
]
doc_section = "attachments.html"
doc_section = "attachments.html"
%]
%]
<script type="text/javascript">
<!--
TUI_hide_default('attachment_text_field');
-->
</script>
<form name="entryform" method="post" action="attachment.cgi"
<form name="entryform" method="post" action="attachment.cgi"
enctype="multipart/form-data"
enctype="multipart/form-data"
onsubmit="return validateAttachmentForm(this)">
onsubmit="return validateAttachmentForm(this)">
...
...
template/en/default/attachment/createformcontents.html.tmpl
View file @
2addcaad
...
@@ -21,29 +21,27 @@
...
@@ -21,29 +21,27 @@
# Marc Schumann <wurblzap@gmail.com>
# Marc Schumann <wurblzap@gmail.com>
#%]
#%]
<tr>
<tr
class="attachment_data"
>
<th><label for="data">File</label>:</th>
<th><label for="data">File</label>:</th>
<td>
<td>
<em>Enter the path to the file on your computer.</em><br>
<em>Enter the path to the file on your computer</em> (or
<input type="file" id="data" name="data" size="50"
<a id="attachment_data_controller" href="javascript:TUI_toggle_class('attachment_text_field');
[% IF Param("allow_attach_url") %]
javascript:TUI_toggle_class('attachment_data')"
onchange="DataFieldHandler()"
>paste text as attachment</a>).<br>
[% END %]
<input type="file" id="data" name="data" size="50" onchange="DataFieldHandler()">
>
</td>
</td>
</tr>
</tr>
[% IF Param("allow_attach_url") %]
<tr class="attachment_text_field">
<tr class="expert_fields">
<th><label for="attach_text">File</label>:</th>
<th><label for="attachurl">AttachURL</label>:</th>
<td>
<td>
<em>URL to be attached instead.</em><br>
<em>Paste the text to be added as an attachment</em> (or
<input type="text" id="attachurl" name="attachurl" size="60"
<a id="attachment_text_field_controller" href="javascript:TUI_toggle_class('attachment_text_field');
maxlength="2000"
javascript:TUI_toggle_class('attachment_data')"
onkeyup="URLFieldHandler()" onblur="URLFieldHandler()">
>attach a file</a>).<br>
<textarea id="attach_text" name="attach_text" cols="80" rows="15"
onkeyup="TextFieldHandler()" onblur="TextFieldHandler()"></textarea>
</td>
</td>
</tr>
</tr>
</tbody>
[% END %]
<tr>
<tr>
<th><label for="description">Description</label>:</th>
<th><label for="description">Description</label>:</th>
<td>
<td>
...
...
template/en/default/attachment/edit.html.tmpl
View file @
2addcaad
...
@@ -68,19 +68,17 @@
...
@@ -68,19 +68,17 @@
<span class="bz_edit">(<a href="javascript:toggle_attachment_details_visibility()">edit</a>)</span>
<span class="bz_edit">(<a href="javascript:toggle_attachment_details_visibility()">edit</a>)</span>
[% END %]
[% END %]
</div>
</div>
[% IF NOT attachment.isurl %]
<div class="details">
<div class="details">
[% attachment.filename FILTER html %] ([% attachment.contenttype FILTER html %])
[% attachment.filename FILTER html %] ([% attachment.contenttype FILTER html %])
[% IF attachment.datasize %]
[% IF attachment.datasize %]
[%+ attachment.datasize FILTER unitconvert %]
[%+ attachment.datasize FILTER unitconvert %]
[% ELSE %]
[% ELSE %]
<em>deleted</em>
<em>deleted</em>
[% END %], created by [%+ INCLUDE global/user.html.tmpl who = attachment.attacher %]
[% END %], created by [%+ INCLUDE global/user.html.tmpl who = attachment.attacher %]
[% IF attachment.isprivate %]
[% IF attachment.isprivate %]
<span class="bz_private">Only visible to <strong>[% Param('insidergroup') FILTER html %]</strong></span>
<span class="bz_private">Only visible to <strong>[% Param('insidergroup') FILTER html %]</strong></span>
[% END %]
[% END %]
</div>
</div>
[% END %]
</div>
</div>
<div id="attachment_information_edit">
<div id="attachment_information_edit">
<span class="bz_hide">
<span class="bz_hide">
...
@@ -99,12 +97,6 @@
...
@@ -99,12 +97,6 @@
%]
%]
</div>
</div>
[% IF attachment.isurl %]
<input type="hidden" name="filename"
value="[% attachment.filename FILTER html %]">
<input type="hidden" name="contenttypeentry"
value="[% attachment.contenttype FILTER html %]">
[% ELSE %]
<div id="attachment_filename">
<div id="attachment_filename">
<label for="filename">Filename:</label>
<label for="filename">Filename:</label>
<input type="text" size="20" class="text block[% editable_or_hide %]"
<input type="text" size="20" class="text block[% editable_or_hide %]"
...
@@ -138,7 +130,7 @@
...
@@ -138,7 +130,7 @@
[%+ 'checked="checked"' IF attachment.ispatch %]>
[%+ 'checked="checked"' IF attachment.ispatch %]>
<label for="ispatch">patch</label>
<label for="ispatch">patch</label>
</div>
</div>
[% END %]
<div class="readonly">
<div class="readonly">
<div class="checkboxes">
<div class="checkboxes">
<div id="attachment_isobsolete">
<div id="attachment_isobsolete">
...
@@ -168,18 +160,6 @@
...
@@ -168,18 +160,6 @@
<div id="attachment_view_window">
<div id="attachment_view_window">
[% IF !attachment.datasize %]
[% IF !attachment.datasize %]
<div><b>The content of this attachment has been deleted.</b></div>
<div><b>The content of this attachment has been deleted.</b></div>
[% ELSIF attachment.isurl %]
<div>
<a href="[% attachment.data FILTER html %]">
[% IF attachment.datasize < 120 %]
[% attachment.data FILTER html %]
[% ELSE %]
[% attachment.data FILTER truncate(80) FILTER html %]
...
[% attachment.data.match(".*(.{20})$").0 FILTER html %]
[% END %]
</a>
</div>
[% ELSIF !Param("allow_attachment_display") %]
[% ELSIF !Param("allow_attachment_display") %]
<div id="view_disabled" >
<div id="view_disabled" >
<p><b>
<p><b>
...
...
template/en/default/attachment/list.html.tmpl
View file @
2addcaad
...
@@ -68,9 +68,8 @@ function toggle_display(link) {
...
@@ -68,9 +68,8 @@ function toggle_display(link) {
[% obsolete_attachments = obsolete_attachments + 1 %]
[% obsolete_attachments = obsolete_attachments + 1 %]
[% END %]
[% END %]
<tr id="a[% count %]" class="[% "bz_contenttype_" _ attachment.contenttype
<tr id="a[% count %]" class="[% "bz_contenttype_" _ attachment.contenttype
FILTER css_class_quote
UNLESS attachment.isurl
%]
FILTER css_class_quote %]
[% " bz_patch" IF attachment.ispatch %]
[% " bz_patch" IF attachment.ispatch %]
[% " bz_url" IF attachment.isurl %]
[% " bz_private" IF attachment.isprivate %]
[% " bz_private" IF attachment.isprivate %]
[% " bz_tr_obsolete bz_default_hidden"
[% " bz_tr_obsolete bz_default_hidden"
IF attachment.isobsolete %]">
IF attachment.isobsolete %]">
...
@@ -87,8 +86,6 @@ function toggle_display(link) {
...
@@ -87,8 +86,6 @@ function toggle_display(link) {
([% attachment.datasize FILTER unitconvert %],
([% attachment.datasize FILTER unitconvert %],
[% IF attachment.ispatch %]
[% IF attachment.ispatch %]
patch)
patch)
[% ELSIF attachment.isurl %]
url)
[% ELSE %]
[% ELSE %]
[%+ attachment.contenttype FILTER html %])
[%+ attachment.contenttype FILTER html %])
[% END %]
[% END %]
...
...
template/en/default/bug/create/create.html.tmpl
View file @
2addcaad
...
@@ -170,7 +170,8 @@ TUI_alternates['expert_fields'] = 'Show Advanced Fields';
...
@@ -170,7 +170,8 @@ TUI_alternates['expert_fields'] = 'Show Advanced Fields';
// Hide the Advanced Fields by default, unless the user has a cookie
// Hide the Advanced Fields by default, unless the user has a cookie
// that specifies otherwise.
// that specifies otherwise.
TUI_hide_default('expert_fields');
TUI_hide_default('expert_fields');
// Also hide the "Paste text as attachment" textarea by default.
TUI_hide_default('attachment_text_field');
-->
-->
</script>
</script>
...
...
template/en/default/bug/show.xml.tmpl
View file @
2addcaad
...
@@ -89,7 +89,6 @@
...
@@ -89,7 +89,6 @@
isobsolete="[% a.isobsolete FILTER xml %]"
isobsolete="[% a.isobsolete FILTER xml %]"
ispatch="[% a.ispatch FILTER xml %]"
ispatch="[% a.ispatch FILTER xml %]"
isprivate="[% a.isprivate FILTER xml %]"
isprivate="[% a.isprivate FILTER xml %]"
isurl="[% a.isurl FILTER xml %]"
>
>
<attachid>[% a.id %]</attachid>
<attachid>[% a.id %]</attachid>
<date>[% a.attached FILTER time("%Y-%m-%d %T %z") FILTER xml %]</date>
<date>[% a.attached FILTER time("%Y-%m-%d %T %z") FILTER xml %]</date>
...
...
template/en/default/global/code-error.html.tmpl
View file @
2addcaad
...
@@ -37,11 +37,7 @@
...
@@ -37,11 +37,7 @@
[% DEFAULT title = "Internal Error" %]
[% DEFAULT title = "Internal Error" %]
[% error_message = BLOCK %]
[% error_message = BLOCK %]
[% IF error == "attachment_url_disabled" %]
[% IF error == "auth_invalid_email" %]
[% title = "Attachment URL Disabled" %]
You cannot attach a URL. This feature is currently disabled.
[% ELSIF error == "auth_invalid_email" %]
[% title = "Invalid Email Address" %]
[% title = "Invalid Email Address" %]
We received an email address (<b>[% addr FILTER html %]</b>)
We received an email address (<b>[% addr FILTER html %]</b>)
that didn't pass our syntax checking for a legal email address,
that didn't pass our syntax checking for a legal email address,
...
...
template/en/default/global/field-descs.none.tmpl
View file @
2addcaad
...
@@ -108,7 +108,6 @@
...
@@ -108,7 +108,6 @@
"attachments.ispatch" => "Attachment is patch",
"attachments.ispatch" => "Attachment is patch",
"attachments.isobsolete" => "Attachment is obsolete",
"attachments.isobsolete" => "Attachment is obsolete",
"attachments.isprivate" => "Attachment is private",
"attachments.isprivate" => "Attachment is private",
"attachments.isurl" => "Attachment is a URL",
"attachments.submitter" => "Attachment creator",
"attachments.submitter" => "Attachment creator",
"blocked" => "Blocks",
"blocked" => "Blocks",
"bug_file_loc" => "URL",
"bug_file_loc" => "URL",
...
...
template/en/default/global/user-error.html.tmpl
View file @
2addcaad
...
@@ -222,11 +222,6 @@
...
@@ -222,11 +222,6 @@
[% title = "Attachment Deletion Disabled" %]
[% title = "Attachment Deletion Disabled" %]
Attachment deletion is disabled on this installation.
Attachment deletion is disabled on this installation.
[% ELSIF error == "attachment_illegal_url" %]
[% title = "Illegal Attachment URL" %]
<em>[% url FILTER html %]</em> is not a legal URL for attachments.
It must start either with http://, https:// or ftp://.
[% ELSIF error == "attachment_removed" %]
[% ELSIF error == "attachment_removed" %]
[% title = "Attachment Removed" %]
[% title = "Attachment Removed" %]
The attachment you are attempting to access has been removed.
The attachment you are attempting to access has been removed.
...
@@ -582,13 +577,8 @@
...
@@ -582,13 +577,8 @@
[%# Hack to get the max value between both limits %]
[%# Hack to get the max value between both limits %]
[%+ max_limit.nsort.last FILTER html %] KB. <br>
[%+ max_limit.nsort.last FILTER html %] KB. <br>
We recommend that you store your attachment elsewhere
We recommend that you store your attachment elsewhere
[% IF Param("allow_attach_url") %]
and then paste the URL to this file on the attachment
and then specify the URL to this file on the attachment
creation page in the appropriate text field.
creation page in the <b>AttachURL</b> field.
[% ELSE %]
and then insert the URL to it in a comment, or in the URL field
for this [% terms.bug %].
[% END %]
<br>Alternately, if your attachment is an image, you could convert
<br>Alternately, if your attachment is an image, you could convert
it to a compressible format like JPG or PNG and try again.
it to a compressible format like JPG or PNG and try again.
...
...
xt/lib/Bugzilla/Test/Search/Constants.pm
View file @
2addcaad
...
@@ -128,13 +128,8 @@ use constant FLAG_FIELDS => {
...
@@ -128,13 +128,8 @@ use constant FLAG_FIELDS => {
# These are fields that we don't test. Test::More will mark these
# These are fields that we don't test. Test::More will mark these
# "TODO & SKIP", and not run tests for them at all.
# "TODO & SKIP", and not run tests for them at all.
#
#
# attachments.isurl can't easily be supported by us, but it's basically
# identical to isprivate and isobsolete for searching, so that's not a big
# loss.
#
# We don't support days_elapsed or owner_idle_time yet.
# We don't support days_elapsed or owner_idle_time yet.
use
constant
SKIP_FIELDS
=>
qw(
use
constant
SKIP_FIELDS
=>
qw(
attachments.isurl
owner_idle_time
owner_idle_time
days_elapsed
days_elapsed
)
;
)
;
...
@@ -1183,7 +1178,6 @@ use constant INJECTION_BROKEN_FIELD => {
...
@@ -1183,7 +1178,6 @@ use constant INJECTION_BROKEN_FIELD => {
'attachments.isobsolete'
=>
{
db_skip
=>
[
'Pg'
]
},
'attachments.isobsolete'
=>
{
db_skip
=>
[
'Pg'
]
},
'attachments.ispatch'
=>
{
db_skip
=>
[
'Pg'
]
},
'attachments.ispatch'
=>
{
db_skip
=>
[
'Pg'
]
},
'attachments.isprivate'
=>
{
db_skip
=>
[
'Pg'
]
},
'attachments.isprivate'
=>
{
db_skip
=>
[
'Pg'
]
},
'attachments.isurl'
=>
{
db_skip
=>
[
'Pg'
]
},
blocked
=>
{
db_skip
=>
[
'Pg'
]
},
blocked
=>
{
db_skip
=>
[
'Pg'
]
},
bug_id
=>
{
db_skip
=>
[
'Pg'
]
},
bug_id
=>
{
db_skip
=>
[
'Pg'
]
},
cclist_accessible
=>
{
db_skip
=>
[
'Pg'
]
},
cclist_accessible
=>
{
db_skip
=>
[
'Pg'
]
},
...
...
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