Commit e755c5668041d08027a61070fe94e5d9d0d154bc

Authored by Josef Spillner
2 parents 9a9bb082 86514f9d

Merge branch 'master' into feature_cyrillic

Showing 828 changed files with 79866 additions and 47407 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 828 files displayed.

@@ -6,25 +6,42 @@ noosfero, that's not a problem). @@ -6,25 +6,42 @@ noosfero, that's not a problem).
6 Developers 6 Developers
7 ========== 7 ==========
8 8
  9 +Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
  10 +Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
9 Antonio Terceiro <terceiro@colivre.coop.br> 11 Antonio Terceiro <terceiro@colivre.coop.br>
10 Aurelio A. Heckert <aurelio@colivre.coop.br> 12 Aurelio A. Heckert <aurelio@colivre.coop.br>
11 Braulio Bhavamitra <brauliobo@gmail.com> 13 Braulio Bhavamitra <brauliobo@gmail.com>
12 Bráulio Bhavamitra <brauliobo@gmail.com> 14 Bráulio Bhavamitra <brauliobo@gmail.com>
13 Caio SBA <caio@colivre.coop.br> 15 Caio SBA <caio@colivre.coop.br>
  16 +Carlos Morais <carlos88morais@gmail.com>
  17 +Carlos Morais + Diego Araújo <diegoamc90@gmail.com>
  18 +Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com>
14 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> 19 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
15 Daniel Cunha <daniel@colivre.coop.br> 20 Daniel Cunha <daniel@colivre.coop.br>
  21 +Diego Araújo <diegoamc90@gmail.com>
  22 +Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
16 Fernanda Lopes <nanda.listas+psl@gmail.com> 23 Fernanda Lopes <nanda.listas+psl@gmail.com>
17 Grazieno Pellegrino <grazieno@gmail.com> 24 Grazieno Pellegrino <grazieno@gmail.com>
18 Italo Valcy <italo@dcc.ufba.br> 25 Italo Valcy <italo@dcc.ufba.br>
  26 +João da Silva <jaodsilv@linux.ime.usp.br>
  27 +João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br>
  28 +João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com>
  29 +João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
  30 +João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
19 Joenio Costa <joenio@colivre.coop.br> 31 Joenio Costa <joenio@colivre.coop.br>
20 Josef Spillner <josef.spillner@tu-dresden.de> 32 Josef Spillner <josef.spillner@tu-dresden.de>
21 Keilla Menezes <keilla@colivre.coop.br> 33 Keilla Menezes <keilla@colivre.coop.br>
  34 +Larissa Reis <larissa@colivre.coop.br>
  35 +Larissa Reis <reiss.larissa@gmail.com>
22 Leandro Nunes dos Santos <leandronunes@gmail.com> 36 Leandro Nunes dos Santos <leandronunes@gmail.com>
23 LinguÁgil 2010 <linguagil.bahia@gmail.com> 37 LinguÁgil 2010 <linguagil.bahia@gmail.com>
24 Martín Olivera <molivera@solar.org.ar> 38 Martín Olivera <molivera@solar.org.ar>
25 Moises Machado <moises@colivre.coop.br> 39 Moises Machado <moises@colivre.coop.br>
26 Nanda Lopes <nanda.listas+psl@gmail.com> 40 Nanda Lopes <nanda.listas+psl@gmail.com>
  41 +Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org>
  42 +Paulo Meirelles <paulo@softwarelivre.org>
27 Rafael Gomes <rafaelgomes@techfree.com.br> 43 Rafael Gomes <rafaelgomes@techfree.com.br>
  44 +Rafael Martins <rmmartins@gmail.com>
28 Raphaël Rousseau <raph@r4f.org> 45 Raphaël Rousseau <raph@r4f.org>
29 Raquel Lira <raquel.lira@gmail.com> 46 Raquel Lira <raquel.lira@gmail.com>
30 Rodrigo Souto <rodrigo@colivre.coop.br> 47 Rodrigo Souto <rodrigo@colivre.coop.br>
@@ -41,3 +58,6 @@ Raphael Rousseau &lt;raph@r4f.org&gt; @@ -41,3 +58,6 @@ Raphael Rousseau &lt;raph@r4f.org&gt;
41 Théo Bondolfi <move@cooperation.net> 58 Théo Bondolfi <move@cooperation.net>
42 Vicente Aguiar <vicenteaguiar@colivre.coop.br> 59 Vicente Aguiar <vicenteaguiar@colivre.coop.br>
43 60
  61 +Arts
  62 +===================================
  63 +Nara Oliveira <narananet@gmail.com>
Gemfile 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +source :rubygems
  2 +gem 'cucumber', '0.4.0'
  3 +gem 'webrat', '0.5.1'
  4 +gem 'rspec', '1.2.9'
  5 +gem 'rspec-rails', '1.2.9'
  6 +gem 'Selenium', '>= 1.1.14'
  7 +gem 'selenium-client', '>= 1.2.17'
  8 +gem 'database_cleaner'
  9 +gem 'exception_notification', '1.0.20090728'
  10 +gem 'system_timer'
  11 +
  12 +def program(name)
  13 + unless system("which #{name} > /dev/null")
  14 + puts "W: Program #{name} is needed, but was not found in your PATH"
  15 + end
  16 +end
  17 +
  18 +program 'java'
  19 +program 'firefox'
Gemfile.lock 0 → 100644
@@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
  1 +GEM
  2 + remote: http://rubygems.org/
  3 + specs:
  4 + Selenium (1.1.14)
  5 + builder (3.0.0)
  6 + cucumber (0.4.0)
  7 + builder (>= 2.1.2)
  8 + diff-lcs (>= 1.1.2)
  9 + polyglot (>= 0.2.9)
  10 + term-ansicolor (>= 1.0.3)
  11 + treetop (>= 1.4.2)
  12 + database_cleaner (0.7.0)
  13 + diff-lcs (1.1.3)
  14 + exception_notification (1.0.20090728)
  15 + nokogiri (1.5.0)
  16 + polyglot (0.3.3)
  17 + rack (1.3.5)
  18 + rspec (1.2.9)
  19 + rspec-rails (1.2.9)
  20 + rack (>= 1.0.0)
  21 + rspec (>= 1.2.9)
  22 + selenium-client (1.2.18)
  23 + system_timer (1.2.4)
  24 + term-ansicolor (1.0.7)
  25 + treetop (1.4.10)
  26 + polyglot
  27 + polyglot (>= 0.3.1)
  28 + webrat (0.5.1)
  29 + nokogiri (>= 1.2.0)
  30 + rack (>= 1.0)
  31 +
  32 +PLATFORMS
  33 + ruby
  34 +
  35 +DEPENDENCIES
  36 + Selenium (>= 1.1.14)
  37 + cucumber (= 0.4.0)
  38 + database_cleaner
  39 + exception_notification (= 1.0.20090728)
  40 + rspec (= 1.2.9)
  41 + rspec-rails (= 1.2.9)
  42 + selenium-client (>= 1.2.17)
  43 + system_timer
  44 + webrat (= 0.5.1)
@@ -13,7 +13,7 @@ After installing the requirements listed in INSTALL, you need to install some @@ -13,7 +13,7 @@ After installing the requirements listed in INSTALL, you need to install some
13 packages be able to run Noosfero tests. On Debian GNU/Linux and Debian-based 13 packages be able to run Noosfero tests. On Debian GNU/Linux and Debian-based
14 systems, you install them with the following command: 14 systems, you install them with the following command:
15 15
16 - # apt-get install libtidy-ruby libhpricot-ruby libmocha-ruby imagemagick po4a xvfb 16 + # apt-get install libtidy-ruby libhpricot-ruby libmocha-ruby imagemagick po4a xvfb libxml2-dev libxslt-dev
17 17
18 On other systems, they may or may not be available through your regular package 18 On other systems, they may or may not be available through your regular package
19 management system. Below are the links to their homepages. 19 management system. Below are the links to their homepages.
@@ -24,6 +24,8 @@ management system. Below are the links to their homepages. @@ -24,6 +24,8 @@ management system. Below are the links to their homepages.
24 * Imagemagick: http://wwwimagemagick.org/ 24 * Imagemagick: http://wwwimagemagick.org/
25 * po4a: http://po4a.alioth.debian.org/ 25 * po4a: http://po4a.alioth.debian.org/
26 * xvfb: http://packages.debian.org/lenny/xvfb 26 * xvfb: http://packages.debian.org/lenny/xvfb
  27 +* Libxml2: http://xmlsoft.org/
  28 +* Libxslt: http://xmlsoft.org/xslt
27 29
28 == Boostraping a development/test environment 30 == Boostraping a development/test environment
29 31
@@ -46,6 +48,9 @@ commands and make sure you understand what you are doing): @@ -46,6 +48,9 @@ commands and make sure you understand what you are doing):
46 rake makemo 48 rake makemo
47 # create some test data: 49 # create some test data:
48 ./script/sample-data 50 ./script/sample-data
  51 + # install latest requirements for running tests
  52 + RAILS_ENV=cucumber rake gems:install
  53 + RAILS_ENV=test rake gems:install
49 # run the automated test suite to make sure your environment is sane: 54 # run the automated test suite to make sure your environment is sane:
50 rake test 55 rake test
51 56
HACKING.rails235 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +This is a draft of how to create a environment to Rails 2.3.5 to Noosfero
  2 +development.
  3 +
  4 +Install dependencies:
  5 +
  6 +gem install rails -v 2.3.5
  7 +gem install ferret
  8 +gem install i18n
  9 +gem install will_paginate -v 2.3.12
  10 +gem install cucumber
  11 +
  12 +Creating initial environment:
  13 +
  14 +rake db:schema:load
@@ -13,7 +13,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or @@ -13,7 +13,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or
13 Debian-based systems, all of these packages are available through the Debian 13 Debian-based systems, all of these packages are available through the Debian
14 archive. You can install them with the following command: 14 archive. You can install them with the following command:
15 15
16 - # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby-data libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby libferret-ruby libdaemons-ruby mongrel mongrel-cluster tango-icon-theme libhpricot-ruby 16 + # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby-data libgettext-ruby1.8 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libwill-paginate-ruby iso-codes libfeedparser-ruby libferret-ruby libdaemons-ruby thin tango-icon-theme libhpricot-ruby
17 17
18 On other systems, they may or may not be available through your regular package 18 On other systems, they may or may not be available through your regular package
19 management system. Below are the links to their homepages. 19 management system. Below are the links to their homepages.
@@ -31,7 +31,7 @@ management system. Below are the links to their homepages. @@ -31,7 +31,7 @@ management system. Below are the links to their homepages.
31 * iso-codes: http://pkg-isocodes.alioth.debian.org/ 31 * iso-codes: http://pkg-isocodes.alioth.debian.org/
32 * feedparser: http://packages.debian.org/sid/libfeedparser-ruby 32 * feedparser: http://packages.debian.org/sid/libfeedparser-ruby
33 * Daemons - http://daemons.rubyforge.org/ 33 * Daemons - http://daemons.rubyforge.org/
34 -* Mongrel: http://mongrel.rubyforge.org/ 34 +* Thin: http://code.macournoyer.com/thin/
35 * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library 35 * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library
36 * Hpricot: http://hpricot.com/ 36 * Hpricot: http://hpricot.com/
37 37
@@ -118,13 +118,13 @@ $ cd current @@ -118,13 +118,13 @@ $ cd current
118 Copy config/ferret_server.yml.dist to config/ferret_server.yml. You will 118 Copy config/ferret_server.yml.dist to config/ferret_server.yml. You will
119 probably not need to customize this configuration, but have a look at it. 119 probably not need to customize this configuration, but have a look at it.
120 120
121 -Create the mongrel configuration file: 121 +Create the thin configuration file:
122 122
123 -$ mongrel_rails cluster::configure 123 +$ thin -C config/thin.yml config
124 124
125 -Edit config/mongrel_cluster.yml to suit your needs. Make sure your apache  
126 -configuration matches the mongrel cluster configuration, specially in respect  
127 -to the ports and numbers of mongrel instances. 125 +Edit config/thin.yml to suit your needs. Make sure your apache
  126 +configuration matches the thin cluster configuration, specially in respect
  127 +to the ports and numbers of thin instances.
128 128
129 Note: currently Noosfero only supports Rails 2.1.0, which is the version in 129 Note: currently Noosfero only supports Rails 2.1.0, which is the version in
130 Debian Lenny. If you have a Rails version newer than that, Noosfero will 130 Debian Lenny. If you have a Rails version newer than that, Noosfero will
@@ -237,6 +237,10 @@ Create the database structure: @@ -237,6 +237,10 @@ Create the database structure:
237 237
238 $ RAILS_ENV=production rake db:schema:load 238 $ RAILS_ENV=production rake db:schema:load
239 239
  240 +Compile the translations:
  241 +
  242 +$ RAILS_ENV=production rake noosfero:translations:compile
  243 +
