100 lines
4.2 KiB
Ruby
100 lines
4.2 KiB
Ruby
|
# A message within the foodsoft.
|
||
|
#
|
||
|
# * sender (User) - the sending User (might be nil if it is a system message)
|
||
|
# * recipient (User) - the receiving User
|
||
|
# * recipients (String) - list of all recipients of this message as User.nick/Group.name
|
||
|
# * subject (string) - message subject
|
||
|
# * body (string) - message body
|
||
|
# * read? (boolean) - message read status
|
||
|
# * email_state (integer) - email state, one of EMAIL_STATE.values
|
||
|
# * created_on (timestamp) - creation timestamp
|
||
|
class Message < ActiveRecord::Base
|
||
|
belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
|
||
|
belongs_to :recipient, :class_name => "User", :foreign_key => "recipient_id"
|
||
|
|
||
|
attr_accessible :recipient_id, :recipient, :subject, :body, :recipients
|
||
|
|
||
|
|
||
|
# Values for the email_state attribute: :none, :pending, :sent, :failed
|
||
|
EMAIL_STATE = {
|
||
|
:none => 0,
|
||
|
:pending => 1,
|
||
|
:sent => 2,
|
||
|
:failed => 3
|
||
|
}
|
||
|
|
||
|
validates_presence_of :recipient_id
|
||
|
validates_length_of :subject, :in => 1..255
|
||
|
validates_presence_of :recipients
|
||
|
validates_presence_of :body
|
||
|
validates_inclusion_of :email_state, :in => EMAIL_STATE.values
|
||
|
|
||
|
@@pending = false
|
||
|
|
||
|
# Automatically determine if this message should be send as an email.
|
||
|
def before_validation_on_create
|
||
|
if (recipient && recipient.settings["messages.sendAsEmail"] == '1')
|
||
|
self.email_state = EMAIL_STATE[:pending]
|
||
|
else
|
||
|
self.email_state = EMAIL_STATE[:none]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Determines if this new message is a pending email.
|
||
|
def after_create
|
||
|
@@pending = @@pending || self.email_state == EMAIL_STATE[:pending]
|
||
|
end
|
||
|
|
||
|
# Returns true if there might be pending emails.
|
||
|
def self.pending?
|
||
|
@@pending
|
||
|
end
|
||
|
|
||
|
# Returns true if this message is a system message, i.e. was sent automatically by the FoodSoft itself.
|
||
|
def system_message?
|
||
|
self.sender_id.nil?
|
||
|
end
|
||
|
|
||
|
# Sends all pending messages that are to be send as emails.
|
||
|
def self.send_emails
|
||
|
transaction do
|
||
|
messages = find(:all, :conditions => ["email_state = ?", EMAIL_STATE[:pending]], :lock => true)
|
||
|
logger.debug("Sending #{messages.size} pending messages as emails...") unless messages.empty?
|
||
|
for message in messages
|
||
|
if (message.recipient && message.recipient.email && !message.recipient.email.empty?)
|
||
|
begin
|
||
|
Mailer.deliver_message(message)
|
||
|
message.update_attribute(:email_state, EMAIL_STATE[:sent])
|
||
|
logger.debug("Delivered message as email: id = #{message.id}, recipient = #{message.recipient.nick}, subject = \"#{message.subject}\"")
|
||
|
rescue => exception
|
||
|
message.update_attribute(:email_state, EMAIL_STATE[:failed])
|
||
|
logger.warn("Failed to deliver message as email: id = #{message.id}, recipient = #{message.recipient.nick}, subject = \"#{message.subject}\", exception = #{exception.message}")
|
||
|
end
|
||
|
else
|
||
|
message.update_attribute(:email_state, EMAIL_STATE[:failed])
|
||
|
logger.warn("Cannot deliver message as email (no user email): id = #{message.id}, recipient = #{message.recipient.nick}, subject = \"#{message.subject}\"")
|
||
|
end
|
||
|
end
|
||
|
logger.debug("Done sending emails.") unless messages.empty?
|
||
|
@@pending = false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
# Returns a new message object created from the attributes specified (recipient, recipients, subject)
|
||
|
# and the body from the given template that can make use of the variables specified.
|
||
|
# The templates are to be stored in app/views/messages, i.e. the template name
|
||
|
# "order_finished" would invoke template file "app/views/messages/order_finished.rhtml".
|
||
|
# Note: you need to set the sender afterwards if this should not be a system message.
|
||
|
#
|
||
|
# Example:
|
||
|
# Message.from_template(
|
||
|
# 'order_finished',
|
||
|
# {:user => user, :group => order_group, :order => self, :results => results, :total => group_order.price},
|
||
|
# {:recipient_id => user.id, :recipients => recipients, :subject => "Bestellung beendet: #{self.name}"}
|
||
|
# ).save!
|
||
|
def self.from_template(template, vars, attributes)
|
||
|
view = ActionView::Base.new(Rails::Configuration.new.view_path, {}, MessagesController.new)
|
||
|
new(attributes.merge(:body => view.render(:file => "messages/#{template}.rhtml", :locals => vars)))
|
||
|
end
|
||
|
end
|