Commit 1182476c928ed1bd9d07130ae292298eb8236526

Authored by Victor Costa
2 parents b1a79e13 d5f224bb

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.

@@ -7,6 +7,7 @@ Developers @@ -7,6 +7,7 @@ Developers
7 ========== 7 ==========
8 8
9 Alan Freihof Tygel <alantygel@gmail.com> 9 Alan Freihof Tygel <alantygel@gmail.com>
  10 +alcampelo <alcampelo@alcampelo.(none)>
10 Alessandro Palmeira <alessandro.palmeira@gmail.com> 11 Alessandro Palmeira <alessandro.palmeira@gmail.com>
11 Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> 12 Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
12 Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> 13 Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
@@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva &lt;alessandro.palmeira@gmail.com&gt; @@ -38,6 +39,7 @@ Alessandro Palmeira + João M. M. Silva &lt;alessandro.palmeira@gmail.com&gt;
38 Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> 39 Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com>
39 Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> 40 Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com>
40 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> 41 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
  42 +Ana Losnak <analosnak@gmail.com>
41 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> 43 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
42 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> 44 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
43 Antonio Terceiro <terceiro@colivre.coop.br> 45 Antonio Terceiro <terceiro@colivre.coop.br>
@@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo &lt;rr.manzo@gmail.com&gt; @@ -85,6 +87,7 @@ Daniel Alves + Rafael Manzo &lt;rr.manzo@gmail.com&gt;
85 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> 87 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
86 Daniel Bucher <daniel.bucher88@gmail.com> 88 Daniel Bucher <daniel.bucher88@gmail.com>
87 Daniel Cunha <daniel@colivre.coop.br> 89 Daniel Cunha <daniel@colivre.coop.br>
  90 +David Carlos <ddavidcarlos1392@gmail.com>
88 diegoamc <diegoamc90@gmail.com> 91 diegoamc <diegoamc90@gmail.com>
89 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> 92 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
90 Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> 93 Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
@@ -114,12 +117,16 @@ Diego Martinez &lt;diegoamc90@gmail.com&gt; @@ -114,12 +117,16 @@ Diego Martinez &lt;diegoamc90@gmail.com&gt;
114 Diego Martinez <diego@diego-K55A.(none)> 117 Diego Martinez <diego@diego-K55A.(none)>
115 Diego + Renan <renanteruoc@gmail.com> 118 Diego + Renan <renanteruoc@gmail.com>
116 Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> 119 Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br>
  120 +Fabio Teixeira <fabio1079@gmail.com>
117 Fernanda Lopes <nanda.listas+psl@gmail.com> 121 Fernanda Lopes <nanda.listas+psl@gmail.com>
118 Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> 122 Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
119 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> 123 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)>
120 Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> 124 Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br>
121 Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> 125 Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com>
  126 +Gabriela Navarro <navarro1703@gmail.com>
122 Grazieno Pellegrino <grazieno@gmail.com> 127 Grazieno Pellegrino <grazieno@gmail.com>
  128 +Gust <darksshades@hotmail.com>
  129 +Hugo Melo <hugo@riseup.net>
123 Isaac Canan <isaac@intelletto.com.br> 130 Isaac Canan <isaac@intelletto.com.br>
124 Italo Valcy <italo@dcc.ufba.br> 131 Italo Valcy <italo@dcc.ufba.br>
125 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> 132 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
@@ -202,6 +209,7 @@ Renan Teruo + Diego Araujo &lt;renanteruoc@gmail.com&gt; @@ -202,6 +209,7 @@ Renan Teruo + Diego Araujo &lt;renanteruoc@gmail.com&gt;
202 Renan Teruo + Diego Araújo <renanteruoc@gmail.com> 209 Renan Teruo + Diego Araújo <renanteruoc@gmail.com>
203 Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> 210 Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com>
204 Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> 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 Rodrigo Souto <diguliu@gmail.com> 213 Rodrigo Souto <diguliu@gmail.com>
206 Rodrigo Souto <rodrigo@colivre.coop.br> 214 Rodrigo Souto <rodrigo@colivre.coop.br>
207 Ronny Kursawe <kursawe.ronny@googlemail.com> 215 Ronny Kursawe <kursawe.ronny@googlemail.com>
app/controllers/admin/environment_design_controller.rb
@@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController @@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController
3 protect 'edit_environment_design', :environment 3 protect 'edit_environment_design', :environment
4 4
5 def available_blocks 5 def available_blocks
  6 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  7 + # the Noosfero core soon, see ActionItem3045
6 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] 8 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
7 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) 9 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
8 end 10 end
app/controllers/admin/users_controller.rb
@@ -45,6 +45,20 @@ class UsersController &lt; AdminController @@ -45,6 +45,20 @@ class UsersController &lt; AdminController
45 redirect_to :action => :index, :q => params[:q], :filter => params[:filter] 45 redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
46 end 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 def download 62 def download
49 respond_to do |format| 63 respond_to do |format|
50 format.html 64 format.html
app/controllers/box_organizer_controller.rb
@@ -80,6 +80,22 @@ class BoxOrganizerController &lt; ApplicationController @@ -80,6 +80,22 @@ class BoxOrganizerController &lt; ApplicationController
80 render :action => 'edit', :layout => false 80 render :action => 'edit', :layout => false
81 end 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 def save 99 def save
84 @block = boxes_holder.blocks.find(params[:id]) 100 @block = boxes_holder.blocks.find(params[:id])
85 @block.update_attributes(params[:block]) 101 @block.update_attributes(params[:block])
@@ -99,6 +115,12 @@ class BoxOrganizerController &lt; ApplicationController @@ -99,6 +115,12 @@ class BoxOrganizerController &lt; ApplicationController
99 end 115 end
100 end 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 protected :boxes_editor? 124 protected :boxes_editor?
103 125
104 end 126 end
app/controllers/embed_controller.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -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 &lt; MyProfileController @@ -24,10 +24,16 @@ class CmsController &lt; MyProfileController
24 (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) 24 (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
25 end 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 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) 28 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))
29 end 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 protect_if :only => [:destroy, :publish] do |c, user, profile| 37 protect_if :only => [:destroy, :publish] do |c, user, profile|
32 profile.articles.find(c.params[:id]).allow_post_content?(user) 38 profile.articles.find(c.params[:id]).allow_post_content?(user)
33 end 39 end
@@ -220,11 +226,10 @@ class CmsController &lt; MyProfileController @@ -220,11 +226,10 @@ class CmsController &lt; MyProfileController
220 226
221 def update_categories 227 def update_categories
222 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new 228 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new
  229 + @categories = @toplevel_categories = environment.top_level_categories
223 if params[:category_id] 230 if params[:category_id]
224 @current_category = Category.find(params[:category_id]) 231 @current_category = Category.find(params[:category_id])
225 @categories = @current_category.children 232 @categories = @current_category.children
226 - else  
227 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
228 end 233 end
229 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false 234 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false
230 end 235 end
app/controllers/my_profile/maps_controller.rb
@@ -31,23 +31,11 @@ class MapsController &lt; MyProfileController @@ -31,23 +31,11 @@ class MapsController &lt; MyProfileController
31 end 31 end
32 32
33 def search_city 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 end 35 end
42 36
43 def search_state 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 end 39 end
52 40
53 end 41 end
app/controllers/my_profile/profile_design_controller.rb
@@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController
55 blocks 55 blocks
56 end 56 end
57 57
58 - def clone  
59 - block = Block.find(params[:id])  
60 - block.duplicate  
61 - redirect_to :action => 'index'  
62 - end  
63 -  
64 end 58 end
app/controllers/my_profile/profile_editor_controller.rb
@@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController @@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController
55 55
56 def update_categories 56 def update_categories
57 @object = profile 57 @object = profile
  58 + @categories = @toplevel_categories = environment.top_level_categories
58 if params[:category_id] 59 if params[:category_id]
59 @current_category = Category.find(params[:category_id]) 60 @current_category = Category.find(params[:category_id])
60 @categories = @current_category.children 61 @categories = @current_category.children
61 - else  
62 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
63 end 62 end
64 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false 63 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false
65 end 64 end
app/controllers/public/account_controller.rb
@@ -69,6 +69,8 @@ class AccountController &lt; ApplicationController @@ -69,6 +69,8 @@ class AccountController &lt; ApplicationController
69 session[:notice] = _("This environment doesn't allow user registration.") 69 session[:notice] = _("This environment doesn't allow user registration.")
70 end 70 end
71 71
  72 + store_location(request.referer) unless params[:return_to] or session[:return_to]
  73 +