240 Now we have to create some initial data. To create your default environment 244 Now we have to create some initial data. To create your default environment
241 (the first one), run the command below: 245 (the first one), run the command below:
242 246
@@ -258,10 +262,6 @@ $ RAILS_ENV=production ./script/runner &quot;User.create(:login =&gt; &#39;adminuser&#39;, :emai @@ -258,10 +262,6 @@ $ RAILS_ENV=production ./script/runner &quot;User.create(:login =&gt; &#39;adminuser&#39;, :emai
258 (replace "adminuser", "admin@example.com", "admin" with the login, email 262 (replace "adminuser", "admin@example.com", "admin" with the login, email
259 and password of your environment admin) 263 and password of your environment admin)
260 264
261 -Compile the translations:  
262 -  
263 -$ RAILS_ENV=production rake noosfero:translations:compile  
264 -  
265 To start the Noosfero application servers: 265 To start the Noosfero application servers:
266 266
267 $ ./script/production start 267 $ ./script/production start
@@ -316,7 +316,7 @@ In other systems the way by which you enable apache modules may be different. @@ -316,7 +316,7 @@ In other systems the way by which you enable apache modules may be different.
316 Now with the Apache configuration. You can use the template below, replacing 316 Now with the Apache configuration. You can use the template below, replacing
317 /var/lib/noosfero/current with the directory in which your noosfero 317 /var/lib/noosfero/current with the directory in which your noosfero
318 installation is, your.domain.com with the domain name of your noosfero site. 318 installation is, your.domain.com with the domain name of your noosfero site.
319 -We are assuming that you are running two mongrel instances on ports 3000 and 319 +We are assuming that you are running two thin instances on ports 3000 and
320 3001. If your setup is different you'll need to adjust <Proxy> section. If you 320 3001. If your setup is different you'll need to adjust <Proxy> section. If you
321 don't understand something in the configuration, please refer to the apache 321 don't understand something in the configuration, please refer to the apache
322 documentation. 322 documentation.
INSTALL.awstats 0 → 100644
@@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
  1 += AWStats setup for Noosfero
  2 +
  3 +AWStats is a free powerful and featureful tool that generates advanced web,
  4 +streaming, ftp or mail server statistics, graphically.
  5 +
  6 +See http://awstats.sourceforge.net/
  7 +
  8 +This guide supposes that the Noosfero server is running GNU/Linux Debian Squeeze.
  9 +
  10 +1. Install AWStats
  11 +
  12 +# apt-get install awstats libgeo-ip-perl geoip-database
  13 +
  14 +2. Basic setup
  15 +
  16 +Create AWStats config file:
  17 +
  18 + * /etc/awstats/awstats.<domain>.conf
  19 +
  20 +Include "/etc/awstats/awstats.conf"
  21 +Include "/etc/noosfero/awstats-noosfero.conf"
  22 +SiteDomain="<domain>"
  23 +HostAliases="<domain-aliases>"
  24 +
  25 +<domain> should be the domain used in your Noosfero server (eg.:
  26 +softwarelivre.org) and the <domain-aliases> should be a list with all aliases
  27 +that you configured in apache (eg.: www.softwarelivre.org
  28 +www2.softwarelivre.org etc).
  29 +
  30 +This setup is considering that the Noosfero server is running varnish (see
  31 +INSTALL.varnish) and varnishncsa-vhost [1].
  32 +
  33 +[1] http://gitorious.org/varnisnncsa-vhost
  34 +
  35 +3. Running AWStats for the first time
  36 +
  37 +Run awstats by hand via command line:
  38 +
  39 +# /usr/lib/cgi-bin/awstats.pl -config=<domain>
  40 +
  41 +You should see something as below as output of this command:
  42 +
  43 +# /usr/lib/cgi-bin/awstats.pl -config=softwarelivre.org
  44 +Create/Update database for config "/etc/awstats/awstats.softwarelivre.org.conf" by AWStats version 6.7 (build 1.892)
  45 +From data in log file "/var/log/varnish/varnishncsa-vhost.log"...
  46 +Phase 1 : First bypass old records, searching new record...
  47 +Searching new records from beginning of log file...
  48 +Phase 2 : Now process new records (Flush history on disk after 20000 hosts)...
  49 +Jumped lines in file: 0
  50 +Parsed lines in file: 452
  51 + Found 0 dropped records,
  52 + Found 0 corrupted records,
  53 + Found 0 old records,
  54 + Found 452 new qualified records.
  55 +
  56 +4. Setup frontend
  57 +
  58 +You should create a new subdomain to have access to the AWStats, usually
  59 +something like tools.<domain> (eg.: tools.softwarelivre.org). Don't include
  60 +this subdomain in HostAliases in the AWStats neither in SiteAlias in the
  61 +Apache.
  62 +
  63 +# cp /usr/share/doc/awstats/examples/apache.conf /etc/apache2/conf.d/awstats.conf
  64 +# invoke-rc.d apache2 restart
  65 +
  66 +ps.: Don't forget to change the port /etc/apache/sites-enabled/000-default to
  67 +8080.
  68 +
  69 +Try: http://tools.<domain>/cgi-bin/awstats.pl?config=<domain>
  70 +(eg.: http://tools.softwarelivre.org/cgi-bin/awstats.pl?config=softwarelivre.org).
  71 +
  72 +5. Schedule AWStats in crontab
  73 +
  74 + * /etc/cron.d/awstats
  75 +
  76 +0,10,20,30,40,50 * * * * www-data [ -x /usr/lib/cgi-bin/awstats.pl -a -f /etc/awstats/awstats.<domain>.conf -a -r /var/log/apache/access.log ] && /usr/lib/cgi-bin/awstats.pl -config=<domain> -update >/dev/null
  77 +
  78 +Done, check the AWStats frontend after one or two days to see if everything is working properly.
app/controllers/admin/role_controller.rb
@@ -5,6 +5,20 @@ class RoleController &lt; AdminController @@ -5,6 +5,20 @@ class RoleController &lt; AdminController
5 @roles = environment.roles.find(:all) 5 @roles = environment.roles.find(:all)
6 end 6 end
7 7
  8 + def new
  9 + @role = Role.new
  10 + end
  11 +
  12 + def create
  13 + @role = Role.new :name => params[:role][:name], :permissions => params[:role][:permissions], :environment => environment
  14 + if @role.save
  15 + redirect_to :action => 'show', :id => @role
  16 + else
  17 + session[:notice] = _('Failed to create role')
  18 + render :action => 'new'
  19 + end
  20 + end
  21 +
8 def show 22 def show
9 @role = environment.roles.find(params[:id]) 23 @role = environment.roles.find(params[:id])
10 end 24 end
app/controllers/admin/users_controller.rb
@@ -3,10 +3,10 @@ class UsersController &lt; AdminController @@ -3,10 +3,10 @@ class UsersController &lt; AdminController
3 protect 'manage_environment_users', :environment 3 protect 'manage_environment_users', :environment
4 4
5 def index 5 def index
6 - @users = environment.users  
7 respond_to do |format| 6 respond_to do |format|
8 format.html 7 format.html
9 format.xml do 8 format.xml do
  9 + @users = User.find(:all, :conditions => {:environment_id => environment.id}, :include => [:person])
10 render :xml => @users.to_xml( 10 render :xml => @users.to_xml(
11 :skip_types => true, 11 :skip_types => true,
12 :only => %w[email login created_at updated_at], 12 :only => %w[email login created_at updated_at],
@@ -14,6 +14,7 @@ class UsersController &lt; AdminController @@ -14,6 +14,7 @@ class UsersController &lt; AdminController
14 ) 14 )
15 end 15 end
16 format.csv do 16 format.csv do
  17 + @users = User.find(:all, :conditions => {:environment_id => environment.id}, :include => [:person])
17 render :template => "users/index_csv.rhtml", :content_type => 'text/csv', :layout => false 18 render :template => "users/index_csv.rhtml", :content_type => 'text/csv', :layout => false
18 end 19 end
19 end 20 end
app/controllers/admin_controller.rb
1 class AdminController < ApplicationController 1 class AdminController < ApplicationController
2 - require_ssl  
3 before_filter :login_required 2 before_filter :login_required
4 end 3 end
app/controllers/application.rb
1 -# his is the application's main controller. Features defined here are  
2 -# available in all controllers.  
3 -class ApplicationController < ActionController::Base  
4 -  
5 - before_filter :change_pg_schema  
6 -  
7 - include ApplicationHelper  
8 - layout :get_layout  
9 - def get_layout  
10 - theme_option(:layout) || 'application'  
11 - end  
12 -  
13 - filter_parameter_logging :password  
14 -  
15 - def log_processing  
16 - super  
17 - return unless ENV['RAILS_ENV'] == 'production'  
18 - if logger && logger.info?  
19 - logger.info(" HTTP Referer: #{request.referer}")  
20 - logger.info(" User Agent: #{request.user_agent}")  
21 - logger.info(" Accept-Language: #{request.headers['HTTP_ACCEPT_LANGUAGE']}")  
22 - end  
23 - end  
24 -  
25 - helper :document  
26 - helper :language  
27 -  
28 - def self.no_design_blocks  
29 - @no_design_blocks = true  
30 - end  
31 - def self.uses_design_blocks?  
32 - !@no_design_blocks  
33 - end  
34 - def uses_design_blocks?  
35 - !@no_design_blocks && self.class.uses_design_blocks?  
36 - end  
37 -  
38 - # Be sure to include AuthenticationSystem in Application Controller instead  
39 - include AuthenticatedSystem  
40 - include PermissionCheck  
41 -  
42 - def self.require_ssl(*options)  
43 - before_filter :check_ssl, *options  
44 - end  
45 - def check_ssl  
46 - return true if (request.ssl? || ENV['RAILS_ENV'] == 'development')  
47 - redirect_to_ssl  
48 - end  
49 - def redirect_to_ssl  
50 - if environment.enable_ssl  
51 - redirect_to(params.merge(:protocol => 'https://', :host => ssl_hostname))  
52 - true  
53 - else  
54 - false  
55 - end  
56 - end  
57 -  
58 - def self.refuse_ssl(*options)  
59 - before_filter :avoid_ssl, *options  
60 - end  
61 - def avoid_ssl  
62 - if (!request.ssl? || ENV['RAILS_ENV'] == 'development')  
63 - true  
64 - else  
65 - redirect_to(params.merge(:protocol => 'http://'))  
66 - false  
67 - end  
68 - end  
69 -  
70 - before_filter :set_locale  
71 - def set_locale  
72 - FastGettext.available_locales = Noosfero.available_locales  
73 - FastGettext.default_locale = Noosfero.default_locale  
74 - FastGettext.set_locale(params[:lang] || session[:lang] || Noosfero.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')  
75 - if params[:lang]  
76 - session[:lang] = params[:lang]  
77 - end  
78 - end  
79 -  
80 - include NeedsProfile  
81 -  
82 - before_filter :detect_stuff_by_domain  
83 - before_filter :init_noosfero_plugins  
84 - attr_reader :environment  
85 -  
86 - before_filter :load_terminology  
87 -  
88 - # declares that the given <tt>actions</tt> cannot be accessed by other HTTP  
89 - # method besides POST.  
90 - def self.post_only(actions, redirect = { :action => 'index'})  
91 - verify :method => :post, :only => actions, :redirect_to => redirect  
92 - end  
93 -  
94 - helper_method :current_person, :current_person  
95 -  
96 - def change_pg_schema  
97 - if Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?  
98 - Noosfero::MultiTenancy.db_by_host = request.host  
99 - end  
100 - end  
101 -  
102 - protected  
103 -  
104 - def boxes_editor?  
105 - false  
106 - end  
107 -  
108 - def content_editor?  
109 - false  
110 - end  
111 -  
112 - def user  
113 - current_user.person if logged_in?  
114 - end  
115 -  
116 - alias :current_person :user  
117 -  
118 - # TODO: move this logic somewhere else (Domain class?)  
119 - def detect_stuff_by_domain  
120 - @domain = Domain.find_by_name(request.host)  
121 - if @domain.nil?  
122 - @environment = Environment.default  
123 - else  
124 - @environment = @domain.environment  
125 - @profile = @domain.profile  
126 - end  
127 - end  
128 -  
129 - def init_noosfero_plugins  
130 - @plugins = Noosfero::Plugin::Manager.new(self)  
131 - @plugins.enabled_plugins.map(&:class).each do |plugin|  
132 - prepend_view_path(plugin.view_path)  
133 - end  
134 - init_noosfero_plugins_controller_filters  
135 - end  
136 -  
137 - # This is a generic method that initialize any possible filter defined by a  
138 - # plugin to the current controller being initialized.  
139 - def init_noosfero_plugins_controller_filters  
140 - @plugins.enabled_plugins.each do |plugin|  
141 - plugin.send(self.class.name.underscore + '_filters').each do |plugin_filter|  
142 - self.class.send(plugin_filter[:type], plugin.class.name.underscore + '_' + plugin_filter[:method_name], (plugin_filter[:options] || {}))  
143 - self.class.send(:define_method, plugin.class.name.underscore + '_' + plugin_filter[:method_name], plugin_filter[:block])  
144 - end  
145 - end  
146 - end  
147 -  
148 - def load_terminology  
149 - # cache terminology for performance  
150 - @@terminology_cache ||= {}  
151 - @@terminology_cache[environment.id] ||= environment.terminology  
152 - Noosfero.terminology = @@terminology_cache[environment.id]  
153 - end  
154 -  
155 - def render_not_found(path = nil)  
156 - @no_design_blocks = true  
157 - @path ||= request.path  
158 - render :template => 'shared/not_found.rhtml', :status => 404, :layout => get_layout  
159 - end  
160 - alias :render_404 :render_not_found  
161 -  
162 - def render_access_denied(message = nil, title = nil)  
163 - @no_design_blocks = true  
164 - @message = message  
165 - @title = title  
166 - render :template => 'shared/access_denied.rhtml', :status => 403  
167 - end  
168 -  
169 - def load_category  
170 - unless params[:category_path].blank?  
171 - path = params[:category_path].join('/')  
172 - @category = environment.categories.find_by_path(path)  
173 - if @category.nil?  
174 - render_not_found(path)  
175 - end  
176 - end  
177 - end  
178 -  
179 -end 1 +require 'application_controller'
app/controllers/application_controller.rb 0 → 100644
@@ -0,0 +1,155 @@ @@ -0,0 +1,155 @@
  1 +class ApplicationController < ActionController::Base
  2 +
  3 + before_filter :change_pg_schema
  4 +
  5 + include ApplicationHelper
  6 + layout :get_layout
  7 + def get_layout
  8 + prepend_view_path('public/' + theme_path)
  9 + theme_option(:layout) || 'application'
  10 + end
  11 +
  12 + filter_parameter_logging :password
  13 +
  14 + def log_processing
  15 + super
  16 + return unless ENV['RAILS_ENV'] == 'production'
  17 + if logger && logger.info?
  18 + logger.info(" HTTP Referer: #{request.referer}")
  19 + logger.info(" User Agent: #{request.user_agent}")
  20 + logger.info(" Accept-Language: #{request.headers['HTTP_ACCEPT_LANGUAGE']}")
  21 + end
  22 + end
  23 +
  24 + helper :document
  25 + helper :language
  26 +
  27 + def self.no_design_blocks
  28 + @no_design_blocks = true
  29 + end
  30 + def self.uses_design_blocks?
  31 + !@no_design_blocks
  32 + end
  33 + def uses_design_blocks?
  34 + !@no_design_blocks && self.class.uses_design_blocks?
  35 + end
  36 +
  37 + # Be sure to include AuthenticationSystem in Application Controller instead
  38 + include AuthenticatedSystem
  39 + include PermissionCheck
  40 +
  41 + before_filter :set_locale
  42 + def set_locale
  43 + FastGettext.available_locales = Noosfero.available_locales
  44 + FastGettext.default_locale = Noosfero.default_locale
  45 + I18n.locale = FastGettext.locale = (params[:lang] || session[:lang] || Noosfero.default_locale || request.env['HTTP_ACCEPT_LANGUAGE'] || 'en')
  46 + if params[:lang]
  47 + session[:lang] = params[:lang]
  48 + end
  49 + end
  50 +
  51 + include NeedsProfile
  52 +
  53 + before_filter :detect_stuff_by_domain
  54 + before_filter :init_noosfero_plugins
  55 + attr_reader :environment
  56 +
  57 + before_filter :load_terminology
  58 +
  59 + # declares that the given <tt>actions</tt> cannot be accessed by other HTTP
  60 + # method besides POST.
  61 + def self.post_only(actions, redirect = { :action => 'index'})
  62 + verify :method => :post, :only => actions, :redirect_to => redirect
  63 + end
  64 +
  65 + helper_method :current_person, :current_person
  66 +
  67 + protected
  68 +
  69 + def change_pg_schema
  70 + if Noosfero::MultiTenancy.on? and ActiveRecord::Base.postgresql?
  71 + Noosfero::MultiTenancy.db_by_host = request.host
  72 + end
  73 + end
  74 +
  75 + def boxes_editor?
  76 + false
  77 + end
  78 +
  79 + def content_editor?
  80 + false
  81 + end
  82 +
  83 +
  84 + def user
  85 + current_user.person if logged_in?
  86 + end
  87 +
  88 + alias :current_person :user
  89 +
  90 + # TODO: move this logic somewhere else (Domain class?)
  91 + def detect_stuff_by_domain
  92 + @domain = Domain.find_by_name(request.host)
  93 + if @domain.nil?
  94 + @environment = Environment.default
  95 + if @environment.nil? && Rails.env.development?
  96 + # This should only happen in development ...
  97 + @environment = Environment.create!(:name => "Noosfero", :is_default => true)
  98 + end
  99 + else
  100 + @environment = @domain.environment
  101 + @profile = @domain.profile
  102 + end
  103 + end
  104 +
  105 + def init_noosfero_plugins
  106 + @plugins = Noosfero::Plugin::Manager.new(self)
  107 + @plugins.each do |plugin|
  108 + prepend_view_path(plugin.class.view_path)
  109 + end
  110 + init_noosfero_plugins_controller_filters
  111 + end
  112 +
  113 + # This is a generic method that initialize any possible filter defined by a
  114 + # plugin to the current controller being initialized.
  115 + def init_noosfero_plugins_controller_filters
  116 + @plugins.each do |plugin|
  117 + plugin.send(self.class.name.underscore + '_filters').each do |plugin_filter|
  118 + self.class.send(plugin_filter[:type], plugin.class.name.underscore + '_' + plugin_filter[:method_name], (plugin_filter[:options] || {}))
  119 + self.class.send(:define_method, plugin.class.name.underscore + '_' + plugin_filter[:method_name], plugin_filter[:block])
  120 + end
  121 + end
  122 + end
  123 +
  124 + def load_terminology
  125 + # cache terminology for performance
  126 + @@terminology_cache ||= {}
  127 + @@terminology_cache[environment.id] ||= environment.terminology
  128 + Noosfero.terminology = @@terminology_cache[environment.id]
  129 + end
  130 +
  131 + def render_not_found(path = nil)
  132 + @no_design_blocks = true
  133 + @path ||= request.path
  134 + render :template => 'shared/not_found.rhtml', :status => 404, :layout => get_layout
  135 + end
  136 + alias :render_404 :render_not_found
  137 +
  138 + def render_access_denied(message = nil, title = nil)
  139 + @no_design_blocks = true
  140 + @message = message
  141 + @title = title
  142 + render :template => 'shared/access_denied.rhtml', :status => 403
  143 + end
  144 +
  145 + def load_category
  146 + unless params[:category_path].blank?
  147 + path = params[:category_path].join('/')
  148 + @category = environment.categories.find_by_path(path)
  149 + if @category.nil?
  150 + render_not_found(path)
  151 + end
  152 + end
  153 + end
  154 +
  155 +end
app/controllers/box_organizer_controller.rb
@@ -82,7 +82,6 @@ class BoxOrganizerController &lt; ApplicationController @@ -82,7 +82,6 @@ class BoxOrganizerController &lt; ApplicationController
82 def save 82 def save
83 @block = boxes_holder.blocks.find(params[:id]) 83 @block = boxes_holder.blocks.find(params[:id])
84 @block.update_attributes(params[:block]) 84 @block.update_attributes(params[:block])
85 - expire_timeout_fragment(@block.cache_key)  
86 redirect_to :action => 'index' 85 redirect_to :action => 'index'
87 end 86 end
88 87
@@ -93,7 +92,6 @@ class BoxOrganizerController &lt; ApplicationController @@ -93,7 +92,6 @@ class BoxOrganizerController &lt; ApplicationController
93 def remove 92 def remove
94 @block = Block.find(params[:id]) 93 @block = Block.find(params[:id])
95 if @block.destroy 94 if @block.destroy
96 - expire_timeout_fragment(@block.cache_key)  
97 redirect_to :action => 'index' 95 redirect_to :action => 'index'
98 else 96 else
99 session[:notice] = _('Failed to remove block') 97 session[:notice] = _('Failed to remove block')
app/controllers/my_profile/cms_controller.rb
@@ -23,15 +23,6 @@ class CmsController &lt; MyProfileController @@ -23,15 +23,6 @@ class CmsController &lt; MyProfileController
23 profile.articles.find(c.params[:id]).allow_post_content?(user) 23 profile.articles.find(c.params[:id]).allow_post_content?(user)
24 end 24 end
25 25
26 - alias :check_ssl_orig :check_ssl  
27 - # Redefines the SSL checking to avoid requiring SSL when creating the "New  
28 - # publication" button on article's public view.  
29 - def check_ssl  
30 - if ((params[:action] == 'new') && (!request.xhr?)) || (params[:action] != 'new')  
31 - check_ssl_orig  
32 - end  
33 - end  
34 -  
35 def boxes_holder 26 def boxes_holder
36 profile 27 profile
37 end 28 end
@@ -59,7 +50,7 @@ class CmsController &lt; MyProfileController @@ -59,7 +50,7 @@ class CmsController &lt; MyProfileController
59 end 50 end
60 51
61 def special_article_types 52 def special_article_types
62 - [Folder, Blog, UploadedFile, Forum, Gallery, RssFeed] 53 + [Folder, Blog, UploadedFile, Forum, Gallery, RssFeed] + @plugins.dispatch(:content_types)
63 end 54 end
64 55
65 def view 56 def view
@@ -206,6 +197,7 @@ class CmsController &lt; MyProfileController @@ -206,6 +197,7 @@ class CmsController &lt; MyProfileController
206 @article = profile.articles.find(params[:id]) 197 @article = profile.articles.find(params[:id])
207 if request.post? 198 if request.post?
208 @article.destroy 199 @article.destroy
  200 + session[:notice] = _("\"#{@article.name}\" was removed.")
209 redirect_to :action => (@article.parent ? 'view' : 'index'), :id => @article.parent 201 redirect_to :action => (@article.parent ? 'view' : 'index'), :id => @article.parent
210 end 202 end
211 end 203 end
@@ -319,10 +311,6 @@ class CmsController &lt; MyProfileController @@ -319,10 +311,6 @@ class CmsController &lt; MyProfileController
319 end 311 end
320 end 312 end
321 313
322 - def maybe_ssl(url)  
323 - [url, url.sub('https:', 'http:')]  
324 - end  
325 -  
326 def valid_article_type?(type) 314 def valid_article_type?(type)
327 (available_article_types + special_article_types).map {|item| item.name}.include?(type) 315 (available_article_types + special_article_types).map {|item| item.name}.include?(type)
328 end 316 end
@@ -365,7 +353,7 @@ class CmsController &lt; MyProfileController @@ -365,7 +353,7 @@ class CmsController &lt; MyProfileController
365 } 353 }
366 end.to_json 354 end.to_json
367 end 355 end
368 - 356 +
369 def content_editor? 357 def content_editor?
370 true 358 true
371 end 359 end
app/controllers/my_profile/manage_products_controller.rb
@@ -111,6 +111,36 @@ class ManageProductsController &lt; ApplicationController @@ -111,6 +111,36 @@ class ManageProductsController &lt; ApplicationController
111 end 111 end
112 end 112 end
113 113
  114 + def manage_product_details
  115 + @product = @profile.products.find(params[:id])
  116 + if request.post?
  117 + @product.update_price_details(params[:price_details]) if params[:price_details]
  118 + render :partial => 'display_price_details'
  119 + else
  120 + render :partial => 'manage_product_details'
  121 + end
  122 + end
  123 +
  124 + def remove_price_detail
  125 + @product = @profile.products.find(params[:product])
  126 + @price_detail = @product.price_details.find(params[:id])
  127 + @product = @price_detail.product
  128 + if request.post?
  129 + @price_detail.destroy
  130 + render :nothing => true
  131 + end
  132 + end
  133 +
  134 + def display_price_composition_bar
  135 + @product = @profile.products.find(params[:id])
  136 + render :partial => 'price_composition_bar'
  137 + end
  138 +
  139 + def display_inputs_cost
  140 + @product = @profile.products.find(params[:id])
  141 + render :inline => "<%= float_to_currency(@product.inputs_cost) %>"
  142 + end
  143 +
114 def destroy 144 def destroy
115 @product = @profile.products.find(params[:id]) 145 @product = @profile.products.find(params[:id])
116 if @product.destroy 146 if @product.destroy
@@ -167,4 +197,18 @@ class ManageProductsController &lt; ApplicationController @@ -167,4 +197,18 @@ class ManageProductsController &lt; ApplicationController
167 end 197 end
168 end 198 end
169 199
  200 + def create_production_cost
  201 + cost = @profile.production_costs.create(:name => params[:id])
  202 + if cost.valid?
  203 + cost.save
  204 + render :text => {:name => cost.name,
  205 + :id => cost.id,
  206 + :ok => true
  207 + }.to_json
  208 + else
  209 + render :text => {:ok => false,
  210 + :error_msg => _(cost.errors['name']) % {:fn => _('Name')}
  211 + }.to_json
  212 + end
  213 + end
170 end 214 end
app/controllers/my_profile/tasks_controller.rb
@@ -33,12 +33,14 @@ class TasksController &lt; MyProfileController @@ -33,12 +33,14 @@ class TasksController &lt; MyProfileController
33 end 33 end
34 end 34 end
35 35
  36 + url = { :action => 'index' }
36 if failed.blank? 37 if failed.blank?
37 session[:notice] = _("All decisions were applied successfully.") 38 session[:notice] = _("All decisions were applied successfully.")
38 else 39 else
39 session[:notice] = _("Some decisions couldn't be applied.") 40 session[:notice] = _("Some decisions couldn't be applied.")
  41 + url[:failed] = failed
40 end 42 end
41 - redirect_to params.merge!(:action => 'index', :failed => failed) 43 + redirect_to url
42 end 44 end
43 45
44 def new 46 def new
app/controllers/my_profile_controller.rb
@@ -2,7 +2,6 @@ class MyProfileController &lt; ApplicationController @@ -2,7 +2,6 @@ class MyProfileController &lt; ApplicationController
2 2
3 needs_profile 3 needs_profile
4 4
5 - require_ssl  
6 5
7 before_filter :login_required 6 before_filter :login_required
8 7
app/controllers/public/account_controller.rb
@@ -2,8 +2,6 @@ class AccountController &lt; ApplicationController @@ -2,8 +2,6 @@ class AccountController &lt; ApplicationController
2 2
3 no_design_blocks 3 no_design_blocks
4 4
5 - require_ssl :except => [ :login_popup, :logout_popup, :profile_details ]  
6 -  
7 before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] 5 before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise]
8 before_filter :redirect_if_logged_in, :only => [:login, :signup] 6 before_filter :redirect_if_logged_in, :only => [:login, :signup]
9 7
@@ -60,6 +58,10 @@ class AccountController &lt; ApplicationController @@ -60,6 +58,10 @@ class AccountController &lt; ApplicationController
60 def signup 58 def signup
61 @invitation_code = params[:invitation_code] 59 @invitation_code = params[:invitation_code]
62 begin 60 begin
  61 + if params[:user]
  62 + params[:user].delete(:password_confirmation_clear)
  63 + params[:user].delete(:password_clear)
  64 + end
