obsolete.ChilliProject/vendor/plugins/acts_as_journalized/lib/journal_formatter.rb

220 lines
7.0 KiB
Ruby

#-- encoding: UTF-8
# This file is part of the acts_as_journalized plugin for the redMine
# project management software
#
# Copyright (C) 2010 Finn GmbH, http://finn.de
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either journal 2
# of the License, or (at your option) any later journal.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# This module holds the formatting methods that each journal has.
# It provides the hooks to apply different formatting to the details
# of a specific journal.
module JournalFormatter
unloadable
mattr_accessor :formatters, :registered_fields
include ApplicationHelper
include CustomFieldsHelper
include ActionView::Helpers::TagHelper
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TextHelper
include ActionController::UrlWriter
extend Redmine::I18n
def self.included(base)
base.class_eval do
# Required to use any link_to in the formatters
def self.default_url_options
{:only_path => true }
end
end
end
def self.register(hash)
if hash[:class]
klazz = hash.delete(:class)
registered_fields[klazz] ||= {}
registered_fields[klazz].merge!(hash)
else
formatters.merge(hash)
end
end
# TODO: Document Formatters (can take up to three params, value, journaled, field ...)
def self.default_formatters
{ :plaintext => (Proc.new {|v,*| v.try(:to_s) }),
:datetime => (Proc.new {|v,*| format_date(v.to_date) }),
:named_association => (Proc.new do |value, journaled, field|
association = journaled.class.reflect_on_association(field.to_sym)
if association
record = association.class_name.constantize.find_by_id(value.to_i)
record.name if record
end
end),
:fraction => (Proc.new {|v,*| "%0.02f" % v.to_f }),
:decimal => (Proc.new {|v,*| v.to_i.to_s }),
:id => (Proc.new {|v,*| "##{v}" }) }
end
self.formatters = default_formatters
self.registered_fields = {}
def format_attribute_detail(key, values, no_html=false)
field = key.to_s.gsub(/\_id$/, "")
label = l(("field_" + field).to_sym)
if format = JournalFormatter.registered_fields[self.class.name.to_sym][key]
formatter = JournalFormatter.formatters[format]
old_value = formatter.call(values.first, journaled, field) if values.first
value = formatter.call(values.last, journaled, field) if values.last
[label, old_value, value]
else
return nil
end
end
def format_custom_value_detail(custom_field, values, no_html)
if custom_field
label = custom_field.name
old_value = format_value(values.first, custom_field.field_format) if values.first
value = format_value(values.last, custom_field.field_format) if values.last
else
label = l(:label_deleted_custom_field)
old_value = values.first
value = values.last
end
[label, old_value, value]
end
def format_attachment_detail(key, values, no_html)
label = l(:label_attachment)
old_value = values.first
value = values.last
[label, old_value, value]
end
def format_html_attachment_detail(key, value)
if !value.blank? && a = Attachment.find_by_id(key.to_i)
link_to_attachment(a)
else
content_tag("i", h(value)) if value.present?
end
end
def format_html_detail(label, old_value, value)
label = content_tag('strong', label)
old_value = content_tag("i", h(old_value)) if old_value && !old_value.blank?
old_value = content_tag("strike", old_value) if old_value and value.blank?
value = content_tag("i", h(value)) if value.present?
value ||= ""
[label, old_value, value]
end
# Formats a detail to be used with a Journal diff
#
# Truncates the content. Adds a link to view a diff.
def format_html_diff_detail(key, label, old_value, value)
link = link_to(l(:label_more), {:controller => 'journals', :action => 'diff', :id => id, :field => key.to_s})
old_value = truncate(old_value, :length => 80)
value = truncate(value, :length => 80) + " " + link
[old_value, value]
end
def property(detail)
key = prop_key(detail)
if key.start_with? "custom_values"
:custom_field
elsif key.start_with? "attachments"
:attachment
elsif journaled.class.columns.collect(&:name).include? key
:attribute
end
end
def prop_key(detail)
if detail.respond_to? :to_ary
detail.first
else
detail
end
end
def values(detail)
key = prop_key(detail)
if detail != key
detail.last
else
details[key.to_s]
end
end
def old_value(detail)
values(detail).first
end
def value(detail)
values(detail).last
end
def render_detail(detail, no_html=false)
if detail.respond_to? :to_ary
key = detail.first
values = detail.last
else
key = detail
values = details[key.to_s]
end
case property(detail)
when :attribute
attr_detail = format_attribute_detail(key, values, no_html)
when :custom_field
custom_field = CustomField.find_by_id(key.sub("custom_values", "").to_i)
cv_detail = format_custom_value_detail(custom_field, values, no_html)
when :attachment
attachment_detail = format_attachment_detail(key.sub("attachments", ""), values, no_html)
end
label, old_value, value = attr_detail || cv_detail || attachment_detail
Redmine::Hook.call_hook :helper_issues_show_detail_after_setting, {:detail => JournalDetail.new(label, old_value, value),
:label => label, :value => value, :old_value => old_value }
return nil unless label || old_value || value # print nothing if there are no values
label, old_value, value = [label, old_value, value].collect(&:to_s)
unless no_html
label, old_value, value = *format_html_detail(label, old_value, value)
value = format_html_attachment_detail(key.sub("attachments", ""), value) if attachment_detail
if property(detail) == :attribute && key == "description"
old_value, value = *format_html_diff_detail(key, label, old_value, value)
end
end
unless value.blank?
if attr_detail || cv_detail
unless old_value.blank?
l(:text_journal_changed, :label => label, :old => old_value, :new => value)
else
l(:text_journal_set_to, :label => label, :value => value)
end
elsif attachment_detail
l(:text_journal_added, :label => label, :value => value)
end
else
l(:text_journal_deleted, :label => label, :old => old_value)
end
end
end