72 @block_bot = !!session[:may_be_a_bot] 74 @block_bot = !!session[:may_be_a_bot]
73 @invitation_code = params[:invitation_code] 75 @invitation_code = params[:invitation_code]
74 begin 76 begin
@@ -77,6 +79,7 @@ class AccountController &lt; ApplicationController @@ -77,6 +79,7 @@ class AccountController &lt; ApplicationController
77 @user.environment = environment 79 @user.environment = environment
78 @terms_of_use = environment.terms_of_use 80 @terms_of_use = environment.terms_of_use
79 @user.person_data = params[:profile_data] 81 @user.person_data = params[:profile_data]
  82 + @user.return_to = session[:return_to]
80 @person = Person.new(params[:profile_data]) 83 @person = Person.new(params[:profile_data])
81 @person.environment = @user.environment 84 @person.environment = @user.environment
82 if request.post? 85 if request.post?
@@ -98,7 +101,7 @@ class AccountController &lt; ApplicationController @@ -98,7 +101,7 @@ class AccountController &lt; ApplicationController
98 end 101 end
99 if @user.activated? 102 if @user.activated?
100 self.current_user = @user 103 self.current_user = @user
101 - redirect_to '/' 104 + go_to_signup_initial_page
102 else 105 else
103 @register_pending = true 106 @register_pending = true
104 end 107 end
@@ -247,15 +250,19 @@ class AccountController &lt; ApplicationController @@ -247,15 +250,19 @@ class AccountController &lt; ApplicationController
247 end 250 end
248 end 251 end
249 252
250 - def check_url 253 + def check_valid_name
251 @identifier = params[:identifier] 254 @identifier = params[:identifier]
252 valid = Person.is_available?(@identifier, environment) 255 valid = Person.is_available?(@identifier, environment)
253 if valid 256 if valid
254 @status = _('This login name is available') 257 @status = _('This login name is available')
255 @status_class = 'validated' 258 @status_class = 'validated'
256 - else 259 + elsif !@identifier.empty?
  260 + @suggested_usernames = suggestion_based_on_username(@identifier)
257 @status = _('This login name is unavailable') 261 @status = _('This login name is unavailable')
258 @status_class = 'invalid' 262 @status_class = 'invalid'
  263 + else
  264 + @status_class = 'invalid'
  265 + @status = _('This field can\'t be blank')
259 end 266 end
260 render :partial => 'identifier_status' 267 render :partial => 'identifier_status'
261 end 268 end
@@ -288,6 +295,23 @@ class AccountController &lt; ApplicationController @@ -288,6 +295,23 @@ class AccountController &lt; ApplicationController
288 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" 295 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript"
289 end 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 protected 315 protected
292 316
293 def redirect? 317 def redirect?
@@ -368,32 +392,29 @@ class AccountController &lt; ApplicationController @@ -368,32 +392,29 @@ class AccountController &lt; ApplicationController
368 end 392 end
369 393
370 def go_to_initial_page 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 if params[:return_to] 401 if params[:return_to]
372 redirect_to params[:return_to] 402 redirect_to params[:return_to]
373 elsif environment.enabled?('allow_change_of_redirection_after_login') 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 else 405 else
389 if environment == current_user.environment 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 else 408 else
392 redirect_back_or_default(:controller => 'home') 409 redirect_back_or_default(:controller => 'home')
393 end 410 end
394 end 411 end
395 end 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 def redirect_if_logged_in 418 def redirect_if_logged_in
398 if logged_in? 419 if logged_in?
399 go_to_initial_page 420 go_to_initial_page
@@ -409,4 +430,22 @@ class AccountController &lt; ApplicationController @@ -409,4 +430,22 @@ class AccountController &lt; ApplicationController
409 user 430 user
410 end 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 end 451 end
app/controllers/public/content_viewer_controller.rb
@@ -52,7 +52,7 @@ class ContentViewerController &lt; ApplicationController @@ -52,7 +52,7 @@ class ContentViewerController &lt; ApplicationController
52 end 52 end
53 53
54 # At this point the page will be showed 54 # At this point the page will be showed
55 - @page.hit 55 + @page.hit unless user_is_a_bot?
56 56
57 @page = FilePresenter.for @page 57 @page = FilePresenter.for @page
58 58
@@ -113,6 +113,15 @@ class ContentViewerController &lt; ApplicationController @@ -113,6 +113,15 @@ class ContentViewerController &lt; ApplicationController
113 @comments = @plugins.filter(:unavailable_comments, @comments) 113 @comments = @plugins.filter(:unavailable_comments, @comments)
114 @comments_count = @comments.count 114 @comments_count = @comments.count
115 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) 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 if params[:slideshow] 126 if params[:slideshow]
118 render :action => 'slideshow', :layout => 'slideshow' 127 render :action => 'slideshow', :layout => 'slideshow'
@@ -178,4 +187,13 @@ class ContentViewerController &lt; ApplicationController @@ -178,4 +187,13 @@ class ContentViewerController &lt; ApplicationController
178 allowed 187 allowed
179 end 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 end 199 end
app/controllers/public/events_controller.rb
@@ -7,11 +7,11 @@ class EventsController &lt; PublicController @@ -7,11 +7,11 @@ class EventsController &lt; PublicController
7 @date = build_date(params[:year], params[:month], params[:day]) 7 @date = build_date(params[:year], params[:month], params[:day])
8 8
9 if !params[:year] && !params[:month] && !params[:day] 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 end 11 end
12 12
13 if params[:year] || params[:month] 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 end 15 end
16 16
17 events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month) 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 &lt; PublicController @@ -21,7 +21,7 @@ class EventsController &lt; PublicController
21 21
22 def events_by_day 22 def events_by_day
23 @date = build_date(params[:year], params[:month], params[:day]) 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 render :partial => 'events' 25 render :partial => 'events'
26 end 26 end
27 27
@@ -29,4 +29,7 @@ class EventsController &lt; PublicController @@ -29,4 +29,7 @@ class EventsController &lt; PublicController
29 29
30 include EventsHelper 30 include EventsHelper
31 31
  32 + def per_page
  33 + 20
  34 + end
32 end 35 end
app/controllers/public/search_controller.rb
@@ -99,14 +99,14 @@ class SearchController &lt; PublicController @@ -99,14 +99,14 @@ class SearchController &lt; PublicController
99 @events = [] 99 @events = []
100 if params[:day] || !params[:year] && !params[:month] 100 if params[:day] || !params[:year] && !params[:month]
101 @events = @category ? 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 end 104 end
105 105
106 if params[:year] || params[:month] 106 if params[:year] || params[:month]
107 @events = @category ? 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 end 110 end
111 111
112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events 112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events
@@ -139,7 +139,7 @@ class SearchController &lt; PublicController @@ -139,7 +139,7 @@ class SearchController &lt; PublicController
139 139
140 def events_by_day 140 def events_by_day
141 @date = build_date(params[:year], params[:month], params[:day]) 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 render :partial => 'events/events' 143 render :partial => 'events/events'
144 end 144 end
145 145
@@ -224,4 +224,8 @@ class SearchController &lt; PublicController @@ -224,4 +224,8 @@ class SearchController &lt; PublicController
224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations) 224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations)
225 end 225 end
226 226
  227 + def per_page
  228 + 20
  229 + end
  230 +
227 end 231 end
app/controllers/themes_controller.rb
@@ -12,7 +12,7 @@ class ThemesController &lt; ApplicationController @@ -12,7 +12,7 @@ class ThemesController &lt; ApplicationController
12 12
13 def index 13 def index
14 @environment = environment 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 @current_theme = target.theme 17 @current_theme = target.theme
18 18
app/helpers/account_helper.rb
@@ -12,4 +12,17 @@ module AccountHelper @@ -12,4 +12,17 @@ module AccountHelper
12 _('Checking if e-mail address is already taken...') 12 _('Checking if e-mail address is already taken...')
13 end 13 end
14 end 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 end 28 end
app/helpers/application_helper.rb
@@ -605,49 +605,18 @@ module ApplicationHelper @@ -605,49 +605,18 @@ module ApplicationHelper
605 end 605 end
606 606
607 attr_reader :environment 607 attr_reader :environment
  608 +
