Extract message system to plugin.

This commit is contained in:
Robert Waltemath 2014-03-07 09:51:24 +01:00 committed by wvengen
parent fe0b17cdb0
commit 7556c753d0
45 changed files with 298 additions and 45 deletions

View file

@ -1,34 +0,0 @@
class MessagesController < ApplicationController
# Renders the "inbox" action.
def index
@messages = Message.public.page(params[:page]).per(@per_page).order('created_at DESC').includes(:sender)
end
# Creates a new message object.
def new
@message = Message.new(params[:message])
if @message.reply_to and not @message.reply_to.is_readable_for?(current_user)
redirect_to new_message_url, alert: 'Nachricht ist privat!'
end
end
# Creates a new message.
def create
@message = @current_user.send_messages.new(params[:message])
if @message.save
Resque.enqueue(UserNotifier, FoodsoftConfig.scope, 'message_deliver', @message.id)
redirect_to messages_url, :notice => I18n.t('messages.create.notice')
else
render :action => 'new'
end
end
# Shows a single message.
def show
@message = Message.find(params[:id])
unless @message.is_readable_for?(current_user)
redirect_to messages_url, alert: 'Nachricht ist privat!'
end
end
end

View file

@ -199,14 +199,9 @@ module ApplicationHelper
end
end
# render user presentation linking to default action (write message)
# render user presentation linking to default action (plugins can override this)
def show_user_link(user=@current_user)
if user.nil?
show_user user
else
link_to show_user(user), new_message_path('message[mail_to]' => user.id),
:title => I18n.t('helpers.application.write_message')
end
show_user user
end
end

View file

@ -1,20 +0,0 @@
module MessagesHelper
def format_subject(message, length)
if message.subject.length > length
subject = truncate(message.subject, :length => length)
body = ""
else
subject = message.subject
body = truncate(message.body, :length => length - subject.length)
end
"<b>#{link_to(h(subject), message)}</b> <span style='color:grey'>#{h(body)}</span>".html_safe
end
def link_to_new_message(options = {})
messages_params = options[:message_params] || nil
link_text = content_tag :id, nil, class: 'icon-envelope'
link_text << " #{options[:text]}" if options[:text].present?
link_to(link_text.html_safe, new_message_path(message: messages_params), class: 'btn',
title: I18n.t('helpers.submit.message.create'))
end
end

View file

@ -13,16 +13,6 @@ class Mailer < ActionMailer::Base
sender: FoodsoftConfig[:email_sender],
errors_to: FoodsoftConfig[:email_sender]
# Sends an email copy of the given internal foodsoft message.
def foodsoft_message(message, recipient)
set_foodcoop_scope
@message = message
mail subject: "[#{FoodsoftConfig[:name]}] " + message.subject,
to: recipient.email,
from: "#{show_user(message.sender)} <#{message.sender.email}>"
end
# Sends an email with instructions on how to reset the password.
# Assumes user.setResetPasswordToken has been successfully called already.
def reset_password(user)

View file

@ -1,92 +0,0 @@
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => "User", :foreign_key => "sender_id"
serialize :recipients_ids, Array
attr_accessor :sent_to_all, :group_id, :recipient_tokens, :reply_to
scope :pending, -> { where(:email_state => 0) }
scope :sent, -> { where(:email_state => 1) }
scope :public, -> { where(:private => false) }
# Values for the email_state attribute: :none, :pending, :sent, :failed
EMAIL_STATE = {
:pending => 0,
:sent => 1,
:failed => 2
}
validates_presence_of :recipients_ids, :subject, :body
validates_length_of :subject, :in => 1..255
validates_inclusion_of :email_state, :in => EMAIL_STATE.values
before_validation :clean_up_recipient_ids, :on => :create
def self.deliver(message_id)
find(message_id).deliver
end
def clean_up_recipient_ids
self.recipients_ids = recipients_ids.uniq.reject { |id| id.blank? } unless recipients_ids.nil?
self.recipients_ids = User.all.collect(&:id) if sent_to_all == "1"
end
def add_recipients(users)
self.recipients_ids = [] if recipients_ids.blank?
self.recipients_ids += users.collect(&:id) unless users.blank?
end
def group_id=(group_id)
@group_id = group_id
add_recipients Group.find(group_id).users unless group_id.blank?
end
def recipient_tokens=(ids)
@recipient_tokens = ids
add_recipients ids.split(",").collect { |id| User.find(id) }
end
def reply_to=(message_id)
@reply_to = Message.find(message_id)
add_recipients([@reply_to.sender])
self.subject = I18n.t('messages.model.reply_subject', :subject => @reply_to.subject)
self.body = I18n.t('messages.model.reply_header', :user => @reply_to.sender.display, :when => I18n.l(@reply_to.created_at, :format => :short)) + "\n"
@reply_to.body.each_line{ |l| self.body += I18n.t('messages.model.reply_indent', :line => l) }
end
def mail_to=(user_id)
user = User.find(user_id)
add_recipients([user])
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
def sender_name
system_message? ? I18n.t('layouts.foodsoft') : sender.display rescue "?"
end
def recipients
User.find(recipients_ids)
end
def deliver
for user in recipients
if user.receive_email?
begin
Mailer.foodsoft_message(self, user).deliver
rescue
Rails.logger.warn "Deliver failed for user \##{user.id}: #{user.email}"
end
end
end
update_attribute(:email_state, 1)
end
def is_readable_for?(user)
!private || sender == user || recipients_ids.include?(user.id)
end
end

