Commit 38b43fc7d5121ed574018483b468bb7f8a2ebef8

Authored by Leandro Santos
2 parents 921031b3 54c2e243

fixing conflict

Showing 527 changed files with 25348 additions and 8883 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 527 files displayed.

@@ -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 &lt;rr.manzo@gmail.com&gt; @@ -120,6 +121,7 @@ Diego Araujo + Rodrigo Souto + Rafael Manzo &lt;rr.manzo@gmail.com&gt;
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 &lt;italo@dcc.ufba.br&gt; @@ -144,6 +146,7 @@ Italo Valcy &lt;italo@dcc.ufba.br&gt;
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 &lt;tallysmartins@gmail.com&gt; @@ -247,8 +250,10 @@ Tallys Martins &lt;tallysmartins@gmail.com&gt;
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>
@@ -20,18 +20,17 @@ gem &#39;locale&#39;, &#39;~&gt; 2.0.5&#39; @@ -20,18 +20,17 @@ gem &#39;locale&#39;, &#39;~&gt; 2.0.5&#39;
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
INSTALL.chat.md
1 -XMPP/Chat Setup  
2 -=============== 1 +Automatic XMPP/Chat Setup
  2 +=========================
  3 +
  4 +Since Noosfero 1.2, the XMPP/Chat can be installed via `noosfero-chat` Debian
  5 +package. So you don't need to follow the manual instructions here if you
  6 +already have it installed on your system.
  7 +
  8 +But if you are going to install the `noosfero-chat` package on a system that
  9 +already has `noosfero` older 1.2 installed then you need to check if apache's
  10 +configuration file `/etc/apache2/sites-available/noosfero` has this line below:
  11 +
  12 + Include /usr/share/noosfero/util/chat/apache/xmpp.conf
  13 +
  14 +Manual XMPP/Chat Setup
  15 +======================
3 16
4 The samples of config file to configure a XMPP/BOSH server with ejabberd, 17 The samples of config file to configure a XMPP/BOSH server with ejabberd,
5 postgresql and apache2 can be found at util/chat directory. 18 postgresql and apache2 can be found at util/chat directory.
@@ -8,7 +21,7 @@ This setup supposes that you are using Noosfero installed via Debian package @@ -8,7 +21,7 @@ This setup supposes that you are using Noosfero installed via Debian package
8 in a production environment. 21 in a production environment.
9 22
10 Steps 23 Steps
11 -===== 24 +-----
12 25
13 This is a step-by-step guide to get a XMPP service working, in a Debian system. 26 This is a step-by-step guide to get a XMPP service working, in a Debian system.
14 27
@@ -144,15 +157,8 @@ You should see a page with a message like that: @@ -144,15 +157,8 @@ You should see a page with a message like that:
144 157
145 ## 9. Test chat session 158 ## 9. Test chat session
146 159
147 -Open Noosfero console and execute:  
148 -  
149 ->> environment = Environment.default  
150 ->> user = Person['guest']  
151 ->> password = user.user.crypted_password  
152 ->> login = user.jid  
153 ->> RubyBOSH.initialize_session(login, password, "http://#{environment.default_hostname}/http-bind", :wait => 30, :hold => 1, :window => 5  
154 -  
155 -If you have luck, should see something like that: 160 +Run `./script/noosfero-test-chat-session`. If you have luck, should see
  161 +something like that:
156 162
157 Ruby-BOSH - SEND 163 Ruby-BOSH - SEND
158 <body window="5" rid="60265" xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" to="vagrant-debian-squeeze.vagrantup.com" wait="30" xmpp:version="1.0" hold="1"/> 164 <body window="5" rid="60265" xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" to="vagrant-debian-squeeze.vagrantup.com" wait="30" xmpp:version="1.0" hold="1"/>
INSTALL.https.md
@@ -11,8 +11,8 @@ as below: @@ -11,8 +11,8 @@ as below:
11 11
12 # mkdir /etc/noosfero/ssl 12 # mkdir /etc/noosfero/ssl
13 # cd /etc/noosfero/ssl 13 # cd /etc/noosfero/ssl
14 - # openssl genrsa 1024 > noosfero.key  
15 - # openssl req -new -x509 -nodes -sha1 -days $[10*365] -key noosfero.key > noosfero.cert 14 + # openssl genrsa 2048 > noosfero.key
  15 + # openssl req -new -x509 -sha256 -nodes -days $[10*365] -key noosfero.key > noosfero.cert
16 # cat noosfero.key noosfero.cert > noosfero.pem 16 # cat noosfero.key noosfero.cert > noosfero.pem
17 17
18 ## Web server configuration 18 ## Web server configuration
@@ -74,7 +74,7 @@ downloading from git @@ -74,7 +74,7 @@ downloading from git
74 74
75 Here we are cloning the noosfero repository from git. Note: you will need to install git before. 75 Here we are cloning the noosfero repository from git. Note: you will need to install git before.
76 76
77 - $ git clone git://gitorious.org/noosfero/noosfero.git current 77 + $ git clone https://gitlab.com/noosfero/noosfero.git current
78 $ cd current 78 $ cd current
79 $ git checkout -b stable origin/stable 79 $ git checkout -b stable origin/stable
80 80
app/controllers/admin/admin_panel_controller.rb
@@ -71,22 +71,4 @@ class AdminPanelController &lt; AdminController @@ -71,22 +71,4 @@ class AdminPanelController &lt; AdminController
71 end 71 end
72 end 72 end
73 end 73 end
74 -  
75 - def manage_organizations_status  
76 - scope = environment.organizations  
77 - @filter = params[:filter] || 'any'  
78 - @title = "Organization profiles"  
79 - @title = @title+" - "+@filter if @filter != 'any'  
80 -  
81 - if @filter == 'enabled'  
82 - scope = scope.visible  
83 - elsif @filter == 'disabled'  
84 - scope = scope.disabled  
85 - end  
86 -  
87 - scope = scope.order('name ASC')  
88 -  
89 - @q = params[:q]  
90 - @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => 10, :page => params[:npage]})[:results]  
91 - end  
92 end 74 end
app/controllers/admin/organizations_controller.rb 0 → 100644
@@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
  1 +class OrganizationsController < AdminController
  2 +
  3 + protect 'manage_environment_organizations', :environment
  4 +
  5 + def index
  6 + @filter = params[:filter] || 'any'
  7 + @title = _('Organization profiles')
  8 + @type = params[:type] || "any"
  9 + @types_filter = [[_('All'), 'any'], [_('Community'), 'Community'], [_('Enterprise'), 'Enterprise']]
  10 + @types_filter = @types_filter | @plugins.dispatch(:organization_types_filter_options)
  11 +
  12 + scope = @plugins.dispatch_first(:filter_manage_organization_scope, @type)
  13 + if scope.blank?
  14 + scope = environment.organizations
  15 + scope = scope.where(:type => @type) if @type != 'any'
  16 + end
  17 +
  18 + if @filter == 'enabled'
  19 + scope = scope.visible
  20 + elsif @filter == 'disabled'
  21 + scope = scope.disabled
  22 + end
  23 +
  24 + scope = scope.order('name ASC')
  25 +
  26 + @q = params[:q]
  27 + @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results]
  28 + end
  29 +
  30 + def activate
  31 + organization = environment.organizations.find(params[:id])
  32 + if organization.enable
  33 + render :text => (_('%s enabled') % organization.name).to_json
  34 + else
  35 + render :text => (_('%s could not be enabled') % organization.name).to_json
  36 + end
  37 + end
  38 +
  39 + def deactivate
  40 + organization = environment.organizations.find(params[:id])
  41 + if organization.disable
  42 + render :text => (_('%s disabled') % organization.name).to_json
  43 + else
  44 + render :text => (_('%s could not be disable') % organization.name).to_json
  45 + end
  46 + end
  47 +
  48 + def destroy
  49 + if request.post?
  50 + organization = environment.organizations.find(params[:id])
  51 + if organization && organization.destroy
  52 + render :text => (_('%s removed') % organization.name).to_json
  53 + else
  54 + render :text => (_('%s could not be removed') % organization.name).to_json
  55 + end
  56 + else
  57 + render :nothing => true
  58 + end
  59 + end
  60 +
  61 + private
  62 +
  63 + def per_page
  64 + 10
  65 + end
  66 +end
app/controllers/admin/role_controller.rb
@@ -2,7 +2,7 @@ class RoleController &lt; AdminController @@ -2,7 +2,7 @@ class RoleController &lt; 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 &lt; ActionController::Base @@ -9,6 +9,7 @@ class ApplicationController &lt; 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 &lt; ActionController::Base @@ -192,4 +193,15 @@ class ApplicationController &lt; 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
@@ -112,6 +112,11 @@ class CmsController &lt; MyProfileController @@ -112,6 +112,11 @@ class CmsController &lt; MyProfileController
112 end 112 end
113 end 113 end
114 end 114 end
  115 +
  116 + unless @article.kind_of?(RssFeed)
  117 + @escaped_body = CGI::escapeHTML(@article.body || '')
  118 + @escaped_abstract = CGI::escapeHTML(@article.abstract || '')
  119 + end
115 end 120 end
116 121
117 def new 122 def new
@@ -143,7 +148,14 @@ class CmsController &lt; MyProfileController @@ -143,7 +148,14 @@ class CmsController &lt; MyProfileController
143 klass = @type.constantize 148 klass = @type.constantize
144 article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {} 149 article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {}
145 article_data.merge!(params[:article]) if params[:article] 150 article_data.merge!(params[:article]) if params[:article]
146 - @article = klass.new(article_data) 151 + article_data.merge!(:profile => profile) if profile
  152 +
  153 + @article = if params[:clone]
  154 + current_article = profile.articles.find(params[:id])
  155 + current_article.copy_without_save
  156 + else
  157 + klass.new(article_data)
  158 + end
147 159
148 parent = check_parent(params[:parent_id]) 160 parent = check_parent(params[:parent_id])
149 if parent 161 if parent
@@ -220,7 +232,7 @@ class CmsController &lt; MyProfileController @@ -220,7 +232,7 @@ class CmsController &lt; MyProfileController
220 if @errors.any? 232 if @errors.any?
221 render :action => 'upload_files', :parent_id => @parent_id 233 render :action => 'upload_files', :parent_id => @parent_id
222 else 234 else
223 - session[:notice] = _('File(s) successfully uploaded') 235 + session[:notice] = _('File(s) successfully uploaded')
224 if @back_to 236 if @back_to
225 redirect_to @back_to 237 redirect_to @back_to
226 elsif @parent 238 elsif @parent
@@ -357,7 +369,8 @@ class CmsController &lt; MyProfileController @@ -357,7 +369,8 @@ class CmsController &lt; MyProfileController
357 @task.ip_address = request.remote_ip 369 @task.ip_address = request.remote_ip
358 @task.user_agent = request.user_agent 370 @task.user_agent = request.user_agent
359 @task.referrer = request.referrer 371 @task.referrer = request.referrer
360 - if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save 372 + @task.requestor = current_person if logged_in?
  373 + 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.') 374 session[:notice] = _('Thanks for your suggestion. The community administrators were notified.')
362 redirect_to @back_to 375 redirect_to @back_to
363 end 376 end
app/controllers/my_profile/friends_controller.rb
1 class FriendsController < MyProfileController 1 class FriendsController < MyProfileController
2 - 2 +
3 protect 'manage_friends', :profile 3 protect 'manage_friends', :profile
4 - 4 +
5 def index 5 def index
6 - @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page) 6 + @suggestions = profile.suggested_profiles.of_person.enabled.includes(:suggestion).limit(per_page)
7 if is_cache_expired?(profile.manage_friends_cache_key(params)) 7 if is_cache_expired?(profile.manage_friends_cache_key(params))
8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage]) 8 @friends = profile.friends.paginate(:per_page => per_page, :page => params[:npage])
9 end 9 end
@@ -18,7 +18,7 @@ class FriendsController &lt; MyProfileController @@ -18,7 +18,7 @@ class FriendsController &lt; MyProfileController
18 end 18 end
19 19
20 def suggest 20 def suggest
21 - @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page) 21 + @suggestions = profile.suggested_profiles.of_person.enabled.includes(:suggestion).limit(per_page)
22 end 22 end
23 23
24 def remove_suggestion 24 def remove_suggestion
@@ -26,13 +26,13 @@ class FriendsController &lt; MyProfileController @@ -26,13 +26,13 @@ class FriendsController &lt; MyProfileController
26 redirect_to :action => 'suggest' unless @person 26 redirect_to :action => 'suggest' unless @person
27 if @person && request.post? 27 if @person && request.post?
28 profile.remove_suggestion(@person) 28 profile.remove_suggestion(@person)
29 - @suggestions = profile.profile_suggestions.of_person.enabled.includes(:suggestion).limit(per_page) 29 + @suggestions = profile.suggested_profiles.of_person.enabled.includes(:suggestion).limit(per_page)
30 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions, :per_page => params[:per_page] || per_page } 30 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :friends_suggestions, :per_page => params[:per_page] || per_page }
31 end 31 end
32 end 32 end
33 33
34 def connections 34 def connections
35 - @suggestion = profile.profile_suggestions.of_person.enabled.find_by_suggestion_id(params[:id]) 35 + @suggestion = profile.suggested_profiles.of_person.enabled.find_by_suggestion_id(params[:id])
36 if @suggestion 36 if @suggestion
37 @tags = @suggestion.tag_connections 37 @tags = @suggestion.tag_connections
38 @profiles = @suggestion.profile_connections 38 @profiles = @suggestion.profile_connections
app/controllers/my_profile/manage_products_controller.rb
@@ -35,7 +35,7 @@ class ManageProductsController &lt; ApplicationController @@ -35,7 +35,7 @@ class ManageProductsController &lt; ApplicationController
35 end 35 end
36 36
37 def categories_for_selection 37 def categories_for_selection
38 - @category = Category.find(params[:category_id]) if params[:category_id] 38 + @category = environment.categories.find_by_id params[:category_id]
39 @object_name = params[:object_name] 39 @object_name = params[:object_name]
40 if @category 40 if @category
41 @categories = @category.children 41 @categories = @category.children
@@ -95,6 +95,20 @@ class ManageProductsController &lt; ApplicationController @@ -95,6 +95,20 @@ class ManageProductsController &lt; ApplicationController
95 end 95 end
96 end 96 end
97 97
  98 + def show_category_tree
  99 + @category = environment.categories.find params[:category_id]
  100 + render :partial => 'selected_category_tree'
  101 + end
  102 +
  103 + def search_categories
  104 + @term = params[:term].downcase
  105 + conditions = ['LOWER(name) LIKE ? OR LOWER(name) LIKE ?', "#{@term}%", "% #{@term}%"]
  106 + @categories = ProductCategory.all :conditions => conditions, :limit => 10
  107 + render :json => (@categories.map do |category|
  108 + {:label => category.name, :value => category.id}
  109 + end)
  110 + end
  111 +