608 def select_categories(object_name, title=nil, title_size=4) 609 def select_categories(object_name, title=nil, title_size=4)
609 return nil if environment.enabled?(:disable_categories) 610 return nil if environment.enabled?(:disable_categories)
610 if title.nil? 611 if title.nil?
611 title = _('Categories') 612 title = _('Categories')
612 end 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, " &rarr; "),  
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 end 620 end
652 621
653 def theme_option(opt = nil) 622 def theme_option(opt = nil)
@@ -934,12 +903,11 @@ module ApplicationHelper @@ -934,12 +903,11 @@ module ApplicationHelper
934 903
935 def page_title 904 def page_title
936 (@page ? @page.title + ' - ' : '') + 905 (@page ? @page.title + ' - ' : '') +
937 - (profile ? profile.short_name + ' - ' : '') +  
938 (@topic ? @topic.title + ' - ' : '') + 906 (@topic ? @topic.title + ' - ' : '') +
939 (@section ? @section.title + ' - ' : '') + 907 (@section ? @section.title + ' - ' : '') +
940 (@toc ? _('Online Manual') + ' - ' : '') + 908 (@toc ? _('Online Manual') + ' - ' : '') +
941 (controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + 909 (controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') +
942 - environment.name + 910 + (profile ? profile.short_name : environment.name) +
943 (@category ? " - #{@category.full_name}" : '') 911 (@category ? " - #{@category.full_name}" : '')
944 end 912 end
945 913
app/helpers/article_helper.rb
@@ -50,8 +50,14 @@ module ArticleHelper @@ -50,8 +50,14 @@ module ArticleHelper
50 'div', 50 'div',
51 check_box(:article, :display_versions) + 51 check_box(:article, :display_versions) +
52 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') 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 end 62 end
57 63
app/helpers/boxes_helper.rb
@@ -65,7 +65,7 @@ module BoxesHelper @@ -65,7 +65,7 @@ module BoxesHelper
65 end 65 end
66 66
67 def display_box_content(box, main_content) 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 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) 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 end 70 end
71 71
@@ -212,13 +212,24 @@ module BoxesHelper @@ -212,13 +212,24 @@ module BoxesHelper
212 212
213 if !block.main? 213 if !block.main?
214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) 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 end 216 end
217 217
218 if block.respond_to?(:help) 218 if block.respond_to?(:help)
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}") 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 end 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 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') 233 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar')
223 end 234 end
224 235
app/helpers/cache_counter_helper.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +module CacheCounterHelper
  2 + def update_cache_counter(name, object, value)
  3 + if object.present?
  4 + object.class.update_counters(object.id, name => value)
  5 + end
  6 + end
  7 +end
app/helpers/categories_helper.rb
@@ -48,4 +48,12 @@ module CategoriesHelper @@ -48,4 +48,12 @@ module CategoriesHelper
48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) 48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value)))
49 end 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(' &rarr; '), 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 end 59 end
app/helpers/comment_helper.rb
@@ -2,7 +2,6 @@ module CommentHelper @@ -2,7 +2,6 @@ module CommentHelper
2 2
3 def article_title(article, args = {}) 3 def article_title(article, args = {})
4 title = article.title 4 title = article.title
5 - title = article.display_title if article.kind_of?(UploadedFile) && article.image?  
6 title = content_tag('h1', h(title), :class => 'title') 5 title = content_tag('h1', h(title), :class => 'title')
7 if article.belongs_to_blog? 6 if article.belongs_to_blog?
8 unless args[:no_link] 7 unless args[:no_link]
@@ -22,6 +21,12 @@ module CommentHelper @@ -22,6 +21,12 @@ module CommentHelper
22 title 21 title
23 end 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 def comment_actions(comment) 30 def comment_actions(comment)
26 url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) 31 url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id)
27 links = links_for_comment_actions(comment) 32 links = links_for_comment_actions(comment)
app/helpers/content_viewer_helper.rb
@@ -14,8 +14,7 @@ module ContentViewerHelper @@ -14,8 +14,7 @@ module ContentViewerHelper
14 end 14 end
15 15
16 def article_title(article, args = {}) 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 title = content_tag('h1', h(title), :class => 'title') 18 title = content_tag('h1', h(title), :class => 'title')
20 if article.belongs_to_blog? || article.belongs_to_forum? 19 if article.belongs_to_blog? || article.belongs_to_forum?
21 unless args[:no_link] 20 unless args[:no_link]
@@ -52,15 +51,6 @@ module ContentViewerHelper @@ -52,15 +51,6 @@ module ContentViewerHelper
52 end 51 end
53 end 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 def addthis_image_tag 54 def addthis_image_tag
65 if File.exists?(Rails.root.join('public', theme_path, 'images', 'addthis.gif')) 55 if File.exists?(Rails.root.join('public', theme_path, 'images', 'addthis.gif'))
66 image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') 56 image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '')
app/helpers/layout_helper.rb
@@ -90,5 +90,8 @@ module LayoutHelper @@ -90,5 +90,8 @@ module LayoutHelper
90 end 90 end
91 end 91 end
92 92
  93 + def meta_description_tag(article=nil)
  94 + article ? truncate(strip_tags(article.body.to_s), :length => 200) : environment.name
  95 + end
