profile_controller.rb
18.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
class ProfileController < PublicController
needs_profile
before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add]
before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse, :send_mail]
before_filter :login_required, :only => [:add, :join, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail, :follow, :unfollow]
before_filter :allow_followers?, :only => [:follow, :unfollow]
before_filter :accept_only_post, :only => [:follow, :unfollow]
helper TagsHelper
helper ActionTrackerHelper
helper CustomFieldsHelper
protect 'send_mail_to_members', :profile, :only => [:send_mail]
def index
@network_activities = !@profile.is_a?(Person) ? @profile.tracked_notifications.visible.paginate(:per_page => 15, :page => params[:page]) : []
if logged_in? && current_person.follows?(@profile)
@network_activities = @profile.tracked_notifications.visible.paginate(:per_page => 15, :page => params[:page]) if @network_activities.empty?
@activities = @profile.activities.paginate(:per_page => 15, :page => params[:page])
end
# TODO Find a way to filter these through sql
@network_activities = filter_private_scraps(@network_activities)
@activities = filter_private_scraps(@activities)
@tags = profile.article_tags
allow_access_to_page
end
def tags
@tags_cache_key = "tags_profile_#{profile.id.to_s}"
if is_cache_expired?(@tags_cache_key)
@tags = profile.article_tags
end
end
def content_tagged
@tag = params[:id]
@tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_#{profile.id.to_s}_page_#{params[:npage]}"
if is_cache_expired?(@tag_cache_key)
@tagged = profile.tagged_with(@tag).paginate(:per_page => 20, :page => params[:npage])
end
end
def tag_feed
@tag = params[:id]
tagged = profile.articles.paginate(:per_page => 20, :page => 1).order('published_at DESC').joins(:tags).where('tags.name LIKE ?', @tag)
feed_writer = FeedWriter.new
data = feed_writer.write(
tagged,
:title => _("%s's contents tagged with \"%s\"").html_safe % [profile.name, @tag],
:description => _("%s's contents tagged with \"%s\"").html_safe % [profile.name, @tag],
:link => url_for(profile.url)
)
render :text => data, :content_type => "text/xml"
end
def communities
if is_cache_expired?(profile.communities_cache_key(params))
@communities = profile.communities.includes(relations_to_include).paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.communities.count)
end
end
def enterprises
@enterprises = profile.enterprises.includes(relations_to_include)
end
def friends
if is_cache_expired?(profile.friends_cache_key(params))
@friends = profile.friends.includes(relations_to_include).paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.friends.count)
end
end
def following
@followed_people = profile.followed_profiles.paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.followed_profiles.count)
puts "FOLLOWED_PEOPLE: #{@followed_people.map(&:name)}"
return @followed_people
end
def followed
@followed_by = profile.followers.paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.followers.count)
end
def members
if is_cache_expired?(profile.members_cache_key(params))
sort = (params[:sort] == 'desc') ? params[:sort] : 'asc'
@profile_admins = profile.admins.includes(relations_to_include).order("name #{sort}").paginate(:per_page => members_per_page, :page => params[:npage])
@profile_members = profile.members.includes(relations_to_include).order("name #{sort}").paginate(:per_page => members_per_page, :page => params[:npage])
@profile_members_url = url_for(:controller => 'profile', :action => 'members')
end
end
def fans
@fans = profile.fans.includes(relations_to_include)
end
def favorite_enterprises
@favorite_enterprises = profile.favorite_enterprises.includes(relations_to_include)
end
def sitemap
@articles = profile.top_level_articles.includes([:profile, :parent])
end
def join_modal
profile.add_member(user)
session[:notice] = _('%s administrator still needs to accept you as member.').html_safe % profile.name
redirect_to :action => :index
end
def join
if !user.memberships.include?(profile)
return if profile.community? && show_confirmation_modal?(profile)
profile.add_member(user)
if !profile.members.include?(user)
render :text => {:message => _('%s administrator still needs to accept you as member.').html_safe % profile.name}.to_json
else
render :text => {:message => _('You just became a member of %s.').html_safe % profile.name}.to_json
end
else
render :text => {:message => _('You are already a member of %s.').html_safe % profile.name}.to_json
end
end
def join_not_logged
session[:join] = profile.identifier
if user
redirect_to :controller => 'profile', :action => 'join'
else
redirect_to :controller => '/account', :action => 'login'
end
end
def leave
if current_person.memberships.include?(profile)
if current_person.is_last_admin?(profile)
render :text => {:redirect_to => url_for({:controller => 'profile_members', :action => 'last_admin', :person => current_person.id})}.to_json
else
render :text => current_person.leave(profile, params[:reload])
end
else
render :text => {:message => _('You are not a member of %s.').html_safe % profile.name}.to_json
end
end
def check_membership
unless logged_in?
render :text => ''
return
end
if user.memberships.include?(profile)
render :text => 'true'
else
render :text => 'false'
end
end
def add
# FIXME this shouldn't be in Person model?
if !user.memberships.include?(profile)
AddFriend.create!(:person => user, :friend => profile)
render :text => _('%s still needs to accept being your friend.').html_safe % profile.name
else
render :text => _('You are already a friend of %s.').html_safe % profile.name
end
end
def follow
if profile.followed_by?(current_person)
render :text => _("You are already following %s.") % profile.name, :status => 400
else
params[:circles] ||= []
selected_circles = params[:circles].map{ |circle_name, circle_id| Circle.find_by(:id => circle_id) }.select{ |c| c.present? }
if selected_circles.present?
current_person.follow(profile, selected_circles)
render :text => _("You are now following %s") % profile.name, :status => 200
else
render :text => _("Select at least one circle to follow %s.") % profile.name, :status => 400
end
end
end
def find_profile_circles
circles = Circle.where(:owner => current_person, :profile_type => profile.class.name)
render :partial => 'blocks/profile_info_actions/circles', :locals => { :circles => circles, :profile_types => Circle.profile_types.to_a }
end
def unfollow
follower = params[:follower_id].present? ? Person.find_by(id: params[:follower_id]) : current_person
if follower && follower.follows?(profile)
follower.unfollow(profile)
end
redirect_url = params["redirect_to"] ? params["redirect_to"] : profile.url
redirect_to redirect_url
end
def check_friendship
unless logged_in?
render :text => ''
return
end
if user == profile || user.already_request_friendship?(profile) || user.is_a_friend?(profile)
render :text => 'true'
else
render :text => 'false'
end
end
def follow_article
article = profile.environment.articles.find params[:article_id]
article.person_followers << user
redirect_to article.url
end
def unfollow_article
article = profile.environment.articles.find params[:article_id]
article.person_followers.delete(user)
redirect_to article.url
end
def unblock
if current_person.is_admin?(profile.environment)
profile.unblock
session[:notice] = _("You have unblocked %s successfully. ").html_safe % profile.name
redirect_to :controller => 'profile', :action => 'index'
else
message = _('You are not allowed to unblock enterprises in this environment.')
render_access_denied(message)
end
end
def leave_scrap
sender = params[:sender_id].nil? ? current_person : Person.find(params[:sender_id])
receiver = params[:receiver_id].nil? ? @profile : Person.find(params[:receiver_id])
@scrap = Scrap.new(params[:scrap])
@scrap.sender= sender
@scrap.receiver= receiver
@scrap.marked_people = treat_followed_entries(params[:filter_followed])
@tab_action = params[:tab_action]
@message = @scrap.save ? _("Message successfully sent.") : _("You can't leave an empty message.")
activities = @profile.activities.paginate(:per_page => 15, :page => params[:page]) if params[:not_load_scraps].nil?
render :partial => 'profile_activities_list', :locals => {:activities => activities}
end
def leave_comment_on_activity
@comment = Comment.new(params[:comment])
@comment.author = user
@activity = ActionTracker::Record.find(params[:source_id])
@comment.source_type, @comment.source_id = (@activity.target_type == 'Article' ? ['Article', @activity.target_id] : [@activity.class.to_s, @activity.id])
@tab_action = params[:tab_action]
@message = @comment.save ? _("Comment successfully added.") : _("You can't leave an empty comment.")
if @tab_action == 'wall'
activities = @profile.activities.paginate(:per_page => 15, :page => params[:page]) if params[:not_load_scraps].nil?
render :partial => 'profile_activities_list', :locals => {:activities => activities}
else
network_activities = @profile.tracked_notifications.visible.paginate(:per_page => 15, :page => params[:page])
render :partial => 'profile_network_activities', :locals => {:network_activities => network_activities}
end
end
def search_followed
circles = find_by_contents(:circles, user, user.owned_circles.where(:profile_type => 'Person'), params[:q])[:results]
local_followed = find_by_contents(:followed, user, user.local_followed_profiles, params[:q])[:results]
external_followed = find_by_contents(:followed, user, user.external_followed_profiles, params[:q])[:results]
result = circles + local_followed + external_followed
render :text => prepare_to_token_input_by_class(result).to_json
end
def view_more_activities
@activities = @profile.activities.paginate(:per_page => 10, :page => params[:page])
render :partial => 'profile_activities_list', :locals => {:activities => @activities}
end
def view_more_network_activities
@activities = @profile.tracked_notifications.paginate(:per_page => 10, :page => params[:page])
render :partial => 'profile_network_activities', :locals => {:network_activities => @activities}
end
def more_comments
profile_filter = @profile.person? ? {:user_id => @profile} : {:target_id => @profile}
activity = ActionTracker::Record.where(:id => params[:activity])
activity = activity.where(profile_filter) if !logged_in? || !current_person.follows?(@profile)
activity = activity.first
comments_count = activity.comments.count
comment_page = (params[:comment_page] || 1).to_i
comments_per_page = 5
no_more_pages = comments_count <= comment_page * comments_per_page
render :update do |page|
page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity],
:partial => 'comment', :collection => activity.comments.flatten.paginate(:per_page => comments_per_page, :page => comment_page)
if no_more_pages
page.remove 'profile-wall-activities-comments-more-'+params[:activity]
else
page.replace_html 'profile-wall-activities-comments-more-'+params[:activity],
:partial => 'more_comments', :locals => {:activity => activity, :comment_page => comment_page}
end
end
end
def more_replies
activity = Scrap.where(:id => params[:activity], :receiver_id => @profile, :scrap_id => nil).first
comments_count = activity.replies.count
comment_page = (params[:comment_page] || 1).to_i
comments_per_page = 5
no_more_pages = comments_count <= comment_page * comments_per_page
render :update do |page|
page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity],
:partial => 'profile_scrap', :collection => activity.replies.paginate(:per_page => comments_per_page, :page => comment_page), :as => :scrap
if no_more_pages
page.remove 'profile-wall-activities-comments-more-'+params[:activity]
else
page.replace_html 'profile-wall-activities-comments-more-'+params[:activity],
:partial => 'more_replies', :locals => {:activity => activity, :comment_page => comment_page}
end
end
end
def remove_scrap
begin
scrap = current_person.scraps(params[:scrap_id])
scrap.destroy
finish_successful_removal 'Scrap successfully removed.'
rescue
finish_unsuccessful_removal 'You could not remove this scrap.'
end
end
def remove_activity
begin
raise if !can_edit_profile
activity = ActionTracker::Record.find(params[:activity_id])
if params[:only_hide]
activity.update_attribute(:visible, false)
else
activity.destroy
end
finish_successful_removal 'Activity successfully removed.'
rescue
finish_unsuccessful_removal 'You could not remove this activity.'
end
end
def remove_notification
begin
raise if !can_edit_profile
notification = ActionTrackerNotification.where(profile_id: profile.id, action_tracker_id: params[:activity_id]).first
notification.destroy
render :text => _('Notification successfully removed.')
rescue
render :text => _('You could not remove this notification.')
end
end
def finish_successful_removal(msg)
if request.xhr?
render :text => {'ok' => true}.to_json, :content_type => 'application/json'
else
session[:notice] = _(msg)
redirect_to :action => :index
end
end
def finish_unsuccessful_removal(msg)
session[:notice] = _(msg)
if request.xhr?
render :text => {'redirect' => url_for(:action => :index)}.to_json, :content_type => 'application/json'
else
redirect_to :action => :index
end
end
def report_abuse
@abuse_report = AbuseReport.new
render :layout => false
end
def register_report
unless user.is_admin? || verify_recaptcha
render :text => {
:ok => false,
:error => {
:code => 1,
:message => _('You could not answer the captcha.')
}
}.to_json
else
begin
abuse_report = AbuseReport.new(params[:abuse_report])
if !params[:content_type].blank?
article = params[:content_type].constantize.find(params[:content_id])
abuse_report.content = article_reported_version(article)
end
user.register_report(abuse_report, profile)
if !params[:content_type].blank?
abuse_report = AbuseReport.find_by(reporter_id: user.id, abuse_complaint_id: profile.opened_abuse_complaint.id)
Delayed::Job.enqueue DownloadReportedImagesJob.new(abuse_report, article)
end
render :text => {
:ok => true,
:message => _('Your abuse report was registered. The administrators are reviewing your report.'),
}.to_json
rescue Exception => exception
logger.error(exception.to_s)
render :text => {
:ok => false,
:error => {
:code => 2,
:message => _('Your report couldn\'t be saved due to some problem. Please contact the administrator.')
}
}.to_json
end
end
end
def remove_comment
#FIXME Check whether these permissions are enough
@comment = Comment.find(params[:comment_id])
if (user == @comment.author || user == profile || user.has_permission?(:moderate_comments, profile))
@comment.destroy
finish_successful_removal 'Comment successfully removed.'
else
finish_unsuccessful_removal 'You could not remove this comment.'
end
end
def send_mail
@mailing = profile.mailings.build(params[:mailing])
@mailing.data = session[:members_filtered] ? {:members_filtered => session[:members_filtered]} : {}
@email_templates = profile.email_templates.where template_type: :organization_members
if request.post?
@mailing.locale = locale
@mailing.person = user
if @mailing.save
session[:notice] = _('The e-mails are being sent')
redirect_to_previous_location
else
session[:notice] = _('Could not create the e-mail')
end
end
end
def icon
size = params[:size] || :portrait
image, mime = profile_icon(profile, size.to_sym, true)
unless image.match(/^\/\/www\.gravatar\.com/).nil?
redirect_to 'https:' + image
else
@file = File.join(Rails.root, 'public', image)
send_file @file, type: mime, disposition: 'inline'
end
end
protected
def check_access_to_profile
unless profile.display_info_to?(user)
redirect_to :action => 'index'
end
end
def store_location
if session[:previous_location].nil?
session[:previous_location] = request.referer
end
end
def redirect_to_previous_location
back = session[:previous_location]
if back
session[:previous_location] = nil
redirect_to back
else
redirect_to profile.url
end
end
def per_page
Noosfero::Constants::PROFILE_PER_PAGE
end
def members_per_page
20
end
def can_edit_profile
@can_edit_profile ||= user && user.has_permission?('edit_profile', profile)
end
helper_method :can_edit_profile
def relations_to_include
[:image, :domains, :preferred_domain, :environment]
end
def allow_followers?
render_not_found unless profile.allow_followers?
end
def treat_followed_entries(entries)
return [] if entries.blank? || profile != user
followed = []
entries.split(',').map do |entry|
klass, identifier = entry.split('_')
case klass
when 'Person'
followed << Person.find(identifier)
when 'Circle'
circle = Circle.find(identifier)
followed += circle.profiles
end
end
followed.uniq
end
def filter_private_scraps(activities)
activities = Array(activities)
activities.delete_if do |item|
if item.kind_of?(ProfileActivity)
target = item.activity
owner = profile
else
target = item.target
owner = item.user
end
!environment.admins.include?(user) &&
owner != user &&
target.is_a?(Scrap) &&
target.marked_people.present? &&
!target.marked_people.include?(user)
end
activities
end
end