98 def add_input 112 def add_input
99 @product = @profile.products.find(params[:id]) 113 @product = @profile.products.find(params[:id])
100 @input = @product.inputs.build 114 @input = @product.inputs.build
app/controllers/my_profile/maps_controller.rb
@@ -16,6 +16,7 @@ class MapsController &lt; MyProfileController @@ -16,6 +16,7 @@ class MapsController &lt; MyProfileController
16 16
17 Profile.transaction do 17 Profile.transaction do
18 if profile.update_attributes!(params[:profile_data]) 18 if profile.update_attributes!(params[:profile_data])
  19 + BlockSweeper.expire_blocks profile.blocks.select{ |b| b.class == LocationBlock }
19 session[:notice] = _('Address was updated successfully!') 20 session[:notice] = _('Address was updated successfully!')
20 redirect_to :action => 'edit_location' 21 redirect_to :action => 'edit_location'
21 end 22 end
app/controllers/my_profile/memberships_controller.rb
@@ -40,7 +40,7 @@ class MembershipsController &lt; MyProfileController @@ -40,7 +40,7 @@ class MembershipsController &lt; MyProfileController
40 end 40 end
41 41
42 def suggest 42 def suggest
43 - @suggestions = profile.profile_suggestions.of_community.enabled.includes(:suggestion).limit(per_page) 43 + @suggestions = profile.suggested_profiles.of_community.enabled.includes(:suggestion).limit(per_page)
44 end 44 end
45 45
46 def remove_suggestion 46 def remove_suggestion
@@ -49,13 +49,13 @@ class MembershipsController &lt; MyProfileController @@ -49,13 +49,13 @@ class MembershipsController &lt; MyProfileController
49 redirect_to :action => 'suggest' unless @community 49 redirect_to :action => 'suggest' unless @community
50 if @community && request.post? 50 if @community && request.post?
51 profile.remove_suggestion(@community) 51 profile.remove_suggestion(@community)
52 - @suggestions = profile.profile_suggestions.of_community.enabled.includes(:suggestion).limit(custom_per_page) 52 + @suggestions = profile.suggested_profiles.of_community.enabled.includes(:suggestion).limit(custom_per_page)
53 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions, :per_page => custom_per_page} 53 render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => @suggestions, :collection => :communities_suggestions, :per_page => custom_per_page}
54 end 54 end
55 end 55 end
56 56
57 def connections 57 def connections
58 - @suggestion = profile.profile_suggestions.of_community.enabled.find_by_suggestion_id(params[:id]) 58 + @suggestion = profile.suggested_profiles.of_community.enabled.find_by_suggestion_id(params[:id])
59 if @suggestion 59 if @suggestion
60 @tags = @suggestion.tag_connections 60 @tags = @suggestion.tag_connections
61 @profiles = @suggestion.profile_connections 61 @profiles = @suggestion.profile_connections
app/controllers/my_profile/profile_design_controller.rb
@@ -4,11 +4,19 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -4,11 +4,19 @@ class ProfileDesignController &lt; 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 &lt; MyProfileController @@ -58,6 +58,7 @@ class ProfileMembersController &lt; 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
app/controllers/my_profile/profile_roles_controller.rb 0 → 100644
@@ -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/controllers/my_profile/tasks_controller.rb
1 class TasksController < MyProfileController 1 class TasksController < MyProfileController
2 2
3 - protect 'perform_task', :profile  
4 - 3 + protect [:perform_task, :view_tasks], :profile, :only => [:index]
  4 + protect :perform_task, :profile, :except => [:index]
  5 +
5 def index 6 def index
6 - @filter = params[:filter_type].blank? ? nil : params[:filter_type] 7 + @filter_type = params[:filter_type].presence
  8 + @filter_text = params[:filter_text].presence
  9 + @filter_responsible = params[:filter_responsible]
7 @task_types = Task.pending_types_for(profile) 10 @task_types = Task.pending_types_for(profile)
8 - @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) 11 +
  12 + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc')
  13 + @tasks = @tasks.where(:responsible_id => @filter_responsible.to_i != -1 ? @filter_responsible : nil) if @filter_responsible.present?
  14 + @tasks = @tasks.paginate(:per_page => Task.per_page, :page => params[:page])
  15 +
9 @failed = params ? params[:failed] : {} 16 @failed = params ? params[:failed] : {}
  17 +
  18 + @responsible_candidates = profile.members.by_role(profile.roles.reject {|r| !r.has_permission?('perform_task')}) if profile.organization?
  19 +
  20 + @view_only = !current_person.has_permission?(:perform_task, profile)
10 end 21 end
11 22
12 def processed 23 def processed
13 @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at) 24 @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at)
14 end 25 end
15 26
  27 + def change_responsible
  28 + task = profile.tasks.find(params[:task_id])
  29 +
  30 + if task.responsible.present? && task.responsible.id != params[:old_responsible_id].to_i
  31 + return render :json => {:notice => _('Task already assigned!'), :success => false, :current_responsible => task.responsible.id}
  32 + end
  33 +
  34 + responsible = profile.members.find(params[:responsible_id]) if params[:responsible_id].present?
  35 + task.responsible = responsible
  36 + task.save!
  37 + render :json => {:notice => _('Task responsible successfully updated!'), :success => true, :new_responsible => {:id => responsible.present? ? responsible.id : nil}}
  38 + end
  39 +
16 VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] 40 VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ]
17 41
18 def close 42 def close
@@ -25,7 +49,7 @@ class TasksController &lt; MyProfileController @@ -25,7 +49,7 @@ class TasksController &lt; MyProfileController
25 task = profile.find_in_all_tasks(id) 49 task = profile.find_in_all_tasks(id)
26 begin 50 begin
27 task.update_attributes(value[:task]) 51 task.update_attributes(value[:task])
28 - task.send(decision) 52 + task.send(decision, current_person)
29 rescue Exception => ex 53 rescue Exception => ex
30 message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})" 54 message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
31 failed[ex.message] ? failed[ex.message] << message : failed[ex.message] = [message] 55 failed[ex.message] ? failed[ex.message] << message : failed[ex.message] = [message]
app/controllers/public/chat_controller.rb
@@ -2,6 +2,7 @@ class ChatController &lt; PublicController @@ -2,6 +2,7 @@ class ChatController &lt; PublicController
2 2
3 before_filter :login_required 3 before_filter :login_required
4 before_filter :check_environment_feature 4 before_filter :check_environment_feature
  5 + before_filter :can_send_message, :only => :register_message
5 6
6 def start_session 7 def start_session
7 login = user.jid 8 login = user.jid
@@ -54,6 +55,16 @@ class ChatController &lt; PublicController @@ -54,6 +55,16 @@ class ChatController &lt; PublicController
54 end 55 end
55 end 56 end
56 57
  58 + def avatars
  59 + profiles = environment.profiles.where(:identifier => params[:profiles])
  60 + avatar_map = profiles.inject({}) do |result, profile|
  61 + result[profile.identifier] = profile_icon(profile, :minor)
  62 + result
  63 + end
  64 +
  65 + render_json avatar_map
  66 + end
  67 +
57 def update_presence_status 68 def update_presence_status
58 if request.xhr? 69 if request.xhr?
59 current_user.update_attributes({:chat_status_at => DateTime.now}.merge(params[:status] || {})) 70 current_user.update_attributes({:chat_status_at => DateTime.now}.merge(params[:status] || {}))
@@ -62,11 +73,17 @@ class ChatController &lt; PublicController @@ -62,11 +73,17 @@ class ChatController &lt; PublicController
62 end 73 end
63 74
64 def save_message 75 def save_message
65 - to = environment.profiles.find_by_identifier(params[:to])  
66 - body = params[:body]  
67 -  
68 - ChatMessage.create!(:to => to, :from => user, :body => body)  
69 - render :text => 'ok' 76 + if request.post?
  77 + to = environment.profiles.where(:identifier => params[:to]).first
  78 + body = params[:body]
  79 +
  80 + begin
  81 + ChatMessage.create!(:to => to, :from => user, :body => body)
  82 + return render_json({:status => 0})
  83 + rescue Exception => exception
  84 + return render_json({:status => 3, :message => exception.to_s, :backtrace => exception.backtrace})
  85 + end
  86 + end
70 end 87 end
71 88
72 def recent_messages 89 def recent_messages
@@ -90,8 +107,9 @@ class ChatController &lt; PublicController @@ -90,8 +107,9 @@ class ChatController &lt; PublicController
90 end 107 end
91 108
92 def recent_conversations 109 def recent_conversations
93 - conversations_order = ActiveRecord::Base.connection.execute("select profiles.identifier from profiles inner join (select distinct r.id as id, MAX(r.created_at) as created_at from (select from_id, to_id, created_at, (case when from_id=#{user.id} then to_id else from_id end) as id from chat_messages where from_id=#{user.id} or to_id=#{user.id}) as r group by id order by created_at desc, id) as t on profiles.id=t.id order by t.created_at desc").entries.map {|e| e['identifier']}  
94 - render :json => {:order => conversations_order.reverse, :domain => environment.default_hostname.gsub('.','-')}.to_json 110 + profiles = Profile.find_by_sql("select profiles.* from profiles inner join (select distinct r.id as id, MAX(r.created_at) as created_at from (select from_id, to_id, created_at, (case when from_id=#{user.id} then to_id else from_id end) as id from chat_messages where from_id=#{user.id} or to_id=#{user.id}) as r group by id order by created_at desc, id) as t on profiles.id=t.id order by t.created_at desc")
  111 + jids = profiles.map(&:jid).reverse
  112 + render :json => jids.to_json
95 end 113 end
96 114
97 #TODO Ideally this is done through roster table on ejabberd. 115 #TODO Ideally this is done through roster table on ejabberd.
@@ -108,4 +126,14 @@ class ChatController &lt; PublicController @@ -108,4 +126,14 @@ class ChatController &lt; PublicController
108 end 126 end
109 end 127 end
110 128
  129 + def can_send_message
  130 + return render_json({:status => 1, :message => 'Missing parameters!'}) if params[:from].nil? || params[:to].nil? || params[:message].nil?
  131 + return render_json({:status => 2, :message => 'You can not send message as another user!'}) if params[:from] != user.jid
  132 + # TODO Maybe register the jid in a table someday to avoid this below
  133 + return render_json({:status => 3, :messsage => 'You can not send messages to strangers!'}) if user.friends.where(:identifier => params[:to].split('@').first).blank?
  134 + end
  135 +
  136 + def render_json(result)
  137 + render :text => result.to_json
  138 + end
111 end 139 end
app/controllers/public/content_viewer_controller.rb
@@ -11,9 +11,10 @@ class ContentViewerController &lt; ApplicationController @@ -11,9 +11,10 @@ class ContentViewerController &lt; ApplicationController
11 path = get_path(params[:page], params[:format]) 11 path = get_path(params[:page], params[:format])
12 12
13 @version = params[:version].to_i 13 @version = params[:version].to_i
  14 + @npage = params[:npage] || '1'
14 15
15 if path.blank? 16 if path.blank?
16 - @page = profile.home_page 17 + @page = profile.home_page
17 return if redirected_to_profile_index 18 return if redirected_to_profile_index
18 else 19 else
19 @page = profile.articles.find_by_path(path) 20 @page = profile.articles.find_by_path(path)
@@ -107,10 +108,12 @@ class ContentViewerController &lt; ApplicationController @@ -107,10 +108,12 @@ class ContentViewerController &lt; ApplicationController
107 if translation.language == locale 108 if translation.language == locale
108 @page = translation 109 @page = translation
109 redirect_to :profile => @page.profile.identifier, :page => @page.explode_path 110 redirect_to :profile => @page.profile.identifier, :page => @page.explode_path
  111 + return true
110 end 112 end
111 end 113 end
112 end 114 end
113 end 115 end
  116 + false
114 end 117 end
115 118
116 def pass_without_comment_captcha? 119 def pass_without_comment_captcha?
@@ -119,21 +122,23 @@ class ContentViewerController &lt; ApplicationController @@ -119,21 +122,23 @@ class ContentViewerController &lt; ApplicationController
119 helper_method :pass_without_comment_captcha? 122 helper_method :pass_without_comment_captcha?
120 123
121 def allow_access_to_page(path) 124 def allow_access_to_page(path)
122 - allowed = true  
123 if @page.nil? # page not found, give error 125 if @page.nil? # page not found, give error
124 render_not_found(path) 126 render_not_found(path)
125 - allowed = false  
126 - elsif !@page.display_to?(user)  
127 - if !profile.public? 127 + return false
  128 + end
  129 +
  130 + unless @page.display_to?(user)
  131 + if !profile.visible? || profile.secret? || (user && user.follows?(profile)) || user.blank?
  132 + render_access_denied
  133 + else #!profile.public?
128 private_profile_partial_parameters 134 private_profile_partial_parameters
129 render :template => 'profile/_private_profile', :status => 403, :formats => [:html] 135 render :template => 'profile/_private_profile', :status => 403, :formats => [:html]
130 - allowed = false  
131 - else #if !profile.visible?  
132 - render_access_denied  
133 - allowed = false  
134 end 136 end
  137 +
  138 + return false
135 end 139 end
136 - allowed 140 +
  141 + return true
137 end 142 end
138 143
139 def user_is_a_bot? 144 def user_is_a_bot?
@@ -178,7 +183,7 @@ class ContentViewerController &lt; ApplicationController @@ -178,7 +183,7 @@ class ContentViewerController &lt; ApplicationController
178 if @page.forum? && @page.has_terms_of_use && terms_accepted == "true" 183 if @page.forum? && @page.has_terms_of_use && terms_accepted == "true"
179 @page.add_agreed_user(user) 184 @page.add_agreed_user(user)
180 end 185 end
181 - end 186 + end
182 187
183 def is_a_forum_topic? (page) 188 def is_a_forum_topic? (page)
184 return (!@page.parent.nil? && @page.parent.forum?) 189 return (!@page.parent.nil? && @page.parent.forum?)
app/controllers/public/events_controller.rb
@@ -5,7 +5,11 @@ class EventsController &lt; PublicController @@ -5,7 +5,11 @@ class EventsController &lt; PublicController
5 5
6 def events 6 def events
7 @events = [] 7 @events = []
8 - @date = build_date(params[:year], params[:month], params[:day]) 8 + begin
  9 + @date = build_date params[:year], params[:month], params[:day]
  10 + rescue ArgumentError # invalid date
  11 + return render_not_found
  12 + end