93 end 96 end
94 97
app/helpers/macros_helper.rb
@@ -20,14 +20,16 @@ module MacrosHelper @@ -20,14 +20,16 @@ module MacrosHelper
20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ 20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({
21 title: #{macro_title(macro).to_json}, 21 title: #{macro_title(macro).to_json},
22 modal: true, 22 modal: true,
23 - buttons: [  
24 - {text: #{_('Ok').to_json}, click: function(){ 23 + buttons: {
  24 + #{_('Ok').to_json}: function(){
25 tinyMCE.activeEditor.execCommand('mceInsertContent', false, 25 tinyMCE.activeEditor.execCommand('mceInsertContent', false,
26 (function(dialog){ #{macro_generator(macro)} })(this)); 26 (function(dialog){ #{macro_generator(macro)} })(this));
27 jQuery(this).dialog('close'); 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 end 35 end
@@ -57,7 +59,11 @@ module MacrosHelper @@ -57,7 +59,11 @@ module MacrosHelper
57 59
58 def macro_generator(macro) 60 def macro_generator(macro)
59 if macro.configuration[:generator] 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 else 67 else
62 macro_default_generator(macro) 68 macro_default_generator(macro)
63 end 69 end
@@ -66,8 +72,7 @@ module MacrosHelper @@ -66,8 +72,7 @@ module MacrosHelper
66 72
67 def macro_default_generator(macro) 73 def macro_default_generator(macro)
68 code = "var params = {};" 74 code = "var params = {};"
69 - configuration = macro_configuration(macro)  
70 - configuration[:params].map do |field| 75 + macro.configuration[:params].map do |field|
71 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" 76 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();"
72 end 77 end
73 code + " 78 code + "
app/helpers/maps_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -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/person_notifier_helper.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +module PersonNotifierHelper
  2 +
  3 + include ApplicationHelper
  4 +
  5 + private
  6 +
  7 + def path_to_image(source)
  8 + top_url + source
  9 + end
  10 +
  11 + def top_url
  12 + top_url = @profile.environment ? @profile.environment.top_url : ''
  13 + end
  14 +
  15 +end
app/helpers/token_helper.rb
@@ -27,7 +27,7 @@ module TokenHelper @@ -27,7 +27,7 @@ module TokenHelper
27 hintText: #{options[:hint_text].to_json}, 27 hintText: #{options[:hint_text].to_json},
28 noResultsText: #{options[:no_results_text].to_json}, 28 noResultsText: #{options[:no_results_text].to_json},
29 searchingText: #{options[:searching_text].to_json}, 29 searchingText: #{options[:searching_text].to_json},
30 - searchDelay: #{options[:serach_delay].to_json}, 30 + searchDelay: #{options[:search_delay].to_json},
31 preventDuplicates: #{options[:prevent_duplicates].to_json}, 31 preventDuplicates: #{options[:prevent_duplicates].to_json},
32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, 32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json},
33 queryParam: #{name.to_json}, 33 queryParam: #{name.to_json},
app/mailers/contact.rb
@@ -46,7 +46,7 @@ class Contact @@ -46,7 +46,7 @@ class Contact
46 to: contact.dest.notification_emails, 46 to: contact.dest.notification_emails,
47 reply_to: contact.email, 47 reply_to: contact.email,
48 subject: "[#{contact.dest.short_name(30)}] " + contact.subject, 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 if contact.sender 52 if contact.sender
app/mailers/mailing.rb
@@ -20,7 +20,7 @@ class Mailing &lt; ActiveRecord::Base @@ -20,7 +20,7 @@ class Mailing &lt; ActiveRecord::Base
20 end 20 end
21 21
22 def generate_from 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 end 24 end
25 25
26 def generate_subject 26 def generate_subject
app/mailers/organization_mailing.rb
1 class OrganizationMailing < Mailing 1 class OrganizationMailing < Mailing
2 2
3 def generate_from 3 def generate_from
4 - "#{person.name} <#{source.environment.contact_email}>" 4 + "#{person.name} <#{source.environment.noreply_email}>"
5 end 5 end
6 6
7 def recipients(offset=0, limit=100) 7 def recipients(offset=0, limit=100)
app/mailers/pending_task_notifier.rb
@@ -11,7 +11,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base @@ -11,7 +11,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base
11 11
12 mail( 12 mail(
13 to: person.email, 13 to: person.email,
14 - from: "#{person.environment.name} <#{person.environment.contact_email}>", 14 + from: "#{person.environment.name} <#{person.environment.noreply_email}>",
15 subject: _("[%s] Pending tasks") % person.environment.name 15 subject: _("[%s] Pending tasks") % person.environment.name
16 ) 16 )
17 end 17 end
app/mailers/task_mailer.rb
@@ -52,7 +52,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -52,7 +52,7 @@ class TaskMailer &lt; ActionMailer::Base
52 end 52 end
53 53
54 def self.generate_from(task) 54 def self.generate_from(task)
55 - "#{task.environment.name} <#{task.environment.contact_email}>" 55 + "#{task.environment.name} <#{task.environment.noreply_email}>"
56 end 56 end
57 57
58 def generate_environment_url(task, url = {}) 58 def generate_environment_url(task, url = {})
app/models/block.rb
@@ -18,17 +18,36 @@ class Block &lt; ActiveRecord::Base @@ -18,17 +18,36 @@ class Block &lt; ActiveRecord::Base
18 18
19 scope :enabled, :conditions => { :enabled => true } 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 # Determines whether a given block must be visible. Optionally a 38 # Determines whether a given block must be visible. Optionally a
22 # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and 39 # <tt>context</tt> must be specified. <tt>context</tt> must be a hash, and
23 # may contain the following keys: 40 # may contain the following keys:
24 # 41 #
25 # * <tt>:article</tt>: the article being viewed currently 42 # * <tt>:article</tt>: the article being viewed currently
26 # * <tt>:language</tt>: in which language the block will be displayed 43 # * <tt>:language</tt>: in which language the block will be displayed
  44 + # * <tt>:user</tt>: the logged user
27 def visible?(context = nil) 45 def visible?(context = nil)
28 return false if display == 'never' 46 return false if display == 'never'
29 47
30 if context 48 if context
31 return false if language != 'all' && language != context[:locale] 49 return false if language != 'all' && language != context[:locale]
  50 + return false unless display_to_user?(context[:user])
32 51
33 begin 52 begin
34 return self.send("display_#{display}", context) 53 return self.send("display_#{display}", context)
@@ -40,6 +59,10 @@ class Block &lt; ActiveRecord::Base @@ -40,6 +59,10 @@ class Block &lt; ActiveRecord::Base
40 true 59 true
41 end 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 def display_always(context) 66 def display_always(context)
44 true 67 true
45 end 68 end
@@ -70,6 +93,14 @@ class Block &lt; ActiveRecord::Base @@ -70,6 +93,14 @@ class Block &lt; ActiveRecord::Base
70 # the homepage of its owner. 93 # the homepage of its owner.
71 settings_items :display, :type => :string, :default => 'always' 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 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: 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 # * <tt>'all'</tt>: the block is always displayed 106 # * <tt>'all'</tt>: the block is always displayed
@@ -143,7 +174,7 @@ class Block &lt; ActiveRecord::Base @@ -143,7 +174,7 @@ class Block &lt; ActiveRecord::Base
143 end 174 end
144 175
145 alias :active_record_cache_key :cache_key 176 alias :active_record_cache_key :cache_key
146 - def cache_key(language='en') 177 + def cache_key(language='en', user=nil)
147 active_record_cache_key+'-'+language 178 active_record_cache_key+'-'+language
148 end 179 end
149 180
@@ -173,12 +204,20 @@ class Block &lt; ActiveRecord::Base @@ -173,12 +204,20 @@ class Block &lt; ActiveRecord::Base
173 'never' => _('Don\'t display'), 204 'never' => _('Don\'t display'),
174 } 205 }
175 206
176 - def display_options 207 + def display_options_available
177 DISPLAY_OPTIONS.keys 208 DISPLAY_OPTIONS.keys
178 end 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 end 221 end
183 222
184 def duplicate 223 def duplicate
app/models/box.rb
@@ -28,6 +28,8 @@ class Box &lt; ActiveRecord::Base @@ -28,6 +28,8 @@ class Box &lt; ActiveRecord::Base
28 CategoriesBlock, 28 CategoriesBlock,
29 CommunitiesBlock, 29 CommunitiesBlock,
30 EnterprisesBlock, 30 EnterprisesBlock,
  31 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  32 + # the Noosfero core soon, see ActionItem3045
31 EnvironmentStatisticsBlock, 33 EnvironmentStatisticsBlock,
32 FansBlock, 34 FansBlock,
33 FavoriteEnterprisesBlock, 35 FavoriteEnterprisesBlock,
@@ -54,6 +56,8 @@ class Box &lt; ActiveRecord::Base @@ -54,6 +56,8 @@ class Box &lt; ActiveRecord::Base
54 CommunitiesBlock, 56 CommunitiesBlock,
55 DisabledEnterpriseMessageBlock, 57 DisabledEnterpriseMessageBlock,
56 EnterprisesBlock, 58 EnterprisesBlock,
  59 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  60 + # the Noosfero core soon, see ActionItem3045
57 EnvironmentStatisticsBlock, 61 EnvironmentStatisticsBlock,
58 FansBlock, 62 FansBlock,
59 FavoriteEnterprisesBlock, 63 FavoriteEnterprisesBlock,
app/models/comment.rb
@@ -170,6 +170,40 @@ class Comment &lt; ActiveRecord::Base @@ -170,6 +170,40 @@ class Comment &lt; ActiveRecord::Base
170 body || '' 170 body || ''
171 end 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 def rejected? 207 def rejected?
174 @rejected 208 @rejected
175 end 209 end
app/models/environment.rb
@@ -147,6 +147,18 @@ class Environment &lt; ActiveRecord::Base @@ -147,6 +147,18 @@ class Environment &lt; ActiveRecord::Base
147 end 147 end
148 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true 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 # Relationships and applied behaviour 163 # Relationships and applied behaviour
152 # ################################################# 164 # #################################################
@@ -163,6 +175,8 @@ class Environment &lt; ActiveRecord::Base @@ -163,6 +175,8 @@ class Environment &lt; ActiveRecord::Base
163 175
164 # "left" area 176 # "left" area
165 env.boxes[1].blocks << LoginBlock.new 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 env.boxes[1].blocks << EnvironmentStatisticsBlock.new 180 env.boxes[1].blocks << EnvironmentStatisticsBlock.new
167 env.boxes[1].blocks << RecentDocumentsBlock.new 181 env.boxes[1].blocks << RecentDocumentsBlock.new
168 182
@@ -580,7 +594,7 @@ class Environment &lt; ActiveRecord::Base @@ -580,7 +594,7 @@ class Environment &lt; ActiveRecord::Base
580 # only one environment can be the default one 594 # only one environment can be the default one
581 validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one') 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 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' 599 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation'
586 600
@@ -768,7 +782,7 @@ class Environment &lt; ActiveRecord::Base @@ -768,7 +782,7 @@ class Environment &lt; ActiveRecord::Base
768 end 782 end
769 783
770 def notification_emails 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 end 786 end
773 787
774 after_create :create_templates 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 class EnvironmentStatisticsBlock < Block 4 class EnvironmentStatisticsBlock < Block
2 5
3 def self.description 6 def self.description
4 - _('Environment stastistics') 7 + _('Environment stastistics (DEPRECATED)')
5 end 8 end
6 9
7 def default_title 10 def default_title
app/models/event.rb
@@ -43,15 +43,12 @@ class Event &lt; Article @@ -43,15 +43,12 @@ class Event &lt; Article
43 scope :next_events_from_month, lambda { |date| 43 scope :next_events_from_month, lambda { |date|
44 date_temp = date.strftime("%Y-%m-%d") 44 date_temp = date.strftime("%Y-%m-%d")
45 { :conditions => ["start_date >= ?","#{date_temp}"], 45 { :conditions => ["start_date >= ?","#{date_temp}"],
46 - :limit => 10,  
47 :order => 'start_date ASC' 46 :order => 'start_date ASC'
48 } 47 }
49 } 48 }
50 49
51 scope :by_month, lambda { |date| 50 scope :by_month, lambda { |date|
52 - date_temp = date.strftime("%Y-%m")  
53 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], 51 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month],
54 - :limit => 10,  
55 :order => 'start_date ASC' 52 :order => 'start_date ASC'
56 } 53 }
57 } 54 }
app/models/forum.rb
@@ -7,6 +7,7 @@ class Forum &lt; Folder @@ -7,6 +7,7 @@ class Forum &lt; Folder
7 7
8 settings_items :terms_of_use, :type => :string, :default => "" 8 settings_items :terms_of_use, :type => :string, :default => ""
9 settings_items :has_terms_of_use, :type => :boolean, :default => false 9 settings_items :has_terms_of_use, :type => :boolean, :default => false
  10 + settings_items :allows_members_to_create_topics, :type => :boolean, :default => false
10 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' 11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
11 12
12 before_save do |forum| 13 before_save do |forum|
@@ -68,4 +69,11 @@ class Forum &lt; Folder @@ -68,4 +69,11 @@ class Forum &lt; Folder
68 self.users_with_agreement.exists? user 69 self.users_with_agreement.exists? user
69 end 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 end 79 end
app/models/friendship.rb
1 class Friendship < ActiveRecord::Base 1 class Friendship < ActiveRecord::Base
2 track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person 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 belongs_to :person, :foreign_key => :person_id 6 belongs_to :person, :foreign_key => :person_id
5 belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' 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 end 18 end
app/models/layout_template.rb
@@ -16,15 +16,15 @@ class LayoutTemplate @@ -16,15 +16,15 @@ class LayoutTemplate
16 end 16 end
17 17
18 def name 18 def name
19 - @config['name'] 19 + _ @config['name']
20 end 20 end
21 21
22 def title 22 def title
23 - @config['title'] 23 + _ @config['title']
24 end 24 end
25 25
26 def description 26 def description
27 - @config['description'] 27 + _ @config['description']
28 end 28 end
29 29
30 def number_of_boxes 30 def number_of_boxes
app/models/link_list_block.rb
@@ -72,6 +72,8 @@ class LinkListBlock &lt; Block @@ -72,6 +72,8 @@ class LinkListBlock &lt; Block
72 def expand_address(address) 72 def expand_address(address)
73 add = if owner.respond_to?(:identifier) 73 add = if owner.respond_to?(:identifier)
74 address.gsub('{profile}', owner.identifier) 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 else 77 else
76 address 78 address
77 end 79 end
app/models/main_block.rb
@@ -24,7 +24,7 @@ class MainBlock &lt; Block @@ -24,7 +24,7 @@ class MainBlock &lt; Block
24 false 24 false
25 end 25 end
26 26
27 - def display_options 27 + def display_options_available
28 ['always', 'except_home_page'] 28 ['always', 'except_home_page']
29 end 29 end
30 30
app/models/members_block.rb
@@ -38,4 +38,15 @@ class MembersBlock &lt; ProfileListBlock @@ -38,4 +38,15 @@ class MembersBlock &lt; ProfileListBlock
38 } 38 }
39 end 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 end 52 end
app/models/national_region.rb
@@ -12,7 +12,7 @@ class NationalRegion &lt; ActiveRecord::Base @@ -12,7 +12,7 @@ class NationalRegion &lt; ActiveRecord::Base
12 adtional_contions = ""; 12 adtional_contions = "";
13 13
14 if like 14 if like
15 - operator = "like" 15 + operator = "ilike"
16 find_return = :all 16 find_return = :all
17 end 17 end
18 18
@@ -41,7 +41,7 @@ class NationalRegion &lt; ActiveRecord::Base @@ -41,7 +41,7 @@ class NationalRegion &lt; ActiveRecord::Base
41 find_return = :first 41 find_return = :first
42 42
43 if like 43 if like
44 - operator = "like" 44 + operator = "ilike"
45 find_return = :all 45 find_return = :all
46 end 46 end
47 47
app/models/organization.rb
@@ -28,18 +28,7 @@ class Organization &lt; Profile @@ -28,18 +28,7 @@ class Organization &lt; Profile
28 28
29 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' 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 def validation_methodology 33 def validation_methodology
45 self.validation_info ? self.validation_info.validation_methodology : nil 34 self.validation_info ? self.validation_info.validation_methodology : nil
app/models/person.rb
@@ -59,18 +59,7 @@ class Person &lt; Profile @@ -59,18 +59,7 @@ class Person &lt; Profile
59 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' 59 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
60 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' 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 scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' 64 scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*'
76 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.*" 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 &lt; Profile @@ -492,6 +481,17 @@ class Person &lt; Profile
492 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) 481 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default)
493 end 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 protected 495 protected
496 496
497 def followed_by?(profile) 497 def followed_by?(profile)
app/models/person_notifier.rb 0 → 100644
@@ -0,0 +1,89 @@ @@ -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 &lt; ActiveRecord::Base @@ -100,10 +100,6 @@ class Profile &lt; ActiveRecord::Base
100 members.order(:name) 100 members.order(:name)
101 end 101 end
102 102
103 - def members_count  
104 - members.count  
105 - end  
106 -  
107 class << self 103 class << self
108 def count_with_distinct(*args) 104 def count_with_distinct(*args)
109 options = args.last || {} 105 options = args.last || {}
@@ -126,10 +122,11 @@ class Profile &lt; ActiveRecord::Base @@ -126,10 +122,11 @@ class Profile &lt; ActiveRecord::Base
126 122
127 scope :visible, :conditions => { :visible => true } 123 scope :visible, :conditions => { :visible => true }
128 scope :public, :conditions => { :visible => true, :public_profile => true } 124 scope :public, :conditions => { :visible => true, :public_profile => true }
129 - # Subclasses must override these methods 125 +
  126 + # Subclasses must override this method
