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.

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