9 13
10 if !params[:year] && !params[:month] && !params[:day] 14 if !params[:year] && !params[:month] && !params[:day]
11 @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page]) 15 @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page])
app/controllers/public/search_controller.rb
@@ -62,7 +62,7 @@ class SearchController &lt; PublicController @@ -62,7 +62,7 @@ class SearchController &lt; PublicController
62 end 62 end
63 63
64 def articles 64 def articles
65 - @scope = @environment.articles.public.paginate(paginate_options) 65 + @scope = @environment.articles.public
66 full_text_search 66 full_text_search
67 end 67 end
68 68
@@ -76,7 +76,7 @@ class SearchController &lt; PublicController @@ -76,7 +76,7 @@ class SearchController &lt; PublicController
76 end 76 end
77 77
78 def products 78 def products
79 - @scope = @environment.products.paginate(paginate_options) 79 + @scope = @environment.products
80 full_text_search 80 full_text_search
81 end 81 end
82 82
@@ -244,7 +244,7 @@ class SearchController &lt; PublicController @@ -244,7 +244,7 @@ class SearchController &lt; PublicController
244 def visible_profiles(klass, *extra_relations) 244 def visible_profiles(klass, *extra_relations)
245 relations = [:image, :domains, :environment, :preferred_domain] 245 relations = [:image, :domains, :environment, :preferred_domain]
246 relations += extra_relations 246 relations += extra_relations
247 - @environment.send(klass.name.underscore.pluralize).visible.includes(relations).paginate(paginate_options) 247 + @environment.send(klass.name.underscore.pluralize).visible.includes(relations)
248 end 248 end
249 249
250 def per_page 250 def per_page
app/controllers/public_controller.rb
@@ -3,7 +3,7 @@ class PublicController &lt; ApplicationController @@ -3,7 +3,7 @@ class PublicController &lt; ApplicationController
3 3
4 def allow_access_to_page 4 def allow_access_to_page
5 unless profile.display_info_to?(user) 5 unless profile.display_info_to?(user)
6 - if profile.visible? 6 + if profile.visible? && !profile.secret
7 private_profile 7 private_profile
8 else 8 else
9 invisible_profile 9 invisible_profile
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'),
@@ -853,7 +871,7 @@ module ApplicationHelper @@ -853,7 +871,7 @@ module ApplicationHelper
853 field_html += capture(&block) 871 field_html += capture(&block)
854 end 872 end
855 873
856 - if controller.action_name == 'signup' || controller.action_name == 'new_community' || (controller.controller_name == "enterprise_registration" && controller.action_name == 'index') 874 + if controller.action_name == 'signup' || controller.action_name == 'new_community' || (controller.controller_name == "enterprise_registration" && controller.action_name == 'index') || (controller.controller_name == 'home' && controller.action_name == 'index' && user.nil?)
857 if profile.signup_fields.include?(name) 875 if profile.signup_fields.include?(name)
858 result = field_html 876 result = field_html
859 end 877 end
@@ -913,6 +931,19 @@ module ApplicationHelper @@ -913,6 +931,19 @@ module ApplicationHelper
913 article_helper.cms_label_for_edit 931 article_helper.cms_label_for_edit
914 end 932 end
915 933
  934 + def label_for_clone_article(article)
  935 + translated_types = {
  936 + Folder => _('Folder'),
  937 + Blog => _('Blog'),
  938 + Event => _('Event'),
  939 + Forum => _('Forum')
  940 + }
  941 +
  942 + translated_type = translated_types[article.class] || _('Article')
  943 +
  944 + _('Clone %s') % translated_type
  945 + end
  946 +
916 def add_rss_feed_to_head(title, url) 947 def add_rss_feed_to_head(title, url)
917 content_for :feeds do 948 content_for :feeds do
918 tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url)) 949 tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url))
@@ -1184,35 +1215,6 @@ module ApplicationHelper @@ -1184,35 +1215,6 @@ module ApplicationHelper
1184 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort 1215 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort
1185 end 1216 end
1186 1217
1187 - #FIXME Use time_ago_in_words instead of this method if you're using Rails 2.2+  
1188 - def time_ago_as_sentence(from_time, include_seconds = false)  
1189 - to_time = Time.now  
1190 - from_time = Time.parse(from_time.to_s)  
1191 - from_time = from_time.to_time if from_time.respond_to?(:to_time)  
1192 - to_time = to_time.to_time if to_time.respond_to?(:to_time)  
1193 - distance_in_minutes = (((to_time - from_time).abs)/60).round  
1194 - distance_in_seconds = ((to_time - from_time).abs).round  
1195 - case distance_in_minutes  
1196 - when 0..1  
1197 - return (distance_in_minutes == 0) ? _('less than a minute') : _('1 minute') unless include_seconds  
1198 - case distance_in_seconds  
1199 - when 0..4 then _('less than 5 seconds')  
1200 - when 5..9 then _('less than 10 seconds')  
1201 - when 10..19 then _('less than 20 seconds')  
1202 - when 20..39 then _('half a minute')  
1203 - when 40..59 then _('less than a minute')  
1204 - else _('1 minute')  
1205 - end  
1206 -  
1207 - when 2..44 then _('%{distance} minutes ago') % { :distance => distance_in_minutes }  
1208 - when 45..89 then _('about 1 hour ago')  
1209 - when 90..1439 then _('about %{distance} hours ago') % { :distance => (distance_in_minutes.to_f / 60.0).round }  
1210 - when 1440..2879 then _('1 day ago')  
1211 - when 2880..10079 then _('%{distance} days ago') % { :distance => (distance_in_minutes / 1440).round }  
1212 - else show_time(from_time)  
1213 - end  
1214 - end  
1215 -  
1216 def comment_balloon(options = {}, &block) 1218 def comment_balloon(options = {}, &block)
1217 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content') 1219 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content')
1218 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") } 1220 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") }
@@ -1480,4 +1482,26 @@ module ApplicationHelper @@ -1480,4 +1482,26 @@ module ApplicationHelper
1480 text_field(object_name, method, options.merge(:class => 'colorpicker_field')) 1482 text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
1481 end 1483 end
1482 1484
  1485 + def fullscreen_buttons(itemId)
  1486 + content="
  1487 + <script>fullscreenPageLoad('#{itemId}')</script>
  1488 + "
  1489 + content+=content_tag('a', content_tag('span',_("Full screen")),
  1490 + { :id=>"fullscreen-btn",
  1491 + :onClick=>"toggle_fullwidth('#{itemId}')",
  1492 + :class=>"button with-text icon-fullscreen",
  1493 + :href=>"#",
  1494 + :title=>_("Go to full screen mode")
  1495 + })
  1496 +
  1497 + content+=content_tag('a', content_tag('span',_("Exit full screen")),
  1498 + { :style=>"display: none;",
  1499 + :id=>"exit-fullscreen-btn",
  1500 + :onClick=>"toggle_fullwidth('#{itemId}')",
  1501 + :class=>"button with-text icon-fullscreen",
  1502 + :href=>"#",
  1503 + :title=>_("Exit full screen mode")
  1504 + })
  1505 + end
  1506 +
1483 end 1507 end
app/helpers/article_helper.rb
@@ -12,6 +12,7 @@ module ArticleHelper @@ -12,6 +12,7 @@ module ArticleHelper
12 @article = article 12 @article = article
13 13
14 visibility_options(@article, tokenized_children) + 14 visibility_options(@article, tokenized_children) +
  15 + topic_creation(@article) +
15 content_tag('h4', _('Options')) + 16 content_tag('h4', _('Options')) +
16 content_tag('div', 17 content_tag('div',
17 (article.profile.has_members? ? 18 (article.profile.has_members? ?
@@ -55,14 +56,7 @@ module ArticleHelper @@ -55,14 +56,7 @@ module ArticleHelper
55 'div', 56 'div',
56 check_box(:article, :display_versions) + 57 check_box(:article, :display_versions) +
57 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') 58 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
58 - ) : '') +  
59 -  
60 - (article.forum? && article.profile.community? ?  
61 - content_tag(  
62 - 'div',  
63 - check_box(:article, :allows_members_to_create_topics) +  
64 - content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')  
65 - ) : '') 59 + ) : '')
66 ) 60 )
67 end 61 end
68 62
@@ -81,6 +75,22 @@ module ArticleHelper @@ -81,6 +75,22 @@ module ArticleHelper
81 ) 75 )
82 end 76 end
83 77
  78 + def topic_creation(article)
  79 + return '' unless article.forum?
  80 +
  81 + general_options = Forum::TopicCreation.general_options(article)
  82 + slider_options = {:id => 'topic-creation-slider'}
  83 + slider_options = general_options.keys.inject(slider_options) do |result, option|
  84 + result.merge!({'data-'+option => general_options[option]})
  85 + end
  86 +
  87 + content_tag('h4', _('Topic creation')) +
  88 + content_tag( 'small', _('Who will be able to create new topics on this forum?')) +
  89 + content_tag('div', '', slider_options) +
  90 + hidden_field_tag('article[topic_creation]', article.topic_creation) +
  91 + javascript_include_tag('topic-creation-config')
  92 + end
  93 +
84 def privacity_exceptions(article, tokenized_children) 94 def privacity_exceptions(article, tokenized_children)
85 content_tag('div', 95 content_tag('div',
86 content_tag('div', 96 content_tag('div',
app/helpers/blog_helper.rb
@@ -17,37 +17,52 @@ module BlogHelper @@ -17,37 +17,52 @@ 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 => _('&laquo; Newer posts'), 23 :previous_label => _('&laquo; Newer posts'),
24 :next_label => _('Older posts &raquo;'), 24 :next_label => _('Older posts &raquo;'),
25 - :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"}  
26 - }) if articles.present? && paginate 25 + :params => {:action=>"view_page",
  26 + :page=>articles.first.parent.path.split('/'),
  27 + :controller=>"content_viewer"}
  28 + }) if articles.present? && conf[:paginate]
27 content = [] 29 content = []
28 artic_len = articles.length 30 artic_len = articles.length
29 articles.each_with_index{ |art,i| 31 articles.each_with_index{ |art,i|
30 - css_add = [ 'position-'+(i+1).to_s() ] 32 + css_add = [ 'blog-post', 'position-'+(i+1).to_s() ]
31 position = (i%2 == 0) ? 'odd-post' : 'even-post' 33 position = (i%2 == 0) ? 'odd-post' : 'even-post'
32 css_add << 'first' if i == 0 34 css_add << 'first' if i == 0
33 css_add << 'last' if i == (artic_len-1) 35 css_add << 'last' if i == (artic_len-1)
34 css_add << 'not-published' if !art.published? 36 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 - ) 37 + css_add << position
  38 + content << (content_tag 'div', id: "post-#{art.id}", class: css_add do
  39 + content_tag 'div', class: position + '-inner blog-post-inner' do
  40 + display_post(art, conf[:format]).html_safe +
  41 + '<br style="clear:both"/>'.html_safe
  42 + end
  43 + end)
42 } 44 }
43 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '') 45 content.join("\n<hr class='sep-posts'/>\n") + (pagination or '')
44 end 46 end
45 47
46 def display_post(article, format = 'full') 48 def display_post(article, format = 'full')
47 - no_comments = (format == 'full') ? false : true 49 + no_comments = (format == 'full' || format == 'compact' ) ? false : true
48 title = article_title(article, :no_comments => no_comments) 50 title = article_title(article, :no_comments => no_comments)
49 - html = send("display_#{format}_format", FilePresenter.for(article)).html_safe  
50 - title + html 51 + method = "display_#{format.split('+')[0]}_format"
  52 + html = send(method, FilePresenter.for(article)).html_safe
  53 + if format.split('+')[1] == 'pic'
  54 + img = article.first_image
  55 + if img.blank?
  56 + '<div class="post-pic empty"></div>'
  57 + else
  58 + '<div class="post-pic" style="background-image:url('+img+')"></div>'
  59 + end
  60 + end.to_s + title + html
  61 + end
  62 +
  63 + def display_compact_format(article)
  64 + render :file => 'content_viewer/_display_compact_format',
  65 + :locals => { :article => article, :format => "compact" }
51 end 66 end
52 67
53 def display_full_format(article) 68 def display_full_format(article)
app/helpers/boxes_helper.rb
@@ -122,7 +122,7 @@ module BoxesHelper @@ -122,7 +122,7 @@ module BoxesHelper
122 end 122 end
123 123
124 def wrap_main_content(content) 124 def wrap_main_content(content)
125 - (1..8).to_a.reverse.inject(content) { |acc,n| content_tag('div', acc, :id => 'main-content-wrapper-' + n.to_s) } 125 + content_tag('div', content, :class => 'main-content')
126 end 126 end
127 127
128 def extract_block_content(content) 128 def extract_block_content(content)
@@ -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', '&nbsp;', :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', '&nbsp;', :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)
@@ -251,8 +251,8 @@ module BoxesHelper @@ -251,8 +251,8 @@ module BoxesHelper
251 content_tag('h2', _('Embed block code')) + 251 content_tag('h2', _('Embed block code')) +
252 content_tag('div', _('Below, you''ll see a field containing embed code for the block. Just copy the code and paste it into your website or blogging software.'), :style => 'margin-bottom: 1em;') + 252 content_tag('div', _('Below, you''ll see a field containing embed code for the block. Just copy the code and paste it into your website or blogging software.'), :style => 'margin-bottom: 1em;') +
253 content_tag('textarea', embed_code, :style => 'margin-bottom: 1em; width:100%; height:40%;', :readonly => 'readonly') + 253 content_tag('textarea', embed_code, :style => 'margin-bottom: 1em; width:100%; height:40%;', :readonly => 'readonly') +
254 - thickbox_close_button(_('Close')), :style => 'display: none;', :id => "embed-code-box-#{block.id}")  
255 - buttons << thickbox_inline_popup_icon(:embed, _('Embed code'), {}, "embed-code-box-#{block.id}") << html 254 + modal_close_button(_('Close')), :style => 'display: none;', :id => "embed-code-box-#{block.id}")
  255 + buttons << modal_inline_icon(:embed, _('Embed code'), {}, "#embed-code-box-#{block.id}") << html
