Commit 1182476c928ed1bd9d07130ae292298eb8236526
Exists in
master
and in
27 other branches
Merge branch 'rails235' into rails3
* rails235: (168 commits) L10n: support for custom locales enhancements: visualization of suggested usernames Allowing translation for url checking string Removed unnecessary lines on test Removed unit tests from functionals file Fixed html and test syntax Removed needless condition Fixed suggestions of usernames Test files should ends with "_test.rb" Added pagination on events_by_day on profile agenda Fix missing variable in funcional test Fix unit tests Change routes from embed controller Remove unused code Autocomplete fields on page load Blocks can returns a block of code to be evaluated Avoid randomness on tests comment-group-plugin: avoid randomness on tests community-track-plugin: fix tests by creating a profile with default boxes anti-spam-plugin-wrapper: ensure to load concrete wrappers ... Conflicts: app/helpers/application_helper.rb app/models/comment.rb app/models/contact.rb app/models/event.rb app/models/mailing.rb app/models/organization.rb app/models/organization_mailing.rb app/models/pending_task_notifier.rb app/models/person.rb app/models/profile.rb app/models/scrap.rb app/models/task_mailer.rb app/models/user.rb app/views/account/_signup_form.rhtml app/views/blocks/profile_image.rhtml app/views/blocks/profile_info.rhtml app/views/box_organizer/_link_list_block.rhtml app/views/box_organizer/edit.rhtml app/views/features/_manage_community_fields.rhtml app/views/features/_manage_enterprise_fields.rhtml app/views/features/_manage_person_fields.rhtml app/views/features/index.rhtml app/views/layouts/application-ng.rhtml app/views/users/_users_list.rhtml db/schema.rb features/forum.feature lib/feed_handler.rb lib/noosfero/plugin.rb plugins/community_track/test/functional/community_track_plugin_content_viewer_controller_test.rb plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb plugins/spaminator/lib/spaminator_plugin/mailer.rb test/functional/content_viewer_controller_test.rb test/functional/profile_controller_test.rb test/functional/profile_design_controller_test.rb test/functional/search_controller_test.rb test/unit/contact_sender_test.rb test/unit/content_viewer_helper_test.rb test/unit/environment_mailing_test.rb test/unit/mailing_test.rb test/unit/organization_mailing_test.rb test/unit/person_test.rb test/unit/profile_test.rb test/unit/uploaded_file_test.rb vendor/plugins/action_tracker/lib/action_tracker_model.rb
Showing
269 changed files
with
5981 additions
and
843 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 269 files displayed.
AUTHORS
... | ... | @@ -7,6 +7,7 @@ Developers |
7 | 7 | ========== |
8 | 8 | |
9 | 9 | Alan Freihof Tygel <alantygel@gmail.com> |
10 | +alcampelo <alcampelo@alcampelo.(none)> | |
10 | 11 | Alessandro Palmeira <alessandro.palmeira@gmail.com> |
11 | 12 | Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> |
12 | 13 | Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> |
... | ... | @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> |
38 | 39 | Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> |
39 | 40 | Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> |
40 | 41 | Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> |
42 | +Ana Losnak <analosnak@gmail.com> | |
41 | 43 | Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> |
42 | 44 | Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> |
43 | 45 | Antonio Terceiro <terceiro@colivre.coop.br> |
... | ... | @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> |
85 | 87 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
86 | 88 | Daniel Bucher <daniel.bucher88@gmail.com> |
87 | 89 | Daniel Cunha <daniel@colivre.coop.br> |
90 | +David Carlos <ddavidcarlos1392@gmail.com> | |
88 | 91 | diegoamc <diegoamc90@gmail.com> |
89 | 92 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> |
90 | 93 | Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> |
... | ... | @@ -114,12 +117,16 @@ Diego Martinez <diegoamc90@gmail.com> |
114 | 117 | Diego Martinez <diego@diego-K55A.(none)> |
115 | 118 | Diego + Renan <renanteruoc@gmail.com> |
116 | 119 | Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> |
120 | +Fabio Teixeira <fabio1079@gmail.com> | |
117 | 121 | Fernanda Lopes <nanda.listas+psl@gmail.com> |
118 | 122 | Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> |
119 | 123 | Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> |
120 | 124 | Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> |
121 | 125 | Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> |
126 | +Gabriela Navarro <navarro1703@gmail.com> | |
122 | 127 | Grazieno Pellegrino <grazieno@gmail.com> |
128 | +Gust <darksshades@hotmail.com> | |
129 | +Hugo Melo <hugo@riseup.net> | |
123 | 130 | Isaac Canan <isaac@intelletto.com.br> |
124 | 131 | Italo Valcy <italo@dcc.ufba.br> |
125 | 132 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> |
... | ... | @@ -202,6 +209,7 @@ Renan Teruo + Diego Araujo <renanteruoc@gmail.com> |
202 | 209 | Renan Teruo + Diego Araújo <renanteruoc@gmail.com> |
203 | 210 | Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> |
204 | 211 | Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> |
212 | +Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org> | |
205 | 213 | Rodrigo Souto <diguliu@gmail.com> |
206 | 214 | Rodrigo Souto <rodrigo@colivre.coop.br> |
207 | 215 | Ronny Kursawe <kursawe.ronny@googlemail.com> | ... | ... |
app/controllers/admin/environment_design_controller.rb
... | ... | @@ -3,6 +3,8 @@ class EnvironmentDesignController < BoxOrganizerController |
3 | 3 | protect 'edit_environment_design', :environment |
4 | 4 | |
5 | 5 | def available_blocks |
6 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
7 | + # the Noosfero core soon, see ActionItem3045 | |
6 | 8 | @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] |
7 | 9 | @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) |
8 | 10 | end | ... | ... |
app/controllers/admin/users_controller.rb
... | ... | @@ -45,6 +45,20 @@ class UsersController < AdminController |
45 | 45 | redirect_to :action => :index, :q => params[:q], :filter => params[:filter] |
46 | 46 | end |
47 | 47 | |
48 | + | |
49 | + def destroy_user | |
50 | + if request.post? | |
51 | + person = environment.people.find_by_id(params[:id]) | |
52 | + if person && person.destroy | |
53 | + session[:notice] = _('The profile was deleted.') | |
54 | + else | |
55 | + session[:notice] = _('Could not remove profile') | |
56 | + end | |
57 | + end | |
58 | + redirect_to :action => :index, :q => params[:q], :filter => params[:filter] | |
59 | + end | |
60 | + | |
61 | + | |
48 | 62 | def download |
49 | 63 | respond_to do |format| |
50 | 64 | format.html | ... | ... |
app/controllers/box_organizer_controller.rb
... | ... | @@ -80,6 +80,22 @@ class BoxOrganizerController < ApplicationController |
80 | 80 | render :action => 'edit', :layout => false |
81 | 81 | end |
82 | 82 | |
83 | + def search_autocomplete | |
84 | + if request.xhr? and params[:query] | |
85 | + search = params[:query] | |
86 | + path_list = if boxes_holder.is_a?(Environment) && boxes_holder.enabled?('use_portal_community') && boxes_holder.portal_community | |
87 | + boxes_holder.portal_community.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{portal}/"+content.path } | |
88 | + elsif boxes_holder.is_a?(Profile) | |
89 | + boxes_holder.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{profile}/"+content.path } | |
90 | + else | |
91 | + [] | |
92 | + end | |
93 | + render :json => path_list.to_json | |
94 | + else | |
95 | + redirect_to "/" | |
96 | + end | |
97 | + end | |
98 | + | |
83 | 99 | def save |
84 | 100 | @block = boxes_holder.blocks.find(params[:id]) |
85 | 101 | @block.update_attributes(params[:block]) |
... | ... | @@ -99,6 +115,12 @@ class BoxOrganizerController < ApplicationController |
99 | 115 | end |
100 | 116 | end |
101 | 117 | |
118 | + def clone_block | |
119 | + block = Block.find(params[:id]) | |
120 | + block.duplicate | |
121 | + redirect_to :action => 'index' | |
122 | + end | |
123 | + | |
102 | 124 | protected :boxes_editor? |
103 | 125 | |
104 | 126 | end | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +class EmbedController < ApplicationController | |
2 | + layout 'embed' | |
3 | + | |
4 | + def block | |
5 | + @block = Block.find(params[:id]) | |
6 | + if !@block.embedable? || !@block.visible? | |
7 | + render 'unavailable.rhtml', :status => 403 | |
8 | + end | |
9 | + rescue ActiveRecord::RecordNotFound | |
10 | + render 'not_found.rhtml', :status => 404 | |
11 | + end | |
12 | + | |
13 | +end | ... | ... |
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -24,10 +24,16 @@ class CmsController < MyProfileController |
24 | 24 | (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) |
25 | 25 | end |
26 | 26 | |
27 | - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files] do |c, user, profile| | |
27 | + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files, :new] do |c, user, profile| | |
28 | 28 | user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) |
29 | 29 | end |
30 | 30 | |
31 | + protect_if :only => :new do |c, user, profile| | |
32 | + article = profile.articles.find_by_id(c.params[:parent_id]) | |
33 | + (!article.nil? && (article.allow_create?(user) || article.parent.allow_create?(user))) || | |
34 | + (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) | |
35 | + end | |
36 | + | |
31 | 37 | protect_if :only => [:destroy, :publish] do |c, user, profile| |
32 | 38 | profile.articles.find(c.params[:id]).allow_post_content?(user) |
33 | 39 | end |
... | ... | @@ -220,11 +226,10 @@ class CmsController < MyProfileController |
220 | 226 | |
221 | 227 | def update_categories |
222 | 228 | @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new |
229 | + @categories = @toplevel_categories = environment.top_level_categories | |
223 | 230 | if params[:category_id] |
224 | 231 | @current_category = Category.find(params[:category_id]) |
225 | 232 | @categories = @current_category.children |
226 | - else | |
227 | - @categories = environment.top_level_categories.select{|i| !i.children.empty?} | |
228 | 233 | end |
229 | 234 | render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false |
230 | 235 | end | ... | ... |
app/controllers/my_profile/maps_controller.rb
... | ... | @@ -31,23 +31,11 @@ class MapsController < MyProfileController |
31 | 31 | end |
32 | 32 | |
33 | 33 | def search_city |
34 | - | |
35 | - term = params[:term]; | |
36 | - | |
37 | - regions = NationalRegion.search_city(term + "%", true).map {|r|{ :label => r.city , :category => r.state}} | |
38 | - | |
39 | - render :json => regions | |
40 | - | |
34 | + render :json => MapsHelper.search_city(params[:term]) | |
41 | 35 | end |
42 | 36 | |
43 | 37 | def search_state |
44 | - | |
45 | - term = params[:term]; | |
46 | - | |
47 | - regions = NationalRegion.search_state(term + "%", true).map {|r|{ :label => r.state}} | |
48 | - | |
49 | - render :json => regions | |
50 | - | |
38 | + render :json => MapsHelper.search_state(params[:term]) | |
51 | 39 | end |
52 | 40 | |
53 | 41 | end | ... | ... |
app/controllers/my_profile/profile_design_controller.rb
app/controllers/my_profile/profile_editor_controller.rb
... | ... | @@ -55,11 +55,10 @@ class ProfileEditorController < MyProfileController |
55 | 55 | |
56 | 56 | def update_categories |
57 | 57 | @object = profile |
58 | + @categories = @toplevel_categories = environment.top_level_categories | |
58 | 59 | if params[:category_id] |
59 | 60 | @current_category = Category.find(params[:category_id]) |
60 | 61 | @categories = @current_category.children |
61 | - else | |
62 | - @categories = environment.top_level_categories.select{|i| !i.children.empty?} | |
63 | 62 | end |
64 | 63 | render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false |
65 | 64 | end | ... | ... |
app/controllers/public/account_controller.rb
... | ... | @@ -69,6 +69,8 @@ class AccountController < ApplicationController |
69 | 69 | session[:notice] = _("This environment doesn't allow user registration.") |
70 | 70 | end |
71 | 71 | |
72 | + store_location(request.referer) unless params[:return_to] or session[:return_to] | |
73 | + | |
72 | 74 | @block_bot = !!session[:may_be_a_bot] |
73 | 75 | @invitation_code = params[:invitation_code] |
74 | 76 | begin |
... | ... | @@ -77,6 +79,7 @@ class AccountController < ApplicationController |
77 | 79 | @user.environment = environment |
78 | 80 | @terms_of_use = environment.terms_of_use |
79 | 81 | @user.person_data = params[:profile_data] |
82 | + @user.return_to = session[:return_to] | |
80 | 83 | @person = Person.new(params[:profile_data]) |
81 | 84 | @person.environment = @user.environment |
82 | 85 | if request.post? |
... | ... | @@ -98,7 +101,7 @@ class AccountController < ApplicationController |
98 | 101 | end |
99 | 102 | if @user.activated? |
100 | 103 | self.current_user = @user |
101 | - redirect_to '/' | |
104 | + go_to_signup_initial_page | |
102 | 105 | else |
103 | 106 | @register_pending = true |
104 | 107 | end |
... | ... | @@ -247,15 +250,19 @@ class AccountController < ApplicationController |
247 | 250 | end |
248 | 251 | end |
249 | 252 | |
250 | - def check_url | |
253 | + def check_valid_name | |
251 | 254 | @identifier = params[:identifier] |
252 | 255 | valid = Person.is_available?(@identifier, environment) |
253 | 256 | if valid |
254 | 257 | @status = _('This login name is available') |
255 | 258 | @status_class = 'validated' |
256 | - else | |
259 | + elsif !@identifier.empty? | |
260 | + @suggested_usernames = suggestion_based_on_username(@identifier) | |
257 | 261 | @status = _('This login name is unavailable') |
258 | 262 | @status_class = 'invalid' |
263 | + else | |
264 | + @status_class = 'invalid' | |
265 | + @status = _('This field can\'t be blank') | |
259 | 266 | end |
260 | 267 | render :partial => 'identifier_status' |
261 | 268 | end |
... | ... | @@ -288,6 +295,23 @@ class AccountController < ApplicationController |
288 | 295 | render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" |
289 | 296 | end |
290 | 297 | |
298 | + def search_cities | |
299 | + if request.xhr? and params[:state_name] and params[:city_name] | |
300 | + render :json => MapsHelper.search_city(params[:city_name], params[:state_name]) | |
301 | + else | |
302 | + render :json => [].to_json | |
303 | + end | |
304 | + end | |
305 | + | |
306 | + def search_state | |
307 | + if request.xhr? and params[:state_name] | |
308 | + render :json => MapsHelper.search_state(params[:state_name]) | |
309 | + else | |
310 | + render :json => [].to_json | |
311 | + end | |
312 | + end | |
313 | + | |
314 | + | |
291 | 315 | protected |
292 | 316 | |
293 | 317 | def redirect? |
... | ... | @@ -368,32 +392,29 @@ class AccountController < ApplicationController |
368 | 392 | end |
369 | 393 | |
370 | 394 | def go_to_initial_page |
395 | + if params[:redirection] | |
396 | + session[:return_to] = @user.return_to | |
397 | + @user.return_to = nil | |
398 | + @user.save | |
399 | + end | |
400 | + | |
371 | 401 | if params[:return_to] |
372 | 402 | redirect_to params[:return_to] |
373 | 403 | elsif environment.enabled?('allow_change_of_redirection_after_login') |
374 | - case user.preferred_login_redirection | |
375 | - when 'keep_on_same_page' | |
376 | - redirect_back_or_default(user.admin_url) | |
377 | - when 'site_homepage' | |
378 | - redirect_to :controller => :home | |
379 | - when 'user_profile_page' | |
380 | - redirect_to user.public_profile_url | |
381 | - when 'user_homepage' | |
382 | - redirect_to user.url | |
383 | - when 'user_control_panel' | |
384 | - redirect_to user.admin_url | |
385 | - else | |
386 | - redirect_back_or_default(user.admin_url) | |
387 | - end | |
404 | + check_redirection_options(user, user.preferred_login_redirection, user.admin_url) | |
388 | 405 | else |
389 | 406 | if environment == current_user.environment |
390 | - redirect_back_or_default(user.admin_url) | |
407 | + check_redirection_options(user, environment.redirection_after_login, user.admin_url) | |
391 | 408 | else |
392 | 409 | redirect_back_or_default(:controller => 'home') |
393 | 410 | end |
394 | 411 | end |
395 | 412 | end |
396 | 413 | |
414 | + def go_to_signup_initial_page | |
415 | + check_redirection_options(user, user.environment.redirection_after_signup, user.url) | |
416 | + end | |
417 | + | |
397 | 418 | def redirect_if_logged_in |
398 | 419 | if logged_in? |
399 | 420 | go_to_initial_page |
... | ... | @@ -409,4 +430,22 @@ class AccountController < ApplicationController |
409 | 430 | user |
410 | 431 | end |
411 | 432 | |
433 | + protected | |
434 | + | |
435 | + def check_redirection_options(user, condition, default) | |
436 | + case condition | |
437 | + when 'keep_on_same_page' | |
438 | + redirect_back_or_default(user.admin_url) | |
439 | + when 'site_homepage' | |
440 | + redirect_to :controller => :home | |
441 | + when 'user_profile_page' | |
442 | + redirect_to user.public_profile_url | |
443 | + when 'user_homepage' | |
444 | + redirect_to user.url | |
445 | + when 'user_control_panel' | |
446 | + redirect_to user.admin_url | |
447 | + else | |
448 | + redirect_back_or_default(default) | |
449 | + end | |
450 | + end | |
412 | 451 | end | ... | ... |
app/controllers/public/content_viewer_controller.rb
... | ... | @@ -52,7 +52,7 @@ class ContentViewerController < ApplicationController |
52 | 52 | end |
53 | 53 | |
54 | 54 | # At this point the page will be showed |
55 | - @page.hit | |
55 | + @page.hit unless user_is_a_bot? | |
56 | 56 | |
57 | 57 | @page = FilePresenter.for @page |
58 | 58 | |
... | ... | @@ -113,6 +113,15 @@ class ContentViewerController < ApplicationController |
113 | 113 | @comments = @plugins.filter(:unavailable_comments, @comments) |
114 | 114 | @comments_count = @comments.count |
115 | 115 | @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) |
116 | + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order] | |
117 | + | |
118 | + if request.xhr? and params[:comment_order] | |
119 | + if @comment_order == 'newest' | |
120 | + @comments = @comments.reverse | |
121 | + end | |
122 | + | |
123 | + return render :partial => 'comment/comment', :collection => @comments | |
124 | + end | |
116 | 125 | |
117 | 126 | if params[:slideshow] |
118 | 127 | render :action => 'slideshow', :layout => 'slideshow' |
... | ... | @@ -178,4 +187,13 @@ class ContentViewerController < ApplicationController |
178 | 187 | allowed |
179 | 188 | end |
180 | 189 | |
190 | + def user_is_a_bot? | |
191 | + user_agent= request.env["HTTP_USER_AGENT"] | |
192 | + user_agent.blank? || | |
193 | + user_agent.match(/bot/) || | |
194 | + user_agent.match(/spider/) || | |
195 | + user_agent.match(/crawler/) || | |
196 | + user_agent.match(/\(.*https?:\/\/.*\)/) | |
197 | + end | |
198 | + | |
181 | 199 | end | ... | ... |
app/controllers/public/events_controller.rb
... | ... | @@ -7,11 +7,11 @@ class EventsController < PublicController |
7 | 7 | @date = build_date(params[:year], params[:month], params[:day]) |
8 | 8 | |
9 | 9 | if !params[:year] && !params[:month] && !params[:day] |
10 | - @events = profile.events.next_events_from_month(@date) | |
10 | + @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page]) | |
11 | 11 | end |
12 | 12 | |
13 | 13 | if params[:year] || params[:month] |
14 | - @events = profile.events.by_month(@date) | |
14 | + @events = profile.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page]) | |
15 | 15 | end |
16 | 16 | |
17 | 17 | events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month) |
... | ... | @@ -21,7 +21,7 @@ class EventsController < PublicController |
21 | 21 | |
22 | 22 | def events_by_day |
23 | 23 | @date = build_date(params[:year], params[:month], params[:day]) |
24 | - @events = profile.events.by_day(@date) | |
24 | + @events = profile.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) | |
25 | 25 | render :partial => 'events' |
26 | 26 | end |
27 | 27 | |
... | ... | @@ -29,4 +29,7 @@ class EventsController < PublicController |
29 | 29 | |
30 | 30 | include EventsHelper |
31 | 31 | |
32 | + def per_page | |
33 | + 20 | |
34 | + end | |
32 | 35 | end | ... | ... |
app/controllers/public/search_controller.rb
... | ... | @@ -99,14 +99,14 @@ class SearchController < PublicController |
99 | 99 | @events = [] |
100 | 100 | if params[:day] || !params[:year] && !params[:month] |
101 | 101 | @events = @category ? |
102 | - environment.events.by_day(@date).in_category(Category.find(@category_id)) : | |
103 | - environment.events.by_day(@date) | |
102 | + environment.events.by_day(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) : | |
103 | + environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) | |
104 | 104 | end |
105 | 105 | |
106 | 106 | if params[:year] || params[:month] |
107 | 107 | @events = @category ? |
108 | - environment.events.by_month(@date).in_category(Category.find(@category_id)) : | |
109 | - environment.events.by_month(@date) | |
108 | + environment.events.by_month(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) : | |
109 | + environment.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page]) | |
110 | 110 | end |
111 | 111 | |
112 | 112 | @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events |
... | ... | @@ -139,7 +139,7 @@ class SearchController < PublicController |
139 | 139 | |
140 | 140 | def events_by_day |
141 | 141 | @date = build_date(params[:year], params[:month], params[:day]) |
142 | - @events = environment.events.by_day(@date) | |
142 | + @events = environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) | |
143 | 143 | render :partial => 'events/events' |
144 | 144 | end |
145 | 145 | |
... | ... | @@ -224,4 +224,8 @@ class SearchController < PublicController |
224 | 224 | @environment.send(klass.name.underscore.pluralize).visible.includes(relations) |
225 | 225 | end |
226 | 226 | |
227 | + def per_page | |
228 | + 20 | |
229 | + end | |
230 | + | |
227 | 231 | end | ... | ... |
app/controllers/themes_controller.rb
... | ... | @@ -12,7 +12,7 @@ class ThemesController < ApplicationController |
12 | 12 | |
13 | 13 | def index |
14 | 14 | @environment = environment |
15 | - @themes = environment.themes + Theme.approved_themes(target) | |
15 | + @themes = (environment.themes + Theme.approved_themes(target)).sort_by { |t| t.name } | |
16 | 16 | |
17 | 17 | @current_theme = target.theme |
18 | 18 | ... | ... |
app/helpers/account_helper.rb
... | ... | @@ -12,4 +12,17 @@ module AccountHelper |
12 | 12 | _('Checking if e-mail address is already taken...') |
13 | 13 | end |
14 | 14 | end |
15 | + | |
16 | + def suggestion_based_on_username(requested_username='') | |
17 | + return "" if requested_username.empty? | |
18 | + usernames = [] | |
19 | + 3.times do | |
20 | + begin | |
21 | + valid_name = requested_username + rand(1000).to_s | |
22 | + end while (usernames.include?(valid_name) || !Person.is_available?(valid_name, environment)) | |
23 | + usernames << valid_name | |
24 | + end | |
25 | + usernames | |
26 | + end | |
27 | + | |
15 | 28 | end | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -605,49 +605,18 @@ module ApplicationHelper |
605 | 605 | end |
606 | 606 | |
607 | 607 | attr_reader :environment |
608 | + | |
608 | 609 | def select_categories(object_name, title=nil, title_size=4) |
609 | 610 | return nil if environment.enabled?(:disable_categories) |
610 | 611 | if title.nil? |
611 | 612 | title = _('Categories') |
612 | 613 | end |
613 | 614 | |
614 | - object = instance_variable_get("@#{object_name}") | |
615 | - | |
616 | - result = content_tag 'h'+title_size.to_s(), title | |
617 | - result << javascript_tag( 'function open_close_cat( link ) { | |
618 | - var div = link.parentNode.getElementsByTagName("div")[0]; | |
619 | - var end = function(){ | |
620 | - if ( div.style.display == "none" ) { | |
621 | - this.link.className="button icon-button icon-down" | |
622 | - } else { | |
623 | - this.link.className="button icon-button icon-up-red" | |
624 | - } | |
625 | - } | |
626 | - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } ) | |
627 | - }') | |
628 | - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel| | |
629 | - next unless object.accept_category?(toplevel) | |
630 | - # FIXME | |
631 | - ([toplevel] + toplevel.children_for_menu).each do |cat| | |
632 | - if cat.top_level? | |
633 | - result << '<div class="categorie_box">'.html_safe | |
634 | - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' ) | |
635 | - result << content_tag('h5', toplevel.name) | |
636 | - result << '<div style="display:none"><ul class="categories">'.html_safe | |
637 | - else | |
638 | - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}" | |
639 | - result << content_tag('li', labelled_check_box( | |
640 | - cat.full_name_without_leading(1, " → "), | |
641 | - "#{object_name}[category_ids][]", cat.id, | |
642 | - object.category_ids.include?(cat.id), :id => checkbox_id, | |
643 | - :onchange => j('this.parentNode.className=(this.checked?"cat_checked":"")') ), | |
644 | - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n" | |
645 | - end | |
646 | - end | |
647 | - result << '</ul></div></div>'.html_safe | |
648 | - end | |
615 | + @object = instance_variable_get("@#{object_name}") | |
616 | + @categories = environment.top_level_categories | |
649 | 617 | |
650 | - content_tag('div', result) | |
618 | + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?} | |
619 | + render :partial => 'shared/select_categories_top', :locals => {:object_name => object_name, :title => title, :title_size => title_size, :multiple => true, :categories_selected => @object.categories }, :layout => false | |
651 | 620 | end |
652 | 621 | |
653 | 622 | def theme_option(opt = nil) |
... | ... | @@ -934,12 +903,11 @@ module ApplicationHelper |
934 | 903 | |
935 | 904 | def page_title |
936 | 905 | (@page ? @page.title + ' - ' : '') + |
937 | - (profile ? profile.short_name + ' - ' : '') + | |
938 | 906 | (@topic ? @topic.title + ' - ' : '') + |
939 | 907 | (@section ? @section.title + ' - ' : '') + |
940 | 908 | (@toc ? _('Online Manual') + ' - ' : '') + |
941 | 909 | (controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + |
942 | - environment.name + | |
910 | + (profile ? profile.short_name : environment.name) + | |
943 | 911 | (@category ? " - #{@category.full_name}" : '') |
944 | 912 | end |
945 | 913 | ... | ... |
app/helpers/article_helper.rb
... | ... | @@ -50,8 +50,14 @@ module ArticleHelper |
50 | 50 | 'div', |
51 | 51 | check_box(:article, :display_versions) + |
52 | 52 | content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') |
53 | - ) : '') | |
53 | + ) : '') + | |
54 | 54 | |
55 | + (article.forum? && article.profile.community? ? | |
56 | + content_tag( | |
57 | + 'div', | |
58 | + check_box(:article, :allows_members_to_create_topics) + | |
59 | + content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics') | |
60 | + ) : '') | |
55 | 61 | ) |
56 | 62 | end |
57 | 63 | ... | ... |
app/helpers/boxes_helper.rb
... | ... | @@ -65,7 +65,7 @@ module BoxesHelper |
65 | 65 | end |
66 | 66 | |
67 | 67 | def display_box_content(box, main_content) |
68 | - context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params } | |
68 | + context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user } | |
69 | 69 | box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) |
70 | 70 | end |
71 | 71 | |
... | ... | @@ -212,13 +212,24 @@ module BoxesHelper |
212 | 212 | |
213 | 213 | if !block.main? |
214 | 214 | buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) |
215 | - buttons << icon_button(:clone, _('Clone'), { :action => 'clone', :id => block.id }, { :method => 'post' }) | |
215 | + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | |
216 | 216 | end |
217 | 217 | |
218 | 218 | if block.respond_to?(:help) |
219 | 219 | buttons << thickbox_inline_popup_icon(:help, _('Help on this block'), {}, "help-on-box-#{block.id}") << content_tag('div', content_tag('h2', _('Help')) + content_tag('div', block.help, :style => 'margin-bottom: 1em;') + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "help-on-box-#{block.id}") |
220 | 220 | end |
221 | 221 | |
222 | + if block.embedable? | |
223 | + embed_code = block.embed_code | |
224 | + embed_code = instance_eval(&embed_code) if embed_code.respond_to?(:call) | |
225 | + html = content_tag('div', | |
226 | + content_tag('h2', _('Embed block code')) + | |
227 | + content_tag('div', _('Below, you''ll see a field containing embed code for the block. Just copy the code and paste it into your website or blogging software.'), :style => 'margin-bottom: 1em;') + | |
228 | + content_tag('textarea', embed_code, :style => 'margin-bottom: 1em; width:100%; height:40%;', :readonly => 'readonly') + | |
229 | + thickbox_close_button(_('Close')), :style => 'display: none;', :id => "embed-code-box-#{block.id}") | |
230 | + buttons << thickbox_inline_popup_icon(:embed, _('Embed code'), {}, "embed-code-box-#{block.id}") << html | |
231 | + end | |
232 | + | |
222 | 233 | content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') |
223 | 234 | end |
224 | 235 | ... | ... |
app/helpers/categories_helper.rb
... | ... | @@ -48,4 +48,12 @@ module CategoriesHelper |
48 | 48 | labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) |
49 | 49 | end |
50 | 50 | |
51 | + #FIXME make this test | |
52 | + def selected_category_link(cat) | |
53 | + content_tag('div', button_to_function_without_text(:remove, _('Remove'), nil) {|page| page["selected-category-#{cat.id}"].remove} + | |
54 | + link_to_function(cat.full_name(' → '), nil, :id => "remove-selected-category-#{cat.id}-button", :class => 'select-subcategory-link') {|page| page["selected-category-#{cat.id}"].remove}, | |
55 | + :class => 'selected-category' | |
56 | + ) | |
57 | + end | |
58 | + | |
51 | 59 | end | ... | ... |
app/helpers/comment_helper.rb
... | ... | @@ -2,7 +2,6 @@ module CommentHelper |
2 | 2 | |
3 | 3 | def article_title(article, args = {}) |
4 | 4 | title = article.title |
5 | - title = article.display_title if article.kind_of?(UploadedFile) && article.image? | |
6 | 5 | title = content_tag('h1', h(title), :class => 'title') |
7 | 6 | if article.belongs_to_blog? |
8 | 7 | unless args[:no_link] |
... | ... | @@ -22,6 +21,12 @@ module CommentHelper |
22 | 21 | title |
23 | 22 | end |
24 | 23 | |
24 | + def comment_extra_contents(comment) | |
25 | + @plugins.dispatch(:comment_extra_contents, comment).collect do |extra_content| | |
26 | + extra_content.kind_of?(Proc) ? self.instance_eval(&extra_content) : extra_content | |
27 | + end.join('\n') | |
28 | + end | |
29 | + | |
25 | 30 | def comment_actions(comment) |
26 | 31 | url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) |
27 | 32 | links = links_for_comment_actions(comment) | ... | ... |
app/helpers/content_viewer_helper.rb
... | ... | @@ -14,8 +14,7 @@ module ContentViewerHelper |
14 | 14 | end |
15 | 15 | |
16 | 16 | def article_title(article, args = {}) |
17 | - title = article.display_title if article.kind_of?(UploadedFile) && article.image? | |
18 | - title = article.title if title.blank? | |
17 | + title = article.title | |
19 | 18 | title = content_tag('h1', h(title), :class => 'title') |
20 | 19 | if article.belongs_to_blog? || article.belongs_to_forum? |
21 | 20 | unless args[:no_link] |
... | ... | @@ -52,15 +51,6 @@ module ContentViewerHelper |
52 | 51 | end |
53 | 52 | end |
54 | 53 | |
55 | - def addthis_facebook_url(article) | |
56 | - "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % { | |
57 | - :title => CGI.escape(article.title), | |
58 | - :url => CGI.escape(url_for(article.url)), | |
59 | - :summary => CGI.escape(truncate(strip_tags(article.body.to_s), :length => 300)), | |
60 | - :image => CGI.escape(article.body_images_paths.first.to_s) | |
61 | - } | |
62 | - end | |
63 | - | |
64 | 54 | def addthis_image_tag |
65 | 55 | if File.exists?(Rails.root.join('public', theme_path, 'images', 'addthis.gif')) |
66 | 56 | image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') | ... | ... |
app/helpers/layout_helper.rb
app/helpers/macros_helper.rb
... | ... | @@ -20,14 +20,16 @@ module MacrosHelper |
20 | 20 | jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ |
21 | 21 | title: #{macro_title(macro).to_json}, |
22 | 22 | modal: true, |
23 | - buttons: [ | |
24 | - {text: #{_('Ok').to_json}, click: function(){ | |
23 | + buttons: { | |
24 | + #{_('Ok').to_json}: function(){ | |
25 | 25 | tinyMCE.activeEditor.execCommand('mceInsertContent', false, |
26 | 26 | (function(dialog){ #{macro_generator(macro)} })(this)); |
27 | 27 | jQuery(this).dialog('close'); |
28 | - }}, | |
29 | - {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}} | |
30 | - ] | |
28 | + }, | |
29 | + #{_('Cancel').to_json}: function(){ | |
30 | + jQuery(this).dialog('close'); | |
31 | + } | |
32 | + } | |
31 | 33 | }); |
32 | 34 | }" |
33 | 35 | end |
... | ... | @@ -57,7 +59,11 @@ module MacrosHelper |
57 | 59 | |
58 | 60 | def macro_generator(macro) |
59 | 61 | if macro.configuration[:generator] |
60 | - macro.configuration[:generator] | |
62 | + if macro.configuration[:generator].respond_to?(:call) | |
63 | + macro.configuration[:generator].call(macro) | |
64 | + else | |
65 | + macro.configuration[:generator] | |
66 | + end | |
61 | 67 | else |
62 | 68 | macro_default_generator(macro) |
63 | 69 | end |
... | ... | @@ -66,8 +72,7 @@ module MacrosHelper |
66 | 72 | |
67 | 73 | def macro_default_generator(macro) |
68 | 74 | code = "var params = {};" |
69 | - configuration = macro_configuration(macro) | |
70 | - configuration[:params].map do |field| | |
75 | + macro.configuration[:params].map do |field| | |
71 | 76 | code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" |
72 | 77 | end |
73 | 78 | code + " | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +module MapsHelper | |
2 | + def self.search_city term, state="" | |
3 | + cities = if state.empty? | |
4 | + NationalRegion.search_city(term + "%", true) | |
5 | + else | |
6 | + NationalRegion.search_city(term + "%", true, state) | |
7 | + end | |
8 | + cities.map {|r|{ :label => r.city , :category => r.state}} | |
9 | + end | |
10 | + | |
11 | + def self.search_state term | |
12 | + NationalRegion.search_state(term + "%", true).map {|r|{ :label => r.state}} | |
13 | + end | |
14 | +end | ... | ... |
app/helpers/token_helper.rb
... | ... | @@ -27,7 +27,7 @@ module TokenHelper |
27 | 27 | hintText: #{options[:hint_text].to_json}, |
28 | 28 | noResultsText: #{options[:no_results_text].to_json}, |
29 | 29 | searchingText: #{options[:searching_text].to_json}, |
30 | - searchDelay: #{options[:serach_delay].to_json}, | |
30 | + searchDelay: #{options[:search_delay].to_json}, | |
31 | 31 | preventDuplicates: #{options[:prevent_duplicates].to_json}, |
32 | 32 | backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, |
33 | 33 | queryParam: #{name.to_json}, | ... | ... |
app/mailers/contact.rb
... | ... | @@ -46,7 +46,7 @@ class Contact |
46 | 46 | to: contact.dest.notification_emails, |
47 | 47 | reply_to: contact.email, |
48 | 48 | subject: "[#{contact.dest.short_name(30)}] " + contact.subject, |
49 | - from: "#{contact.name} <#{contact.dest.environment.contact_email}>" | |
49 | + from: "#{contact.name} <#{contact.dest.environment.noreply_email}>" | |
50 | 50 | } |
51 | 51 | |
52 | 52 | if contact.sender | ... | ... |
app/mailers/mailing.rb
... | ... | @@ -20,7 +20,7 @@ class Mailing < ActiveRecord::Base |
20 | 20 | end |
21 | 21 | |
22 | 22 | def generate_from |
23 | - "#{source.name} <#{source.contact_email}>" | |
23 | + "#{source.name} <#{if source.is_a? Environment then source.noreply_email else source.contact_email end}>" | |
24 | 24 | end |
25 | 25 | |
26 | 26 | def generate_subject | ... | ... |
app/mailers/organization_mailing.rb
app/mailers/pending_task_notifier.rb
... | ... | @@ -11,7 +11,7 @@ class PendingTaskNotifier < ActionMailer::Base |
11 | 11 | |
12 | 12 | mail( |
13 | 13 | to: person.email, |
14 | - from: "#{person.environment.name} <#{person.environment.contact_email}>", | |
14 | + from: "#{person.environment.name} <#{person.environment.noreply_email}>", | |
15 | 15 | subject: _("[%s] Pending tasks") % person.environment.name |
16 | 16 | ) |
17 | 17 | end | ... | ... |
app/mailers/task_mailer.rb
... | ... | @@ -52,7 +52,7 @@ class TaskMailer < ActionMailer::Base |
52 | 52 | end |
53 | 53 | |
54 | 54 | def self.generate_from(task) |
55 | - "#{task.environment.name} <#{task.environment.contact_email}>" | |
55 | + "#{task.environment.name} <#{task.environment.noreply_email}>" | |
56 | 56 | end |
57 | 57 | |
58 | 58 | def generate_environment_url(task, url = {}) | ... | ... |
app/models/block.rb
... | ... | @@ -18,17 +18,36 @@ class Block < ActiveRecord::Base |
18 | 18 | |
19 | 19 | scope :enabled, :conditions => { :enabled => true } |
20 | 20 | |
21 | + def embedable? | |
22 | + false | |
23 | + end | |
24 | + | |
25 | + def embed_code | |
26 | + me = self | |
27 | + lambda do | |
28 | + content_tag('iframe', '', | |
29 | + :src => url_for(:controller => 'embed', :action => 'block', :id => me.id, :only_path => false), | |
30 | + :frameborder => 0, | |
31 | + :width => 1024, | |
32 | + :height => 768, | |
33 | + :class => "embed block #{me.class.name.to_css_class}" | |
34 | + ) | |
35 | + end | |
36 | + end | |
37 | + | |
21 | 38 | # Determines whether a given block must be visible. Optionally a |
22 | 39 | # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and |
23 | 40 | # may contain the following keys: |
24 | 41 | # |
25 | 42 | # * <tt>:article</tt>: the article being viewed currently |
26 | 43 | # * <tt>:language</tt>: in which language the block will be displayed |
44 | + # * <tt>:user</tt>: the logged user | |
27 | 45 | def visible?(context = nil) |
28 | 46 | return false if display == 'never' |
29 | 47 | |
30 | 48 | if context |
31 | 49 | return false if language != 'all' && language != context[:locale] |
50 | + return false unless display_to_user?(context[:user]) | |
32 | 51 | |
33 | 52 | begin |
34 | 53 | return self.send("display_#{display}", context) |
... | ... | @@ -40,6 +59,10 @@ class Block < ActiveRecord::Base |
40 | 59 | true |
41 | 60 | end |
42 | 61 | |
62 | + def display_to_user?(user) | |
63 | + display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged') | |
64 | + end | |
65 | + | |
43 | 66 | def display_always(context) |
44 | 67 | true |
45 | 68 | end |
... | ... | @@ -70,6 +93,14 @@ class Block < ActiveRecord::Base |
70 | 93 | # the homepage of its owner. |
71 | 94 | settings_items :display, :type => :string, :default => 'always' |
72 | 95 | |
96 | + | |
97 | + # The condition for displaying a block to users. It can assume the following values: | |
98 | + # | |
99 | + # * <tt>'all'</tt>: the block is always displayed | |
100 | + # * <tt>'logged'</tt>: the block is displayed to logged users only | |
101 | + # * <tt>'not_logged'</tt>: the block is displayed only to not logged users | |
102 | + settings_items :display_user, :type => :string, :default => 'all' | |
103 | + | |
73 | 104 | # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: |
74 | 105 | # |
75 | 106 | # * <tt>'all'</tt>: the block is always displayed |
... | ... | @@ -143,7 +174,7 @@ class Block < ActiveRecord::Base |
143 | 174 | end |
144 | 175 | |
145 | 176 | alias :active_record_cache_key :cache_key |
146 | - def cache_key(language='en') | |
177 | + def cache_key(language='en', user=nil) | |
147 | 178 | active_record_cache_key+'-'+language |
148 | 179 | end |
149 | 180 | |
... | ... | @@ -173,12 +204,20 @@ class Block < ActiveRecord::Base |
173 | 204 | 'never' => _('Don\'t display'), |
174 | 205 | } |
175 | 206 | |
176 | - def display_options | |
207 | + def display_options_available | |
177 | 208 | DISPLAY_OPTIONS.keys |
178 | 209 | end |
179 | 210 | |
180 | - def display_option_label(option) | |
181 | - DISPLAY_OPTIONS[option] | |
211 | + def display_options | |
212 | + DISPLAY_OPTIONS.slice(*display_options_available) | |
213 | + end | |
214 | + | |
215 | + def display_user_options | |
216 | + @display_user_options ||= { | |
217 | + 'all' => __('All users'), | |
218 | + 'logged' => __('Logged'), | |
219 | + 'not_logged' => __('Not logged'), | |
220 | + } | |
182 | 221 | end |
183 | 222 | |
184 | 223 | def duplicate | ... | ... |
app/models/box.rb
... | ... | @@ -28,6 +28,8 @@ class Box < ActiveRecord::Base |
28 | 28 | CategoriesBlock, |
29 | 29 | CommunitiesBlock, |
30 | 30 | EnterprisesBlock, |
31 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
32 | + # the Noosfero core soon, see ActionItem3045 | |
31 | 33 | EnvironmentStatisticsBlock, |
32 | 34 | FansBlock, |
33 | 35 | FavoriteEnterprisesBlock, |
... | ... | @@ -54,6 +56,8 @@ class Box < ActiveRecord::Base |
54 | 56 | CommunitiesBlock, |
55 | 57 | DisabledEnterpriseMessageBlock, |
56 | 58 | EnterprisesBlock, |
59 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
60 | + # the Noosfero core soon, see ActionItem3045 | |
57 | 61 | EnvironmentStatisticsBlock, |
58 | 62 | FansBlock, |
59 | 63 | FavoriteEnterprisesBlock, | ... | ... |
app/models/comment.rb
... | ... | @@ -170,6 +170,40 @@ class Comment < ActiveRecord::Base |
170 | 170 | body || '' |
171 | 171 | end |
172 | 172 | |
173 | + class Notifier < ActionMailer::Base | |
174 | + def mail(comment) | |
175 | + profile = comment.article.profile | |
176 | + recipients comment.notification_emails | |
177 | + from "#{profile.environment.name} <#{profile.environment.noreply_email}>" | |
178 | + subject _("[%s] you got a new comment!") % [profile.environment.name] | |
179 | + body :recipient => profile.nickname || profile.name, | |
180 | + :sender => comment.author_name, | |
181 | + :sender_link => comment.author_link, | |
182 | + :article_title => comment.article.name, | |
183 | + :comment_url => comment.url, | |
184 | + :comment_title => comment.title, | |
185 | + :comment_body => comment.body, | |
186 | + :environment => profile.environment.name, | |
187 | + :url => profile.environment.top_url | |
188 | + end | |
189 | + def mail_to_followers(comment, emails) | |
190 | + profile = comment.article.profile | |
191 | + bcc emails | |
192 | + from "#{profile.environment.name} <#{profile.environment.noreply_email}>" | |
193 | + subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name] | |
194 | + body :recipient => profile.nickname || profile.name, | |
195 | + :sender => comment.author_name, | |
196 | + :sender_link => comment.author_link, | |
197 | + :article_title => comment.article.name, | |
198 | + :comment_url => comment.url, | |
199 | + :unsubscribe_url => comment.article.view_url.merge({:unfollow => true}), | |
200 | + :comment_title => comment.title, | |
201 | + :comment_body => comment.body, | |
202 | + :environment => profile.environment.name, | |
203 | + :url => profile.environment.top_url | |
204 | + end | |
205 | + end | |
206 | + | |
173 | 207 | def rejected? |
174 | 208 | @rejected |
175 | 209 | end | ... | ... |
app/models/environment.rb
... | ... | @@ -147,6 +147,18 @@ class Environment < ActiveRecord::Base |
147 | 147 | end |
148 | 148 | validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true |
149 | 149 | |
150 | + def self.signup_redirection_options | |
151 | + { | |
152 | + 'keep_on_same_page' => _('Stays on the same page the user was before signup.'), | |
153 | + 'site_homepage' => _('Redirects the user to the environment homepage.'), | |
154 | + 'user_profile_page' => _('Redirects the user to his profile page.'), | |
155 | + 'user_homepage' => _('Redirects the user to his homepage.'), | |
156 | + 'user_control_panel' => _('Redirects the user to his control panel.') | |
157 | + } | |
158 | + end | |
159 | + validates_inclusion_of :redirection_after_signup, :in => Environment.signup_redirection_options.keys, :allow_nil => true | |
160 | + | |
161 | + | |
150 | 162 | # ################################################# |
151 | 163 | # Relationships and applied behaviour |
152 | 164 | # ################################################# |
... | ... | @@ -163,6 +175,8 @@ class Environment < ActiveRecord::Base |
163 | 175 | |
164 | 176 | # "left" area |
165 | 177 | env.boxes[1].blocks << LoginBlock.new |
178 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
179 | + # the Noosfero core soon, see ActionItem3045 | |
166 | 180 | env.boxes[1].blocks << EnvironmentStatisticsBlock.new |
167 | 181 | env.boxes[1].blocks << RecentDocumentsBlock.new |
168 | 182 | |
... | ... | @@ -580,7 +594,7 @@ class Environment < ActiveRecord::Base |
580 | 594 | # only one environment can be the default one |
581 | 595 | validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one') |
582 | 596 | |
583 | - validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |record| ! record.contact_email.blank? }) | |
597 | + validates_format_of :contact_email, :noreply_email, :with => Noosfero::Constants::EMAIL_FORMAT, :allow_blank => true | |
584 | 598 | |
585 | 599 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' |
586 | 600 | |
... | ... | @@ -768,7 +782,7 @@ class Environment < ActiveRecord::Base |
768 | 782 | end |
769 | 783 | |
770 | 784 | def notification_emails |
771 | - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email) | |
785 | + [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email) | |
772 | 786 | end |
773 | 787 | |
774 | 788 | after_create :create_templates | ... | ... |
app/models/environment_statistics_block.rb
1 | +# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
2 | +# the Noosfero core soon, see ActionItem3045 | |
3 | + | |
1 | 4 | class EnvironmentStatisticsBlock < Block |
2 | 5 | |
3 | 6 | def self.description |
4 | - _('Environment stastistics') | |
7 | + _('Environment stastistics (DEPRECATED)') | |
5 | 8 | end |
6 | 9 | |
7 | 10 | def default_title | ... | ... |
app/models/event.rb
... | ... | @@ -43,15 +43,12 @@ class Event < Article |
43 | 43 | scope :next_events_from_month, lambda { |date| |
44 | 44 | date_temp = date.strftime("%Y-%m-%d") |
45 | 45 | { :conditions => ["start_date >= ?","#{date_temp}"], |
46 | - :limit => 10, | |
47 | 46 | :order => 'start_date ASC' |
48 | 47 | } |
49 | 48 | } |
50 | 49 | |
51 | 50 | scope :by_month, lambda { |date| |
52 | - date_temp = date.strftime("%Y-%m") | |
53 | 51 | { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], |
54 | - :limit => 10, | |
55 | 52 | :order => 'start_date ASC' |
56 | 53 | } |
57 | 54 | } | ... | ... |
app/models/forum.rb
... | ... | @@ -7,6 +7,7 @@ class Forum < Folder |
7 | 7 | |
8 | 8 | settings_items :terms_of_use, :type => :string, :default => "" |
9 | 9 | settings_items :has_terms_of_use, :type => :boolean, :default => false |
10 | + settings_items :allows_members_to_create_topics, :type => :boolean, :default => false | |
10 | 11 | has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' |
11 | 12 | |
12 | 13 | before_save do |forum| |
... | ... | @@ -68,4 +69,11 @@ class Forum < Folder |
68 | 69 | self.users_with_agreement.exists? user |
69 | 70 | end |
70 | 71 | |
72 | + def can_create_topic?(user, profile) | |
73 | + return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics | |
74 | + end | |
75 | + | |
76 | + def allow_create?(user) | |
77 | + super || can_create_topic?(user, profile) | |
78 | + end | |
71 | 79 | end | ... | ... |
app/models/friendship.rb
1 | 1 | class Friendship < ActiveRecord::Base |
2 | 2 | track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person |
3 | - | |
3 | + | |
4 | + extend CacheCounterHelper | |
5 | + | |
4 | 6 | belongs_to :person, :foreign_key => :person_id |
5 | 7 | belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' |
8 | + | |
9 | + after_create do |friendship| | |
10 | + update_cache_counter(:friends_count, friendship.person, 1) | |
11 | + update_cache_counter(:friends_count, friendship.friend, 1) | |
12 | + end | |
13 | + | |
14 | + after_destroy do |friendship| | |
15 | + update_cache_counter(:friends_count, friendship.person, -1) | |
16 | + update_cache_counter(:friends_count, friendship.friend, -1) | |
17 | + end | |
6 | 18 | end | ... | ... |
app/models/layout_template.rb
... | ... | @@ -16,15 +16,15 @@ class LayoutTemplate |
16 | 16 | end |
17 | 17 | |
18 | 18 | def name |
19 | - @config['name'] | |
19 | + _ @config['name'] | |
20 | 20 | end |
21 | 21 | |
22 | 22 | def title |
23 | - @config['title'] | |
23 | + _ @config['title'] | |
24 | 24 | end |
25 | 25 | |
26 | 26 | def description |
27 | - @config['description'] | |
27 | + _ @config['description'] | |
28 | 28 | end |
29 | 29 | |
30 | 30 | def number_of_boxes | ... | ... |
app/models/link_list_block.rb
... | ... | @@ -72,6 +72,8 @@ class LinkListBlock < Block |
72 | 72 | def expand_address(address) |
73 | 73 | add = if owner.respond_to?(:identifier) |
74 | 74 | address.gsub('{profile}', owner.identifier) |
75 | + elsif owner.is_a?(Environment) && owner.enabled?('use_portal_community') && owner.portal_community | |
76 | + address.gsub('{portal}', owner.portal_community.identifier) | |
75 | 77 | else |
76 | 78 | address |
77 | 79 | end | ... | ... |
app/models/main_block.rb
app/models/members_block.rb
... | ... | @@ -38,4 +38,15 @@ class MembersBlock < ProfileListBlock |
38 | 38 | } |
39 | 39 | end |
40 | 40 | |
41 | + def cache_key(language='en', user=nil) | |
42 | + logged = '' | |
43 | + if user | |
44 | + logged += '-logged-in' | |
45 | + if user.is_member_of? self.owner | |
46 | + logged += '-member' | |
47 | + end | |
48 | + end | |
49 | + super + logged | |
50 | + end | |
51 | + | |
41 | 52 | end | ... | ... |
app/models/national_region.rb
... | ... | @@ -12,7 +12,7 @@ class NationalRegion < ActiveRecord::Base |
12 | 12 | adtional_contions = ""; |
13 | 13 | |
14 | 14 | if like |
15 | - operator = "like" | |
15 | + operator = "ilike" | |
16 | 16 | find_return = :all |
17 | 17 | end |
18 | 18 | |
... | ... | @@ -41,7 +41,7 @@ class NationalRegion < ActiveRecord::Base |
41 | 41 | find_return = :first |
42 | 42 | |
43 | 43 | if like |
44 | - operator = "like" | |
44 | + operator = "ilike" | |
45 | 45 | find_return = :all |
46 | 46 | end |
47 | 47 | ... | ... |
app/models/organization.rb
... | ... | @@ -28,18 +28,7 @@ class Organization < Profile |
28 | 28 | |
29 | 29 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' |
30 | 30 | |
31 | - scope :more_popular, | |
32 | - :select => "#{Profile.qualified_column_names}, count(resource_id) as total", | |
33 | - :group => Profile.qualified_column_names, | |
34 | - :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id", | |
35 | - :order => "total DESC" | |
36 | - | |
37 | - scope :more_active, | |
38 | - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total", | |
39 | - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id", | |
40 | - :group => Profile.qualified_column_names, | |
41 | - :order => 'total DESC', | |
42 | - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] | |
31 | + scope :more_popular, :order => 'members_count DESC' | |
43 | 32 | |
44 | 33 | def validation_methodology |
45 | 34 | self.validation_info ? self.validation_info.validation_methodology : nil | ... | ... |
app/models/person.rb
... | ... | @@ -59,18 +59,7 @@ class Person < Profile |
59 | 59 | has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' |
60 | 60 | has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' |
61 | 61 | |
62 | - scope :more_popular, | |
63 | - :select => "#{Profile.qualified_column_names}, count(friend_id) as total", | |
64 | - :group => Profile.qualified_column_names, | |
65 | - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id", | |
66 | - :order => "total DESC" | |
67 | - | |
68 | - scope :more_active, | |
69 | - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total", | |
70 | - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id", | |
71 | - :group => Profile.qualified_column_names, | |
72 | - :order => 'total DESC', | |
73 | - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] | |
62 | + scope :more_popular, :order => 'friends_count DESC' | |
74 | 63 | |
75 | 64 | scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' |
76 | 65 | scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*" |
... | ... | @@ -492,6 +481,17 @@ class Person < Profile |
492 | 481 | gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) |
493 | 482 | end |
494 | 483 | |
484 | + settings_items :last_notification, :type => DateTime | |
485 | + settings_items :notification_time, :type => :integer, :default => 0 | |
486 | + | |
487 | + def notifier | |
488 | + @notifier ||= PersonNotifier.new(self) | |
489 | + end | |
490 | + | |
491 | + after_update do |person| | |
492 | + person.notifier.reschedule_next_notification_mail | |
493 | + end | |
494 | + | |
495 | 495 | protected |
496 | 496 | |
497 | 497 | def followed_by?(profile) | ... | ... |
... | ... | @@ -0,0 +1,89 @@ |
1 | +class PersonNotifier | |
2 | + | |
3 | + def initialize(person) | |
4 | + @person = person | |
5 | + end | |
6 | + | |
7 | + def self.schedule_all_next_notification_mail | |
8 | + Delayed::Job.enqueue(NotifyAllJob.new) unless NotifyAllJob.exists? | |
9 | + end | |
10 | + | |
11 | + def schedule_next_notification_mail | |
12 | + dispatch_notification_mail if !NotifyJob.exists?(@person.id) | |
13 | + end | |
14 | + | |
15 | + def dispatch_notification_mail | |
16 | + Delayed::Job.enqueue(NotifyJob.new(@person.id), nil, @person.notification_time.hours.from_now) if @person.notification_time>0 | |
17 | + end | |
18 | + | |
19 | + def reschedule_next_notification_mail | |
20 | + return nil unless @person.setting_changed?(:notification_time) || @person.setting_changed?(:last_notification) | |
21 | + NotifyJob.find(@person.id).delete_all | |
22 | + schedule_next_notification_mail | |
23 | + end | |
24 | + | |
25 | + def notify | |
26 | + if @person.notification_time && @person.notification_time > 0 | |
27 | + from = @person.last_notification || DateTime.now - @person.notification_time.hours | |
28 | + notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", from]) | |
29 | + Noosfero.with_locale @person.environment.default_language do | |
30 | + Mailer::deliver_content_summary(@person, notifications) unless notifications.empty? | |
31 | + end | |
32 | + @person.settings[:last_notification] = DateTime.now | |
33 | + @person.save! | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + class NotifyAllJob | |
38 | + def self.exists? | |
39 | + Delayed::Job.where(:handler => "--- !ruby/object:PersonNotifier::NotifyAllJob {}\n\n").count > 0 | |
40 | + end | |
41 | + | |
42 | + def perform | |
43 | + Person.find_each {|person| person.notifier.schedule_next_notification_mail } | |
44 | + end | |
45 | + end | |
46 | + | |
47 | + class NotifyJob < Struct.new(:person_id) | |
48 | + | |
49 | + def self.exists?(person_id) | |
50 | + !find(person_id).empty? | |
51 | + end | |
52 | + | |
53 | + def self.find(person_id) | |
54 | + Delayed::Job.where(:handler => "--- !ruby/struct:PersonNotifier::NotifyJob \nperson_id: #{person_id}\n") | |
55 | + end | |
56 | + | |
57 | + def perform | |
58 | + Person.find(person_id).notifier.notify | |
59 | + end | |
60 | + | |
61 | + def on_permanent_failure | |
62 | + person = Person.find(person_id) | |
63 | + person.notifier.dispatch_notification_mail | |
64 | + end | |
65 | + | |
66 | + end | |
67 | + | |
68 | + class Mailer < ActionMailer::Base | |
69 | + | |
70 | + add_template_helper(PersonNotifierHelper) | |
71 | + | |
72 | + def session | |
73 | + {:theme => nil} | |
74 | + end | |
75 | + | |
76 | + def content_summary(person, notifications) | |
77 | + @current_theme = 'default' | |
78 | + @profile = person | |
79 | + recipients person.email | |
80 | + from "#{@profile.environment.name} <#{@profile.environment.contact_email}>" | |
81 | + subject _("[%s] Network Activity") % [@profile.environment.name] | |
82 | + body :recipient => @profile.nickname || @profile.name, | |
83 | + :environment => @profile.environment.name, | |
84 | + :url => @profile.environment.top_url, | |
85 | + :notifications => notifications | |
86 | + content_type "text/html" | |
87 | + end | |
88 | + end | |
89 | +end | ... | ... |
app/models/profile.rb
... | ... | @@ -100,10 +100,6 @@ class Profile < ActiveRecord::Base |
100 | 100 | members.order(:name) |
101 | 101 | end |
102 | 102 | |
103 | - def members_count | |
104 | - members.count | |
105 | - end | |
106 | - | |
107 | 103 | class << self |
108 | 104 | def count_with_distinct(*args) |
109 | 105 | options = args.last || {} |
... | ... | @@ -126,10 +122,11 @@ class Profile < ActiveRecord::Base |
126 | 122 | |
127 | 123 | scope :visible, :conditions => { :visible => true } |
128 | 124 | scope :public, :conditions => { :visible => true, :public_profile => true } |
129 | - # Subclasses must override these methods | |
125 | + | |
126 | + # Subclasses must override this method | |
130 | 127 | scope :more_popular |
131 | - scope :more_active | |
132 | 128 | |
129 | + scope :more_active, :order => 'activities_count DESC' | |
133 | 130 | scope :more_recent, :order => "created_at DESC" |
134 | 131 | |
135 | 132 | acts_as_trackable :dependent => :destroy |
... | ... | @@ -626,10 +623,10 @@ private :generate_url, :url_options |
626 | 623 | # Adds a person as member of this Profile. |
627 | 624 | def add_member(person) |
628 | 625 | if self.has_members? |
629 | - if self.closed? && members_count > 0 | |
626 | + if self.closed? && members.count > 0 | |
630 | 627 | AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) |
631 | 628 | else |
632 | - self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0 | |
629 | + self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0 | |
633 | 630 | self.affiliate(person, Profile::Roles.member(environment.id)) |
634 | 631 | end |
635 | 632 | else | ... | ... |
app/models/scrap.rb
... | ... | @@ -17,7 +17,7 @@ class Scrap < ActiveRecord::Base |
17 | 17 | |
18 | 18 | scope :not_replies, :conditions => {:scrap_id => nil} |
19 | 19 | |
20 | - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target | |
20 | + track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target | |
21 | 21 | |
22 | 22 | track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} |
23 | 23 | |
... | ... | @@ -57,4 +57,21 @@ class Scrap < ActiveRecord::Base |
57 | 57 | sender != receiver && (is_root? ? root.receiver.receives_scrap_notification? : receiver.receives_scrap_notification?) |
58 | 58 | end |
59 | 59 | |
60 | + class Notifier < ActionMailer::Base | |
61 | + def mail(scrap) | |
62 | + sender, receiver = scrap.sender, scrap.receiver | |
63 | + recipients receiver.email | |
64 | + | |
65 | + from "#{sender.environment.name} <#{sender.environment.noreply_email}>" | |
66 | + subject _("[%s] You received a scrap!") % [sender.environment.name] | |
67 | + body :recipient => receiver.name, | |
68 | + :sender => sender.name, | |
69 | + :sender_link => sender.url, | |
70 | + :scrap_content => scrap.content, | |
71 | + :wall_url => scrap.scrap_wall_url, | |
72 | + :environment => sender.environment.name, | |
73 | + :url => sender.environment.top_url | |
74 | + end | |
75 | + end | |
76 | + | |
60 | 77 | end | ... | ... |
app/models/text_article.rb
... | ... | @@ -22,4 +22,23 @@ class TextArticle < Article |
22 | 22 | def can_display_versions? |
23 | 23 | true |
24 | 24 | end |
25 | + | |
26 | + before_save :set_relative_path | |
27 | + | |
28 | + def set_relative_path | |
29 | + parsed = Hpricot(self.body.to_s) | |
30 | + parsed.search('img[@src]').map { |i| change_element_path(i, 'src') } | |
31 | + parsed.search('a[@href]').map { |i| change_element_path(i, 'href') } | |
32 | + self.body = parsed.to_s | |
33 | + end | |
34 | + | |
35 | + def change_element_path(el, attribute) | |
36 | + fullpath = /(https?):\/\/(#{environment.default_hostname})(:\d+)?(\/.*)/.match(el[attribute]) | |
37 | + if fullpath | |
38 | + domain = fullpath[2] | |
39 | + path = fullpath[4] | |
40 | + el[attribute] = path if domain == environment.default_hostname | |
41 | + end | |
42 | + end | |
43 | + | |
25 | 44 | end | ... | ... |
app/models/theme.rb
... | ... | @@ -42,17 +42,25 @@ class Theme |
42 | 42 | end |
43 | 43 | |
44 | 44 | def approved_themes(owner) |
45 | - Dir.glob(File.join(system_themes_dir, '*')).select do |item| | |
46 | - if File.exists?( File.join(item, 'theme.yml') ) | |
47 | - config = YAML.load_file(File.join(item, 'theme.yml')) | |
48 | - (config['owner_type'] == owner.class.base_class.name) && | |
49 | - (config['owner_id'] == owner.id) || config['public'] | |
45 | + Dir.glob(File.join(system_themes_dir, '*')).map do |item| | |
46 | + next unless File.exists? File.join(item, 'theme.yml') | |
47 | + id = File.basename item | |
48 | + config = YAML.load_file File.join(item, 'theme.yml') | |
49 | + | |
50 | + approved = config['public'] | |
51 | + unless approved | |
52 | + begin | |
53 | + approved = owner.kind_of?(config['owner_type'].constantize) | |
54 | + rescue | |
55 | + end | |
56 | + approved &&= config['owner_id'] == owner.id if config['owner_id'].present? | |
50 | 57 | end |
51 | - end.map do |desc| | |
52 | - new(File.basename(desc)) | |
58 | + | |
59 | + [id, config] if approved | |
60 | + end.compact.map do |id, config| | |
61 | + new id, config | |
53 | 62 | end |
54 | 63 | end |
55 | - | |
56 | 64 | end |
57 | 65 | |
58 | 66 | class DuplicatedIdentifier < Exception; end | ... | ... |
app/models/uploaded_file.rb
... | ... | @@ -16,15 +16,12 @@ class UploadedFile < Article |
16 | 16 | |
17 | 17 | include ShortFilename |
18 | 18 | |
19 | - settings_items :title, :type => 'string' | |
20 | - xss_terminate :only => [ :title ] | |
21 | - | |
22 | - def title_with_default | |
23 | - title_without_default || short_filename(name, 60) | |
19 | + def title | |
20 | + if self.name.present? then self.name else self.filename end | |
21 | + end | |
22 | + def title= value | |
23 | + self.name = value | |
24 | 24 | end |
25 | - alias_method_chain :title, :default | |
26 | - | |
27 | - validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? }) | |
28 | 25 | |
29 | 26 | sanitize_filename |
30 | 27 | |
... | ... | @@ -36,10 +33,6 @@ class UploadedFile < Article |
36 | 33 | self.image? ? self.full_filename(:display).to_s.gsub(Rails.root.join('public').to_s, '') : nil |
37 | 34 | end |
38 | 35 | |
39 | - def display_title | |
40 | - title.blank? ? name : title | |
41 | - end | |
42 | - | |
43 | 36 | def first_paragraph |
44 | 37 | '' |
45 | 38 | end |
... | ... | @@ -113,7 +106,7 @@ class UploadedFile < Article |
113 | 106 | alias :orig_set_filename :filename= |
114 | 107 | def filename=(value) |
115 | 108 | orig_set_filename(value) |
116 | - self.name = self.filename | |
109 | + self.name ||= self.filename | |
117 | 110 | end |
118 | 111 | |
119 | 112 | def download_headers | ... | ... |
app/models/user.rb
... | ... | @@ -63,6 +63,44 @@ class User < ActiveRecord::Base |
63 | 63 | self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) |
64 | 64 | end |
65 | 65 | |
66 | + class Mailer < ActionMailer::Base | |
67 | + def activation_email_notify(user) | |
68 | + user_email = "#{user.login}@#{user.email_domain}" | |
69 | + recipients user_email | |
70 | + from "#{user.environment.name} <#{user.environment.noreply_email}>" | |
71 | + subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name } | |
72 | + body :name => user.name, | |
73 | + :email => user_email, | |
74 | + :webmail => MailConf.webmail_url(user.login, user.email_domain), | |
75 | + :environment => user.environment.name, | |
76 | + :url => url_for(:host => user.environment.default_hostname, :controller => 'home') | |
77 | + end | |
78 | + | |
79 | + def activation_code(user) | |
80 | + recipients user.email | |
81 | + | |
82 | + from "#{user.environment.name} <#{user.environment.noreply_email}>" | |
83 | + subject _("[%s] Activate your account") % [user.environment.name] | |
84 | + body :recipient => user.name, | |
85 | + :activation_code => user.activation_code, | |
86 | + :environment => user.environment.name, | |
87 | + :url => user.environment.top_url, | |
88 | + :redirection => (true if user.return_to) | |
89 | + end | |
90 | + | |
91 | + def signup_welcome_email(user) | |
92 | + email_body = user.environment.signup_welcome_text_body.gsub('{user_name}', user.name) | |
93 | + email_subject = user.environment.signup_welcome_text_subject | |
94 | + | |
95 | + content_type 'text/html' | |
96 | + recipients user.email | |
97 | + | |
98 | + from "#{user.environment.name} <#{user.environment.noreply_email}>" | |
99 | + subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject | |
100 | + body email_body | |
101 | + end | |
102 | + end | |
103 | + | |
66 | 104 | def signup! |
67 | 105 | User.transaction do |
68 | 106 | self.save! |
... | ... | @@ -159,7 +197,7 @@ class User < ActiveRecord::Base |
159 | 197 | encryption_methods[sym] = block |
160 | 198 | end |
161 | 199 | |
162 | - # the encryption method used for this instance | |
200 | + # the encryption method used for this instance | |
163 | 201 | def encryption_method |
164 | 202 | (password_type || User.system_encryption_method).to_sym |
165 | 203 | end |
... | ... | @@ -202,7 +240,7 @@ class User < ActiveRecord::Base |
202 | 240 | end |
203 | 241 | |
204 | 242 | def remember_token? |
205 | - remember_token_expires_at && Time.now.utc < remember_token_expires_at | |
243 | + remember_token_expires_at && Time.now.utc < remember_token_expires_at | |
206 | 244 | end |
207 | 245 | |
208 | 246 | # These create and unset the fields required for remembering users between browser closes |
... | ... | @@ -231,7 +269,7 @@ class User < ActiveRecord::Base |
231 | 269 | raise IncorrectPassword unless self.authenticated?(current) |
232 | 270 | self.force_change_password!(new, confirmation) |
233 | 271 | end |
234 | - | |
272 | + | |
235 | 273 | # Changes the password of a user without asking for the old password. This |
236 | 274 | # method is intended to be used by the "I forgot my password", and must be |
237 | 275 | # used with care. |
... | ... | @@ -302,7 +340,7 @@ class User < ActiveRecord::Base |
302 | 340 | end |
303 | 341 | |
304 | 342 | protected |
305 | - # before filter | |
343 | + # before filter | |
306 | 344 | def encrypt_password |
307 | 345 | return if password.blank? |
308 | 346 | self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? | ... | ... |
app/sweepers/profile_sweeper.rb
... | ... | @@ -8,6 +8,8 @@ class ProfileSweeper # < ActiveRecord::Observer |
8 | 8 | end |
9 | 9 | |
10 | 10 | def after_create(profile) |
11 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
12 | + # the Noosfero core soon, see ActionItem3045 | |
11 | 13 | expire_statistics_block_cache(profile) |
12 | 14 | end |
13 | 15 | |
... | ... | @@ -29,6 +31,8 @@ protected |
29 | 31 | expire_blogs(profile) if profile.organization? |
30 | 32 | end |
31 | 33 | |
34 | + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | |
35 | + # the Noosfero core soon, see ActionItem3045 | |
32 | 36 | def expire_statistics_block_cache(profile) |
33 | 37 | blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } |
34 | 38 | BlockSweeper.expire_blocks(blocks) | ... | ... |
app/views/account/_identifier_status.html.erb
1 | 1 | <div class='status-identifier'> |
2 | - <p><span class='<%= @status_class %>'><%= @status %></span></p> | |
2 | + | |
3 | + <span class='<%= @status_class %>'><%= @status %></span> | |
4 | + <% if @suggested_usernames %> | |
5 | + <div class='suggested_usernames'> | |
6 | + <%= _('Available: ') %> | |
7 | + <% @suggested_usernames.each do |username| %> | |
8 | + <a href='#'><%= username %></a> | |
9 | + <% end %> | |
10 | + </div> | |
11 | + <% end %> | |
3 | 12 | <script type="text/javascript"> |
4 | 13 | jQuery('#user_login').removeClass('<%= validation_classes %>'); |
5 | 14 | jQuery('#user_login').addClass('<%= @status_class %>'); |
15 | + jQuery('.suggested_usernames a').click(function(e) { | |
16 | + e.preventDefault(); | |
17 | + | |
18 | + fill_username(this.innerHTML); | |
19 | + }); | |
6 | 20 | </script> |
7 | 21 | </div> | ... | ... |
app/views/account/_signup_form.html.erb
... | ... | @@ -7,6 +7,8 @@ |
7 | 7 | |
8 | 8 | <% @profile_data = @person %> |
9 | 9 | |
10 | +<%= javascript_include_tag('sign_up_password_rate') %> | |
11 | + | |
10 | 12 | <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> |
11 | 13 | |
12 | 14 | <%= labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> |
... | ... | @@ -35,24 +37,30 @@ |
35 | 37 | <%= required text_field(:user, :login, :id => 'user_login', |
36 | 38 | :onchange => 'this.value = convToValidUsername(this.value);') %> |
37 | 39 | <div id='url-check'><p> </p></div> |
40 | + <span id='checking-message' class='checking' style='display:none'><%= _('Checking availability of login name...') %></span> | |
38 | 41 | </div> |
39 | 42 | <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %> |
40 | 43 | <br style="clear: both;" /> |
41 | 44 | </div> |
42 | 45 | </div> |
43 | - <%= observe_field 'user_login', | |
44 | - :url => { :action => 'check_url' }, | |
45 | - :with => 'identifier', | |
46 | - :update => 'url-check', | |
47 | - :loading => "jQuery('#user_login').removeClass('#{validation_classes}').addClass('checking'); | |
48 | - jQuery('#url-check').html('<p><span class=\"checking\">#{checking_message(:url)}</span></p>');", | |
49 | - :complete => "jQuery('#user_login').removeClass('checking')" | |
50 | - %> | |
51 | - | |
46 | + <%= javascript_include_tag "signup_form" %> | |
52 | 47 | <div id='signup-password'> |
53 | 48 | <%= required f.password_field(:password, :id => 'user_pw') %> |
54 | 49 | <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> |
55 | - <div id='fake-check'><p> </p></div> | |
50 | + <div id='password-rate'> | |
51 | + <p><span class="invalid hidden" id='result-short'> | |
52 | + <%=_('Short') %> | |
53 | + </span></p> | |
54 | + <p><span class="invalid hidden" id='result-bad'> | |
55 | + <%=_('Bad') %> | |
56 | + </span></p> | |
57 | + <p><span class="invalid hidden" id='result-good'> | |
58 | + <%=_('Good') %> | |
59 | + </span></p> | |
60 | + <p><span class="invalid hidden" id='result-strong'> | |
61 | + <%=_('Strong') %> | |
62 | + </span></p> | |
63 | + </div> | |
56 | 64 | </div> |
57 | 65 | |
58 | 66 | <div id='signup-password-confirmation'> |
... | ... | @@ -182,4 +190,9 @@ jQuery(function($) { |
182 | 190 | else $(this).addClass('validated'); |
183 | 191 | }); |
184 | 192 | }); |
193 | + | |
194 | +function fill_username(element){ | |
195 | + jQuery('#url-check').html("<p><span class='checking'><%= _('This login name is available') %></span></p>") | |
196 | + jQuery('#user_login').val(element).addClass('validated').removeClass('invalid') | |
197 | +} | |
185 | 198 | </script> | ... | ... |
app/views/admin_panel/_site_info.html.erb
1 | 1 | <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %> |
2 | 2 | <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %> |
3 | +<%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %> | |
3 | 4 | <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> |
4 | 5 | <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> |
5 | 6 | <%= required f.text_field(:reports_lower_bound, :size => 3) %> | ... | ... |
app/views/blocks/profile_image.html.erb
app/views/box_organizer/_link_list_block.html.erb
1 | +<%= javascript_include_tag "edit-link-list.js" %> | |
2 | + | |
1 | 3 | <strong><%= _('Links') %></strong> |
2 | 4 | <div id='edit-link-list-block'> |
3 | -<table id='links' class='noborder'> | |
4 | - <tr> | |
5 | - <th><%= _('Icon') %></th> | |
6 | - <th><%= _('Name') %></th> | |
7 | - <th><%= _('Address') %></th> | |
8 | - <th><%= _('Title') %></th> | |
9 | - <th><%= _('Target') %></th> | |
10 | - </tr> | |
11 | - <% for link in @block.links do %> | |
12 | - <tr> | |
13 | - <td><%= icon_selector(link['icon']) %></td> | |
14 | - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td> | |
15 | - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td> | |
16 | - <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td> | |
17 | - <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td> | |
18 | - </tr> | |
19 | - <% end %> | |
20 | -</table> | |
5 | + <ul class='link-list-header'> | |
6 | + <li class='link-list-icon'><%= _('Icon') %></li> | |
7 | + <li class='link-list-name'><%= _('Name') %></li> | |
8 | + <li class='link-list-address'><%= _('Address') %></li> | |
9 | + <li class='link-list-target'><%= _('Target') %></li> | |
10 | + </ul> | |
11 | + <ul id="dropable-link-list"> | |
12 | + <% for link in @block.links do %> | |
13 | + <li> | |
14 | + <ul class="link-list-row"> | |
15 | + <li> | |
16 | + <%= icon_selector(link['icon']) %> | |
17 | + </li> | |
18 | + <li> | |
19 | + <%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %> | |
20 | + </li> | |
21 | + <li> | |
22 | + <%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %> | |
23 | + </li> | |
24 | + <li> | |
25 | + <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %> | |
26 | + </li> | |
27 | + <li> | |
28 | + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row") %> | |
29 | + </li> | |
30 | + </ul> | |
31 | + </li> | |
32 | + <% end %> | |
33 | + </ul> | |
34 | + <input type="hidden" id="page_url" value="<%=url_for(:action=>'search_autocomplete')%>" /> | |
21 | 35 | </div> |
22 | 36 | |
23 | 37 | <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| |
24 | - page.insert_html :bottom, 'links', j(content_tag('tr', | |
25 | - content_tag('td', icon_selector('ok')) + | |
26 | - content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) + | |
27 | - content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') + | |
28 | - content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) + | |
29 | - content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) | |
38 | + page.insert_html :bottom, 'dropable-link-list', content_tag('li', | |
39 | + content_tag('ul', | |
40 | + content_tag('li', icon_selector('ok')) + | |
41 | + content_tag('li', text_field_tag('block[links][][name]', '', :maxlength => 20)) + | |
42 | + content_tag('li', text_field_tag('block[links][][address]', nil, :class => 'link-address')) + | |
43 | + content_tag('li', select_tag('block[links][][target]', | |
44 | + options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) + | |
45 | + content_tag('li', button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row")), | |
46 | + :class=>"link-list-row new_link_row") | |
30 | 47 | ) + |
31 | - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight")) | |
48 | + javascript_tag("new_link_action()") | |
32 | 49 | end %> | ... | ... |
app/views/box_organizer/edit.html.erb
... | ... | @@ -7,13 +7,14 @@ |
7 | 7 | |
8 | 8 | <%= render :partial => partial_for_class(@block.class) %> |
9 | 9 | |
10 | - <%= labelled_form_field _('Display this block:'), '' %> | |
11 | - <div style='margin-left: 10px'> | |
12 | - <% @block.display_options.each do |option| %> | |
13 | - <%= radio_button(:block, :display, option) %> | |
14 | - <%= label_tag("block_display_#{option}", _(@block.display_option_label(option))) %> | |
15 | - <br/> | |
16 | - <% end %> | |
10 | + <div class="display"> | |
11 | + <%= labelled_form_field _('Display this block:'), | |
12 | + select_tag('block[display]', options_from_collection_for_select(@block.display_options, :first, :last, @block.display)) | |
13 | + %> | |
14 | + </div> | |
15 | + <div class="display_user"> | |
16 | + <%= labelled_form_field _('Display to users:'), '' %> | |
17 | + <%= select_tag('block[display_user]', options_from_collection_for_select(@block.display_user_options, :first, :last, @block.display_user)) %> | |
17 | 18 | </div> |
18 | 19 | |
19 | 20 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +<div id="addThis"> | |
2 | + <script type="text/javascript"> | |
3 | + addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>'; | |
4 | + addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>'; | |
5 | + addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>'; | |
6 | + </script> | |
7 | + <a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a> | |
8 | +</div> | ... | ... |
app/views/content_viewer/_article_toolbar.html.erb
... | ... | @@ -26,7 +26,7 @@ |
26 | 26 | <%= expirable_button @page, :spread, content, url if url %> |
27 | 27 | <% end %> |
28 | 28 | |
29 | - <% if !@page.gallery? && @page.allow_create?(user) %> | |
29 | + <% if !@page.gallery? && (@page.allow_create?(user) || (@page.parent && @page.parent.allow_create?(user))) %> | |
30 | 30 | <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> |
31 | 31 | <% content = _('Add translation') %> |
32 | 32 | <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> | ... | ... |
app/views/content_viewer/view_page.html.erb
... | ... | @@ -43,21 +43,7 @@ |
43 | 43 | <%= render :partial => 'shared/disabled_enterprise' %> |
44 | 44 | |
45 | 45 | <% if NOOSFERO_CONF['addthis_enabled'] %> |
46 | -<div id="addThis"> | |
47 | -<script type="text/javascript"> | |
48 | - addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>'; | |
49 | - addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>'; | |
50 | - addthis_config = { | |
51 | - services_custom: { | |
52 | - name: 'Facebook', | |
53 | - url: '<%= addthis_facebook_url(@page) %>', | |
54 | - icon: 'http://cache.addthiscdn.com/icons/v1/thumbs/facebook.gif' | |
55 | - } | |
56 | - }; | |
57 | - addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>'; | |
58 | -</script> | |
59 | -<a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a> | |
60 | -</div> | |
46 | + <%= render :partial => 'addthis' %> | |
61 | 47 | <% end %> |
62 | 48 | |
63 | 49 | <% cache(@page.cache_key(params, user, language)) do %> |
... | ... | @@ -84,6 +70,8 @@ |
84 | 70 | |
85 | 71 | <%= display_source_info(@page) %> |
86 | 72 | |
73 | +<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %> | |
74 | + | |
87 | 75 | <div class="comments" id="comments_list"> |
88 | 76 | |
89 | 77 | <% if @page.accept_comments? || @comments_count > 0 %> |
... | ... | @@ -92,8 +80,26 @@ |
92 | 80 | </h3> |
93 | 81 | <% end %> |
94 | 82 | |
95 | - <% if @page.accept_comments? && @comments.count > 1 %> | |
83 | + <% if @page.accept_comments? && @comments_count > 1 %> | |
96 | 84 | <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> |
85 | + | |
86 | + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %> | |
87 | + <%= javascript_include_tag "comment_order.js" %> | |
88 | + <div class="comment-order"> | |
89 | + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %> | |
90 | + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %> | |
91 | + <% end %> | |
92 | + </div> | |
93 | + <% end %> | |
94 | + | |
95 | + <% if @page.accept_comments? and @comments.count > 1 %> | |
96 | + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %> | |
97 | + <%= javascript_include_tag "comment_order.js" %> | |
98 | + <div class="comment-order"> | |
99 | + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %> | |
100 | + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %> | |
101 | + <% end %> | |
102 | + </div> | |
97 | 103 | <% end %> |
98 | 104 | |
99 | 105 | <ul class="article-comments-list"> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= display_block(@block) %> | ... | ... |
... | ... | @@ -0,0 +1,6 @@ |
1 | +<div id='not-found'> | |
2 | + <p> | |
3 | + <%= _('You may have clicked an expired link or mistyped the address.') %> | |
4 | + <%= _('If you clicked a link that was in another site, or was given to you by someone else, it would be nice if you tell them that their link is not valid anymore.') %> | |
5 | + </p> | |
6 | +</div> | ... | ... |
app/views/events/_events.html.erb
app/views/features/_manage_community_fields.html.erb
1 | -<h2><%= _('Manage community fields') %></h2> | |
2 | - | |
3 | 1 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %> |
4 | 2 | |
5 | 3 | <table id='community_fields_conf'> |
... | ... | @@ -9,21 +7,37 @@ |
9 | 7 | <th><%= _('Required') %></th> |
10 | 8 | <th><%= _('Display on creation?') %></th> |
11 | 9 | </tr> |
10 | + | |
11 | + <tr class='manage-fields-batch-actions'> | |
12 | + <td> | |
13 | + <%= _("Check/Uncheck All")%> | |
14 | + </td> | |
15 | + <td> | |
16 | + <input type="checkbox" id="community_active" /> | |
17 | + </td> | |
18 | + <td> | |
19 | + <input type="checkbox" id="community_required" /> | |
20 | + </td> | |
21 | + <td> | |
22 | + <input type="checkbox" id="community_signup" /> | |
23 | + </td> | |
24 | + </tr> | |
25 | + | |
12 | 26 | <% @community_fields.each do |field| %> |
13 | 27 | <tr> |
14 | 28 | <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> |
15 | 29 | |
16 | 30 | <td> |
17 | 31 | <%= hidden_field_tag "community_fields[#{field}][active]", false %> |
18 | - <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "$('community_fields[#{field}][required]').disabled=$('community_fields[#{field}][signup]').disabled=!this.checked;" %> | |
32 | + <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "active_action(this, 'community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %> | |
19 | 33 | </td> |
20 | 34 | <td> |
21 | 35 | <%= hidden_field_tag "community_fields[#{field}][required]", false %> |
22 | - <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "if(this.checked) $('community_fields[#{field}][signup]').checked = true;" %> | |
36 | + <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "required_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %> | |
23 | 37 | </td> |
24 | 38 | <td> |
25 | 39 | <%= hidden_field_tag "community_fields[#{field}][signup]", false %> |
26 | - <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "if(!this.checked) $('community_fields[#{field}][required]').checked = false;" %> | |
40 | + <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "signup_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %> | |
27 | 41 | </td> |
28 | 42 | |
29 | 43 | </tr> |
... | ... | @@ -31,18 +45,18 @@ |
31 | 45 | </table> |
32 | 46 | |
33 | 47 | <script type='text/javascript'> |
34 | - var trs = $$('#community_fields_conf tr'); | |
48 | + var trs = jQuery('#community_fields_conf tr'); | |
35 | 49 | var tr, td2; |
36 | - for ( var i=0; tr=trs[i]; i++ ) { | |
50 | + for ( var i=2; tr=trs[i]; i++ ) { | |
37 | 51 | if ( td2 = tr.getElementsByTagName('td')[1] ) { |
38 | - td2.getElementsByTagName('input')[0].onclick(); | |
52 | + td2.getElementsByTagName('input')[1].onclick(); | |
39 | 53 | } |
40 | 54 | } |
41 | 55 | </script> |
42 | 56 | |
43 | 57 | <div> |
44 | 58 | <% button_bar do %> |
45 | - <%= submit_button('save', _('Save changes')) %> | |
59 | + <%= submit_button('save', _('Save changes'), :id=>"save_community_fields") %> | |
46 | 60 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> |
47 | 61 | <% end %> |
48 | 62 | </div> | ... | ... |
app/views/features/_manage_enterprise_fields.html.erb
1 | -<h2><%= _('Manage enterprise fields') %></h2> | |
2 | - | |
3 | 1 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %> |
4 | 2 | |
5 | 3 | <table id='enterprise_fields_conf'> |
... | ... | @@ -9,21 +7,37 @@ |
9 | 7 | <th><%= _('Required') %></th> |
10 | 8 | <th><%= _('Display on registration?') %></th> |
11 | 9 | </tr> |
10 | + | |
11 | + <tr class='manage-fields-batch-actions'> | |
12 | + <td> | |
13 | + <%= _("Check/Uncheck All")%> | |
14 | + </td> | |
15 | + <td> | |
16 | + <input type="checkbox" id="enterprise_active" /> | |
17 | + </td> | |
18 | + <td> | |
19 | + <input type="checkbox" id="enterprise_required" /> | |
20 | + </td> | |
21 | + <td> | |
22 | + <input type="checkbox" id="enterprise_signup" /> | |
23 | + </td> | |
24 | + </tr> | |
25 | + | |
12 | 26 | <% @enterprise_fields.each do |field| %> |
13 | 27 | <tr> |
14 | 28 | |
15 | 29 | <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> |
16 | 30 | <td> |
17 | 31 | <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %> |
18 | - <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "$('enterprise_fields[#{field}][required]').disabled=$('enterprise_fields[#{field}][signup]').disabled=!this.checked;" %> | |
32 | + <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "active_action(this, 'enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %> | |
19 | 33 | </td> |
20 | 34 | <td> |
21 | 35 | <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %> |
22 | - <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "if(this.checked) $('enterprise_fields[#{field}][signup]').checked = true;" %> | |
36 | + <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "required_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %> | |
23 | 37 | </td> |
24 | 38 | <td> |
25 | 39 | <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %> |
26 | - <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "if(!this.checked) $('enterprise_fields[#{field}][required]').checked = false;" %> | |
40 | + <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "signup_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %> | |
27 | 41 | </td> |
28 | 42 | |
29 | 43 | </tr> |
... | ... | @@ -31,18 +45,18 @@ |
31 | 45 | </table> |
32 | 46 | |
33 | 47 | <script type='text/javascript'> |
34 | - var trs = $$('#enterprise_fields_conf tr'); | |
48 | + var trs = jQuery('#enterprise_fields_conf tr'); | |
35 | 49 | var tr, td2; |
36 | - for ( var i=0; tr=trs[i]; i++ ) { | |
50 | + for ( var i=2; tr=trs[i]; i++ ) { | |
37 | 51 | if ( td2 = tr.getElementsByTagName('td')[1] ) { |
38 | - td2.getElementsByTagName('input')[0].onclick(); | |
52 | + td2.getElementsByTagName('input')[1].onclick(); | |
39 | 53 | } |
40 | 54 | } |
41 | 55 | </script> |
42 | 56 | |
43 | 57 | <div> |
44 | 58 | <% button_bar do %> |
45 | - <%= submit_button('save', _('Save changes')) %> | |
59 | + <%= submit_button('save', _('Save changes'), :id=>"save_enterprise_fields") %> | |
46 | 60 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> |
47 | 61 | <% end %> |
48 | 62 | </div> | ... | ... |
app/views/features/_manage_person_fields.html.erb
1 | -<h2><%= _('Manage person fields') %></h2> | |
2 | - | |
3 | 1 | <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %> |
4 | 2 | |
5 | 3 | <table id='person_fields_conf'> |
... | ... | @@ -9,31 +7,48 @@ |
9 | 7 | <th><%= _('Required') %></th> |
10 | 8 | <th><%= _('Display on signup?') %></th> |
11 | 9 | </tr> |
10 | + | |
11 | + <tr class='manage-fields-batch-actions'> | |
12 | + <td> | |
13 | + <%= _("Check/Uncheck All")%> | |
14 | + </td> | |
15 | + <td> | |
16 | + <input type="checkbox" id="person_active" /> | |
17 | + </td> | |
18 | + <td> | |
19 | + <input type="checkbox" id="person_required" /> | |
20 | + </td> | |
21 | + <td> | |
22 | + <input type="checkbox" id="person_signup" /> | |
23 | + </td> | |
24 | + </tr> | |
25 | + | |
12 | 26 | <% @person_fields.each do |field| %> |
13 | 27 | <tr> |
14 | 28 | <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> |
15 | 29 | <td> |
16 | 30 | <%= hidden_field_tag "person_fields[#{field}][active]", false %> |
17 | - <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "$('person_fields[#{field}][required]').disabled=$('person_fields[#{field}][signup]').disabled=!this.checked;" %> | |
31 | + <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "active_action(this, 'person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %> | |
18 | 32 | </td> |
19 | 33 | <td> |
20 | 34 | <%= hidden_field_tag "person_fields[#{field}][required]", false %> |
21 | - <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "if(this.checked) $('person_fields[#{field}][signup]').checked = true;" %> | |
35 | + <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "required_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %> | |
22 | 36 | </td> |
23 | 37 | <td> |
24 | 38 | <%= hidden_field_tag "person_fields[#{field}][signup]", false %> |
25 | - <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "if(!this.checked) $('person_fields[#{field}][required]').checked = false;" %> | |
39 | + <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "signup_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %> | |
26 | 40 | </td> |
27 | 41 | </tr> |
28 | 42 | <% end %> |
29 | 43 | </table> |
30 | 44 | |
31 | 45 | <script type='text/javascript'>// <!-- |
32 | - var trs = $$('#person_fields_conf tr'); | |
46 | + var trs = jQuery('#person_fields_conf tr'); | |
47 | + | |
33 | 48 | var tr, td2; |
34 | - for ( var i=0; tr=trs[i]; i++ ) { | |
49 | + for ( var i=2; tr=trs[i]; i++ ) { | |
35 | 50 | if ( td2 = tr.getElementsByTagName('td')[1] ) { |
36 | - td2.getElementsByTagName('input')[0].onclick(); | |
51 | + td2.getElementsByTagName('input')[1].onclick(); | |
37 | 52 | } |
38 | 53 | } |
39 | 54 | // --> |
... | ... | @@ -41,7 +56,7 @@ |
41 | 56 | |
42 | 57 | <div> |
43 | 58 | <% button_bar do %> |
44 | - <%= submit_button('save', _('Save changes')) %> | |
59 | + <%= submit_button('save', _('Save changes'), :id=>"save_person_fields") %> | |
45 | 60 | <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> |
46 | 61 | <% end %> |
47 | 62 | </div> | ... | ... |
app/views/features/index.html.erb
... | ... | @@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the |
26 | 26 | |
27 | 27 | <h2><%= _('Configure features') %></h2> |
28 | 28 | |
29 | +<h3><%= _('Page to redirect after signup') %></h3> | |
30 | + <%= select 'environment', 'redirection_after_signup', Environment.signup_redirection_options.map{|key,value|[value,key]} %> | |
31 | +<hr/> | |
29 | 32 | <h3><%= _('Page to redirect after login') %></h3> |
30 | 33 | <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %> |
31 | 34 | <hr/> |
35 | + | |
32 | 36 | <h3><%= _('Organization Approval Method') %></h3> |
33 | 37 | <%= select_organization_approval_method('environment', 'organization_approval_method') %> |
34 | 38 | <hr/> | ... | ... |
app/views/features/manage_fields.html.erb
1 | -<%= render :partial => 'manage_person_fields' %> | |
1 | +<h1><%= _('Manage fields displayed for profiles') %></h1> | |
2 | 2 | |
3 | -<% if !environment.enabled?('disable_asset_enterprises') %> | |
4 | - <%= render :partial => 'manage_enterprise_fields' %> | |
3 | +<% tabs = [] %> | |
4 | +<% tabs << {:title => _("Person's fields"), :id => 'person-fields', | |
5 | + :content => (render :partial => 'manage_person_fields')} %> | |
6 | +<% tabs << {:title => _("Community's fields"), :id => 'community-fields', | |
7 | + :content => (render :partial => 'manage_community_fields')} %> | |
8 | +<% unless environment.enabled?('disable_asset_enterprises') %> | |
9 | + <% tabs << {:title => _("Enterprise's fields"), :id => 'enterprise-fields', | |
10 | + :content => (render :partial => 'manage_enterprise_fields')} %> | |
5 | 11 | <% end %> |
6 | 12 | |
7 | -<%= render :partial => 'manage_community_fields' %> | |
13 | +<%= render_tabs(tabs) %> | |
14 | + | |
15 | +<%= javascript_include_tag "manage-fields.js" %> | ... | ... |
app/views/layouts/application-ng.html.erb
... | ... | @@ -6,6 +6,27 @@ |
6 | 6 | <!--<meta http-equiv="refresh" content="1"/>--> |
7 | 7 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
8 | 8 | <meta name="description" content="<%= @environment.name %>" /> |
9 | + | |
10 | + <!-- Twitter Card --> | |
11 | + <meta name="twitter:card" value="summary"> | |
12 | + <meta name="twitter:title" content="<%= h page_title %>"> | |
13 | + <meta name="twitter:description" content="<%= meta_description_tag(@page) %>"> | |
14 | + | |
15 | + <!-- Open Graph --> | |
16 | + <meta property="og:type" content="<%= @page ? 'article' : 'website' %>"> | |
17 | + <meta property="og:url" content="<%= @page ? url_for(@page.url) : @environment.top_url %>"> | |
18 | + <meta property="og:title" content="<%= h page_title %>"> | |
19 | + <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>"> | |
20 | + <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>"> | |
21 | + | |
22 | + <% if @page %> | |
23 | + <meta property="article:published_time" content="<%= show_date(@page.published_at) %>"> | |
24 | + <% @page.body_images_paths.each do |img| %> | |
25 | + <meta name="twitter:image" content="<%= img.to_s %>"> | |
26 | + <meta property="og:image" content="<%= img.to_s %>"> | |
27 | + <% end %> | |
28 | + <% end %> | |
29 | + | |
9 | 30 | <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> |
10 | 31 | <%= noosfero_javascript %> |
11 | 32 | <%= noosfero_stylesheets %> | ... | ... |
... | ... | @@ -0,0 +1,35 @@ |
1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
2 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= html_language %>" lang="<%= html_language %>"> | |
3 | + <head> | |
4 | + <title>Noosfero embed block</title> | |
5 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |
6 | + <%= noosfero_stylesheets %> | |
7 | + <%= noosfero_javascript %> | |
8 | + </head> | |
9 | + <body class="<%= h body_classes %>"> | |
10 | + <div id="embed"> | |
11 | + <div id="wrap-1"> | |
12 | + <div id="wrap-2"> | |
13 | + <div id="content"> | |
14 | + <div id="content-inner"> | |
15 | + <div class="boxes" id="boxes"> | |
16 | + <div class="box box-1" id="box-1"> | |
17 | + <div class="blocks"> | |
18 | + <%= yield %> | |
19 | + </div> | |
20 | + </div> | |
21 | + </div> | |
22 | + </div> | |
23 | + </div> | |
24 | + </div> | |
25 | + </div> | |
26 | + </div> | |
27 | + | |
28 | + <script type="text/javascript"> | |
29 | + jQuery(document).ready(function(){ | |
30 | + jQuery('a').attr('target','_blank'); | |
31 | + }); | |
32 | + </script> | |
33 | + | |
34 | + </body> | |
35 | +</html> | ... | ... |
app/views/person_notifier/mailer/_add_member_in_community.rhtml
0 → 100644
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> | ... | ... |
... | ... | @@ -0,0 +1,33 @@ |
1 | +<% Comment %> | |
2 | +<% Profile %> | |
3 | +<% Person %> | |
4 | + | |
5 | +<table style="background: #f0f0f1;border-bottom: 1px solid #d2d2d2 !important;border-top: 1px solid #fff;margin-bottom: 0;"> | |
6 | +<tr> | |
7 | + <td> | |
8 | + <% if comment.author %> | |
9 | + <%= link_to profile_image(comment.author, :minor), | |
10 | + comment.author_url, | |
11 | + :class => 'comment-picture', | |
12 | + :title => comment.author_name | |
13 | + %> | |
14 | + <% end %> | |
15 | + </td> | |
16 | + <td> | |
17 | + <%= comment.author.present? ? link_to(comment.author_name, comment.author.url, :style => "font-size: 12px; color: #333; font-weight: bold; text-decoration: none;") : content_tag('strong', comment.author_name) %> | |
18 | + <% unless comment.title.blank? %> | |
19 | + <span style="font-size: 12px;"><%= comment.title %></span><br/> | |
20 | + <% end %> | |
21 | + <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> | |
22 | + <span style="font-size: 8px; color: #444444"><%= time_ago_as_sentence(comment.created_at) %></span> | |
23 | + <br style="clear: both;" /> | |
24 | + | |
25 | + <% unless comment.replies.blank? %> | |
26 | + <ul class="comment-replies"> | |
27 | + <% comment.replies.each do |reply| %> | |
28 | + <%= render :partial => 'comment', :locals => { :comment => reply } %> | |
29 | + <% end %> | |
30 | + </ul> | |
31 | + <% end %> | |
32 | + </td> | |
33 | +</table> | ... | ... |
... | ... | @@ -0,0 +1,27 @@ |
1 | +<table> | |
2 | +<tr> | |
3 | + <td> | |
4 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | |
5 | + </td> | |
6 | + <td> | |
7 | + <p style="width:550px"> | |
8 | + <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> | |
9 | + <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> | |
10 | + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
11 | + </p> | |
12 | + <p> | |
13 | + <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> | |
14 | + <br/> | |
15 | + <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span> | |
16 | + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') %> | |
17 | + </p> | |
18 | + <p><%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %></p> | |
19 | + </td> | |
20 | +</tr> | |
21 | +<tr> | |
22 | + <td></td> | |
23 | + <td> | |
24 | + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> | |
25 | + </td> | |
26 | +</tr> | |
27 | +</table> | ... | ... |
app/views/person_notifier/mailer/_default_activity.rhtml
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +<table> | |
2 | +<tr> | |
3 | + <td> | |
4 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | |
5 | + </td> | |
6 | + <td> | |
7 | + <p style="width:550px"> | |
8 | + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> | |
9 | + <span style="font-size: 10px; color: #444444; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
10 | + </p> | |
11 | + </td> | |
12 | +</tr> | |
13 | +<tr> | |
14 | + <td></td> | |
15 | + <td> | |
16 | + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %> | |
17 | + </td> | |
18 | +</tr> | |
19 | +</table> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> | ... | ... |
app/views/person_notifier/mailer/_leave_scrap_to_self.rhtml
0 → 120000
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity } %> | ... | ... |
app/views/person_notifier/mailer/_profile_comments.rhtml
0 → 100644
... | ... | @@ -0,0 +1,13 @@ |
1 | +<% if activity.comments_count > 2 %> | |
2 | + <div style="font-size: 10px;"> | |
3 | + <% if activity.params['url'].blank? %> | |
4 | + <%= _("%s comments") % activity.comments_count %> | |
5 | + <% else %> | |
6 | + <%= link_to(_("View all %s comments") % activity.comments_count, activity.params['url']) %> | |
7 | + <% end %> | |
8 | + </div> | |
9 | +<% else %> | |
10 | + <ul> | |
11 | + <%= render :partial => 'comment', :collection => activity.comments %> | |
12 | + </ul> | |
13 | +<% end %> | ... | ... |
app/views/person_notifier/mailer/_reply_scrap_on_self.rhtml
0 → 120000
... | ... | @@ -0,0 +1,15 @@ |
1 | +<table> | |
2 | + <tr> | |
3 | + <td> | |
4 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | |
5 | + </td> | |
6 | + <td> | |
7 | + <p style="width:550px"> | |
8 | + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> | |
9 | + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> | |
10 | + </p> | |
11 | + </td> | |
12 | +</tr> | |
13 | +</table> | |
14 | +<div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div> | |
15 | +<br/> | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +<h3><%= _("%s's network activity") % @profile.name %></h3> | |
2 | +<br/> | |
3 | +<div> | |
4 | +<% @notifications.each do |activity| %> | |
5 | + <div style="border-left:none;border-right:none;border-top:1px solid #ccc;border-bottom:none;padding:10px;width:600px"> | |
6 | + <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %> | |
7 | + </div> | |
8 | +<% end %> | |
9 | +</div> | |
10 | + | |
11 | +<div style="color:#444444;font-size:11px;"> | |
12 | +<p><%= _("Greetings,") %></p> | |
13 | +<br/> | |
14 | +<p>--</p> | |
15 | +<p><%= _('%s team.') % @environment %></p> | |
16 | +<p><%= url_for @url %></p> | |
17 | +</div> | |
18 | +<br/> | ... | ... |
app/views/profile_editor/_person.html.erb
... | ... | @@ -19,3 +19,8 @@ |
19 | 19 | <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> |
20 | 20 | |
21 | 21 | <%= render :partial => 'person_form', :locals => {:f => f} %> |
22 | + | |
23 | + <h2><%= _('Notification options') %></h2> | |
24 | + <div> | |
25 | + <%= select_tag 'profile_data[notification_time]', options_for_select([[_('Disabled'), 0], [_('Hourly'), 1], [_('Half Day'), 12], [_('Daily'), 24]], @profile.notification_time) %> | |
26 | + </div> | ... | ... |
app/views/profile_editor/_person_form.html.erb
... | ... | @@ -19,8 +19,8 @@ |
19 | 19 | <%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), '<div class="select-birth-date">' + pick_date(:profile_data, :birth_date, {:start_year => (Date.today.year - 100), :end_year => (Date.today.year - 5)}) + '</div>')) %> |
20 | 20 | <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> |
21 | 21 | <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> |
22 | -<%= optional_field(@person, 'state', f.text_field(:state, :rel => _('State'))) %> | |
23 | -<%= optional_field(@person, 'city', f.text_field(:city, :rel => _('City'))) %> | |
22 | +<%= optional_field(@person, 'state', f.text_field(:state, :id => 'state_field', :rel => _('State'))) %> | |
23 | +<%= optional_field(@person, 'city', f.text_field(:city, :id => 'city_field', :rel => _('City'))) %> | |
24 | 24 | <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> |
25 | 25 | <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> |
26 | 26 | <%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %> |
... | ... | @@ -36,6 +36,7 @@ |
36 | 36 | </div> |
37 | 37 | <% end %> |
38 | 38 | |
39 | +<%= javascript_include_tag('city_state_validation') %> | |
39 | 40 | <script type='text/javascript'> |
40 | 41 | function toggle_text_field(id, span_id) { |
41 | 42 | if ($(id).value == "Others") { | ... | ... |
app/views/shared/_organization_custom_fields.html.erb
... | ... | @@ -13,8 +13,8 @@ |
13 | 13 | <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> |
14 | 14 | <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> |
15 | 15 | <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> |
16 | -<%= optional_field(profile, 'city', f.text_field(:city)) %> | |
17 | -<%= optional_field(profile, 'state', f.text_field(:state)) %> | |
16 | +<%= optional_field(profile, 'city', f.text_field(:city, :id =>'city_field')) %> | |
17 | +<%= optional_field(profile, 'state', f.text_field(:state,:id =>'state_field')) %> | |
18 | 18 | <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %> |
19 | 19 | <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %> |
20 | 20 | |
... | ... | @@ -29,3 +29,4 @@ |
29 | 29 | <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %> |
30 | 30 | <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %> |
31 | 31 | <% end %> |
32 | +<%= javascript_include_tag('city_state_validation') %> | ... | ... |
app/views/shared/_select_categories.html.erb
1 | -<div id="category-ajax-selector"> | |
1 | +<% extend CategoriesHelper %> | |
2 | + | |
2 | 3 | <% if !@current_category.nil? %> |
3 | - <h3 class="box-title"><%= _('Current category:') %></h3> | |
4 | 4 | <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> |
5 | + <%= hidden_field_tag "#{object_name}[category_ids][]", @current_category.id if multiple %> | |
6 | + <%= button_to_remote_without_text(:back, _('Back'), | |
7 | + { :update => "select-categories", | |
8 | + :url => { :action => 'update_categories', :id => @object }, | |
9 | + :loaded => visual_effect(:highlight, "select-categories") | |
10 | + }, | |
11 | + :id => 'cancel-category-button') %> | |
5 | 12 | <% |
6 | 13 | categories = [@current_category] |
7 | 14 | categories.push(@current_category) while @current_category = @current_category.parent |
8 | 15 | %> |
9 | 16 | <%= categories.compact.reverse.map{|i| |
10 | - link_to_remote(i.name, | |
17 | + link_to_remote(i.name, | |
11 | 18 | :update => "select-categories", |
12 | 19 | :url => { :action => 'update_categories', :category_id => i.id, :id => @object }, |
13 | 20 | :loaded => visual_effect(:highlight, "select-categories"), |
14 | 21 | :class => 'select-current-category-link')}.join(' → ') |
15 | 22 | %> |
16 | - <strong> | |
17 | - <%= button_to_function_without_text(:save, _('Save'), nil, :id => 'save-category-button') do |page| | |
18 | - page.insert_html :bottom, 'selected-categories', content_tag('li', categories.first.full_name + | |
23 | + <%= button_to_function_without_text(:add, _('Add'), nil, :id => 'save-category-button') do |page| | |
24 | + page.insert_html :bottom, 'selected-categories', content_tag('div', | |
19 | 25 | hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + |
20 | - button_to_function_without_text(:cancel, _('Remove'), nil, :id => "remove-selected-category-#{categories.first.id}-button") {|page| page["selected-category-#{categories.first.id}"].remove}, :id => "selected-category-#{categories.first.id}") | |
26 | + selected_category_link(categories.first), :id => "selected-category-#{categories.first.id}") | |
27 | + page.replace_html 'select-categories', :partial => 'shared/select_subcategories', | |
28 | + :locals => {:object_name => object_name, :categories => @toplevel_categories} | |
21 | 29 | end if multiple %> |
22 | - <%= button_to_remote_without_text(:cancel, _('Cancel'), | |
23 | - { :update => "select-categories", | |
24 | - :url => { :action => 'update_categories', :id => @object }, | |
25 | - :loaded => visual_effect(:highlight, "select-categories") | |
26 | - }, | |
27 | - :id => 'cancel-category-button') %> | |
28 | - </strong> | |
29 | -<% else %> | |
30 | - <h3 class="box-title"><%= _('Select a category:') %></h3> | |
31 | 30 | <% end %> |
32 | 31 | |
33 | -<% if !@categories.empty? %> | |
34 | - <h3><%= _('Categories:') %></h3> | |
35 | - <% @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)}.each do |category| %> | |
36 | - <%= link_to_remote category.name, | |
37 | - { :update => "select-categories", | |
38 | - :url => { :action => "update_categories", :category_id => category.id, :id => @object}, | |
39 | - :loaded => visual_effect(:highlight, "select-categories") | |
40 | - }, | |
41 | - :class => 'select-subcategory-link', | |
42 | - :id => "select-category-#{category.id}-link" | |
43 | - %> | |
44 | - <% end %> | |
45 | -<% end %> | |
32 | +<div class="toplevel-categories"> | |
33 | + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %> | |
46 | 34 | </div> | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +<% categories_selected ||= nil %> | |
2 | +<% title ||= nil %> | |
3 | + | |
4 | +<% extend CategoriesHelper %> | |
5 | + | |
6 | +<%= content_tag "h#{title_size}", title, :class => "box-title" %> | |
7 | + | |
8 | +<%= hidden_field_tag "#{object_name}[category_ids][]", nil %> | |
9 | + | |
10 | +<div id="category-ajax-selector"> | |
11 | +<% unless categories_selected.nil? %> | |
12 | +<div id="selected-categories"> | |
13 | + <div class="label"><%= _('Selected categories:') %></div> | |
14 | + <% categories_selected.each do |cat| %> | |
15 | + <div id="selected-category-<%= cat.id %>"> | |
16 | + <%= hidden_field_tag("#{object_name}[category_ids][]", cat.id) %> | |
17 | + <%= selected_category_link(cat) %> | |
18 | + </div> | |
19 | + <% end %> | |
20 | +</div> | |
21 | +<% end %> | |
22 | +<div id="select-categories"> | |
23 | + <%= render :partial => 'shared/select_categories', :locals => {:object_name => object_name, :multiple => true, :categories_selected => categories_selected }, :layout => false %> | |
24 | +</div> | |
25 | + | |
26 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +<% if !categories.nil? && !categories.empty? && !@object.nil? %> | |
2 | + <hr> | |
3 | + <div class="category-helper-label"><%= _('Click to select a category') %></div> | |
4 | + | |
5 | + <% categories.select{|i| @object.accept_category?(i)}.each do |category| %> | |
6 | + | |
7 | + <%= link_to_remote category.name, | |
8 | + { :update => "select-categories", | |
9 | + :url => { :action => "update_categories", :category_id => category.id, :id => @object}, | |
10 | + :loaded => visual_effect(:highlight, "select-categories") | |
11 | + }, | |
12 | + :class => 'select-subcategory-link', | |
13 | + :id => "select-category-#{category.id}-link" | |
14 | + %> | |
15 | + <% end %> | |
16 | +<% end %> | ... | ... |
app/views/shared/block.html.erb
app/views/themes/_select_template.html.erb
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | "/designs/templates/#{template.id}/thumbnail.png", |
13 | 13 | :alt => _('The "%s" template')) + |
14 | 14 | '<div class="opt-info">'.html_safe + |
15 | - content_tag('strong', template.name, :class => 'name') + | |
15 | + content_tag('strong', template.name, :title => template.title, :class => 'name') + | |
16 | 16 | ' <br/> '.html_safe |
17 | 17 | |
18 | 18 | if @current_template == template.id # selected | ... | ... |
app/views/user/mailer/activation_code.html.erb
1 | 1 | <%= _('Hi, %{recipient}!') % { :recipient => @recipient } %> |
2 | 2 | |
3 | -<%= word_wrap(_('Welcome to %{environment}! To activate your account, follow the link: %{activation_url}') % { :environment => @environment, :activation_url => @url + url_for(:controller => :account, :action => :activate, :activation_code => @activation_code) }) %> | |
3 | +<%= word_wrap(_('Welcome to %{environment}! To activate your account, follow the link: %{activation_url}') % { :environment => @environment, :activation_url => @url + url_for(:controller => :account, :action => :activate, :activation_code => @activation_code, :redirection => @redirection) }) %> | |
4 | 4 | |
5 | 5 | <%= _("Greetings,") %> |
6 | 6 | ... | ... |
app/views/users/_users_list.html.erb
1 | 1 | <div class="environment-users-results-header"> |
2 | - <div id='environment-users-filter-title'><%= users_filter_title(@filter) %></div> | |
2 | + <div id='environment-users-filter-title'><%= filter_title(@filter) %></div> | |
3 | 3 | <%= filter_selector(@filter) %> |
4 | 4 | <div style="clear: both"></div> |
5 | 5 | </div> |
... | ... | @@ -19,16 +19,17 @@ |
19 | 19 | <td class='actions'> |
20 | 20 | <div class="members-buttons-cell"> |
21 | 21 | <% if p.is_admin? %> |
22 | - <%= button_without_text :'reset-admin-role', _('Reset admin role'), :action => 'reset_admin_role', :id => p, :q => @q, :filter => @filter %> | |
22 | + <%= button_without_text :'reset-admin-role', _('Reset admin role'), {:action => 'reset_admin_role', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to reset this user as administrator?") %> | |
23 | 23 | <% else %> |
24 | - <%= button_without_text :'set-admin-role', _('Set admin role'), :action => 'set_admin_role', :id => p, :q => @q, :filter => @filter %> | |
24 | + <%= button_without_text :'set-admin-role', _('Set admin role'), {:action => 'set_admin_role', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to set this user as administrator?") %> | |
25 | 25 | <% end %> |
26 | 26 | <% if !p.user.activated? %> |
27 | - <%= button_without_text :'activate-user', _('Activate user'), :action => 'activate', :id => p, :q => @q, :filter => @filter %> | |
27 | + <%= button_without_text :'activate-user', _('Activate user'), {:action => 'activate', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to activate this user?") %> | |
28 | 28 | <% else %> |
29 | - <%= button_without_text :'deactivate-user', _('Deactivate user'), :action => 'deactivate', :id => p, :q => @q, :filter => @filter %> | |
29 | + <%= button_without_text :'deactivate-user', _('Deactivate user'), {:action => 'deactivate', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to deactivate this user?") %> | |
30 | 30 | <% end %> |
31 | - </div> | |
31 | + <%= button_without_text :'delete', _('Remove'), {:action => :destroy_user, :id => p, :q => @q}, :method => :post, :filter => @filter, :confirm => _("Do you want to remove this user?") %> | |
32 | + </div> | |
32 | 33 | </td> |
33 | 34 | </tr> |
34 | 35 | <% end %> | ... | ... |
... | ... | @@ -0,0 +1,6 @@ |
1 | +if Delayed::Backend::ActiveRecord::Job.table_exists? | |
2 | + job = Delayed::Backend::ActiveRecord::Job.all :conditions => ['handler LIKE ?', "%ActivitiesCounterCacheJob%"] | |
3 | + if job.blank? | |
4 | + Delayed::Backend::ActiveRecord::Job.enqueue(ActivitiesCounterCacheJob.new, -3) | |
5 | + end | |
6 | +end | ... | ... |
config/initializers/delayed_job_config.rb
1 | 1 | require 'delayed_job' |
2 | 2 | Delayed::Worker.backend = :active_record |
3 | 3 | Delayed::Worker.max_attempts = 2 |
4 | -Delayed::Worker.max_run_time = 10.minutes | |
4 | + | |
5 | +# TODO This is consuming ton of space on development with a postgres connection | |
6 | +# error on the jobs. This must be verified before going into production. | |
7 | +# Logging jobs backtraces | |
8 | +#class Delayed::Worker | |
9 | +# def handle_failed_job_with_loggin(job, error) | |
10 | +# handle_failed_job_without_loggin(job,error) | |
11 | +# Delayed::Worker.logger.error(error.message) | |
12 | +# Delayed::Worker.logger.error(error.backtrace.join("\n")) | |
13 | +# end | |
14 | +# alias_method_chain :handle_failed_job, :loggin | |
15 | +#end | ... | ... |