View file

@ -3,4 +3,3 @@
%section= render 'shared/group', group: @ordergroup
= link_to t('ui.edit'), edit_admin_ordergroup_path(@ordergroup), class: 'btn'
= link_to t('ui.delete'), [:admin, @ordergroup], :data => {:confirm => t('.confirm')}, :method => :delete, class: 'btn btn-danger'
= link_to t('.send_message'), new_message_path(:message => {:group_id => @ordergroup.id}), class: 'btn'

View file

@ -37,4 +37,3 @@
= link_to t('ui.edit'), edit_admin_user_path(@user), class: 'btn'
= link_to t('ui.delete'), [:admin, @user], :data => {:confirm => t('.confirm', user: @user.first_name)},
:method => :delete, class: 'btn btn-danger'
= link_to t('.send_message'), new_message_path(:message => {:mail_to => @user.id}), class: 'btn'

View file

@ -3,4 +3,3 @@
%section= render 'shared/group', group: @workgroup
= link_to t('ui.edit'), edit_admin_workgroup_path(@workgroup), class: 'btn'
= link_to t('ui.delete'), [:admin, @workgroup], :data => {:confirm => t('.confirm')}, :method => :delete, class: 'btn btn-danger'
= link_to_new_message(message_params: {group_id: @workgroup.id})

View file

@ -15,5 +15,4 @@
%td= ordergroup.name
%td=h ordergroup.users.collect { |u| show_user(u) }.join(", ")
%td= format_date ordergroup.last_order.try(:starts)
%td= link_to_new_message(message_params: {group_id: ordergroup.id})

View file

@ -21,5 +21,4 @@
%td= user.phone if @current_user.role_admin? || user.settings.profile["phone_is_public"]
%td= user.ordergroup_name
%td= user.workgroups.collect(&:name).join(', ')
%td= link_to_new_message(message_params: {mail_to: user.id})

View file

@ -2,6 +2,5 @@
%h3= workgroup.name
= render :partial => 'shared/group', :locals => { :group => workgroup }
= link_to t('.show_tasks'), workgroup_tasks_path(workgroup_id: workgroup), class: 'btn'
= link_to_new_message message_params: {group_id: workgroup.id}
- if workgroup.member?(current_user)
= link_to t('.edit'), edit_foodcoop_workgroup_path(workgroup), class: 'btn'

View file

@ -4,7 +4,6 @@
%li.nav-header= t '.foodcoop'
%li= link_to t('.members'), foodcoop_users_path
%li= link_to t('.tasks'), user_tasks_path
%li= link_to t('.write_message'), new_message_path
- has_ordergroup = !@current_user.ordergroup.nil?
- has_orders_role = @current_user.role_orders?

View file