256 end 256 end
257 257
258 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') 258 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar')
@@ -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/chat_helper.rb
@@ -9,12 +9,12 @@ module ChatHelper @@ -9,12 +9,12 @@ module ChatHelper
9 avatar = profile_image(user, :portrait, :class => 'avatar') 9 avatar = profile_image(user, :portrait, :class => 'avatar')
10 content_tag('span', 10 content_tag('span',
11 link_to(avatar + content_tag('span', user.name) + ui_icon('ui-icon-triangle-1-s'), 11 link_to(avatar + content_tag('span', user.name) + ui_icon('ui-icon-triangle-1-s'),
12 - '#', 12 + '',
13 :onclick => 'toggleMenu(this); return false', 13 :onclick => 'toggleMenu(this); return false',
14 :class => icon_class + ' simplemenu-trigger' 14 :class => icon_class + ' simplemenu-trigger'
15 ) + 15 ) +
16 content_tag('ul', 16 content_tag('ul',
17 - links.map{|link| content_tag('li', link_to(link[1], '#', :class => link[0], :id => link[2], 'data-jid' => user.jid), :class => 'simplemenu-item') }.join("\n"), 17 + links.map{|link| content_tag('li', link_to(link[1], '', :class => link[0], :id => link[2], 'data-jid' => user.jid), :class => 'simplemenu-item') }.join("\n"),
18 :style => 'display: none; z-index: 100', 18 :style => 'display: none; z-index: 100',
19 :class => 'simplemenu-submenu' 19 :class => 'simplemenu-submenu'
20 ), 20 ),
app/helpers/comment_helper.rb
1 module CommentHelper 1 module CommentHelper
  2 + include DatesHelper
2 3
3 def article_title(article, args = {}) 4 def article_title(article, args = {})
4 title = article.title 5 title = article.title
app/helpers/content_viewer_helper.rb
@@ -2,6 +2,7 @@ module ContentViewerHelper @@ -2,6 +2,7 @@ module ContentViewerHelper
2 2
3 include BlogHelper 3 include BlogHelper
4 include ForumHelper 4 include ForumHelper
  5 + include DatesHelper
5 6
6 def display_number_of_comments(n) 7 def display_number_of_comments(n)
7 base_str = "<span class='comment-count hide'>#{n}</span>" 8 base_str = "<span class='comment-count hide'>#{n}</span>"
@@ -24,8 +25,9 @@ module ContentViewerHelper @@ -24,8 +25,9 @@ module ContentViewerHelper
24 unless args[:no_comments] || !article.accept_comments 25 unless args[:no_comments] || !article.accept_comments
25 comments = (" - %s") % link_to_comments(article) 26 comments = (" - %s") % link_to_comments(article)
26 end 27 end
  28 + date_format = show_with_right_format_date article
27 title << content_tag('span', 29 title << content_tag('span',
28 - content_tag('span', show_date(article.published_at), :class => 'date') + 30 + date_format +
29 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + 31 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
30 content_tag('span', comments, :class => 'comments'), 32 content_tag('span', comments, :class => 'comments'),
31 :class => 'created-at' 33 :class => 'created-at'
@@ -34,6 +36,24 @@ module ContentViewerHelper @@ -34,6 +36,24 @@ module ContentViewerHelper
34 title 36 title
35 end 37 end
36 38
  39 + def show_with_right_format_date article
  40 + date_format = article.environment.date_format
  41 + use_numbers = false
  42 + year = true
  43 + left_time = false
  44 + if date_format == 'numbers_with_year'
  45 + use_numbers = true
  46 + elsif date_format == 'numbers'
  47 + use_numbers = true
  48 + year = false
  49 + elsif date_format == 'month_name'
  50 + year = false
  51 + elsif date_format == 'past_time'
  52 + left_time = true
  53 + end
  54 + content_tag('span', show_date(article.published_at, use_numbers , year, left_time), :class => 'date')
  55 + end
  56 +
37 def link_to_comments(article, args = {}) 57 def link_to_comments(article, args = {})
38 return '' unless article.accept_comments? 58 return '' unless article.accept_comments?
39 reference_to_article number_of_comments(article), article, 'comments_list' 59 reference_to_article number_of_comments(article), article, 'comments_list'
app/helpers/dates_helper.rb
@@ -2,6 +2,7 @@ require &#39;noosfero/i18n&#39; @@ -2,6 +2,7 @@ require &#39;noosfero/i18n&#39;
2 2
3 module DatesHelper 3 module DatesHelper
4 4
  5 + include ActionView::Helpers::DateHelper
5 def months 6 def months
6 I18n.t('date.month_names') 7 I18n.t('date.month_names')
7 end 8 end
@@ -15,10 +16,12 @@ module DatesHelper @@ -15,10 +16,12 @@ module DatesHelper
15 end 16 end
16 17
17 # formats a date for displaying. 18 # formats a date for displaying.
18 - def show_date(date, use_numbers = false, year=true) 19 + def show_date(date, use_numbers = false, year = true, left_time = false)
19 if date && use_numbers 20 if date && use_numbers
20 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}') 21 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
21 date_format % { :day => date.day, :month => date.month, :year => date.year } 22 date_format % { :day => date.day, :month => date.month, :year => date.year }
  23 + elsif date && left_time
  24 + date_format = time_ago_in_words(date)
22 elsif date 25 elsif date
23 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}') 26 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
24 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year } 27 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
app/helpers/events_helper.rb
1 module EventsHelper 1 module EventsHelper
2 2
  3 + include DatesHelper
3 def list_events(date, events) 4 def list_events(date, events)
4 title = _('Events for %s') % show_date_month(date) 5 title = _('Events for %s') % show_date_month(date)
5 content_tag('h2', title) + 6 content_tag('h2', title) +
app/helpers/folder_helper.rb
1 -require 'short_filename'  
2 -  
3 module FolderHelper 1 module FolderHelper
4 2
5 - include ShortFilename  
6 include ArticleHelper 3 include ArticleHelper
7 4
8 def list_contents(configure={}) 5 def list_contents(configure={})
@@ -10,8 +7,8 @@ module FolderHelper @@ -10,8 +7,8 @@ module FolderHelper
10 configure[:list_type] ||= :folder 7 configure[:list_type] ||= :folder
11 if !configure[:contents].blank? 8 if !configure[:contents].blank?
12 configure[:contents] = configure[:contents].paginate( 9 configure[:contents] = configure[:contents].paginate(
13 - :order => "updated_at DESC",  
14 - :per_page => 10, 10 + :order => "name ASC",
  11 + :per_page => 30,
15 :page => params[:npage] 12 :page => params[:npage]
16 ) 13 )
17 14
@@ -25,49 +22,32 @@ module FolderHelper @@ -25,49 +22,32 @@ module FolderHelper
25 articles.select {|article| article.display_to?(user)} 22 articles.select {|article| article.display_to?(user)}
26 end 23 end
27 24
28 - def display_content_in_listing(configure={})  
29 - recursive = configure[:recursive] || false  
30 - list_type = configure[:list_type] || :folder  
31 - level = configure[:level] || 0  
32 - content = FilePresenter.for configure[:content] 25 + def display_content_icon(content_item)
  26 + content = FilePresenter.for content_item
33 content_link = if content.image? 27 content_link = if content.image?
34 - link_to('&nbsp;' * (level * 4) +  
35 - image_tag(icon_for_article(content)) + short_filename(content.name), 28 + link_to(
  29 + image_tag(icon_for_article(content, :bigicon)),
36 content.url.merge(:view => true) 30 content.url.merge(:view => true)
37 ) 31 )
38 else 32 else
39 - link_to('&nbsp;' * (level * 4) +  
40 - short_filename(content.name),  
41 - content.url.merge(:view => true), :class => icon_for_article(content) 33 + link_to('',
  34 + content.url.merge(:view => true),
  35 + :class => icon_for_article(content, :bigicon)
42 ) 36 )
43 end 37 end
44 - result = content_tag(  
45 - 'tr',  
46 - content_tag('td', content_link ) +  
47 - content_tag('td', show_date(content.updated_at), :class => 'last-update'),  
48 - :class => "#{list_type}-item"  
49 - )  
50 - if recursive  
51 - result + content.children.map {|item|  
52 - display_content_in_listing :content=>item, :recursive=>recursive,  
53 - :list_type=>list_type, :level=>level+1  
54 - }.join("\n")  
55 - else  
56 - result  
57 - end  
58 end 38 end
59 39
60 - def icon_for_article(article) 40 + def icon_for_article(article, size = 'icon')
61 article = FilePresenter.for article 41 article = FilePresenter.for article
62 - icon = article.respond_to?(:icon_name) ?  
63 - article.icon_name :  
64 - article.class.icon_name(article)  
65 - if (icon =~ /\//)  
66 - icon 42 + if article.respond_to?(:sized_icon)
  43 + article.sized_icon(size)
67 else 44 else
68 - klasses = 'icon ' + [icon].flatten.map{|name| 'icon-'+name}.join(' ') 45 + icon = article.respond_to?(:icon_name) ?
  46 + article.icon_name :
  47 + article.class.icon_name(article)
  48 + klasses = "#{size} " + [icon].flatten.map{|name| "#{size}-"+name}.join(' ')
69 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter) 49 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter)
70 - klasses += ' icon-upload-file' 50 + klasses += " #{size}-upload-file"
71 end 51 end
72 klasses 52 klasses
73 end 53 end
app/helpers/forum_helper.rb
1 module ForumHelper 1 module ForumHelper
  2 + include ActionView::Helpers::DateHelper
2 3
3 def cms_label_for_new_children 4 def cms_label_for_new_children
4 _('New discussion topic') 5 _('New discussion topic')
@@ -42,9 +43,9 @@ module ForumHelper @@ -42,9 +43,9 @@ module ForumHelper
42 def last_topic_update(article) 43 def last_topic_update(article)
43 info = article.info_from_last_update 44 info = article.info_from_last_update
44 if info[:author_url] 45 if info[:author_url]
45 - time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url]) 46 + time_ago_in_words(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url])
46 else 47 else
47 - time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + info[:author_name] 48 + time_ago_in_words(info[:date]) + ' ' + _('by') + ' ' + info[:author_name]
48 end 49 end
49 end 50 end
50 51
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/manage_products_helper.rb
@@ -75,9 +75,12 @@ module ManageProductsHelper @@ -75,9 +75,12 @@ module ManageProductsHelper
75 end 75 end
76 76
77 def categories_container(categories_selection_html, hierarchy_html = '') 77 def categories_container(categories_selection_html, hierarchy_html = '')
78 - hidden_field_tag('selected_category_id') +  
79 - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +  
80 - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper') 78 + content_tag 'div',
  79 + render('categories_autocomplete') +
  80 + hidden_field_tag('selected_category_id') +
  81 + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
  82 + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'),
  83 + :id => 'categories-container'
81 end 84 end
82 85
83 def select_for_categories(categories, level = 0) 86 def select_for_categories(categories, level = 0)
app/helpers/profile_editor_helper.rb
@@ -141,8 +141,9 @@ module ProfileEditorHelper @@ -141,8 +141,9 @@ module ProfileEditorHelper
141 ) 141 )
142 end 142 end
143 143
144 - def control_panel_button(title, icon, url)  
145 - link_to title, url, :class => 'control-panel-%s' % icon 144 + def control_panel_button(title, icon, url, html_options = {})
  145 + html_options ||= {}
  146 + link_to title, url, html_options.merge(:class => 'control-panel-%s' % icon)
146 end 147 end
147 148
148 def unchangeable_privacy_field(profile) 149 def unchangeable_privacy_field(profile)
app/helpers/search_helper.rb
@@ -106,6 +106,10 @@ module SearchHelper @@ -106,6 +106,10 @@ module SearchHelper
106 end 106 end
107 end 107 end
108 108
  109 + def city_with_state_for_profile(p)
  110 + city_with_state(p.region) || [p.city, p.state].compact.reject(&:blank?).join(', ')
  111 + end
  112 +
109 def display_selector(asset, display, float = 'right') 113 def display_selector(asset, display, float = 'right')
110 display = nil if display.blank? 114 display = nil if display.blank?
111 display ||= asset_class(asset).default_search_display 115 display ||= asset_class(asset).default_search_display
app/helpers/tinymce_helper.rb
@@ -17,9 +17,10 @@ module TinymceHelper @@ -17,9 +17,10 @@ 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] = "fullscreen | insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
23 if options[:mode] == 'simple' 24 if options[:mode] == 'simple'
24 options[:menubar] = false 25 options[:menubar] = false
25 else 26 else
app/helpers/users_helper.rb
@@ -14,7 +14,7 @@ module UsersHelper @@ -14,7 +14,7 @@ module UsersHelper
14 select_field = select_tag(:filter, options, :onchange => onchange) 14 select_field = select_tag(:filter, options, :onchange => onchange)
15 content_tag('div', 15 content_tag('div',
16 content_tag('strong', _('Filter')) + ': ' + select_field, 16 content_tag('strong', _('Filter')) + ': ' + select_field,
17 - :class => "environment-users-customize-search" 17 + :class => "environment-profiles-customize-search"
18 ) 18 )
19 end 19 end
20 20
app/mailers/task_mailer.rb
@@ -5,7 +5,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -5,7 +5,7 @@ class TaskMailer &lt; ActionMailer::Base
5 @target = task.target.name 5 @target = task.target.name
6 @environment = task.environment.name 6 @environment = task.environment.name
7 @url = generate_environment_url(task, :controller => 'home') 7 @url = generate_environment_url(task, :controller => 'home')
8 - url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url) 8 + url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url.merge(:script_name => Noosfero.root('/')))
9 @tasks_url = url_for_tasks_list 9 @tasks_url = url_for_tasks_list
10 10
11 mail( 11 mail(
@@ -56,7 +56,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -56,7 +56,7 @@ class TaskMailer &lt; ActionMailer::Base
56 end 56 end
57 57
58 def generate_environment_url(task, url = {}) 58 def generate_environment_url(task, url = {})
59 - url_for(Noosfero.url_options.merge(:host => task.environment.default_hostname).merge(url)) 59 + url_for(Noosfero.url_options.merge(:host => task.environment.default_hostname).merge(url).merge(:script_name => Noosfero.root('/')))
60 end 60 end
61 61
62 end 62 end
app/models/add_friend.rb
@@ -54,7 +54,7 @@ class AddFriend &lt; Task @@ -54,7 +54,7 @@ class AddFriend &lt; Task
54 end 54 end
55 55
56 def remove_from_suggestion_list(task) 56 def remove_from_suggestion_list(task)
57 - suggestion = task.requestor.profile_suggestions.find_by_suggestion_id task.target.id 57 + suggestion = task.requestor.suggested_profiles.find_by_suggestion_id task.target.id
58 suggestion.disable if suggestion 58 suggestion.disable if suggestion
59 end 59 end
60 end 60 end
app/models/article.rb
@@ -5,7 +5,7 @@ class Article &lt; ActiveRecord::Base @@ -5,7 +5,7 @@ class Article &lt; 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
@@ -25,6 +25,16 @@ class Article &lt; ActiveRecord::Base @@ -25,6 +25,16 @@ class Article &lt; ActiveRecord::Base
25 :display => %w[full] 25 :display => %w[full]
26 } 26 }
27 27
  28 + def initialize(*params)
  29 + super
  30 +
  31 + if !params.blank? && params.first.has_key?(:profile) && !params.first[:profile].blank?
  32 + profile = params.first[:profile]
  33 + self.published = false unless profile.public?
  34 + end
  35 +
  36 + end
  37 +
28 def self.default_search_display 38 def self.default_search_display
29 'full' 39 'full'
30 end 40 end
@@ -86,6 +96,8 @@ class Article &lt; ActiveRecord::Base @@ -86,6 +96,8 @@ class Article &lt; ActiveRecord::Base
86 belongs_to :translation_of, :class_name => 'Article', :foreign_key => :translation_of_id 96 belongs_to :translation_of, :class_name => 'Article', :foreign_key => :translation_of_id
87 before_destroy :rotate_translations 97 before_destroy :rotate_translations
88 98
  99 + acts_as_voteable
  100 +
