mailboxer-without-notification 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +11 -0
  4. data/.yardopts +2 -0
  5. data/Appraisals +19 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +298 -0
  9. data/Rakefile +11 -0
  10. data/app/mailers/message_mailer.rb +37 -0
  11. data/app/models/conversation.rb +179 -0
  12. data/app/models/mailbox.rb +122 -0
  13. data/app/models/message.rb +218 -0
  14. data/app/models/receipt.rb +176 -0
  15. data/app/uploaders/attachment_uploader.rb +3 -0
  16. data/app/views/message_mailer/new_message_email.html.erb +20 -0
  17. data/app/views/message_mailer/new_message_email.text.erb +10 -0
  18. data/app/views/message_mailer/reply_message_email.html.erb +20 -0
  19. data/app/views/message_mailer/reply_message_email.text.erb +10 -0
  20. data/config/locales/en.yml +7 -0
  21. data/config/locales/fr.yml +7 -0
  22. data/db/migrate/20110511145103_create_mailboxer.rb +61 -0
  23. data/db/migrate/20110719110700_add_notified_object.rb +17 -0
  24. data/db/migrate/20110912163911_add_notification_code.rb +13 -0
  25. data/db/migrate/20111204163911_add_attachments.rb +9 -0
  26. data/db/migrate/20120813110712_rename_receipts_read.rb +9 -0
  27. data/db/migrate/20130305144212_add_global_notification_support.rb +9 -0
  28. data/db/migrate/20131003144212_change_table_notification.rb +10 -0
  29. data/db/migrate/20131003214212_change_relations.rb +6 -0
  30. data/gemfiles/rails3.0.gemfile +8 -0
  31. data/gemfiles/rails3.1.gemfile +8 -0
  32. data/gemfiles/rails3.2.gemfile +8 -0
  33. data/gemfiles/rails4.0.gemfile +8 -0
  34. data/lib/generators/mailboxer/install_generator.rb +35 -0
  35. data/lib/generators/mailboxer/templates/initializer.rb +17 -0
  36. data/lib/generators/mailboxer/views_generator.rb +9 -0
  37. data/lib/mailboxer.rb +37 -0
  38. data/lib/mailboxer/concerns/configurable_mailer.rb +13 -0
  39. data/lib/mailboxer/engine.rb +17 -0
  40. data/lib/mailboxer/models/messageable.rb +225 -0
  41. data/mailboxer.gemspec +49 -0
  42. data/spec/dummy/.gitignore +5 -0
  43. data/spec/dummy/Gemfile +33 -0
  44. data/spec/dummy/Rakefile +7 -0
  45. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  46. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  47. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  48. data/spec/dummy/app/mailers/.gitkeep +0 -0
  49. data/spec/dummy/app/models/.gitkeep +0 -0
  50. data/spec/dummy/app/models/cylon.rb +7 -0
  51. data/spec/dummy/app/models/duck.rb +11 -0
  52. data/spec/dummy/app/models/user.rb +6 -0
  53. data/spec/dummy/app/views/home/index.html.haml +7 -0
  54. data/spec/dummy/app/views/layouts/application.html.haml +11 -0
  55. data/spec/dummy/config.ru +4 -0
  56. data/spec/dummy/config/application.rb +42 -0
  57. data/spec/dummy/config/boot.rb +10 -0
  58. data/spec/dummy/config/database.yml +24 -0
  59. data/spec/dummy/config/environment.rb +5 -0
  60. data/spec/dummy/config/environments/development.rb +26 -0
  61. data/spec/dummy/config/environments/production.rb +49 -0
  62. data/spec/dummy/config/environments/test.rb +33 -0
  63. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/spec/dummy/config/initializers/inflections.rb +10 -0
  65. data/spec/dummy/config/initializers/mailboxer.rb +17 -0
  66. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  67. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  68. data/spec/dummy/config/initializers/session_store.rb +8 -0
  69. data/spec/dummy/config/locales/en.yml +5 -0
  70. data/spec/dummy/config/routes.rb +58 -0
  71. data/spec/dummy/config/sunspot.yml +17 -0
  72. data/spec/dummy/db/migrate/20110228120600_create_users.rb +14 -0
  73. data/spec/dummy/db/migrate/20110306002940_create_ducks.rb +14 -0
  74. data/spec/dummy/db/migrate/20110306015107_create_cylons.rb +14 -0
  75. data/spec/dummy/db/migrate/20120305103200_create_mailboxer.rb +61 -0
  76. data/spec/dummy/db/migrate/20120305103201_add_notified_object.rb +17 -0
  77. data/spec/dummy/db/migrate/20120305103202_add_notification_code.rb +13 -0
  78. data/spec/dummy/db/migrate/20120305103203_add_attachments.rb +5 -0
  79. data/spec/dummy/db/migrate/20120813110712_rename_receipts_read.rb +9 -0
  80. data/spec/dummy/db/migrate/20130305144212_add_global_notification_support.rb +11 -0
  81. data/spec/dummy/db/migrate/20131003144212_change_table_notification.rb +10 -0
  82. data/spec/dummy/db/migrate/20131003214212_change_relations.rb +6 -0
  83. data/spec/dummy/db/schema.rb +74 -0
  84. data/spec/dummy/public/404.html +26 -0
  85. data/spec/dummy/public/422.html +26 -0
  86. data/spec/dummy/public/500.html +26 -0
  87. data/spec/dummy/public/favicon.ico +0 -0
  88. data/spec/dummy/public/index.html +239 -0
  89. data/spec/dummy/public/robots.txt +5 -0
  90. data/spec/dummy/public/uploads/testfile.txt +1 -0
  91. data/spec/dummy/script/rails +6 -0
  92. data/spec/factories/cylon.rb +10 -0
  93. data/spec/factories/duck.rb +10 -0
  94. data/spec/factories/user.rb +10 -0
  95. data/spec/integration/message_and_receipt_spec.rb +903 -0
  96. data/spec/integration/navigation_spec.rb +9 -0
  97. data/spec/mailboxer/concerns/configurable_mailer_spec.rb +27 -0
  98. data/spec/mailboxer_spec.rb +7 -0
  99. data/spec/mailers/message_mailer_spec.rb +109 -0
  100. data/spec/models/conversation_spec.rb +154 -0
  101. data/spec/models/mailbox_spec.rb +160 -0
  102. data/spec/models/mailboxer_models_messageable_spec.rb +324 -0
  103. data/spec/models/message_spec.rb +222 -0
  104. data/spec/models/receipt_spec.rb +56 -0
  105. data/spec/spec_helper.rb +36 -0
  106. data/spec/testfile.txt +1 -0
  107. metadata +301 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ spec/dummy/db/*.sqlite3
5
+ spec/dummy/log/*.log
6
+ spec/dummy/log/*.lck
7
+ spec/dummy/tmp/
8
+ spec/dummy/.project
9
+ spec/dummy/solr
10
+ **.tmp_*
11
+ Gemfile.lock
12
+ .idea
13
+ .project
14
+ .document
15
+ .settings/
16
+ rdoc/
17
+ doc/
18
+ .yardoc/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - rbx-19mode
6
+ - jruby-19mode
7
+ gemfile:
8
+ #- gemfiles/rails3.0.gemfile
9
+ - gemfiles/rails3.1.gemfile
10
+ - gemfiles/rails3.2.gemfile
11
+ - gemfiles/rails4.0.gemfile
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ lib/**/*.rb
2
+ app/**/*.rb
data/Appraisals ADDED
@@ -0,0 +1,19 @@
1
+ # appraise "rails3.0" do
2
+ # gem "rails", "~> 3.0.15"
3
+ # gem "mailboxer", :path => "../"
4
+ # end
5
+
6
+ appraise "rails3.1" do
7
+ gem "rails", "~> 3.1.6"
8
+ gem "mailboxer", :path => "../"
9
+ end
10
+
11
+ appraise "rails3.2" do
12
+ gem "rails", "~> 3.2.6"
13
+ gem "mailboxer", :path => "../"
14
+ end
15
+
16
+ appraise "rails4.0" do
17
+ gem "rails", ">=4.0.0"
18
+ gem "mailboxer", :path => "../"
19
+ end
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2013 Justin Coyne
2
+ Copyright (c) 2012 Universidad Politécnica de Madrid
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,298 @@
1
+ I juste take the gem mailboxer and I remove the notifications. The table is now nammed messages (and not notifications).
2
+ I correct the spec tests too. Only 4 minors errors to corect. The gem is working.
3
+
4
+ We can now send messages without subject.
5
+
6
+
7
+ # Mailboxer 0.10.x [![](https://secure.travis-ci.org/ging/mailboxer.png)](http://travis-ci.org/ging/mailboxer) [![Gem Version](https://badge.fury.io/rb/mailboxer.png)](http://badge.fury.io/rb/mailboxer) [![](https://gemnasium.com/ging/mailboxer.png)](https://gemnasium.com/ging/mailboxer)
8
+
9
+ This project is based on the need for a private message system for [ging
10
+ / social\_stream](https://github.com/ging/social_stream). Instead of creating our core message system heavily
11
+ dependent on our development, we are trying to implement a generic and
12
+ potent messaging gem.
13
+
14
+ After looking for a good gem to use we noticed the lack of messaging gems
15
+ and functionality in them. Mailboxer tries to fill this void delivering
16
+ a powerful and flexible message system. It supports the use of
17
+ conversations with two or more participants, sending notifications to
18
+ recipients (intended to be used as system notifications “Your picture has
19
+ new comments”, “John Doe has updated his document”, etc.), and emailing the
20
+ messageable model (if configured to do so). It has a complete implementation
21
+ of a `Mailbox` object for each messageable with `inbox`, `sentbox` and
22
+ `trash`.
23
+
24
+ The gem is constantly growing and improving its functionality. As it is
25
+ used with our parallel development [ging / social\_stream](https://github.com/ging/social_stream) we are finding and fixing bugs continously. If you want
26
+ some functionality not supported yet or marked as TODO, you can create
27
+ an [issue](https://github.com/ging/mailboxer/issues) to ask for it. It will be great feedback for us, and we
28
+ will know what you may find useful in the gem.
29
+
30
+ Mailboxer was born from the great, but outdated, code from [lpsergi /
31
+ acts*as*messageable](https://github.com/psergi/acts_as_messageable).
32
+
33
+ We are now working to make exhaustive documentation and some wiki
34
+ pages in order to make it even easier to use the gem to its full potencial.
35
+ Please, give us some time if you find something missing or [ask for
36
+ it](https://github.com/ging/mailboxer/issues).
37
+
38
+ Installation
39
+ ------------
40
+
41
+ Add to your Gemfile:
42
+
43
+ ```ruby
44
+ gem 'mailboxer'
45
+ ```
46
+
47
+ Then run:
48
+
49
+ ```sh
50
+ $ bundle update
51
+ ```
52
+
53
+ Run install script:
54
+
55
+ ```sh
56
+ $ rails g mailboxer:install
57
+ ```
58
+
59
+ And don't forget to migrate your database:
60
+
61
+ ```sh
62
+ $ rake db:migrate
63
+ ```
64
+
65
+ ## Requirements & Settings
66
+
67
+ ### Emails
68
+
69
+ We are now adding support for sending emails when a Notification or a Message is sent to one or more recipients. You should modify the mailboxer initializer (/config/initializer/mailboxer.rb) to edit these settings.
70
+
71
+ ```ruby
72
+ Mailboxer.setup do |config|
73
+ #Enables or disables email sending for Notifications and Messages
74
+ config.uses_emails = true
75
+ #Configures the default `from` address for the email sent for Messages and Notifications of Mailboxer
76
+ config.default_from = "no-reply@dit.upm.es"
77
+ ...
78
+ end
79
+ ```
80
+
81
+ You can change the way in which emails are delivered by specifying a custom implementation of notification and message mailers
82
+
83
+ ```ruby
84
+ Mailboxer.setup do |config|
85
+ config.notification_mailer = CustomNotificationMailer
86
+ config.message_mailer = CustomMessageMailer
87
+ ...
88
+ end
89
+ ```
90
+
91
+ ### User identities
92
+
93
+ Users must have an identity defined by a `name` and an `email`. We must ensure that Messageable models have some specific methods. These methods are:
94
+
95
+ ```ruby
96
+ #Returning any kind of identification you want for the model
97
+ def name
98
+ return "You should add method :name in your Messageable model"
99
+ end
100
+ ```
101
+
102
+ ```ruby
103
+ #Returning the email address of the model if an email should be sent for this object (Message or Notification).
104
+ #If no mail has to be sent, return nil.
105
+ def mailboxer_email(object)
106
+ #Check if an email should be sent for that object
107
+ #if true
108
+ return "define_email@on_your.model"
109
+ #if false
110
+ #return nil
111
+ end
112
+ ```
113
+
114
+ These names are explicit enough to avoid colliding with other methods, but as long as you need to change them you can do it by using mailboxer initializer (/config/initializer/mailboxer.rb). Just add or uncomment the following lines:
115
+
116
+ ```ruby
117
+ Mailboxer.setup do |config|
118
+ # ...
119
+ #Configures the methods needed by mailboxer
120
+ config.email_method = :mailboxer_email
121
+ config.name_method = :name
122
+ # ...
123
+ end
124
+ ```
125
+
126
+ You may change whatever you want or need. For example:
127
+
128
+ ```ruby
129
+ config.email_method = :notifications_email
130
+ config.name_method = :display_name
131
+ ```
132
+
133
+ Will use the method `notification_email(object)` instead of `mailboxer_email(object)` and `display_name` for `name`.
134
+
135
+ Using default or custom method names, if your model doesn't implement them, Mailboxer will use dummy methods so as to notify you of missing methods rather than crashing.
136
+
137
+ ## Preparing your models
138
+
139
+ In your model:
140
+
141
+ ```ruby
142
+ class User < ActiveRecord::Base
143
+ acts_as_messageable
144
+ end
145
+ ```
146
+
147
+ You are not limited to the User model. You can use Mailboxer in any other model and use it in serveral different models. If you have ducks and cylons in your application and you want to exchange messages as if they were the same, just add `acts_as_messageable` to each one and you will be able to send duck-duck, duck-cylon, cylon-duck and cylon-cylon messages. Of course, you can extend it for as many classes as you need.
148
+
149
+ Example:
150
+
151
+ ```ruby
152
+ class Duck < ActiveRecord::Base
153
+ acts_as_messageable
154
+ end
155
+ ```
156
+
157
+ ```ruby
158
+ class Cylon < ActiveRecord::Base
159
+ acts_as_messageable
160
+ end
161
+ ```
162
+
163
+ ## Mailboxer API
164
+
165
+ ### Warning for version 0.8.0
166
+ Version 0.8.0 sees `Messageable#read` and `Messageable#unread` renamed to `mark_as_(un)read`, and `Receipt#read` and `Receipt#unread` to `is_(un)read`. This may break existing applications, but `read` is a reserved name for Active Record, and the best pratice in this case is simply avoid using it.
167
+
168
+ ### How can I send a message?
169
+
170
+ ```ruby
171
+ #alfa wants to send a message to beta
172
+ alfa.send_message(beta, "Body", "subject")
173
+ ```
174
+
175
+ ### How can I reply a message?
176
+
177
+ ```ruby
178
+ #alfa wants to reply to all in a conversation
179
+ #using a receipt
180
+ alfa.reply_to_all(receipt, "Reply body")
181
+
182
+ #using a conversation
183
+ alfa.reply_to_conversation(conversation, "Reply body")
184
+ ```
185
+
186
+ ```ruby
187
+ #alfa wants to reply to the sender of a message (and ONLY the sender)
188
+ #using a receipt
189
+ alfa.reply_to_sender(receipt, "Reply body")
190
+ ```
191
+
192
+ ### How can I retrieve my conversations?
193
+
194
+ ```ruby
195
+ #alfa wants to retrieve all his conversations
196
+ alfa.mailbox.conversations
197
+
198
+ #A wants to retrieve his inbox
199
+ alfa.mailbox.inbox
200
+
201
+ #A wants to retrieve his sent conversations
202
+ alfa.mailbox.sentbox
203
+
204
+ #alfa wants to retrieve his trashed conversations
205
+ alfa.mailbox.trash
206
+ ```
207
+
208
+ ### How can I delete a message from trash?
209
+
210
+ ```ruby
211
+ #delete conversations forever for one receipt (still in database)
212
+ receipt.mark_as_deleted
213
+
214
+ #you can mark conversation as deleted for one participant
215
+ conversation.mark_as_deleted participant
216
+
217
+ #Mark the object as deleted for messageable
218
+ #Object can be:
219
+ #* A Receipt
220
+ #* A Conversation
221
+ #* A Notification
222
+ #* A Message
223
+ #* An array with any of them
224
+ alfa.mark_as_deleted conversation
225
+ ```
226
+
227
+ ### How can I paginate conversations?
228
+
229
+ You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses `select('DISTINCT conversations.*')` which was not respected before Kaminari 0.12.4 according to its changelog. Working corretly on Kaminari 0.13.0.
230
+
231
+ ```ruby
232
+ #Paginating all conversations using :page parameter and 9 per page
233
+ conversations = alfa.mailbox.conversations.page(params[:page]).per(9)
234
+
235
+ #Paginating received conversations using :page parameter and 9 per page
236
+ conversations = alfa.mailbox.inbox.page(params[:page]).per(9)
237
+
238
+ #Paginating sent conversations using :page parameter and 9 per page
239
+ conversations = alfa.mailbox.sentbox.page(params[:page]).per(9)
240
+
241
+ #Paginating trashed conversations using :page parameter and 9 per page
242
+ conversations = alfa.mailbox.trash.page(params[:page]).per(9)
243
+ ```
244
+
245
+ ### How can I read the messages of a conversation?
246
+
247
+ As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation a get the message associated with them.
248
+
249
+ This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.
250
+
251
+ ```ruby
252
+ #alfa gets the last conversation (chronologically, the first in the inbox)
253
+ conversation = alfa.mailbox.inbox.first
254
+
255
+ #alfa gets it receipts chronologically ordered.
256
+ receipts = conversation.receipts_for alfa
257
+
258
+ #using the receipts (i.e. in the view)
259
+ receipts.each do |receipt|
260
+ ...
261
+ message = receipt.message
262
+ read = receipt.is_unread? #or message.is_unread?(alfa)
263
+ ...
264
+ end
265
+ ```
266
+
267
+ You can take a look at the full documentation for Mailboxer in [rubydoc.info](http://rubydoc.info/gems/mailboxer/frames).
268
+
269
+ ## Do you want to test Mailboxer?
270
+
271
+ Thanks to [Roman Kushnir (@RKushnir)](https://github.com/RKushnir/) you can test Mailboxer with this [sample app](https://github.com/RKushnir/mailboxer-app).
272
+
273
+ ## I need a GUI!
274
+
275
+ If you need a GUI you should take a look a these links:
276
+
277
+ * The [rails-messaging](https://github.com/frodefi/rails-messaging) project.
278
+ * The wiki page [GUI Example on a real application](https://github.com/ging/mailboxer/wiki/GUI-Example-on-a-real-application).
279
+
280
+ ## Contributors
281
+ * [Roendal](https://github.com/ging/mailboxer/commits/master?author=Roendal) (Eduardo Casanova)
282
+ * [dickeyxxx](https://github.com/ging/mailboxer/commits/master?author=dickeyxxx) (Jeff Dickey)
283
+ * [RKushnir](https://github.com/ging/mailboxer/commits/master?author=RKushnir) (Roman Kushnir)
284
+ * [amaierhofer](https://github.com/ging/mailboxer/commits/master?author=amaierhofer) (Andreas Maierhofer)
285
+ * [tonydewan](https://github.com/ging/mailboxer/commits/master?author=tonydewan) (Tony Dewan)
286
+ * [plentz](https://github.com/ging/mailboxer/commits/master?author=plentz) (Diego Plentz)
287
+ * [laserlemon](https://github.com/ging/mailboxer/commits/master?author=laserlemon) (Steve Richert)
288
+ * [daveworth](https://github.com/ging/mailboxer/commits/master?author=daveworth) (Dave Worth)
289
+ * [rafaelgg](https://github.com/ging/mailboxer/commits/master?author=rafaelgg) (Rafael Garcia)
290
+ * [joshblour](https://github.com/ging/mailboxer/commits/master?author=joshblour) (joshblour)
291
+ * [iamdeuterium](https://github.com/ging/mailboxer/commits/master?author=iamdeuterium) (iamdeuterium)
292
+ * [daveworth](https://github.com/ging/mailboxer/commits/master?author=daveworth) (Dave Worth)
293
+ * [parndt](https://github.com/ging/mailboxer/commits/master?author=parndt) (Philip Arndt)
294
+ * [atd](https://github.com/ging/mailboxer/commits/master?author=atd) (Antonio Tapiador)
295
+ * [mobilutz](https://github.com/ging/mailboxer/commits/master?author=mobilutz) (Lutz)
296
+ * [bennick](https://github.com/ging/mailboxer/commits/master?author=bennick) (Ryan Bennick)
297
+ * [rjst](https://github.com/ging/mailboxer/commits/master?author=rjst) (Ricardo Trindade)
298
+ * [fabianoalmeida](https://github.com/ging/mailboxer/commits/master?author=fabianoalmeida) (Fabiano Almeida)
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require "bundler/gem_tasks"
5
+
6
+ require 'appraisal'
7
+ require 'rspec/core'
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ task :default => :spec
11
+
@@ -0,0 +1,37 @@
1
+ class MessageMailer < ActionMailer::Base
2
+ default :from => Mailboxer.default_from
3
+ #Sends and email for indicating a new message or a reply to a receiver.
4
+ #It calls new_message_email if notifing a new message and reply_message_email
5
+ #when indicating a reply to an already created conversation.
6
+ def send_email(message, receiver)
7
+ if message.conversation.messages.size > 1
8
+ reply_message_email(message,receiver)
9
+ else
10
+ new_message_email(message,receiver)
11
+ end
12
+ end
13
+
14
+ include ActionView::Helpers::SanitizeHelper
15
+
16
+ #Sends an email for indicating a new message for the receiver
17
+ def new_message_email(message,receiver)
18
+ @message = message
19
+ @receiver = receiver
20
+ subject = message.subject.to_s
21
+ subject = strip_tags(subject) unless subject.html_safe?
22
+ mail :to => receiver.send(Mailboxer.email_method,message),
23
+ :subject => t('mailboxer.message_mailer.subject_new', :subject => subject),
24
+ :template_name => 'new_message_email'
25
+ end
26
+
27
+ #Sends and email for indicating a reply in an already created conversation
28
+ def reply_message_email(message,receiver)
29
+ @message = message
30
+ @receiver = receiver
31
+ subject = message.subject.to_s
32
+ subject = strip_tags(subject) unless subject.html_safe?
33
+ mail :to => receiver.send(Mailboxer.email_method,message),
34
+ :subject => t('mailboxer.message_mailer.subject_reply', :subject => subject),
35
+ :template_name => 'reply_message_email'
36
+ end
37
+ end
@@ -0,0 +1,179 @@
1
+ class Conversation < ActiveRecord::Base
2
+ attr_accessible :subject if Mailboxer.protected_attributes?
3
+
4
+ has_many :messages, :dependent => :destroy
5
+ has_many :receipts, :through => :messages
6
+
7
+ #validates_presence_of :subject
8
+
9
+ before_validation :clean
10
+
11
+ scope :participant, lambda {|participant|
12
+ select('DISTINCT conversations.*').
13
+ #where('notifications.type'=> Message.name).
14
+ order("conversations.updated_at DESC").
15
+ joins(:receipts).merge(Receipt.recipient(participant))
16
+ }
17
+ scope :inbox, lambda {|participant|
18
+ participant(participant).merge(Receipt.inbox.not_trash.not_deleted)
19
+ }
20
+ scope :sentbox, lambda {|participant|
21
+ participant(participant).merge(Receipt.sentbox.not_trash.not_deleted)
22
+ }
23
+ scope :trash, lambda {|participant|
24
+ participant(participant).merge(Receipt.trash)
25
+ }
26
+ scope :unread, lambda {|participant|
27
+ participant(participant).merge(Receipt.is_unread)
28
+ }
29
+ scope :not_trash, lambda {|participant|
30
+ participant(participant).merge(Receipt.not_trash)
31
+ }
32
+
33
+ #Mark the conversation as read for one of the participants
34
+ def mark_as_read(participant)
35
+ return if participant.nil?
36
+ self.receipts_for(participant).mark_as_read
37
+ end
38
+
39
+ #Mark the conversation as unread for one of the participants
40
+ def mark_as_unread(participant)
41
+ return if participant.nil?
42
+ self.receipts_for(participant).mark_as_unread
43
+ end
44
+
45
+ #Move the conversation to the trash for one of the participants
46
+ def move_to_trash(participant)
47
+ return if participant.nil?
48
+ self.receipts_for(participant).move_to_trash
49
+ end
50
+
51
+ #Takes the conversation out of the trash for one of the participants
52
+ def untrash(participant)
53
+ return if participant.nil?
54
+ self.receipts_for(participant).untrash
55
+ end
56
+
57
+ #Mark the conversation as deleted for one of the participants
58
+ def mark_as_deleted(participant)
59
+ return if participant.nil?
60
+ deleted_receipts = self.receipts_for(participant).mark_as_deleted
61
+ if is_orphaned?
62
+ self.destroy
63
+ else
64
+ deleted_receipts
65
+ end
66
+ end
67
+
68
+ #Returns an array of participants
69
+ def recipients
70
+ if self.last_message
71
+ recps = self.last_message.recipients
72
+ recps = recps.is_a?(Array) ? recps : [recps]
73
+ recps
74
+ else
75
+ []
76
+ end
77
+ end
78
+
79
+ #Returns an array of participants
80
+ def participants
81
+ recipients
82
+ end
83
+
84
+ #Originator of the conversation.
85
+ def originator
86
+ @originator ||= self.original_message.sender
87
+ end
88
+
89
+ #First message of the conversation.
90
+ def original_message
91
+ @original_message ||= self.messages.order('created_at').first
92
+ end
93
+
94
+ #Sender of the last message.
95
+ def last_sender
96
+ @last_sender ||= self.last_message.sender
97
+ end
98
+
99
+ #Last message in the conversation.
100
+ def last_message
101
+ @last_message ||= self.messages.order('created_at DESC').first
102
+ end
103
+
104
+ #Returns the receipts of the conversation for one participants
105
+ def receipts_for(participant)
106
+ Receipt.conversation(self).recipient(participant)
107
+ end
108
+
109
+ #Returns the number of messages of the conversation
110
+ def count_messages
111
+ Message.conversation(self).count
112
+ end
113
+
114
+ #Returns true if the messageable is a participant of the conversation
115
+ def is_participant?(participant)
116
+ return false if participant.nil?
117
+ self.receipts_for(participant).count != 0
118
+ end
119
+
120
+
121
+ #Adds a new participant to the conversation
122
+ def add_participant(participant)
123
+ messages = self.messages
124
+ messages.each do |message|
125
+ receipt = Receipt.new
126
+ receipt.message = message
127
+ receipt.is_read = false
128
+ receipt.receiver = participant
129
+ receipt.mailbox_type = 'inbox'
130
+ receipt.updated_at = message.updated_at
131
+ receipt.created_at = message.created_at
132
+ receipt.save
133
+ end
134
+ end
135
+
136
+ #Returns true if the participant has at least one trashed message of the conversation
137
+ def is_trashed?(participant)
138
+ return false if participant.nil?
139
+ self.receipts_for(participant).trash.count != 0
140
+ end
141
+
142
+ #Returns true if the participant has deleted the conversation
143
+ def is_deleted?(participant)
144
+ return false if participant.nil?
145
+ return self.receipts_for(participant).deleted.count == self.receipts_for(participant).count
146
+ end
147
+
148
+ #Returns true if both participants have deleted the conversation
149
+ def is_orphaned?
150
+ participants.reduce(true) do |is_orphaned, participant|
151
+ is_orphaned && is_deleted?(participant)
152
+ end
153
+ end
154
+
155
+ #Returns true if the participant has trashed all the messages of the conversation
156
+ def is_completely_trashed?(participant)
157
+ return false if participant.nil?
158
+ self.receipts_for(participant).trash.count == self.receipts_for(participant).count
159
+ end
160
+
161
+ def is_read?(participant)
162
+ !self.is_unread?(participant)
163
+ end
164
+
165
+ #Returns true if the participant has at least one unread message of the conversation
166
+ def is_unread?(participant)
167
+ return false if participant.nil?
168
+ self.receipts_for(participant).not_trash.is_unread.count != 0
169
+ end
170
+
171
+ protected
172
+
173
+ include ActionView::Helpers::SanitizeHelper
174
+
175
+ #Use the default sanitize to clean the conversation subject
176
+ def clean
177
+ self.subject = sanitize self.subject
178
+ end
179
+ end