63 @user = User.new(params[:user]) 65 @user = User.new(params[:user])
64 @user.terms_of_use = environment.terms_of_use 66 @user.terms_of_use = environment.terms_of_use
65 @user.environment = environment 67 @user.environment = environment
@@ -91,7 +93,6 @@ class AccountController &lt; ApplicationController @@ -91,7 +93,6 @@ class AccountController &lt; ApplicationController
91 if logged_in? 93 if logged_in?
92 self.current_user.forget_me 94 self.current_user.forget_me
93 end 95 end
94 - cookies.delete :auth_token  
95 reset_session 96 reset_session
96 session[:notice] = _("You have been logged out.") 97 session[:notice] = _("You have been logged out.")
97 redirect_to :controller => 'home', :action => 'index' 98 redirect_to :controller => 'home', :action => 'index'
@@ -209,16 +210,26 @@ class AccountController &lt; ApplicationController @@ -209,16 +210,26 @@ class AccountController &lt; ApplicationController
209 @identifier = params[:identifier] 210 @identifier = params[:identifier]
210 valid = Person.is_available?(@identifier, environment) 211 valid = Person.is_available?(@identifier, environment)
211 if valid 212 if valid
212 - @status = _('Available!') 213 + @status = _('This login name is available')
213 @status_class = 'available' 214 @status_class = 'available'
214 else 215 else
215 - @status = _('Unavailable!') 216 + @status = _('This login name is unavailable')
216 @status_class = 'unavailable' 217 @status_class = 'unavailable'
217 end 218 end
218 - @url = environment.top_url + '/' + @identifier  
219 render :partial => 'identifier_status' 219 render :partial => 'identifier_status'
220 end 220 end
221 221
  222 + def check_email
  223 + if User.find_by_email_and_environment_id(params[:address], environment.id).nil?
  224 + @status = _('This e-mail address is available')
  225 + @status_class = 'available'
  226 + else
  227 + @status = _('This e-mail address is taken')
  228 + @status_class = 'unavailable'
  229 + end
  230 + render :partial => 'email_status'
  231 + end
  232 +
222 def user_data 233 def user_data
223 user_data = 234 user_data =
224 if logged_in? 235 if logged_in?
@@ -231,7 +242,7 @@ class AccountController &lt; ApplicationController @@ -231,7 +242,7 @@ class AccountController &lt; ApplicationController
231 session[:notice] = nil # consume the notice 242 session[:notice] = nil # consume the notice
232 end 243 end
233 244
234 - @plugins.enabled_plugins.each { |plugin| user_data.merge!(plugin.user_data_extras) } 245 + @plugins.each { |plugin| user_data.merge!(plugin.user_data_extras) }
235 246
236 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" 247 render :text => user_data.to_json, :layout => false, :content_type => "application/javascript"
237 end 248 end
app/controllers/public/browse_controller.rb
@@ -6,6 +6,8 @@ class BrowseController &lt; PublicController @@ -6,6 +6,8 @@ class BrowseController &lt; PublicController
6 more_recent 6 more_recent
7 more_active 7 more_active
8 more_popular 8 more_popular
  9 + more_comments
  10 + more_views
9 ) 11 )
10 12
11 def per_page 13 def per_page
@@ -36,6 +38,18 @@ class BrowseController &lt; PublicController @@ -36,6 +38,18 @@ class BrowseController &lt; PublicController
36 @results = @results.compact.paginate(:per_page => per_page, :page => params[:page]) 38 @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
37 end 39 end
38 40
  41 + def contents
  42 + @filter = filter
  43 + @title = self.filter_description(params[:action] + '_' + @filter )
  44 +
  45 + @results = @environment.articles.published.text_articles.send(@filter)
  46 +
  47 + if !params[:query].blank?
  48 + @results = @results.find_by_contents(params[:query])
  49 + end
  50 + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
  51 + end
  52 +
39 protected 53 protected
40 54
41 def filter 55 def filter
@@ -54,6 +68,9 @@ class BrowseController &lt; PublicController @@ -54,6 +68,9 @@ class BrowseController &lt; PublicController
54 'communities_more_recent' => _('More recent communities'), 68 'communities_more_recent' => _('More recent communities'),
55 'communities_more_active' => _('More active communities'), 69 'communities_more_active' => _('More active communities'),
56 'communities_more_popular' => _('More popular communities'), 70 'communities_more_popular' => _('More popular communities'),
  71 + 'contents_more_recent' => _('More recent contents'),
  72 + 'contents_more_views' => _('Most viewed contents'),
  73 + 'contents_more_comments' => _('Most commented contents'),
57 }[str] || str 74 }[str] || str
58 end 75 end
59 76
app/controllers/public/catalog_controller.rb
@@ -4,10 +4,11 @@ class CatalogController &lt; PublicController @@ -4,10 +4,11 @@ class CatalogController &lt; PublicController
4 before_filter :check_enterprise_and_environment 4 before_filter :check_enterprise_and_environment
5 5
6 def index 6 def index
7 - @products = @profile.products.paginate(:per_page => 10, :page => params[:page]) 7 + @products = @profile.products.paginate(:order => 'name asc', :per_page => 9, :page => params[:page])
8 end 8 end
9 9
10 protected 10 protected
  11 +
11 def check_enterprise_and_environment 12 def check_enterprise_and_environment
12 unless @profile.kind_of?(Enterprise) && !@profile.environment.enabled?('disable_products_for_enterprises') 13 unless @profile.kind_of?(Enterprise) && !@profile.environment.enabled?('disable_products_for_enterprises')
13 redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index' 14 redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index'
app/controllers/public/content_viewer_controller.rb
@@ -31,14 +31,6 @@ class ContentViewerController &lt; ApplicationController @@ -31,14 +31,6 @@ class ContentViewerController &lt; ApplicationController
31 end 31 end
32 end 32 end
33 33
34 - if !@page.public? && !request.ssl?  
35 - return if redirect_to_ssl  
36 - end  
37 -  
38 - if @page.public?  
39 - return unless avoid_ssl  
40 - end  
41 -  
42 if !@page.display_to?(user) 34 if !@page.display_to?(user)
43 if profile.display_info_to?(user) || !profile.visible? 35 if profile.display_info_to?(user) || !profile.visible?
44 message = _('You are not allowed to view this content. You can contact the owner of this profile to request access then.') 36 message = _('You are not allowed to view this content. You can contact the owner of this profile to request access then.')
@@ -54,7 +46,7 @@ class ContentViewerController &lt; ApplicationController @@ -54,7 +46,7 @@ class ContentViewerController &lt; ApplicationController
54 return 46 return
55 end 47 end
56 48
57 - redirect_to_translation 49 + redirect_to_translation if @page.profile.redirect_l10n
58 50
59 # At this point the page will be showed 51 # At this point the page will be showed
60 @page.hit 52 @page.hit
@@ -119,7 +111,11 @@ class ContentViewerController &lt; ApplicationController @@ -119,7 +111,11 @@ class ContentViewerController &lt; ApplicationController
119 def add_comment 111 def add_comment
120 @comment.author = user if logged_in? 112 @comment.author = user if logged_in?
121 @comment.article = @page 113 @comment.article = @page
122 - if (logged_in? || @comment.reply_of_id || verify_recaptcha(:model => @comment, :message => _('Please type the words correctly'))) && @comment.save 114 + @comment.ip_address = request.remote_ip
  115 + plugins_filter_comment(@comment)
  116 + return if @comment.rejected?
  117 + if (pass_without_comment_captcha? || verify_recaptcha(:model => @comment, :message => _('Please type the words correctly'))) && @comment.save
  118 + plugins_comment_saved(@comment)
123 @page.touch 119 @page.touch
124 @comment = nil # clear the comment form 120 @comment = nil # clear the comment form
125 redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view] 121 redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view]
@@ -128,6 +124,23 @@ class ContentViewerController &lt; ApplicationController @@ -128,6 +124,23 @@ class ContentViewerController &lt; ApplicationController
128 end 124 end
129 end 125 end
130 126
  127 + def plugins_filter_comment(comment)
  128 + @plugins.each do |plugin|
  129 + plugin.filter_comment(comment)
  130 + end
  131 + end
  132 +
  133 + def plugins_comment_saved(comment)
  134 + @plugins.each do |plugin|
  135 + plugin.comment_saved(comment)
  136 + end
  137 + end
  138 +
  139 + def pass_without_comment_captcha?
  140 + logged_in? && !environment.enabled?('captcha_for_logged_users')
  141 + end
  142 + helper_method :pass_without_comment_captcha?
  143 +
131 def remove_comment 144 def remove_comment
132 @comment = @page.comments.find(params[:remove_comment]) 145 @comment = @page.comments.find(params[:remove_comment])
133 if (user == @comment.author || user == @page.profile || user.has_permission?(:moderate_comments, @page.profile)) 146 if (user == @comment.author || user == @page.profile || user.has_permission?(:moderate_comments, @page.profile))
app/controllers/public/enterprise_registration_controller.rb
1 class EnterpriseRegistrationController < ApplicationController 1 class EnterpriseRegistrationController < ApplicationController
2 2
3 - require_ssl  
4 3
5 before_filter :login_required 4 before_filter :login_required
6 5
app/controllers/public/home_controller.rb
@@ -14,4 +14,8 @@ class HomeController &lt; PublicController @@ -14,4 +14,8 @@ class HomeController &lt; PublicController
14 end 14 end
15 end 15 end
16 16
  17 + def terms
  18 + @no_design_blocks = true
  19 + end
  20 +
17 end 21 end
app/controllers/public/profile_controller.rb
@@ -23,7 +23,7 @@ class ProfileController &lt; PublicController @@ -23,7 +23,7 @@ class ProfileController &lt; PublicController
23 23
24 def tags 24 def tags
25 @tags_cache_key = "tags_profile_#{profile.id.to_s}" 25 @tags_cache_key = "tags_profile_#{profile.id.to_s}"
26 - if is_cache_expired?(@tags_cache_key, true) 26 + if is_cache_expired?(@tags_cache_key)
27 @tags = profile.article_tags 27 @tags = profile.article_tags
28 end 28 end
29 end 29 end
@@ -31,7 +31,7 @@ class ProfileController &lt; PublicController @@ -31,7 +31,7 @@ class ProfileController &lt; PublicController
31 def content_tagged 31 def content_tagged
32 @tag = params[:id] 32 @tag = params[:id]
33 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_#{profile.id.to_s}_page_#{params[:npage]}" 33 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_#{profile.id.to_s}_page_#{params[:npage]}"
34 - if is_cache_expired?(@tag_cache_key, true) 34 + if is_cache_expired?(@tag_cache_key)
35 @tagged = profile.find_tagged_with(@tag).paginate(:per_page => 20, :page => params[:npage]) 35 @tagged = profile.find_tagged_with(@tag).paginate(:per_page => 20, :page => params[:npage])
36 end 36 end
37 end 37 end
@@ -211,7 +211,8 @@ class ProfileController &lt; PublicController @@ -211,7 +211,8 @@ class ProfileController &lt; PublicController
211 211
212 def remove_activity 212 def remove_activity
213 begin 213 begin
214 - activity = current_person.tracked_actions.find(params[:activity_id]) 214 + raise if !can_edit_profile
  215 + activity = ActionTracker::Record.find(params[:activity_id])
215 activity.destroy 216 activity.destroy
216 render :text => _('Activity successfully removed.') 217 render :text => _('Activity successfully removed.')
217 rescue 218 rescue
@@ -219,6 +220,17 @@ class ProfileController &lt; PublicController @@ -219,6 +220,17 @@ class ProfileController &lt; PublicController
219 end 220 end
220 end 221 end
221 222
  223 + def remove_notification
  224 + begin
  225 + raise if !can_edit_profile
  226 + notification = ActionTrackerNotification.find(:first, :conditions => {:profile_id => profile.id, :action_tracker_id => params[:activity_id]})
  227 + notification.destroy
  228 + render :text => _('Notification successfully removed.')
  229 + rescue
  230 + render :text => _('You could not remove this notification.')
  231 + end
  232 + end
  233 +
222 def profile_info 234 def profile_info
223 begin 235 begin
224 @block = profile.blocks.find(params[:block_id]) 236 @block = profile.blocks.find(params[:block_id])
@@ -320,4 +332,8 @@ class ProfileController &lt; PublicController @@ -320,4 +332,8 @@ class ProfileController &lt; PublicController
320 20 332 20
321 end 333 end
322 334
  335 + def can_edit_profile
  336 + @can_edit_profile ||= user && user.has_permission?('edit_profile', profile)
  337 + end
  338 + helper_method :can_edit_profile
323 end 339 end
app/controllers/public/search_controller.rb
@@ -207,7 +207,7 @@ class SearchController &lt; PublicController @@ -207,7 +207,7 @@ class SearchController &lt; PublicController
207 207
208 def tags 208 def tags
209 @tags_cache_key = "tags_env_#{environment.id.to_s}" 209 @tags_cache_key = "tags_env_#{environment.id.to_s}"
210 - if is_cache_expired?(@tags_cache_key, true) 210 + if is_cache_expired?(@tags_cache_key)
211 @tags = environment.tag_counts 211 @tags = environment.tag_counts
212 end 212 end
213 end 213 end
@@ -215,7 +215,7 @@ class SearchController &lt; PublicController @@ -215,7 +215,7 @@ class SearchController &lt; PublicController
215 def tag 215 def tag
216 @tag = params[:tag] 216 @tag = params[:tag]
217 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}" 217 @tag_cache_key = "tag_#{CGI.escape(@tag.to_s)}_env_#{environment.id.to_s}_page_#{params[:npage]}"
218 - if is_cache_expired?(@tag_cache_key, true) 218 + if is_cache_expired?(@tag_cache_key)
219 @tagged = environment.articles.find_tagged_with(@tag).paginate(:per_page => 10, :page => params[:npage]) 219 @tagged = environment.articles.find_tagged_with(@tag).paginate(:per_page => 10, :page => params[:npage])
220 end 220 end
221 end 221 end
app/controllers/public_controller.rb
1 class PublicController < ApplicationController 1 class PublicController < ApplicationController
2 - refuse_ssl  
3 end 2 end
app/helpers/account_helper.rb
1 module AccountHelper 1 module AccountHelper
2 2
  3 + def validation_classes
  4 + 'available unavailable valid invalid checking'
  5 + end
  6 +
  7 + def checking_message(key)
  8 + case key
  9 + when :url
  10 + _('Checking availability of login name...')
  11 + when :email
  12 + _('Checking if e-mail address is already taken...')
  13 + end
  14 + end
3 end 15 end
app/helpers/application_helper.rb
  1 +require 'redcloth'
  2 +