89 before_create do |article| 101 before_create do |article|
90 article.published_at ||= Time.now 102 article.published_at ||= Time.now
91 if article.reference_article && !article.parent 103 if article.reference_article && !article.parent
@@ -491,11 +503,11 @@ class Article &lt; ActiveRecord::Base @@ -491,11 +503,11 @@ class Article &lt; ActiveRecord::Base
491 return [] if user.nil? || (profile && !profile.public? && !user.follows?(profile)) 503 return [] if user.nil? || (profile && !profile.public? && !user.follows?(profile))
492 where( 504 where(
493 [ 505 [
494 - "published = ? OR last_changed_by_id = ? OR profile_id = ? OR ?  
495 - OR (show_to_followers = ? AND ?)", true, user.id, user.id, 506 + "published = ? OR last_changed_by_id = ? OR profile_id = ? OR ?
  507 + OR (show_to_followers = ? AND ? AND profile_id = ?)", true, user.id, user.id,
496 profile.nil? ? false : user.has_permission?(:view_private_content, profile), 508 profile.nil? ? false : user.has_permission?(:view_private_content, profile),
497 - true, user.follows?(profile)  
498 - ] 509 + true, user.follows?(profile), (profile.nil? ? nil : profile.id)
  510 + ]
499 ) 511 )
500 } 512 }
501 513
@@ -509,7 +521,7 @@ class Article &lt; ActiveRecord::Base @@ -509,7 +521,7 @@ class Article &lt; ActiveRecord::Base
509 521
510 def display_to?(user = nil) 522 def display_to?(user = nil)
511 if published? 523 if published?
512 - profile.display_info_to?(user) 524 + (profile.secret? || !profile.visible?) ? profile.display_info_to?(user) : true
513 else 525 else
514 if !user 526 if !user
515 false 527 false
@@ -567,25 +579,24 @@ class Article &lt; ActiveRecord::Base @@ -567,25 +579,24 @@ class Article &lt; ActiveRecord::Base
567 profile.visible? && profile.public? && published? 579 profile.visible? && profile.public? && published?
568 end 580 end
569 581
570 -  
571 - def copy(options = {}) 582 + def copy_without_save(options = {})
572 attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) } 583 attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
573 attrs.merge!(options) 584 attrs.merge!(options)
574 object = self.class.new 585 object = self.class.new
575 attrs.each do |key, value| 586 attrs.each do |key, value|
576 object.send(key.to_s+'=', value) 587 object.send(key.to_s+'=', value)
577 end 588 end
  589 + object
  590 + end
  591 +
  592 + def copy(options = {})
  593 + object = copy_without_save(options)
578 object.save 594 object.save
579 object 595 object
580 end 596 end
581 597
582 def copy!(options = {}) 598 def copy!(options = {})
583 - attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }  
584 - attrs.merge!(options)  
585 - object = self.class.new  
586 - attrs.each do |key, value|  
587 - object.send(key.to_s+'=', value)  
588 - end 599 + object = copy_without_save(options)
589 object.save! 600 object.save!
590 object 601 object
591 end 602 end
@@ -769,7 +780,9 @@ class Article &lt; ActiveRecord::Base @@ -769,7 +780,9 @@ class Article &lt; ActiveRecord::Base
769 end 780 end
770 781
771 def first_image 782 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 783 + img = ( image.present? && { 'src' => image.public_filename } ) ||
  784 + Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first ||
  785 + Nokogiri::HTML.fragment(self.body.to_s).search('img').first
773 img.nil? ? '' : img['src'] 786 img.nil? ? '' : img['src']
774 end 787 end
775 788
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, :mirror
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
@@ -13,17 +15,29 @@ class Block &lt; ActiveRecord::Base @@ -13,17 +15,29 @@ class Block &lt; ActiveRecord::Base
13 15
14 acts_as_list :scope => :box 16 acts_as_list :scope => :box
15 belongs_to :box 17 belongs_to :box
  18 + belongs_to :mirror_block, :class_name => "Block"
  19 + has_many :observers, :class_name => "Block", :foreign_key => "mirror_block_id"
16 20
17 acts_as_having_settings 21 acts_as_having_settings
18 22
19 scope :enabled, :conditions => { :enabled => true } 23 scope :enabled, :conditions => { :enabled => true }
20 24
  25 + after_save do |block|
  26 + if block.owner.kind_of?(Profile) && block.owner.is_template? && block.mirror?
  27 + block.observers.each do |observer|
  28 + observer.copy_from(block)
  29 + observer.title = block.title
  30 + observer.save
  31 + end
  32 + end
  33 + end
  34 +
21 def embedable? 35 def embedable?
22 false 36 false
23 end 37 end
24 38
25 def get_limit 39 def get_limit
26 - [0,limit].max 40 + [0,limit.to_i].max
27 end 41 end
28 42
29 def embed_code 43 def embed_code
@@ -110,8 +124,13 @@ class Block &lt; ActiveRecord::Base @@ -110,8 +124,13 @@ class Block &lt; ActiveRecord::Base
110 # * <tt>'all'</tt>: the block is always displayed 124 # * <tt>'all'</tt>: the block is always displayed
111 settings_items :language, :type => :string, :default => 'all' 125 settings_items :language, :type => :string, :default => 'all'
112 126
113 - # The block can be configured to be fixed. Only can be edited by environment admins  
114 - settings_items :fixed, :type => :boolean, :default => false 127 + # The block can be configured to define the edition modes options. Only can be edited by environment admins
  128 + # It can assume the following values:
  129 + #
  130 + # * <tt>'all'</tt>: the block owner has all edit options for this block
  131 + # * <tt>'none'</tt>: the block owner can't do anything with the block
  132 + settings_items :edit_modes, :type => :string, :default => 'all'
  133 + settings_items :move_modes, :type => :string, :default => 'all'
115 134
116 # returns the description of the block, used when the user sees a list of 135 # returns the description of the block, used when the user sees a list of
117 # blocks to choose one to include in the design. 136 # blocks to choose one to include in the design.
@@ -148,7 +167,11 @@ class Block &lt; ActiveRecord::Base @@ -148,7 +167,11 @@ class Block &lt; ActiveRecord::Base
148 167
149 # Is this block editable? (Default to <tt>false</tt>) 168 # Is this block editable? (Default to <tt>false</tt>)
150 def editable? 169 def editable?
151 - true 170 + self.edit_modes == "all"
  171 + end
  172 +
  173 + def movable?
  174 + self.move_modes == "all"
152 end 175 end
153 176
154 # must always return false, except on MainBlock clas. 177 # must always return false, except on MainBlock clas.
@@ -228,6 +251,21 @@ class Block &lt; ActiveRecord::Base @@ -228,6 +251,21 @@ class Block &lt; ActiveRecord::Base
228 } 251 }
229 end 252 end
230 253
  254 + def edit_block_options
  255 + @edit_options ||= {
  256 + 'all' => _('Can be modified'),
  257 + 'none' => _('Cannot be modified')
  258 + }
  259 + end
  260 +
  261 + def move_block_options
  262 + @move_options ||= {
  263 + 'all' => _('Can be moved'),
  264 + 'none' => _('Cannot be moved')
  265 + }
  266 + end
  267 +
  268 +
231 def duplicate 269 def duplicate
232 duplicated_block = self.dup 270 duplicated_block = self.dup
233 duplicated_block.display = 'never' 271 duplicated_block.display = 'never'
@@ -243,6 +281,10 @@ class Block &lt; ActiveRecord::Base @@ -243,6 +281,10 @@ class Block &lt; ActiveRecord::Base
243 self.position = block.position 281 self.position = block.position
244 end 282 end
245 283
  284 + def add_observer(block)
  285 + self.observers << block
  286 + end
  287 +
246 private 288 private
247 289
248 def home_page_path 290 def home_page_path
app/models/blog.rb
@@ -76,9 +76,12 @@ class Blog &lt; Folder @@ -76,9 +76,12 @@ class Blog &lt; 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,
  80 + :in => [ 'full', 'short', 'short+pic', 'compact'],
  81 + :if => :visualization_format
80 82
81 - settings_items :display_posts_in_current_language, :type => :boolean, :default => false 83 + settings_items :display_posts_in_current_language,
  84 + :type => :boolean, :default => false
82 85
83 alias :display_posts_in_current_language? :display_posts_in_current_language 86 alias :display_posts_in_current_language? :display_posts_in_current_language
84 87
app/models/chat_message.rb
@@ -4,4 +4,5 @@ class ChatMessage &lt; ActiveRecord::Base @@ -4,4 +4,5 @@ class ChatMessage &lt; ActiveRecord::Base
4 belongs_to :to, :class_name => 'Profile' 4 belongs_to :to, :class_name => 'Profile'
5 belongs_to :from, :class_name => 'Profile' 5 belongs_to :from, :class_name => 'Profile'
6 6
  7 + validates_presence_of :from, :to
7 end 8 end
app/models/comment.rb
@@ -37,6 +37,8 @@ class Comment &lt; ActiveRecord::Base @@ -37,6 +37,8 @@ class Comment &lt; ActiveRecord::Base
37 37
38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation' 38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
39 39
  40 + acts_as_voteable
  41 +
40 def comment_root 42 def comment_root
41 (reply_of && reply_of.comment_root) || self 43 (reply_of && reply_of.comment_root) || self
42 end 44 end
app/models/environment.rb
@@ -3,7 +3,17 @@ @@ -3,7 +3,17 @@
3 # domains. 3 # domains.
4 class Environment < ActiveRecord::Base 4 class Environment < ActiveRecord::Base
5 5
6 - attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound, :noreply_email, :signup_welcome_screen_body, :members_whitelist_enabled, :members_whitelist, :highlighted_news_amount, :portal_news_amount 6 + attr_accessible :name, :is_default, :signup_welcome_text_subject,
  7 + :signup_welcome_text_body, :terms_of_use,
  8 + :message_for_disabled_enterprise, :news_amount_by_folder,
  9 + :default_language, :languages, :description,
  10 + :organization_approval_method, :enabled_plugins,
  11 + :enabled_features, :redirection_after_login,
  12 + :redirection_after_signup, :contact_email, :theme,
  13 + :reports_lower_bound, :noreply_email,
  14 + :signup_welcome_screen_body, :members_whitelist_enabled,
  15 + :members_whitelist, :highlighted_news_amount,
  16 + :portal_news_amount, :date_format
7 17
8 has_many :users 18 has_many :users
9 19
@@ -14,11 +24,19 @@ class Environment &lt; ActiveRecord::Base @@ -14,11 +24,19 @@ class Environment &lt; ActiveRecord::Base
14 24
15 IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/ 25 IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/
16 26
  27 + validates_inclusion_of :date_format,
  28 + :in => [ 'numbers_with_year', 'numbers',
  29 + 'month_name_with_year', 'month_name',
  30 + 'past_time'],
  31 + :if => :date_format
  32 +
17 def self.verify_filename(filename) 33 def self.verify_filename(filename)
18 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS 34 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS
19 filename 35 filename
20 end 36 end
21 37
  38 + NUMBER_OF_BOXES = 4
  39 +
22 PERMISSIONS['Environment'] = { 40 PERMISSIONS['Environment'] = {
23 'view_environment_admin_panel' => N_('View environment admin panel'), 41 'view_environment_admin_panel' => N_('View environment admin panel'),
24 'edit_environment_features' => N_('Edit environment features'), 42 'edit_environment_features' => N_('Edit environment features'),
@@ -27,6 +45,7 @@ class Environment &lt; ActiveRecord::Base @@ -27,6 +45,7 @@ class Environment &lt; ActiveRecord::Base
27 'manage_environment_roles' => N_('Manage environment roles'), 45 'manage_environment_roles' => N_('Manage environment roles'),
28 'manage_environment_validators' => N_('Manage environment validators'), 46 'manage_environment_validators' => N_('Manage environment validators'),
29 'manage_environment_users' => N_('Manage environment users'), 47 'manage_environment_users' => N_('Manage environment users'),
  48 + 'manage_environment_organizations' => N_('Manage environment organizations'),
30 'manage_environment_templates' => N_('Manage environment templates'), 49 'manage_environment_templates' => N_('Manage environment templates'),
31 'manage_environment_licenses' => N_('Manage environment licenses'), 50 'manage_environment_licenses' => N_('Manage environment licenses'),
32 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'), 51 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
@@ -72,7 +91,8 @@ class Environment &lt; ActiveRecord::Base @@ -72,7 +91,8 @@ class Environment &lt; ActiveRecord::Base
72 'edit_profile_design', 91 'edit_profile_design',
73 'manage_products', 92 'manage_products',
74 'manage_friends', 93 'manage_friends',
75 - 'perform_task' 94 + 'perform_task',
  95 + 'view_tasks'
76 ] 96 ]
77 ) 97 )
78 end 98 end
@@ -172,7 +192,7 @@ class Environment &lt; ActiveRecord::Base @@ -172,7 +192,7 @@ class Environment &lt; ActiveRecord::Base
172 acts_as_having_boxes 192 acts_as_having_boxes
173 193
174 after_create do |env| 194 after_create do |env|
175 - 3.times do 195 + NUMBER_OF_BOXES.times do
176 env.boxes << Box.new 196 env.boxes << Box.new
177 end 197 end
178 198
@@ -337,6 +357,16 @@ class Environment &lt; ActiveRecord::Base @@ -337,6 +357,16 @@ class Environment &lt; ActiveRecord::Base
337 self.save! 357 self.save!
338 end 358 end
339 359
  360 + def enable_all_plugins
  361 + Noosfero::Plugin.available_plugin_names.each do |plugin|
  362 + plugin_name = plugin.to_s + "Plugin"
  363 + unless self.enabled_plugins.include?(plugin_name)
  364 + self.enabled_plugins += [plugin_name]
  365 + end
  366 + end
  367 + self.save!
  368 + end
  369 +
340 # Disables a feature identified by its name 370 # Disables a feature identified by its name
341 def disable(feature, must_save=true) 371 def disable(feature, must_save=true)
342 self.settings["#{feature}_enabled".to_sym] = false 372 self.settings["#{feature}_enabled".to_sym] = false
@@ -737,8 +767,8 @@ class Environment &lt; ActiveRecord::Base @@ -737,8 +767,8 @@ class Environment &lt; ActiveRecord::Base
737 end 767 end
738 768
739 def is_default_template?(template) 769 def is_default_template?(template)
740 - is_default = template == community_default_template  
741 - is_default = is_default || template == person_default_template 770 + is_default = template == community_default_template
  771 + is_default = is_default || template == person_default_template