130 scope :more_popular 127 scope :more_popular
131 - scope :more_active  
132 128
  129 + scope :more_active, :order => 'activities_count DESC'
133 scope :more_recent, :order => "created_at DESC" 130 scope :more_recent, :order => "created_at DESC"
134 131
135 acts_as_trackable :dependent => :destroy 132 acts_as_trackable :dependent => :destroy
@@ -626,10 +623,10 @@ private :generate_url, :url_options @@ -626,10 +623,10 @@ private :generate_url, :url_options
626 # Adds a person as member of this Profile. 623 # Adds a person as member of this Profile.
627 def add_member(person) 624 def add_member(person)
628 if self.has_members? 625 if self.has_members?
629 - if self.closed? && members_count > 0 626 + if self.closed? && members.count > 0
630 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) 627 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
631 else 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 self.affiliate(person, Profile::Roles.member(environment.id)) 630 self.affiliate(person, Profile::Roles.member(environment.id))
634 end 631 end
635 else 632 else
app/models/scrap.rb
@@ -17,7 +17,7 @@ class Scrap &lt; ActiveRecord::Base @@ -17,7 +17,7 @@ class Scrap &lt; ActiveRecord::Base
17 17
18 scope :not_replies, :conditions => {:scrap_id => nil} 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 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} 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 &lt; ActiveRecord::Base @@ -57,4 +57,21 @@ class Scrap &lt; ActiveRecord::Base
57 sender != receiver && (is_root? ? root.receiver.receives_scrap_notification? : receiver.receives_scrap_notification?) 57 sender != receiver && (is_root? ? root.receiver.receives_scrap_notification? : receiver.receives_scrap_notification?)
58 end 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 end 77 end
app/models/text_article.rb
@@ -22,4 +22,23 @@ class TextArticle &lt; Article @@ -22,4 +22,23 @@ class TextArticle &lt; Article
22 def can_display_versions? 22 def can_display_versions?
23 true 23 true
24 end 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 end 44 end
app/models/theme.rb
@@ -42,17 +42,25 @@ class Theme @@ -42,17 +42,25 @@ class Theme
42 end 42 end
43 43
44 def approved_themes(owner) 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 end 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 end 62 end
54 end 63 end
55 -  
56 end 64 end
57 65
58 class DuplicatedIdentifier < Exception; end 66 class DuplicatedIdentifier < Exception; end
app/models/uploaded_file.rb
@@ -16,15 +16,12 @@ class UploadedFile &lt; Article @@ -16,15 +16,12 @@ class UploadedFile &lt; Article
16 16
17 include ShortFilename 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 end 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 sanitize_filename 26 sanitize_filename
30 27
@@ -36,10 +33,6 @@ class UploadedFile &lt; Article @@ -36,10 +33,6 @@ class UploadedFile &lt; Article
36 self.image? ? self.full_filename(:display).to_s.gsub(Rails.root.join('public').to_s, '') : nil 33 self.image? ? self.full_filename(:display).to_s.gsub(Rails.root.join('public').to_s, '') : nil
37 end 34 end
38 35
39 - def display_title  
40 - title.blank? ? name : title  
41 - end  
42 -  
43 def first_paragraph 36 def first_paragraph
44 '' 37 ''
45 end 38 end
@@ -113,7 +106,7 @@ class UploadedFile &lt; Article @@ -113,7 +106,7 @@ class UploadedFile &lt; Article
113 alias :orig_set_filename :filename= 106 alias :orig_set_filename :filename=
114 def filename=(value) 107 def filename=(value)
115 orig_set_filename(value) 108 orig_set_filename(value)
116 - self.name = self.filename 109 + self.name ||= self.filename
117 end 110 end
118 111
119 def download_headers 112 def download_headers
app/models/user.rb
@@ -63,6 +63,44 @@ class User &lt; ActiveRecord::Base @@ -63,6 +63,44 @@ class User &lt; ActiveRecord::Base
63 self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) 63 self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true)
64 end 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 def signup! 104 def signup!
67 User.transaction do 105 User.transaction do
68 self.save! 106 self.save!
@@ -159,7 +197,7 @@ class User &lt; ActiveRecord::Base @@ -159,7 +197,7 @@ class User &lt; ActiveRecord::Base
159 encryption_methods[sym] = block 197 encryption_methods[sym] = block
160 end 198 end
161 199
162 - # the encryption method used for this instance 200 + # the encryption method used for this instance
163 def encryption_method 201 def encryption_method
164 (password_type || User.system_encryption_method).to_sym 202 (password_type || User.system_encryption_method).to_sym
165 end 203 end
@@ -202,7 +240,7 @@ class User &lt; ActiveRecord::Base @@ -202,7 +240,7 @@ class User &lt; ActiveRecord::Base
202 end 240 end
203 241
204 def remember_token? 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 end 244 end
207 245
208 # These create and unset the fields required for remembering users between browser closes 246 # These create and unset the fields required for remembering users between browser closes
@@ -231,7 +269,7 @@ class User &lt; ActiveRecord::Base @@ -231,7 +269,7 @@ class User &lt; ActiveRecord::Base
231 raise IncorrectPassword unless self.authenticated?(current) 269 raise IncorrectPassword unless self.authenticated?(current)
232 self.force_change_password!(new, confirmation) 270 self.force_change_password!(new, confirmation)
233 end 271 end
234 - 272 +
235 # Changes the password of a user without asking for the old password. This 273 # Changes the password of a user without asking for the old password. This
236 # method is intended to be used by the "I forgot my password", and must be 274 # method is intended to be used by the "I forgot my password", and must be
237 # used with care. 275 # used with care.
@@ -302,7 +340,7 @@ class User &lt; ActiveRecord::Base @@ -302,7 +340,7 @@ class User &lt; ActiveRecord::Base
302 end 340 end
303 341
304 protected 342 protected
305 - # before filter 343 + # before filter
306 def encrypt_password 344 def encrypt_password
307 return if password.blank? 345 return if password.blank?
308 self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? 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 # &lt; ActiveRecord::Observer @@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer
8 end 8 end
9 9
10 def after_create(profile) 10 def after_create(profile)
  11 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  12 + # the Noosfero core soon, see ActionItem3045
