Revision 1297:0a574315af3e app
| app/controllers/boards_controller.rb | ||
|---|---|---|
| 39 | 39 |
sort_init 'updated_on', 'desc' |
| 40 | 40 |
sort_update 'created_on' => "#{Message.table_name}.created_on",
|
| 41 | 41 |
'replies' => "#{Message.table_name}.replies_count",
|
| 42 |
'updated_on' => "#{Message.table_name}.updated_on"
|
|
| 42 |
'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
|
|
| 43 | 43 |
|
| 44 | 44 |
@topic_count = @board.topics.count |
| 45 | 45 |
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page'] |
| 46 |
@topics = @board.topics.reorder("#{Message.table_name}.sticky DESC").order(sort_clause).all(
|
|
| 47 |
:include => [:author, {:last_reply => :author}],
|
|
| 48 |
:limit => @topic_pages.items_per_page, |
|
| 49 |
:offset => @topic_pages.current.offset) |
|
| 46 |
@topics = @board.topics. |
|
| 47 |
reorder("#{Message.table_name}.sticky DESC").
|
|
| 48 |
includes(:last_reply). |
|
| 49 |
limit(@topic_pages.items_per_page). |
|
| 50 |
offset(@topic_pages.current.offset). |
|
| 51 |
order(sort_clause). |
|
| 52 |
preload(:author, {:last_reply => :author}).
|
|
| 53 |
all |
|
| 50 | 54 |
@message = Message.new(:board => @board) |
| 51 | 55 |
render :action => 'show', :layout => !request.xhr? |
| 52 | 56 |
} |
| app/controllers/messages_controller.rb | ||
|---|---|---|
| 123 | 123 |
|
| 124 | 124 |
private |
| 125 | 125 |
def find_message |
| 126 |
find_board |
|
| 126 |
return unless find_board
|
|
| 127 | 127 |
@message = @board.messages.find(params[:id], :include => :parent) |
| 128 | 128 |
@topic = @message.root |
| 129 | 129 |
rescue ActiveRecord::RecordNotFound |
| ... | ... | |
| 135 | 135 |
@project = @board.project |
| 136 | 136 |
rescue ActiveRecord::RecordNotFound |
| 137 | 137 |
render_404 |
| 138 |
nil |
|
| 138 | 139 |
end |
| 139 | 140 |
end |
| app/controllers/my_controller.rb | ||
|---|---|---|
| 182 | 182 |
# params[:block] : id of the block to add |
| 183 | 183 |
def add_block |
| 184 | 184 |
block = params[:block].to_s.underscore |
| 185 |
(render :nothing => true; return) unless block && (BLOCKS.keys.include? block) |
|
| 186 |
@user = User.current |
|
| 187 |
layout = @user.pref[:my_page_layout] || {}
|
|
| 188 |
# remove if already present in a group |
|
| 189 |
%w(top left right).each {|f| (layout[f] ||= []).delete block }
|
|
| 190 |
# add it on top |
|
| 191 |
layout['top'].unshift block |
|
| 192 |
@user.pref[:my_page_layout] = layout |
|
| 193 |
@user.pref.save |
|
| 185 |
if block.present? && BLOCKS.key?(block) |
|
| 186 |
@user = User.current |
|
| 187 |
layout = @user.pref[:my_page_layout] || {}
|
|
| 188 |
# remove if already present in a group |
|
| 189 |
%w(top left right).each {|f| (layout[f] ||= []).delete block }
|
|
| 190 |
# add it on top |
|
| 191 |
layout['top'].unshift block |
|
| 192 |
@user.pref[:my_page_layout] = layout |
|
| 193 |
@user.pref.save |
|
| 194 |
end |
|
| 194 | 195 |
redirect_to :action => 'page_layout' |
| 195 | 196 |
end |
| 196 | 197 |
|
| app/helpers/application_helper.rb | ||
|---|---|---|
| 610 | 610 |
|
| 611 | 611 |
def parse_inline_attachments(text, project, obj, attr, only_path, options) |
| 612 | 612 |
# when using an image link, try to use an attachment, if possible |
| 613 |
if options[:attachments] || (obj && obj.respond_to?(:attachments)) |
|
| 614 |
attachments = options[:attachments] || obj.attachments |
|
| 613 |
attachments = options[:attachments] || [] |
|
| 614 |
attachments += obj.attachments if obj.respond_to?(:attachments) |
|
| 615 |
if attachments.present? |
|
| 615 | 616 |
text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m| |
| 616 | 617 |
filename, ext, alt, alttext = $1.downcase, $2, $3, $4 |
| 617 | 618 |
# search for the picture in attachments |
| ... | ... | |
| 716 | 717 |
# identifier:document:"Some document" |
| 717 | 718 |
# identifier:version:1.0.0 |
| 718 | 719 |
# identifier:source:some/file |
| 719 |
def parse_redmine_links(text, project, obj, attr, only_path, options) |
|
| 720 |
text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m|
|
|
| 720 |
def parse_redmine_links(text, default_project, obj, attr, only_path, options)
|
|
| 721 |
text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m|
|
|
| 721 | 722 |
leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17 |
| 722 | 723 |
link = nil |
| 724 |
project = default_project |
|
| 723 | 725 |
if project_identifier |
| 724 | 726 |
project = Project.visible.find_by_identifier(project_identifier) |
| 725 | 727 |
end |
| ... | ... | |
| 805 | 807 |
when 'commit', 'source', 'export' |
| 806 | 808 |
if project |
| 807 | 809 |
repository = nil |
| 808 |
if name =~ %r{^(([a-z0-9\-]+)\|)(.+)$}
|
|
| 810 |
if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$}
|
|
| 809 | 811 |
repo_prefix, repo_identifier, name = $1, $2, $3 |
| 810 | 812 |
repository = project.repositories.detect {|repo| repo.identifier == repo_identifier}
|
| 811 | 813 |
else |
| ... | ... | |
| 832 | 834 |
end |
| 833 | 835 |
when 'attachment' |
| 834 | 836 |
attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil) |
| 835 |
if attachments && attachment = attachments.detect {|a| a.filename == name }
|
|
| 837 |
if attachments && attachment = Attachment.latest_attach(attachments, name)
|
|
| 836 | 838 |
link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
|
| 837 | 839 |
:class => 'attachment' |
| 838 | 840 |
end |
| app/helpers/issues_helper.rb | ||
|---|---|---|
| 350 | 350 |
association = Issue.reflect_on_association(field.to_sym) |
| 351 | 351 |
if association |
| 352 | 352 |
record = association.class_name.constantize.find_by_id(id) |
| 353 |
return record.name if record |
|
| 353 |
if record |
|
| 354 |
record.name.force_encoding('UTF-8') if record.name.respond_to?(:force_encoding)
|
|
| 355 |
return record.name |
|
| 356 |
end |
|
| 354 | 357 |
end |
| 355 | 358 |
end |
| 356 | 359 |
|
| app/helpers/queries_helper.rb | ||
|---|---|---|
| 87 | 87 |
format_time(value) |
| 88 | 88 |
when 'Date' |
| 89 | 89 |
format_date(value) |
| 90 |
when 'Fixnum', 'Float'
|
|
| 90 |
when 'Fixnum' |
|
| 91 | 91 |
if column.name == :done_ratio |
| 92 | 92 |
progress_bar(value, :width => '80px') |
| 93 |
elsif column.name == :spent_hours |
|
| 94 |
sprintf "%.2f", value |
|
| 95 | 93 |
else |
| 96 |
h(value.to_s)
|
|
| 94 |
value.to_s
|
|
| 97 | 95 |
end |
| 96 |
when 'Float' |
|
| 97 |
sprintf "%.2f", value |
|
| 98 | 98 |
when 'User' |
| 99 | 99 |
link_to_user value |
| 100 | 100 |
when 'Project' |
| app/models/issue.rb | ||
|---|---|---|
| 418 | 418 |
|
| 419 | 419 |
if attrs['parent_issue_id'].present? |
| 420 | 420 |
s = attrs['parent_issue_id'].to_s |
| 421 |
unless (m = s.match(%r{\A#?(\d+)\z})) && Issue.visible(user).exists?(m[1])
|
|
| 421 |
unless (m = s.match(%r{\A#?(\d+)\z})) && (m[1] == parent_id.to_s || Issue.visible(user).exists?(m[1]))
|
|
| 422 | 422 |
@invalid_parent_issue_id = attrs.delete('parent_issue_id')
|
| 423 | 423 |
end |
| 424 | 424 |
end |
| app/models/mail_handler.rb | ||
|---|---|---|
| 249 | 249 |
def add_attachments(obj) |
| 250 | 250 |
if email.attachments && email.attachments.any? |
| 251 | 251 |
email.attachments.each do |attachment| |
| 252 |
filename = attachment.filename |
|
| 253 |
unless filename.respond_to?(:encoding) |
|
| 254 |
# try to reencode to utf8 manually with ruby1.8 |
|
| 255 |
h = attachment.header['Content-Disposition'] |
|
| 256 |
unless h.nil? |
|
| 257 |
begin |
|
| 258 |
if m = h.value.match(/filename\*[0-9\*]*=([^=']+)'/) |
|
| 259 |
filename = Redmine::CodesetUtil.to_utf8(filename, m[1]) |
|
| 260 |
elsif m = h.value.match(/filename=.*=\?([^\?]+)\?[BbQq]\?/) |
|
| 261 |
# http://tools.ietf.org/html/rfc2047#section-4 |
|
| 262 |
filename = Redmine::CodesetUtil.to_utf8(filename, m[1]) |
|
| 263 |
end |
|
| 264 |
rescue |
|
| 265 |
# nop |
|
| 266 |
end |
|
| 267 |
end |
|
| 268 |
end |
|
| 269 | 252 |
obj.attachments << Attachment.create(:container => obj, |
| 270 | 253 |
:file => attachment.decoded, |
| 271 |
:filename => filename, |
|
| 254 |
:filename => attachment.filename,
|
|
| 272 | 255 |
:author => user, |
| 273 | 256 |
:content_type => attachment.mime_type) |
| 274 | 257 |
end |
| ... | ... | |
| 391 | 374 |
|
| 392 | 375 |
def cleaned_up_subject |
| 393 | 376 |
subject = email.subject.to_s |
| 394 |
unless subject.respond_to?(:encoding) |
|
| 395 |
# try to reencode to utf8 manually with ruby1.8 |
|
| 396 |
begin |
|
| 397 |
if h = email.header[:subject] |
|
| 398 |
# http://tools.ietf.org/html/rfc2047#section-4 |
|
| 399 |
if m = h.value.match(/=\?([^\?]+)\?[BbQq]\?/) |
|
| 400 |
subject = Redmine::CodesetUtil.to_utf8(subject, m[1]) |
|
| 401 |
end |
|
| 402 |
end |
|
| 403 |
rescue |
|
| 404 |
# nop |
|
| 405 |
end |
|
| 406 |
end |
|
| 407 | 377 |
subject.strip[0,255] |
| 408 | 378 |
end |
| 409 | 379 |
|
| app/models/project.rb | ||
|---|---|---|
| 751 | 751 |
def copy_wiki(project) |
| 752 | 752 |
# Check that the source project has a wiki first |
| 753 | 753 |
unless project.wiki.nil? |
| 754 |
self.wiki ||= Wiki.new
|
|
| 754 |
wiki = self.wiki || Wiki.new
|
|
| 755 | 755 |
wiki.attributes = project.wiki.attributes.dup.except("id", "project_id")
|
| 756 | 756 |
wiki_pages_map = {}
|
| 757 | 757 |
project.wiki.pages.each do |page| |
| ... | ... | |
| 763 | 763 |
wiki.pages << new_wiki_page |
| 764 | 764 |
wiki_pages_map[page.id] = new_wiki_page |
| 765 | 765 |
end |
| 766 |
|
|
| 767 |
self.wiki = wiki |
|
| 766 | 768 |
wiki.save |
| 767 | 769 |
# Reproduce page hierarchy |
| 768 | 770 |
project.wiki.pages.each do |page| |
| app/views/context_menus/issues.html.erb | ||
|---|---|---|
| 111 | 111 |
<li><%= bulk_update_custom_field_context_menu_link(field, text, value || text) %></li> |
| 112 | 112 |
<% end %> |
| 113 | 113 |
<% unless field.is_required? %> |
| 114 |
<li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '') %></li> |
|
| 114 |
<li><%= bulk_update_custom_field_context_menu_link(field, l(:label_none), '__none__') %></li>
|
|
| 115 | 115 |
<% end %> |
| 116 | 116 |
</ul> |
| 117 | 117 |
</li> |
| app/views/issues/_form.html.erb | ||
|---|---|---|
| 18 | 18 |
<% end %> |
| 19 | 19 |
|
| 20 | 20 |
<% if @issue.safe_attribute? 'subject' %> |
| 21 |
<p><%= f.text_field :subject, :size => 80, :required => true %></p> |
|
| 21 |
<p><%= f.text_field :subject, :size => 80, :maxlength => 255, :required => true %></p>
|
|
| 22 | 22 |
<% end %> |
| 23 | 23 |
|
| 24 | 24 |
<% if @issue.safe_attribute? 'description' %> |
| app/views/timelog/_form.html.erb | ||
|---|---|---|
| 12 | 12 |
<p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
|
| 13 | 13 |
<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
|
| 14 | 14 |
<p><%= f.text_field :hours, :size => 6, :required => true %></p> |
| 15 |
<p><%= f.text_field :comments, :size => 100 %></p> |
|
| 15 |
<p><%= f.text_field :comments, :size => 100, :maxlength => 255 %></p>
|
|
| 16 | 16 |
<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p> |
| 17 | 17 |
<% @time_entry.custom_field_values.each do |value| %> |
| 18 | 18 |
<p><%= custom_field_tag_with_label :time_entry, value %></p> |
Also available in: Unified diff