1 # Methods added to this helper will be available to all templates in the 3 # Methods added to this helper will be available to all templates in the
2 # application. 4 # application.
3 module ApplicationHelper 5 module ApplicationHelper
@@ -95,7 +97,7 @@ module ApplicationHelper @@ -95,7 +97,7 @@ module ApplicationHelper
95 text = content_tag('div', button + content_tag('div', content_tag('div', content) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box') 97 text = content_tag('div', button + content_tag('div', content_tag('div', content) + close_button, :class => 'help_message', :id => help_id, :style => 'display: none;'), :class => 'help_box')
96 98
97 unless block.nil? 99 unless block.nil?
98 - concat(text, block.binding) 100 + concat(text)
99 end 101 end
100 102
101 text 103 text
@@ -256,7 +258,7 @@ module ApplicationHelper @@ -256,7 +258,7 @@ module ApplicationHelper
256 end 258 end
257 259
258 def button_bar(options = {}, &block) 260 def button_bar(options = {}, &block)
259 - concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options)), block.binding) 261 + concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options)))
260 end 262 end
261 263
262 VIEW_EXTENSIONS = %w[.rhtml .html.erb] 264 VIEW_EXTENSIONS = %w[.rhtml .html.erb]
@@ -538,7 +540,7 @@ module ApplicationHelper @@ -538,7 +540,7 @@ module ApplicationHelper
538 {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}}, 540 {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}},
539 {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}}, 541 {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}},
540 {_('Join') => {:href => url_for(profile.join_url), :class => 'join-community', :style => 'display: none'}}, 542 {_('Join') => {:href => url_for(profile.join_url), :class => 'join-community', :style => 'display: none'}},
541 - {_('Leave') => {:href => url_for(profile.leave_url), :class => 'leave-community', :style => 'display: none'}}, 543 + {_('Leave community') => {:href => url_for(profile.leave_url), :class => 'leave-community', :style => 'display: none'}},
542 {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}} 544 {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}
543 ] 545 ]
544 elsif profile.kind_of?(Enterprise) 546 elsif profile.kind_of?(Enterprise)
@@ -587,19 +589,20 @@ module ApplicationHelper @@ -587,19 +589,20 @@ module ApplicationHelper
587 589
588 def gravatar_url_for(email, options = {}) 590 def gravatar_url_for(email, options = {})
589 # Ta dando erro de roteamento 591 # Ta dando erro de roteamento
590 - url_for( { :gravatar_id => Digest::MD5.hexdigest(email), 592 + default = theme_option['gravatar'] || NOOSFERO_CONF['gravatar'] || nil
  593 + url_for( { :gravatar_id => Digest::MD5.hexdigest(email.to_s),
591 :host => 'www.gravatar.com', 594 :host => 'www.gravatar.com',
592 :protocol => 'http://', 595 :protocol => 'http://',
593 :only_path => false, 596 :only_path => false,
594 :controller => 'avatar.php', 597 :controller => 'avatar.php',
595 - :d => NOOSFERO_CONF['gravatar'] ? NOOSFERO_CONF['gravatar'] : nil 598 + :d => default
596 }.merge(options) ) 599 }.merge(options) )
597 end 600 end
598 601
599 def str_gravatar_url_for(email, options = {}) 602 def str_gravatar_url_for(email, options = {})
600 - default = NOOSFERO_CONF['gravatar'] ? NOOSFERO_CONF['gravatar'] : nil 603 + default = theme_option['gravatar'] || NOOSFERO_CONF['gravatar'] || nil
601 url = 'http://www.gravatar.com/avatar.php?gravatar_id=' + 604 url = 'http://www.gravatar.com/avatar.php?gravatar_id=' +
602 - Digest::MD5.hexdigest(email) 605 + Digest::MD5.hexdigest(email.to_s)
603 { 606 {
604 :only_path => false, 607 :only_path => false,
605 :d => default 608 :d => default
@@ -609,6 +612,10 @@ module ApplicationHelper @@ -609,6 +612,10 @@ module ApplicationHelper
609 url 612 url
610 end 613 end
611 614
  615 + def gravatar_profile_url(email)
  616 + 'http://www.gravatar.com/'+ Digest::MD5.hexdigest(email.to_s)
  617 + end
  618 +
612 attr_reader :environment 619 attr_reader :environment
613 def select_categories(object_name, title=nil, title_size=4) 620 def select_categories(object_name, title=nil, title_size=4)
614 return nil if environment.enabled?(:disable_categories) 621 return nil if environment.enabled?(:disable_categories)
@@ -753,7 +760,7 @@ module ApplicationHelper @@ -753,7 +760,7 @@ module ApplicationHelper
753 760
754 # Should be on the forms_helper file but when its there the translation of labels doesn't work 761 # Should be on the forms_helper file but when its there the translation of labels doesn't work
755 class NoosferoFormBuilder < ActionView::Helpers::FormBuilder 762 class NoosferoFormBuilder < ActionView::Helpers::FormBuilder
756 - extend ActionView::Helpers::TagHelper 763 + extend ActionView::Helpers::TagHelper
757 764
758 def self.output_field(text, field_html, field_id = nil) 765 def self.output_field(text, field_html, field_id = nil)
759 # try to guess an id if none given 766 # try to guess an id if none given
@@ -775,7 +782,7 @@ module ApplicationHelper @@ -775,7 +782,7 @@ module ApplicationHelper
775 (field_helpers - %w(hidden_field)).each do |selector| 782 (field_helpers - %w(hidden_field)).each do |selector|
776 src = <<-END_SRC 783 src = <<-END_SRC
777 def #{selector}(field, *args, &proc) 784 def #{selector}(field, *args, &proc)
778 - text = object.class.human_attribute_name(field.to_s) 785 + text = object.class.respond_to?(:human_attribute_name) && object.class.human_attribute_name(field.to_s) || field.to_s.humanize
779 NoosferoFormBuilder::output_field(text, super) 786 NoosferoFormBuilder::output_field(text, super)
780 end 787 end
781 END_SRC 788 END_SRC
@@ -877,7 +884,7 @@ module ApplicationHelper @@ -877,7 +884,7 @@ module ApplicationHelper
877 end 884 end
878 885
879 if block 886 if block
880 - concat(result, block.binding) 887 + concat(result)
881 end 888 end
882 889
883 result 890 result
@@ -909,18 +916,11 @@ module ApplicationHelper @@ -909,18 +916,11 @@ module ApplicationHelper
909 916
910 def login_url 917 def login_url
911 options = Noosfero.url_options.merge({ :controller => 'account', :action => 'login' }) 918 options = Noosfero.url_options.merge({ :controller => 'account', :action => 'login' })
912 - if environment.enable_ssl && (ENV['RAILS_ENV'] != 'development')  
913 - options.merge!(:protocol => 'https://', :host => ssl_hostname)  
914 - end  
915 url_for(options) 919 url_for(options)
916 end 920 end
917 921
918 - def ssl_hostname  
919 - environment.default_hostname  
920 - end  
921 -  
922 def base_url 922 def base_url
923 - environment.top_url(request.ssl?) 923 + environment.top_url
924 end 924 end
925 925
926 def helper_for_article(article) 926 def helper_for_article(article)
@@ -985,7 +985,7 @@ module ApplicationHelper @@ -985,7 +985,7 @@ module ApplicationHelper
985 'thickbox', 985 'thickbox',
986 'lightbox', 986 'lightbox',
987 'colorpicker', 987 'colorpicker',
988 - colorbox_stylesheet_path, 988 + 'colorbox',
989 pngfix_stylesheet_path, 989 pngfix_stylesheet_path,
990 ] + 990 ] +
991 tokeninput_stylesheets 991 tokeninput_stylesheets
@@ -1000,10 +1000,6 @@ module ApplicationHelper @@ -1000,10 +1000,6 @@ module ApplicationHelper
1000 'iepngfix/iepngfix.css' 1000 'iepngfix/iepngfix.css'
1001 end 1001 end
1002 1002
1003 - def colorbox_stylesheet_path  
1004 - 'colorbox/colorbox.css'  
1005 - end  
1006 -  
1007 def tokeninput_stylesheets 1003 def tokeninput_stylesheets
1008 ['token-input', 'token-input-facebook', 'token-input-mac'] 1004 ['token-input', 'token-input-facebook', 'token-input-mac']
1009 end 1005 end
@@ -1024,7 +1020,7 @@ module ApplicationHelper @@ -1024,7 +1020,7 @@ module ApplicationHelper
1024 options.merge!(:page => params[:npage]) 1020 options.merge!(:page => params[:npage])
1025 content = article.to_html(options) 1021 content = article.to_html(options)
1026 content = content.kind_of?(Proc) ? self.instance_eval(&content) : content 1022 content = content.kind_of?(Proc) ? self.instance_eval(&content) : content
1027 - @plugins && @plugins.enabled_plugins.each do |plugin| 1023 + @plugins && @plugins.each do |plugin|
1028 content = plugin.parse_content(content) 1024 content = plugin.parse_content(content)
1029 end 1025 end
1030 content 1026 content
@@ -1134,15 +1130,26 @@ module ApplicationHelper @@ -1134,15 +1130,26 @@ module ApplicationHelper
1134 link_to(content_tag(:span, _('Communities Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger') 1130 link_to(content_tag(:span, _('Communities Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger')
1135 end 1131 end
1136 1132
  1133 + def browse_contents_menu
  1134 + links = [
  1135 + {s_('contents|More Comments') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_comments'})}},
  1136 + {s_('contents|More Views') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_views'})}},
  1137 + {s_('contents|More Recent') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_recent'})}}
  1138 + ]
  1139 +
  1140 + link_to(content_tag(:span, _('Contents'), :class => 'icon-blog'), {:controller => "browse", :action => 'contents'}, :id => 'submenu-contents') +
  1141 + link_to(content_tag(:span, _('Contents Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-contents-trigger')
  1142 + end
  1143 +
1137 def pagination_links(collection, options={}) 1144 def pagination_links(collection, options={})
1138 - options = {:prev_label => '&laquo; ' + _('Previous'), :next_label => _('Next') + ' &raquo;'}.merge(options) 1145 + options = {:previous_label => '&laquo; ' + _('Previous'), :next_label => _('Next') + ' &raquo;'}.merge(options)
1139 will_paginate(collection, options) 1146 will_paginate(collection, options)
1140 end 1147 end
1141 1148
1142 def render_environment_features(folder) 1149 def render_environment_features(folder)
1143 result = '' 1150 result = ''
1144 environment.enabled_features.keys.each do |feature| 1151 environment.enabled_features.keys.each do |feature|
1145 - file = File.join(@controller.view_paths, 'shared', folder.to_s, "#{feature}.rhtml") 1152 + file = File.join(@controller.view_paths.last, 'shared', folder.to_s, "#{feature}.rhtml")
1146 if File.exists?(file) 1153 if File.exists?(file)
1147 result << render(:file => file, :use_full_path => false) 1154 result << render(:file => file, :use_full_path => false)
1148 end 1155 end
@@ -1166,7 +1173,7 @@ module ApplicationHelper @@ -1166,7 +1173,7 @@ module ApplicationHelper
1166 pending_tasks_count = link_to(count.to_s, @environment.top_url + '/myprofile/{login}/tasks', :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) 1173 pending_tasks_count = link_to(count.to_s, @environment.top_url + '/myprofile/{login}/tasks', :id => 'pending-tasks-count', :title => _("Manage your pending tasks"))
1167 end 1174 end
1168 1175
1169 - (_('Welcome, %s') % link_to('<i></i><strong>{login}</strong>', @environment.top_url + '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) + 1176 + (_("<span class='welcome'>Welcome,</span> %s") % link_to('<i></i><strong>{login}</strong>', @environment.top_url + '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) +
1170 render_environment_features(:usermenu) + 1177 render_environment_features(:usermenu) +
1171 link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', @environment.top_url + '/admin', :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + 1178 link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', @environment.top_url + '/admin', :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') +
1172 manage_enterprises.to_s + 1179 manage_enterprises.to_s +
@@ -1226,7 +1233,7 @@ module ApplicationHelper @@ -1226,7 +1233,7 @@ module ApplicationHelper
1226 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content') 1233 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content')
1227 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") } 1234 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") }
1228 classes = options.delete(:class) || options.delete("class") || '' 1235 classes = options.delete(:class) || options.delete("class") || ''
1229 - concat(content_tag('div', wrapper + tag('br', :style => 'clear: both;'), { :class => 'comment-balloon ' + classes.to_s }.merge(options)), block.binding) 1236 + concat(content_tag('div', wrapper + tag('br', :style => 'clear: both;'), { :class => 'comment-balloon ' + classes.to_s }.merge(options)))
1230 end 1237 end
1231 1238
1232 def display_source_info(page) 1239 def display_source_info(page)
@@ -1247,25 +1254,27 @@ module ApplicationHelper @@ -1247,25 +1254,27 @@ module ApplicationHelper
1247 task.information[:message] % values 1254 task.information[:message] % values
1248 end 1255 end
1249 1256
  1257 + def add_zoom_to_article_images
  1258 + add_zoom_to_images if environment.enabled?(:show_zoom_button_on_article_images)
  1259 + end
  1260 +
1250 def add_zoom_to_images 1261 def add_zoom_to_images
1251 - if environment.enabled?(:show_zoom_button_on_article_images)  
1252 - stylesheet_link_tag('fancybox') +  
1253 - javascript_include_tag('jquery.fancybox-1.3.4.pack') +  
1254 - javascript_tag("jQuery(function($) {  
1255 - $(window).load( function() {  
1256 - $('#article .article-body img').each( function(index) {  
1257 - var original = original_image_dimensions($(this).attr('src'));  
1258 - if ($(this).width() < original['width'] || $(this).height() < original['height']) {  
1259 - $(this).wrap('<div class=\"zoomable-image\" />');  
1260 - $(this).parent('.zoomable-image').attr('style', $(this).attr('style'));  
1261 - $(this).attr('style', '');  
1262 - $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>');  
1263 - }  
1264 - });  
1265 - $('.zoomify-image').fancybox(); 1262 + stylesheet_link_tag('fancybox') +
  1263 + javascript_include_tag('jquery.fancybox-1.3.4.pack') +
  1264 + javascript_tag("jQuery(function($) {
  1265 + $(window).load( function() {
  1266 + $('#article .article-body img').each( function(index) {
  1267 + var original = original_image_dimensions($(this).attr('src'));
  1268 + if ($(this).width() < original['width'] || $(this).height() < original['height']) {
  1269 + $(this).wrap('<div class=\"zoomable-image\" />');
  1270 + $(this).parent('.zoomable-image').attr('style', $(this).attr('style'));
  1271 + $(this).attr('style', '');
  1272 + $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>');
  1273 + }
1266 }); 1274 });
1267 - });" % _('Zoom in'))  
1268 - end 1275 + $('.zoomify-image').fancybox();
  1276 + });
  1277 + });" % _('Zoom in'))
1269 end 1278 end
1270 1279
1271 def render_dialog_error_messages(instance_name) 1280 def render_dialog_error_messages(instance_name)
@@ -1303,4 +1312,29 @@ module ApplicationHelper @@ -1303,4 +1312,29 @@ module ApplicationHelper
1303 ) + content_tag('span', ' | ', :class => 'comment-footer comment-footer-hide') 1312 ) + content_tag('span', ' | ', :class => 'comment-footer comment-footer-hide')
1304 end 1313 end
1305 end 1314 end
  1315 +
  1316 + def cache_timeout(key, timeout, &block)
  1317 + cache(key, { :expires_in => timeout }, &block)
  1318 + end
  1319 +
  1320 + def is_cache_expired?(key)
  1321 + !cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller))
  1322 + end
  1323 +
  1324 + def render_tabs(tabs)
  1325 + titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }
  1326 + contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }
  1327 +
  1328 + content_tag :div, :class => 'ui-tabs' do
  1329 + content_tag(:ul, titles) + contents
  1330 + end
  1331 + end
  1332 +
  1333 + def delete_article_message(article)
  1334 + if article.folder?
  1335 + _("Are you sure that you want to remove the folder \"#{article.name}\"? Note that all the items inside it will also be removed!")
  1336 + else
  1337 + _("Are you sure that you want to remove the item \"#{article.name}\"?")
  1338 + end
  1339 + end
1306 end 1340 end
app/helpers/blog_helper.rb
@@ -17,7 +17,7 @@ module BlogHelper @@ -17,7 +17,7 @@ module BlogHelper
17 def list_posts(articles, format = 'full') 17 def list_posts(articles, format = 'full')
18 pagination = will_paginate(articles, { 18 pagination = will_paginate(articles, {
19 :param_name => 'npage', 19 :param_name => 'npage',
20 - :prev_label => _('&laquo; Newer posts'), 20 + :previous_label => _('&laquo; Newer posts'),
21 :next_label => _('Older posts &raquo;') 21 :next_label => _('Older posts &raquo;')
22 }) 22 })
23 content = [] 23 content = []
app/helpers/boxes_helper.rb
@@ -81,8 +81,8 @@ module BoxesHelper @@ -81,8 +81,8 @@ module BoxesHelper
81 box_decorator == DontMoveBlocks 81 box_decorator == DontMoveBlocks
82 end 82 end
83 83
84 - def display_block_content(block, main_content = nil)  
85 - content = block.main? ? wrap_main_content(main_content) : block.content 84 + def display_block_content(block, person, main_content = nil)
  85 + content = block.main? ? wrap_main_content(main_content) : block.content({:person => person})
86 result = extract_block_content(content) 86 result = extract_block_content(content)
87 footer_content = extract_block_content(block.footer) 87 footer_content = extract_block_content(block.footer)
88 unless footer_content.blank? 88 unless footer_content.blank?
@@ -99,7 +99,7 @@ module BoxesHelper @@ -99,7 +99,7 @@ module BoxesHelper
99 unless block.visible? 99 unless block.visible?
100 options[:title] = _("This block is invisible. Your visitors will not see it.") 100 options[:title] = _("This block is invisible. Your visitors will not see it.")
101 end 101 end
102 - @controller.send(:content_editor?) || @plugins.enabled_plugins.each do |plugin| 102 + @controller.send(:content_editor?) || @plugins.each do |plugin|
103 result = plugin.parse_content(result) 103 result = plugin.parse_content(result)
104 end 104 end
105 box_decorator.block_target(block.box, block) + 105 box_decorator.block_target(block.box, block) +
app/helpers/catalog_helper.rb
1 module CatalogHelper 1 module CatalogHelper
2 2
3 -include DisplayHelper  
4 -include ManageProductsHelper 3 + include DisplayHelper
  4 + include ManageProductsHelper
5 5
6 - def display_products_list(profile, products)  
7 - data = ''  
8 - extra_content = []  
9 - extra_content_list = []  
10 - products.each { |product|  
11 - extra_content = @plugins.map(:catalog_item_extras, product).collect { |content| instance_eval(&content) } if @plugins  
12 - extra_content_list = @plugins.map(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } if @plugins  
13 - data << content_tag('li',  
14 - link_to_product(product, :class => 'product-pic', :style => 'background-image:url(%s)' % product.default_image(:portrait) ) +  
15 - content_tag('h3', link_to_product(product)) +  
16 - content_tag('ul',  
17 - (product.price ? content_tag('li', _('Price: %s') % ( "%.2f" % product.price), :class => 'product_price') : '') +  
18 - content_tag('li', product_category_name(profile, product.product_category), :class => 'product_category') +  
19 - extra_content_list.map { |content| content_tag('li', content)}.join("\n")  
20 - ) +  
21 - (product.description ? content_tag('div',  
22 - txt2html(product.description),  
23 - :class => 'description') : tag('br',  
24 - :style => 'clear:both')) +  
25 - extra_content.join("\n"),  
26 - :class => 'product')  
27 - }  
28 - content_tag('h1', _('Products/Services')) + content_tag('ul', data, :id => 'product_list')  
29 - end  
30 -  
31 - private  
32 -  
33 - def product_category_name(profile, product_category)  
34 - if profile.enabled?  
35 - link_to_product_category(product_category)  
36 - else  
37 - product_category ? product_category.full_name(' &rarr; ') : _('Uncategorized product')  
38 - end  
39 - end  
40 end 6 end
app/helpers/cms_helper.rb
@@ -16,7 +16,7 @@ module CmsHelper @@ -16,7 +16,7 @@ module CmsHelper
16 end 16 end
17 17
18 def pagination_links(collection, options={}) 18 def pagination_links(collection, options={})
19 - options = {:prev_label => '&laquo; ', :next_label => ' &raquo;', :page_links => false}.merge(options) 19 + options = {:previous_label => '&laquo; ', :next_label => ' &raquo;', :page_links => false}.merge(options)
20 will_paginate(collection, options) 20 will_paginate(collection, options)
21 end 21 end
22 22
@@ -49,12 +49,6 @@ module CmsHelper @@ -49,12 +49,6 @@ module CmsHelper
49 end 49 end
50 50
51 def display_delete_button(article) 51 def display_delete_button(article)
52 - confirm_message = if article.folder?  
53 - _('Are you sure that you want to remove this folder? Note that all the items inside it will also be removed!')  
54 - else  
55 - _('Are you sure that you want to remove this item?')  
56 - end  
57 -  
58 - button_without_text :delete, _('Delete'), { :action => 'destroy', :id => article.id }, :method => :post, :confirm => confirm_message 52 + button_without_text :delete, _('Delete'), { :action => 'destroy', :id => article.id }, :method => :post, :confirm => delete_article_message(article)
59 end 53 end
60 end 54 end
app/helpers/content_viewer_helper.rb
@@ -55,7 +55,7 @@ module ContentViewerHelper @@ -55,7 +55,7 @@ module ContentViewerHelper
55 "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % { 55 "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % {
56 :title => CGI.escape(article.title), 56 :title => CGI.escape(article.title),
57 :url => CGI.escape(url_for(article.url)), 57 :url => CGI.escape(url_for(article.url)),
58 - :summary => CGI.escape(truncate(strip_tags(article.body.to_s), 300)), 58 + :summary => CGI.escape(truncate(strip_tags(article.body.to_s), :length => 300)),
59 :image => CGI.escape(article.body_images_paths.first.to_s) 59 :image => CGI.escape(article.body_images_paths.first.to_s)
60 } 60 }
61 end 61 end
app/helpers/dates_helper.rb
@@ -42,11 +42,11 @@ module DatesHelper @@ -42,11 +42,11 @@ module DatesHelper
42 end 42 end
43 end 43 end
44 44
45 - def show_period(date1, date2 = nil) 45 + def show_period(date1, date2 = nil, use_numbers = false)
46 if (date1 == date2) || (date2.nil?) 46 if (date1 == date2) || (date2.nil?)
47 - show_date(date1) 47 + show_date(date1, use_numbers)
48 else 48 else
49 - _('from %{date1} to %{date2}') % {:date1 => show_date(date1), :date2 => show_date(date2)} 49 + _('from %{date1} to %{date2}') % {:date1 => show_date(date1, use_numbers), :date2 => show_date(date2, use_numbers)}
50 end 50 end
51 end 51 end
52 52
app/helpers/display_helper.rb
@@ -8,6 +8,20 @@ module DisplayHelper @@ -8,6 +8,20 @@ module DisplayHelper
8 opts 8 opts
9 end 9 end
10 10
  11 + def image_link_to_product(product, opts={})
  12 + return _('No product') unless product
  13 + target = product_path(product)
  14 + link_to image_tag(product.default_image(:big), :alt => product.name),
  15 + target,
  16 + opts
  17 + end
  18 +
  19 + def price_span(price, options = {})
  20 + content_tag 'span',
  21 + number_to_currency(price, :unit => environment.currency_unit, :delimiter => environment.currency_delimiter, :separator => environment.currency_separator),
  22 + options
  23 + end
  24 +