11 expire_statistics_block_cache(profile) 13 expire_statistics_block_cache(profile)
12 end 14 end
13 15
@@ -29,6 +31,8 @@ protected @@ -29,6 +31,8 @@ protected
29 expire_blogs(profile) if profile.organization? 31 expire_blogs(profile) if profile.organization?
30 end 32 end
31 33
  34 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  35 + # the Noosfero core soon, see ActionItem3045
32 def expire_statistics_block_cache(profile) 36 def expire_statistics_block_cache(profile)
33 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } 37 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) }
34 BlockSweeper.expire_blocks(blocks) 38 BlockSweeper.expire_blocks(blocks)
app/views/account/_identifier_status.html.erb
1 <div class='status-identifier'> 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 <script type="text/javascript"> 12 <script type="text/javascript">
4 jQuery('#user_login').removeClass('<%= validation_classes %>'); 13 jQuery('#user_login').removeClass('<%= validation_classes %>');
5 jQuery('#user_login').addClass('<%= @status_class %>'); 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 </script> 20 </script>
7 </div> 21 </div>
app/views/account/_signup_form.html.erb
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 7
8 <% @profile_data = @person %> 8 <% @profile_data = @person %>
9 9
  10 +<%= javascript_include_tag('sign_up_password_rate') %>
  11 +
10 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> 12 <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %>
11 13
12 <%= labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> 14 <%= labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %>
@@ -35,24 +37,30 @@ @@ -35,24 +37,30 @@
35 <%= required text_field(:user, :login, :id => 'user_login', 37 <%= required text_field(:user, :login, :id => 'user_login',
36 :onchange => 'this.value = convToValidUsername(this.value);') %> 38 :onchange => 'this.value = convToValidUsername(this.value);') %>
37 <div id='url-check'><p>&nbsp;</p></div> 39 <div id='url-check'><p>&nbsp;</p></div>
  40 + <span id='checking-message' class='checking' style='display:none'><%= _('Checking availability of login name...') %></span>
