Commit cc81e07501b41177911bd389ce1bba503e1bd206
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
merging with master
Showing
136 changed files
with
2164 additions
and
423 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 136 files displayed.
AUTHORS.md
@@ -92,6 +92,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | @@ -92,6 +92,7 @@ Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | ||
92 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | 92 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
93 | Daniel Bucher <daniel.bucher88@gmail.com> | 93 | Daniel Bucher <daniel.bucher88@gmail.com> |
94 | Daniel Cunha <daniel@colivre.coop.br> | 94 | Daniel Cunha <daniel@colivre.coop.br> |
95 | +daniel <dtygel@eita.org.br> | ||
95 | David Carlos <ddavidcarlos1392@gmail.com> | 96 | David Carlos <ddavidcarlos1392@gmail.com> |
96 | diegoamc <diegoamc90@gmail.com> | 97 | diegoamc <diegoamc90@gmail.com> |
97 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | 98 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> |
@@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com> | @@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com> | ||
120 | Diego + Jefferson <diegoamc90@gmail.com> | 121 | Diego + Jefferson <diegoamc90@gmail.com> |
121 | Diego Martinez <diegoamc90@gmail.com> | 122 | Diego Martinez <diegoamc90@gmail.com> |
122 | Diego + Renan <renanteruoc@gmail.com> | 123 | Diego + Renan <renanteruoc@gmail.com> |
124 | +dtygel <dtygel@gmail.com> | ||
123 | DylanGuedes <djmgguedes@gmail.com> | 125 | DylanGuedes <djmgguedes@gmail.com> |
124 | Eduardo Passos <eduardo@risa.localdomain.localhost> | 126 | Eduardo Passos <eduardo@risa.localdomain.localhost> |
125 | Eduardo Passos <eduardosteps@gmail.com> | 127 | Eduardo Passos <eduardosteps@gmail.com> |
@@ -144,6 +146,7 @@ Italo Valcy <italo@dcc.ufba.br> | @@ -144,6 +146,7 @@ Italo Valcy <italo@dcc.ufba.br> | ||
144 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | 146 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> |
145 | Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> | 147 | Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> |
146 | Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> | 148 | Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> |
149 | +Jérôme Jutteau <j.jutteau@gmail.com> | ||
147 | João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> | 150 | João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> |
148 | João da Silva <jaodsilv@linux.ime.usp.br> | 151 | João da Silva <jaodsilv@linux.ime.usp.br> |
149 | João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> | 152 | João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> |
@@ -247,8 +250,10 @@ Tallys Martins <tallysmartins@gmail.com> | @@ -247,8 +250,10 @@ Tallys Martins <tallysmartins@gmail.com> | ||
247 | Tallys Martins <tallysmartins@yahoo.com.br> | 250 | Tallys Martins <tallysmartins@yahoo.com.br> |
248 | tallys <tallys@tallys> | 251 | tallys <tallys@tallys> |
249 | tallys <tallys@tallys.(none)> | 252 | tallys <tallys@tallys.(none)> |
253 | +Thiago Casotti <thiago.casotti@uol.com.br> | ||
250 | Thiago Zoroastro <thiago.zoroastro@bol.com.br> | 254 | Thiago Zoroastro <thiago.zoroastro@bol.com.br> |
251 | Tuux <tuxa@galaxie.eu.org> | 255 | Tuux <tuxa@galaxie.eu.org> |
256 | +TWS <tablettws@gmail.com> | ||
252 | Valessio Brito <contato@valessiobrito.com.br> | 257 | Valessio Brito <contato@valessiobrito.com.br> |
253 | Valessio Brito <contato@valessiobrito.info> | 258 | Valessio Brito <contato@valessiobrito.info> |
254 | Valessio Brito <valessio@gmail.com> | 259 | Valessio Brito <valessio@gmail.com> |
Gemfile
@@ -20,18 +20,17 @@ gem 'locale', '~> 2.0.5' | @@ -20,18 +20,17 @@ gem 'locale', '~> 2.0.5' | ||
20 | gem 'whenever', :require => false | 20 | gem 'whenever', :require => false |
21 | gem 'eita-jrails', '>= 0.9.5', :require => 'jrails' | 21 | gem 'eita-jrails', '>= 0.9.5', :require => 'jrails' |
22 | 22 | ||
23 | -group :assets do | ||
24 | - gem 'uglifier', '>= 1.0.3' | ||
25 | - gem 'sass-rails' | ||
26 | -end | 23 | +# asset pipeline |
24 | +gem 'uglifier', '>= 1.0.3' | ||
25 | +gem 'sass-rails' | ||
27 | 26 | ||
28 | group :production do | 27 | group :production do |
29 | gem 'dalli', '~> 2.7.0' | 28 | gem 'dalli', '~> 2.7.0' |
30 | end | 29 | end |
31 | 30 | ||
32 | group :test do | 31 | group :test do |
33 | - gem 'rspec', '~> 2.10.0' | ||
34 | - gem 'rspec-rails', '~> 2.10.1' | 32 | + gem 'rspec', '~> 2.14.0' |
33 | + gem 'rspec-rails', '~> 2.14.1' | ||
35 | gem 'mocha', '~> 1.1.0', :require => false | 34 | gem 'mocha', '~> 1.1.0', :require => false |
36 | end | 35 | end |
37 | 36 |
app/controllers/admin/role_controller.rb
@@ -2,7 +2,7 @@ class RoleController < AdminController | @@ -2,7 +2,7 @@ class RoleController < AdminController | ||
2 | protect 'manage_environment_roles', :environment | 2 | protect 'manage_environment_roles', :environment |
3 | 3 | ||
4 | def index | 4 | def index |
5 | - @roles = environment.roles.find(:all) | 5 | + @roles = environment.roles.find(:all, :conditions => {:profile_id => nil}) |
6 | end | 6 | end |
7 | 7 | ||
8 | def new | 8 | def new |
app/controllers/application_controller.rb
@@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base | @@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base | ||
9 | before_filter :allow_cross_domain_access | 9 | before_filter :allow_cross_domain_access |
10 | before_filter :login_required, :if => :private_environment? | 10 | before_filter :login_required, :if => :private_environment? |
11 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] | 11 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] |
12 | + before_filter :redirect_to_current_user | ||
12 | 13 | ||
13 | def verify_members_whitelist | 14 | def verify_members_whitelist |
14 | render_access_denied unless user.is_admin? || environment.in_whitelist?(user) | 15 | render_access_denied unless user.is_admin? || environment.in_whitelist?(user) |
@@ -192,4 +193,15 @@ class ApplicationController < ActionController::Base | @@ -192,4 +193,15 @@ class ApplicationController < ActionController::Base | ||
192 | def private_environment? | 193 | def private_environment? |
193 | @environment.enabled?(:restrict_to_members) | 194 | @environment.enabled?(:restrict_to_members) |
194 | end | 195 | end |
196 | + | ||
197 | + def redirect_to_current_user | ||
198 | + if params[:profile] == '~' | ||
199 | + if logged_in? | ||
200 | + redirect_to params.merge(:profile => user.identifier) | ||
201 | + else | ||
202 | + render_not_found | ||
203 | + end | ||
204 | + end | ||
205 | + end | ||
206 | + | ||
195 | end | 207 | end |
app/controllers/my_profile/cms_controller.rb
@@ -357,7 +357,8 @@ class CmsController < MyProfileController | @@ -357,7 +357,8 @@ class CmsController < MyProfileController | ||
357 | @task.ip_address = request.remote_ip | 357 | @task.ip_address = request.remote_ip |
358 | @task.user_agent = request.user_agent | 358 | @task.user_agent = request.user_agent |
359 | @task.referrer = request.referrer | 359 | @task.referrer = request.referrer |
360 | - if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save | 360 | + @task.requestor = current_person if logged_in? |
361 | + if (logged_in? || verify_recaptcha(:model => @task, :message => _('Please type the words correctly'))) && @task.save | ||
361 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') | 362 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') |
362 | redirect_to @back_to | 363 | redirect_to @back_to |
363 | end | 364 | end |
app/controllers/my_profile/profile_design_controller.rb
@@ -4,11 +4,19 @@ class ProfileDesignController < BoxOrganizerController | @@ -4,11 +4,19 @@ class ProfileDesignController < BoxOrganizerController | ||
4 | 4 | ||
5 | protect 'edit_profile_design', :profile | 5 | protect 'edit_profile_design', :profile |
6 | 6 | ||
7 | - before_filter :protect_fixed_block, :only => [:save, :move_block] | 7 | + before_filter :protect_uneditable_block, :only => [:save] |
8 | + before_filter :protect_fixed_block, :only => [:move_block] | ||
9 | + | ||
10 | + def protect_uneditable_block | ||
11 | + block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) | ||
12 | + if !current_person.is_admin? && !block.editable? | ||
13 | + render_access_denied | ||
14 | + end | ||
15 | + end | ||
8 | 16 | ||
9 | def protect_fixed_block | 17 | def protect_fixed_block |
10 | block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) | 18 | block = boxes_holder.blocks.find(params[:id].gsub(/^block-/, '')) |
11 | - if block.fixed && !current_person.is_admin? | 19 | + if !current_person.is_admin? && !block.movable? |
12 | render_access_denied | 20 | render_access_denied |
13 | end | 21 | end |
14 | end | 22 | end |
app/controllers/my_profile/profile_members_controller.rb
@@ -58,6 +58,7 @@ class ProfileMembersController < MyProfileController | @@ -58,6 +58,7 @@ class ProfileMembersController < MyProfileController | ||
58 | 58 | ||
59 | def change_role | 59 | def change_role |
60 | @roles = Profile::Roles.organization_member_roles(environment.id) | 60 | @roles = Profile::Roles.organization_member_roles(environment.id) |
61 | + @custom_roles = profile.custom_roles | ||
61 | begin | 62 | begin |
62 | @member = profile.members.find(params[:id]) | 63 | @member = profile.members.find(params[:id]) |
63 | rescue ActiveRecord::RecordNotFound | 64 | rescue ActiveRecord::RecordNotFound |
@@ -0,0 +1,116 @@ | @@ -0,0 +1,116 @@ | ||
1 | +class ProfileRolesController < MyProfileController | ||
2 | + | ||
3 | + protect 'manage_custom_roles', :profile | ||
4 | + | ||
5 | + def index | ||
6 | + @roles = profile.custom_roles | ||
7 | + end | ||
8 | + | ||
9 | + def new | ||
10 | + @role = Role.new | ||
11 | + end | ||
12 | + | ||
13 | + def create | ||
14 | + @role = Role.new({:name => params[:role][:name], :permissions => params[:role][:permissions], :environment => environment }, :without_protection => true) | ||
15 | + if @role.save | ||
16 | + profile.custom_roles << @role | ||
17 | + redirect_to :action => 'show', :id => @role | ||
18 | + else | ||
19 | + session[:notice] = _('Failed to create role') | ||
20 | + render :action => 'new' | ||
21 | + end | ||
22 | + end | ||
23 | + | ||
24 | + def show | ||
25 | + @role = environment.roles.find(params[:id]) | ||
26 | + end | ||
27 | + | ||
28 | + def edit | ||
29 | + @role = environment.roles.find(params[:id]) | ||
30 | + end | ||
31 | + | ||
32 | + def assign_role_by_members | ||
33 | + return redirect_to "/" if params[:q].nil? or !request.xhr? | ||
34 | + arg = params[:q].downcase | ||
35 | + result = find_by_contents(:people, environment, profile.members, params[:q])[:results] | ||
36 | + render :text => prepare_to_token_input(result).to_json | ||
37 | + end | ||
38 | + | ||
39 | + def destroy | ||
40 | + @role = environment.roles.find(params[:id]) | ||
41 | + @members = profile.members_by_role(@role) | ||
42 | + @roles_list = all_roles(environment, profile) | ||
43 | + @roles_list.delete(@role) | ||
44 | + end | ||
45 | + | ||
46 | + def remove | ||
47 | + @role = environment.roles.find(params[:id]) | ||
48 | + @members = profile.members_by_role(@role) | ||
49 | + member_roles = params[:roles] ? environment.roles.find(params[:roles].select{|r|!r.to_i.zero?}) : [] | ||
50 | + append_roles(@members, member_roles, profile) | ||
51 | + if @role.destroy | ||
52 | + session[:notice] = _('Role successfuly removed!') | ||
53 | + else | ||
54 | + session[:notice] = _('Failed to remove role!') | ||
55 | + end | ||
56 | + redirect_to :action => 'index' | ||
57 | + end | ||
58 | + | ||
59 | + def update | ||
60 | + @role = environment.roles.find(params[:id]) | ||
61 | + if @role.update_attributes(params[:role]) | ||
62 | + redirect_to :action => 'show', :id => @role | ||
63 | + else | ||
64 | + session[:notice] = _('Failed to edit role') | ||
65 | + render :action => 'edit' | ||
66 | + end | ||
67 | + end | ||
68 | + | ||
69 | + def assign | ||
70 | + @role = environment.roles.find(params[:id]) | ||
71 | + @roles_list = all_roles(environment, profile) | ||
72 | + @roles_list.delete(@role) | ||
73 | + end | ||
74 | + | ||
75 | + def define | ||
76 | + @role = environment.roles.find(params[:id]) | ||
77 | + selected_role = params[:selected_role] ? environment.roles.find(params[:selected_role].to_i) : nil | ||
78 | + if params[:assign_role_by].eql? "members" | ||
79 | + members_list = params[:person_id].split(',').collect {|id| environment.profiles.find(id.to_i)} | ||
80 | + members_list.collect{|person| person.add_role(@role, profile)} | ||
81 | + elsif params[:assign_role_by].eql? "roles" | ||
82 | + members = profile.members_by_role(selected_role) | ||
83 | + replace_role(members, selected_role, @role, profile) | ||
84 | + else | ||
85 | + session[:notice] = _("Error") | ||
86 | + end | ||
87 | + redirect_to :action => 'index' | ||
88 | + end | ||
89 | + | ||
90 | + protected | ||
91 | + | ||
92 | + def append_roles(members, roles, profile) | ||
93 | + members.each do |person| | ||
94 | + all_roles = person.find_roles(profile).map(&:role) + roles | ||
95 | + person.define_roles(all_roles, profile) | ||
96 | + end | ||
97 | + end | ||
98 | + | ||
99 | + def all_roles(environment, profile) | ||
100 | + Profile::Roles.organization_member_roles(environment.id) + profile.custom_roles | ||
101 | + end | ||
102 | + | ||
103 | + def replace_roles(members, roles, profile) | ||
104 | + members.each do |person| | ||
105 | + person.define_roles(roles, profile) | ||
106 | + end | ||
107 | + end | ||
108 | + | ||
109 | + def replace_role(members, role, new_role, profile) | ||
110 | + members.each do |person| | ||
111 | + person.remove_role(role, profile) | ||
112 | + person.add_role(new_role, profile) | ||
113 | + end | ||
114 | + end | ||
115 | + | ||
116 | +end |
app/helpers/application_helper.rb
@@ -707,6 +707,24 @@ module ApplicationHelper | @@ -707,6 +707,24 @@ module ApplicationHelper | ||
707 | javascript_include_tag script if script | 707 | javascript_include_tag script if script |
708 | end | 708 | end |
709 | 709 | ||
710 | + def template_path | ||
711 | + if profile.nil? | ||
712 | + "/designs/templates/#{environment.layout_template}" | ||
713 | + else | ||
714 | + "/designs/templates/#{profile.layout_template}" | ||
715 | + end | ||
716 | + end | ||
717 | + | ||
718 | + def template_javascript_src | ||
719 | + script = File.join template_path, '/javascripts/template.js' | ||
720 | + script if File.exists? File.join(Rails.root, 'public', script) | ||
721 | + end | ||
722 | + | ||
723 | + def templete_javascript_ng | ||
724 | + script = template_javascript_src | ||
725 | + javascript_include_tag script if script | ||
726 | + end | ||
727 | + | ||
710 | def file_field_or_thumbnail(label, image, i) | 728 | def file_field_or_thumbnail(label, image, i) |
711 | display_form_field label, ( | 729 | display_form_field label, ( |
712 | render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'), | 730 | render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'), |
app/helpers/blog_helper.rb
@@ -17,28 +17,28 @@ module BlogHelper | @@ -17,28 +17,28 @@ module BlogHelper | ||
17 | _('Configure blog') | 17 | _('Configure blog') |
18 | end | 18 | end |
19 | 19 | ||
20 | - def list_posts(articles, format = 'full', paginate = true) | 20 | + def list_posts(articles, conf = { format: 'full', paginate: true }) |
21 | pagination = will_paginate(articles, { | 21 | pagination = will_paginate(articles, { |
22 | :param_name => 'npage', | 22 | :param_name => 'npage', |
23 | :previous_label => _('« Newer posts'), | 23 | :previous_label => _('« Newer posts'), |
24 | :next_label => _('Older posts »'), | 24 | :next_label => _('Older posts »'), |
25 | :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} | 25 | :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} |
26 | - }) if articles.present? && paginate | 26 | + }) if articles.present? && conf[:paginate] |
27 | content = [] | 27 | content = [] |
28 | artic_len = articles.length | 28 | artic_len = articles.length |
29 | articles.each_with_index{ |art,i| | 29 | articles.each_with_index{ |art,i| |
30 | - css_add = [ 'position-'+(i+1).to_s() ] | 30 | + css_add = [ 'blog-post', 'position-'+(i+1).to_s() ] |
31 | position = (i%2 == 0) ? 'odd-post' : 'even-post' | 31 | position = (i%2 == 0) ? 'odd-post' : 'even-post' |
32 | css_add << 'first' if i == 0 | 32 | css_add << 'first' if i == 0 |
33 | css_add << 'last' if i == (artic_len-1) | 33 | css_add << 'last' if i == (artic_len-1) |
34 | css_add << 'not-published' if !art.published? | 34 | css_add << 'not-published' if !art.published? |
35 | - css_add << position + '-inner' | ||
36 | - content << content_tag('div', | ||
37 | - content_tag('div', | ||
38 | - display_post(art, format).html_safe + '<br style="clear:both"/>'.html_safe, | ||
39 | - :class => 'blog-post ' + css_add.join(' '), | ||
40 | - :id => "post-#{art.id}"), :class => position | ||
41 | - ) | 35 | + css_add << position |
36 | + content << (content_tag 'div', id: "post-#{art.id}", class: css_add do | ||
37 | + content_tag 'div', class: position + '-inner blog-post-inner' do | ||
38 | + display_post(art, conf[:format]).html_safe + | ||
39 | + '<br style="clear:both"/>'.html_safe | ||
40 | + end | ||
41 | + end) | ||
42 | } | 42 | } |
43 | content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') | 43 | content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') |
44 | end | 44 | end |
@@ -46,7 +46,16 @@ module BlogHelper | @@ -46,7 +46,16 @@ module BlogHelper | ||
46 | def display_post(article, format = 'full') | 46 | def display_post(article, format = 'full') |
47 | no_comments = (format == 'full') ? false : true | 47 | no_comments = (format == 'full') ? false : true |
48 | title = article_title(article, :no_comments => no_comments) | 48 | title = article_title(article, :no_comments => no_comments) |
49 | - html = send("display_#{format}_format", FilePresenter.for(article)).html_safe | 49 | + method = "display_#{format.split('+')[0]}_format" |
50 | + html = send(method, FilePresenter.for(article)).html_safe | ||
51 | + if format.split('+')[1] == 'pic' | ||
52 | + img = article.first_image | ||
53 | + if img.blank? | ||
54 | + '<div class="post-pic empty"></div>' | ||
55 | + else | ||
56 | + '<div class="post-pic" style="background-image:url('+img+')"></div>' | ||
57 | + end | ||
58 | + end.to_s + | ||
50 | title + html | 59 | title + html |
51 | end | 60 | end |
52 | 61 |
app/helpers/boxes_helper.rb
@@ -190,7 +190,7 @@ module BoxesHelper | @@ -190,7 +190,7 @@ module BoxesHelper | ||
190 | else | 190 | else |
191 | "before-block-#{block.id}" | 191 | "before-block-#{block.id}" |
192 | end | 192 | end |
193 | - if block.nil? or modifiable?(block) | 193 | + if block.nil? || movable?(block) |
194 | content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') | 194 | content_tag('div', ' ', :id => id, :class => 'block-target' ) + drop_receiving_element(id, :url => { :action => 'move_block', :target => id }, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover') |
195 | else | 195 | else |
196 | "" | 196 | "" |
@@ -199,14 +199,14 @@ module BoxesHelper | @@ -199,14 +199,14 @@ module BoxesHelper | ||
199 | 199 | ||
200 | # makes the given block draggable so it can be moved away. | 200 | # makes the given block draggable so it can be moved away. |
201 | def block_handle(block) | 201 | def block_handle(block) |
202 | - modifiable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" | 202 | + movable?(block) ? draggable_element("block-#{block.id}", :revert => true) : "" |
203 | end | 203 | end |
204 | 204 | ||
205 | def block_edit_buttons(block) | 205 | def block_edit_buttons(block) |
206 | buttons = [] | 206 | buttons = [] |
207 | nowhere = 'javascript: return false;' | 207 | nowhere = 'javascript: return false;' |
208 | 208 | ||
209 | - if modifiable?(block) | 209 | + if movable?(block) |
210 | if block.first? | 210 | if block.first? |
211 | buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) | 211 | buttons << icon_button('up-disabled', _("Can't move up anymore."), nowhere) |
212 | else | 212 | else |
@@ -229,15 +229,15 @@ module BoxesHelper | @@ -229,15 +229,15 @@ module BoxesHelper | ||
229 | buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) | 229 | buttons << icon_button('left', _('Move to the opposite side'), { :action => 'move_block', :target => 'end-of-box-' + holder.boxes[1].id.to_s, :id => block.id }, :method => 'post' ) |
230 | end | 230 | end |
231 | end | 231 | end |
232 | + end | ||
232 | 233 | ||
233 | - if block.editable? | ||
234 | - buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | ||
235 | - end | 234 | + if editable?(block) |
235 | + buttons << modal_icon_button(:edit, _('Edit'), { :action => 'edit', :id => block.id }) | ||
236 | + end | ||
236 | 237 | ||
237 | - if !block.main? | ||
238 | - buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | ||
239 | - buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | ||
240 | - end | 238 | + if movable?(block) && !block.main? |
239 | + buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) | ||
240 | + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' }) | ||
241 | end | 241 | end |
242 | 242 | ||
243 | if block.respond_to?(:help) | 243 | if block.respond_to?(:help) |
@@ -273,7 +273,11 @@ module BoxesHelper | @@ -273,7 +273,11 @@ module BoxesHelper | ||
273 | classes | 273 | classes |
274 | end | 274 | end |
275 | 275 | ||
276 | - def modifiable?(block) | ||
277 | - return !block.fixed || environment.admins.include?(user) | 276 | + def movable?(block) |
277 | + return block.movable? || user.is_admin? | ||
278 | + end | ||
279 | + | ||
280 | + def editable?(block) | ||
281 | + return block.editable? || user.is_admin? | ||
278 | end | 282 | end |
279 | end | 283 | end |
app/helpers/layout_helper.rb
@@ -28,7 +28,7 @@ module LayoutHelper | @@ -28,7 +28,7 @@ module LayoutHelper | ||
28 | end | 28 | end |
29 | 29 | ||
30 | def noosfero_javascript | 30 | def noosfero_javascript |
31 | - plugins_javascripts = @plugins.flat_map{ |plugin| plugin.js_files.map{ |js| plugin.class.public_path(js, true) } }.flatten | 31 | + plugins_javascripts = @plugins.flat_map{ |plugin| Array.wrap(plugin.js_files).map{ |js| plugin.class.public_path(js, true) } }.flatten |
32 | 32 | ||
33 | output = '' | 33 | output = '' |
34 | output += render 'layouts/javascript' | 34 | output += render 'layouts/javascript' |
@@ -38,6 +38,8 @@ module LayoutHelper | @@ -38,6 +38,8 @@ module LayoutHelper | ||
38 | output += theme_javascript_ng.to_s | 38 | output += theme_javascript_ng.to_s |
39 | output += javascript_tag 'render_all_jquery_ui_widgets()' | 39 | output += javascript_tag 'render_all_jquery_ui_widgets()' |
40 | 40 | ||
41 | + output += templete_javascript_ng.to_s | ||
42 | + | ||
41 | output | 43 | output |
42 | end | 44 | end |
43 | 45 | ||
@@ -70,11 +72,7 @@ module LayoutHelper | @@ -70,11 +72,7 @@ module LayoutHelper | ||
70 | end | 72 | end |
71 | 73 | ||
72 | def template_stylesheet_path | 74 | def template_stylesheet_path |
73 | - if profile.nil? | ||
74 | - "/designs/templates/#{environment.layout_template}/stylesheets/style.css" | ||
75 | - else | ||
76 | - "/designs/templates/#{profile.layout_template}/stylesheets/style.css" | ||
77 | - end | 75 | + File.join template_path, "/stylesheets/style.css" |
78 | end | 76 | end |
79 | 77 | ||
80 | 78 |
app/helpers/tinymce_helper.rb
@@ -17,6 +17,7 @@ module TinymceHelper | @@ -17,6 +17,7 @@ module TinymceHelper | ||
17 | searchreplace wordcount visualblocks visualchars code fullscreen | 17 | searchreplace wordcount visualblocks visualchars code fullscreen |
18 | insertdatetime media nonbreaking save table contextmenu directionality | 18 | insertdatetime media nonbreaking save table contextmenu directionality |
19 | emoticons template paste textcolor colorpicker textpattern], | 19 | emoticons template paste textcolor colorpicker textpattern], |
20 | + :image_advtab => true, | ||
20 | :language => tinymce_language | 21 | :language => tinymce_language |
21 | 22 | ||
22 | options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" | 23 | options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" |
app/models/article.rb
@@ -5,7 +5,7 @@ class Article < ActiveRecord::Base | @@ -5,7 +5,7 @@ class Article < ActiveRecord::Base | ||
5 | :allow_members_to_edit, :translation_of_id, :language, | 5 | :allow_members_to_edit, :translation_of_id, :language, |
6 | :license_id, :parent_id, :display_posts_in_current_language, | 6 | :license_id, :parent_id, :display_posts_in_current_language, |
7 | :category_ids, :posts_per_page, :moderate_comments, | 7 | :category_ids, :posts_per_page, :moderate_comments, |
8 | - :accept_comments, :feed, :published, :source, | 8 | + :accept_comments, :feed, :published, :source, :source_name, |
9 | :highlighted, :notify_comments, :display_hits, :slug, | 9 | :highlighted, :notify_comments, :display_hits, :slug, |
10 | :external_feed_builder, :display_versions, :external_link, | 10 | :external_feed_builder, :display_versions, :external_link, |
11 | :image_builder, :show_to_followers | 11 | :image_builder, :show_to_followers |
@@ -769,7 +769,9 @@ class Article < ActiveRecord::Base | @@ -769,7 +769,9 @@ class Article < ActiveRecord::Base | ||
769 | end | 769 | end |
770 | 770 | ||
771 | def first_image | 771 | def first_image |
772 | - img = Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || Nokogiri::HTML.fragment(self.body.to_s).search('img').first | 772 | + img = ( image.present? && { 'src' => image.public_filename } ) || |
773 | + Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first || | ||
774 | + Nokogiri::HTML.fragment(self.body.to_s).search('img').first | ||
773 | img.nil? ? '' : img['src'] | 775 | img.nil? ? '' : img['src'] |
774 | end | 776 | end |
775 | 777 |
app/models/block.rb
1 | class Block < ActiveRecord::Base | 1 | class Block < ActiveRecord::Base |
2 | 2 | ||
3 | - attr_accessible :title, :display, :limit, :box_id, :posts_per_page, :visualization_format, :language, :display_user, :box, :fixed | 3 | + attr_accessible :title, :display, :limit, :box_id, :posts_per_page, |
4 | + :visualization_format, :language, :display_user, | ||
5 | + :box, :edit_modes, :move_modes | ||
4 | 6 | ||
5 | # to be able to generate HTML | 7 | # to be able to generate HTML |
6 | include ActionView::Helpers::UrlHelper | 8 | include ActionView::Helpers::UrlHelper |
@@ -23,7 +25,7 @@ class Block < ActiveRecord::Base | @@ -23,7 +25,7 @@ class Block < ActiveRecord::Base | ||
23 | end | 25 | end |
24 | 26 | ||
25 | def get_limit | 27 | def get_limit |
26 | - [0,limit].max | 28 | + [0,limit.to_i].max |
27 | end | 29 | end |
28 | 30 | ||
29 | def embed_code | 31 | def embed_code |
@@ -110,8 +112,13 @@ class Block < ActiveRecord::Base | @@ -110,8 +112,13 @@ class Block < ActiveRecord::Base | ||
110 | # * <tt>'all'</tt>: the block is always displayed | 112 | # * <tt>'all'</tt>: the block is always displayed |
111 | settings_items :language, :type => :string, :default => 'all' | 113 | settings_items :language, :type => :string, :default => 'all' |
112 | 114 | ||
113 | - # The block can be configured to be fixed. Only can be edited by environment admins | ||
114 | - settings_items :fixed, :type => :boolean, :default => false | 115 | + # The block can be configured to define the edition modes options. Only can be edited by environment admins |
116 | + # It can assume the following values: | ||
117 | + # | ||
118 | + # * <tt>'all'</tt>: the block owner has all edit options for this block | ||
119 | + # * <tt>'none'</tt>: the block owner can't do anything with the block | ||
120 | + settings_items :edit_modes, :type => :string, :default => 'all' | ||
121 | + settings_items :move_modes, :type => :string, :default => 'all' | ||
115 | 122 | ||
116 | # returns the description of the block, used when the user sees a list of | 123 | # returns the description of the block, used when the user sees a list of |
117 | # blocks to choose one to include in the design. | 124 | # blocks to choose one to include in the design. |
@@ -148,7 +155,11 @@ class Block < ActiveRecord::Base | @@ -148,7 +155,11 @@ class Block < ActiveRecord::Base | ||
148 | 155 | ||
149 | # Is this block editable? (Default to <tt>false</tt>) | 156 | # Is this block editable? (Default to <tt>false</tt>) |
150 | def editable? | 157 | def editable? |
151 | - true | 158 | + self.edit_modes == "all" |
159 | + end | ||
160 | + | ||
161 | + def movable? | ||
162 | + self.move_modes == "all" | ||
152 | end | 163 | end |
153 | 164 | ||
154 | # must always return false, except on MainBlock clas. | 165 | # must always return false, except on MainBlock clas. |
@@ -228,6 +239,21 @@ class Block < ActiveRecord::Base | @@ -228,6 +239,21 @@ class Block < ActiveRecord::Base | ||
228 | } | 239 | } |
229 | end | 240 | end |
230 | 241 | ||
242 | + def edit_block_options | ||
243 | + @edit_options ||= { | ||
244 | + 'all' => _('Can be modified'), | ||
245 | + 'none' => _('Cannot be modified') | ||
246 | + } | ||
247 | + end | ||
248 | + | ||
249 | + def move_block_options | ||
250 | + @move_options ||= { | ||
251 | + 'all' => _('Can be moved'), | ||
252 | + 'none' => _('Cannot be moved') | ||
253 | + } | ||
254 | + end | ||
255 | + | ||
256 | + | ||
231 | def duplicate | 257 | def duplicate |
232 | duplicated_block = self.dup | 258 | duplicated_block = self.dup |
233 | duplicated_block.display = 'never' | 259 | duplicated_block.display = 'never' |
app/models/blog.rb
@@ -76,7 +76,7 @@ class Blog < Folder | @@ -76,7 +76,7 @@ class Blog < Folder | ||
76 | end | 76 | end |
77 | 77 | ||
78 | settings_items :visualization_format, :type => :string, :default => 'full' | 78 | settings_items :visualization_format, :type => :string, :default => 'full' |
79 | - validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format | 79 | + validates_inclusion_of :visualization_format, :in => [ 'full', 'short', 'short+pic' ], :if => :visualization_format |
80 | 80 | ||
81 | settings_items :display_posts_in_current_language, :type => :boolean, :default => false | 81 | settings_items :display_posts_in_current_language, :type => :boolean, :default => false |
82 | 82 |
app/models/environment.rb
@@ -19,6 +19,8 @@ class Environment < ActiveRecord::Base | @@ -19,6 +19,8 @@ class Environment < ActiveRecord::Base | ||
19 | filename | 19 | filename |
20 | end | 20 | end |
21 | 21 | ||
22 | + NUMBER_OF_BOXES = 4 | ||
23 | + | ||
22 | PERMISSIONS['Environment'] = { | 24 | PERMISSIONS['Environment'] = { |
23 | 'view_environment_admin_panel' => N_('View environment admin panel'), | 25 | 'view_environment_admin_panel' => N_('View environment admin panel'), |
24 | 'edit_environment_features' => N_('Edit environment features'), | 26 | 'edit_environment_features' => N_('Edit environment features'), |
@@ -172,7 +174,7 @@ class Environment < ActiveRecord::Base | @@ -172,7 +174,7 @@ class Environment < ActiveRecord::Base | ||
172 | acts_as_having_boxes | 174 | acts_as_having_boxes |
173 | 175 | ||
174 | after_create do |env| | 176 | after_create do |env| |
175 | - 3.times do | 177 | + NUMBER_OF_BOXES.times do |
176 | env.boxes << Box.new | 178 | env.boxes << Box.new |
177 | end | 179 | end |
178 | 180 | ||
@@ -737,8 +739,8 @@ class Environment < ActiveRecord::Base | @@ -737,8 +739,8 @@ class Environment < ActiveRecord::Base | ||
737 | end | 739 | end |
738 | 740 | ||
739 | def is_default_template?(template) | 741 | def is_default_template?(template) |
740 | - is_default = template == community_default_template | ||
741 | - is_default = is_default || template == person_default_template | 742 | + is_default = template == community_default_template |
743 | + is_default = is_default || template == person_default_template | ||
742 | is_default = is_default || template == enterprise_default_template | 744 | is_default = is_default || template == enterprise_default_template |
743 | is_default | 745 | is_default |
744 | end | 746 | end |
app/models/highlights_block.rb
@@ -26,8 +26,16 @@ class HighlightsBlock < Block | @@ -26,8 +26,16 @@ class HighlightsBlock < Block | ||
26 | end | 26 | end |
27 | 27 | ||
28 | def featured_images | 28 | def featured_images |
29 | - block_images = images.select{|i| !i[:image_src].nil? }.sort { |x, y| x[:position] <=> y[:position] } | ||
30 | - shuffle ? block_images.shuffle : block_images | 29 | + images = get_images |
30 | + shuffle ? images.shuffle : images | ||
31 | + end | ||
32 | + | ||
33 | + def get_images | ||
34 | + images.select do |i| | ||
35 | + !i[:image_src].nil? | ||
36 | + end.sort do |x, y| | ||
37 | + x[:position] <=> y[:position] | ||
38 | + end | ||
31 | end | 39 | end |
32 | 40 | ||
33 | def content(args={}) | 41 | def content(args={}) |
app/models/organization.rb
@@ -29,6 +29,8 @@ class Organization < Profile | @@ -29,6 +29,8 @@ class Organization < Profile | ||
29 | 29 | ||
30 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' | 30 | has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' |
31 | 31 | ||
32 | + has_many :custom_roles, :class_name => 'Role', :foreign_key => :profile_id | ||
33 | + | ||
32 | scope :more_popular, :order => 'members_count DESC' | 34 | scope :more_popular, :order => 'members_count DESC' |
33 | 35 | ||
34 | validate :presence_of_required_fieds, :unless => :is_template | 36 | validate :presence_of_required_fieds, :unless => :is_template |
app/models/profile.rb
@@ -22,6 +22,8 @@ class Profile < ActiveRecord::Base | @@ -22,6 +22,8 @@ class Profile < ActiveRecord::Base | ||
22 | :display => %w[compact] | 22 | :display => %w[compact] |
23 | } | 23 | } |
24 | 24 | ||
25 | + NUMBER_OF_BOXES = 4 | ||
26 | + | ||
25 | def self.default_search_display | 27 | def self.default_search_display |
26 | 'compact' | 28 | 'compact' |
27 | end | 29 | end |
@@ -43,7 +45,7 @@ class Profile < ActiveRecord::Base | @@ -43,7 +45,7 @@ class Profile < ActiveRecord::Base | ||
43 | find_role('editor', env_id) | 45 | find_role('editor', env_id) |
44 | end | 46 | end |
45 | def self.organization_member_roles(env_id) | 47 | def self.organization_member_roles(env_id) |
46 | - all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? } | 48 | + all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? || !r.profile_id.nil?} |
47 | end | 49 | end |
48 | def self.all_roles(env_id) | 50 | def self.all_roles(env_id) |
49 | Role.all :conditions => { :environment_id => env_id } | 51 | Role.all :conditions => { :environment_id => env_id } |
@@ -75,6 +77,7 @@ class Profile < ActiveRecord::Base | @@ -75,6 +77,7 @@ class Profile < ActiveRecord::Base | ||
75 | 'publish_content' => N_('Publish content'), | 77 | 'publish_content' => N_('Publish content'), |
76 | 'invite_members' => N_('Invite members'), | 78 | 'invite_members' => N_('Invite members'), |
77 | 'send_mail_to_members' => N_('Send e-Mail to members'), | 79 | 'send_mail_to_members' => N_('Send e-Mail to members'), |
80 | + 'manage_custom_roles' => N_('Manage custom roles'), | ||
78 | } | 81 | } |
79 | 82 | ||
80 | acts_as_accessible | 83 | acts_as_accessible |
@@ -361,7 +364,7 @@ class Profile < ActiveRecord::Base | @@ -361,7 +364,7 @@ class Profile < ActiveRecord::Base | ||
361 | if template | 364 | if template |
362 | apply_template(template, :copy_articles => false) | 365 | apply_template(template, :copy_articles => false) |
363 | else | 366 | else |
364 | - 3.times do | 367 | + NUMBER_OF_BOXES.times do |
365 | self.boxes << Box.new | 368 | self.boxes << Box.new |
366 | end | 369 | end |
367 | 370 | ||
@@ -404,6 +407,7 @@ class Profile < ActiveRecord::Base | @@ -404,6 +407,7 @@ class Profile < ActiveRecord::Base | ||
404 | alias_method_chain :template, :default | 407 | alias_method_chain :template, :default |
405 | 408 | ||
406 | def apply_template(template, options = {:copy_articles => true}) | 409 | def apply_template(template, options = {:copy_articles => true}) |
410 | + self.template = template | ||
407 | copy_blocks_from(template) | 411 | copy_blocks_from(template) |
408 | copy_articles_from(template) if options[:copy_articles] | 412 | copy_articles_from(template) if options[:copy_articles] |
409 | self.apply_type_specific_template(template) | 413 | self.apply_type_specific_template(template) |
app/models/suggest_article.rb
1 | class SuggestArticle < Task | 1 | class SuggestArticle < Task |
2 | 2 | ||
3 | - validates_presence_of :target_id, :article_name, :email, :name, :article_body | 3 | + validates_presence_of :target_id |
4 | + validates_presence_of :email, :name, :if => Proc.new { |task| task.requestor.blank? } | ||
5 | + validates_associated :article_object | ||
4 | 6 | ||
5 | settings_items :email, :type => String | 7 | settings_items :email, :type => String |
6 | settings_items :name, :type => String | 8 | settings_items :name, :type => String |
7 | - settings_items :article_name, :type => String | ||
8 | - settings_items :article_body, :type => String | ||
9 | - settings_items :article_abstract, :type => String | ||
10 | - settings_items :article_parent_id, :type => String | ||
11 | - settings_items :source, :type => String | ||
12 | - settings_items :source_name, :type => String | ||
13 | - settings_items :highlighted, :type => :boolean, :default => false | ||
14 | settings_items :ip_address, :type => String | 9 | settings_items :ip_address, :type => String |
15 | settings_items :user_agent, :type => String | 10 | settings_items :user_agent, :type => String |
16 | settings_items :referrer, :type => String | 11 | settings_items :referrer, :type => String |
12 | + settings_items :article, :type => Hash, :default => {} | ||
17 | 13 | ||
18 | after_create :schedule_spam_checking | 14 | after_create :schedule_spam_checking |
19 | 15 | ||
@@ -24,34 +20,49 @@ class SuggestArticle < Task | @@ -24,34 +20,49 @@ class SuggestArticle < Task | ||
24 | include Noosfero::Plugin::HotSpot | 20 | include Noosfero::Plugin::HotSpot |
25 | 21 | ||
26 | def sender | 22 | def sender |
27 | - "#{name} (#{email})" | 23 | + requestor ? "#{requestor.name}" : "#{name} (#{email})" |
24 | + end | ||
25 | + | ||
26 | + def article_object | ||
27 | + if @article_object.nil? | ||
28 | + @article_object = article_type.new(article.merge({:profile => target}).except(:type)) | ||
29 | + if requestor.present? | ||
30 | + @article_object.author = requestor | ||
31 | + else | ||
32 | + @article_object.author_name = name | ||
33 | + end | ||
34 | + end | ||
35 | + @article_object | ||
36 | + end | ||
37 | + | ||
38 | + def article_type | ||
39 | + if article[:type].present? | ||
40 | + type = article[:type].constantize | ||
41 | + return type if type < Article | ||
42 | + end | ||
43 | + TinyMceArticle | ||
28 | end | 44 | end |
29 | 45 | ||
30 | def perform | 46 | def perform |
31 | - task = TinyMceArticle.new | ||
32 | - task.profile = target | ||
33 | - task.name = article_name | ||
34 | - task.author_name = name | ||
35 | - task.body = article_body | ||
36 | - task.abstract = article_abstract | ||
37 | - task.parent_id = article_parent_id | ||
38 | - task.source = source | ||
39 | - task.source_name = source_name | ||
40 | - task.highlighted = highlighted | ||
41 | - task.save! | 47 | + article_object.save! |
42 | end | 48 | end |
43 | 49 | ||
44 | def title | 50 | def title |
45 | _("Article suggestion") | 51 | _("Article suggestion") |
46 | end | 52 | end |
47 | 53 | ||
54 | + def article_name | ||
55 | + article[:name] | ||
56 | + end | ||
57 | + | ||
48 | def subject | 58 | def subject |
49 | article_name | 59 | article_name |
50 | end | 60 | end |
51 | 61 | ||
52 | def information | 62 | def information |
53 | - { :message => _('%{sender} suggested the publication of the article: %{subject}.'), | ||
54 | - :variables => {:sender => sender} } | 63 | + variables = requestor.blank? ? {:requestor => sender} : {} |
64 | + { :message => _('%{requestor} suggested the publication of the article: %{subject}.'), | ||
65 | + :variables => variables } | ||
55 | end | 66 | end |
56 | 67 | ||
57 | def accept_details | 68 | def accept_details |
@@ -63,8 +74,8 @@ class SuggestArticle < Task | @@ -63,8 +74,8 @@ class SuggestArticle < Task | ||
63 | end | 74 | end |
64 | 75 | ||
65 | def target_notification_description | 76 | def target_notification_description |
66 | - _('%{sender} suggested the publication of the article: %{article}.') % | ||
67 | - {:sender => sender, :article => article_name} | 77 | + _('%{requestor} suggested the publication of the article: %{article}.') % |
78 | + {:requestor => sender, :article => article_name} | ||
68 | end | 79 | end |
69 | 80 | ||
70 | def target_notification_message | 81 | def target_notification_message |
app/models/user.rb
@@ -45,7 +45,7 @@ class User < ActiveRecord::Base | @@ -45,7 +45,7 @@ class User < ActiveRecord::Base | ||
45 | p = Person.new | 45 | p = Person.new |
46 | 46 | ||
47 | p.attributes = user.person_data | 47 | p.attributes = user.person_data |
48 | - p.identifier = user.login | 48 | + p.identifier = user.login if p.identifier.blank? |
49 | p.user = user | 49 | p.user = user |
50 | p.environment = user.environment | 50 | p.environment = user.environment |
51 | p.name ||= user.name || user.login | 51 | p.name ||= user.name || user.login |
app/views/blocks/profile_info_actions/_join_leave_community.html.erb
1 | -<div class='join-leave-button'> | 1 | +<div class='join-leave-button require-login-popup'> |
2 | <% if logged_in? %> | 2 | <% if logged_in? %> |
3 | <% if profile.members.include?(user) %> | 3 | <% if profile.members.include?(user) %> |
4 | <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, | 4 | <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, |
app/views/box_organizer/edit.html.erb
@@ -5,12 +5,6 @@ | @@ -5,12 +5,6 @@ | ||
5 | 5 | ||
6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> | 6 | <%= labelled_form_field(_('Custom title for this block: '), text_field(:block, :title, :maxlength => 20)) %> |
7 | 7 | ||
8 | - <% if environment.admins.include?(user) %> | ||
9 | - <div class="fixed_block"> | ||
10 | - <%= labelled_check_box(_("Fixed"), "block[fixed]", value = "1", checked = @block.fixed) %> | ||
11 | - </div> | ||
12 | - <% end %> | ||
13 | - | ||
14 | <%= render :partial => partial_for_class(@block.class) %> | 8 | <%= render :partial => partial_for_class(@block.class) %> |
15 | 9 | ||
16 | <div class="display"> | 10 | <div class="display"> |
@@ -25,6 +19,15 @@ | @@ -25,6 +19,15 @@ | ||
25 | 19 | ||
26 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> | 20 | <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> |
27 | 21 | ||
22 | + <% if user.is_admin? %> | ||
23 | + <div class="edit-modes"> | ||
24 | + <%= labelled_form_field _('Edit options:'), select_tag('block[edit_modes]', options_from_collection_for_select(@block.edit_block_options, :first, :last, @block.edit_modes)) %> | ||
25 | + </div> | ||
26 | + <div class="move-modes"> | ||
27 | + <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %> | ||
28 | + </div> | ||
29 | + <% end %> | ||
30 | + | ||
28 | <% button_bar do %> | 31 | <% button_bar do %> |
29 | <%= submit_button(:save, _('Save')) %> | 32 | <%= submit_button(:save, _('Save')) %> |
30 | <%= modal_close_button(_('Cancel')) %> | 33 | <%= modal_close_button(_('Cancel')) %> |
app/views/cms/_blog.html.erb
@@ -64,7 +64,11 @@ | @@ -64,7 +64,11 @@ | ||
64 | <%= labelled_check_box(_('Remove cover image'),'remove_image',true,false)%> | 64 | <%= labelled_check_box(_('Remove cover image'),'remove_image',true,false)%> |
65 | <% end %> | 65 | <% end %> |
66 | 66 | ||
67 | -<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ [ _('Full post'), 'full'], [ _('First paragraph'), 'short'] ])) %> | 67 | +<%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ |
68 | + [ _('Full post'), 'full'], | ||
69 | + [ _('First paragraph'), 'short'], | ||
70 | + [ _('First paragraph, with post picture'), 'short+pic'] | ||
71 | +])) %> | ||
68 | 72 | ||
69 | <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> | 73 | <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> |
70 | 74 |
app/views/cms/suggest_an_article.html.erb
@@ -6,21 +6,22 @@ | @@ -6,21 +6,22 @@ | ||
6 | 6 | ||
7 | <%= labelled_form_for 'task' do |f| %> | 7 | <%= labelled_form_for 'task' do |f| %> |
8 | 8 | ||
9 | - <%= required labelled_form_field(_('Title'), text_field(:task, 'article_name', :size => 50)) %> | 9 | + <%= required labelled_form_field(_('Title'), text_field('task[article]', 'name', :size => 50)) %> |
10 | 10 | ||
11 | - <%= labelled_form_field(_('Source'), text_field(:task, 'source_name')) %> | 11 | + <%= labelled_form_field(_('Source'), text_field('task[article]', 'source_name')) %> |
12 | 12 | ||
13 | - <%= labelled_form_field(_('Source URL'), text_field(:task, 'source')) %> | 13 | + <%= labelled_form_field(_('Source URL'), text_field('task[article]', 'source')) %> |
14 | 14 | ||
15 | - <%= required labelled_form_field(_('Your name'), text_field(:task, 'name')) %> | ||
16 | - | ||
17 | - <%= required labelled_form_field(_('Email'), text_field(:task, 'email')) %> | 15 | + <% unless logged_in? %> |
16 | + <%= required labelled_form_field(_('Your name'), text_field(:task, 'name')) %> | ||
17 | + <%= required labelled_form_field(_('Email'), text_field(:task, 'email')) %> | ||
18 | + <% end %> | ||
18 | 19 | ||
19 | - <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => :task, :abstract_method => 'article_abstract', :body_method => 'article_body'} %> | 20 | + <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => 'task[article]'} %> |
20 | 21 | ||
21 | <%= hidden_field_tag('back_to', @back_to) %> | 22 | <%= hidden_field_tag('back_to', @back_to) %> |
22 | 23 | ||
23 | - <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) %> | 24 | + <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) unless logged_in? %> |
24 | 25 | ||
25 | <% button_bar do %> | 26 | <% button_bar do %> |
26 | <%= submit_button :save, _('Save') %> | 27 | <%= submit_button :save, _('Save') %> |
app/views/content_viewer/blog_page.html.erb
@@ -18,6 +18,9 @@ | @@ -18,6 +18,9 @@ | ||
18 | format = inside_block.visualization_format | 18 | format = inside_block.visualization_format |
19 | paginate = false | 19 | paginate = false |
20 | end | 20 | end |
21 | - (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format, paginate)) | 21 | + (blog.empty? ? |
22 | + content_tag('em', _('(no posts)')) : | ||
23 | + list_posts(posts, format: format, paginate: paginate) | ||
24 | + ) | ||
22 | %> | 25 | %> |
23 | </div> | 26 | </div> |
app/views/features/manage_fields.html.erb
1 | <h1><%= _('Manage fields displayed for profiles') %></h1> | 1 | <h1><%= _('Manage fields displayed for profiles') %></h1> |
2 | 2 | ||
3 | +<%= javascript_include_tag "manage-fields.js" %> | ||
4 | + | ||
3 | <% tabs = [] %> | 5 | <% tabs = [] %> |
4 | <% tabs << {:title => _("Person's fields"), :id => 'person-fields', | 6 | <% tabs << {:title => _("Person's fields"), :id => 'person-fields', |
5 | :content => (render :partial => 'manage_person_fields')} %> | 7 | :content => (render :partial => 'manage_person_fields')} %> |
@@ -11,5 +13,3 @@ | @@ -11,5 +13,3 @@ | ||
11 | <% end %> | 13 | <% end %> |
12 | 14 | ||
13 | <%= render_tabs(tabs) %> | 15 | <%= render_tabs(tabs) %> |
14 | - | ||
15 | -<%= javascript_include_tag "manage-fields.js" %> |
app/views/profile/report_abuse.html.erb
@@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
24 | $('#report-abuse-submit-button').css('cursor', 'progress'); | 24 | $('#report-abuse-submit-button').css('cursor', 'progress'); |
25 | $.ajax({ | 25 | $.ajax({ |
26 | type: 'POST', | 26 | type: 'POST', |
27 | - url: <%= url_for({:controller => 'profile', :action => 'register_report', :profile => profile.identifier}) %>, | 27 | + url: <%= url_for({:controller => 'profile', :action => 'register_report', :profile => profile.identifier}).to_json %>, |
28 | data: $(form).serialize(), | 28 | data: $(form).serialize(), |
29 | dataType: 'json', | 29 | dataType: 'json', |
30 | success: function(data, status, ajax){ | 30 | success: function(data, status, ajax){ |
app/views/profile_editor/edit.html.erb
1 | <h1><%= _('Profile settings for %s') % profile.name %></h1> | 1 | <h1><%= _('Profile settings for %s') % profile.name %></h1> |
2 | 2 | ||
3 | -<%= javascript_include_tag 'deactivate_profile' %> | ||
4 | <%= error_messages_for :profile_data %> | 3 | <%= error_messages_for :profile_data %> |
5 | 4 | ||
6 | <%= labelled_form_for :profile_data, :html => { :id => 'profile-data', :multipart => true } do |f| %> | 5 | <%= labelled_form_for :profile_data, :html => { :id => 'profile-data', :multipart => true } do |f| %> |
app/views/profile_editor/index.html.erb
@@ -28,6 +28,8 @@ | @@ -28,6 +28,8 @@ | ||
28 | 28 | ||
29 | <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %> | 29 | <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %> |
30 | 30 | ||
31 | + <%= control_panel_button(_('Manage Roles'), 'roles', :controller => 'profile_roles') %> | ||
32 | + | ||
31 | <% unless profile.enterprise? %> | 33 | <% unless profile.enterprise? %> |
32 | <%= case profile.blogs.count | 34 | <%= case profile.blogs.count |
33 | when 0 | 35 | when 0 |
app/views/profile_members/change_role.html.erb
1 | <h3> <%= _('Changing role of %s') % @member.name %> </h3> | 1 | <h3> <%= _('Changing role of %s') % @member.name %> </h3> |
2 | 2 | ||
3 | <%= labelled_form_for :member, :url => {:action => 'update_roles'} do |f| %> | 3 | <%= labelled_form_for :member, :url => {:action => 'update_roles'} do |f| %> |
4 | - | ||
5 | - <%= _('Roles:') %> <br> | 4 | + |
5 | + <h4><%= _('Roles:') %></h4> | ||
6 | <% @roles.each do |r| %> | 6 | <% @roles.each do |r| %> |
7 | <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/> | 7 | <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/> |
8 | <ul class="role-permissions"> | 8 | <ul class="role-permissions"> |
@@ -11,6 +11,17 @@ | @@ -11,6 +11,17 @@ | ||
11 | <% end %> | 11 | <% end %> |
12 | </ul> | 12 | </ul> |
13 | <% end %> | 13 | <% end %> |
14 | + <% unless @custom_roles.empty? %> | ||
15 | + <h4><%= _('Custom Roles:') %></h4> | ||
16 | + <% @custom_roles.each do |r| %> | ||
17 | + <%= labelled_check_box(r.name, 'roles[]', r.id, @associations.map(&:role).include?(r) ) %><br/> | ||
18 | + <ul class="role-permissions"> | ||
19 | + <% r.permissions.each do |p| %> | ||
20 | + <li> <%= permission_name(p) %> </li> | ||
21 | + <% end %> | ||
22 | + </ul> | ||
23 | + <% end %> | ||
24 | + <% end %> | ||
14 | <%= hidden_field_tag 'person', @member.id %> | 25 | <%= hidden_field_tag 'person', @member.id %> |
15 | 26 | ||
16 | <% button_bar do %> | 27 | <% button_bar do %> |
@@ -0,0 +1,22 @@ | @@ -0,0 +1,22 @@ | ||
1 | +<%= error_messages_for :role %> | ||
2 | + | ||
3 | +<%= labelled_form_for :role, :url => (mode == :edit) ? {:action => 'update', :id => role} : {:action => 'create'} do |f| %> | ||
4 | + | ||
5 | + <%= required_fields_message %> | ||
6 | + | ||
7 | + <%= required f.text_field(:name) %> | ||
8 | + | ||
9 | + <% permissions.each do |key| %> | ||
10 | + <div class="permissions <%= key.downcase %>"> | ||
11 | + <h4><%= _('%s Permissions:' % key) %></h4> | ||
12 | + <% ActiveRecord::Base::PERMISSIONS[key].keys.each do |p| %> | ||
13 | + <%= check_box_tag("role[permissions][]", p, role.has_permission?(p), { :id => p }) %> | ||
14 | + <%= content_tag(:label, permission_name(p), { :for => p }) %><br/> | ||
15 | + <% end %> | ||
16 | + </div> | ||
17 | + <% end %> | ||
18 | + | ||
19 | + <% button_bar do %> | ||
20 | + <%= submit_button('save', (mode == :edit) ? _('Save changes') : _('Create role'), :cancel => {:action => 'index'} ) %> | ||
21 | + <% end %> | ||
22 | +<% end %> |
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
1 | +<%= javascript_include_tag('assign_role.js') %> | ||
2 | + | ||
3 | +<h1> <%= _("Assign #{@role.name}") %> </h1> | ||
4 | + | ||
5 | + | ||
6 | +<%= labelled_form_for :role, :url => { :action => 'define', :id => @role.id } do |f| %> | ||
7 | + | ||
8 | + <h2> | ||
9 | + <%= _("Assign role by:") %> | ||
10 | + </h2> | ||
11 | + <p> | ||
12 | + <%= labelled_radio_button _("Members"), :assign_role_by, "members", true, :id => "assign_role_by_members", :class => "assign_role_by" %> | ||
13 | + | ||
14 | + <%= labelled_radio_button _("Roles"), :assign_role_by, "roles", false, :id => "assign_role_by_roles", :class => "assign_role_by" %> | ||
15 | + </p> | ||
16 | + <div class="assign_by_members"> | ||
17 | + <%=token_input_field_tag(:person_id, 'search-profile-members', {:action => 'assign_role_by_members'}, | ||
18 | + {:focus => false, :hint_text => _('Select members to assign the role')}) %> | ||
19 | + | ||
20 | + <% button_bar do %> | ||
21 | + <%= submit_button(:forward, _("Confirm")) %> | ||
22 | + <% end %> | ||
23 | + </div> | ||
24 | + <div class="assign_by_roles" style="display: none;"> | ||
25 | + <h6> | ||
26 | + <%= _("Replace role: ") %> | ||
27 | + </h6> | ||
28 | + <% @roles_list.each do |role| %> | ||
29 | + <%= labelled_radio_button role.name , :selected_role, role.id , false, :class => "selected_role" %> <br> | ||
30 | + <% end %> | ||
31 | + <% button_bar do %> | ||
32 | + <%= submit_button('save',_('Confirm'), :cancel => {:action => 'index'} ) %> | ||
33 | + <% end %> | ||
34 | + </div> | ||
35 | +<% end %> |
@@ -0,0 +1,23 @@ | @@ -0,0 +1,23 @@ | ||
1 | +<h1> <%= _("Deleting #{@role.name}") %> </h1> | ||
2 | + | ||
3 | +<% if @members.nil? || @members.empty? %> | ||
4 | + <p><%= _('This role is not being currently used.')%></p> | ||
5 | + <p><%= _('Are you sure you want to delete this role?') %></p> | ||
6 | + | ||
7 | + <% button_bar do %> | ||
8 | + <%= button(:remove, _('Yes, I am sure'), {:action => 'remove', :id => @role.id}, :method => :post) %> | ||
9 | + <%= button(:cancel, _('No, I gave up'), {:action => 'index'}) %> | ||
10 | + <% end %> | ||
11 | +<% else %> | ||
12 | + <p><%= _('There are members currently using this role.')%></p> | ||
13 | + <p><%= _('To which role do you want to change them?') %></p> | ||
14 | + <%= labelled_form_for :role, :url => { :action => 'remove', :id => @role.id } do |f| %> | ||
15 | + <% @roles_list.each do |role| %> | ||
16 | + <%= check_box_tag("roles[]", role.id, false ,{:id => role.key}) %> | ||
17 | + <%= content_tag(:label, role.name, { :for => role.key }) %><br/> | ||
18 | + <% end %> | ||
19 | + <% button_bar do %> | ||
20 | + <%= submit_button('save',_('Delete role'), :cancel => {:action => 'index'} ) %> | ||
21 | + <% end %> | ||
22 | + <% end %> | ||
23 | +<% end %> |
@@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
1 | +<h1><%= _('Manage user roles') %></h1> | ||
2 | + | ||
3 | +<table> | ||
4 | + <tr> | ||
5 | + <th><%= _('Role') %></th> | ||
6 | + <th><%= _('Actions') %></th> | ||
7 | + </tr> | ||
8 | + <% @roles.each do |role| %> | ||
9 | + <tr> | ||
10 | + <td> | ||
11 | + <%= link_to role.name, :action => 'show', :id => role %> | ||
12 | + </td> | ||
13 | + <td> | ||
14 | + <div style="text-align: center;"> | ||
15 | + <%= button_without_text :edit, _('Edit'), :action => 'edit', :id => role %> | ||
16 | + <%= button_without_text :delete, _('Delete'), :action => 'destroy', :id => role %> | ||
17 | + <%= button_without_text 'vertical-toggle', _('Assign'), :action => 'assign', :id => role %> | ||
18 | + </div> | ||
19 | + </td> | ||
20 | + </tr> | ||
21 | + <% end %> | ||
22 | +</table> | ||
23 | + | ||
24 | +<% button_bar do %> | ||
25 | + <%= button :add, _('Create a new role'), :action => 'new' %> | ||
26 | + <%= button :back, _('Back to control panel'), :controller => 'profile_editor' %> | ||
27 | +<% end %> |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +<h1> <%= _(@role.name) %></h1> | ||
2 | + | ||
3 | +<h3> <%= _('Permissions') %> </h3> | ||
4 | +<ul> | ||
5 | + <% @role.permissions.each do |p| %> | ||
6 | + <li> <%= permission_name(p) %> </li> | ||
7 | + <% end %> | ||
8 | +</ul> | ||
9 | + | ||
10 | +<% button_bar do %> | ||
11 | + <%= button :edit, _('Edit'), :action => 'edit', :id => @role %> | ||
12 | + <%= button :back, _('Back to roles management'), :action => 'index' %> | ||
13 | +<% end %> |
app/views/shared/_profile_search_form.html.erb
1 | +<% search_label = _("Find in %s's content") % profile.short_name %> | ||
1 | <%= form_tag( { :controller => 'profile_search', :profile => profile.identifier}, :method => 'get', :class => 'search_form' ) do %> | 2 | <%= form_tag( { :controller => 'profile_search', :profile => profile.identifier}, :method => 'get', :class => 'search_form' ) do %> |
2 | <div class="search-field"> | 3 | <div class="search-field"> |
3 | <span class="formfield"> | 4 | <span class="formfield"> |
4 | - <%= search_input_with_suggestions 'q', :articles, @q, :title => _("Find in %s's content") % profile.short_name %> | 5 | + <%= search_input_with_suggestions 'q', :articles, @q, :title => search_label, :placeholder => search_label %> |
5 | </span> | 6 | </span> |
6 | <%= submit_button(:search, _('Search')) %> | 7 | <%= submit_button(:search, _('Search')) %> |
7 | <div> | 8 | <div> |
app/views/spam/_suggest_article.html.erb
@@ -7,13 +7,13 @@ | @@ -7,13 +7,13 @@ | ||
7 | <ul class="suggest-article-details" style="display: none"> | 7 | <ul class="suggest-article-details" style="display: none"> |
8 | <li><strong><%=_('Sent by')%></strong>: <%=task.name%> </li> | 8 | <li><strong><%=_('Sent by')%></strong>: <%=task.name%> </li> |
9 | <li><strong><%=_('Email')%></strong>: <%=task.email%> </li> | 9 | <li><strong><%=_('Email')%></strong>: <%=task.email%> </li> |
10 | - <li><strong><%=_('Source')%></strong>: <%=task.source_name%> </li> | ||
11 | - <li><strong><%=_('Source URL')%></strong>: <%=task.source%> </li> | ||
12 | - <li><strong><%=_('Folder')%></strong>: <%=(a = Article.find_by_id(task.article_parent_id))?a.name : '<em>' + s_('Folder|none') + '</em>'%> </li> | ||
13 | - <li><strong><%=_('Lead')%></strong>: <%=task.article_abstract.blank? ? '<em>' + s_('Abstract|empty') + '</em>' : task.article_abstract%> </li> | 10 | + <li><strong><%=_('Source')%></strong>: <%=task.article_object.source_name%> </li> |
11 | + <li><strong><%=_('Source URL')%></strong>: <%=task.article_object.source%> </li> | ||
12 | + <li><strong><%=_('Folder')%></strong>: <%=(a = Article.find_by_id(task.article_object.parent_id))?a.name : '<em>' + s_('Folder|none') + '</em>'%> </li> | ||
13 | + <li><strong><%=_('Lead')%></strong>: <%=task.article_object.abstract.blank? ? '<em>' + s_('Abstract|empty') + '</em>' : task.article_object.abstract%> </li> | ||
14 | <li><strong><%=_('Body')%></strong>: | 14 | <li><strong><%=_('Body')%></strong>: |
15 | <div class='suggest-article-body'> | 15 | <div class='suggest-article-body'> |
16 | - <%= task.article_body %> | 16 | + <%= task.article_object.body %> |
17 | </div> | 17 | </div> |
18 | </li> | 18 | </li> |
19 | </ul> | 19 | </ul> |
app/views/tasks/_add_member_accept_details.html.erb
1 | <%= content = _("Roles:")+"<br />" | 1 | <%= content = _("Roles:")+"<br />" |
2 | -roles = Profile::Roles.organization_member_roles(task.target.environment.id) | 2 | +roles = Profile::Roles.organization_member_roles(task.target.environment.id) + profile.custom_roles |
3 | roles.each do |role| | 3 | roles.each do |role| |
4 | content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false)+"<br />" | 4 | content += labelled_check_box(role.name, "tasks[#{task.id}][task][roles][]", role.id, false)+"<br />" |
5 | end | 5 | end |
6 | content_tag('p', content, :class => 'member-classify-suggestion') | 6 | content_tag('p', content, :class => 'member-classify-suggestion') |
7 | %> | 7 | %> |
8 | - |
app/views/tasks/_suggest_article_accept_details.html.erb
1 | <%= render :file => 'shared/tiny_mce' %> | 1 | <%= render :file => 'shared/tiny_mce' %> |
2 | 2 | ||
3 | -<%= labelled_form_field(_("Sent by: "), f.text_field(:name)) %> | ||
4 | -<p><%= label_tag(_("Email: %s") % task.email) %> </p> | ||
5 | -<%= required labelled_form_field(_('Title'), f.text_field(:article_name, :size => 50)) %> | ||
6 | -<%= labelled_form_field(_('Source'), f.text_field(:source_name)) %> | ||
7 | -<%= labelled_form_field(_("Source URL"), f.text_field(:source)) %> | 3 | +<% unless task.requestor %> |
4 | + <%= labelled_form_field(_("Sent by: "), f.text_field(:name)) %> | ||
5 | + <p><%= label_tag(_("Email: %s") % task.email) %> </p> | ||
6 | +<% end %> | ||
8 | 7 | ||
9 | -<%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task][article_parent_id]", task.target) %> | ||
10 | -<%= labelled_form_field(_('Highlight this article'), f.check_box(:highlighted)) %> | 8 | +<%= f.fields_for 'article', OpenStruct.new(task.article) do |a| %> |
9 | + <%= required labelled_form_field(_('Title'), a.text_field(:name, :size => 50)) %> | ||
10 | + <%= labelled_form_field(_('Source'), a.text_field(:source_name)) %> | ||
11 | + <%= labelled_form_field(_("Source URL"), a.text_field(:source)) %> | ||
11 | 12 | ||
12 | -<%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :f => f, :abstract_method => 'article_abstract', :body_method => 'article_body', :lead_id => task.id} %> | 13 | + <%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task][article][parent_id]", task.target, task.article[:parent_id]) %> |
14 | + <%= labelled_form_field(_('Highlight this article'), a.check_box(:highlighted)) %> | ||
15 | + | ||
16 | + <%= a.hidden_field(:type) %> | ||
17 | + | ||
18 | + <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :f => a, :lead_id => task.id} %> | ||
19 | +<% end %> |
app/views/user_mailer/profiles_suggestions_email.html.erb
@@ -10,8 +10,8 @@ | @@ -10,8 +10,8 @@ | ||
10 | <% @people_suggestions.each do |person| %> | 10 | <% @people_suggestions.each do |person| %> |
11 | <li><a href="<%= url_for(person.public_profile_url) %>"><%= person.name %></a></li> | 11 | <li><a href="<%= url_for(person.public_profile_url) %>"><%= person.name %></a></li> |
12 | <% end %> | 12 | <% end %> |
13 | - <ul> | ||
14 | - <%= _("To see the full list of friends suggestions, follow the link: %s") % @people_suggestions_url %> | 13 | + </ul> |
14 | + <%= _("To see the full list of friends suggestions, follow the link: %s") % url_for(@people_suggestions_url) %> | ||
15 | <% end %> | 15 | <% end %> |
16 | 16 | ||
17 | <% unless @communities_suggestions.empty? %> | 17 | <% unless @communities_suggestions.empty? %> |
@@ -21,13 +21,15 @@ | @@ -21,13 +21,15 @@ | ||
21 | <% @communities_suggestions.each do |community| %> | 21 | <% @communities_suggestions.each do |community| %> |
22 | <li><a href="<%= url_for(community.public_profile_url) %>"><%= community.name %></a></li> | 22 | <li><a href="<%= url_for(community.public_profile_url) %>"><%= community.name %></a></li> |
23 | <% end %> | 23 | <% end %> |
24 | - <ul> | ||
25 | - <%= _("To see the full list of communities suggestions, follow the link: %s") % @communities_suggestions_url %> | 24 | + </ul> |
25 | + <%= _("To see the full list of communities suggestions, follow the link: %s") % url_for(@communities_suggestions_url) %> | ||
26 | <% end %> | 26 | <% end %> |
27 | 27 | ||
28 | 28 | ||
29 | <%= _("Greetings,") %> | 29 | <%= _("Greetings,") %> |
30 | 30 | ||
31 | --- | ||
32 | -<%= _('%s team.') % @environment %> | 31 | +<p><%= _("Greetings,") %></p> |
32 | + | ||
33 | +--<br/> | ||
34 | +<%= _('%s team.') % @environment %><br/> | ||
33 | <%= @url %> | 35 | <%= @url %> |
config/environments/development.rb
@@ -35,4 +35,8 @@ Noosfero::Application.configure do | @@ -35,4 +35,8 @@ Noosfero::Application.configure do | ||
35 | config.assets.debug = true | 35 | config.assets.debug = true |
36 | 36 | ||
37 | config.consider_all_requests_local = true | 37 | config.consider_all_requests_local = true |
38 | + | ||
39 | + # send emails to /tmp/mails | ||
40 | + config.action_mailer.delivery_method = :file | ||
41 | + | ||
38 | end | 42 | end |
config/routes.rb
@@ -56,37 +56,37 @@ Noosfero::Application.routes.draw do | @@ -56,37 +56,37 @@ Noosfero::Application.routes.draw do | ||
56 | match 'search(/:action(/*category_path))', :controller => 'search' | 56 | match 'search(/:action(/*category_path))', :controller => 'search' |
57 | 57 | ||
58 | # events | 58 | # events |
59 | - match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format}/ | ||
60 | - match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format}/ | ||
61 | - match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format}/ | ||
62 | - match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format}/ | ||
63 | - match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format}/ | 59 | + match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format_in_url}/ |
60 | + match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
61 | + match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/ | ||
62 | + match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/ | ||
63 | + match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
64 | 64 | ||
65 | # catalog | 65 | # catalog |
66 | - match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/, :as => :catalog | 66 | + match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/, :as => :catalog |
67 | 67 | ||
68 | # invite | 68 | # invite |
69 | - match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format}/ | ||
70 | - match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format}/ | 69 | + match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format_in_url}/ |
70 | + match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
71 | 71 | ||
72 | # feeds per tag | 72 | # feeds per tag |
73 | - match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format}/, :as => :tag_feed | 73 | + match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :tag_feed |
74 | 74 | ||
75 | # profile tags | 75 | # profile tags |
76 | - match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format}/ | ||
77 | - match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format}/ | 76 | + match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/ |
77 | + match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format_in_url}/ | ||
78 | 78 | ||
79 | # profile search | 79 | # profile search |
80 | - match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format}/ | 80 | + match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/ |
81 | 81 | ||
82 | # comments | 82 | # comments |
83 | - match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format}/ | 83 | + match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format_in_url}/ |
84 | 84 | ||
85 | # public profile information | 85 | # public profile information |
86 | - match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format}/, :as => :profile | 86 | + match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :profile |
87 | 87 | ||
88 | # contact | 88 | # contact |
89 | - match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ | 89 | + match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format_in_url}/ |
90 | 90 | ||
91 | # map balloon | 91 | # map balloon |
92 | match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/ | 92 | match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/ |
@@ -98,8 +98,8 @@ Noosfero::Application.routes.draw do | @@ -98,8 +98,8 @@ Noosfero::Application.routes.draw do | ||
98 | ## Controllers that are profile-specific (for profile admins ) | 98 | ## Controllers that are profile-specific (for profile admins ) |
99 | ###################################################### | 99 | ###################################################### |
100 | # profile customization - "My profile" | 100 | # profile customization - "My profile" |
101 | - match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format}/ | ||
102 | - match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format}/, :as => :myprofile | 101 | + match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/ |
102 | + match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format_in_url}/, :as => :myprofile | ||
103 | 103 | ||
104 | 104 | ||
105 | ###################################################### | 105 | ###################################################### |
@@ -127,14 +127,14 @@ Noosfero::Application.routes.draw do | @@ -127,14 +127,14 @@ Noosfero::Application.routes.draw do | ||
127 | # cache stuff - hack | 127 | # cache stuff - hack |
128 | match 'public/:action/:id', :controller => 'public' | 128 | match 'public/:action/:id', :controller => 'public' |
129 | 129 | ||
130 | - match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new | 130 | + match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new |
131 | match '*page/versions', :controller => 'content_viewer', :action => 'article_versions' | 131 | match '*page/versions', :controller => 'content_viewer', :action => 'article_versions' |
132 | 132 | ||
133 | - match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new | 133 | + match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new |
134 | match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' | 134 | match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' |
135 | 135 | ||
136 | # match requests for profiles that don't have a custom domain | 136 | # match requests for profiles that don't have a custom domain |
137 | - match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new | 137 | + match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new |
138 | 138 | ||
139 | # match requests for content in domains hosted for profiles | 139 | # match requests for content in domains hosted for profiles |
140 | match '/(*page)', :controller => 'content_viewer', :action => 'view_page' | 140 | match '/(*page)', :controller => 'content_viewer', :action => 'view_page' |
db/migrate/20150210143723_add_custom_roles_permission_to_admin_roles.rb
0 → 100644
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +class AddCustomRolesPermissionToAdminRoles < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + environment_admin = Role.find_by_key("environment_administrator") | ||
4 | + profile_admin = Role.find_by_key("profile_admin") | ||
5 | + environment_admin.permissions.append("manage_custom_roles") | ||
6 | + profile_admin.permissions.append("manage_custom_roles") | ||
7 | + environment_admin.save! | ||
8 | + profile_admin.save! | ||
9 | + end | ||
10 | + def self.down | ||
11 | + environment_admin = Role.find_by_key("environment_administrator") | ||
12 | + profile_admin = Role.find_by_key("profile_admin") | ||
13 | + environment_admin.permissions.delete("manage_custom_roles") | ||
14 | + profile_admin.permissions.delete("manage_custom_roles") | ||
15 | + environment_admin.save! | ||
16 | + profile_admin.save! | ||
17 | + end | ||
18 | +end |
db/migrate/20150423144533_add_new_box_to_every_environment_and_profile.rb
0 → 100644
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +class AddNewBoxToEveryEnvironmentAndProfile < ActiveRecord::Migration | ||
2 | + def up | ||
3 | + Environment.find_each do |env| | ||
4 | + env.boxes << Box.new if env.boxes.count < 4 | ||
5 | + end | ||
6 | + | ||
7 | + Profile.find_each do |profile| | ||
8 | + profile.boxes << Box.new if profile.boxes.count < 4 | ||
9 | + end | ||
10 | + end | ||
11 | + | ||
12 | + def down | ||
13 | + say "this migration can't be reverted" | ||
14 | + end | ||
15 | +end |
db/schema.rb
@@ -593,6 +593,7 @@ ActiveRecord::Schema.define(:version => 20150408231524) do | @@ -593,6 +593,7 @@ ActiveRecord::Schema.define(:version => 20150408231524) do | ||
593 | t.boolean "system", :default => false | 593 | t.boolean "system", :default => false |
594 | t.text "permissions" | 594 | t.text "permissions" |
595 | t.integer "environment_id" | 595 | t.integer "environment_id" |
596 | + t.integer "profile_id" | ||
596 | end | 597 | end |
597 | 598 | ||
598 | create_table "scraps", :force => true do |t| | 599 | create_table "scraps", :force => true do |t| |
debian/changelog
1 | +noosfero (1.2~0) UNRELEASED; urgency=medium | ||
2 | + | ||
3 | + * Temporary version in heavy development | ||
4 | + | ||
5 | + -- Antonio Terceiro <terceiro@debian.org> Fri, 08 May 2015 16:08:18 -0300 | ||
6 | + | ||
7 | +noosfero (1.1) wheezy; urgency=low | ||
8 | + | ||
9 | + * Noosfero 1.1 final release | ||
10 | + | ||
11 | + -- Antonio Terceiro <terceiro@colivre.coop.br> Mon, 04 May 2015 18:47:35 -0300 | ||
12 | + | ||
1 | noosfero (1.1~rc4) wheezy; urgency=medium | 13 | noosfero (1.1~rc4) wheezy; urgency=medium |
2 | 14 | ||
3 | * Fourth release candidate for Noosfero 1.1 | 15 | * Fourth release candidate for Noosfero 1.1 |
debian/control
@@ -14,8 +14,8 @@ Build-Depends: cucumber, | @@ -14,8 +14,8 @@ Build-Depends: cucumber, | ||
14 | ruby-database-cleaner, | 14 | ruby-database-cleaner, |
15 | ruby-gettext, | 15 | ruby-gettext, |
16 | ruby-mocha, | 16 | ruby-mocha, |
17 | - ruby-rspec, | ||
18 | - ruby-rspec-rails, | 17 | + ruby-rspec (>= 2.14), |
18 | + ruby-rspec-rails (>= 2.14), | ||
19 | ruby-selenium-webdriver, | 19 | ruby-selenium-webdriver, |
20 | ruby-sqlite3, | 20 | ruby-sqlite3, |
21 | ruby-tidy, | 21 | ruby-tidy, |
@@ -59,7 +59,9 @@ Depends: adduser, | @@ -59,7 +59,9 @@ Depends: adduser, | ||
59 | ruby-redcloth, | 59 | ruby-redcloth, |
60 | ruby-rest-client, | 60 | ruby-rest-client, |
61 | ruby-rmagick, | 61 | ruby-rmagick, |
62 | + ruby-sass-rails, | ||
62 | ruby-tzinfo (>= 1.1.0-2~), | 63 | ruby-tzinfo (>= 1.1.0-2~), |
64 | + ruby-uglifier, | ||
63 | ruby-whenever, | 65 | ruby-whenever, |
64 | ruby-will-paginate (>= 2.3.12-1~), | 66 | ruby-will-paginate (>= 2.3.12-1~), |
65 | tango-icon-theme, | 67 | tango-icon-theme, |
debian/noosfero.install
@@ -25,6 +25,7 @@ etc/init.d/noosfero etc/init.d | @@ -25,6 +25,7 @@ etc/init.d/noosfero etc/init.d | ||
25 | etc/logrotate.d/noosfero etc/logrotate.d | 25 | etc/logrotate.d/noosfero etc/logrotate.d |
26 | etc/noosfero/varnish-accept-language.vcl etc/noosfero | 26 | etc/noosfero/varnish-accept-language.vcl etc/noosfero |
27 | etc/noosfero/varnish-noosfero.vcl etc/noosfero | 27 | etc/noosfero/varnish-noosfero.vcl etc/noosfero |
28 | +etc/awstats-noosfero.conf etc/noosfero | ||
28 | lib usr/share/noosfero | 29 | lib usr/share/noosfero |
29 | locale usr/share/noosfero | 30 | locale usr/share/noosfero |
30 | plugins usr/share/noosfero | 31 | plugins usr/share/noosfero |
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +Feature: Change appearance | ||
2 | + As a user | ||
3 | + I want to change the appearance of my profile page | ||
4 | + | ||
5 | + Background: | ||
6 | + Given the following users | ||
7 | + | login | name | | ||
8 | + | joaosilva | Joao Silva | | ||
9 | + | ||
10 | + Scenario: Change appearance from default(3 boxes) to Left Top and Right(4 boxes) | ||
11 | + Given I am logged in as "joaosilva" | ||
12 | + And I go to joaosilva's control panel | ||
13 | + And I follow "Edit sideboxes" | ||
14 | + And I should not see an element ".box-4" | ||
15 | + And I go to joaosilva's control panel | ||
16 | + And I follow "Edit Appearance" | ||
17 | + And I follow "Left Top and Right" | ||
18 | + And I go to joaosilva's control panel | ||
19 | + And I follow "Edit sideboxes" | ||
20 | + And I should see an element ".box-4" |
features/signup.feature
@@ -267,32 +267,6 @@ Feature: signup | @@ -267,32 +267,6 @@ Feature: signup | ||
267 | Then I should be on the homepage | 267 | Then I should be on the homepage |
268 | 268 | ||
269 | @selenium | 269 | @selenium |
270 | - Scenario: join community on signup | ||
271 | - Given the following users | ||
272 | - | login | name | | ||
273 | - | mariasilva | Maria Silva | | ||
274 | - And the following communities | ||
275 | - | name | identifier | owner | | ||
276 | - | Free Software | freesoftware | mariasilva | | ||
277 | - And feature "skip_new_user_email_confirmation" is disabled on environment | ||
278 | - And I am on /freesoftware | ||
279 | - When I follow "Join" | ||
280 | - And I follow "New user" | ||
281 | - And I fill in the following within ".no-boxes": | ||
282 | - | e-Mail | josesilva@example.com | | ||
283 | - | Username | josesilva | | ||
284 | - | Password | secret | | ||
285 | - | Password confirmation | secret | | ||
286 | - | Full name | José da Silva | | ||
287 | - And wait for the captcha signup time | ||
288 | - And I press "Create my account" | ||
289 | - And I go to josesilva's confirmation URL | ||
290 | - And I fill in "Username" with "josesilva" | ||
291 | - And I fill in "Password" with "secret" | ||
292 | - And I press "Log in" | ||
293 | - Then "José da Silva" should be a member of "Free Software" | ||
294 | - | ||
295 | - @selenium | ||
296 | Scenario: user registration is moderated by admin | 270 | Scenario: user registration is moderated by admin |
297 | Given feature "admin_must_approve_new_users" is enabled on environment | 271 | Given feature "admin_must_approve_new_users" is enabled on environment |
298 | And feature "skip_new_user_email_confirmation" is disabled on environment | 272 | And feature "skip_new_user_email_confirmation" is disabled on environment |
features/step_definitions/noosfero_steps.rb
@@ -94,8 +94,8 @@ Given /^the following blocks$/ do |table| | @@ -94,8 +94,8 @@ Given /^the following blocks$/ do |table| | ||
94 | owner.boxes<< Box.new | 94 | owner.boxes<< Box.new |
95 | owner.boxes.first.blocks << MainBlock.new | 95 | owner.boxes.first.blocks << MainBlock.new |
96 | end | 96 | end |
97 | - box_id = owner.boxes.last.id | ||
98 | - klass.constantize.create!(item.merge(:box_id => box_id)) | 97 | + box = owner.boxes.where(:position => 3).first |
98 | + klass.constantize.create!(item.merge(:box => box)) | ||
99 | end | 99 | end |
100 | end | 100 | end |
101 | 101 |
lib/authenticated_system.rb
@@ -60,7 +60,11 @@ module AuthenticatedSystem | @@ -60,7 +60,11 @@ module AuthenticatedSystem | ||
60 | if logged_in? && authorized? | 60 | if logged_in? && authorized? |
61 | true | 61 | true |
62 | else | 62 | else |
63 | - access_denied | 63 | + if params[:require_login_popup] |
64 | + render :json => { :require_login_popup => true } | ||
65 | + else | ||
66 | + access_denied | ||
67 | + end | ||
64 | end | 68 | end |
65 | end | 69 | end |
66 | 70 |
lib/noosfero.rb
@@ -57,6 +57,12 @@ module Noosfero | @@ -57,6 +57,12 @@ module Noosfero | ||
57 | '[a-z0-9][a-z0-9~.]*([_\-][a-z0-9~.]+)*' | 57 | '[a-z0-9][a-z0-9~.]*([_\-][a-z0-9~.]+)*' |
58 | end | 58 | end |
59 | 59 | ||
60 | + # All valid identifiers, plus ~ meaning "the current user". See | ||
61 | + # ApplicationController#redirect_to_current_user | ||
62 | + def self.identifier_format_in_url | ||
63 | + "(#{identifier_format}|~)" | ||
64 | + end | ||
65 | + | ||
60 | def self.default_hostname | 66 | def self.default_hostname |
61 | Environment.table_exists? && Environment.default ? Environment.default.default_hostname : 'localhost' | 67 | Environment.table_exists? && Environment.default ? Environment.default.default_hostname : 'localhost' |
62 | end | 68 | end |
lib/noosfero/plugin.rb
@@ -8,6 +8,10 @@ class Noosfero::Plugin | @@ -8,6 +8,10 @@ class Noosfero::Plugin | ||
8 | self.context = context | 8 | self.context = context |
9 | end | 9 | end |
10 | 10 | ||
11 | + def environment | ||
12 | + context.environment if self.context | ||
13 | + end | ||
14 | + | ||
11 | class << self | 15 | class << self |
12 | 16 | ||
13 | attr_writer :should_load | 17 | attr_writer :should_load |
@@ -35,6 +39,7 @@ class Noosfero::Plugin | @@ -35,6 +39,7 @@ class Noosfero::Plugin | ||
35 | # filters must be loaded after all extensions | 39 | # filters must be loaded after all extensions |
36 | klasses.each do |plugin| | 40 | klasses.each do |plugin| |
37 | load_plugin_filters plugin | 41 | load_plugin_filters plugin |
42 | + load_plugin_hotspots plugin | ||
38 | end | 43 | end |
39 | end | 44 | end |
40 | 45 | ||
@@ -108,6 +113,23 @@ class Noosfero::Plugin | @@ -108,6 +113,23 @@ class Noosfero::Plugin | ||
108 | end | 113 | end |
109 | end | 114 | end |
110 | 115 | ||
116 | + # This is a generic method to extend the hotspots list with plugins | ||
117 | + # hotspots. This allows plugins to extend other plugins. | ||
118 | + # To use this, the plugin must define its hotspots inside a module Hotspots. | ||
119 | + # Its also needed to include Noosfero::Plugin::HotSpot module | ||
120 | + # in order to dispatch plugins methods. | ||
121 | + # | ||
122 | + # Checkout FooPlugin for usage example. | ||
123 | + def load_plugin_hotspots(plugin) | ||
124 | + ActionDispatch::Reloader.to_prepare do | ||
125 | + begin | ||
126 | + module_name = "#{plugin.name}::Hotspots" | ||
127 | + Noosfero::Plugin.send(:include, module_name.constantize) | ||
128 | + rescue NameError | ||
129 | + end | ||
130 | + end | ||
131 | + end | ||
132 | + | ||
111 | def add_controller_filters(controller_class, plugin, filters) | 133 | def add_controller_filters(controller_class, plugin, filters) |
112 | unless filters.is_a?(Array) | 134 | unless filters.is_a?(Array) |
113 | filters = [filters] | 135 | filters = [filters] |
lib/noosfero/version.rb
lib/tasks/backup.rake
1 | -desc "Creates a backup of the user files stored in public/" | ||
2 | -task :backup do | ||
3 | - dirs = Dir.glob('public/images/[0-9][0-9][0-9][0-9]') + ['public/articles', 'public/thumbnails', 'public/user_themes'].select { |d| File.exists?(d) } | ||
4 | - tarball = 'backups/files-' + Time.now.strftime('%Y-%m-%d-%R') + '.tar' | 1 | +task :load_backup_config do |
2 | + $config = YAML.load_file('config/database.yml') | ||
3 | +end | ||
4 | + | ||
5 | +task :check_backup_support => :load_backup_config do | ||
6 | + if $config['production']['adapter'] != 'postgresql' | ||
7 | + fail("Only PostgreSQL is supported for backups at the moment") | ||
8 | + end | ||
9 | +end | ||
10 | + | ||
11 | +backup_dirs = [ | ||
12 | + 'public/image_uploads', | ||
13 | + 'public/articles', | ||
14 | + 'public/thumbnails', | ||
15 | + 'public/user_themes', | ||
16 | +] | ||
17 | + | ||
18 | +desc "Creates a backup of the database and uploaded files" | ||
19 | +task :backup => :check_backup_support do | ||
20 | + dirs = backup_dirs.select { |d| File.exists?(d) } | ||
21 | + | ||
22 | + backup_name = Time.now.strftime('%Y-%m-%d-%R') | ||
23 | + backup_file = File.join('tmp/backup', backup_name) + '.tar.gz' | ||
24 | + mkdir_p 'tmp/backup' | ||
25 | + dump = File.join('tmp/backup', backup_name) + '.sql' | ||
26 | + | ||
27 | + database = $config['production']['database'] | ||
28 | + host = $config['production']['host'] | ||
29 | + sh "pg_dump -h #{host} #{database} > #{dump}" | ||
30 | + | ||
31 | + sh 'tar', 'chaf', backup_file, dump, *dirs | ||
32 | + rm_f dump | ||
33 | + | ||
34 | + puts "****************************************************" | ||
35 | + puts "Backup in #{backup_file} !" | ||
36 | + puts | ||
37 | + puts "To restore, use:" | ||
38 | + puts "$ rake restore BACKUP=#{backup_file}" | ||
39 | + puts "****************************************************" | ||
40 | +end | ||
41 | + | ||
42 | +def invalid_backup!(message, items=[]) | ||
43 | + puts "E: #{message}" | ||
44 | + items.each do |i| | ||
45 | + puts "E: - #{i}" | ||
46 | + end | ||
47 | + puts "E: Is this a backup archive created by Noosfero with \`rake backup\`?" | ||
48 | + exit 1 | ||
49 | +end | ||
50 | + | ||
51 | +desc "Restores a backup created previousy with \`rake backup\`" | ||
52 | +task :restore => :check_backup_support do | ||
53 | + backup = ENV["BACKUP"] | ||
54 | + unless backup | ||
55 | + puts "usage: rake restore BACKUP=/path/to/backup" | ||
56 | + exit 1 | ||
57 | + end | ||
58 | + | ||
59 | + files = `tar taf #{backup}`.split | ||
60 | + | ||
61 | + # validate files in the backup | ||
62 | + invalid_files = [] | ||
63 | + files.each do |f| | ||
64 | + if f !~ /tmp\/backup\// && (backup_dirs.none? { |d| f =~ /^#{d}\// }) | ||
65 | + invalid_files << f | ||
66 | + end | ||
67 | + end | ||
68 | + if invalid_files.size > 0 | ||
69 | + invalid_backup!("Invalid files found in the backup archive", invalid_files) | ||
70 | + end | ||
71 | + | ||
72 | + # find database dump in the archive | ||
73 | + dumps = files.select do |f| | ||
74 | + File.dirname(f) == 'tmp/backup' && f =~ /\.sql$/ | ||
75 | + end | ||
76 | + if dumps.size == 0 | ||
77 | + invalid_backup!("Could not find a database dump in the archive.") | ||
78 | + elsif dumps.size > 1 | ||
79 | + invalid_backup!("Multiple database dumps found in the archive:", dumps) | ||
80 | + end | ||
81 | + dump = dumps.first | ||
82 | + | ||
83 | + database = $config['production']['database'] | ||
84 | + username = $config['production']['username'] | ||
85 | + host = $config['production']['host'] | ||
86 | + | ||
87 | + puts "WARNING: backups should be restored to an empty database, otherwise" | ||
88 | + puts "data from the backup may not be loaded properly." | ||
89 | + puts | ||
90 | + puts 'You can remove the existing database and create a new one with:' | ||
91 | + puts | ||
92 | + puts "$ sudo -u postgres dropdb -h #{host} #{database}" | ||
93 | + puts "$ sudo -u postgres createdb -h #{host} #{database} --owner #{username}" | ||
94 | + puts | ||
95 | + print "Are you sure you want to continue (y/N)? " | ||
96 | + response = $stdin.gets.strip | ||
97 | + unless ['y', 'yes'].include?(response.downcase) | ||
98 | + puts "*** ABORTED." | ||
99 | + exit 1 | ||
100 | + end | ||
101 | + | ||
102 | + sh 'tar', 'xaf', backup | ||
103 | + sh "rails dbconsole production < #{dump}" | ||
104 | + rm_f dump | ||
5 | 105 | ||
6 | - mkdir_p(File.dirname(tarball)) | ||
7 | - sh('tar', 'cf', tarball, *dirs) | 106 | + puts "****************************************************" |
107 | + puts "Backup restored!" | ||
108 | + puts "****************************************************" | ||
8 | end | 109 | end |
lib/tasks/doc.rake
@@ -12,9 +12,8 @@ namespace :noosfero do | @@ -12,9 +12,8 @@ namespace :noosfero do | ||
12 | end | 12 | end |
13 | end | 13 | end |
14 | task :unlink_plugins_textiles do | 14 | task :unlink_plugins_textiles do |
15 | - root = Pathname.new(File.dirname(__FILE__) + '/../..').expand_path | ||
16 | - rm_f Dir.glob(root.join('doc/noosfero/plugins/*.textile')) - | ||
17 | - [root.join('doc/noosfero/plugins/index.textile')] | 15 | + rm_f Dir.glob('doc/noosfero/plugins/*.textile') - |
16 | + ['doc/noosfero/plugins/index.textile'] | ||
18 | end | 17 | end |
19 | input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"} | 18 | input = Dir.glob('doc/noosfero/**/*.textile') + plugins_textiles.map{|i| "doc/noosfero/plugins/#{File.basename(i)}"} |
20 | topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq | 19 | topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }.uniq |
lib/tasks/error_messages.rake
@@ -4,7 +4,7 @@ targets = [] | @@ -4,7 +4,7 @@ targets = [] | ||
4 | templates.each do |template| | 4 | templates.each do |template| |
5 | target = template.gsub(/.erb$/, '') | 5 | target = template.gsub(/.erb$/, '') |
6 | targets << target | 6 | targets << target |
7 | - file target => [:makemo, template] do | 7 | + file target => [:makemo, template, :environment] do |
8 | require 'erb' | 8 | require 'erb' |
9 | erb = ERB.new(File.read(template)) | 9 | erb = ERB.new(File.read(template)) |
10 | File.open(target, 'w') do |file| | 10 | File.open(target, 'w') do |file| |
plugins/event/po/pt/event.po
@@ -5,8 +5,8 @@ | @@ -5,8 +5,8 @@ | ||
5 | # | 5 | # |
6 | msgid "" | 6 | msgid "" |
7 | msgstr "" | 7 | msgstr "" |
8 | -"Project-Id-Version: 1.0-690-gcb6e853\n" | ||
9 | -"POT-Creation-Date: 2015-03-05 12:09-0300\n" | 8 | +"Project-Id-Version: 1.1~rc4\n" |
9 | +"POT-Creation-Date: 2015-04-20 19:44-0300\n" | ||
10 | "PO-Revision-Date: 2015-01-30 00:18-0000\n" | 10 | "PO-Revision-Date: 2015-01-30 00:18-0000\n" |
11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 11 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
12 | "Language-Team: LANGUAGE <LL@li.org>\n" | 12 | "Language-Team: LANGUAGE <LL@li.org>\n" |
@@ -16,61 +16,53 @@ msgstr "" | @@ -16,61 +16,53 @@ msgstr "" | ||
16 | "Content-Transfer-Encoding: 8bit\n" | 16 | "Content-Transfer-Encoding: 8bit\n" |
17 | "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | 17 | "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" |
18 | 18 | ||
19 | +#: plugins/event/lib/event_plugin.rb:4 | ||
20 | +msgid "Event Extras" | ||
21 | +msgstr "Extras para Eventos" | ||
22 | + | ||
23 | +#: plugins/event/lib/event_plugin.rb:8 | ||
24 | +msgid "" | ||
25 | +"Include a new block to show the environment's or profiles' events information" | ||
26 | +msgstr "" | ||
27 | +"Adiciona um novo bloco para apresentar as informações de eventos do ambiente " | ||
28 | +"ou dos perfis" | ||
29 | + | ||
19 | #: plugins/event/lib/event_plugin/event_block.rb:12 | 30 | #: plugins/event/lib/event_plugin/event_block.rb:12 |
20 | msgid "Events" | 31 | msgid "Events" |
21 | msgstr "Eventos" | 32 | msgstr "Eventos" |
22 | 33 | ||
23 | #: plugins/event/lib/event_plugin/event_block.rb:16 | 34 | #: plugins/event/lib/event_plugin/event_block.rb:16 |
24 | msgid "Show the profile events or all environment events." | 35 | msgid "Show the profile events or all environment events." |
25 | -msgstr "Mostrar todos os eventos." | 36 | +msgstr "Mostra todos os eventos de um perfil ou do ambiente." |
26 | 37 | ||
27 | #: plugins/event/lib/event_plugin/event_block.rb:65 | 38 | #: plugins/event/lib/event_plugin/event_block.rb:65 |
28 | -#, fuzzy | ||
29 | msgid "One month ago" | 39 | msgid "One month ago" |
30 | msgid_plural "%d months ago" | 40 | msgid_plural "%d months ago" |
31 | -msgstr[0] "Iniciou a um mês atrás." | ||
32 | -msgstr[1] "Iniciou a %d meses atrás." | 41 | +msgstr[0] "Um mês atrás" |
42 | +msgstr[1] "%d meses atrás." | ||
33 | 43 | ||
34 | #: plugins/event/lib/event_plugin/event_block.rb:67 | 44 | #: plugins/event/lib/event_plugin/event_block.rb:67 |
35 | msgid "Yesterday" | 45 | msgid "Yesterday" |
36 | msgid_plural "%d days ago" | 46 | msgid_plural "%d days ago" |
37 | -msgstr[0] "" | ||
38 | -msgstr[1] "" | 47 | +msgstr[0] "Ontem" |
48 | +msgstr[1] "%d dias atrás" | ||
39 | 49 | ||
40 | #: plugins/event/lib/event_plugin/event_block.rb:69 | 50 | #: plugins/event/lib/event_plugin/event_block.rb:69 |
41 | msgid "Today" | 51 | msgid "Today" |
42 | -msgstr "" | 52 | +msgstr "Hoje" |
43 | 53 | ||
44 | #: plugins/event/lib/event_plugin/event_block.rb:71 | 54 | #: plugins/event/lib/event_plugin/event_block.rb:71 |
45 | msgid "Tomorrow" | 55 | msgid "Tomorrow" |
46 | msgid_plural "%d days left to start" | 56 | msgid_plural "%d days left to start" |
47 | -msgstr[0] "" | ||
48 | -msgstr[1] "" | 57 | +msgstr[0] "Amanhã" |
58 | +msgstr[1] "%d dias para começar" | ||
49 | 59 | ||
50 | #: plugins/event/lib/event_plugin/event_block.rb:73 | 60 | #: plugins/event/lib/event_plugin/event_block.rb:73 |
51 | -#, fuzzy | ||
52 | msgid "One month left to start" | 61 | msgid "One month left to start" |
53 | msgid_plural "%d months left to start" | 62 | msgid_plural "%d months left to start" |
54 | msgstr[0] "Um mês para iniciar" | 63 | msgstr[0] "Um mês para iniciar" |
55 | msgstr[1] "% meses para iniciar" | 64 | msgstr[1] "% meses para iniciar" |
56 | 65 | ||
57 | -#: plugins/event/lib/event_plugin.rb:4 | ||
58 | -msgid "Event Extras" | ||
59 | -msgstr "Eventos" | ||
60 | - | ||
61 | -#: plugins/event/lib/event_plugin.rb:8 | ||
62 | -msgid "" | ||
63 | -"Include a new block to show the environment's or profiles' events information" | ||
64 | -msgstr "" | ||
65 | -"Adiciona um novo bloco para apresentar as informações de eventos do ambiente " | ||
66 | -"ou de perfis" | ||
67 | - | ||
68 | -#: plugins/event/views/event_plugin/event_block_item.html.erb:6 | ||
69 | -msgid "Duration: 1 day" | ||
70 | -msgid_plural "Duration: %s days" | ||
71 | -msgstr[0] "" | ||
72 | -msgstr[1] "" | ||
73 | - | ||
74 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:1 | 66 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:1 |
75 | msgid "Limit of items" | 67 | msgid "Limit of items" |
76 | msgstr "Limite de itens" | 68 | msgstr "Limite de itens" |
@@ -94,12 +86,17 @@ msgstr "Mostrar apenas eventos futuros" | @@ -94,12 +86,17 @@ msgstr "Mostrar apenas eventos futuros" | ||
94 | 86 | ||
95 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:22 | 87 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:22 |
96 | msgid "Limit of days to display" | 88 | msgid "Limit of days to display" |
97 | -msgstr "Limite de dias de distância para mostrar eventos" | 89 | +msgstr "Limite de dias para mostrar" |
98 | 90 | ||
99 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:24 | 91 | #: plugins/event/views/profile_design/event_plugin/_event_block.html.erb:24 |
100 | -#, fuzzy | ||
101 | msgid "Only show events in this interval of days." | 92 | msgid "Only show events in this interval of days." |
102 | -msgstr "Mostar somente eventos que acontecem dentro do limite de dias" | 93 | +msgstr "Mostar somente os eventos nesse intervalo de dias" |
94 | + | ||
95 | +#: plugins/event/views/event_plugin/event_block_item.html.erb:6 | ||
96 | +msgid "Duration: 1 day" | ||
97 | +msgid_plural "Duration: %s days" | ||
98 | +msgstr[0] "Duração: 1 dia" | ||
99 | +msgstr[1] "Duração: %s dias" | ||
103 | 100 | ||
104 | #~ msgid "Started one day ago." | 101 | #~ msgid "Started one day ago." |
105 | #~ msgid_plural "Started %d days ago." | 102 | #~ msgid_plural "Started %d days ago." |
plugins/foo/lib/foo_plugin.rb
1 | class FooPlugin < Noosfero::Plugin | 1 | class FooPlugin < Noosfero::Plugin |
2 | + include Noosfero::Plugin::HotSpot | ||
2 | 3 | ||
3 | def self.plugin_name | 4 | def self.plugin_name |
4 | "Foo" | 5 | "Foo" |
@@ -8,12 +9,29 @@ class FooPlugin < Noosfero::Plugin | @@ -8,12 +9,29 @@ class FooPlugin < Noosfero::Plugin | ||
8 | _("A sample plugin to test autoload craziness.") | 9 | _("A sample plugin to test autoload craziness.") |
9 | end | 10 | end |
10 | 11 | ||
12 | + module Hotspots | ||
13 | + # -> Custom foo plugin hotspot | ||
14 | + # do something to extend the FooPlugin behaviour | ||
15 | + # receive params a, b and c | ||
16 | + # returns = boolean or something else | ||
17 | + def foo_plugin_my_hotspot(a, b, c) | ||
18 | + end | ||
19 | + | ||
20 | + # -> Custom title for foo profiles tab | ||
21 | + # returns = a string with a custom title | ||
22 | + def foo_plugin_tab_title | ||
23 | + end | ||
24 | + end | ||
25 | + | ||
11 | def control_panel_buttons | 26 | def control_panel_buttons |
12 | {:title => 'Foo plugin button', :icon => '', :url => ''} | 27 | {:title => 'Foo plugin button', :icon => '', :url => ''} |
13 | end | 28 | end |
14 | 29 | ||
15 | def profile_tabs | 30 | def profile_tabs |
16 | - {:title => 'Foo plugin tab', :id => 'foo_plugin', :content => lambda {'Foo plugin random content'} } | 31 | + title = plugins.dispatch_first(:foo_plugin_tab_title) |
32 | + title = 'Foo plugin tab' unless title | ||
33 | + | ||
34 | + {:title => title, :id => 'foo_plugin', :content => lambda {'Foo plugin random content'} } | ||
17 | end | 35 | end |
18 | 36 | ||
19 | end | 37 | end |
plugins/foo/test/unit/foo_plugin_test.rb
@@ -4,7 +4,25 @@ class FooPluginTest < ActiveSupport::TestCase | @@ -4,7 +4,25 @@ class FooPluginTest < ActiveSupport::TestCase | ||
4 | def test_foo | 4 | def test_foo |
5 | FooPlugin::Bar.create! | 5 | FooPlugin::Bar.create! |
6 | end | 6 | end |
7 | + | ||
7 | def test_monkey_patch | 8 | def test_monkey_patch |
8 | Profile.new.bar | 9 | Profile.new.bar |
9 | end | 10 | end |
11 | + | ||
12 | + should "respond to new hotspots" do | ||
13 | + plugin = FooPlugin.new | ||
14 | + | ||
15 | + assert plugin.respond_to?(:foo_plugin_my_hotspot) | ||
16 | + assert plugin.respond_to?(:foo_plugin_tab_title) | ||
17 | + end | ||
18 | + | ||
19 | + should "other plugin respond to new hotspots" do | ||
20 | + class TestPlugin < Noosfero::Plugin | ||
21 | + end | ||
22 | + | ||
23 | + plugin = TestPlugin.new | ||
24 | + | ||
25 | + assert plugin.respond_to?(:foo_plugin_my_hotspot) | ||
26 | + assert plugin.respond_to?(:foo_plugin_tab_title) | ||
27 | + end | ||
10 | end | 28 | end |
plugins/google_analytics/lib/ext/profile.rb
@@ -2,4 +2,9 @@ require_dependency 'profile' | @@ -2,4 +2,9 @@ require_dependency 'profile' | ||
2 | 2 | ||
3 | class Profile | 3 | class Profile |
4 | settings_items :google_analytics_profile_id | 4 | settings_items :google_analytics_profile_id |
5 | + attr_accessible :google_analytics_profile_id | ||
6 | + | ||
7 | + descendants.each do |descendant| | ||
8 | + descendant.attr_accessible :google_analytics_profile_id | ||
9 | + end | ||
5 | end | 10 | end |
plugins/google_analytics/lib/google_analytics_plugin.rb
@@ -19,12 +19,15 @@ class GoogleAnalyticsPlugin < Noosfero::Plugin | @@ -19,12 +19,15 @@ class GoogleAnalyticsPlugin < Noosfero::Plugin | ||
19 | 19 | ||
20 | def head_ending | 20 | def head_ending |
21 | unless profile_id.blank? | 21 | unless profile_id.blank? |
22 | - expanded_template('tracking-code.rhtml',{:profile_id => profile_id}) | 22 | + expanded_template('tracking-code.html.erb',{:profile_id => profile_id}) |
23 | end | 23 | end |
24 | end | 24 | end |
25 | 25 | ||
26 | def profile_editor_extras | 26 | def profile_editor_extras |
27 | - expanded_template('profile-editor-extras.rhtml',{:profile_id => profile_id}) | 27 | + analytics_id = profile_id |
28 | + lambda { | ||
29 | + render :file => 'profile-editor-extras', :locals => { :profile_id => analytics_id } | ||
30 | + } | ||
28 | end | 31 | end |
29 | 32 | ||
30 | end | 33 | end |
plugins/google_analytics/test/functional/profile_editor_controller_test.rb
0 → 100644
@@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
1 | +require 'test_helper' | ||
2 | +require 'profile_editor_controller' | ||
3 | + | ||
4 | +# Re-raise errors caught by the controller. | ||
5 | +class ProfileEditorController; def rescue_action(e) raise e end; end | ||
6 | + | ||
7 | +class ProfileEditorControllerTest < ActionController::TestCase | ||
8 | + | ||
9 | + def setup | ||
10 | + @controller = ProfileEditorController.new | ||
11 | + @request = ActionController::TestRequest.new | ||
12 | + @response = ActionController::TestResponse.new | ||
13 | + @profile = create_user('default_user').person | ||
14 | + login_as(@profile.identifier) | ||
15 | + Environment.default.enable_plugin(GoogleAnalyticsPlugin.name) | ||
16 | + end | ||
17 | + | ||
18 | + attr_accessor :profile | ||
19 | + | ||
20 | + should 'add extra fields to profile editor info and settings' do | ||
21 | + get :edit, :profile => profile.identifier | ||
22 | + assert_tag_in_string @response.body, :tag => 'label', :content => /Google Analytics/, :attributes => { :for => 'profile_data_google_analytics_profile_id' } | ||
23 | + assert_tag_in_string @response.body, :tag => 'input', :attributes => { :id => 'profile_data_google_analytics_profile_id' } | ||
24 | + end | ||
25 | + | ||
26 | + should 'save code filled in on field' do | ||
27 | + post :edit, :profile => profile.identifier, :profile_data => {:google_analytics_profile_id => 12345678} | ||
28 | + assert_equal '12345678', Person.find(profile.id).google_analytics_profile_id | ||
29 | + end | ||
30 | + | ||
31 | +end |
plugins/google_analytics/test/unit/google_analytics_plugin_test.rb
@@ -27,11 +27,6 @@ class GoogleAnalyticsPluginTest < ActiveSupport::TestCase | @@ -27,11 +27,6 @@ class GoogleAnalyticsPluginTest < ActiveSupport::TestCase | ||
27 | assert_equal 'content', @plugin.head_ending | 27 | assert_equal 'content', @plugin.head_ending |
28 | end | 28 | end |
29 | 29 | ||
30 | - should 'add extra fields to profile editor info and settings' do | ||
31 | - assert_tag_in_string @plugin.profile_editor_extras, | ||
32 | - :tag => 'input', :attributes => {:id => 'profile_data_google_analytics_profile_id', :value => 10} | ||
33 | - end | ||
34 | - | ||
35 | should 'extends Profile with attr google_analytics_profile_id' do | 30 | should 'extends Profile with attr google_analytics_profile_id' do |
36 | assert_respond_to Profile.new, :google_analytics_profile_id | 31 | assert_respond_to Profile.new, :google_analytics_profile_id |
37 | end | 32 | end |
plugins/google_analytics/views/profile-editor-extras.html.erb
0 → 100644
@@ -0,0 +1,3 @@ | @@ -0,0 +1,3 @@ | ||
1 | +<h2><%= c_('Statistics') %></h2> | ||
2 | +<%= labelled_form_field(_('Google Analytics Profile ID'), text_field(:profile_data, :google_analytics_profile_id, :value => profile_id)) %> | ||
3 | +<%= link_to(_('See how to configure statistics for your profile'), '/doc/plugins/google_analytics', :target => '_blank') %> |
plugins/google_analytics/views/profile-editor-extras.rhtml
@@ -1,5 +0,0 @@ | @@ -1,5 +0,0 @@ | ||
1 | -<% extend ApplicationHelper %> | ||
2 | - | ||
3 | -<h2><%= c_('Statistics') %></h2> | ||
4 | -<%= labelled_form_field(_('Google Analytics Profile ID'), text_field(:profile_data, :google_analytics_profile_id, :value => profile_id)) %> | ||
5 | -<%= link_to(_('See how to configure statistics for your profile'), '/doc/plugins/google_analytics', :target => '_blank') %> |
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +<script> | ||
2 | + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ | ||
3 | + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), | ||
4 | + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) | ||
5 | + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); | ||
6 | + | ||
7 | + ga('create', '<%= escape_javascript locals[:profile_id] %>', 'auto'); | ||
8 | + ga('send', 'pageview'); | ||
9 | +</script> |
plugins/google_analytics/views/tracking-code.rhtml
@@ -1,10 +0,0 @@ | @@ -1,10 +0,0 @@ | ||
1 | -<script type="text/javascript"> | ||
2 | - var _gaq = _gaq || []; | ||
3 | - _gaq.push(['_setAccount', '<%= escape_javascript locals[:profile_id] %>']); | ||
4 | - _gaq.push(['_trackPageview']); | ||
5 | - (function() { | ||
6 | - var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | ||
7 | - ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | ||
8 | - var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | ||
9 | - })(); | ||
10 | -</script> |
plugins/ldap/lib/ldap_authentication.rb
@@ -77,18 +77,20 @@ class LdapAuthentication | @@ -77,18 +77,20 @@ class LdapAuthentication | ||
77 | end | 77 | end |
78 | 78 | ||
79 | def get_user_attributes_from_ldap_entry(entry) | 79 | def get_user_attributes_from_ldap_entry(entry) |
80 | - { | ||
81 | - :dn => entry.dn, | ||
82 | - :fullname => LdapAuthentication.get_attr(entry, self.attr_fullname), | ||
83 | - :mail => LdapAuthentication.get_attr(entry, self.attr_mail), | ||
84 | - } | 80 | + attributes = entry.instance_values["myhash"] |
81 | + | ||
82 | + attributes[:dn] = entry.dn | ||
83 | + attributes[:fullname] = LdapAuthentication.get_attr(entry, self.attr_fullname) | ||
84 | + attributes[:mail] = LdapAuthentication.get_attr(entry, self.attr_mail) | ||
85 | + | ||
86 | + attributes | ||
85 | end | 87 | end |
86 | 88 | ||
87 | # Return the attributes needed for the LDAP search. It will only | 89 | # Return the attributes needed for the LDAP search. It will only |
88 | # include the user attributes if on-the-fly registration is enabled | 90 | # include the user attributes if on-the-fly registration is enabled |
89 | def search_attributes | 91 | def search_attributes |
90 | if onthefly_register? | 92 | if onthefly_register? |
91 | - ['dn', self.attr_fullname, self.attr_mail] | 93 | + nil |
92 | else | 94 | else |
93 | ['dn'] | 95 | ['dn'] |
94 | end | 96 | end |
@@ -111,6 +113,7 @@ class LdapAuthentication | @@ -111,6 +113,7 @@ class LdapAuthentication | ||
111 | end | 113 | end |
112 | login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) | 114 | login_filter = Net::LDAP::Filter.eq( self.attr_login, login ) |
113 | object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) | 115 | object_filter = Net::LDAP::Filter.eq( "objectClass", "*" ) |
116 | + | ||
114 | attrs = {} | 117 | attrs = {} |
115 | 118 | ||
116 | search_filter = object_filter & login_filter | 119 | search_filter = object_filter & login_filter |
plugins/ldap/lib/ldap_plugin.rb
1 | require File.dirname(__FILE__) + '/ldap_authentication.rb' | 1 | require File.dirname(__FILE__) + '/ldap_authentication.rb' |
2 | 2 | ||
3 | class LdapPlugin < Noosfero::Plugin | 3 | class LdapPlugin < Noosfero::Plugin |
4 | + include Noosfero::Plugin::HotSpot | ||
4 | 5 | ||
5 | def self.plugin_name | 6 | def self.plugin_name |
6 | "LdapPlugin" | 7 | "LdapPlugin" |
@@ -10,6 +11,26 @@ class LdapPlugin < Noosfero::Plugin | @@ -10,6 +11,26 @@ class LdapPlugin < Noosfero::Plugin | ||
10 | _("A plugin that add ldap support.") | 11 | _("A plugin that add ldap support.") |
11 | end | 12 | end |
12 | 13 | ||
14 | + module Hotspots | ||
15 | + # -> Custom ldap plugin hotspot to set profile data before user creation | ||
16 | + # receive the followings params: | ||
17 | + # - attrs with ldap received data | ||
18 | + # - login received by ldap | ||
19 | + # - params from current context | ||
20 | + # returns = updated person_data hash | ||
21 | + def ldap_plugin_set_profile_data(attrs, params) | ||
22 | + [attrs, params] | ||
23 | + end | ||
24 | + | ||
25 | + # -> Custom ldap plugin hotspot to update user object | ||
26 | + # receive the followings params: | ||
27 | + # - user: user object | ||
28 | + # - attrs with ldap received data | ||
29 | + # returns = none | ||
30 | + def ldap_plugin_update_user(user, attrs) | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
13 | def allow_user_registration | 34 | def allow_user_registration |
14 | false | 35 | false |
15 | end | 36 | end |
@@ -35,17 +56,22 @@ class LdapPlugin < Noosfero::Plugin | @@ -35,17 +56,22 @@ class LdapPlugin < Noosfero::Plugin | ||
35 | 56 | ||
36 | if attrs | 57 | if attrs |
37 | user.login = login | 58 | user.login = login |
38 | - user.email = attrs[:mail] | 59 | + user.email = get_email(attrs, login) |
39 | user.name = attrs[:fullname] | 60 | user.name = attrs[:fullname] |
40 | user.password = password | 61 | user.password = password |
41 | user.password_confirmation = password | 62 | user.password_confirmation = password |
42 | - user.person_data = context.params[:profile_data] | 63 | + user.person_data = plugins.pipeline(:ldap_plugin_set_profile_data, attrs, context.params).last[:profile_data] |
43 | user.activated_at = Time.now.utc | 64 | user.activated_at = Time.now.utc |
44 | user.activation_code = nil | 65 | user.activation_code = nil |
45 | 66 | ||
46 | ldap = LdapAuthentication.new(context.environment.ldap_plugin_attributes) | 67 | ldap = LdapAuthentication.new(context.environment.ldap_plugin_attributes) |
47 | begin | 68 | begin |
48 | - user = nil unless user.save | 69 | + if user.save |
70 | + user.activate | ||
71 | + plugins.dispatch(:ldap_plugin_update_user, user, attrs) | ||
72 | + else | ||
73 | + user = nil | ||
74 | + end | ||
49 | rescue | 75 | rescue |
50 | #User not saved | 76 | #User not saved |
51 | end | 77 | end |
@@ -54,7 +80,6 @@ class LdapPlugin < Noosfero::Plugin | @@ -54,7 +80,6 @@ class LdapPlugin < Noosfero::Plugin | ||
54 | end | 80 | end |
55 | 81 | ||
56 | else | 82 | else |
57 | - | ||
58 | return nil if !user.activated? | 83 | return nil if !user.activated? |
59 | 84 | ||
60 | begin | 85 | begin |
@@ -69,6 +94,16 @@ class LdapPlugin < Noosfero::Plugin | @@ -69,6 +94,16 @@ class LdapPlugin < Noosfero::Plugin | ||
69 | user | 94 | user |
70 | end | 95 | end |
71 | 96 | ||
97 | + def get_email(attrs, login) | ||
98 | + return attrs[:mail] unless attrs[:mail].blank? | ||
99 | + | ||
100 | + if attrs[:fullname] | ||
101 | + return attrs[:fullname].to_slug + "@ldap.user" | ||
102 | + else | ||
103 | + return login.to_slug + "@ldap.user" | ||
104 | + end | ||
105 | + end | ||
106 | + | ||
72 | def login_extra_contents | 107 | def login_extra_contents |
73 | proc do | 108 | proc do |
74 | @person = Person.new(:environment => @environment) | 109 | @person = Person.new(:environment => @environment) |
plugins/require_auth_to_comment/controllers/require_auth_to_comment_plugin_admin_controller.rb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +class RequireAuthToCommentPluginAdminController < AdminController | ||
2 | + | ||
3 | + def index | ||
4 | + settings = params[:settings] | ||
5 | + settings ||= {} | ||
6 | + @settings = Noosfero::Plugin::Settings.new(environment, RequireAuthToCommentPlugin, settings) | ||
7 | + if request.post? | ||
8 | + @settings.save! | ||
9 | + session[:notice] = 'Settings succefully saved.' | ||
10 | + redirect_to :action => 'index' | ||
11 | + end | ||
12 | + end | ||
13 | + | ||
14 | +end |
plugins/require_auth_to_comment/lib/require_auth_to_comment_plugin.rb
@@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin < Noosfero::Plugin | @@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin < Noosfero::Plugin | ||
21 | end | 21 | end |
22 | 22 | ||
23 | def stylesheet? | 23 | def stylesheet? |
24 | - true | 24 | + !display_login_popup? |
25 | + end | ||
26 | + | ||
27 | + def display_login_popup? | ||
28 | + settings = Noosfero::Plugin::Settings.new(context.environment, self.class) | ||
29 | + settings.require_type == 'display_login_popup' | ||
30 | + end | ||
31 | + | ||
32 | + def self.require_type_default_setting | ||
33 | + 'hide_button' | ||
25 | end | 34 | end |
26 | 35 | ||
27 | def js_files | 36 | def js_files |
28 | - ['hide_comment_form.js', 'jquery.livequery.min.js'] | 37 | + ['hide_comment_form.js', 'jquery.livequery.min.js'] + (display_login_popup? ? ['comment_require_login.js'] : []) |
29 | end | 38 | end |
30 | 39 | ||
31 | def body_beginning | 40 | def body_beginning |
plugins/require_auth_to_comment/public/comment_require_login.js
0 → 100644
@@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
1 | +(function($) { | ||
2 | + $(window).bind('userDataLoaded', function(event, data) { | ||
3 | + if (!data.login && $('meta[name="profile.allow_unauthenticated_comments"]').length <= 0) { | ||
4 | + $('.display-comment-form').unbind(); | ||
5 | + $('.display-comment-form').addClass('require-login-popup'); | ||
6 | + } | ||
7 | + }); | ||
8 | +})(jQuery); |
plugins/require_auth_to_comment/test/unit/require_auth_to_comment_plugin_test.rb
@@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | @@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | ||
5 | def setup | 5 | def setup |
6 | @plugin = RequireAuthToCommentPlugin.new | 6 | @plugin = RequireAuthToCommentPlugin.new |
7 | @comment = Comment.new | 7 | @comment = Comment.new |
8 | + @environment = fast_create(Environment) | ||
8 | end | 9 | end |
9 | 10 | ||
10 | - attr_reader :plugin, :comment | 11 | + attr_reader :plugin, :comment, :environment |
11 | 12 | ||
12 | should 'reject comments for unauthenticated users' do | 13 | should 'reject comments for unauthenticated users' do |
13 | plugin.context = logged_in(false) | 14 | plugin.context = logged_in(false) |
@@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | @@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest < ActiveSupport::TestCase | ||
29 | assert !comment.rejected? | 30 | assert !comment.rejected? |
30 | end | 31 | end |
31 | 32 | ||
33 | + should 'the default require type setting be hide_button' do | ||
34 | + assert_equal 'hide_button', plugin.class.require_type_default_setting | ||
35 | + end | ||
36 | + | ||
37 | + should 'display_login_popup? be false by default' do | ||
38 | + context = mock(); | ||
39 | + context.expects(:environment).returns(environment) | ||
40 | + plugin.expects(:context).returns(context) | ||
41 | + assert !plugin.display_login_popup? | ||
42 | + end | ||
43 | + | ||
44 | + should 'display_login_popup? be true if require_type is defined as display_login_popup' do | ||
45 | + context = mock(); | ||
46 | + context.expects(:environment).returns(environment) | ||
47 | + environment[:settings] = {:require_auth_to_comment_plugin => {:require_type => "display_login_popup"}} | ||
48 | + plugin.expects(:context).returns(context) | ||
49 | + assert plugin.display_login_popup? | ||
50 | + end | ||
51 | + | ||
52 | + should 'not display stylesheet if login popup is active' do | ||
53 | + plugin.expects(:display_login_popup?).returns(true) | ||
54 | + assert !plugin.stylesheet? | ||
55 | + end | ||
56 | + | ||
57 | + should 'display stylesheet if login popup is inactive' do | ||
58 | + plugin.expects(:display_login_popup?).returns(false) | ||
59 | + assert plugin.stylesheet? | ||
60 | + end | ||
61 | + | ||
32 | protected | 62 | protected |
33 | 63 | ||
34 | def logged_in(boolean) | 64 | def logged_in(boolean) |
plugins/require_auth_to_comment/views/require_auth_to_comment_plugin_admin/index.html.erb
0 → 100644
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +<h1><%= _('Require auth to comment Settings')%></h1> | ||
2 | + | ||
3 | +<%= form_for(:settings) do |f| %> | ||
4 | + | ||
5 | + <div class="require-type"> | ||
6 | + <strong> | ||
7 | + <div class="hide-button"> | ||
8 | + <%= radio_button(:settings, :require_type, 'hide_button') %> <%= _('Hide button') %> | ||
9 | + </div> | ||
10 | + <div class="display-login-popup"> | ||
11 | + <%= radio_button(:settings, :require_type, 'display_login_popup') %> <%= _('Display login popup') %> | ||
12 | + </div> | ||
13 | + </strong> | ||
14 | + </div> | ||
15 | + | ||
16 | + <% button_bar do %> | ||
17 | + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %> | ||
18 | + <% end %> | ||
19 | + | ||
20 | +<% end %> |
plugins/send_email/controllers/send_email_plugin_base_controller.rb
@@ -11,7 +11,8 @@ module SendEmailPluginBaseController | @@ -11,7 +11,8 @@ module SendEmailPluginBaseController | ||
11 | ) | 11 | ) |
12 | @mail.subject = params[:subject] unless params[:subject].blank? | 12 | @mail.subject = params[:subject] unless params[:subject].blank? |
13 | if @mail.valid? | 13 | if @mail.valid? |
14 | - SendEmailPlugin::Sender.send_message(request.referer, @context_url, @mail).deliver | 14 | + @referer = request.referer |
15 | + SendEmailPlugin::Sender.send_message(@referer, @context_url, @mail).deliver | ||
15 | if request.xhr? | 16 | if request.xhr? |
16 | render :text => _('Message sent') | 17 | render :text => _('Message sent') |
17 | else | 18 | else |
plugins/send_email/lib/send_email_plugin.rb
@@ -16,9 +16,9 @@ class SendEmailPlugin < Noosfero::Plugin | @@ -16,9 +16,9 @@ class SendEmailPlugin < Noosfero::Plugin | ||
16 | 16 | ||
17 | def parse_content(html, source) | 17 | def parse_content(html, source) |
18 | if context.profile | 18 | if context.profile |
19 | - html.gsub!(/\{sendemail\}/, "/profile/#{context.profile.identifier}/plugin/send_email/deliver") | 19 | + html.gsub!(/({|%7[Bb])sendemail(}|%7[Dd])/, "/profile/#{context.profile.identifier}/plugin/send_email/deliver") |
20 | else | 20 | else |
21 | - html.gsub!(/\{sendemail\}/, '/plugin/send_email/deliver') | 21 | + html.gsub!(/({|%7[Bb])sendemail(}|%7[Dd])/, '/plugin/send_email/deliver') |
22 | end | 22 | end |
23 | [html, source] | 23 | [html, source] |
24 | end | 24 | end |
plugins/send_email/lib/send_email_plugin/mail.rb
@@ -10,12 +10,11 @@ class SendEmailPlugin::Mail | @@ -10,12 +10,11 @@ class SendEmailPlugin::Mail | ||
10 | validate :recipients_format | 10 | validate :recipients_format |
11 | 11 | ||
12 | def initialize(attributes = {:subject => 'New mail'}) | 12 | def initialize(attributes = {:subject => 'New mail'}) |
13 | - @environment = attributes[:environment] | ||
14 | - @from = attributes[:from] | ||
15 | - @to = attributes[:to] | ||
16 | - @subject = attributes[:subject] | ||
17 | - @message = attributes[:message] | ||
18 | - @params = attributes[:params] | 13 | + if attributes |
14 | + attributes.each do |attr,value| | ||
15 | + self.send("#{attr}=", value) | ||
16 | + end | ||
17 | + end | ||
19 | end | 18 | end |
20 | 19 | ||
21 | def recipients_format | 20 | def recipients_format |
@@ -36,7 +35,7 @@ class SendEmailPlugin::Mail | @@ -36,7 +35,7 @@ class SendEmailPlugin::Mail | ||
36 | end | 35 | end |
37 | 36 | ||
38 | def params=(value = {}) | 37 | def params=(value = {}) |
39 | - [:action, :controller, :to, :message, :subject, :from].each{|k| value.delete(k)} | 38 | + [:profile, :action, :controller, :to, :message, :subject, :from, :commit].each{|k| value.delete(k)} |
40 | @params = value | 39 | @params = value |
41 | end | 40 | end |
42 | 41 |
plugins/send_email/lib/send_email_plugin/sender.rb
@@ -7,9 +7,9 @@ class SendEmailPlugin::Sender < Noosfero::Plugin::MailerBase | @@ -7,9 +7,9 @@ class SendEmailPlugin::Sender < Noosfero::Plugin::MailerBase | ||
7 | @params = mail.params | 7 | @params = mail.params |
8 | 8 | ||
9 | mail( | 9 | mail( |
10 | + content_type: 'text/plain', | ||
10 | to: mail.to, | 11 | to: mail.to, |
11 | from: mail.from, | 12 | from: mail.from, |
12 | - body: mail.params, | ||
13 | subject: "[#{mail.environment.name}] #{mail.subject}" | 13 | subject: "[#{mail.environment.name}] #{mail.subject}" |
14 | ) | 14 | ) |
15 | end | 15 | end |
plugins/send_email/test/functional/send_email_plugin_base_controller_test.rb
@@ -54,6 +54,13 @@ def run_common_tests | @@ -54,6 +54,13 @@ def run_common_tests | ||
54 | post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john') | 54 | post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john') |
55 | assert_equal '[Colivre.net] Hello john', ActionMailer::Base.deliveries.first.subject | 55 | assert_equal '[Colivre.net] Hello john', ActionMailer::Base.deliveries.first.subject |
56 | end | 56 | end |
57 | + | ||
58 | + should 'deliver mail with message from view' do | ||
59 | + Environment.any_instance.stubs(:send_email_plugin_allow_to).returns('john@example.com') | ||
60 | + post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john') | ||
61 | + assert_match /Contact from/, ActionMailer::Base.deliveries.first.body.to_s | ||
62 | + end | ||
63 | + | ||
57 | end | 64 | end |
58 | 65 | ||
59 | class SendEmailPluginProfileControllerTest < ActionController::TestCase | 66 | class SendEmailPluginProfileControllerTest < ActionController::TestCase |
plugins/send_email/test/unit/send_email_plugin_sender_test.rb
@@ -15,12 +15,14 @@ class SendEmailPluginSenderTest < ActiveSupport::TestCase | @@ -15,12 +15,14 @@ class SendEmailPluginSenderTest < ActiveSupport::TestCase | ||
15 | end | 15 | end |
16 | 16 | ||
17 | should 'be able to deliver mail' do | 17 | should 'be able to deliver mail' do |
18 | + @mail.expects(:params).returns({}) | ||
18 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) | 19 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) |
19 | assert_equal 'noreply@localhost', response.from.join | 20 | assert_equal 'noreply@localhost', response.from.join |
20 | assert_equal "[Noosfero] #{@mail.subject}", response.subject | 21 | assert_equal "[Noosfero] #{@mail.subject}", response.subject |
21 | end | 22 | end |
22 | 23 | ||
23 | should 'deliver mail to john@example.com' do | 24 | should 'deliver mail to john@example.com' do |
25 | + @mail.expects(:params).returns({}) | ||
24 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) | 26 | response = SendEmailPlugin::Sender.send_message("http://localhost/contact", 'http//profile', @mail) |
25 | assert_equal ['john@example.com'], response.to | 27 | assert_equal ['john@example.com'], response.to |
26 | end | 28 | end |
plugins/send_email/test/unit/send_email_plugin_test.rb
@@ -26,4 +26,12 @@ class SendEmailPluginTest < ActiveSupport::TestCase | @@ -26,4 +26,12 @@ class SendEmailPluginTest < ActiveSupport::TestCase | ||
26 | assert_match /profile\/#{@plugin.context.profile.identifier}\/plugin\/send_email\/deliver/, @plugin.parse_content("expand this macro {sendemail}", nil).first | 26 | assert_match /profile\/#{@plugin.context.profile.identifier}\/plugin\/send_email\/deliver/, @plugin.parse_content("expand this macro {sendemail}", nil).first |
27 | end | 27 | end |
28 | 28 | ||
29 | + should 'expand macro used on form on profile context' do | ||
30 | + profile = fast_create(Community) | ||
31 | + @plugin.context.stubs(:profile).returns(profile) | ||
32 | + article = RawHTMLArticle.create!(:name => 'Raw HTML', :body => "<form action='{sendemail}'></form>", :profile => profile) | ||
33 | + | ||
34 | + assert_match /profile\/#{profile.identifier}\/plugin\/send_email\/deliver/, @plugin.parse_content(article.to_html, nil).first | ||
35 | + end | ||
36 | + | ||
29 | end | 37 | end |
plugins/send_email/views/send_email_plugin/sender/message.html.erb
plugins/send_email/views/send_email_plugin/sender/send_message.html.erb
0 → 100644
plugins/send_email/views/send_email_plugin/success.html.erb
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | 2 | ||
3 | <table class='sendemail-plugin-message-sent'> | 3 | <table class='sendemail-plugin-message-sent'> |
4 | <tr><td class='label'><strong><%= c_('Subject') %>:</strong></td><td class='value'><em><%=h @mail.subject %></em></td></tr> | 4 | <tr><td class='label'><strong><%= c_('Subject') %>:</strong></td><td class='value'><em><%=h @mail.subject %></em></td></tr> |
5 | - <tr><td class='label'><strong><%= c_('Message') %>:</strong></td><td class='value'><pre><%=h render :file => 'send_email_plugin/sender/message' %></pre></td></tr> | 5 | + <tr><td class='label'><strong><%= c_('Message') %>:</strong></td><td class='value'><pre><%=h render :file => 'send_email_plugin/sender/send_message' %></pre></td></tr> |
6 | </table> | 6 | </table> |
7 | 7 | ||
8 | <p><%= button :back, c_('Back'), :back %></p> | 8 | <p><%= button :back, c_('Back'), :back %></p> |
plugins/sub_organizations/db/migrate/20150508153119_add_timestamp_to_relation.rb
0 → 100644
plugins/sub_organizations/lib/sub_organizations_plugin/relation.rb
1 | class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord | 1 | class SubOrganizationsPlugin::Relation < Noosfero::Plugin::ActiveRecord |
2 | - record_timestamps = false | ||
3 | - | ||
4 | belongs_to :parent, :polymorphic => true | 2 | belongs_to :parent, :polymorphic => true |
5 | belongs_to :child, :polymorphic => true | 3 | belongs_to :child, :polymorphic => true |
6 | 4 |
plugins/vote/public/style.css
plugins/vote/views/vote/_vote.html.erb
@@ -5,7 +5,7 @@ reload_url = url_for(:controller => 'vote_plugin_profile', :profile => profile.i | @@ -5,7 +5,7 @@ reload_url = url_for(:controller => 'vote_plugin_profile', :profile => profile.i | ||
5 | 5 | ||
6 | <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action"> | 6 | <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action"> |
7 | 7 | ||
8 | - <%= link_to_remote content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), :url => url, :html => {:class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'}"} %> | 8 | + <%= link_to content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), url, :class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'} require-login-popup" %> |
9 | 9 | ||
10 | <% if !voters.blank? %> | 10 | <% if !voters.blank? %> |
11 | <span class="vote-detail"> | 11 | <span class="vote-detail"> |
public/designs/templates/lefttopright/javascripts/template.js
0 → 100644
public/designs/templates/lefttopright/stylesheets/style.css
0 → 100644
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +#boxes { | ||
2 | + display: table; | ||
3 | + width: 100%; | ||
4 | +} | ||
5 | + | ||
6 | +.box-1 { | ||
7 | + width: 58%; | ||
8 | + float: left; | ||
9 | + margin: 1% 1% 0% 1%; | ||
10 | +} | ||
11 | + | ||
12 | + | ||
13 | +.box-2 { | ||
14 | + position: relative; | ||
15 | + float: left; | ||
16 | + width: 20%; | ||
17 | +} | ||
18 | + | ||
19 | +.box-3 { | ||
20 | + position: relative; | ||
21 | + float: right; | ||
22 | + width: 20%; | ||
23 | + margin-top: 1%; | ||
24 | +} | ||
25 | + | ||
26 | +.box-4 { | ||
27 | + float: left; | ||
28 | + width: 79%; | ||
29 | + margin-left: 21%; | ||
30 | +} | ||
31 | + | ||
32 | +#profile-activity ul, | ||
33 | +#profile-network ul, | ||
34 | +#profile-wall ul { | ||
35 | + width: 460px; | ||
36 | +} | ||
37 | +#profile-activity ul.comment-replies, | ||
38 | +#profile-network ul.comment-replies, | ||
39 | +#profile-wall ul.comment-replies { | ||
40 | + width: auto; | ||
41 | +} | ||
42 | + |
3.02 KB
@@ -0,0 +1,434 @@ | @@ -0,0 +1,434 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
2 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> | ||
3 | + | ||
4 | +<svg | ||
5 | + xmlns:dc="http://purl.org/dc/elements/1.1/" | ||
6 | + xmlns:cc="http://creativecommons.org/ns#" | ||
7 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||
8 | + xmlns:svg="http://www.w3.org/2000/svg" | ||
9 | + xmlns="http://www.w3.org/2000/svg" | ||
10 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
11 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||
12 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||
13 | + width="64px" | ||
14 | + height="64px" | ||
15 | + id="svg2383" | ||
16 | + sodipodi:version="0.32" | ||
17 | + inkscape:version="0.48.3.1 r9886" | ||
18 | + sodipodi:docname="thumbnail.svg" | ||
19 | + inkscape:output_extension="org.inkscape.output.svg.inkscape" | ||
20 | + inkscape:export-filename="thumbnail.png" | ||
21 | + inkscape:export-xdpi="90" | ||
22 | + inkscape:export-ydpi="90" | ||
23 | + version="1.1"> | ||
24 | + <defs | ||
25 | + id="defs2385"> | ||
26 | + <linearGradient | ||
27 | + id="linearGradient3263"> | ||
28 | + <stop | ||
29 | + id="stop3265" | ||
30 | + offset="0" | ||
31 | + style="stop-color:#204a87;stop-opacity:1" /> | ||
32 | + <stop | ||
33 | + id="stop3267" | ||
34 | + offset="1" | ||
35 | + style="stop-color:#729fcf;stop-opacity:1" /> | ||
36 | + </linearGradient> | ||
37 | + <linearGradient | ||
38 | + id="linearGradient3257" | ||
39 | + inkscape:collect="always"> | ||
40 | + <stop | ||
41 | + id="stop3259" | ||
42 | + offset="0" | ||
43 | + style="stop-color:#204a87;stop-opacity:1" /> | ||
44 | + <stop | ||
45 | + id="stop3261" | ||
46 | + offset="1" | ||
47 | + style="stop-color:#729fcf;stop-opacity:1" /> | ||
48 | + </linearGradient> | ||
49 | + <linearGradient | ||
50 | + inkscape:collect="always" | ||
51 | + id="linearGradient3245"> | ||
52 | + <stop | ||
53 | + style="stop-color:#204a87;stop-opacity:1" | ||
54 | + offset="0" | ||
55 | + id="stop3247" /> | ||
56 | + <stop | ||
57 | + style="stop-color:#729fcf;stop-opacity:1" | ||
58 | + offset="1" | ||
59 | + id="stop3249" /> | ||
60 | + </linearGradient> | ||
61 | + <inkscape:perspective | ||
62 | + sodipodi:type="inkscape:persp3d" | ||
63 | + inkscape:vp_x="0 : 32 : 1" | ||
64 | + inkscape:vp_y="0 : 1000 : 0" | ||
65 | + inkscape:vp_z="64 : 32 : 1" | ||
66 | + inkscape:persp3d-origin="32 : 21.333333 : 1" | ||
67 | + id="perspective2391" /> | ||
68 | + <filter | ||
69 | + inkscape:collect="always" | ||
70 | + id="filter3241"> | ||
71 | + <feGaussianBlur | ||
72 | + inkscape:collect="always" | ||
73 | + stdDeviation="0.9075" | ||
74 | + id="feGaussianBlur3243" /> | ||
75 | + </filter> | ||
76 | + <linearGradient | ||
77 | + inkscape:collect="always" | ||
78 | + xlink:href="#linearGradient3245" | ||
79 | + id="linearGradient3251" | ||
80 | + x1="11.5" | ||
81 | + y1="60.5" | ||
82 | + x2="3.5" | ||
83 | + y2="3.5" | ||
84 | + gradientUnits="userSpaceOnUse" | ||
85 | + gradientTransform="translate(2,0)" /> | ||
86 | + <linearGradient | ||
87 | + inkscape:collect="always" | ||
88 | + xlink:href="#linearGradient3263" | ||
89 | + id="linearGradient3253" | ||
90 | + x1="49.5" | ||
91 | + y1="60.5" | ||
92 | + x2="23.5" | ||
93 | + y2="3.5" | ||
94 | + gradientUnits="userSpaceOnUse" | ||
95 | + gradientTransform="translate(2,0)" /> | ||
96 | + <linearGradient | ||
97 | + inkscape:collect="always" | ||
98 | + xlink:href="#linearGradient3257" | ||
99 | + id="linearGradient3255" | ||
100 | + x1="60.5" | ||
101 | + y1="60.5" | ||
102 | + x2="51.5" | ||
103 | + y2="3.5" | ||
104 | + gradientUnits="userSpaceOnUse" /> | ||
105 | + <filter | ||
106 | + color-interpolation-filters="sRGB" | ||
107 | + inkscape:collect="always" | ||
108 | + id="filter3241-2"> | ||
109 | + <feGaussianBlur | ||
110 | + inkscape:collect="always" | ||
111 | + stdDeviation="0.9075" | ||
112 | + id="feGaussianBlur3243-4" /> | ||
113 | + </filter> | ||
114 | + <linearGradient | ||
115 | + inkscape:collect="always" | ||
116 | + xlink:href="#linearGradient3245-1" | ||
117 | + id="linearGradient3251-0" | ||
118 | + x1="11.5" | ||
119 | + y1="60.5" | ||
120 | + x2="3.5" | ||
121 | + y2="3.5" | ||
122 | + gradientUnits="userSpaceOnUse" | ||
123 | + gradientTransform="translate(249.71429,298.93361)" /> | ||
124 | + <linearGradient | ||
125 | + inkscape:collect="always" | ||
126 | + id="linearGradient3245-1"> | ||
127 | + <stop | ||
128 | + style="stop-color:#204a87;stop-opacity:1" | ||
129 | + offset="0" | ||
130 | + id="stop3247-6" /> | ||
131 | + <stop | ||
132 | + style="stop-color:#729fcf;stop-opacity:1" | ||
133 | + offset="1" | ||
134 | + id="stop3249-5" /> | ||
135 | + </linearGradient> | ||
136 | + <filter | ||
137 | + color-interpolation-filters="sRGB" | ||
138 | + inkscape:collect="always" | ||
139 | + id="filter3241-4-8"> | ||
140 | + <feGaussianBlur | ||
141 | + inkscape:collect="always" | ||
142 | + stdDeviation="0.9075" | ||
143 | + id="feGaussianBlur3243-0-7" /> | ||
144 | + </filter> | ||
145 | + <linearGradient | ||
146 | + inkscape:collect="always" | ||
147 | + xlink:href="#linearGradient3263-5-8" | ||
148 | + id="linearGradient5185" | ||
149 | + gradientUnits="userSpaceOnUse" | ||
150 | + gradientTransform="matrix(1.4160224,0,0,0.76166072,243.22589,313.33388)" | ||
151 | + x1="42.5" | ||
152 | + y1="60.5" | ||
153 | + x2="19.5" | ||
154 | + y2="3.5" /> | ||
155 | + <linearGradient | ||
156 | + id="linearGradient3263-5-8"> | ||
157 | + <stop | ||
158 | + id="stop3265-4-3" | ||
159 | + offset="0" | ||
160 | + style="stop-color:#204a87;stop-opacity:1" /> | ||
161 | + <stop | ||
162 | + id="stop3267-2-4" | ||
163 | + offset="1" | ||
164 | + style="stop-color:#729fcf;stop-opacity:1" /> | ||
165 | + </linearGradient> | ||
166 | + <filter | ||
167 | + color-interpolation-filters="sRGB" | ||
168 | + inkscape:collect="always" | ||
169 | + id="filter3241-0"> | ||
170 | + <feGaussianBlur | ||
171 | + inkscape:collect="always" | ||
172 | + stdDeviation="0.9075" | ||
173 | + id="feGaussianBlur3243-3" /> | ||
174 | + </filter> | ||
175 | + <linearGradient | ||
176 | + inkscape:collect="always" | ||
177 | + xlink:href="#linearGradient3245-7" | ||
178 | + id="linearGradient5168" | ||
179 | + gradientUnits="userSpaceOnUse" | ||
180 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" | ||
181 | + x1="11.5" | ||
182 | + y1="60.5" | ||
183 | + x2="3.5" | ||
184 | + y2="3.5" /> | ||
185 | + <linearGradient | ||
186 | + inkscape:collect="always" | ||
187 | + id="linearGradient3245-7"> | ||
188 | + <stop | ||
189 | + style="stop-color:#204a87;stop-opacity:1" | ||
190 | + offset="0" | ||
191 | + id="stop3247-0" /> | ||
192 | + <stop | ||
193 | + style="stop-color:#729fcf;stop-opacity:1" | ||
194 | + offset="1" | ||
195 | + id="stop3249-7" /> | ||
196 | + </linearGradient> | ||
197 | + <linearGradient | ||
198 | + inkscape:collect="always" | ||
199 | + xlink:href="#linearGradient3245-70" | ||
200 | + id="linearGradient3251-55" | ||
201 | + x1="11.5" | ||
202 | + y1="60.5" | ||
203 | + x2="3.5" | ||
204 | + y2="3.5" | ||
205 | + gradientUnits="userSpaceOnUse" | ||
206 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" /> | ||
207 | + <linearGradient | ||
208 | + inkscape:collect="always" | ||
209 | + id="linearGradient3245-70"> | ||
210 | + <stop | ||
211 | + style="stop-color:#204a87;stop-opacity:1" | ||
212 | + offset="0" | ||
213 | + id="stop3247-2" /> | ||
214 | + <stop | ||
215 | + style="stop-color:#729fcf;stop-opacity:1" | ||
216 | + offset="1" | ||
217 | + id="stop3249-87" /> | ||
218 | + </linearGradient> | ||
219 | + <linearGradient | ||
220 | + inkscape:collect="always" | ||
221 | + xlink:href="#linearGradient3245-1" | ||
222 | + id="linearGradient5832" | ||
223 | + gradientUnits="userSpaceOnUse" | ||
224 | + gradientTransform="translate(249.71429,298.93361)" | ||
225 | + x1="11.5" | ||
226 | + y1="60.5" | ||
227 | + x2="3.5" | ||
228 | + y2="3.5" /> | ||
229 | + <linearGradient | ||
230 | + inkscape:collect="always" | ||
231 | + xlink:href="#linearGradient3263-5-8" | ||
232 | + id="linearGradient5834" | ||
233 | + gradientUnits="userSpaceOnUse" | ||
234 | + gradientTransform="matrix(1.4160224,0,0,0.76166072,243.22589,313.33388)" | ||
235 | + x1="42.5" | ||
236 | + y1="60.5" | ||
237 | + x2="19.5" | ||
238 | + y2="3.5" /> | ||
239 | + <linearGradient | ||
240 | + inkscape:collect="always" | ||
241 | + xlink:href="#linearGradient3245-7" | ||
242 | + id="linearGradient5836" | ||
243 | + gradientUnits="userSpaceOnUse" | ||
244 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" | ||
245 | + x1="11.5" | ||
246 | + y1="60.5" | ||
247 | + x2="3.5" | ||
248 | + y2="3.5" /> | ||
249 | + <linearGradient | ||
250 | + inkscape:collect="always" | ||
251 | + xlink:href="#linearGradient3245-70" | ||
252 | + id="linearGradient5838" | ||
253 | + gradientUnits="userSpaceOnUse" | ||
254 | + gradientTransform="matrix(1.0025263,0,0,0.76423683,344.68831,300.13218)" | ||
255 | + x1="11.5" | ||
256 | + y1="60.5" | ||
257 | + x2="3.5" | ||
258 | + y2="3.5" /> | ||
259 | + </defs> | ||
260 | + <sodipodi:namedview | ||
261 | + id="base" | ||
262 | + pagecolor="#ffffff" | ||
263 | + bordercolor="#666666" | ||
264 | + borderopacity="1.0" | ||
265 | + inkscape:pageopacity="0.0" | ||
266 | + inkscape:pageshadow="2" | ||
267 | + inkscape:zoom="2.5351563" | ||
268 | + inkscape:cx="-16.066434" | ||
269 | + inkscape:cy="0.12147739" | ||
270 | + inkscape:current-layer="layer1" | ||
271 | + showgrid="true" | ||
272 | + inkscape:document-units="px" | ||
273 | + inkscape:grid-bbox="true" | ||
274 | + inkscape:window-width="1364" | ||
275 | + inkscape:window-height="678" | ||
276 | + inkscape:window-x="0" | ||
277 | + inkscape:window-y="27" | ||
278 | + objecttolerance="10" | ||
279 | + gridtolerance="10" | ||
280 | + guidetolerance="10" | ||
281 | + inkscape:window-maximized="0"> | ||
282 | + <inkscape:grid | ||
283 | + type="xygrid" | ||
284 | + id="grid2382" | ||
285 | + visible="true" | ||
286 | + enabled="true" | ||
287 | + originx="0.5px" | ||
288 | + originy="0.5px" | ||
289 | + empcolor="#0000ff" | ||
290 | + empopacity="0.1254902" | ||
291 | + dotted="true" /> | ||
292 | + </sodipodi:namedview> | ||
293 | + <metadata | ||
294 | + id="metadata2388"> | ||
295 | + <rdf:RDF> | ||
296 | + <cc:Work | ||
297 | + rdf:about=""> | ||
298 | + <dc:format>image/svg+xml</dc:format> | ||
299 | + <dc:type | ||
300 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||
301 | + </cc:Work> | ||
302 | + </rdf:RDF> | ||
303 | + </metadata> | ||
304 | + <g | ||
305 | + id="layer1" | ||
306 | + inkscape:label="Layer 1" | ||
307 | + inkscape:groupmode="layer"> | ||
308 | + <g | ||
309 | + transform="translate(-247.62879,-298.93361)" | ||
310 | + id="g5187"> | ||
311 | + <g | ||
312 | + id="g4846"> | ||
313 | + <g | ||
314 | + id="g3190-2" | ||
315 | + style="opacity:0.4;filter:url(#filter3241-2)" | ||
316 | + transform="translate(250.71429,299.93361)"> | ||
317 | + <rect | ||
318 | + y="1.5" | ||
319 | + x="1.5" | ||
320 | + height="59" | ||
321 | + width="11" | ||
322 | + id="rect3184-1" | ||
323 | + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
324 | + ry="2" | ||
325 | + rx="2" /> | ||
326 | + </g> | ||
327 | + <rect | ||
328 | + y="300.43362" | ||
329 | + x="251.21428" | ||
330 | + height="59" | ||
331 | + width="11" | ||
332 | + id="rect2395-8" | ||
333 | + style="fill:url(#linearGradient5832);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
334 | + ry="2" | ||
335 | + rx="2" /> | ||
336 | + <rect | ||
337 | + ry="1" | ||
338 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
339 | + id="rect3158-7" | ||
340 | + width="9" | ||
341 | + height="57" | ||
342 | + x="252.21428" | ||
343 | + y="301.43362" | ||
344 | + rx="1" /> | ||
345 | + </g> | ||
346 | + <g | ||
347 | + transform="matrix(0.69260722,0,0,1,81.51265,0)" | ||
348 | + id="g5180"> | ||
349 | + <rect | ||
350 | + rx="2" | ||
351 | + ry="2" | ||
352 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241-4-8);enable-background:accumulate" | ||
353 | + id="rect3188-8" | ||
354 | + width="31" | ||
355 | + height="59" | ||
356 | + x="16.5" | ||
357 | + y="2.5" | ||
358 | + transform="matrix(1.4160224,0,0,0.76166071,243.80989,314.09132)" /> | ||
359 | + <rect | ||
360 | + y="314.47638" | ||
361 | + x="265.17426" | ||
362 | + height="44.937984" | ||
363 | + width="43.896694" | ||
364 | + id="rect3156-3" | ||
365 | + style="fill:url(#linearGradient5834);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
366 | + ry="1.5233214" /> | ||
367 | + <rect | ||
368 | + y="315.23804" | ||
369 | + x="266.59027" | ||
370 | + height="43.414661" | ||
371 | + width="41.064651" | ||
372 | + id="rect3162-1" | ||
373 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:1.03852236;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
374 | + ry="0.7616607" | ||
375 | + inkscape:export-xdpi="90" | ||
376 | + inkscape:export-ydpi="90" /> | ||
377 | + </g> | ||
378 | + <g | ||
379 | + transform="matrix(0.9761091,0,0,1,6.3333026,0)" | ||
380 | + id="g5108"> | ||
381 | + <rect | ||
382 | + rx="2" | ||
383 | + ry="2" | ||
384 | + style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3241-0);enable-background:accumulate" | ||
385 | + id="rect3184-5" | ||
386 | + width="11" | ||
387 | + height="59" | ||
388 | + x="2.5" | ||
389 | + y="2.5" | ||
390 | + transform="matrix(0,1.0025263,-0.76423683,0,312.09322,298.92289)" /> | ||
391 | + <g | ||
392 | + transform="matrix(0,1,-1,0,611.46116,-45.820829)" | ||
393 | + id="g4877-9"> | ||
394 | + <rect | ||
395 | + ry="1.5284736" | ||
396 | + style="fill:url(#linearGradient5836);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
397 | + id="rect2395-95" | ||
398 | + width="11.02779" | ||
399 | + height="45.089973" | ||
400 | + x="346.19211" | ||
401 | + y="301.27853" /> | ||
402 | + <rect | ||
403 | + y="302.04276" | ||
404 | + x="347.19461" | ||
405 | + height="43.561501" | ||
406 | + width="9.0227375" | ||
407 | + id="rect3158-2" | ||
408 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
409 | + ry="0.76423681" /> | ||
410 | + </g> | ||
411 | + </g> | ||
412 | + <g | ||
413 | + id="g4877-8" | ||
414 | + transform="translate(-47.956003,13.002947)"> | ||
415 | + <rect | ||
416 | + y="301.27853" | ||
417 | + x="346.19211" | ||
418 | + height="45.089973" | ||
419 | + width="11.02779" | ||
420 | + id="rect2395-1" | ||
421 | + style="fill:url(#linearGradient5838);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
422 | + ry="1.5284736" /> | ||
423 | + <rect | ||
424 | + ry="0.76423681" | ||
425 | + style="opacity:0.6;fill:none;stroke:#ffffff;stroke-width:0.87531;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" | ||
426 | + id="rect3158-71" | ||
427 | + width="9.0227375" | ||
428 | + height="43.561501" | ||
429 | + x="347.19461" | ||
430 | + y="302.04276" /> | ||
431 | + </g> | ||
432 | + </g> | ||
433 | + </g> | ||
434 | +</svg> |