11 def product_path(product) 25 def product_path(product)
12 product.enterprise.enabled? ? product.enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => product) : product.enterprise.url 26 product.enterprise.enabled? ? product.enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => product) : product.enterprise.url
13 end 27 end
app/helpers/forms_helper.rb
@@ -14,9 +14,9 @@ module FormsHelper @@ -14,9 +14,9 @@ module FormsHelper
14 14
15 def labelled_check_box( human_name, name, value = "1", checked = false, options = {} ) 15 def labelled_check_box( human_name, name, value = "1", checked = false, options = {} )
16 options[:id] ||= 'checkbox-' + FormsHelper.next_id_number 16 options[:id] ||= 'checkbox-' + FormsHelper.next_id_number
17 - check_box_tag( name, value, checked, options ) +  
18 - content_tag( 'label', human_name, :for => options[:id] ) +  
19 - hidden_field_tag(name, '0') 17 + hidden_field_tag(name, '0') +
  18 + check_box_tag( name, value, checked, options ) +
  19 + content_tag( 'label', human_name, :for => options[:id] )
20 end 20 end
21 21
22 def labelled_text_field( human_name, name, value=nil, options={} ) 22 def labelled_text_field( human_name, name, value=nil, options={} )
app/helpers/forum_helper.rb
@@ -11,7 +11,7 @@ module ForumHelper @@ -11,7 +11,7 @@ module ForumHelper
11 def list_forum_posts(articles) 11 def list_forum_posts(articles)
12 pagination = will_paginate(articles, { 12 pagination = will_paginate(articles, {
13 :param_name => 'npage', 13 :param_name => 'npage',
14 - :prev_label => _('&laquo; Newer posts'), 14 + :previous_label => _('&laquo; Newer posts'),
15 :next_label => _('Older posts &raquo;') 15 :next_label => _('Older posts &raquo;')
16 }) 16 })
17 content = [content_tag('tr', 17 content = [content_tag('tr',
app/helpers/manage_products_helper.rb
@@ -55,7 +55,7 @@ module ManageProductsHelper @@ -55,7 +55,7 @@ module ManageProductsHelper
55 def options_for_select_categories(categories, selected = nil) 55 def options_for_select_categories(categories, selected = nil)
56 categories.sort_by{|cat| cat.name.transliterate}.map do |category| 56 categories.sort_by{|cat| cat.name.transliterate}.map do |category|
57 selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '') 57 selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')
58 - "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{truncate(category.name, 33) + (category.leaf? ? '': ' &raquo;')}</option>" 58 + "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{truncate(category.name, :length => 33) + (category.leaf? ? '': ' &raquo;')}</option>"
59 end.join("\n") 59 end.join("\n")
60 end 60 end
61 61
@@ -271,4 +271,23 @@ module ManageProductsHelper @@ -271,4 +271,23 @@ module ManageProductsHelper
271 return input_amount_used if input.unit.blank? 271 return input_amount_used if input.unit.blank?
272 n_('1 %{singular_unit}', '%{num} %{plural_unit}', input.amount_used.to_f) % { :num => input_amount_used, :singular_unit => content_tag('span', input.unit.singular, :class => 'input-unit'), :plural_unit => content_tag('span', input.unit.plural, :class => 'input-unit') } 272 n_('1 %{singular_unit}', '%{num} %{plural_unit}', input.amount_used.to_f) % { :num => input_amount_used, :singular_unit => content_tag('span', input.unit.singular, :class => 'input-unit'), :plural_unit => content_tag('span', input.unit.plural, :class => 'input-unit') }
273 end 273 end
  274 +
  275 + def select_production_cost(product,selected=nil)
  276 + url = url_for( :controller => 'manage_products', :action => 'create_production_cost' )
  277 + prompt_msg = _('Insert the name of the new cost:')
  278 + error_msg = _('Something went wrong. Please, try again')
  279 + select_tag('price_details[][production_cost_id]',
  280 + '<option value="" disabled="disabled">' + _('Select...') + '</option>' +
  281 + options_for_select(product.available_production_costs.map {|item| [truncate(item.name, 10, '...'), item.id]} + [[_('Other cost'), '']], selected),
  282 + {:class => 'production-cost-selection',
  283 + :onchange => "productionCostTypeChange(this, '#{url}', '#{prompt_msg}', '#{error_msg}')"})
  284 + end
  285 +
  286 + def price_composition_progressbar_text(product, args = {})
  287 + currency = environment.currency_unit
  288 + production_cost = args[:production_cost_value] || product.formatted_value(:total_production_cost)
  289 + product_price = args[:product_price] || product.formatted_value(:price)
  290 +
  291 + _("%{currency} %{production_cost} of %{currency} %{product_price}") % {:currency => currency, :production_cost => content_tag('span', production_cost, :class => 'production_cost'), :product_price => content_tag('span', product_price, :class => 'product_price')}
  292 + end
274 end 293 end
app/helpers/profile_editor_helper.rb
@@ -137,8 +137,8 @@ module ProfileEditorHelper @@ -137,8 +137,8 @@ module ProfileEditorHelper
137 content_tag( 137 content_tag(
138 'div', 138 'div',
139 capture(&block) + '<br style="clear:left;"/>&nbsp;', 139 capture(&block) + '<br style="clear:left;"/>&nbsp;',
140 - :class => 'control-panel'),  
141 - block.binding) 140 + :class => 'control-panel')
  141 + )
142 end 142 end
143 143
144 def control_panel_button(title, icon, url) 144 def control_panel_button(title, icon, url)
app/helpers/profile_helper.rb
@@ -15,12 +15,4 @@ module ProfileHelper @@ -15,12 +15,4 @@ module ProfileHelper
15 end 15 end
16 end 16 end
17 17
18 - def render_tabs(tabs)  
19 - titles = tabs.inject(''){ |result, tab| result << content_tag(:li, link_to(tab[:title], '#'+tab[:id]), :class => 'tab') }  
20 - contents = tabs.inject(''){ |result, tab| result << content_tag(:div, tab[:content], :id => tab[:id]) }  
21 -  
22 - content_tag :div, :class => 'ui-tabs' do  
23 - content_tag(:ul, titles) + contents  
24 - end  
25 - end  
26 end 18 end
app/helpers/sweeper_helper.rb
@@ -4,9 +4,7 @@ module SweeperHelper @@ -4,9 +4,7 @@ module SweeperHelper
4 ActionController::Base.new().expire_fragment(*args) 4 ActionController::Base.new().expire_fragment(*args)
5 end 5 end
6 6
7 - def expire_timeout_fragment(*args)  
8 - ActionController::Base.new().expire_timeout_fragment(*args)  
9 - end 7 + alias :expire_timeout_fragment :expire_fragment
10 8
11 def expire_friends(profile) 9 def expire_friends(profile)
12 # public friends page 10 # public friends page
@@ -22,7 +20,7 @@ module SweeperHelper @@ -22,7 +20,7 @@ module SweeperHelper
22 20
23 # friends blocks 21 # friends blocks
24 blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} 22 blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)}
25 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 23 + BlockSweeper.expire_blocks(blocks)
26 end 24 end
27 25
28 def expire_communities(profile) 26 def expire_communities(profile)
@@ -34,13 +32,13 @@ module SweeperHelper @@ -34,13 +32,13 @@ module SweeperHelper
34 32
35 # communities block 33 # communities block
36 blocks = profile.blocks.select{|b| b.kind_of?(CommunitiesBlock)} 34 blocks = profile.blocks.select{|b| b.kind_of?(CommunitiesBlock)}
37 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 35 + BlockSweeper.expire_blocks(blocks)
38 end 36 end
39 37
40 def expire_enterprises(profile) 38 def expire_enterprises(profile)
41 # enterprises and favorite enterprises blocks 39 # enterprises and favorite enterprises blocks
42 blocks = profile.blocks.select {|b| [EnterprisesBlock, FavoriteEnterprisesBlock].any?{|klass| b.kind_of?(klass)} } 40 blocks = profile.blocks.select {|b| [EnterprisesBlock, FavoriteEnterprisesBlock].any?{|klass| b.kind_of?(klass)} }
43 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 41 + BlockSweeper.expire_blocks(blocks)
44 end 42 end
45 43
46 def expire_profile_index(profile) 44 def expire_profile_index(profile)
app/helpers/tags_helper.rb
@@ -50,7 +50,7 @@ module TagsHelper @@ -50,7 +50,7 @@ module TagsHelper
50 style = ""+ 50 style = ""+
51 "font-size: #{ (v * delta).round + min_size }px;"+ 51 "font-size: #{ (v * delta).round + min_size }px;"+
52 "top: #{ -(delta/2) - (v * (delta/2)).round }px;" 52 "top: #{ -(delta/2) - (v * (delta/2)).round }px;"
53 - destination = url.kind_of?(Hash) ? url_for(url.merge(tagname_option => tag)) : (url.to_s + tag) 53 + destination = url.merge(tagname_option => tag)
54 54
55 if options[:show_count] 55 if options[:show_count]
56 display_count = options[:show_count] ? "<small><sup>(#{count})</sup></small>" : "" 56 display_count = options[:show_count] ? "<small><sup>(#{count})</sup></small>" : ""
app/models/add_member.rb
@@ -11,7 +11,9 @@ class AddMember &lt; Task @@ -11,7 +11,9 @@ class AddMember &lt; Task
11 settings_items :roles 11 settings_items :roles
12 12
13 def perform 13 def perform
14 - self.roles ||= [Profile::Roles.member(organization.environment.id).id] 14 + if !self.roles or (self.roles.uniq.compact.length == 1 and self.roles.uniq.compact.first.to_i.zero?)
  15 + self.roles = [Profile::Roles.member(organization.environment.id).id]
  16 + end
15 target.affiliate(requestor, self.roles.select{|r| !r.to_i.zero? }.map{|i| Role.find(i)}) 17 target.affiliate(requestor, self.roles.select{|r| !r.to_i.zero? }.map{|i| Role.find(i)})
16 end 18 end
17 19
app/models/article.rb
@@ -13,7 +13,7 @@ class Article &lt; ActiveRecord::Base @@ -13,7 +13,7 @@ class Article &lt; ActiveRecord::Base
13 validates_presence_of :profile_id, :name 13 validates_presence_of :profile_id, :name
14 validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? } 14 validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? }
15 15
16 - validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('<!-- %{fn} -->The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } 16 + validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? }
17 17
18 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' 18 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
19 19
@@ -34,7 +34,7 @@ class Article &lt; ActiveRecord::Base @@ -34,7 +34,7 @@ class Article &lt; ActiveRecord::Base
34 before_destroy :rotate_translations 34 before_destroy :rotate_translations
35 35
36 before_create do |article| 36 before_create do |article|
37 - article.published_at = article.created_at if article.published_at.nil? 37 + article.published_at ||= Time.now
38 if article.reference_article && !article.parent 38 if article.reference_article && !article.parent
39 parent = article.reference_article.parent 39 parent = article.reference_article.parent
40 if parent && parent.blog? && article.profile.has_blog? 40 if parent && parent.blog? && article.profile.has_blog?
@@ -233,7 +233,7 @@ class Article &lt; ActiveRecord::Base @@ -233,7 +233,7 @@ class Article &lt; ActiveRecord::Base
233 233
234 include ActionView::Helpers::TextHelper 234 include ActionView::Helpers::TextHelper
235 def short_title 235 def short_title
236 - truncate self.title, 15, '...' 236 + truncate self.title, :length => 15, :omission => '...'
237 end 237 end
238 238
239 def belongs_to_blog? 239 def belongs_to_blog?
@@ -355,11 +355,20 @@ class Article &lt; ActiveRecord::Base @@ -355,11 +355,20 @@ class Article &lt; ActiveRecord::Base
355 ['Folder', 'Blog', 'Forum', 'Gallery'] 355 ['Folder', 'Blog', 'Forum', 'Gallery']
356 end 356 end
357 357
  358 + def self.text_article_types
  359 + ['TextArticle', 'TextileArticle', 'TinyMceArticle']
  360 + end
  361 +
358 named_scope :published, :conditions => { :published => true } 362 named_scope :published, :conditions => { :published => true }
359 named_scope :folders, :conditions => { :type => folder_types} 363 named_scope :folders, :conditions => { :type => folder_types}
360 named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types] 364 named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types]
361 named_scope :galleries, :conditions => { :type => 'Gallery' } 365 named_scope :galleries, :conditions => { :type => 'Gallery' }
362 named_scope :images, :conditions => { :is_image => true } 366 named_scope :images, :conditions => { :is_image => true }
  367 + named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ]
  368 +
  369 + named_scope :more_comments, :order => "comments_count DESC"
  370 + named_scope :more_views, :order => "hits DESC"
  371 + named_scope :more_recent, :order => "created_at DESC"
363 372
364 def self.display_filter(user, profile) 373 def self.display_filter(user, profile)
365 return {:conditions => ['published = ?', true]} if !user 374 return {:conditions => ['published = ?', true]} if !user
@@ -487,8 +496,8 @@ class Article &lt; ActiveRecord::Base @@ -487,8 +496,8 @@ class Article &lt; ActiveRecord::Base
487 end 496 end
488 497
489 alias :active_record_cache_key :cache_key 498 alias :active_record_cache_key :cache_key
490 - def cache_key(params = {}, the_profile = nil)  
491 - active_record_cache_key + 499 + def cache_key(params = {}, the_profile = nil, language = 'en')
  500 + active_record_cache_key+'-'+language +
492 (allow_post_content?(the_profile) ? "-owner" : '') + 501 (allow_post_content?(the_profile) ? "-owner" : '') +
493 (params[:npage] ? "-npage-#{params[:npage]}" : '') + 502 (params[:npage] ? "-npage-#{params[:npage]}" : '') +
494 (params[:year] ? "-year-#{params[:year]}" : '') + 503 (params[:year] ? "-year-#{params[:year]}" : '') +
@@ -505,7 +514,7 @@ class Article &lt; ActiveRecord::Base @@ -505,7 +514,7 @@ class Article &lt; ActiveRecord::Base
505 end 514 end
506 515
507 def short_lead 516 def short_lead
508 - truncate sanitize_html(self.lead), 170, '...' 517 + truncate sanitize_html(self.lead), :length => 170, :omission => '...'
509 end 518 end
510 519
511 def creator 520 def creator
@@ -528,6 +537,28 @@ class Article &lt; ActiveRecord::Base @@ -528,6 +537,28 @@ class Article &lt; ActiveRecord::Base
528 end 537 end
529 end 538 end
530 539
  540 + def more_comments_label
  541 + amount = self.comments_count
  542 + {
  543 + 0 => _('no comments'),
  544 + 1 => _('one comment')
  545 + }[amount] || _("%s comments") % amount
  546 +
  547 + end
  548 +
  549 + def more_views_label
  550 + amount = self.hits
  551 + {
  552 + 0 => _('no views'),
  553 + 1 => _('one view')
  554 + }[amount] || _("%s views") % amount
  555 +
  556 + end
  557 +
  558 + def more_recent_label
  559 + _('Created at: ')
  560 + end
  561 +
531 private 562 private
532 563
533 def sanitize_tag_list 564 def sanitize_tag_list
app/models/article_block.rb
@@ -8,7 +8,7 @@ class ArticleBlock &lt; Block @@ -8,7 +8,7 @@ class ArticleBlock &lt; Block
8 _('This block displays one of your articles. You can edit the block to select which one of your articles is going to be displayed in the block.') 8 _('This block displays one of your articles. You can edit the block to select which one of your articles is going to be displayed in the block.')
9 end 9 end
10 10
11 - def content 11 + def content(args={})
12 block = self 12 block = self
13 lambda do 13 lambda do
14 block_title(block.title) + 14 block_title(block.title) +
app/models/block.rb
@@ -81,7 +81,7 @@ class Block &lt; ActiveRecord::Base @@ -81,7 +81,7 @@ class Block &lt; ActiveRecord::Base
81 # The method can also return <tt>nil</tt>, which means "no content". 81 # The method can also return <tt>nil</tt>, which means "no content".
82 # 82 #
83 # See BoxesHelper#extract_block_content for implementation details. 83 # See BoxesHelper#extract_block_content for implementation details.
84 - def content 84 + def content(args={})
85 "This is block number %d" % self.id 85 "This is block number %d" % self.id
86 end 86 end
87 87
@@ -127,6 +127,11 @@ class Block &lt; ActiveRecord::Base @@ -127,6 +127,11 @@ class Block &lt; ActiveRecord::Base
127 true 127 true
128 end 128 end
129 129
  130 + alias :active_record_cache_key :cache_key
  131 + def cache_key(language='en')
  132 + active_record_cache_key+'-'+language
  133 + end
  134 +
130 def timeout 135 def timeout
131 4.hours 136 4.hours
132 end 137 end
app/models/blog.rb
@@ -68,7 +68,7 @@ class Blog &lt; Folder @@ -68,7 +68,7 @@ class Blog &lt; Folder
68 settings_items :visualization_format, :type => :string, :default => 'full' 68 settings_items :visualization_format, :type => :string, :default => 'full'
69 validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format 69 validates_inclusion_of :visualization_format, :in => [ 'full', 'short' ], :if => :visualization_format
70 70
71 - settings_items :display_posts_in_current_language, :type => :boolean, :default => true 71 + settings_items :display_posts_in_current_language, :type => :boolean, :default => false
72 72
73 alias :display_posts_in_current_language? :display_posts_in_current_language 73 alias :display_posts_in_current_language? :display_posts_in_current_language
74 74
app/models/blog_archives_block.rb
@@ -20,11 +20,15 @@ class BlogArchivesBlock &lt; Block @@ -20,11 +20,15 @@ class BlogArchivesBlock &lt; Block
20 blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog 20 blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog
21 end 21 end
22 22
23 - def content 23 + def visible_posts(person)
  24 + blog.posts.native_translations.select {|post| post.display_to?(person)}
  25 + end
  26 +
  27 + def content(args={})