38 </div> 41 </div>
39 <%= 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') %> 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 <br style="clear: both;" /> 43 <br style="clear: both;" />
41 </div> 44 </div>
42 </div> 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 <div id='signup-password'> 47 <div id='signup-password'>
53 <%= required f.password_field(:password, :id => 'user_pw') %> 48 <%= required f.password_field(:password, :id => 'user_pw') %>
54 <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %> 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>&nbsp;</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 </div> 64 </div>
57 65
58 <div id='signup-password-confirmation'> 66 <div id='signup-password-confirmation'>
@@ -182,4 +190,9 @@ jQuery(function($) { @@ -182,4 +190,9 @@ jQuery(function($) {
182 else $(this).addClass('validated'); 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 </script> 198 </script>
app/views/admin_panel/_site_info.html.erb
1 <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %> 1 <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %>
2 <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %> 2 <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %>
  3 +<%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
3 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
4 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> 5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %>
5 <%= required f.text_field(:reports_lower_bound, :size => 3) %> 6 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
app/views/blocks/profile_image.html.erb
1 <div class="vcard"> 1 <div class="vcard">
2 2
3 -<p><%= block.title %></p> 3 +<% if block.title.present? %>
  4 + <p><%= block.title %></p>
  5 +<% end %>
4 6
5 <div class="profile-big-image"> 7 <div class="profile-big-image">
6 <div class="profile-big-image-inner1"> 8 <div class="profile-big-image-inner1">
app/views/box_organizer/_link_list_block.html.erb
  1 +<%= javascript_include_tag "edit-link-list.js" %>
  2 +
1 <strong><%= _('Links') %></strong> 3 <strong><%= _('Links') %></strong>
2 <div id='edit-link-list-block'> 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 </div> 35 </div>
22 36
23 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| 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 end %> 49 end %>
app/views/box_organizer/edit.html.erb
@@ -7,13 +7,14 @@ @@ -7,13 +7,14 @@
7 7
8 <%= render :partial => partial_for_class(@block.class) %> 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 </div> 18 </div>
18 19
19 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> 20 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %>
app/views/content_viewer/_addthis.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -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,7 +26,7 @@
26 <%= expirable_button @page, :spread, content, url if url %> 26 <%= expirable_button @page, :spread, content, url if url %>
27 <% end %> 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 <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> 30 <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %>
31 <% content = _('Add translation') %> 31 <% content = _('Add translation') %>
32 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> 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,21 +43,7 @@
43 <%= render :partial => 'shared/disabled_enterprise' %> 43 <%= render :partial => 'shared/disabled_enterprise' %>
44 44
45 <% if NOOSFERO_CONF['addthis_enabled'] %> 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 <% end %> 47 <% end %>
62 48
63 <% cache(@page.cache_key(params, user, language)) do %> 49 <% cache(@page.cache_key(params, user, language)) do %>
@@ -84,6 +70,8 @@ @@ -84,6 +70,8 @@
84 70
85 <%= display_source_info(@page) %> 71 <%= display_source_info(@page) %>
86 72
  73 +<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %>
  74 +
87 <div class="comments" id="comments_list"> 75 <div class="comments" id="comments_list">
88 76
89 <% if @page.accept_comments? || @comments_count > 0 %> 77 <% if @page.accept_comments? || @comments_count > 0 %>
@@ -92,8 +80,26 @@ @@ -92,8 +80,26 @@
92 </h3> 80 </h3>
93 <% end %> 81 <% end %>
94 82
95 - <% if @page.accept_comments? && @comments.count > 1 %> 83 + <% if @page.accept_comments? && @comments_count > 1 %>
96 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> 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 <% end %> 103 <% end %>
98 104
99 <ul class="article-comments-list"> 105 <ul class="article-comments-list">
app/views/embed/block.html.erb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= display_block(@block) %>
app/views/embed/not_found.rhtml 0 → 100644
@@ -0,0 +1,6 @@ @@ -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/embed/unavailable.rhtml 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<div id='unavailable'>
  2 + <p><%= _('Embed unavailable.') %></p>
  3 +</div>
app/views/events/_events.html.erb
1 -<%= list_events(@date, @events) %>  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +<%= list_events(@date, @events) %>
  3 +
  4 +<%= pagination_links @events, :param_name => 'page' %>
app/views/features/_manage_community_fields.html.erb
1 -<h2><%= _('Manage community fields') %></h2>  
2 -  
3 <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %> 1 <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %>
4 2
5 <table id='community_fields_conf'> 3 <table id='community_fields_conf'>
@@ -9,21 +7,37 @@ @@ -9,21 +7,37 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on creation?') %></th> 8 <th><%= _('Display on creation?') %></th>
11 </tr> 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 <% @community_fields.each do |field| %> 26 <% @community_fields.each do |field| %>
13 <tr> 27 <tr>
14 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 28 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 29
16 <td> 30 <td>
17 <%= hidden_field_tag "community_fields[#{field}][active]", false %> 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 </td> 33 </td>
20 <td> 34 <td>
21 <%= hidden_field_tag "community_fields[#{field}][required]", false %> 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 </td> 37 </td>
24 <td> 38 <td>
25 <%= hidden_field_tag "community_fields[#{field}][signup]", false %> 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 </td> 41 </td>
28 42
29 </tr> 43 </tr>
@@ -31,18 +45,18 @@ @@ -31,18 +45,18 @@
31 </table> 45 </table>
32 46
33 <script type='text/javascript'> 47 <script type='text/javascript'>
34 - var trs = $$('#community_fields_conf tr'); 48 + var trs = jQuery('#community_fields_conf tr');
35 var tr, td2; 49 var tr, td2;
36 - for ( var i=0; tr=trs[i]; i++ ) { 50 + for ( var i=2; tr=trs[i]; i++ ) {
37 if ( td2 = tr.getElementsByTagName('td')[1] ) { 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38 - td2.getElementsByTagName('input')[0].onclick(); 52 + td2.getElementsByTagName('input')[1].onclick();
39 } 53 }
40 } 54 }
41 </script> 55 </script>
42 56
43 <div> 57 <div>
44 <% button_bar do %> 58 <% button_bar do %>
45 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_community_fields") %>
46 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 <% end %> 61 <% end %>
48 </div> 62 </div>
app/views/features/_manage_enterprise_fields.html.erb
1 -<h2><%= _('Manage enterprise fields') %></h2>  
2 -  
3 <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %> 1 <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %>
4 2
5 <table id='enterprise_fields_conf'> 3 <table id='enterprise_fields_conf'>
@@ -9,21 +7,37 @@ @@ -9,21 +7,37 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on registration?') %></th> 8 <th><%= _('Display on registration?') %></th>
11 </tr> 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 <% @enterprise_fields.each do |field| %> 26 <% @enterprise_fields.each do |field| %>
13 <tr> 27 <tr>
14 28
15 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 29 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
16 <td> 30 <td>
17 <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %> 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 </td> 33 </td>
20 <td> 34 <td>
21 <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %> 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 </td> 37 </td>
24 <td> 38 <td>
25 <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %> 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 </td> 41 </td>
28 42
29 </tr> 43 </tr>
@@ -31,18 +45,18 @@ @@ -31,18 +45,18 @@
31 </table> 45 </table>
32 46
33 <script type='text/javascript'> 47 <script type='text/javascript'>
34 - var trs = $$('#enterprise_fields_conf tr'); 48 + var trs = jQuery('#enterprise_fields_conf tr');
35 var tr, td2; 49 var tr, td2;
36 - for ( var i=0; tr=trs[i]; i++ ) { 50 + for ( var i=2; tr=trs[i]; i++ ) {
37 if ( td2 = tr.getElementsByTagName('td')[1] ) { 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38 - td2.getElementsByTagName('input')[0].onclick(); 52 + td2.getElementsByTagName('input')[1].onclick();
39 } 53 }
40 } 54 }
41 </script> 55 </script>
42 56
43 <div> 57 <div>
44 <% button_bar do %> 58 <% button_bar do %>
45 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_enterprise_fields") %>
46 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 <% end %> 61 <% end %>
48 </div> 62 </div>
app/views/features/_manage_person_fields.html.erb
1 -<h2><%= _('Manage person fields') %></h2>  
2 -  
3 <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %> 1 <%= labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %>
4 2
5 <table id='person_fields_conf'> 3 <table id='person_fields_conf'>
@@ -9,31 +7,48 @@ @@ -9,31 +7,48 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on signup?') %></th> 8 <th><%= _('Display on signup?') %></th>
11 </tr> 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 <% @person_fields.each do |field| %> 26 <% @person_fields.each do |field| %>
13 <tr> 27 <tr>
14 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 28 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 <td> 29 <td>
16 <%= hidden_field_tag "person_fields[#{field}][active]", false %> 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 </td> 32 </td>
19 <td> 33 <td>
20 <%= hidden_field_tag "person_fields[#{field}][required]", false %> 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 </td> 36 </td>
23 <td> 37 <td>
24 <%= hidden_field_tag "person_fields[#{field}][signup]", false %> 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 </td> 40 </td>
27 </tr> 41 </tr>
28 <% end %> 42 <% end %>
29 </table> 43 </table>
30 44
31 <script type='text/javascript'>// <!-- 45 <script type='text/javascript'>// <!--
32 - var trs = $$('#person_fields_conf tr'); 46 + var trs = jQuery('#person_fields_conf tr');
  47 +
33 var tr, td2; 48 var tr, td2;
34 - for ( var i=0; tr=trs[i]; i++ ) { 49 + for ( var i=2; tr=trs[i]; i++ ) {
35 if ( td2 = tr.getElementsByTagName('td')[1] ) { 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,7 +56,7 @@
41 56
42 <div> 57 <div>
43 <% button_bar do %> 58 <% button_bar do %>
44 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_person_fields") %>
45 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
46 <% end %> 61 <% end %>
47 </div> 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,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the
26 26
27 <h2><%= _('Configure features') %></h2> 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 <h3><%= _('Page to redirect after login') %></h3> 32 <h3><%= _('Page to redirect after login') %></h3>
30 <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %> 33 <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %>
31 <hr/> 34 <hr/>
  35 +
32 <h3><%= _('Organization Approval Method') %></h3> 36 <h3><%= _('Organization Approval Method') %></h3>
33 <%= select_organization_approval_method('environment', 'organization_approval_method') %> 37 <%= select_organization_approval_method('environment', 'organization_approval_method') %>
34 <hr/> 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 <% end %> 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 +6,27 @@
6 <!--<meta http-equiv="refresh" content="1"/>--> 6 <!--<meta http-equiv="refresh" content="1"/>-->
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
8 <meta name="description" content="<%= @environment.name %>" /> 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 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> 30 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" />
10 <%= noosfero_javascript %> 31 <%= noosfero_javascript %>
11 <%= noosfero_stylesheets %> 32 <%= noosfero_stylesheets %>
app/views/layouts/embed.rhtml 0 → 100644
@@ -0,0 +1,35 @@ @@ -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 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_comment.rhtml 0 → 100644
@@ -0,0 +1,33 @@ @@ -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>
app/views/person_notifier/mailer/_create_article.rhtml 0 → 100644
@@ -0,0 +1,27 @@ @@ -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 @@ @@ -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>
app/views/person_notifier/mailer/_join_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_leave_scrap.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -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 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_new_friendship.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -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 @@ @@ -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 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_upload_image.rhtml 0 → 100644
@@ -0,0 +1,15 @@ @@ -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/>
app/views/person_notifier/mailer/content_summary.rhtml 0 → 100644
@@ -0,0 +1,18 @@ @@ -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,3 +19,8 @@
19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> 19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
20 20
21 <%= render :partial => 'person_form', :locals => {:f => f} %> 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,8 +19,8 @@
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>')) %> 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 <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> 20 <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %>
21 <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> 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 <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %> 24 <%= optional_field(@person, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code, :rel => _('ZIP code')))) %>
25 <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %> 25 <%= optional_field(@person, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address, :rel => _('Address')))) %>
26 <%= optional_field(@person, 'address_reference', labelled_form_field(_('Address reference'), text_field(:profile_data, :address_reference, :rel => _('Address reference')))) %> 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,6 +36,7 @@
36 </div> 36 </div>
37 <% end %> 37 <% end %>
38 38
  39 +<%= javascript_include_tag('city_state_validation') %>
39 <script type='text/javascript'> 40 <script type='text/javascript'>
40 function toggle_text_field(id, span_id) { 41 function toggle_text_field(id, span_id) {
41 if ($(id).value == "Others") { 42 if ($(id).value == "Others") {
app/views/shared/_organization_custom_fields.html.erb
@@ -13,8 +13,8 @@ @@ -13,8 +13,8 @@
13 <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %> 13 <%= optional_field(profile, 'address_reference', labelled_form_field(_('Address reference'), text_field(object_name, :address_reference))) %>
14 <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %> 14 <%= optional_field(profile, 'district', labelled_form_field(_('District'), text_field(object_name, :district))) %>
15 <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(object_name, :zip_code))) %> 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 <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %> 18 <%= optional_field(profile, 'country', select_country(_('Country'), object_name, 'country', {:class => 'type-select'})) %>
19 <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %> 19 <%= optional_field(profile, 'tag_list', f.text_field(:tag_list)) %>
20 20
@@ -29,3 +29,4 @@ @@ -29,3 +29,4 @@
29 <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %> 29 <%= optional_field(profile, 'acronym', f.text_field(:acronym)) %>
30 <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %> 30 <%= optional_field(profile, 'foundation_year', f.text_field(:foundation_year)) %>
31 <% end %> 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 <% if !@current_category.nil? %> 3 <% if !@current_category.nil? %>
3 - <h3 class="box-title"><%= _('Current category:') %></h3>  
4 <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> 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 categories = [@current_category] 13 categories = [@current_category]
7 categories.push(@current_category) while @current_category = @current_category.parent 14 categories.push(@current_category) while @current_category = @current_category.parent
8 %> 15 %>
9 <%= categories.compact.reverse.map{|i| 16 <%= categories.compact.reverse.map{|i|
10 - link_to_remote(i.name, 17 + link_to_remote(i.name,
11 :update => "select-categories", 18 :update => "select-categories",
12 :url => { :action => 'update_categories', :category_id => i.id, :id => @object }, 19 :url => { :action => 'update_categories', :category_id => i.id, :id => @object },
13 :loaded => visual_effect(:highlight, "select-categories"), 20 :loaded => visual_effect(:highlight, "select-categories"),
14 :class => 'select-current-category-link')}.join(' &rarr; ') 21 :class => 'select-current-category-link')}.join(' &rarr; ')
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 hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + 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 end if multiple %> 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 <% end %> 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 %> &nbsp;  
45 -<% end %> 32 +<div class="toplevel-categories">
  33 + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %>
46 </div> 34 </div>
app/views/shared/_select_categories_top.rhtml 0 → 100644
@@ -0,0 +1,26 @@ @@ -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>
app/views/shared/_select_subcategories.rhtml 0 → 100644
@@ -0,0 +1,16 @@ @@ -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
1 <% if block.cacheable? && use_cache %> 1 <% if block.cacheable? && use_cache %>
2 - <% cache_timeout(block.cache_key(language), block.timeout) do %> 2 + <% cache_timeout(block.cache_key(language, user), block.timeout) do %>
3 <%= display_block_content(block, user, main_content) %> 3 <%= display_block_content(block, user, main_content) %>
4 <% end %> 4 <% end %>
5 <% else %> 5 <% else %>
app/views/themes/_select_template.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 "/designs/templates/#{template.id}/thumbnail.png", 12 "/designs/templates/#{template.id}/thumbnail.png",
13 :alt => _('The "%s" template')) + 13 :alt => _('The "%s" template')) +
14 '<div class="opt-info">'.html_safe + 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 ' <br/> '.html_safe 16 ' <br/> '.html_safe
17 17
18 if @current_template == template.id # selected 18 if @current_template == template.id # selected
app/views/user/mailer/activation_code.html.erb
1 <%= _('Hi, %{recipient}!') % { :recipient => @recipient } %> 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 <%= _("Greetings,") %> 5 <%= _("Greetings,") %>
6 6
app/views/users/_users_list.html.erb
1 <div class="environment-users-results-header"> 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 <%= filter_selector(@filter) %> 3 <%= filter_selector(@filter) %>
4 <div style="clear: both"></div> 4 <div style="clear: both"></div>
5 </div> 5 </div>
@@ -19,16 +19,17 @@ @@ -19,16 +19,17 @@
19 <td class='actions'> 19 <td class='actions'>
20 <div class="members-buttons-cell"> 20 <div class="members-buttons-cell">
21 <% if p.is_admin? %> 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 <% else %> 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 <% end %> 25 <% end %>
26 <% if !p.user.activated? %> 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 <% else %> 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 <% end %> 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 </td> 33 </td>
33 </tr> 34 </tr>
34 <% end %> 35 <% end %>
config/initializers/activities_counter_cache.rb 0 → 100644
@@ -0,0 +1,6 @@ @@ -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 require 'delayed_job' 1 require 'delayed_job'
2 Delayed::Worker.backend = :active_record 2 Delayed::Worker.backend = :active_record
3 Delayed::Worker.max_attempts = 2 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
config/initializers/noosfero_extensions.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +require 'noosfero/role_assignment_ext'
  2 +require 'noosfero/action_tracker_ext'