742 is_default = is_default || template == enterprise_default_template 772 is_default = is_default || template == enterprise_default_template
743 is_default 773 is_default
744 end 774 end
app/models/forum.rb
@@ -3,11 +3,11 @@ class Forum &lt; Folder @@ -3,11 +3,11 @@ class Forum &lt; Folder
3 acts_as_having_posts :order => 'updated_at DESC' 3 acts_as_having_posts :order => 'updated_at DESC'
4 include PostsLimit 4 include PostsLimit
5 5
6 - attr_accessible :has_terms_of_use, :terms_of_use, :allows_members_to_create_topics 6 + attr_accessible :has_terms_of_use, :terms_of_use, :topic_creation
7 7
8 settings_items :terms_of_use, :type => :string, :default => "" 8 settings_items :terms_of_use, :type => :string, :default => ""
9 settings_items :has_terms_of_use, :type => :boolean, :default => false 9 settings_items :has_terms_of_use, :type => :boolean, :default => false
10 - settings_items :allows_members_to_create_topics, :type => :boolean, :default => false 10 + settings_items :topic_creation, :type => :string, :default => 'self'
11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' 11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
12 12
13 before_save do |forum| 13 before_save do |forum|
@@ -33,6 +33,23 @@ class Forum &lt; Folder @@ -33,6 +33,23 @@ class Forum &lt; Folder
33 _('An internet forum, also called message board, where discussions can be held.') 33 _('An internet forum, also called message board, where discussions can be held.')
34 end 34 end
35 35
  36 + module TopicCreation
  37 + BASE = ActiveSupport::OrderedHash.new
  38 + BASE['users'] = _('Logged users')
  39 +
  40 + PERSON = ActiveSupport::OrderedHash.new
  41 + PERSON['self'] = _('Me')
  42 + PERSON['related'] = _('Friends')
  43 +
  44 + GROUP = ActiveSupport::OrderedHash.new
  45 + GROUP['self'] = _('Administrators')
  46 + GROUP['related'] = _('Members')
  47 +
  48 + def self.general_options(forum)
  49 + forum.profile.person? ? PERSON.merge(BASE) : GROUP.merge(BASE)
  50 + end
  51 + end
  52 +
36 include ActionView::Helpers::TagHelper 53 include ActionView::Helpers::TagHelper
37 def to_html(options = {}) 54 def to_html(options = {})
38 proc do 55 proc do
@@ -69,11 +86,17 @@ class Forum &lt; Folder @@ -69,11 +86,17 @@ class Forum &lt; Folder
69 self.users_with_agreement.exists? user 86 self.users_with_agreement.exists? user
70 end 87 end
71 88
72 - def can_create_topic?(user, profile)  
73 - return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics 89 + def can_create_topic?(user)
  90 + return true if user == profile || profile.admins.include?(user) || profile.environment.admins.include?(user)
  91 + case topic_creation
  92 + when 'related'
  93 + profile.person? ? profile.friends.include?(user) : profile.members.include?(user)
  94 + when 'users'
  95 + user.present?
  96 + end
74 end 97 end
75 98
76 def allow_create?(user) 99 def allow_create?(user)
77 - super || can_create_topic?(user, profile) 100 + super || can_create_topic?(user)
78 end 101 end
79 end 102 end
app/models/highlights_block.rb
@@ -26,8 +26,16 @@ class HighlightsBlock &lt; Block @@ -26,8 +26,16 @@ class HighlightsBlock &lt; 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 &lt; Profile @@ -29,6 +29,8 @@ class Organization &lt; 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/person.rb
@@ -84,9 +84,9 @@ roles] } @@ -84,9 +84,9 @@ roles] }
84 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' 84 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
85 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' 85 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
86 86
87 - has_many :profile_suggestions, :foreign_key => :person_id, :order => 'score DESC', :dependent => :destroy  
88 - has_many :suggested_people, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]  
89 - has_many :suggested_communities, :through => :profile_suggestions, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true] 87 + has_many :suggested_profiles, :class_name => 'ProfileSuggestion', :foreign_key => :person_id, :order => 'score DESC', :dependent => :destroy
  88 + has_many :suggested_people, :through => :suggested_profiles, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Person', true]
  89 + has_many :suggested_communities, :through => :suggested_profiles, :source => :suggestion, :conditions => ['profile_suggestions.suggestion_type = ? AND profile_suggestions.enabled = ?', 'Community', true]
90 90
91 scope :more_popular, :order => 'friends_count DESC' 91 scope :more_popular, :order => 'friends_count DESC'
92 92
@@ -103,6 +103,8 @@ roles] } @@ -103,6 +103,8 @@ roles] }
103 103
104 belongs_to :user, :dependent => :delete 104 belongs_to :user, :dependent => :delete
105 105
  106 + acts_as_voter
  107 +
106 def can_change_homepage? 108 def can_change_homepage?
107 !environment.enabled?('cant_change_homepage') || is_admin? 109 !environment.enabled?('cant_change_homepage') || is_admin?
108 end 110 end
@@ -522,7 +524,7 @@ roles] } @@ -522,7 +524,7 @@ roles] }
522 end 524 end
523 525
524 def remove_suggestion(profile) 526 def remove_suggestion(profile)
525 - suggestion = profile_suggestions.find_by_suggestion_id profile.id 527 + suggestion = suggested_profiles.find_by_suggestion_id profile.id
526 suggestion.disable if suggestion 528 suggestion.disable if suggestion
527 end 529 end
528 530
app/models/product_category.rb
@@ -10,6 +10,9 @@ class ProductCategory &lt; Category @@ -10,6 +10,9 @@ class ProductCategory &lt; Category
10 :joins => :products, 10 :joins => :products,
11 :conditions => ['products.profile_id = ?', enterprise.id] 11 :conditions => ['products.profile_id = ?', enterprise.id]
12 }} 12 }}
  13 + scope :by_environment, lambda { |environment| {
  14 + :conditions => ['environment_id = ?', environment.id]
  15 + }}
13 scope :unique_by_level, lambda { |level| { 16 scope :unique_by_level, lambda { |level| {
14 :select => "DISTINCT ON (filtered_category) split_part(path, '/', #{level}) AS filtered_category, categories.*" 17 :select => "DISTINCT ON (filtered_category) split_part(path, '/', #{level}) AS filtered_category, categories.*"
15 }} 18 }}
app/models/profile.rb
@@ -22,6 +22,8 @@ class Profile &lt; ActiveRecord::Base @@ -22,6 +22,8 @@ class Profile &lt; 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 &lt; ActiveRecord::Base @@ -43,7 +45,7 @@ class Profile &lt; 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 }
@@ -69,12 +71,14 @@ class Profile &lt; ActiveRecord::Base @@ -69,12 +71,14 @@ class Profile &lt; ActiveRecord::Base
69 'manage_friends' => N_('Manage friends'), 71 'manage_friends' => N_('Manage friends'),
70 'validate_enterprise' => N_('Validate enterprise'), 72 'validate_enterprise' => N_('Validate enterprise'),
71 'perform_task' => N_('Perform task'), 73 'perform_task' => N_('Perform task'),
  74 + 'view_tasks' => N_('View tasks'),
72 'moderate_comments' => N_('Moderate comments'), 75 'moderate_comments' => N_('Moderate comments'),
73 'edit_appearance' => N_('Edit appearance'), 76 'edit_appearance' => N_('Edit appearance'),
74 'view_private_content' => N_('View private content'), 77 'view_private_content' => N_('View private content'),
75 'publish_content' => N_('Publish content'), 78 'publish_content' => N_('Publish content'),
76 'invite_members' => N_('Invite members'), 79 'invite_members' => N_('Invite members'),
77 'send_mail_to_members' => N_('Send e-Mail to members'), 80 'send_mail_to_members' => N_('Send e-Mail to members'),
  81 + 'manage_custom_roles' => N_('Manage custom roles'),
78 } 82 }
79 83
80 acts_as_accessible 84 acts_as_accessible
@@ -317,16 +321,25 @@ class Profile &lt; ActiveRecord::Base @@ -317,16 +321,25 @@ class Profile &lt; ActiveRecord::Base
317 @top_level_articles ||= Article.top_level_for(self) 321 @top_level_articles ||= Article.top_level_for(self)
318 end 322 end
319 323
320 - def self.is_available?(identifier, environment)  
321 - !(identifier =~ IDENTIFIER_FORMAT).nil? && !RESERVED_IDENTIFIERS.include?(identifier) && Profile.find(:first, :conditions => ['environment_id = ? and identifier = ?', environment.id, identifier]).nil? 324 + def self.is_available?(identifier, environment, profile_id=nil)
  325 + return false unless identifier =~ IDENTIFIER_FORMAT &&
  326 + !RESERVED_IDENTIFIERS.include?(identifier) &&
  327 + (NOOSFERO_CONF['exclude_profile_identifier_pattern'].blank? || identifier !~ /#{NOOSFERO_CONF['exclude_profile_identifier_pattern']}/)
  328 + return true if environment.nil?
  329 +
  330 + profiles = environment.profiles.where(:identifier => identifier)
  331 + profiles = profiles.where(['id != ?', profile_id]) if profile_id.present?
  332 + !profiles.exists?
322 end 333 end
323 334
324 validates_presence_of :identifier, :name 335 validates_presence_of :identifier, :name
325 - validates_format_of :identifier, :with => IDENTIFIER_FORMAT, :if => lambda { |profile| !profile.identifier.blank? }  
326 - validates_exclusion_of :identifier, :in => RESERVED_IDENTIFIERS  
327 - validates_uniqueness_of :identifier, :scope => :environment_id  
328 validates_length_of :nickname, :maximum => 16, :allow_nil => true 336 validates_length_of :nickname, :maximum => 16, :allow_nil => true
329 validate :valid_template 337 validate :valid_template
  338 + validate :valid_identifier
  339 +
  340 + def valid_identifier
  341 + errors.add(:identifier, _('is not available.')) unless Profile.is_available?(identifier, environment, id)
  342 + end
330 343
331 def valid_template 344 def valid_template
332 if template_id.present? && template && !template.is_template 345 if template_id.present? && template && !template.is_template
@@ -352,7 +365,7 @@ class Profile &lt; ActiveRecord::Base @@ -352,7 +365,7 @@ class Profile &lt; ActiveRecord::Base
352 if template 365 if template
353 apply_template(template, :copy_articles => false) 366 apply_template(template, :copy_articles => false)
354 else 367 else
355 - 3.times do 368 + NUMBER_OF_BOXES.times do
356 self.boxes << Box.new 369 self.boxes << Box.new
357 end 370 end
358 371
@@ -380,6 +393,9 @@ class Profile &lt; ActiveRecord::Base @@ -380,6 +393,9 @@ class Profile &lt; ActiveRecord::Base
380 new_block = block.class.new(:title => block[:title]) 393 new_block = block.class.new(:title => block[:title])
381 new_block.copy_from(block) 394 new_block.copy_from(block)
382 new_box.blocks << new_block 395 new_box.blocks << new_block
  396 + if block.mirror?
  397 + block.add_observer(new_block)
  398 + end
383 end 399 end
384 end 400 end
385 end 401 end
@@ -395,6 +411,7 @@ class Profile &lt; ActiveRecord::Base @@ -395,6 +411,7 @@ class Profile &lt; ActiveRecord::Base
395 alias_method_chain :template, :default 411 alias_method_chain :template, :default
396 412
397 def apply_template(template, options = {:copy_articles => true}) 413 def apply_template(template, options = {:copy_articles => true})
  414 + self.template = template
398 copy_blocks_from(template) 415 copy_blocks_from(template)
399 copy_articles_from(template) if options[:copy_articles] 416 copy_articles_from(template) if options[:copy_articles]
400 self.apply_type_specific_template(template) 417 self.apply_type_specific_template(template)
@@ -1008,7 +1025,7 @@ private :generate_url, :url_options @@ -1008,7 +1025,7 @@ private :generate_url, :url_options
1008 end 1025 end
1009 1026
1010 def remove_from_suggestion_list(person) 1027 def remove_from_suggestion_list(person)
1011 - suggestion = person.profile_suggestions.find_by_suggestion_id self.id 1028 + suggestion = person.suggested_profiles.find_by_suggestion_id self.id
1012 suggestion.disable if suggestion 1029 suggestion.disable if suggestion
1013 end 1030 end
1014 1031
app/models/profile_suggestion.rb
@@ -113,14 +113,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base @@ -113,14 +113,14 @@ class ProfileSuggestion &lt; ActiveRecord::Base
113 suggested_profiles = all_suggestions(person) 113 suggested_profiles = all_suggestions(person)
114 return if suggested_profiles.nil? 114 return if suggested_profiles.nil?
115 115
116 - already_suggested_profiles = person.profile_suggestions.map(&:suggestion_id).join(',') 116 + already_suggested_profiles = person.suggested_profiles.map(&:suggestion_id).join(',')
117 suggested_profiles = suggested_profiles.where("profiles.id NOT IN (#{already_suggested_profiles})") if already_suggested_profiles.present? 117 suggested_profiles = suggested_profiles.where("profiles.id NOT IN (#{already_suggested_profiles})") if already_suggested_profiles.present?
118 #TODO suggested_profiles = suggested_profiles.order('score DESC') 118 #TODO suggested_profiles = suggested_profiles.order('score DESC')
119 suggested_profiles = suggested_profiles.limit(N_SUGGESTIONS) 119 suggested_profiles = suggested_profiles.limit(N_SUGGESTIONS)
120 return if suggested_profiles.blank? 120 return if suggested_profiles.blank?
121 121
122 suggested_profiles.each do |suggested_profile| 122 suggested_profiles.each do |suggested_profile|
123 - suggestion = person.profile_suggestions.find_or_initialize_by_suggestion_id(suggested_profile.id) 123 + suggestion = person.suggested_profiles.find_or_initialize_by_suggestion_id(suggested_profile.id)
124 RULES.each do |rule, options| 124 RULES.each do |rule, options|
125 begin 125 begin
126 value = suggested_profile.send("#{rule}_count").to_i 126 value = suggested_profile.send("#{rule}_count").to_i
@@ -273,7 +273,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base @@ -273,7 +273,7 @@ class ProfileSuggestion &lt; ActiveRecord::Base
273 end 273 end
274 274
275 def self.generate_profile_suggestions(person, force = false) 275 def self.generate_profile_suggestions(person, force = false)
276 - return if person.profile_suggestions.enabled.count >= MIN_LIMIT && !force 276 + return if person.suggested_profiles.enabled.count >= MIN_LIMIT && !force
277 Delayed::Job.enqueue ProfileSuggestionsJob.new(person.id) unless ProfileSuggestionsJob.exists?(person.id) 277 Delayed::Job.enqueue ProfileSuggestionsJob.new(person.id) unless ProfileSuggestionsJob.exists?(person.id)
278 end 278 end
279 279
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 &lt; Task @@ -24,34 +20,49 @@ class SuggestArticle &lt; 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(target.present? ? {: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 &lt; Task @@ -63,8 +74,8 @@ class SuggestArticle &lt; 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/task.rb
@@ -33,6 +33,8 @@ class Task &lt; ActiveRecord::Base @@ -33,6 +33,8 @@ class Task &lt; ActiveRecord::Base
33 33
34 belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id 34 belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id
35 belongs_to :target, :foreign_key => :target_id, :polymorphic => true 35 belongs_to :target, :foreign_key => :target_id, :polymorphic => true
  36 + belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id
  37 + belongs_to :closed_by, :class_name => 'Person', :foreign_key => :closed_by_id
36 38
37 validates_uniqueness_of :code, :on => :create 39 validates_uniqueness_of :code, :on => :create
38 validates_presence_of :code 40 validates_presence_of :code
@@ -76,11 +78,9 @@ class Task &lt; ActiveRecord::Base @@ -76,11 +78,9 @@ class Task &lt; ActiveRecord::Base
76 # this method finished the task. It calls #perform, which must be overriden 78 # this method finished the task. It calls #perform, which must be overriden
77 # by subclasses. At the end a message (as returned by #finish_message) is 79 # by subclasses. At the end a message (as returned by #finish_message) is
78 # sent to the requestor with #notify_requestor. 80 # sent to the requestor with #notify_requestor.
79 - def finish 81 + def finish(closed_by=nil)
80 transaction do 82 transaction do
81 - self.status = Task::Status::FINISHED  
82 - self.end_date = Time.now  
83 - self.save! 83 + close(Task::Status::FINISHED, closed_by)
84 self.perform 84 self.perform
85 begin 85 begin
86 send_notification(:finished) 86 send_notification(:finished)
@@ -105,11 +105,9 @@ class Task &lt; ActiveRecord::Base @@ -105,11 +105,9 @@ class Task &lt; ActiveRecord::Base
105 105
106 # this method cancels the task. At the end a message (as returned by 106 # this method cancels the task. At the end a message (as returned by
107 # #cancel_message) is sent to the requestor with #notify_requestor. 107 # #cancel_message) is sent to the requestor with #notify_requestor.
108 - def cancel 108 + def cancel(closed_by=nil)
109 transaction do 109 transaction do
110 - self.status = Task::Status::CANCELLED  
111 - self.end_date = Time.now  
112 - self.save! 110 + close(Task::Status::CANCELLED, closed_by)
113 begin 111 begin
114 send_notification(:cancelled) 112 send_notification(:cancelled)
115 rescue NotImplementedError => ex 113 rescue NotImplementedError => ex
@@ -118,6 +116,13 @@ class Task &lt; ActiveRecord::Base @@ -118,6 +116,13 @@ class Task &lt; ActiveRecord::Base
118 end 116 end
119 end 117 end
120 118
  119 + def close(status, closed_by)
  120 + self.status = status
  121 + self.end_date = Time.now
  122 + self.closed_by = closed_by
  123 + self.save!
  124 + end
  125 +
121 # Here are the tasks customizable options. 126 # Here are the tasks customizable options.
122 127
123 def title 128 def title
@@ -239,6 +244,10 @@ class Task &lt; ActiveRecord::Base @@ -239,6 +244,10 @@ class Task &lt; ActiveRecord::Base
239 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] } 244 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] }
240 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } 245 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} }
241 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } 246 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} }
  247 + scope :like, lambda { |field, value| where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value}
  248 + scope :pending_all, lambda { |profile, filter_type, filter_text|
  249 + self.to(profile).without_spam.pending.of(filter_type).like('data', filter_text)
  250 + }