24 owner_blog = self.blog 28 owner_blog = self.blog
25 return nil unless owner_blog 29 return nil unless owner_blog
26 results = '' 30 results = ''
27 - owner_blog.posts.native_translations.group_by {|i| i.published_at.year }.sort_by { |year,count| -year }.each do |year, results_by_year| 31 + visible_posts(args[:person]).group_by {|i| i.published_at.year }.sort_by { |year,count| -year }.each do |year, results_by_year|
28 results << content_tag('li', content_tag('strong', "#{year} (#{results_by_year.size})")) 32 results << content_tag('li', content_tag('strong', "#{year} (#{results_by_year.size})"))
29 results << "<ul class='#{year}-archive'>" 33 results << "<ul class='#{year}-archive'>"
30 results_by_year.group_by{|i| [ ('%02d' % i.published_at.month()), gettext(MONTHS[i.published_at.month() - 1])]}.sort.reverse.each do |month, results_by_month| 34 results_by_year.group_by{|i| [ ('%02d' % i.published_at.month()), gettext(MONTHS[i.published_at.month() - 1])]}.sort.reverse.each do |month, results_by_month|
app/models/categories_block.rb
@@ -28,7 +28,7 @@ class CategoriesBlock &lt; Block @@ -28,7 +28,7 @@ class CategoriesBlock &lt; Block
28 Category.top_level_for(self.owner).from_types(self.category_types) 28 Category.top_level_for(self.owner).from_types(self.category_types)
29 end 29 end
30 30
31 - def content 31 + def content(args={})
32 block = self 32 block = self
33 lambda do 33 lambda do
34 render :file => 'blocks/categories', :locals => { :block => block } 34 render :file => 'blocks/categories', :locals => { :block => block }
app/models/category.rb
1 class Category < ActiveRecord::Base 1 class Category < ActiveRecord::Base
2 2
3 - validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.') 3 + validates_exclusion_of :slug, :in => [ 'index' ], :message => N_('%{fn} cannot be like that.').fix_i18n
4 validates_presence_of :name, :environment_id 4 validates_presence_of :name, :environment_id
5 - validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.') 5 + validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('%{fn} is already being used by another category.').fix_i18n
6 belongs_to :environment 6 belongs_to :environment
7 7
8 validates_inclusion_of :display_color, :in => [ 1, 2, 3, 4, nil ] 8 validates_inclusion_of :display_color, :in => [ 1, 2, 3, 4, nil ]
9 - validates_uniqueness_of :display_color, :scope => :environment_id, :if => (lambda { |cat| ! cat.display_color.nil? }), :message => N_('%{fn} was already assigned to another category.') 9 + validates_uniqueness_of :display_color, :scope => :environment_id, :if => (lambda { |cat| ! cat.display_color.nil? }), :message => N_('%{fn} was already assigned to another category.').fix_i18n
10 10
11 # Finds all top level categories for a given environment. 11 # Finds all top level categories for a given environment.
12 named_scope :top_level_for, lambda { |environment| 12 named_scope :top_level_for, lambda { |environment|
app/models/change_password.rb
@@ -30,10 +30,10 @@ class ChangePassword &lt; Task @@ -30,10 +30,10 @@ class ChangePassword &lt; Task
30 unless data.login.blank? || data.email.blank? 30 unless data.login.blank? || data.email.blank?
31 user = User.find_by_login_and_environment_id(data.login, data.environment_id) 31 user = User.find_by_login_and_environment_id(data.login, data.environment_id)
32 if user.nil? 32 if user.nil?
33 - data.errors.add(:login, _('%{fn} is not a valid username.')) 33 + data.errors.add(:login, _('%{fn} is not a valid username.').fix_i18n)
34 else 34 else
35 if user.email != data.email 35 if user.email != data.email
36 - data.errors.add(:email, _('%{fn} is invalid.')) 36 + data.errors.add(:email)
37 end 37 end
38 end 38 end
39 end 39 end
app/models/comment.rb
@@ -2,7 +2,7 @@ class Comment &lt; ActiveRecord::Base @@ -2,7 +2,7 @@ class Comment &lt; ActiveRecord::Base
2 2
3 track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target 3 track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target
4 4
5 - validates_presence_of :title, :body 5 + validates_presence_of :body
6 belongs_to :article, :counter_cache => true 6 belongs_to :article, :counter_cache => true
7 belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' 7 belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id'
8 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy 8 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy
@@ -17,7 +17,7 @@ class Comment &lt; ActiveRecord::Base @@ -17,7 +17,7 @@ class Comment &lt; ActiveRecord::Base
17 validates_presence_of :author_id, :if => (lambda { |rec| rec.name.blank? && rec.email.blank? }) 17 validates_presence_of :author_id, :if => (lambda { |rec| rec.name.blank? && rec.email.blank? })
18 validates_each :name do |rec,attribute,value| 18 validates_each :name do |rec,attribute,value|
19 if rec.author_id && (!rec.name.blank? || !rec.email.blank?) 19 if rec.author_id && (!rec.name.blank? || !rec.email.blank?)
20 - rec.errors.add(:name, _('%{fn} can only be informed for unauthenticated authors')) 20 + rec.errors.add(:name, _('%{fn} can only be informed for unauthenticated authors').fix_i18n)
21 end 21 end
22 end 22 end
23 23
@@ -126,4 +126,12 @@ class Comment &lt; ActiveRecord::Base @@ -126,4 +126,12 @@ class Comment &lt; ActiveRecord::Base
126 end 126 end
127 end 127 end
128 128
  129 + def rejected?
  130 + @rejected
  131 + end
  132 +
  133 + def reject!
  134 + @rejected = true
  135 + end
  136 +
129 end 137 end
app/models/community.rb
@@ -34,7 +34,7 @@ class Community &lt; Organization @@ -34,7 +34,7 @@ class Community &lt; Organization
34 super 34 super
35 self.required_fields.each do |field| 35 self.required_fields.each do |field|
36 if self.send(field).blank? 36 if self.send(field).blank?
37 - self.errors.add(field, _('%{fn} can\'t be blank')) 37 + self.errors.add_on_blank(field)
38 end 38 end
39 end 39 end
40 end 40 end
app/models/create_community.rb
@@ -16,7 +16,7 @@ class CreateCommunity &lt; Task @@ -16,7 +16,7 @@ class CreateCommunity &lt; Task
16 def validate 16 def validate
17 self.environment.required_community_fields.each do |field| 17 self.environment.required_community_fields.each do |field|
18 if self.send(field).blank? 18 if self.send(field).blank?
19 - self.errors.add(field, _('%{fn} can\'t be blank')) 19 + self.errors.add_on_blank(field)
20 end 20 end
21 end 21 end
22 end 22 end
app/models/create_enterprise.rb
@@ -40,12 +40,12 @@ class CreateEnterprise &lt; Task @@ -40,12 +40,12 @@ class CreateEnterprise &lt; Task
40 40
41 if self.region && self.target 41 if self.region && self.target
42 unless self.region.validators.include?(self.target) || self.target_type == "Environment" 42 unless self.region.validators.include?(self.target) || self.target_type == "Environment"
43 - self.errors.add(:target, '%{fn} is not a validator for the chosen region') 43 + self.errors.add(:target, _('%{fn} is not a validator for the chosen region').fix_i18n)
44 end 44 end
45 end 45 end
46 46
47 if self.status != Task::Status::CANCELLED && self.identifier && Profile.exists?(:identifier => self.identifier) 47 if self.status != Task::Status::CANCELLED && self.identifier && Profile.exists?(:identifier => self.identifier)
48 - self.errors.add(:identifier, '%{fn} is already being as identifier by another enterprise, organization or person.') 48 + self.errors.add(:identifier, _('%{fn} is already being as identifier by another enterprise, organization or person.').fix_i18n)
49 end 49 end
50 end 50 end
51 51
app/models/disabled_enterprise_message_block.rb
@@ -12,7 +12,7 @@ class DisabledEnterpriseMessageBlock &lt; Block @@ -12,7 +12,7 @@ class DisabledEnterpriseMessageBlock &lt; Block
12 _('Message') 12 _('Message')
13 end 13 end
14 14
15 - def content 15 + def content(args={})
16 message = self.owner.environment.message_for_disabled_enterprise || '' 16 message = self.owner.environment.message_for_disabled_enterprise || ''
17 lambda do 17 lambda do
18 render :file => 'blocks/disabled_enterprise_message', :locals => {:message => message} 18 render :file => 'blocks/disabled_enterprise_message', :locals => {:message => message}
app/models/domain.rb
@@ -10,14 +10,14 @@ class Domain &lt; ActiveRecord::Base @@ -10,14 +10,14 @@ class Domain &lt; ActiveRecord::Base
10 10
11 # <tt>name</tt> must be a sequence of word characters (a to z, plus 0 to 9, 11 # <tt>name</tt> must be a sequence of word characters (a to z, plus 0 to 9,
12 # plus '_'). Letters must be lowercase 12 # plus '_'). Letters must be lowercase
13 - validates_format_of :name, :with => /^([a-z0-9_-]+\.)+[a-z0-9_-]+$/, :message => N_('%{fn} must be composed only of lowercase latters (a to z), numbers (0 to 9), "_" and "-"') 13 + validates_format_of :name, :with => /^([a-z0-9_-]+\.)+[a-z0-9_-]+$/, :message => N_('%{fn} must be composed only of lowercase latters (a to z), numbers (0 to 9), "_" and "-"').fix_i18n
14 14
15 # checks validations that could not be expressed using Rails' predefined 15 # checks validations that could not be expressed using Rails' predefined
16 # validations. In particular: 16 # validations. In particular:
17 # * <tt>name</tt> must not start with 'www.' 17 # * <tt>name</tt> must not start with 'www.'
18 def validate 18 def validate
19 if self.name =~ /^www\./ 19 if self.name =~ /^www\./
20 - self.errors.add(:name, _('%{fn} must not start with www.')) 20 + self.errors.add(:name, _('%{fn} must not start with www.').fix_i18n)
21 end 21 end
22 end 22 end
23 23
app/models/enterprise.rb
@@ -6,6 +6,7 @@ class Enterprise &lt; Organization @@ -6,6 +6,7 @@ class Enterprise &lt; Organization
6 6
7 has_many :products, :dependent => :destroy, :order => 'name ASC' 7 has_many :products, :dependent => :destroy, :order => 'name ASC'
8 has_many :inputs, :through => :products 8 has_many :inputs, :through => :products
  9 + has_many :production_costs, :as => :owner
9 10
10 has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people' 11 has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people'
11 12
@@ -45,7 +46,7 @@ class Enterprise &lt; Organization @@ -45,7 +46,7 @@ class Enterprise &lt; Organization
45 super 46 super
46 self.required_fields.each do |field| 47 self.required_fields.each do |field|
47 if self.send(field).blank? 48 if self.send(field).blank?
48 - self.errors.add(field, _("%{fn} can't be blank")) 49 + self.errors.add_on_blank(field)
49 end 50 end
50 end 51 end
51 end 52 end
@@ -75,7 +76,11 @@ class Enterprise &lt; Organization @@ -75,7 +76,11 @@ class Enterprise &lt; Organization
75 end 76 end
76 77
77 after_save do |e| 78 after_save do |e|
78 - e.products.each{ |p| p.enterprise_updated(e) } 79 + e.delay.update_products_position
  80 + end
  81 +
  82 + def update_products_position
  83 + products.each{ |p| p.enterprise_updated(self) }
79 end 84 end
80 85
81 def closed? 86 def closed?
app/models/enterprise_homepage.rb
@@ -12,18 +12,13 @@ class EnterpriseHomepage &lt; Article @@ -12,18 +12,13 @@ class EnterpriseHomepage &lt; Article
12 profile.nil? ? _('Homepage') : profile.name 12 profile.nil? ? _('Homepage') : profile.name
13 end 13 end
14 14
15 - # FIXME isn't this too much including just to be able to generate some HTML?  
16 - include ActionView::Helpers::TagHelper  
17 - include ActionView::Helpers::UrlHelper  
18 - include ActionController::UrlWriter  
19 - include ActionView::Helpers::AssetTagHelper  
20 - include EnterpriseHomepageHelper  
21 - include CatalogHelper  
22 -  
23 - def to_html(options ={})  
24 - products = self.profile.products  
25 - display_profile_info(self.profile) + content_tag('div', self.body || '') +  
26 - (self.profile.environment.enabled?('disable_products_for_enterprises') ? '' : display_products_list(self.profile, products)) 15 + def to_html(options = {})
  16 + enterprise_homepage = self
  17 + lambda do
  18 + extend EnterpriseHomepageHelper
  19 + @products = profile.products.paginate(:order => 'id asc', :per_page => 9, :page => 1)
  20 + render :partial => 'content_viewer/enterprise_homepage', :object => enterprise_homepage
  21 + end
27 end 22 end
28 23
29 def can_display_hits? 24 def can_display_hits?
app/models/environment.rb
@@ -120,7 +120,8 @@ class Environment &lt; ActiveRecord::Base @@ -120,7 +120,8 @@ class Environment &lt; ActiveRecord::Base
120 'enterprises_are_validated_when_created' => __('Enterprises are validated when created'), 120 'enterprises_are_validated_when_created' => __('Enterprises are validated when created'),
121 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'), 121 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'),
122 'xmpp_chat' => _('XMPP/Jabber based chat'), 122 'xmpp_chat' => _('XMPP/Jabber based chat'),
123 - 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images') 123 + 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images'),
  124 + 'captcha_for_logged_users' => _('Ask captcha when a logged user comments too'),
124 } 125 }
125 end 126 end
126 127
@@ -174,6 +175,7 @@ class Environment &lt; ActiveRecord::Base @@ -174,6 +175,7 @@ class Environment &lt; ActiveRecord::Base
174 acts_as_accessible 175 acts_as_accessible
175 176
176 has_many :units, :order => 'position' 177 has_many :units, :order => 'position'
  178 + has_many :production_costs, :as => :owner
177 179
178 def superior_intances 180 def superior_intances
179 [self, nil] 181 [self, nil]
@@ -221,7 +223,6 @@ class Environment &lt; ActiveRecord::Base @@ -221,7 +223,6 @@ class Environment &lt; ActiveRecord::Base
221 settings_items :layout_template, :type => String, :default => 'default' 223 settings_items :layout_template, :type => String, :default => 'default'
222 settings_items :homepage, :type => String 224 settings_items :homepage, :type => String
223 settings_items :description, :type => String, :default => '<div style="text-align: center"><a href="http://noosfero.org/"><img src="/images/noosfero-network.png" alt="Noosfero"/></a></div>' 225 settings_items :description, :type => String, :default => '<div style="text-align: center"><a href="http://noosfero.org/"><img src="/images/noosfero-network.png" alt="Noosfero"/></a></div>'
224 - settings_items :enable_ssl  
225 settings_items :local_docs, :type => Array, :default => [] 226 settings_items :local_docs, :type => Array, :default => []
226 settings_items :news_amount_by_folder, :type => Integer, :default => 4 227 settings_items :news_amount_by_folder, :type => Integer, :default => 4
227 settings_items :help_message_to_add_enterprise, :type => String, :default => '' 228 settings_items :help_message_to_add_enterprise, :type => String, :default => ''
@@ -562,8 +563,8 @@ class Environment &lt; ActiveRecord::Base @@ -562,8 +563,8 @@ class Environment &lt; ActiveRecord::Base
562 domain 563 domain
563 end 564 end
564 565
565 - def top_url(ssl = false)  
566 - protocol = (ssl ? 'https' : 'http') 566 + def top_url
  567 + protocol = 'http'
567 result = "#{protocol}://#{default_hostname}" 568 result = "#{protocol}://#{default_hostname}"
568 if Noosfero.url_options.has_key?(:port) 569 if Noosfero.url_options.has_key?(:port)
569 result << ':' << Noosfero.url_options[:port].to_s 570 result << ':' << Noosfero.url_options[:port].to_s
app/models/environment_finder.rb
@@ -53,7 +53,7 @@ class EnvironmentFinder @@ -53,7 +53,7 @@ class EnvironmentFinder
53 # SECURITY no risk of SQL injection, since product_category_ids comes from trusted source 53 # SECURITY no risk of SQL injection, since product_category_ids comes from trusted source
54 @environment.send(asset).find_by_contents(query, ferret_options, options.merge({:include => 'product_categorizations', :conditions => 'product_categorizations.category_id = (%s)' % product_category.id })) 54 @environment.send(asset).find_by_contents(query, ferret_options, options.merge({:include => 'product_categorizations', :conditions => 'product_categorizations.category_id = (%s)' % product_category.id }))
55 elsif product_category && asset == :enterprises 55 elsif product_category && asset == :enterprises
56 - @environment.send(asset).find_by_contents(query, ferret_options, options.merge(:joins => 'inner join product_categorizations on (product_categorizations.product_id = products.id)', :include => 'products', :conditions => "product_categorizations.category_id = (#{product_category.id})")) 56 + @environment.send(asset).find_by_contents(query, ferret_options, options.merge(:joins => 'inner join products on products.enterprise_id = profiles.id inner join product_categorizations on (product_categorizations.product_id = products.id)', :conditions => "product_categorizations.category_id = (#{product_category.id})"))
57 else 57 else
58 @environment.send(asset).find_by_contents(query, ferret_options, options) 58 @environment.send(asset).find_by_contents(query, ferret_options, options)
59 end 59 end
app/models/environment_statistics_block.rb
@@ -12,7 +12,7 @@ class EnvironmentStatisticsBlock &lt; Block @@ -12,7 +12,7 @@ class EnvironmentStatisticsBlock &lt; Block
12 _('This block presents some statistics about your environment.') 12 _('This block presents some statistics about your environment.')
13 end 13 end
14 14
15 - def content 15 + def content(args={})
16 users = owner.people.visible.count 16 users = owner.people.visible.count
17 enterprises = owner.enterprises.visible.count 17 enterprises = owner.enterprises.visible.count
18 communities = owner.communities.visible.count 18 communities = owner.communities.visible.count
app/models/event.rb
@@ -22,7 +22,7 @@ class Event &lt; Article @@ -22,7 +22,7 @@ class Event &lt; Article
22 22
23 validates_each :start_date do |event,field,value| 23 validates_each :start_date do |event,field,value|
24 if event.end_date && event.start_date && event.start_date > event.end_date 24 if event.end_date && event.start_date && event.start_date > event.end_date
25 - event.errors.add(:start_date, _('%{fn} cannot come before end date.')) 25 + event.errors.add(:start_date, _('%{fn} cannot come before end date.').fix_i18n)
26 end 26 end
27 end 27 end
28 28
app/models/featured_products_block.rb
@@ -25,7 +25,7 @@ class FeaturedProductsBlock &lt; Block @@ -25,7 +25,7 @@ class FeaturedProductsBlock &lt; Block
25 self.owner.highlighted_products_with_image 25 self.owner.highlighted_products_with_image
26 end 26 end
27 27
28 - def content 28 + def content(args={})
29 block = self 29 block = self
30 lambda do 30 lambda do
31 render :file => 'blocks/featured_products', :locals => { :block => block } 31 render :file => 'blocks/featured_products', :locals => { :block => block }
app/models/feed_reader_block.rb
@@ -13,6 +13,7 @@ class FeedReaderBlock &lt; Block @@ -13,6 +13,7 @@ class FeedReaderBlock &lt; Block
13 old_address = address 13 old_address = address
14 orig_set_address(new_address) 14 orig_set_address(new_address)
15 self.enabled = (new_address && new_address != old_address) || (new_address && self.enabled) || false 15 self.enabled = (new_address && new_address != old_address) || (new_address && self.enabled) || false
  16 + self.fetched_at = nil
16 end 17 end
17 18
18 settings_items :limit, :type => :integer 19 settings_items :limit, :type => :integer
@@ -71,12 +72,13 @@ class FeedReaderBlock &lt; Block @@ -71,12 +72,13 @@ class FeedReaderBlock &lt; Block
71 self.feed_title = nil 72 self.feed_title = nil
72 self.error_message = nil 73 self.error_message = nil
73 end 74 end
  75 +