@ -3,6 +3,9 @@
- content_for(:sidebar) do
= render :partial => 'start_nav'
-# placeholder deface to add content using erb[silent]:contains()
- '<dashboard_top_mark>'
- unless @unaccepted_tasks.empty? && @next_tasks.empty? && @unassigned_tasks.size == 0
%section.row-fluid
- unless @next_tasks.empty?
@ -32,11 +35,8 @@
%h2= t '.ordergroup.title'
= render :partial => "apple_bar", :locals => {:apple_bar => AppleBar.new(current_user.ordergroup)}
- unless Message.public.empty?
%section
%h2= t '.messages.title'
= render 'messages/messages', messages: Message.public.order('created_at DESC').limit(5), pagination: false
%p= link_to t('.messages.view_all'), messages_path
-# placeholder deface to add content using erb[silent]:contains()
- '<dashboard_middle_mark>'
- if current_user.ordergroup
// Ordergroup overview
@ -63,3 +63,6 @@
%td{:style => "color:#{color}; width:5em", :class => "currency"}= number_to_currency(ft.amount)
%br/
%p= link_to t('.my_ordergroup.transactions.view'), my_ordergroup_path
-# placeholder deface to add content using erb[silent]:contains()
- '<dashboard_bottom_mark>'

View file

@ -1,4 +0,0 @@
= @message.body
======================================================================
\
= t '.footer', reply_url: new_message_url('message[reply_to]' => @message.id), msg_url: message_url(@message), profile_url: my_profile_url

View file

@ -1,14 +0,0 @@
- if pagination
- if Message.public.count > 20
= items_per_page
= pagination_links_remote messages
- unless messages.empty?
%table.table.table-striped
%tbody
- for message in messages
%tr
%td= format_subject(message, 130)
%td= h(message.sender_name)
%td= format_time(message.created_at)
%td= link_to t('.reply'), new_message_path(:message => {:reply_to => message.id}), class: 'btn'

View file

@ -1,6 +0,0 @@
- title t('.title')
- content_for :actionbar do
= link_to t('.new'), new_message_path, class: 'btn btn-primary'
#messages
= render 'messages', messages: @messages, pagination: true

View file

@ -1 +0,0 @@
$('#messages').html('#{j(render('messages', messages: @messages, pagination: true))}');

View file

@ -1,46 +0,0 @@
- content_for :javascript do
:javascript
$(function() {
$('#message_recipient_tokens').tokenInput("#{users_path(:format => :json)}", {
crossDomain: false,
prePopulate: $('#message_recipient_tokens').data('pre'),
hintText: '#{t '.search_user'}',
noResultText: '#{t '.no_user_found'}',
searchingText: '#{t '.search'}',
theme: 'facebook'
});
$('#message_sent_to_all').on('touchclick', function() {
if ($(this).is(':checked')) {
$('#recipients').slideUp();
} else {
$('#recipients').slideDown();
}
});
});
- title t('.title')
= simple_form_for @message do |f|
- if FoodsoftConfig[:mailing_list].blank?
= f.input :sent_to_all, :as => :boolean
- else
%b= t('.list.desc', list: mail_to(FoodsoftConfig[:mailing_list])).html_safe
%br/
%small{:style => "color:grey"}
= t '.list.subscribe_msg'
%br/
- if FoodsoftConfig[:mailing_list_subscribe].blank?
= t('.list.subscribe', link: link_to(t('.list.wiki'), wiki_page_path('MailingListe'))).html_safe
- else
= t('.list.mail', email: mail_to(FoodsoftConfig[:mailing_list_subscribe])).html_safe
#recipients
= f.input :recipient_tokens, :input_html => { 'data-pre' => User.where(id: @message.recipients_ids).map(&:token_attributes).to_json }
= f.input :group_id, :as => :select, :collection => Group.undeleted.order('type DESC, name ASC').reject { |g| g.memberships.empty? }
= f.input :private
= f.input :subject, input_html: {class: 'input-xxlarge'}
= f.input :body, input_html: {class: 'input-xxlarge'}
.form-actions
= f.submit class: 'btn btn-primary'
= link_to t('ui.or_cancel'), :back

View file

@ -1,21 +0,0 @@
- title t('.title')
%div{:style => "width:40em"}
%table{:style => "width:25em"}
%tr
%td= t '.from'
%td=h @message.sender_name
%tr
%td= t '.subject'
%td
%b=h @message.subject
%tr
%td= t '.sent_on'
%td= format_time(@message.created_at)
%hr/
%p= simple_format(h(@message.body))
%hr/
%p
= link_to t('.reply'), new_message_path(:message => {:reply_to => @message.id}), class: 'btn'
|
= link_to t('.all_messages'), messages_path

View file

@ -8,11 +8,6 @@ class UserNotifier
self.send method_name, args
end
def self.message_deliver(args)
message_id = args.first
Message.find(message_id).deliver
end
def self.finished_order(args)
order_id = args.first
Order.find(order_id).group_orders.each do |group_order|