242 251
243 scope :to, lambda { |profile| 252 scope :to, lambda { |profile|
244 environment_condition = nil 253 environment_condition = nil
app/models/uploaded_file.rb
1 -require 'short_filename'  
2 -  
3 # Article type that handles uploaded files. 1 # Article type that handles uploaded files.
4 # 2 #
5 # Limitation: only file metadata are versioned. Only the latest version 3 # Limitation: only file metadata are versioned. Only the latest version
@@ -14,8 +12,6 @@ class UploadedFile &lt; Article @@ -14,8 +12,6 @@ class UploadedFile &lt; Article
14 12
15 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent 13 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent
16 14
17 - include ShortFilename  
18 -  
19 def title 15 def title
20 if self.name.present? then self.name else self.filename end 16 if self.name.present? then self.name else self.filename end
21 end 17 end
@@ -65,7 +61,7 @@ class UploadedFile &lt; Article @@ -65,7 +61,7 @@ class UploadedFile &lt; Article
65 # :min_size => 2.megabytes 61 # :min_size => 2.megabytes
66 # :max_size => 5.megabytes 62 # :max_size => 5.megabytes
67 has_attachment :storage => :file_system, 63 has_attachment :storage => :file_system,
68 - :thumbnails => { :icon => [24,24], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' }, 64 + :thumbnails => { :icon => [24,24], :bigicon => [50,50], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' },
69 :thumbnail_class => Thumbnail, 65 :thumbnail_class => Thumbnail,
70 :max_size => self.max_size 66 :max_size => self.max_size
71 67
app/models/user.rb
@@ -45,7 +45,7 @@ class User &lt; ActiveRecord::Base @@ -45,7 +45,7 @@ class User &lt; 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/presenters/image.rb
@@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter @@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter
4 f.image? ? 10 : nil 4 f.image? ? 10 : nil
5 end 5 end
6 6
  7 + def sized_icon(size)
  8 + public_filename size
  9 + end
  10 +
7 def icon_name 11 def icon_name
8 public_filename :icon 12 public_filename :icon
9 end 13 end
app/views/admin_panel/_site_info.html.erb
@@ -3,6 +3,21 @@ @@ -3,6 +3,21 @@
3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %> 3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> 5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %>
  6 +
  7 +<%= labelled_form_field(
  8 + _("Article's date format"),
  9 + select(:environment, :date_format,
  10 + options_for_select([
  11 + [ _('mm/dd/yyyy'), 'numbers_with_year'],
  12 + [ _('mm/dd'), 'numbers'],
  13 + [ _('Month dd, yyyy'), 'month_name_with_year'],
  14 + [ _('Month dd'), 'month_name'],
  15 + [ _('X minutes/hours/days/months/years ago'), 'past_time']
  16 + ], environment.date_format
  17 + )
  18 + )
  19 +) %>
  20 +
6 <%= required f.text_field(:reports_lower_bound, :size => 3) %> 21 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
7 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %> 22 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %>
8 <%= label_tag :languages, _('Available languages') %> 23 <%= label_tag :languages, _('Available languages') %>
app/views/admin_panel/index.html.erb
@@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
18 <table> 18 <table>
19 <tr><td><%= link_to _('User roles'), :controller => 'role' %></td></tr> 19 <tr><td><%= link_to _('User roles'), :controller => 'role' %></td></tr>
20 <tr><td><%= link_to _('Users'), :controller => 'users' %></td></tr> 20 <tr><td><%= link_to _('Users'), :controller => 'users' %></td></tr>
  21 + <tr><td><%= link_to _('Organizations'), :controller => 'organizations' %></td></tr>
21 <tr><td><%= link_to _('Profile templates'), :controller => 'templates' %></td></tr> 22 <tr><td><%= link_to _('Profile templates'), :controller => 'templates' %></td></tr>
22 <tr><td><%= link_to _('Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr> 23 <tr><td><%= link_to _('Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr>
23 - <tr><td><%= link_to _('Manage organizations status'), :action => 'manage_organizations_status' %></td></tr>  
24 </table> 24 </table>
25 25
26 26
app/views/admin_panel/manage_organizations_status.html.erb
@@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
1 -<h1><%= _('Manage organizations') %></h1>  
2 -  
3 -<%= form_tag( { :action => 'manage_organizations_status' }, :method => 'get', :class => 'users-search' ) do %>  
4 -  
5 - <div class="search-field">  
6 - <span class="formfield">  
7 - <%= text_field_tag 'q', @q, :title => _("Find profiles"), :style=>"width:85%" %>  
8 - </span>  
9 -  
10 - <%= submit_button(:search, _('Search')) %>  
11 - </div>  
12 -  
13 - <div class="environment-users-results-header">  
14 - <div id='environment-users-filter-title'><%= @title %></div>  
15 -  
16 - <div id="environment-users-filter-filter">  
17 - <strong><%= _("Filter by: ") %></strong>  
18 -  
19 - <select id="profile_filter_select">  
20 - <%= options_for_select([['Any', 'any'],["Disabled profiles", "disabled"], ["Enabled profiles", "enabled"]], @filter) %>  
21 - </select>  
22 - </div>  
23 - <div style="clear: both"></div>  
24 - </div>  
25 -  
26 - <table>  
27 - <colgroup>  
28 - <col width="80%">  
29 - <col width="20%">  
30 - </colgroup>  
31 -  
32 - <tr>  
33 - <th><%= _('Member') %></th>  
34 - <th><%= _('Actions') %></th>  
35 - </tr>  
36 -  
37 - <% @collection.each do |p| %>  
38 - <tr title="<%= p.name %>">  
39 - <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>  
40 -  
41 - <td class='actions'>  
42 - <div class="members-buttons-cell">  
43 - <% if p.visible %>  
44 - <%= button_without_text :'deactivate-user', _('Deactivate'), {:controller => "profile_editor", :action => 'deactivate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to deactivate this profile ?") %>  
45 - <% else %>  
46 - <%= button_without_text :'activate-user', _('Activate'), {:controller => "profile_editor", :action => 'activate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to activate this profile ?") %>  
47 - <% end %>  
48 - <%= button_without_text :'delete', _('Remove'), {:controller => "profile_editor", :action => 'destroy_profile', :profile => p.identifier, :id => p.id, :return_to => "/admin/admin_panel/manage_organizations_status"}, :method => :post, :confirm => _("Do you want to deactivate this profile ?") %>  
49 - </div>  
50 - </td>  
51 - </tr>  
52 - <% end %>  
53 - </table>  
54 -  
55 -<% end %>  
56 -  
57 -<%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>  
58 -  
59 -<% button_bar do %>  
60 - <%= button :back, _('Back'), :controller => 'admin_panel' %>  
61 -<% end %>  
62 -  
63 -<script type="text/javascript">  
64 - jQuery(document).ready(function(){  
65 - jQuery("#profile_filter_select").change(function(){  
66 - document.location.href = '/admin/admin_panel/manage_organizations_status?filter='+this.value;  
67 - });  
68 - });  
69 -</script>  
70 \ No newline at end of file 0 \ No newline at end of file
app/views/blocks/profile_info_actions/_common.html.erb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +<li><%= report_abuse(profile, :button) %></li>
  2 +<%= render_environment_features(:profile_actions) %>
app/views/blocks/profile_info_actions/_community.html.erb
@@ -13,8 +13,6 @@ @@ -13,8 +13,6 @@
13 </li> 13 </li>
14 <% end %> 14 <% end %>
15 15
16 - <li><%= report_abuse(profile, :button) %></li>  
17 -  
18 - <%= render_environment_features(:profile_actions) %> 16 + <%= render :partial => 'blocks/profile_info_actions/common' %>
19 <% end %> 17 <% end %>
20 </ul> 18 </ul>
app/views/blocks/profile_info_actions/_enterprise.html.erb
@@ -8,5 +8,5 @@ @@ -8,5 +8,5 @@
8 <li><%= button(:'menu-mail', _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button'} ) %></li> 8 <li><%= button(:'menu-mail', _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button'} ) %></li>
9 <% end %> 9 <% end %>
10 10
11 - <li><%= report_abuse(profile, :button) %></li> 11 + <%= render :partial => 'blocks/profile_info_actions/common' %>
12 </ul> 12 </ul>
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/blocks/profile_info_actions/_person.html.erb
@@ -11,6 +11,6 @@ @@ -11,6 +11,6 @@
11 <li><%= button(:back, _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}) %></li> 11 <li><%= button(:back, _('Send an e-mail'), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}) %></li>
12 <% end %> 12 <% end %>
13 13
14 - <li><%= report_abuse(profile, :button) %></li> 14 + <%= render :partial => 'blocks/profile_info_actions/common' %>
15 <% end %> 15 <% end %>
16 </ul> 16 </ul>
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,21 @@ @@ -25,6 +19,21 @@
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 +
  31 + <% if @block.owner.kind_of?(Profile) && @block.owner.is_template? %>
  32 + <div class="mirror_block">
  33 + <%= labelled_check_box(_("Mirror"), "block[mirror]", value = "1", checked = @block.mirror) %>
  34 + </div>
  35 + <% end %>
  36 +
28 <% button_bar do %> 37 <% button_bar do %>
29 <%= submit_button(:save, _('Save')) %> 38 <%= submit_button(:save, _('Save')) %>
30 <%= modal_close_button(_('Cancel')) %> 39 <%= modal_close_button(_('Cancel')) %>
app/views/chat/start_session_error.html.erb
1 <p> 1 <p>
2 <%= ui_icon('ui-icon-alert') %> 2 <%= ui_icon('ui-icon-alert') %>
3 -<%= _('Could not connect to chat') %>, <a id='chat-retry' href='#' data-jid='<%= user.jid %>'><%= _('try again') %></a>. 3 +<%= _('Could not connect to chat') %>, <a id='chat-retry' href='' data-jid='<%= user.jid %>'><%= _('try again') %></a>.
4 </p> 4 </p>
app/views/cms/_blog.html.erb
@@ -64,7 +64,12 @@ @@ -64,7 +64,12 @@
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 + [ _("Title, Image, Lead"), 'compact']
  72 +])) %>
68 73
69 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> 74 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %>
70 75
app/views/cms/_forum.html.erb
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 <h1><%= _('My Forum') %></h1> 3 <h1><%= _('My Forum') %></h1>
4 4
  5 +<%= required_fields_message %>
  6 +
5 <%= render :file => 'shared/tiny_mce' %> 7 <%= render :file => 'shared/tiny_mce' %>
6 8
7 <%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %> 9 <%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %>
app/views/cms/_view_items.html.erb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +<% @articles.each do |article| article = FilePresenter.for article %>
  2 + <tr title="<%= article.title%>" >
  3 + <td class="article-name">
  4 + <%= link_to_article(article) %>
  5 + </td>
  6 + <% short_description = article.respond_to?(:short_description) ?
  7 + article.short_description :
  8 + article.class.short_description %>
  9 + <td class="article-mime" title=<%= short_description.to_json %>>
  10 + <%= short_description %>
  11 + </td>
  12 + <td class="last-update">
  13 + <%= time_ago_in_words article.updated_at %>
  14 + </td>
  15 + <td class="article-controls">
  16 + <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>
  17 + <%= button_without_text :eyes, _('Public view'), article.view_url %>
  18 + <%= display_spread_button(article) unless remove_content_button(:spread, article) %>
  19 + <% if user.can_change_homepage? && !remove_content_button(:home, article) %>
  20 + <% if profile.home_page != article %>
  21 + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  22 + <% else %>
  23 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  24 + <% end %>
  25 + <% end %>
  26 + <%= display_delete_button(article) if !remove_content_button(:delete, article) %>
  27 + </td>
  28 + </tr>
  29 +<% end %>
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/cms/view.html.erb
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 <tr> 37 <tr>
38 <th><%= _('Name') %></th> 38 <th><%= _('Name') %></th>
39 <th><%= _('Type') %></th> 39 <th><%= _('Type') %></th>
  40 + <th><%= _('Last update') %></th>