74 def finish_fetch 76 def finish_fetch
75 self.fetched_at = Time.now 77 self.fetched_at = Time.now
76 self.save! 78 self.save!
77 end 79 end
78 80
79 - def content 81 + def content(args={})
80 block_title(title) + formatted_feed_content 82 block_title(title) + formatted_feed_content
81 end 83 end
82 84
app/models/highlights_block.rb
@@ -28,7 +28,7 @@ class HighlightsBlock &lt; Block @@ -28,7 +28,7 @@ class HighlightsBlock &lt; Block
28 shuffle ? block_images.shuffle : block_images 28 shuffle ? block_images.shuffle : block_images
29 end 29 end
30 30
31 - def content 31 + def content(args={})
32 block = self 32 block = self
33 lambda do 33 lambda do
34 render :file => 'blocks/highlights', :locals => { :block => block } 34 render :file => 'blocks/highlights', :locals => { :block => block }
app/models/image.rb
@@ -9,15 +9,15 @@ class Image &lt; ActiveRecord::Base @@ -9,15 +9,15 @@ class Image &lt; ActiveRecord::Base
9 has_attachment :content_type => :image, 9 has_attachment :content_type => :image,
10 :storage => :file_system, 10 :storage => :file_system,
11 :path_prefix => 'public/image_uploads', 11 :path_prefix => 'public/image_uploads',
12 - :resize_to => '320x200>', 12 + :resize_to => '800x600>',
13 :thumbnails => { :big => '150x150', 13 :thumbnails => { :big => '150x150',
14 :thumb => '100x100', 14 :thumb => '100x100',
15 :portrait => '64x64', 15 :portrait => '64x64',
16 :minor => '50x50', 16 :minor => '50x50',
17 :icon => '20x20!' }, 17 :icon => '20x20!' },
18 - :max_size => 500.kilobytes # remember to update validate message below 18 + :max_size => 5.megabytes # remember to update validate message below
19 19
20 - validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 500.0 KB") 20 + validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n
21 21
22 delay_attachment_fu_thumbnails 22 delay_attachment_fu_thumbnails
23 23
app/models/input.rb
@@ -45,6 +45,18 @@ class Input &lt; ActiveRecord::Base @@ -45,6 +45,18 @@ class Input &lt; ActiveRecord::Base
45 %w[price_per_unit amount_used].each do |field| 45 %w[price_per_unit amount_used].each do |field|
46 return true unless self.send(field).blank? 46 return true unless self.send(field).blank?
47 end 47 end
48 - return false 48 + false
  49 + end
  50 +
  51 + def has_all_price_details?
  52 + %w[price_per_unit unit amount_used].each do |field|
  53 + return false if self.send(field).blank?
  54 + end
  55 + true
  56 + end
  57 +
  58 + def cost
  59 + return 0 if self.amount_used.blank? || self.price_per_unit.blank?
  60 + self.amount_used * self.price_per_unit
49 end 61 end
50 end 62 end
app/models/link_list_block.rb
@@ -47,7 +47,7 @@ class LinkListBlock &lt; Block @@ -47,7 +47,7 @@ class LinkListBlock &lt; Block
47 _('This block can be used to create a menu of links. You can add, remove and update the links as you wish.') 47 _('This block can be used to create a menu of links. You can add, remove and update the links as you wish.')
48 end 48 end
49 49
50 - def content 50 + def content(args={})
51 block_title(title) + 51 block_title(title) +
52 content_tag('ul', 52 content_tag('ul',
53 links.select{|i| !i[:name].blank? and !i[:address].blank?}.map{|i| content_tag('li', link_html(i))} 53 links.select{|i| !i[:name].blank? and !i[:address].blank?}.map{|i| content_tag('li', link_html(i))}
app/models/location_block.rb
@@ -11,7 +11,7 @@ class LocationBlock &lt; Block @@ -11,7 +11,7 @@ class LocationBlock &lt; Block
11 _('Shows where the profile is on the material world.') 11 _('Shows where the profile is on the material world.')
12 end 12 end
13 13
14 - def content 14 + def content(args={})
15 profile = self.owner 15 profile = self.owner
16 title = self.title 16 title = self.title
17 if profile.lat 17 if profile.lat
app/models/login_block.rb
@@ -8,7 +8,7 @@ class LoginBlock &lt; Block @@ -8,7 +8,7 @@ class LoginBlock &lt; Block
8 _('This block presents a login/logout block.') 8 _('This block presents a login/logout block.')
9 end 9 end
10 10
11 - def content 11 + def content(args={})
12 lambda do 12 lambda do
13 render :file => 'blocks/login_block' 13 render :file => 'blocks/login_block'
14 end 14 end
app/models/main_block.rb
@@ -8,7 +8,7 @@ class MainBlock &lt; Block @@ -8,7 +8,7 @@ class MainBlock &lt; Block
8 _('This block presents the main content of your pages.') 8 _('This block presents the main content of your pages.')
9 end 9 end
10 10
11 - def content 11 + def content(args={})
12 nil 12 nil
13 end 13 end
14 14
app/models/my_network_block.rb
@@ -14,7 +14,7 @@ class MyNetworkBlock &lt; Block @@ -14,7 +14,7 @@ class MyNetworkBlock &lt; Block
14 _('This block displays some info about your networking.') 14 _('This block displays some info about your networking.')
15 end 15 end
16 16
17 - def content 17 + def content(args={})
18 block = self 18 block = self
19 lambda do 19 lambda do
20 render :file => 'blocks/my_network', :locals => { 20 render :file => 'blocks/my_network', :locals => {
app/models/organization.rb
@@ -157,4 +157,8 @@ class Organization &lt; Profile @@ -157,4 +157,8 @@ class Organization &lt; Profile
157 members_by_role(role).map { |member| {:id => member.id, :name => member.name} }.to_json 157 members_by_role(role).map { |member| {:id => member.id, :name => member.name} }.to_json
158 end 158 end
159 159
  160 + def disable
  161 + self.visible = false
  162 + save!
  163 + end
160 end 164 end
app/models/person.rb
@@ -116,10 +116,17 @@ class Person &lt; Profile @@ -116,10 +116,17 @@ class Person &lt; Profile
116 contact_phone 116 contact_phone
117 contact_information 117 contact_information
118 description 118 description
  119 + image
119 ] 120 ]
120 121
121 validates_multiparameter_assignments 122 validates_multiparameter_assignments
122 123
  124 + validates_each :birth_date do |record,attr,value|
  125 + if value && value.year == 1
  126 + record.errors.add(attr)
  127 + end
  128 + end
  129 +
123 def self.fields 130 def self.fields
124 FIELDS 131 FIELDS
125 end 132 end
@@ -129,7 +136,7 @@ class Person &lt; Profile @@ -129,7 +136,7 @@ class Person &lt; Profile
129 self.required_fields.each do |field| 136 self.required_fields.each do |field|
130 if self.send(field).blank? 137 if self.send(field).blank?
131 unless (field == 'custom_area_of_study' && self.area_of_study != 'Others') || (field == 'custom_formation' && self.formation != 'Others') 138 unless (field == 'custom_area_of_study' && self.area_of_study != 'Others') || (field == 'custom_formation' && self.formation != 'Others')
132 - self.errors.add(field, _('%{fn} is mandatory')) 139 + self.errors.add_on_blank(field)
133 end 140 end
134 end 141 end
135 end 142 end
@@ -191,7 +198,7 @@ class Person &lt; Profile @@ -191,7 +198,7 @@ class Person &lt; Profile
191 198
192 validates_each :email, :on => :update do |record,attr,value| 199 validates_each :email, :on => :update do |record,attr,value|
193 if User.find(:first, :conditions => ['email = ? and id != ? and environment_id = ?', value, record.user.id, record.environment.id]) 200 if User.find(:first, :conditions => ['email = ? and id != ? and environment_id = ?', value, record.user.id, record.environment.id])
194 - record.errors.add(attr, _('%{fn} is already used by other user')) 201 + record.errors.add(attr, _('%{fn} is already used by other user').fix_i18n)
195 end 202 end
196 end 203 end
197 204
@@ -403,7 +410,15 @@ class Person &lt; Profile @@ -403,7 +410,15 @@ class Person &lt; Profile
403 end 410 end
404 411
405 def control_panel_settings_button 412 def control_panel_settings_button
406 - {:title => _('Profile Info and settings'), :icon => 'edit-profile'} 413 + {:title => _('Edit Profile'), :icon => 'edit-profile'}
  414 + end
  415 +
  416 + def disable
  417 + self.visible = false
  418 + user.password = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{identifier}--")
  419 + user.password_confirmation = user.password
  420 + save!
  421 + user.save!
407 end 422 end
408 423
409 protected 424 protected
app/models/price_detail.rb 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +class PriceDetail < ActiveRecord::Base
  2 +
  3 + belongs_to :product
  4 + validates_presence_of :product_id
  5 +
  6 + belongs_to :production_cost
  7 + validates_presence_of :production_cost_id
  8 + validates_uniqueness_of :production_cost_id, :scope => :product_id
  9 +
  10 + def price
  11 + self[:price] || 0
  12 + end
  13 +
  14 + include FloatHelper
  15 + def price=(value)
  16 + if value.is_a?(String)
  17 + super(decimal_to_float(value))
  18 + else
  19 + super(value)
  20 + end
  21 + end
  22 +
  23 + def formatted_value(value)
  24 + ("%.2f" % self[value]).to_s.gsub('.', product.enterprise.environment.currency_separator) if self[value]
  25 + end
  26 +
  27 +end
app/models/product.rb
@@ -5,6 +5,8 @@ class Product &lt; ActiveRecord::Base @@ -5,6 +5,8 @@ class Product &lt; ActiveRecord::Base
5 has_many :product_qualifiers 5 has_many :product_qualifiers
6 has_many :qualifiers, :through => :product_qualifiers 6 has_many :qualifiers, :through => :product_qualifiers
7 has_many :inputs, :dependent => :destroy, :order => 'position' 7 has_many :inputs, :dependent => :destroy, :order => 'position'
  8 + has_many :price_details, :dependent => :destroy
  9 + has_many :production_costs, :through => :price_details
8 10
9 validates_uniqueness_of :name, :scope => :enterprise_id, :allow_nil => true 11 validates_uniqueness_of :name, :scope => :enterprise_id, :allow_nil => true
10 validates_presence_of :product_category_id 12 validates_presence_of :product_category_id
@@ -101,12 +103,13 @@ class Product &lt; ActiveRecord::Base @@ -101,12 +103,13 @@ class Product &lt; ActiveRecord::Base
101 enterprise.public_profile 103 enterprise.public_profile
102 end 104 end
103 105
104 - def formatted_value(value)  
105 - ("%.2f" % self[value]).to_s.gsub('.', enterprise.environment.currency_separator) if self[value] 106 + def formatted_value(method)
  107 + value = self[method] || self.send(method)
  108 + ("%.2f" % value).to_s.gsub('.', enterprise.environment.currency_separator) if value
106 end 109 end
107 110
108 def price_with_discount 111 def price_with_discount
109 - price - discount if discount 112 + discount ? (price - discount) : price
110 end 113 end
111 114
112 def price=(value) 115 def price=(value)
@@ -125,6 +128,23 @@ class Product &lt; ActiveRecord::Base @@ -125,6 +128,23 @@ class Product &lt; ActiveRecord::Base
125 end 128 end
126 end 129 end
127 130
  131 + # Note: will probably be completely overhauled for AI1413
  132 + def inputs_prices?
  133 + return false if self.inputs.count <= 0
  134 + self.inputs.each do |input|
  135 + return false if input.has_price_details? == false
  136 + end
  137 + true
  138 + end
  139 +
  140 + def any_inputs_details?
  141 + return false if self.inputs.count <= 0
  142 + self.inputs.each do |input|
  143 + return true if input.has_all_price_details? == true
  144 + end
  145 + false
  146 + end
  147 +
128 def has_basic_info? 148 def has_basic_info?
129 %w[unit price discount].each do |field| 149 %w[unit price discount].each do |field|
130 return true if !self.send(field).blank? 150 return true if !self.send(field).blank?
@@ -153,4 +173,44 @@ class Product &lt; ActiveRecord::Base @@ -153,4 +173,44 @@ class Product &lt; ActiveRecord::Base
153 true 173 true
154 end 174 end
155 175
  176 + def inputs_cost
  177 + return 0 if inputs.empty?
  178 + inputs.map(&:cost).inject { |sum,price| sum + price }
  179 + end
  180 +
  181 + def total_production_cost
  182 + return inputs_cost if price_details.empty?
  183 + inputs_cost + price_details.map(&:price).inject { |sum,price| sum + price }
  184 + end
  185 +
  186 + def price_described?
  187 + return false if price.blank? or price == 0
  188 + (price - total_production_cost).zero?
  189 + end
  190 +
  191 + def update_price_details(price_details)
  192 + self.price_details.destroy_all
  193 + price_details.each do |price_detail|
  194 + self.price_details.create(price_detail)
  195 + end
  196 + end
  197 +
  198 + def price_description_percentage
  199 + return 0 if price.blank? || price.zero?
  200 + total_production_cost * 100 / price
  201 + end
  202 +
  203 + def available_production_costs
  204 + self.enterprise.environment.production_costs + self.enterprise.production_costs
  205 + end
  206 +
  207 + include ActionController::UrlWriter
  208 + def price_composition_bar_display_url
  209 + url_for({:host => enterprise.default_hostname, :controller => 'manage_products', :action => 'display_price_composition_bar', :profile => enterprise.identifier, :id => self.id }.merge(Noosfero.url_options))
  210 + end
  211 +
  212 + def inputs_cost_update_url
  213 + url_for({:host => enterprise.default_hostname, :controller => 'manage_products', :action => 'display_inputs_cost', :profile => enterprise.identifier, :id => self.id }.merge(Noosfero.url_options))
  214 + end
  215 +
156 end 216 end
app/models/production_cost.rb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +class ProductionCost < ActiveRecord::Base
  2 +
  3 + belongs_to :owner, :polymorphic => true
  4 + validates_presence_of :owner
  5 + validates_presence_of :name
  6 + validates_length_of :name, :maximum => 30, :allow_blank => true
  7 + validates_uniqueness_of :name, :scope => [:owner_id, :owner_type]
  8 +end
app/models/products_block.rb
@@ -16,7 +16,7 @@ class ProductsBlock &lt; Block @@ -16,7 +16,7 @@ class ProductsBlock &lt; Block
16 _('This block presents a list of your products.') 16 _('This block presents a list of your products.')
17 end 17 end
18 18
19 - def content 19 + def content(args={})
20 block_title(title) + 20 block_title(title) +
21 content_tag( 21 content_tag(
22 'ul', 22 'ul',
app/models/profile.rb
@@ -20,12 +20,16 @@ class Profile &lt; ActiveRecord::Base @@ -20,12 +20,16 @@ class Profile &lt; ActiveRecord::Base
20 find_role('editor', env_id) 20 find_role('editor', env_id)
21 end 21 end
22 def self.organization_member_roles(env_id) 22 def self.organization_member_roles(env_id)
23 - [admin(env_id), moderator(env_id), member(env_id)] 23 + all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? }
24 end 24 end
25 def self.all_roles(env_id) 25 def self.all_roles(env_id)
26 - [admin(env_id), member(env_id), moderator(env_id), owner(env_id), editor(env_id)] 26 + Role.all :conditions => { :environment_id => env_id }
  27 + end
  28 + def self.method_missing(m, *args, &block)
  29 + role = find_role(m, args[0])
  30 + return role unless role.nil?
  31 + super
27 end 32 end
28 -  
29 private 33 private
30 def self.find_role(name, env_id) 34 def self.find_role(name, env_id)
31 ::Role.find_by_key_and_environment_id("profile_#{name}", env_id) 35 ::Role.find_by_key_and_environment_id("profile_#{name}", env_id)
@@ -115,6 +119,7 @@ class Profile &lt; ActiveRecord::Base @@ -115,6 +119,7 @@ class Profile &lt; ActiveRecord::Base
115 119
116 acts_as_having_settings :field => :data 120 acts_as_having_settings :field => :data
117 121
  122 + settings_items :redirect_l10n, :type => :boolean, :default => false
118 settings_items :public_content, :type => :boolean, :default => true 123 settings_items :public_content, :type => :boolean, :default => true
119 settings_items :description 124 settings_items :description
120 125
@@ -147,6 +152,7 @@ class Profile &lt; ActiveRecord::Base @@ -147,6 +152,7 @@ class Profile &lt; ActiveRecord::Base
147 doc 152 doc
148 chat 153 chat
149 plugin 154 plugin
  155 + site
150 ] 156 ]
151 157
152 belongs_to :user 158 belongs_to :user
@@ -609,7 +615,7 @@ private :generate_url, :url_options @@ -609,7 +615,7 @@ private :generate_url, :url_options
609 include ActionView::Helpers::TextHelper 615 include ActionView::Helpers::TextHelper
610 def short_name(chars = 40) 616 def short_name(chars = 40)
611 if self[:nickname].blank? 617 if self[:nickname].blank?
612 - truncate self.name, chars, '...' 618 + truncate self.name, :length => chars, :omission => '...'
613 else 619 else
614 self[:nickname] 620 self[:nickname]
615 end 621 end
@@ -806,15 +812,10 @@ private :generate_url, :url_options @@ -806,15 +812,10 @@ private :generate_url, :url_options
806 end 812 end
807 813
808 def disable 814 def disable
809 - self.visible = false  
810 - user.password = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{identifier}--")  
811 - user.password_confirmation = user.password  
812 - save!  
813 - user.save!  
814 end 815 end
815 816
816 def control_panel_settings_button 817 def control_panel_settings_button
817 - {:title => _('Profile Info and settings'), :icon => 'edit-profile'} 818 + {:title => _('Edit Profile'), :icon => 'edit-profile'}
818 end 819 end
819 820
820 def self.identification 821 def self.identification
app/models/profile_image_block.rb
@@ -10,7 +10,7 @@ class ProfileImageBlock &lt; Block @@ -10,7 +10,7 @@ class ProfileImageBlock &lt; Block
10 _('This block presents the profile image') 10 _('This block presents the profile image')
11 end 11 end
12 12
13 - def content 13 + def content(args={})
14 block = self 14 block = self
15 s = show_name 15 s = show_name
16 lambda do 16 lambda do
app/models/profile_info_block.rb
@@ -8,7 +8,7 @@ class ProfileInfoBlock &lt; Block @@ -8,7 +8,7 @@ class ProfileInfoBlock &lt; Block
8 _('Basic information about <i>%{user}</i>: how long <i>%{user}</i> is part of <i>%{env}</i> and useful links.') % { :user => self.owner.name(), :env => self.owner.environment.name() } 8 _('Basic information about <i>%{user}</i>: how long <i>%{user}</i> is part of <i>%{env}</i> and useful links.') % { :user => self.owner.name(), :env => self.owner.environment.name() }
9 end 9 end
10 10
11 - def content 11 + def content(args={})
12 block = self 12 block = self
13 lambda do 13 lambda do
14 render :file => 'blocks/profile_info', :locals => { :block => block } 14 render :file => 'blocks/profile_info', :locals => { :block => block }
app/models/profile_list_block.rb
@@ -37,7 +37,7 @@ class ProfileListBlock &lt; Block @@ -37,7 +37,7 @@ class ProfileListBlock &lt; Block
37 _('Clicking on the people or groups will take you to their home page.') 37 _('Clicking on the people or groups will take you to their home page.')
38 end 38 end
39 39
40 - def content 40 + def content(args={})
41 profiles = self.profile_list 41 profiles = self.profile_list
42 title = self.view_title 42 title = self.view_title
43 nl = "\n" 43 nl = "\n"
app/models/profile_search_block.rb
@@ -4,7 +4,7 @@ class ProfileSearchBlock &lt; Block @@ -4,7 +4,7 @@ class ProfileSearchBlock &lt; Block
4 _('Display a form to search the profile') 4 _('Display a form to search the profile')
5 end 5 end
6 6
7 - def content 7 + def content(args={})
8 title = self.title 8 title = self.title
9 lambda do 9 lambda do
10 render :file => 'blocks/profile_search', :locals => { :title => title } 10 render :file => 'blocks/profile_search', :locals => { :title => title }
app/models/raw_html_block.rb
@@ -6,7 +6,7 @@ class RawHTMLBlock &lt; Block @@ -6,7 +6,7 @@ class RawHTMLBlock &lt; Block
6 6
7 settings_items :html, :type => :text 7 settings_items :html, :type => :text
8 8
9 - def content 9 + def content(args={})
10 (title.blank? ? '' : block_title(title)) + html.to_s 10 (title.blank? ? '' : block_title(title)) + html.to_s
11 end 11 end
12 12
app/models/recent_documents_block.rb
@@ -15,7 +15,7 @@ class RecentDocumentsBlock &lt; Block @@ -15,7 +15,7 @@ class RecentDocumentsBlock &lt; Block
15 settings_items :limit, :type => :integer, :default => 5 15 settings_items :limit, :type => :integer, :default => 5
16 16
17 include ActionController::UrlWriter 17 include ActionController::UrlWriter
18 - def content 18 + def content(args={})
19 docs = self.limit.nil? ? owner.recent_documents : owner.recent_documents(self.limit) 19 docs = self.limit.nil? ? owner.recent_documents : owner.recent_documents(self.limit)
20 20
21 block_title(title) + 21 block_title(title) +
app/models/sellers_search_block.rb
@@ -16,7 +16,7 @@ class SellersSearchBlock &lt; Block @@ -16,7 +16,7 @@ class SellersSearchBlock &lt; Block
16 _('This block presents a search engine for products.') 16 _('This block presents a search engine for products.')
17 end 17 end
18 18
19 - def content 19 + def content(args={})
20 title = self.title 20 title = self.title
21 lambda do 21 lambda do
22 render :file => 'search/_sellers_form', :locals => { :title => title } 22 render :file => 'search/_sellers_form', :locals => { :title => title }
app/models/slideshow_block.rb
@@ -31,7 +31,7 @@ class SlideshowBlock &lt; Block @@ -31,7 +31,7 @@ class SlideshowBlock &lt; Block
31 gallery.images.reject {|item| item.folder?} 31 gallery.images.reject {|item| item.folder?}
32 end 32 end
33 33
34 - def content 34 + def content(args={})
35 block = self 35 block = self
36 if gallery 36 if gallery
37 images = block_images 37 images = block_images
app/models/tags_block.rb
@@ -19,7 +19,7 @@ class TagsBlock &lt; Block @@ -19,7 +19,7 @@ class TagsBlock &lt; Block
19 Try to add some tags to some articles and you'l see your tag cloud growing.") 19 Try to add some tags to some articles and you'l see your tag cloud growing.")
20 end 20 end
21 21
22 - def content 22 + def content(args={})
23 tags = owner.article_tags 23 tags = owner.article_tags
24 return '' if tags.empty? 24 return '' if tags.empty?
25 25
app/models/theme.rb
@@ -43,8 +43,11 @@ class Theme @@ -43,8 +43,11 @@ class Theme
43 43
44 def approved_themes(owner) 44 def approved_themes(owner)
45 Dir.glob(File.join(system_themes_dir, '*')).select do |item| 45 Dir.glob(File.join(system_themes_dir, '*')).select do |item|
46 - config = YAML.load_file(File.join(item, 'theme.yml'))  
47 - (config['owner_type'] == owner.class.base_class.name) && (config['owner_id'] == owner.id) || config['public'] 46 + if File.exists?( File.join(item, 'theme.yml') )
  47 + config = YAML.load_file(File.join(item, 'theme.yml'))
  48 + (config['owner_type'] == owner.class.base_class.name) &&
  49 + (config['owner_id'] == owner.id) || config['public']
  50 + end
48 end.map do |desc| 51 end.map do |desc|
49 new(File.basename(desc)) 52 new(File.basename(desc))
50 end 53 end
app/models/uploaded_file.rb
@@ -50,7 +50,7 @@ class UploadedFile &lt; Article @@ -50,7 +50,7 @@ class UploadedFile &lt; Article
50 :thumbnail_class => Thumbnail, 50 :thumbnail_class => Thumbnail,
51 :max_size => 5.megabytes # remember to update validate message below 51 :max_size => 5.megabytes # remember to update validate message below
52 52
53 - validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 5.0 MB") 53 + validates_attachment :size => N_("%{fn} of uploaded file was larger than the maximum size of 5.0 MB").fix_i18n
54 54
55 delay_attachment_fu_thumbnails 55 delay_attachment_fu_thumbnails
56 56
app/models/user.rb
@@ -100,7 +100,7 @@ class User &lt; ActiveRecord::Base @@ -100,7 +100,7 @@ class User &lt; ActiveRecord::Base
100 before_save :encrypt_password 100 before_save :encrypt_password
101 validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|user| !user.email.blank?}) 101 validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|user| !user.email.blank?})
102 102
103 - validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('%{fn} must be checked in order to signup.') 103 + validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('%{fn} must be checked in order to signup.').fix_i18n
104 104
105 # Authenticates a user by their login name and unencrypted password. Returns the user or nil. 105 # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
106 def self.authenticate(login, password, environment = nil) 106 def self.authenticate(login, password, environment = nil)
app/sweepers/article_sweeper.rb
@@ -13,15 +13,11 @@ class ArticleSweeper &lt; ActiveRecord::Observer @@ -13,15 +13,11 @@ class ArticleSweeper &lt; ActiveRecord::Observer
13 protected 13 protected
14 14
15 def expire_caches(article) 15 def expire_caches(article)
16 - article.hierarchy.each do |a|  
17 - if a != article  
18 - a.touch  
19 - end  
20 - end 16 + article.hierarchy.each { |a| a.touch if a != article }
21 blocks = article.profile.blocks 17 blocks = article.profile.blocks
22 blocks += article.profile.environment.blocks if article.profile.environment 18 blocks += article.profile.environment.blocks if article.profile.environment
23 blocks = blocks.select{|b|[RecentDocumentsBlock, BlogArchivesBlock].any?{|c| b.kind_of?(c)}} 19 blocks = blocks.select{|b|[RecentDocumentsBlock, BlogArchivesBlock].any?{|c| b.kind_of?(c)}}
24 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 20 + BlockSweeper.expire_blocks(blocks)
25 env = article.profile.environment 21 env = article.profile.environment
26 if env && (env.portal_community == article.profile) 22 if env && (env.portal_community == article.profile)
27 expire_fragment(env.portal_news_cache_key) 23 expire_fragment(env.portal_news_cache_key)
app/sweepers/block_sweeper.rb 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +class BlockSweeper < ActiveRecord::Observer
  2 +
  3 + observe :block
  4 +
  5 + class << self
  6 + include SweeperHelper
  7 +
  8 + def cache_key_regex(block)
  9 + regex = '-[a-z]*$'
  10 + clean_ck = block.cache_key.gsub(/#{regex}/,'')
  11 + %r{#{clean_ck+regex}}
  12 + end
  13 +
  14 + # Expire block's all languages cache
  15 + def expire_block(block)
  16 + expire_timeout_fragment(cache_key_regex(block))
  17 + end
  18 +
  19 + def expire_blocks(blocks)
  20 + blocks.each { |block| expire_block(block) }
  21 + end
  22 + end
  23 +
  24 + def after_save(block)
  25 + self.class.expire_block(block)
  26 + end
  27 +
  28 +end
app/sweepers/friendship_sweeper.rb
@@ -35,7 +35,7 @@ protected @@ -35,7 +35,7 @@ protected
35 end 35 end
36 36
37 blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} 37 blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)}
38 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 38 + BlockSweeper.expire_blocks(blocks)
39 end 39 end
40 40
41 end 41 end
app/sweepers/profile_sweeper.rb
@@ -31,7 +31,7 @@ protected @@ -31,7 +31,7 @@ protected
31 31
32 def expire_statistics_block_cache(profile) 32 def expire_statistics_block_cache(profile)
33 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } 33 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) }
34 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 34 + BlockSweeper.expire_blocks(blocks)
35 end 35 end
36 36
37 def expire_blogs(profile) 37 def expire_blogs(profile)
app/sweepers/role_assignment_sweeper.rb
@@ -25,7 +25,7 @@ protected @@ -25,7 +25,7 @@ protected
25 25
26 profile.blocks_to_expire_cache.each { |block| 26 profile.blocks_to_expire_cache.each { |block|
27 blocks = profile.blocks.select{|b| b.kind_of?(block)} 27 blocks = profile.blocks.select{|b| b.kind_of?(block)}
28 - blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} 28 + BlockSweeper.expire_blocks(blocks)
29 } 29 }
30 end 30 end
31 31
app/views/account/_email_status.rhtml 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +<div class='status-identifier'>
  2 + <p><span class='<%= @status_class %>'><%= @status %></span></p>
  3 + <script type="text/javascript">
  4 + jQuery('#user_email').removeClass('<%= validation_classes %>');
  5 + jQuery('#user_email').addClass('<%= @status_class %>');
  6 + </script>
  7 +</div>