40 <th><%= _('Actions') %></th> 41 <th><%= _('Actions') %></th>
41 </tr> 42 </tr>
42 43
@@ -54,32 +55,7 @@ @@ -54,32 +55,7 @@
54 </tr> 55 </tr>
55 <% end %> 56 <% end %>
56 57
57 - <% @articles.each do |article| article = FilePresenter.for article %>  
58 - <tr title="<%= article.title%>" >  
59 - <td class="article-name">  
60 - <%= link_to_article(article) %>  
61 - </td>  
62 - <% short_description = article.respond_to?(:short_description) ?  
63 - article.short_description :  
64 - article.class.short_description %>  
65 - <td class="article-mime" title=<%= short_description.to_json %>>  
66 - <%= short_description %>  
67 - </td>  
68 - <td class="article-controls">  
69 - <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>  
70 - <%= button_without_text :eyes, _('Public view'), article.view_url %>  
71 - <%= display_spread_button(article) unless remove_content_button(:spread, article) %>  
72 - <% if user.can_change_homepage? && !remove_content_button(:home, article) %>  
73 - <% if profile.home_page != article %>  
74 - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>  
75 - <% else %>  
76 - <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>  
77 - <% end %>  
78 - <% end %>  
79 - <%= display_delete_button(article) if !remove_content_button(:delete, article) %>  
80 - </td>  
81 - </tr>  
82 - <% end %> 58 + <%= render 'view_items' %>
83 59
84 </table> 60 </table>
85 61
app/views/content_viewer/_article_toolbar.html.erb
1 <div<%= user && " class='logged-in'" %>> 1 <div<%= user && " class='logged-in'" %>>
2 <div id="article-actions"> 2 <div id="article-actions">
3 3
  4 + <%= fullscreen_buttons('#article') %>
4 5
5 <% if @page.allow_edit?(user) && !remove_content_button(:edit, @page) %> 6 <% if @page.allow_edit?(user) && !remove_content_button(:edit, @page) %>
6 <% content = content_tag('span', label_for_edit_article(@page)) %> 7 <% content = content_tag('span', label_for_edit_article(@page)) %>
@@ -29,6 +30,10 @@ @@ -29,6 +30,10 @@
29 <% end %> 30 <% end %>
30 31
31 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %> 32 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %>
  33 +
  34 + <% content = content_tag('span', label_for_clone_article(@page)) %>
  35 + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %>
  36 + <%= expirable_button @page, :clone, content, url %>
32 <% end %> 37 <% end %>
33 38
34 <% if @page.accept_uploads? && @page.allow_create?(user) %> 39 <% if @page.accept_uploads? && @page.allow_create?(user) %>
@@ -57,7 +62,7 @@ @@ -57,7 +62,7 @@
57 <% if @page.blog? and !@page.image.nil? %> 62 <% if @page.blog? and !@page.image.nil? %>
58 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div> 63 <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div>
59 <% end %> 64 <% end %>
60 - <%= link_to(image_tag('icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> 65 + <%= link_to(image_tag('/images/icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
61 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> 66 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
62 <%= article_title(@page, :no_link => true) %> 67 <%= article_title(@page, :no_link => true) %>
63 <%= article_translations(@page) %> 68 <%= article_translations(@page) %>
app/views/content_viewer/_display_compact_format.html.erb 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +<% if article.image %>
  2 + <% className = "article-compact-abstract-with-image" %>
  3 + <% if article.image.thumbnails_processed? %>
  4 + <% image_file = article.image.public_filename(:big) %>
  5 + <% else %>
  6 + <% image_file = "/images/icons-app/image-loading-thumb.png" %>
  7 + <% end %>
  8 +<% else %>
  9 + <% className = "article-compact-abstract" %>
  10 +<% end %>
  11 +
  12 +<div>
  13 + <% if article.image %>
  14 + <div class = "article-compact-image">
  15 + <%= image_tag(image_file) %>
  16 + </div>
  17 + <% end %>
  18 + <div class = <%= className %> >
  19 + <%= article.abstract.truncate(400) %>
  20 + </div>
  21 +</div>
app/views/content_viewer/blog_page.html.erb
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 </div> 8 </div>
9 </div> 9 </div>
10 <hr class="pre-posts"/> 10 <hr class="pre-posts"/>
11 -<div class="blog-posts"> 11 +<div class="blog-posts page-<%= @npage %>">
12 <% paginate = true %> 12 <% paginate = true %>
13 <%= 13 <%=
14 posts = @posts 14 posts = @posts
@@ -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/content_viewer/folder.html.erb
1 <% unless folder.body.blank? %> 1 <% unless folder.body.blank? %>
2 - <div> 2 + <div class="folder-description">
3 <%= folder.body %> 3 <%= folder.body %>
4 </div> 4 </div>
5 - <hr/>  
6 <% end %> 5 <% end %>
7 6
8 <% if folder.children.empty? %> 7 <% if folder.children.empty? %>
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/manage_products/_categories_autocomplete.html.erb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %>
  2 +
  3 +<%= javascript_include_tag '/javascripts/product_categories.js' %>
  4 +<% javascript_tag do %>
  5 + product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %>
  6 + product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %>
  7 + product_categories.autocomplete.load('#product_category_id')
  8 +<% end %>
app/views/manage_products/_selected_category_tree.html.erb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +<%= categories_container selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true) %>
  2 +
app/views/manage_products/edit_category.html.erb
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 16
17 <h3><%= _('Edit category of this product:') %></h3> 17 <h3><%= _('Edit category of this product:') %></h3>
18 18
19 - <%= categories_container(selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %> 19 + <%= render 'manage_products/selected_category_tree' %>
20 20
21 <div id='categories_selection_actionbar'> 21 <div id='categories_selection_actionbar'>
22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %> 22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %>
app/views/organizations/_results.html.erb 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +<div class='results'>
  2 + <table id='organizations-list'>
  3 + <colgroup>
  4 + <col width="60%">
  5 + <col width="20%">
  6 + <col width="20%">
  7 + </colgroup>
  8 +
  9 + <tr>
  10 + <th><%= _('Profile') %></th>
  11 + <th><%= _('Actions') %></th>
  12 + <th><%= _('Type') %>
  13 +
  14 + <%= select_tag(:type, options_for_select(@types_filter, @type)) %>
  15 + </th>
  16 + </tr>
  17 +
  18 + <% @collection.each do |p| %>
  19 + <tr title="<%= p.name %>">
  20 + <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
  21 +
  22 + <td class='actions'>
  23 + <div class="members-buttons-cell">
  24 + <% if p.visible %>
  25 + <%= button_without_text :'deactivate-user', _('Deactivate'), {:action => 'deactivate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to deactivate this organization?") %>
  26 + <% else %>
  27 + <%= button_without_text :'activate-user', _('Activate'), {:action => 'activate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to activate this organization?") %>
  28 + <% end %>
  29 + <%= button_without_text :'delete', _('Remove'), {:action => 'destroy', :id => p.id}, :class => 'action', 'data-method' => :post, 'data-confirm' => _("Do you want to destroy this organization?") %>
  30 + </div>
  31 + </td>
  32 +
  33 + <td> <%= _("#{p.type}") %> </td>
  34 + </tr>
  35 + <% end %>
  36 + </table>
  37 +
  38 + <div>
  39 + <%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
  40 + </div>
  41 +</div>
app/views/organizations/index.html.erb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +<h1><%= _('Organizations') %></h1>
  2 +
  3 +<%= form_tag( { :action => 'index' }, :method => 'get', :id => 'manage-profiles' ) do %>
  4 +
  5 + <div class="search-field">
  6 + <span class="formfield">
  7 + <%= text_field_tag 'q', @q, :title => _('Find organizations'), :style=>"width:85%" %>
  8 + </span>
  9 +
  10 + <%= submit_button(:search, _('Search')) %>
  11 + </div>
  12 +
  13 + <div class="environment-profiles-results-header">
  14 + <div id='environment-profiles-filter-title'><%= @title %></div>
  15 +
  16 + <div id="environment-profiles-filter-filter">
  17 + <strong><%= _("Filter by: ") %></strong>
  18 + <%= select_tag(:filter, options_for_select([[_('Any'), 'any'],[_('Disabled'), "disabled"], [_('Enabled') , "enabled"]], @filter)) %>
  19 + </div>
  20 + <div style="clear: both"></div>
  21 + </div>
  22 +
  23 + <%= render :partial => 'results' %>
  24 +
  25 + <% button_bar do %>
  26 + <%= button :back, _('Back'), :controller => 'admin_panel' %>
  27 + <% end %>
  28 +<% end %>
  29 +
  30 +<%= javascript_include_tag 'manage-organizations' %>
app/views/organizations/index.js.erb 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../../views/shared/admin/profiles/index.js.rb
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_comment.html.erb
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 <span style="font-size: 12px;"><%= comment.title %></span><br/> 19 <span style="font-size: 12px;"><%= comment.title %></span><br/>
20 <% end %> 20 <% end %>
21 <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> 21 <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/>
22 - <span style="font-size: 8px; color: #929292"><%= time_ago_as_sentence(comment.created_at) %></span> 22 + <span style="font-size: 8px; color: #929292"><%= time_ago_in_words(comment.created_at) %></span>
23 <br style="clear: both;" /> 23 <br style="clear: both;" />
24 24
25 <% unless comment.replies.blank? %> 25 <% unless comment.replies.blank? %>
app/views/person_notifier/mailer/_create_article.html.erb
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span>
8 <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> 8 <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span>
9 - <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> 9 + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_in_words(activity.created_at) %></span>
10 </p> 10 </p>
11 <p> 11 <p>
12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> 12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span>
app/views/person_notifier/mailer/_default_activity.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <td> 5 <td>
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
8 - <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> 8 + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(activity.created_at) %></span>
9 </p> 9 </p>
10 </td> 10 </td>
11 </tr> 11 </tr>
app/views/person_notifier/mailer/_task.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <span style="font-size: 14px"> 12 <span style="font-size: 14px">
13 <%= task_information(task) %> 13 <%= task_information(task) %>
14 </span> 14 </span>
15 - <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(task.created_at) %></span> 15 + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(task.created_at) %></span>
16 </div> 16 </div>
17 </td> 17 </td>
18 </tr> 18 </tr>
app/views/person_notifier/mailer/_upload_image.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <td> 5 <td>
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
8 - <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> 8 + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_in_words(activity.created_at) %></span>
9 </p> 9 </p>
10 </td> 10 </td>
11 </tr> 11 </tr>
app/views/profile/_comment.html.erb
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <%= txt2html comment.body %> 40 <%= txt2html comment.body %>
41 </div> 41 </div>
42 <div class="profile-activity-time"> 42 <div class="profile-activity-time">
43 - <%= time_ago_as_sentence(comment.created_at) %> 43 + <%= time_ago_in_words(comment.created_at) %>
44 </div> 44 </div>
45 </div> 45 </div>
46 46
app/views/profile/_create_article.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small> 12 <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small>
13 </div> 13 </div>
14 <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %> 14 <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %>
15 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 15 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
16 <div class='profile-wall-actions'> 16 <div class='profile-wall-actions'>
17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %> 17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
18 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :only_hide => true, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 18 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :only_hide => true, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
app/views/profile/_default_activity.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 </div> 3 </div>
4 <div class='profile-activity-description'> 4 <div class='profile-activity-description'>
5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
6 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 6 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
7 <div class='profile-wall-actions'> 7 <div class='profile-wall-actions'>
8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %> 8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
app/views/profile/_leave_scrap.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 </div> 3 </div>
4 <div class='profile-activity-description'> 4 <div class='profile-activity-description'>
5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
6 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 6 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
7 <div class='profile-wall-actions'> 7 <div class='profile-wall-actions'>
8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
9 </div> 9 </div>
app/views/profile/_profile_scrap.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 <p class='profile-activity-text'><%= txt2html scrap.content %></p> 7 <p class='profile-activity-text'><%= txt2html scrap.content %></p>
8 - <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> 8 + <p class='profile-activity-time'><%= time_ago_in_words(scrap.created_at) %></p>
9 <div class='profile-wall-actions'> 9 <div class='profile-wall-actions'>
10 <% if logged_in? && current_person.follows?(scrap.sender) %> 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 <span class='profile-activity-send-reply'> 11 <span class='profile-activity-send-reply'>
@@ -22,5 +22,5 @@ @@ -22,5 +22,5 @@
22 <% end %> 22 <% end %>
23 </ul> 23 </ul>
24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %> 24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
25 - <hr /> 25 + <hr />
26 </li> 26 </li>
app/views/profile/_profile_scraps.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 <p class='profile-activity-text'><%= txt2html scrap.content %></p> 7 <p class='profile-activity-text'><%= txt2html scrap.content %></p>
8 - <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> 8 + <p class='profile-activity-time'><%= time_ago_in_words(scrap.created_at) %></p>
9 <div class='profile-wall-actions'> 9 <div class='profile-wall-actions'>
10 <% if logged_in? && current_person.follows?(scrap.sender) %> 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 <span class='profile-activity-send-reply'> 11 <span class='profile-activity-send-reply'>
app/views/profile/_upload_image.html.erb
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 </div> 4 </div>
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 6 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
7 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 7 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
8 <div class='profile-wall-actions'> 8 <div class='profile-wall-actions'>
9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
10 </div> 10 </div>
app/views/profile/content_tagged.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <h1><%= _('Content tagged with "%s"') % escaped_tag %></h1> 5 <h1><%= _('Content tagged with "%s"') % escaped_tag %></h1>
6 6
7 <p> 7 <p>
8 -<%= link_to image_tag('icons-mime/rss-feed.png', :alt => _('Feed for this tag'), :title => _('Feed for this tag')), tag_feed_path, :class => 'blog-feed-link'%> 8 +<%= link_to image_tag('/images/icons-mime/rss-feed.png', :alt => _('Feed for this tag'), :title => _('Feed for this tag')), tag_feed_path, :class => 'blog-feed-link'%>
9 </p> 9 </p>
10 10
11 <% cache_timeout(@tag_cache_key, 4.hour) do %> 11 <% cache_timeout(@tag_cache_key, 4.hour) do %>
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){