app/views/account/_identifier_status.rhtml
1 <div class='status-identifier'> 1 <div class='status-identifier'>
2 - <p><%= @url %> <span class='<%= @status_class %>'><%= @status %></span> </p> 2 + <p><span class='<%= @status_class %>'><%= @status %></span></p>
  3 + <script type="text/javascript">
  4 + jQuery('#user_login').removeClass('<%= validation_classes %>');
  5 + jQuery('#user_login').addClass('<%= @status_class %>');
  6 + </script>
3 </div> 7 </div>
app/views/account/_signup_form.rhtml
1 <%= error_messages_for :user, :person %> 1 <%= error_messages_for :user, :person %>
2 2
3 -<% if ! defined? hidden_atention || ! hidden_atention %>  
4 -<p/>  
5 -<div class="atention">  
6 -<%= _('Dear user, welcome to the %s network. To start your participation in this space, fill in the fields below. After this operation, your login and password will be registered, allowing you to create %s and %s in this environment.') % [environment.name, __('communities'), __('enterprises')] %>  
7 -</div>  
8 -<% end %>  
9 -  
10 -<% labelled_form_for :user, @user, :html => { :multipart => true } do |f| %> 3 +<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form' } do |f| %>
11 4
12 <%= hidden_field_tag :invitation_code, @invitation_code %> 5 <%= hidden_field_tag :invitation_code, @invitation_code %>
13 6
14 -<%= required_fields_message %> 7 +<div id='signup-form-header'>
15 8
16 -<div id='signup-email'>  
17 - <%= required f.text_field(:email) %>  
18 - <%= content_tag(:small,_('This e-mail address will be used to contact you.')) %>  
19 -</div> 9 + <span id="signup-domain"><%= environment.default_hostname %>/</span>
  10 + <div id='signup-login'>
  11 + <div id='signup-login-field'>
  12 + <%= required f.text_field(:login, :onchange => 'this.value = convToValidLogin(this.value);', :rel => s_('signup|Login')) %>
  13 + <div id='url-check'><p>&nbsp;</p></div>
  14 + </div>
  15 + <%= content_tag(:small, _('Choose your login name carefully! It will be your network access and you will not be able to change it later.'), :id => 'signup-balloon') %>
  16 + <br style="clear: both;" />
  17 + </div>
  18 + <%= observe_field 'user_login',
  19 + :url => { :action => 'check_url' },
  20 + :with => 'identifier',
  21 + :update => 'url-check',
  22 + :loading => "jQuery('#user_login').removeClass('#{validation_classes}').addClass('checking');
  23 + jQuery('#url-check').html('<p><span class=\"checking\">#{checking_message(:url)}</span></p>');",
  24 + :complete => "jQuery('#user_login').removeClass('checking')"
  25 + %>
20 26
21 -<%= required f.text_field(:login, :onchange => 'this.value = convToValidLogin( this.value )') %>  
22 -<%= content_tag(:small,_('Insert your login')) %>  
23 -<div id='url-check'></div> 27 + <div id='signup-password'>
  28 + <%= required f.password_field(:password, :id => 'user_pw') %>
  29 + <%= f.text_field(:password_clear, :value => _('password')) %>
  30 + <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.'), :id => 'password-balloon') %>
  31 + <div id='fake-check'><p>&nbsp;</p></div>
  32 + </div>
  33 +
  34 + <div id='signup-password-confirmation'>
  35 + <%= required f.password_field(:password_confirmation) %>
  36 + <%= f.text_field(:password_confirmation_clear, :value => _('password confirmation')) %>
  37 + <div id='password-check'><p>&nbsp;</p></div>
  38 + </div>
  39 +
  40 + <div id='signup-email'>
  41 + <%= required f.text_field(:email, :rel => _('e-Mail')) %>
  42 + <%= content_tag(:small,_('This e-mail address will be used to contact you.')) %>
  43 + <div id='email-check'><p>&nbsp;</p></div>
  44 + </div>
  45 + <%= observe_field "user_email",
  46 + :url => { :action => "check_email" },
  47 + :with => "address",
  48 + :update => "email-check",
  49 + :loading => "jQuery('#user_email').removeClass('#{validation_classes}').addClass('checking');
  50 + jQuery('#email-check').html('<p><span class=\"checking\">#{checking_message(:email)}</span></p>');",
  51 + :complete => "jQuery('#user_email').removeClass('checking')",
  52 + :before => "if (!( jQuery('#user_email').valid() )) {
  53 + jQuery('#user_email').removeClass('#{validation_classes}').addClass('unavailable');
  54 + jQuery('#email-check').html('<p><span class=\"unavailable\">#{_('This e-mail address is not valid')}</span></p>');
  55 + return false;
  56 + }"
  57 + %>
24 58
25 -<%= observe_field 'user_login', :url => {:action => 'check_url'}, :with => 'identifier', :update => 'url-check' %> 59 + <%= label :profile_data, :name %>
  60 + <%= required text_field(:profile_data, :name, :rel => _('Full name')) %>
26 61
27 -<div id='signup-password'>  
28 - <%= required f.password_field(:password) %>  
29 - <%= content_tag(:small,_('Choose a password that you can remember easily. It must have at least 4 characters.')) %>  
30 </div> 62 </div>
31 63
32 -<%= required f.password_field(:password_confirmation) %>  
33 -<%= content_tag(:small,_('To confirm, repeat your password.')) %>  
34 -  
35 -<% labelled_fields_for :profile_data, @person do |f| %>  
36 - <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %>  
37 -<% end %>  
38 -  
39 -<% unless @terms_of_use.blank? %>  
40 - <div id='terms-of-use-box' class='formfieldline'>  
41 - <%= _("By clicking on 'I accept the terms of use' below you are agreeing to the %s") %  
42 - link_to_function(_('Terms of use'), nil) do |page|  
43 - page['terms-of-use'].show  
44 - end %>  
45 -  
46 - <div id='terms-of-use' style='display: none;'>  
47 - <%= @terms_of_use %>  
48 - <%= link_to_function(_('Hide'), nil) do |page|  
49 - page['terms-of-use'].hide  
50 - end %> 64 +<div id="signup-form-profile">
  65 +
  66 + <% labelled_fields_for :profile_data, @person do |f| %>
  67 + <%= render :partial => 'profile_editor/person_form', :locals => {:f => f} %>
  68 + <% end %>
  69 +
  70 + <% unless @terms_of_use.blank? %>
  71 + <div id='terms-of-use-box' class='formfieldline'>
  72 + <%= labelled_check_box(_('I accept the %s') % link_to(_('terms of use'), {:controller => 'home', :action => 'terms'}, :target => '_blank'), 'user[terms_accepted]') %>
51 </div> 73 </div>
52 - <p><%= labelled_check_box(environment.terms_of_use_acceptance_text.blank? ? _('I accept the terms of use') : environment.terms_of_use_acceptance_text, 'user[terms_accepted]') %></p>  
53 - </div>  
54 -<% end %>  
55 -  
56 -<% if params[:enterprise_code] %>  
57 - <%= hidden_field_tag :enterprise_code, params[:enterprise_code] %>  
58 - <%= hidden_field_tag :answer, params[:answer] %>  
59 - <%= hidden_field_tag :terms_accepted, params[:terms_accepted] %>  
60 - <%= hidden_field_tag :new_user, true %>  
61 -<% end %>  
62 -  
63 -<% button_bar do %>  
64 - <%= submit_button('save', _('Sign up'), :cancel => {:action => 'index'}, :class => 'icon-menu-login') %>  
65 -<% end %> 74 + <% end %>
  75 +
  76 + <% if params[:enterprise_code] %>
  77 + <%= hidden_field_tag :enterprise_code, params[:enterprise_code] %>
  78 + <%= hidden_field_tag :answer, params[:answer] %>
  79 + <%= hidden_field_tag :terms_accepted, params[:terms_accepted] %>
  80 + <%= hidden_field_tag :new_user, true %>
  81 + <% end %>
  82 +</div>
  83 +
  84 +<p style="text-align: center">
  85 + <%= submit_button('save', _('Create my account')) %>
  86 +</p>
  87 +
66 <% end -%> 88 <% end -%>
  89 +
  90 +<script type="text/javascript">
  91 +jQuery(function($) {
  92 + $('#signup-form input[type=text], #signup-form textarea').each(function() {
  93 + if ($(this).attr('rel')) var default_value = $(this).attr('rel').toLowerCase();
  94 + if ($(this).val() == '') $(this).val(default_value);
  95 + $(this).bind('focus', function() {
  96 + if ($(this).val() == default_value) $(this).val('');
  97 + });
  98 + $(this).bind('blur', function() {
  99 + if ($(this).val() == '') {
  100 + $(this).val(default_value);
  101 + $(this).removeClass('filled-in');
  102 + }
  103 + else $(this).addClass('filled-in');
  104 + });
  105 + });
  106 +
  107 + $('#signup-form').bind('submit', function() {
  108 + $('#signup-form input[type=text], #signup-form textarea').each(function() {
  109 + if ($(this).attr('rel')) var default_value = $(this).attr('rel').toLowerCase();
  110 + if ($(this).val() == default_value) $(this).val('');
  111 + });
  112 + return true;
  113 + });
  114 +
  115 + $('#user_password_clear, #user_password_confirmation_clear').show();
  116 + $('#user_password_clear, #user_password_confirmation_clear').unbind();
  117 + $('#user_pw, #user_password_confirmation').hide();
  118 + $('#user_password_clear').focus(function() {
  119 + $(this).hide();
  120 + $('#user_pw').show();
  121 + $('#user_pw').focus();
  122 + });
  123 + $('#user_pw').focus(function() {
  124 + $('#password-balloon').fadeIn('slow');
  125 + });
  126 + $('#user_pw').blur(function() {
  127 + if ($(this).val() == '') {
  128 + $('#user_password_clear').show();
  129 + $(this).hide();
  130 + }
  131 + });
  132 + $('#user_password_confirmation_clear').focus(function() {
  133 + $(this).hide();
  134 + $('#user_password_confirmation').show();
  135 + $('#user_password_confirmation').focus();
  136 + });
  137 + $('#user_password_confirmation, #user_pw').blur(function() {
  138 + if ($('#user_password_confirmation').val() == '') {
  139 + $('#user_password_confirmation_clear').show();
  140 + $('#user_password_confirmation').hide();
  141 + } else if ($('#user_password_confirmation').val() == $('#user_pw').val()) {
  142 + $('#user_password_confirmation').addClass('passwords_match').removeClass('passwords_differ');
  143 + $('#user_pw').removeClass('invalid_input').addClass('valid_input');
  144 + $('#password-check').html("<p>&nbsp;</p>");
  145 + } else if ($('#user_password_confirmation').val() != $('#user_pw').val()) {
  146 + $('#user_password_confirmation').removeClass('passwords_match').addClass('passwords_differ');
  147 + $('#user_pw').addClass('invalid_input').removeClass('valid_input');
  148 + $('#password-check').html("<p><span class='unavailable'><%= _('Passwords don\'t match') %></span></p>");
  149 + }
  150 + $('#password-balloon').fadeOut('slow');
  151 + });
  152 + $('#user_login').focus(function() {
  153 + $('#signup-balloon').fadeIn('slow');
  154 + });
  155 + $('#user_login').blur(function() { $('#signup-balloon').fadeOut('slow'); });
  156 + $('#signup-form').validate({ rules: { 'user[email]': { email: true } }, messages: { 'user[email]' : '' } });
  157 +});
  158 +</script>