Commit 2157d022b5dd108a5568c70485d635df9f2891fb

Authored by Joenio Costa
2 parents a3e6850a e0543b02

Merge branch 'rails235' into AI2983-pg_search_escape_chars_fix

Showing 306 changed files with 6622 additions and 1457 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 306 files displayed.

AUTHORS 0 → 100644
@@ -0,0 +1,239 @@ @@ -0,0 +1,239 @@
  1 +If you are not listed here, but should be, please write to the noosfero mailing
  2 +list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev
  3 +(this list requires subscription to post, but since you are an author of
  4 +noosfero, that's not a problem).
  5 +
  6 +Developers
  7 +==========
  8 +
  9 +Alan Freihof Tygel <alantygel@gmail.com>
  10 +alcampelo <alcampelo@alcampelo.(none)>
  11 +Alessandro Palmeira <alessandro.palmeira@gmail.com>
  12 +Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
  13 +Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
  14 +Alessandro Palmeira + Caio Salgado <caio.csalgado@gmail.com>
  15 +Alessandro Palmeira + Caio Salgado + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
  16 +Alessandro Palmeira + Carlos Morais <alessandro.palmeira@gmail.com>
  17 +Alessandro Palmeira + Daniel Alves <alessandro.palmeira@gmail.com>
  18 +Alessandro Palmeira + Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
  19 +Alessandro Palmeira + Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
  20 +Alessandro Palmeira + Diego Araujo <alessandro.palmeira@gmail.com>
  21 +Alessandro Palmeira + Diego Araújo <alessandro.palmeira@gmail.com>
  22 +Alessandro Palmeira + Diego Araujo + Daniela Feitosa <alessandro.palmeira@gmail.com>
  23 +Alessandro Palmeira + Diego Araujo <diegoamc90@gmail.com>
  24 +Alessandro Palmeira + Diego Araújo <diegoamc90@gmail.com>
  25 +Alessandro Palmeira + Diego Araujo + Eduardo Morais <alessandro.palmeira@gmail.com>
  26 +Alessandro Palmeira + Diego Araújo + João M. M. da Silva <alessandro.palmeira@gmail.com>
  27 +Alessandro Palmeira + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
  28 +Alessandro Palmeira + Diego Araujo + João M. M. da Silva + Paulo Meirelles <alessandro.palmeira@gmail.com>
  29 +Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  30 +Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com>
  31 +Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@gmail.com>
  32 +Alessandro Palmeira + Eduardo Morais <alessandro.palmeira@gmail.com>
  33 +Alessandro Palmeira + Guilherme Rojas <alessandro.palmeira@gmail.com>
  34 +Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com>
  35 +Alessandro Palmeira + João M. M. da Silva <alessandro.palmeira@gmail.com>
  36 +Alessandro Palmeira + Joao M. M. da Silva + Diego Araujo <alessandro.palmeira@gmail.com>
  37 +Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com>
  38 +Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com>
  39 +Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com>
  40 +Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com>
  41 +Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
  42 +Ana Losnak <analosnak@gmail.com>
  43 +Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
  44 +Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
  45 +Antonio Terceiro <terceiro@colivre.coop.br>
  46 +Arthur Del Esposte <arthurmde@yahoo.com.br>
  47 +Aurelio A. Heckert <aurelio@colivre.coop.br>
  48 +Braulio Bhavamitra <brauliobo@gmail.com>
  49 +Bráulio Bhavamitra <brauliobo@gmail.com>
  50 +Braulio Bhavamitra <braulio@eita.org.br>
  51 +Caio <caio.csalgado@gmail.com>
  52 +Caio + Diego + Pedro + João <caio.csalgado@gmail.com>
  53 +Caio Formiga <caio.formiga@gmail.com>
  54 +Caio, Pedro <caio.csalgado@gmail.com>
  55 +Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com>
  56 +Caio Salgado <caio.csalgado@gmail.com>
  57 +Caio Salgado + Carlos Morais + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  58 +Caio Salgado + Diego Araujo <caio.csalgado@gmail.com>
  59 +Caio Salgado + Diego Araújo <caio.csalgado@gmail.com>
  60 +Caio Salgado + Diego Araújo <diegoamc90@gmail.com>
  61 +Caio Salgado + Diego Araújo + Jefferson Fernandes <caio.csalgado@gmail.com>
  62 +Caio Salgado + Diego Araújo + João M. M. da Silva <caio.csalgado@gmail.com>
  63 +Caio Salgado + Diego Araújo + Pedro Leal <caio.csalgado@gmail.com>
  64 +Caio Salgado + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  65 +Caio Salgado + Diego Araújo + Rafael Manzo <diegoamc90@gmail.com>
  66 +Caio Salgado + Jefferson Fernandes <caio.csalgado@gmail.com>
  67 +Caio Salgado + Jefferson Fernandes <jeffs.fernandes@gmail.com>
  68 +Caio Salgado + Rafael Manzo <caio.csalgado@gmail.com>
  69 +Caio Salgado + Renan Teruo <caio.csalgado@gmail.com>
  70 +Caio Salgado + Renan Teruo <caio.salgado@gmail.com>
  71 +Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
  72 +Caio Salgado + Renan Teruo <renanteruoc@gmail.com>
  73 +Caio SBA <caio@colivre.coop.br>
  74 +Carlos Andre de Souza <carlos.andre.souza@msn.com>
  75 +Carlos Morais <carlos88morais@gmail.com>
  76 +Carlos Morais + Diego Araújo <diegoamc90@gmail.com>
  77 +Carlos Morais + Eduardo Morais <carlos88morais@gmail.com>
  78 +Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com>
  79 +Carlos Morais + Pedro Leal <carlos88morais@gmail.com>
  80 +Daniel Alves + Diego Araújo <danpaulalves@gmail.com>
  81 +Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
  82 +Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
  83 +Daniel Alves + Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
  84 +Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com>
  85 +Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com>
  86 +Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
  87 +Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
  88 +Daniel Bucher <daniel.bucher88@gmail.com>
  89 +Daniel Cunha <daniel@colivre.coop.br>
  90 +David Carlos <ddavidcarlos1392@gmail.com>
  91 +diegoamc <diegoamc90@gmail.com>
  92 +Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
  93 +Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
  94 +Diego Araújo + Alessandro Palmeira + Rafael Manzo <rr.manzo@gmail.com>
  95 +Diego Araujo + Caio Salgado <diegoamc90@gmail.com>
  96 +Diego Araújo + Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
  97 +Diego Araújo <diegoamc90@gmail.com>
  98 +Diego Araújo + Eduardo Morais + Paulo Meirelles <diegoamc90@gmail.com>
  99 +Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
  100 +Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com>
  101 +Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
  102 +Diego Araújo + João Machini <diegoamc90@gmail.com>
  103 +Diego Araújo + João Machini <digoamc90@gmail.com>
  104 +Diego Araújo + João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  105 +Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
  106 +Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com>
  107 +Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com>
  108 +Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com>
  109 +Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
  110 +Diego Araujo + Rafael Manzo <diegoamc90@gmail.com>
  111 +Diego Araújo + Rafael Manzo <diegoamc90@gmail.com>
  112 +Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com>
  113 +Diego Araújo + Renan Teruo <diegoamc90@gmail.com>
  114 +Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com>
  115 +Diego + Jefferson <diegoamc90@gmail.com>
  116 +Diego Martinez <diegoamc90@gmail.com>
  117 +Diego Martinez <diego@diego-K55A.(none)>
  118 +Diego + Renan <renanteruoc@gmail.com>
  119 +Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br>
  120 +Fabio Teixeira <fabio1079@gmail.com>
  121 +Fernanda Lopes <nanda.listas+psl@gmail.com>
  122 +Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
  123 +Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)>
  124 +Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br>
  125 +Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com>
  126 +Gabriela Navarro <navarro1703@gmail.com>
  127 +Grazieno Pellegrino <grazieno@gmail.com>
  128 +Gust <darksshades@hotmail.com>
  129 +Hugo Melo <hugo@riseup.net>
  130 +Isaac Canan <isaac@intelletto.com.br>
  131 +Italo Valcy <italo@dcc.ufba.br>
  132 +Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
  133 +Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com>
  134 +Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com>
  135 +João da Silva <jaodsilv@linux.ime.usp.br>
  136 +João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br>
  137 +João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br>
  138 +João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br>
  139 +Joao M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  140 +João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  141 +João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br>
  142 +João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
  143 +João M. M. da Silva + Caio Salgado <jaodsilv@linux.ime.usp.br>
  144 +João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br>
  145 +João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com>
  146 +João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
  147 +João M. M. da Silva + Diego Araújo + Pedro Leal <jaodsilv@linux.ime.usp.br>
  148 +João M. M. da Silva <jaodsilv@linux.ime.usp.br>
  149 +Joao M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
  150 +João M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
  151 +João M. M. da Silva + João M. Miranda <jaodsilv@linux.ime.usp.br>
  152 +João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
  153 +João M. M. da Silva + Pedro Leal <jaodsilv@linux.ime.usp.br>
  154 +João M. M. da Silva + Rafael Manzo + Diego Araújo <jaodsilv@linux.ime.usp.br>
  155 +João M. M. da Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br>
  156 +João M. M. da Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
  157 +João M. M. Silva + Caio Salgado <jaodsilv@linux.ime.usp.br>
  158 +João M. M. Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
  159 +Joao M. M. Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
  160 +João M. M. Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
  161 +João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br>
  162 +João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
  163 +Joenio Costa <joenio@colivre.coop.br>
  164 +Josef Spillner <josef.spillner@tu-dresden.de>
  165 +Junior Silva <juniorsilva1001@gmail.com>
  166 +Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)>
  167 +Junior Silva <juniorsilva@colivre.coop.br>
  168 +Keilla Menezes <keilla@colivre.coop.br>
  169 +Larissa Reis <larissa@colivre.coop.br>
  170 +Larissa Reis <reiss.larissa@gmail.com>
  171 +Leandro Nunes dos Santos <81665687568@serpro-1541727.Home>
  172 +Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)>
  173 +Leandro Nunes dos Santos <leandronunes@gmail.com>
  174 +Leandro Nunes dos Santos <leandro.santos@serpro.gov.br>
  175 +LinguÁgil 2010 <linguagil.bahia@gmail.com>
  176 +Lucas Melo <lucas@colivre.coop.br>
  177 +Lucas Melo <lucaspradomelo@gmail.com>
  178 +Luis David Aguilar Carlos <ludwig9003@gmail.com>
  179 +Marcos Ramos <ms.ramos@outlook.com>
  180 +Martín Olivera <molivera@solar.org.ar>
  181 +Moises Machado <moises@colivre.coop.br>
  182 +Naíla Alves <naila@colivre.coop.br>
  183 +Nanda Lopes <nanda.listas+psl@gmail.com>
  184 +Paulo Meirelles + Alessandro Palmeira + João M. M. da Silva <paulo@softwarelivre.org>
  185 +Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org>
  186 +Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org>
  187 +Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org>
  188 +Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org>
  189 +Paulo Meirelles <paulo@softwarelivre.org>
  190 +Paulo Meirelles + Rafael Manzo <paulo@softwarelivre.org>
  191 +Rafael Gomes <rafaelgomes@techfree.com.br>
  192 +Rafael Manzo + Alessandro Palmeira <rr.manzo@gmail.com>
  193 +Rafael Manzo + Daniel Alves <danpaulalves@gmail.com>
  194 +Rafael Manzo + Diego Araújo <rr.manzo@gmail.com>
  195 +Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com>
  196 +Rafael Manzo + Paulo Meirelles <rr.manzo@gmail.com>
  197 +Rafael Martins <rmmartins@gmail.com>
  198 +Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com>
  199 +Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com>
  200 +Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com>
  201 +Rafael Reggiani Manzo + Diego Araújo <rr.manzo@gmail.com>
  202 +Rafael Reggiani Manzo + João M. M. da Silva <rr.manzo@gmail.com>
  203 +Rafael Reggiani Manzo <rr.manzo@gmail.com>
  204 +Raphaël Rousseau <raph@r4f.org>
  205 +Raquel Lira <raquel.lira@gmail.com>
  206 +Renan Teruo + Caio Salgado <renanteruoc@gmail.com>
  207 +Renan Teruoc + Diego Araujo <renanteruoc@gmail.com>
  208 +Renan Teruo + Diego Araujo <renanteruoc@gmail.com>
  209 +Renan Teruo + Diego Araújo <renanteruoc@gmail.com>
  210 +Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com>
  211 +Renan Teruo + Rafael Manzo <renanteruoc@gmail.com>
  212 +Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org>
  213 +Rodrigo Souto <diguliu@gmail.com>
  214 +Rodrigo Souto <rodrigo@colivre.coop.br>
  215 +Ronny Kursawe <kursawe.ronny@googlemail.com>
  216 +root <root@debian.sdr.serpro>
  217 +Samuel R. C. Vale <srcvale@holoscopio.com>
  218 +Valessio Brito <contato@valessiobrito.com.br>
  219 +Valessio Brito <contato@valessiobrito.info>
  220 +Valessio Brito <valessio@gmail.com>
  221 +vfcosta <vfcosta@gmail.com>
  222 +Victor Carvalho <victorhugodf.ac@gmail.com>
  223 +Victor Costa <vfcosta@gmail.com>
  224 +Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com>
  225 +Vinicius Cubas Brand <viniciuscb@gmail.com>
  226 +Visita <visita@debian.(none)>
  227 +Yann Lugrin <yann.lugrin@liquid-concept.ch>
  228 +
  229 +Ideas, specifications and incentive
  230 +===================================
  231 +Daniel Tygel <dtygel@fbes.org.br>
  232 +Guilherme Rocha <guilherme@gf7.com.br>
  233 +Raphael Rousseau <raph@r4f.org>
  234 +Théo Bondolfi <move@cooperation.net>
  235 +Vicente Aguiar <vicenteaguiar@colivre.coop.br>
  236 +
  237 +Arts
  238 +===================================
  239 +Nara Oliveira <narananet@gmail.com>
@@ -23,7 +23,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or De @@ -23,7 +23,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or De
23 # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 \ 23 # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 \
24 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libhpricot-ruby \ 24 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libhpricot-ruby \
25 libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin \ 25 libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin \
26 - tango-icon-theme libnokogiri-ruby 26 + tango-icon-theme
27 27
28 On other systems, they may or may not be available through your regular package management system. Below are the links to their homepages. 28 On other systems, they may or may not be available through your regular package management system. Below are the links to their homepages.
29 29
@@ -41,7 +41,6 @@ On other systems, they may or may not be available through your regular package @@ -41,7 +41,6 @@ On other systems, they may or may not be available through your regular package
41 * Thin: http://code.macournoyer.com/thin 41 * Thin: http://code.macournoyer.com/thin
42 * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library 42 * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library
43 * Hpricot: http://hpricot.com 43 * Hpricot: http://hpricot.com
44 -* Nokogiri: http://nokogiri.org/  
45 44
46 If you manage to install Noosfero successfully on other systems than Debian, 45 If you manage to install Noosfero successfully on other systems than Debian,
47 please feel free to contact the Noosfero development mailing with the 46 please feel free to contact the Noosfero development mailing with the
app/controllers/admin/environment_design_controller.rb
@@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController @@ -3,6 +3,8 @@ class EnvironmentDesignController &lt; BoxOrganizerController
3 protect 'edit_environment_design', :environment 3 protect 'edit_environment_design', :environment
4 4
5 def available_blocks 5 def available_blocks
  6 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  7 + # the Noosfero core soon, see ActionItem3045
6 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] 8 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
7 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) 9 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
8 end 10 end
app/controllers/admin/environment_themes_controller.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class EnvironmentThemesController < ThemesController
  2 +
  3 + protect 'edit_appearance', :environment
  4 +
  5 + no_design_blocks
  6 +
  7 + def target
  8 + @target = environment
  9 + end
  10 +
  11 +end
app/controllers/admin/users_controller.rb
@@ -7,7 +7,7 @@ class UsersController &lt; AdminController @@ -7,7 +7,7 @@ class UsersController &lt; AdminController
7 include UsersHelper 7 include UsersHelper
8 8
9 def index 9 def index
10 - @filter = params[:filter] 10 + @filter = params[:filter] || 'all_users'
11 scope = environment.people.no_templates 11 scope = environment.people.no_templates
12 if @filter == 'admin_users' 12 if @filter == 'admin_users'
13 scope = scope.admins 13 scope = scope.admins
@@ -16,6 +16,7 @@ class UsersController &lt; AdminController @@ -16,6 +16,7 @@ class UsersController &lt; AdminController
16 elsif @filter == 'deactivated_users' 16 elsif @filter == 'deactivated_users'
17 scope = scope.deactivated 17 scope = scope.deactivated
18 end 18 end
  19 + scope = scope.order('name ASC')
19 @q = params[:q] 20 @q = params[:q]
20 @collection = find_by_contents(:people, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results] 21 @collection = find_by_contents(:people, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results]
21 end 22 end
@@ -44,6 +45,20 @@ class UsersController &lt; AdminController @@ -44,6 +45,20 @@ class UsersController &lt; AdminController
44 redirect_to :action => :index, :q => params[:q], :filter => params[:filter] 45 redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
45 end 46 end
46 47
  48 +
  49 + def destroy_user
  50 + if request.post?
  51 + person = environment.people.find_by_id(params[:id])
  52 + if person && person.destroy
  53 + session[:notice] = _('The profile was deleted.')
  54 + else
  55 + session[:notice] = _('Could not remove profile')
  56 + end
  57 + end
  58 + redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
  59 + end
  60 +
  61 +
47 def download 62 def download
48 respond_to do |format| 63 respond_to do |format|
49 format.html 64 format.html
app/controllers/application_controller.rb
@@ -21,6 +21,7 @@ class ApplicationController &lt; ActionController::Base @@ -21,6 +21,7 @@ class ApplicationController &lt; ActionController::Base
21 include ApplicationHelper 21 include ApplicationHelper
22 layout :get_layout 22 layout :get_layout
23 def get_layout 23 def get_layout
  24 + return nil if request.format == :js
24 theme_layout = theme_option(:layout) 25 theme_layout = theme_option(:layout)
25 if theme_layout 26 if theme_layout
26 theme_view_file('layouts/'+theme_layout) || theme_layout 27 theme_view_file('layouts/'+theme_layout) || theme_layout
app/controllers/box_organizer_controller.rb
@@ -70,7 +70,7 @@ class BoxOrganizerController &lt; ApplicationController @@ -70,7 +70,7 @@ class BoxOrganizerController &lt; ApplicationController
70 else 70 else
71 @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1) 71 @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1)
72 @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3]) 72 @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3])
73 - @boxes = boxes_holder.boxes 73 + @boxes = boxes_holder.boxes.with_position
74 render :action => 'add_block', :layout => false 74 render :action => 'add_block', :layout => false
75 end 75 end
76 end 76 end
@@ -80,6 +80,22 @@ class BoxOrganizerController &lt; ApplicationController @@ -80,6 +80,22 @@ class BoxOrganizerController &lt; ApplicationController
80 render :action => 'edit', :layout => false 80 render :action => 'edit', :layout => false
81 end 81 end
82 82
  83 + def search_autocomplete
  84 + if request.xhr? and params[:query]
  85 + search = params[:query]
  86 + path_list = if boxes_holder.is_a?(Environment) && boxes_holder.enabled?('use_portal_community') && boxes_holder.portal_community
  87 + boxes_holder.portal_community.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{portal}/"+content.path }
  88 + elsif boxes_holder.is_a?(Profile)
  89 + boxes_holder.articles.find(:all, :conditions=>"name ILIKE '%#{search}%' or path ILIKE '%#{search}%'", :limit=>20).map { |content| "/{profile}/"+content.path }
  90 + else
  91 + []
  92 + end
  93 + render :json => path_list.to_json
  94 + else
  95 + redirect_to "/"
  96 + end
  97 + end
  98 +
83 def save 99 def save
84 @block = boxes_holder.blocks.find(params[:id]) 100 @block = boxes_holder.blocks.find(params[:id])
85 @block.update_attributes(params[:block]) 101 @block.update_attributes(params[:block])
@@ -99,6 +115,12 @@ class BoxOrganizerController &lt; ApplicationController @@ -99,6 +115,12 @@ class BoxOrganizerController &lt; ApplicationController
99 end 115 end
100 end 116 end
101 117
  118 + def clone_block
  119 + block = Block.find(params[:id])
  120 + block.duplicate
  121 + redirect_to :action => 'index'
  122 + end
  123 +
102 protected :boxes_editor? 124 protected :boxes_editor?
103 125
104 end 126 end
app/controllers/my_profile/cms_controller.rb
@@ -24,10 +24,16 @@ class CmsController &lt; MyProfileController @@ -24,10 +24,16 @@ class CmsController &lt; MyProfileController
24 (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))) 24 (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
25 end 25 end
26 26
27 - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files] do |c, user, profile| 27 + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files, :new] do |c, user, profile|
28 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)) 28 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))
29 end 29 end
30 30
  31 + protect_if :only => :new do |c, user, profile|
  32 + article = profile.articles.find_by_id(c.params[:parent_id])
  33 + (!article.nil? && (article.allow_create?(user) || article.parent.allow_create?(user))) ||
  34 + (user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile)))
  35 + end
  36 +
31 protect_if :only => [:destroy, :publish] do |c, user, profile| 37 protect_if :only => [:destroy, :publish] do |c, user, profile|
32 profile.articles.find(c.params[:id]).allow_post_content?(user) 38 profile.articles.find(c.params[:id]).allow_post_content?(user)
33 end 39 end
@@ -221,11 +227,10 @@ class CmsController &lt; MyProfileController @@ -221,11 +227,10 @@ class CmsController &lt; MyProfileController
221 227
222 def update_categories 228 def update_categories
223 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new 229 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new
  230 + @categories = @toplevel_categories = environment.top_level_categories
224 if params[:category_id] 231 if params[:category_id]
225 @current_category = Category.find(params[:category_id]) 232 @current_category = Category.find(params[:category_id])
226 @categories = @current_category.children 233 @categories = @current_category.children
227 - else  
228 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
229 end 234 end
230 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false 235 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false
231 end 236 end
app/controllers/my_profile/profile_design_controller.rb
@@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController @@ -55,10 +55,4 @@ class ProfileDesignController &lt; BoxOrganizerController
55 blocks 55 blocks
56 end 56 end
57 57
58 - def clone  
59 - block = Block.find(params[:id])  
60 - block.duplicate  
61 - redirect_to :action => 'index'  
62 - end  
63 -  
64 end 58 end
app/controllers/my_profile/profile_editor_controller.rb
@@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController @@ -55,11 +55,10 @@ class ProfileEditorController &lt; MyProfileController
55 55
56 def update_categories 56 def update_categories
57 @object = profile 57 @object = profile
  58 + @categories = @toplevel_categories = environment.top_level_categories
58 if params[:category_id] 59 if params[:category_id]
59 @current_category = Category.find(params[:category_id]) 60 @current_category = Category.find(params[:category_id])
60 @categories = @current_category.children 61 @categories = @current_category.children
61 - else  
62 - @categories = environment.top_level_categories.select{|i| !i.children.empty?}  
63 end 62 end
64 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false 63 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false
65 end 64 end
app/controllers/my_profile/profile_members_controller.rb
@@ -2,7 +2,7 @@ class ProfileMembersController &lt; MyProfileController @@ -2,7 +2,7 @@ class ProfileMembersController &lt; MyProfileController
2 protect 'manage_memberships', :profile 2 protect 'manage_memberships', :profile
3 3
4 def index 4 def index
5 - @members = profile.members 5 + @members = profile.members_by_name
6 @member_role = environment.roles.find_by_name('member') 6 @member_role = environment.roles.find_by_name('member')
7 end 7 end
8 8
app/controllers/my_profile/profile_themes_controller.rb 0 → 100644
@@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
  1 +class ProfileThemesController < ThemesController
  2 +
  3 + needs_profile
  4 +
  5 + protect 'edit_appearance', :profile
  6 +
  7 + no_design_blocks
  8 +
  9 + def target
  10 + @target = profile
  11 + end
  12 +
  13 + def new
  14 + if !request.xhr?
  15 + id = params[:name] ? params[:name].to_slug : 'my-theme'
  16 + t = Theme.new(id, :name => params[:name], :owner => profile, :public => false)
  17 + t.save
  18 + redirect_to :action => 'index'
  19 + else
  20 + render :action => 'new', :layout => false
  21 + end
  22 + end
  23 +
  24 + def edit
  25 + @theme = profile.find_theme(params[:id])
  26 + @css_files = @theme.css_files
  27 + @image_files = @theme.image_files
  28 + end
  29 +
  30 + def add_css
  31 + @theme = profile.find_theme(params[:id])
  32 + if request.xhr?
  33 + render :action => 'add_css', :layout => false
  34 + else
  35 + @theme.add_css(params[:css])
  36 + redirect_to :action => 'edit', :id => @theme.id
  37 + end
  38 + end
  39 +
  40 + def css_editor
  41 + @theme = profile.find_theme(params[:id])
  42 + @css = params[:css]
  43 +
  44 + @code = @theme.read_css(@css)
  45 + render :action => 'css_editor', :layout => false
  46 + end
  47 +
  48 + post_only :update_css
  49 + def update_css
  50 + @theme = profile.find_theme(params[:id])
  51 + @theme.update_css(params[:css], params[:csscode])
  52 + redirect_to :action => 'edit', :id => @theme.id
  53 + end
  54 +
  55 + def add_image
  56 + @theme = profile.find_theme(params[:id])
  57 + if request.xhr?
  58 + render :action => 'add_image', :layout => false
  59 + else
  60 + @theme.add_image(params[:image].original_filename, params[:image].read)
  61 + redirect_to :action => 'edit', :id => @theme.id
  62 + end
  63 + end
  64 +
  65 + def start_test
  66 + session[:theme] = params[:id]
  67 + redirect_to :controller => 'content_viewer', :profile => profile.identifier, :action => 'view_page'
  68 + end
  69 +
  70 + def stop_test
  71 + session[:theme] = nil
  72 + redirect_to :action => 'index'
  73 + end
  74 +
  75 +end
app/controllers/my_profile/themes_controller.rb
@@ -1,91 +0,0 @@ @@ -1,91 +0,0 @@
1 -class ThemesController < MyProfileController  
2 -  
3 - protect 'edit_appearance', :profile  
4 - no_design_blocks  
5 -  
6 - def set  
7 - profile.update_theme(params[:id])  
8 - redirect_to :action => 'index'  
9 - end  
10 -  
11 - def unset  
12 - profile.update_theme(nil)  
13 - redirect_to :action => 'index'  
14 - end  
15 -  
16 - def index  
17 - @themes = profile.environment.themes + Theme.approved_themes(profile)  
18 - @current_theme = profile.theme  
19 -  
20 - @layout_templates = LayoutTemplate.all  
21 - @current_template = profile.layout_template  
22 - end  
23 -  
24 - def new  
25 - if !request.xhr?  
26 - id = params[:name] ? params[:name].to_slug : 'my-theme'  
27 - t = Theme.new(id, :name => params[:name], :owner => profile, :public => false)  
28 - t.save  
29 - redirect_to :action => 'index'  
30 - else  
31 - render :action => 'new', :layout => false  
32 - end  
33 - end  
34 -  
35 - def edit  
36 - @theme = profile.find_theme(params[:id])  
37 - @css_files = @theme.css_files  
38 - @image_files = @theme.image_files  
39 - end  
40 -  
41 - def add_css  
42 - @theme = profile.find_theme(params[:id])  
43 - if request.xhr?  
44 - render :action => 'add_css', :layout => false  
45 - else  
46 - @theme.add_css(params[:css])  
47 - redirect_to :action => 'edit', :id => @theme.id  
48 - end  
49 - end  
50 -  
51 - def css_editor  
52 - @theme = profile.find_theme(params[:id])  
53 - @css = params[:css]  
54 -  
55 - @code = @theme.read_css(@css)  
56 - render :action => 'css_editor', :layout => false  
57 - end  
58 -  
59 - post_only :update_css  
60 - def update_css  
61 - @theme = profile.find_theme(params[:id])  
62 - @theme.update_css(params[:css], params[:csscode])  
63 - redirect_to :action => 'edit', :id => @theme.id  
64 - end  
65 -  
66 - def add_image  
67 - @theme = profile.find_theme(params[:id])  
68 - if request.xhr?  
69 - render :action => 'add_image', :layout => false  
70 - else  
71 - @theme.add_image(params[:image].original_filename, params[:image].read)  
72 - redirect_to :action => 'edit', :id => @theme.id  
73 - end  
74 - end  
75 -  
76 - def start_test  
77 - session[:theme] = params[:id]  
78 - redirect_to :controller => 'content_viewer', :profile => profile.identifier, :action => 'view_page'  
79 - end  
80 -  
81 - def stop_test  
82 - session[:theme] = nil  
83 - redirect_to :action => 'index'  
84 - end  
85 -  
86 - def set_layout_template  
87 - profile.update_layout_template(params[:id])  
88 - redirect_to :action => 'index'  
89 - end  
90 -  
91 -end  
app/controllers/public/account_controller.rb
@@ -69,6 +69,8 @@ class AccountController &lt; ApplicationController @@ -69,6 +69,8 @@ class AccountController &lt; ApplicationController
69 session[:notice] = _("This environment doesn't allow user registration.") 69 session[:notice] = _("This environment doesn't allow user registration.")
70 end 70 end
71 71
  72 + store_location(request.referer) unless params[:return_to] or session[:return_to]
  73 +
72 @block_bot = !!session[:may_be_a_bot] 74 @block_bot = !!session[:may_be_a_bot]
73 @invitation_code = params[:invitation_code] 75 @invitation_code = params[:invitation_code]
74 begin 76 begin
@@ -77,6 +79,7 @@ class AccountController &lt; ApplicationController @@ -77,6 +79,7 @@ class AccountController &lt; ApplicationController
77 @user.environment = environment 79 @user.environment = environment
78 @terms_of_use = environment.terms_of_use 80 @terms_of_use = environment.terms_of_use
79 @user.person_data = params[:profile_data] 81 @user.person_data = params[:profile_data]
  82 + @user.return_to = session[:return_to]
80 @person = Person.new(params[:profile_data]) 83 @person = Person.new(params[:profile_data])
81 @person.environment = @user.environment 84 @person.environment = @user.environment
82 if request.post? 85 if request.post?
@@ -98,7 +101,7 @@ class AccountController &lt; ApplicationController @@ -98,7 +101,7 @@ class AccountController &lt; ApplicationController
98 end 101 end
99 if @user.activated? 102 if @user.activated?
100 self.current_user = @user 103 self.current_user = @user
101 - redirect_to '/' 104 + go_to_signup_initial_page
102 else 105 else
103 @register_pending = true 106 @register_pending = true
104 end 107 end
@@ -368,32 +371,29 @@ class AccountController &lt; ApplicationController @@ -368,32 +371,29 @@ class AccountController &lt; ApplicationController
368 end 371 end
369 372
370 def go_to_initial_page 373 def go_to_initial_page
  374 + if params[:redirection]
  375 + session[:return_to] = @user.return_to
  376 + @user.return_to = nil
  377 + @user.save
  378 + end
  379 +
371 if params[:return_to] 380 if params[:return_to]
372 redirect_to params[:return_to] 381 redirect_to params[:return_to]
373 elsif environment.enabled?('allow_change_of_redirection_after_login') 382 elsif environment.enabled?('allow_change_of_redirection_after_login')
374 - case user.preferred_login_redirection  
375 - when 'keep_on_same_page'  
376 - redirect_back_or_default(user.admin_url)  
377 - when 'site_homepage'  
378 - redirect_to :controller => :home  
379 - when 'user_profile_page'  
380 - redirect_to user.public_profile_url  
381 - when 'user_homepage'  
382 - redirect_to user.url  
383 - when 'user_control_panel'  
384 - redirect_to user.admin_url  
385 - else  
386 - redirect_back_or_default(user.admin_url)  
387 - end 383 + check_redirection_options(user, user.preferred_login_redirection, user.admin_url)
388 else 384 else
389 if environment == current_user.environment 385 if environment == current_user.environment
390 - redirect_back_or_default(user.admin_url) 386 + check_redirection_options(user, environment.redirection_after_login, user.admin_url)
391 else 387 else
392 redirect_back_or_default(:controller => 'home') 388 redirect_back_or_default(:controller => 'home')
393 end 389 end
394 end 390 end
395 end 391 end
396 392
  393 + def go_to_signup_initial_page
  394 + check_redirection_options(user, user.environment.redirection_after_signup, user.url)
  395 + end
  396 +
397 def redirect_if_logged_in 397 def redirect_if_logged_in
398 if logged_in? 398 if logged_in?
399 go_to_initial_page 399 go_to_initial_page
@@ -409,4 +409,22 @@ class AccountController &lt; ApplicationController @@ -409,4 +409,22 @@ class AccountController &lt; ApplicationController
409 user 409 user
410 end 410 end
411 411
  412 + protected
  413 +
  414 + def check_redirection_options(user, condition, default)
  415 + case condition
  416 + when 'keep_on_same_page'
  417 + redirect_back_or_default(user.admin_url)
  418 + when 'site_homepage'
  419 + redirect_to :controller => :home
  420 + when 'user_profile_page'
  421 + redirect_to user.public_profile_url
  422 + when 'user_homepage'
  423 + redirect_to user.url
  424 + when 'user_control_panel'
  425 + redirect_to user.admin_url
  426 + else
  427 + redirect_back_or_default(default)
  428 + end
  429 + end
412 end 430 end
app/controllers/public/comment_controller.rb
@@ -71,7 +71,9 @@ class CommentController &lt; ApplicationController @@ -71,7 +71,9 @@ class CommentController &lt; ApplicationController
71 return 71 return
72 end 72 end
73 73
74 - @comment.save 74 + if @comment.save
  75 + @plugins.dispatch(:process_extra_comment_params, [@comment,params])
  76 + end
75 77
76 respond_to do |format| 78 respond_to do |format|
77 format.js do 79 format.js do
@@ -113,6 +115,8 @@ class CommentController &lt; ApplicationController @@ -113,6 +115,8 @@ class CommentController &lt; ApplicationController
113 115
114 def update 116 def update
115 if @comment.update_attributes(params[:comment]) 117 if @comment.update_attributes(params[:comment])
  118 + @plugins.dispatch(:process_extra_comment_params, [@comment,params])
  119 +
116 respond_to do |format| 120 respond_to do |format|
117 format.js do 121 format.js do
118 comment_to_render = @comment.comment_root 122 comment_to_render = @comment.comment_root
app/controllers/public/content_viewer_controller.rb
@@ -111,6 +111,15 @@ class ContentViewerController &lt; ApplicationController @@ -111,6 +111,15 @@ class ContentViewerController &lt; ApplicationController
111 @comments = @plugins.filter(:unavailable_comments, @comments) 111 @comments = @plugins.filter(:unavailable_comments, @comments)
112 @comments_count = @comments.count 112 @comments_count = @comments.count
113 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) 113 @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] )
  114 + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
  115 +
  116 + if request.xhr? and params[:comment_order]
  117 + if @comment_order == 'newest'
  118 + @comments = @comments.reverse
  119 + end
  120 +
  121 + return render :partial => 'comment/comment', :collection => @comments
  122 + end
114 123
115 if params[:slideshow] 124 if params[:slideshow]
116 render :action => 'slideshow', :layout => 'slideshow' 125 render :action => 'slideshow', :layout => 'slideshow'
app/controllers/public/events_controller.rb
@@ -7,11 +7,11 @@ class EventsController &lt; PublicController @@ -7,11 +7,11 @@ class EventsController &lt; PublicController
7 @date = build_date(params[:year], params[:month], params[:day]) 7 @date = build_date(params[:year], params[:month], params[:day])
8 8
9 if !params[:year] && !params[:month] && !params[:day] 9 if !params[:year] && !params[:month] && !params[:day]
10 - @events = profile.events.next_events_from_month(@date) 10 + @events = profile.events.next_events_from_month(@date).paginate(:per_page => per_page, :page => params[:page])
11 end 11 end
12 12
13 if params[:year] || params[:month] 13 if params[:year] || params[:month]
14 - @events = profile.events.by_month(@date) 14 + @events = profile.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page])
15 end 15 end
16 16
17 events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month) 17 events_in_range = profile.events.by_range((@date - 1.month).at_beginning_of_month .. (@date + 1.month).at_end_of_month)
@@ -29,4 +29,7 @@ class EventsController &lt; PublicController @@ -29,4 +29,7 @@ class EventsController &lt; PublicController
29 29
30 include EventsHelper 30 include EventsHelper
31 31
  32 + def per_page
  33 + 20
  34 + end
32 end 35 end
app/controllers/public/profile_controller.rb
@@ -67,7 +67,7 @@ class ProfileController &lt; PublicController @@ -67,7 +67,7 @@ class ProfileController &lt; PublicController
67 67
68 def members 68 def members
69 if is_cache_expired?(profile.members_cache_key(params)) 69 if is_cache_expired?(profile.members_cache_key(params))
70 - @members = profile.members.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage]) 70 + @members = profile.members_by_name.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
71 end 71 end
72 end 72 end
73 73
@@ -304,14 +304,6 @@ class ProfileController &lt; PublicController @@ -304,14 +304,6 @@ class ProfileController &lt; PublicController
304 end 304 end
305 end 305 end
306 306
307 - def profile_info  
308 - begin  
309 - @block = profile.blocks.find(params[:block_id])  
310 - rescue  
311 - render :text => _('Profile information could not be loaded')  
312 - end  
313 - end  
314 -  
315 def report_abuse 307 def report_abuse
316 @abuse_report = AbuseReport.new 308 @abuse_report = AbuseReport.new
317 render :layout => false 309 render :layout => false
app/controllers/public/search_controller.rb
@@ -99,14 +99,14 @@ class SearchController &lt; PublicController @@ -99,14 +99,14 @@ class SearchController &lt; PublicController
99 @events = [] 99 @events = []
100 if params[:day] || !params[:year] && !params[:month] 100 if params[:day] || !params[:year] && !params[:month]
101 @events = @category ? 101 @events = @category ?
102 - environment.events.by_day(@date).in_category(Category.find(@category_id)) :  
103 - environment.events.by_day(@date) 102 + environment.events.by_day(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) :
  103 + environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
104 end 104 end
105 105
106 if params[:year] || params[:month] 106 if params[:year] || params[:month]
107 @events = @category ? 107 @events = @category ?
108 - environment.events.by_month(@date).in_category(Category.find(@category_id)) :  
109 - environment.events.by_month(@date) 108 + environment.events.by_month(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) :
  109 + environment.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page])
110 end 110 end
111 111
112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events 112 @scope = date_range && params[:action] == 'events' ? environment.events.by_range(date_range) : environment.events
@@ -139,7 +139,7 @@ class SearchController &lt; PublicController @@ -139,7 +139,7 @@ class SearchController &lt; PublicController
139 139
140 def events_by_day 140 def events_by_day
141 @date = build_date(params[:year], params[:month], params[:day]) 141 @date = build_date(params[:year], params[:month], params[:day])
142 - @events = environment.events.by_day(@date) 142 + @events = environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page])
143 render :partial => 'events/events' 143 render :partial => 'events/events'
144 end 144 end
145 145
@@ -224,4 +224,8 @@ class SearchController &lt; PublicController @@ -224,4 +224,8 @@ class SearchController &lt; PublicController
224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations) 224 @environment.send(klass.name.underscore.pluralize).visible.includes(relations)
225 end 225 end
226 226
  227 + def per_page
  228 + 20
  229 + end
  230 +
227 end 231 end
app/controllers/themes_controller.rb 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +class ThemesController < ApplicationController
  2 +
  3 + before_filter :login_required
  4 +
  5 + no_design_blocks
  6 +
  7 + # attr_reader :target
  8 +
  9 + def target
  10 + @target
  11 + end
  12 +
  13 + def index
  14 + @environment = environment
  15 + @themes = (environment.themes + Theme.approved_themes(target)).sort_by { |t| t.name }
  16 +
  17 + @current_theme = target.theme
  18 +
  19 + @layout_templates = LayoutTemplate.all
  20 + @current_template = target.layout_template
  21 + end
  22 +
  23 + def set
  24 + target.update_theme(params[:id])
  25 + redirect_to :action => 'index'
  26 + end
  27 +
  28 + def unset
  29 + if target.kind_of?(Environment)
  30 + target.update_theme('default')
  31 + else
  32 + target.update_theme(nil)
  33 + end
  34 + redirect_to :action => 'index'
  35 + end
  36 +
  37 + def set_layout_template
  38 + target.update_layout_template(params[:id])
  39 + redirect_to :action => 'index'
  40 + end
  41 +
  42 +end
app/helpers/application_helper.rb
@@ -608,49 +608,18 @@ module ApplicationHelper @@ -608,49 +608,18 @@ module ApplicationHelper
608 end 608 end
609 609
610 attr_reader :environment 610 attr_reader :environment
  611 +
611 def select_categories(object_name, title=nil, title_size=4) 612 def select_categories(object_name, title=nil, title_size=4)
612 return nil if environment.enabled?(:disable_categories) 613 return nil if environment.enabled?(:disable_categories)
613 if title.nil? 614 if title.nil?
614 title = _('Categories') 615 title = _('Categories')
615 end 616 end
616 617
617 - object = instance_variable_get("@#{object_name}")  
618 -  
619 - result = content_tag 'h'+title_size.to_s(), title  
620 - result << javascript_tag( 'function open_close_cat( link ) {  
621 - var div = link.parentNode.getElementsByTagName("div")[0];  
622 - var end = function(){  
623 - if ( div.style.display == "none" ) {  
624 - this.link.className="button icon-button icon-down"  
625 - } else {  
626 - this.link.className="button icon-button icon-up-red"  
627 - }  
628 - }  
629 - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } )  
630 - }')  
631 - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel|  
632 - next unless object.accept_category?(toplevel)  
633 - # FIXME  
634 - ([toplevel] + toplevel.children_for_menu).each do |cat|  
635 - if cat.top_level?  
636 - result << '<div class="categorie_box">'.html_safe  
637 - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )  
638 - result << content_tag('h5', toplevel.name)  
639 - result << '<div style="display:none"><ul class="categories">'.html_safe  
640 - else  
641 - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"  
642 - result << content_tag('li', labelled_check_box(  
643 - cat.full_name_without_leading(1, " &rarr; "),  
644 - "#{object_name}[category_ids][]", cat.id,  
645 - object.category_ids.include?(cat.id), :id => checkbox_id,  
646 - :onchange => 'this.parentNode.className=(this.checked?"cat_checked":"")' ),  
647 - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"  
648 - end  
649 - end  
650 - result << '</ul></div></div>'.html_safe  
651 - end 618 + @object = instance_variable_get("@#{object_name}")
  619 + @categories = environment.top_level_categories
652 620
653 - content_tag('div', result) 621 + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?}
  622 + render :partial => 'shared/select_categories_top', :locals => {:object_name => object_name, :title => title, :title_size => title_size, :multiple => true, :categories_selected => @object.categories }, :layout => false
654 end 623 end
655 624
656 def theme_option(opt = nil) 625 def theme_option(opt = nil)
@@ -920,12 +889,11 @@ module ApplicationHelper @@ -920,12 +889,11 @@ module ApplicationHelper
920 889
921 def page_title 890 def page_title
922 (@page ? @page.title + ' - ' : '') + 891 (@page ? @page.title + ' - ' : '') +
923 - (profile ? profile.short_name + ' - ' : '') +  
924 (@topic ? @topic.title + ' - ' : '') + 892 (@topic ? @topic.title + ' - ' : '') +
925 (@section ? @section.title + ' - ' : '') + 893 (@section ? @section.title + ' - ' : '') +
926 (@toc ? _('Online Manual') + ' - ' : '') + 894 (@toc ? _('Online Manual') + ' - ' : '') +
927 (@controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') + 895 (@controller.controller_name == 'chat' ? _('Chat') + ' - ' : '') +
928 - environment.name + 896 + (profile ? profile.short_name : environment.name) +
929 (@category ? " - #{@category.full_name}" : '') 897 (@category ? " - #{@category.full_name}" : '')
930 end 898 end
931 899
@@ -1382,16 +1350,16 @@ module ApplicationHelper @@ -1382,16 +1350,16 @@ module ApplicationHelper
1382 end 1350 end
1383 1351
1384 def convert_macro(html, source) 1352 def convert_macro(html, source)
1385 - doc = Nokogiri::HTML(html) 1353 + doc = Hpricot(html)
1386 #TODO This way is more efficient but do not support macro inside of 1354 #TODO This way is more efficient but do not support macro inside of
1387 # macro. You must parse them from the inside-out in order to enable 1355 # macro. You must parse them from the inside-out in order to enable
1388 # that. 1356 # that.
1389 - doc.css('.macro').each do |macro| 1357 + doc.search('.macro').each do |macro|
1390 macro_name = macro['data-macro'] 1358 macro_name = macro['data-macro']
1391 result = @plugins.parse_macro(macro_name, macro, source) 1359 result = @plugins.parse_macro(macro_name, macro, source)
1392 - macro.content = result.kind_of?(Proc) ? self.instance_eval(&result) : result 1360 + macro.inner_html = result.kind_of?(Proc) ? self.instance_eval(&result) : result
1393 end 1361 end
1394 - CGI.unescapeHTML(doc.xpath('//body/*').to_s) 1362 + doc.html
1395 end 1363 end
1396 1364
1397 def default_folder_for_image_upload(profile) 1365 def default_folder_for_image_upload(profile)
app/helpers/article_helper.rb
@@ -49,8 +49,14 @@ module ArticleHelper @@ -49,8 +49,14 @@ module ArticleHelper
49 'div', 49 'div',
50 check_box(:article, :display_versions) + 50 check_box(:article, :display_versions) +
51 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') 51 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
52 - ) : '') 52 + ) : '') +
53 53
  54 + (article.forum? && article.profile.community? ?
  55 + content_tag(
  56 + 'div',
  57 + check_box(:article, :allows_members_to_create_topics) +
  58 + content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')
  59 + ) : '')
54 ) 60 )
55 end 61 end
56 62
app/helpers/boxes_helper.rb
@@ -39,7 +39,7 @@ module BoxesHelper @@ -39,7 +39,7 @@ module BoxesHelper
39 end 39 end
40 40
41 def display_boxes(holder, main_content) 41 def display_boxes(holder, main_content)
42 - boxes = holder.boxes.first(holder.boxes_limit) 42 + boxes = holder.boxes.with_position.first(holder.boxes_limit)
43 content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n") 43 content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n")
44 content = main_content if (content.blank?) 44 content = main_content if (content.blank?)
45 45
@@ -65,7 +65,7 @@ module BoxesHelper @@ -65,7 +65,7 @@ module BoxesHelper
65 end 65 end
66 66
67 def display_box_content(box, main_content) 67 def display_box_content(box, main_content)
68 - context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params } 68 + context = { :article => @page, :request_path => request.path, :locale => locale, :params => request.params, :user => user }
69 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box) 69 box_decorator.select_blocks(box.blocks.includes(:box), context).map { |item| display_block(item, main_content) }.join("\n") + box_decorator.block_target(box)
70 end 70 end
71 71
@@ -212,7 +212,7 @@ module BoxesHelper @@ -212,7 +212,7 @@ module BoxesHelper
212 212
213 if !block.main? 213 if !block.main?
214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')}) 214 buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post', :confirm => _('Are you sure you want to remove this block?')})
215 - buttons << icon_button(:clone, _('Clone'), { :action => 'clone', :id => block.id }, { :method => 'post' }) 215 + buttons << icon_button(:clone, _('Clone'), { :action => 'clone_block', :id => block.id }, { :method => 'post' })
216 end 216 end
217 217
218 if block.respond_to?(:help) 218 if block.respond_to?(:help)
app/helpers/cache_counter_helper.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +module CacheCounterHelper
  2 + def update_cache_counter(name, object, value)
  3 + if object.present?
  4 + object.class.update_counters(object.id, name => value)
  5 + end
  6 + end
  7 +end
app/helpers/categories_helper.rb
@@ -48,4 +48,12 @@ module CategoriesHelper @@ -48,4 +48,12 @@ module CategoriesHelper
48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) 48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value)))
49 end 49 end
50 50
  51 + #FIXME make this test
  52 + def selected_category_link(cat)
  53 + content_tag('div', button_to_function_without_text(:remove, _('Remove'), nil) {|page| page["selected-category-#{cat.id}"].remove} +
  54 + link_to_function(cat.full_name(' &rarr; '), nil, :id => "remove-selected-category-#{cat.id}-button", :class => 'select-subcategory-link') {|page| page["selected-category-#{cat.id}"].remove},
  55 + :class => 'selected-category'
  56 + )
  57 + end
  58 +
51 end 59 end
app/helpers/comment_helper.rb
@@ -2,7 +2,6 @@ module CommentHelper @@ -2,7 +2,6 @@ module CommentHelper
2 2
3 def article_title(article, args = {}) 3 def article_title(article, args = {})
4 title = article.title 4 title = article.title
5 - title = article.display_title if article.kind_of?(UploadedFile) && article.image?  
6 title = content_tag('h1', h(title), :class => 'title') 5 title = content_tag('h1', h(title), :class => 'title')
7 if article.belongs_to_blog? 6 if article.belongs_to_blog?
8 unless args[:no_link] 7 unless args[:no_link]
@@ -22,6 +21,12 @@ module CommentHelper @@ -22,6 +21,12 @@ module CommentHelper
22 title 21 title
23 end 22 end
24 23
  24 + def comment_extra_contents(comment)
  25 + @plugins.dispatch(:comment_extra_contents, comment).collect do |extra_content|
  26 + extra_content.kind_of?(Proc) ? self.instance_eval(&extra_content) : extra_content
  27 + end.join('\n')
  28 + end
  29 +
25 def comment_actions(comment) 30 def comment_actions(comment)
26 url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id) 31 url = url_for(:profile => profile.identifier, :controller => :comment, :action => :check_actions, :id => comment.id)
27 links = links_for_comment_actions(comment) 32 links = links_for_comment_actions(comment)
app/helpers/content_viewer_helper.rb
@@ -14,8 +14,7 @@ module ContentViewerHelper @@ -14,8 +14,7 @@ module ContentViewerHelper
14 end 14 end
15 15
16 def article_title(article, args = {}) 16 def article_title(article, args = {})
17 - title = article.display_title if article.kind_of?(UploadedFile) && article.image?  
18 - title = article.title if title.blank? 17 + title = article.title
19 title = content_tag('h1', h(title), :class => 'title') 18 title = content_tag('h1', h(title), :class => 'title')
20 if article.belongs_to_blog? || article.belongs_to_forum? 19 if article.belongs_to_blog? || article.belongs_to_forum?
21 unless args[:no_link] 20 unless args[:no_link]
@@ -52,15 +51,6 @@ module ContentViewerHelper @@ -52,15 +51,6 @@ module ContentViewerHelper
52 end 51 end
53 end 52 end
54 53
55 - def addthis_facebook_url(article)  
56 - "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % {  
57 - :title => CGI.escape(article.title),  
58 - :url => CGI.escape(url_for(article.url)),  
59 - :summary => CGI.escape(truncate(strip_tags(article.body.to_s), :length => 300)),  
60 - :image => CGI.escape(article.body_images_paths.first.to_s)  
61 - }  
62 - end  
63 -  
64 def addthis_image_tag 54 def addthis_image_tag
65 if File.exists?(File.join(Rails.root, 'public', theme_path, 'images', 'addthis.gif')) 55 if File.exists?(File.join(Rails.root, 'public', theme_path, 'images', 'addthis.gif'))
66 image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') 56 image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '')
app/helpers/layout_helper.rb
@@ -90,5 +90,8 @@ module LayoutHelper @@ -90,5 +90,8 @@ module LayoutHelper
90 end 90 end
91 end 91 end
92 92
  93 + def meta_description_tag(article=nil)
  94 + article ? truncate(strip_tags(article.body.to_s), :length => 200) : environment.name
  95 + end
93 end 96 end
94 97
app/helpers/macros_helper.rb
@@ -20,14 +20,16 @@ module MacrosHelper @@ -20,14 +20,16 @@ module MacrosHelper
20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({ 20 jQuery('<div>'+#{macro_configuration_dialog(macro).to_json}+'</div>').dialog({
21 title: #{macro_title(macro).to_json}, 21 title: #{macro_title(macro).to_json},
22 modal: true, 22 modal: true,
23 - buttons: [  
24 - {text: #{_('Ok').to_json}, click: function(){ 23 + buttons: {
  24 + #{_('Ok').to_json}: function(){
25 tinyMCE.activeEditor.execCommand('mceInsertContent', false, 25 tinyMCE.activeEditor.execCommand('mceInsertContent', false,
26 (function(dialog){ #{macro_generator(macro)} })(this)); 26 (function(dialog){ #{macro_generator(macro)} })(this));
27 jQuery(this).dialog('close'); 27 jQuery(this).dialog('close');
28 - }},  
29 - {text: #{_('Cancel').to_json}, click: function(){jQuery(this).dialog('close');}}  
30 - ] 28 + },
  29 + #{_('Cancel').to_json}: function(){
  30 + jQuery(this).dialog('close');
  31 + }
  32 + }
31 }); 33 });
32 }" 34 }"
33 end 35 end
@@ -57,7 +59,11 @@ module MacrosHelper @@ -57,7 +59,11 @@ module MacrosHelper
57 59
58 def macro_generator(macro) 60 def macro_generator(macro)
59 if macro.configuration[:generator] 61 if macro.configuration[:generator]
60 - macro.configuration[:generator] 62 + if macro.configuration[:generator].respond_to?(:call)
  63 + macro.configuration[:generator].call(macro)
  64 + else
  65 + macro.configuration[:generator]
  66 + end
61 else 67 else
62 macro_default_generator(macro) 68 macro_default_generator(macro)
63 end 69 end
@@ -66,8 +72,7 @@ module MacrosHelper @@ -66,8 +72,7 @@ module MacrosHelper
66 72
67 def macro_default_generator(macro) 73 def macro_default_generator(macro)
68 code = "var params = {};" 74 code = "var params = {};"
69 - configuration = macro_configuration(macro)  
70 - configuration[:params].map do |field| 75 + macro.configuration[:params].map do |field|
71 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();" 76 code += "params.#{field[:name]} = jQuery('*[name=#{field[:name]}]', dialog).val();"
72 end 77 end
73 code + " 78 code + "
app/helpers/person_notifier_helper.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +module PersonNotifierHelper
  2 +
  3 + include ApplicationHelper
  4 +
  5 + private
  6 +
  7 + def path_to_image(source)
  8 + top_url + source
  9 + end
  10 +
  11 + def top_url
  12 + top_url = @profile.environment ? @profile.environment.top_url : ''
  13 + end
  14 +
  15 +end
app/helpers/token_helper.rb
@@ -27,7 +27,7 @@ module TokenHelper @@ -27,7 +27,7 @@ module TokenHelper
27 hintText: #{options[:hint_text].to_json}, 27 hintText: #{options[:hint_text].to_json},
28 noResultsText: #{options[:no_results_text].to_json}, 28 noResultsText: #{options[:no_results_text].to_json},
29 searchingText: #{options[:searching_text].to_json}, 29 searchingText: #{options[:searching_text].to_json},
30 - searchDelay: #{options[:serach_delay].to_json}, 30 + searchDelay: #{options[:search_delay].to_json},
31 preventDuplicates: #{options[:prevent_duplicates].to_json}, 31 preventDuplicates: #{options[:prevent_duplicates].to_json},
32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, 32 backspaceDeleteItem: #{options[:backspace_delete_item].to_json},
33 queryParam: #{name.to_json}, 33 queryParam: #{name.to_json},
app/models/block.rb
@@ -22,11 +22,13 @@ class Block &lt; ActiveRecord::Base @@ -22,11 +22,13 @@ class Block &lt; ActiveRecord::Base
22 # 22 #
23 # * <tt>:article</tt>: the article being viewed currently 23 # * <tt>:article</tt>: the article being viewed currently
24 # * <tt>:language</tt>: in which language the block will be displayed 24 # * <tt>:language</tt>: in which language the block will be displayed
  25 + # * <tt>:user</tt>: the logged user
25 def visible?(context = nil) 26 def visible?(context = nil)
26 return false if display == 'never' 27 return false if display == 'never'
27 28
28 if context 29 if context
29 return false if language != 'all' && language != context[:locale] 30 return false if language != 'all' && language != context[:locale]
  31 + return false unless display_to_user?(context[:user])
30 32
31 begin 33 begin
32 return self.send("display_#{display}", context) 34 return self.send("display_#{display}", context)
@@ -38,6 +40,10 @@ class Block &lt; ActiveRecord::Base @@ -38,6 +40,10 @@ class Block &lt; ActiveRecord::Base
38 true 40 true
39 end 41 end
40 42
  43 + def display_to_user?(user)
  44 + display_user == 'all' || (user.nil? && display_user == 'not_logged') || (user && display_user == 'logged')
  45 + end
  46 +
41 def display_always(context) 47 def display_always(context)
42 true 48 true
43 end 49 end
@@ -68,6 +74,14 @@ class Block &lt; ActiveRecord::Base @@ -68,6 +74,14 @@ class Block &lt; ActiveRecord::Base
68 # the homepage of its owner. 74 # the homepage of its owner.
69 settings_items :display, :type => :string, :default => 'always' 75 settings_items :display, :type => :string, :default => 'always'
70 76
  77 +
  78 + # The condition for displaying a block to users. It can assume the following values:
  79 + #
  80 + # * <tt>'all'</tt>: the block is always displayed
  81 + # * <tt>'logged'</tt>: the block is displayed to logged users only
  82 + # * <tt>'not_logged'</tt>: the block is displayed only to not logged users
  83 + settings_items :display_user, :type => :string, :default => 'all'
  84 +
71 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: 85 # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment:
72 # 86 #
73 # * <tt>'all'</tt>: the block is always displayed 87 # * <tt>'all'</tt>: the block is always displayed
@@ -141,7 +155,7 @@ class Block &lt; ActiveRecord::Base @@ -141,7 +155,7 @@ class Block &lt; ActiveRecord::Base
141 end 155 end
142 156
143 alias :active_record_cache_key :cache_key 157 alias :active_record_cache_key :cache_key
144 - def cache_key(language='en') 158 + def cache_key(language='en', user=nil)
145 active_record_cache_key+'-'+language 159 active_record_cache_key+'-'+language
146 end 160 end
147 161
@@ -171,12 +185,20 @@ class Block &lt; ActiveRecord::Base @@ -171,12 +185,20 @@ class Block &lt; ActiveRecord::Base
171 'never' => __('Don\'t display'), 185 'never' => __('Don\'t display'),
172 } 186 }
173 187
174 - def display_options 188 + def display_options_available
175 DISPLAY_OPTIONS.keys 189 DISPLAY_OPTIONS.keys
176 end 190 end
177 191
178 - def display_option_label(option)  
179 - DISPLAY_OPTIONS[option] 192 + def display_options
  193 + DISPLAY_OPTIONS.slice(*display_options_available)
  194 + end
  195 +
  196 + def display_user_options
  197 + @display_user_options ||= {
  198 + 'all' => __('All users'),
  199 + 'logged' => __('Logged'),
  200 + 'not_logged' => __('Not logged'),
  201 + }
180 end 202 end
181 203
182 def duplicate 204 def duplicate
app/models/box.rb
@@ -5,12 +5,14 @@ class Box &lt; ActiveRecord::Base @@ -5,12 +5,14 @@ class Box &lt; ActiveRecord::Base
5 5
6 include Noosfero::Plugin::HotSpot 6 include Noosfero::Plugin::HotSpot
7 7
  8 + named_scope :with_position, :conditions => ['boxes.position > 0']
  9 +
8 def environment 10 def environment
9 owner ? (owner.kind_of?(Environment) ? owner : owner.environment) : nil 11 owner ? (owner.kind_of?(Environment) ? owner : owner.environment) : nil
10 end 12 end
11 13
12 def acceptable_blocks 14 def acceptable_blocks
13 - blocks_classes = central? ? Box.acceptable_center_blocks + plugins.dispatch(:extra_blocks, :position => 1) : Box.acceptable_side_blocks + plugins.dispatch(:extra_blocks, :position => [2, 3]) 15 + blocks_classes = central? ? Box.acceptable_center_blocks + plugins.dispatch(:extra_blocks, :type => owner.class, :position => 1) : Box.acceptable_side_blocks + plugins.dispatch(:extra_blocks, :type => owner.class, :position => [2, 3])
14 to_css_class_name(blocks_classes) 16 to_css_class_name(blocks_classes)
15 end 17 end
16 18
@@ -24,6 +26,8 @@ class Box &lt; ActiveRecord::Base @@ -24,6 +26,8 @@ class Box &lt; ActiveRecord::Base
24 CategoriesBlock, 26 CategoriesBlock,
25 CommunitiesBlock, 27 CommunitiesBlock,
26 EnterprisesBlock, 28 EnterprisesBlock,
  29 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  30 + # the Noosfero core soon, see ActionItem3045
27 EnvironmentStatisticsBlock, 31 EnvironmentStatisticsBlock,
28 FansBlock, 32 FansBlock,
29 FavoriteEnterprisesBlock, 33 FavoriteEnterprisesBlock,
@@ -50,6 +54,8 @@ class Box &lt; ActiveRecord::Base @@ -50,6 +54,8 @@ class Box &lt; ActiveRecord::Base
50 CommunitiesBlock, 54 CommunitiesBlock,
51 DisabledEnterpriseMessageBlock, 55 DisabledEnterpriseMessageBlock,
52 EnterprisesBlock, 56 EnterprisesBlock,
  57 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  58 + # the Noosfero core soon, see ActionItem3045
53 EnvironmentStatisticsBlock, 59 EnvironmentStatisticsBlock,
54 FansBlock, 60 FansBlock,
55 FavoriteEnterprisesBlock, 61 FavoriteEnterprisesBlock,
app/models/comment.rb
@@ -172,7 +172,7 @@ class Comment &lt; ActiveRecord::Base @@ -172,7 +172,7 @@ class Comment &lt; ActiveRecord::Base
172 def mail(comment) 172 def mail(comment)
173 profile = comment.article.profile 173 profile = comment.article.profile
174 recipients comment.notification_emails 174 recipients comment.notification_emails
175 - from "#{profile.environment.name} <#{profile.environment.contact_email}>" 175 + from "#{profile.environment.name} <#{profile.environment.noreply_email}>"
176 subject _("[%s] you got a new comment!") % [profile.environment.name] 176 subject _("[%s] you got a new comment!") % [profile.environment.name]
177 body :recipient => profile.nickname || profile.name, 177 body :recipient => profile.nickname || profile.name,
178 :sender => comment.author_name, 178 :sender => comment.author_name,
@@ -187,7 +187,7 @@ class Comment &lt; ActiveRecord::Base @@ -187,7 +187,7 @@ class Comment &lt; ActiveRecord::Base
187 def mail_to_followers(comment, emails) 187 def mail_to_followers(comment, emails)
188 profile = comment.article.profile 188 profile = comment.article.profile
189 bcc emails 189 bcc emails
190 - from "#{profile.environment.name} <#{profile.environment.contact_email}>" 190 + from "#{profile.environment.name} <#{profile.environment.noreply_email}>"
191 subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name] 191 subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name]
192 body :recipient => profile.nickname || profile.name, 192 body :recipient => profile.nickname || profile.name,
193 :sender => comment.author_name, 193 :sender => comment.author_name,
app/models/contact.rb
@@ -26,7 +26,7 @@ class Contact &lt; ActiveRecord::Base #WithoutTable @@ -26,7 +26,7 @@ class Contact &lt; ActiveRecord::Base #WithoutTable
26 content_type 'text/html' 26 content_type 'text/html'
27 emails = contact.dest.notification_emails 27 emails = contact.dest.notification_emails
28 recipients emails 28 recipients emails
29 - from "#{contact.name} <#{contact.dest.environment.contact_email}>" 29 + from "#{contact.name} <#{contact.dest.environment.noreply_email}>"
30 reply_to contact.email 30 reply_to contact.email
31 if contact.sender 31 if contact.sender
32 headers 'X-Noosfero-Sender' => contact.sender.identifier 32 headers 'X-Noosfero-Sender' => contact.sender.identifier
app/models/environment.rb
@@ -26,7 +26,8 @@ class Environment &lt; ActiveRecord::Base @@ -26,7 +26,8 @@ class Environment &lt; ActiveRecord::Base
26 'manage_environment_users' => N_('Manage environment users'), 26 'manage_environment_users' => N_('Manage environment users'),
27 'manage_environment_templates' => N_('Manage environment templates'), 27 'manage_environment_templates' => N_('Manage environment templates'),
28 'manage_environment_licenses' => N_('Manage environment licenses'), 28 'manage_environment_licenses' => N_('Manage environment licenses'),
29 - 'manage_environment_trusted_sites' => N_('Manage environment trusted sites') 29 + 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
  30 + 'edit_appearance' => N_('Edit appearance'),
30 } 31 }
31 32
32 module Roles 33 module Roles
@@ -144,6 +145,18 @@ class Environment &lt; ActiveRecord::Base @@ -144,6 +145,18 @@ class Environment &lt; ActiveRecord::Base
144 end 145 end
145 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true 146 validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true
146 147
  148 + def self.signup_redirection_options
  149 + {
  150 + 'keep_on_same_page' => _('Stays on the same page the user was before signup.'),
  151 + 'site_homepage' => _('Redirects the user to the environment homepage.'),
  152 + 'user_profile_page' => _('Redirects the user to his profile page.'),
  153 + 'user_homepage' => _('Redirects the user to his homepage.'),
  154 + 'user_control_panel' => _('Redirects the user to his control panel.')
  155 + }
  156 + end
  157 + validates_inclusion_of :redirection_after_signup, :in => Environment.signup_redirection_options.keys, :allow_nil => true
  158 +
  159 +
147 # ################################################# 160 # #################################################
148 # Relationships and applied behaviour 161 # Relationships and applied behaviour
149 # ################################################# 162 # #################################################
@@ -160,6 +173,8 @@ class Environment &lt; ActiveRecord::Base @@ -160,6 +173,8 @@ class Environment &lt; ActiveRecord::Base
160 173
161 # "left" area 174 # "left" area
162 env.boxes[1].blocks << LoginBlock.new 175 env.boxes[1].blocks << LoginBlock.new
  176 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  177 + # the Noosfero core soon, see ActionItem3045
163 env.boxes[1].blocks << EnvironmentStatisticsBlock.new 178 env.boxes[1].blocks << EnvironmentStatisticsBlock.new
164 env.boxes[1].blocks << RecentDocumentsBlock.new 179 env.boxes[1].blocks << RecentDocumentsBlock.new
165 180
@@ -185,7 +200,7 @@ class Environment &lt; ActiveRecord::Base @@ -185,7 +200,7 @@ class Environment &lt; ActiveRecord::Base
185 has_many :product_categories, :conditions => { :type => 'ProductCategory'} 200 has_many :product_categories, :conditions => { :type => 'ProductCategory'}
186 has_many :regions 201 has_many :regions
187 202
188 - has_many :roles 203 + has_many :roles, :dependent => :destroy
189 204
190 has_many :qualifiers 205 has_many :qualifiers
191 has_many :certifiers 206 has_many :certifiers
@@ -591,7 +606,7 @@ class Environment &lt; ActiveRecord::Base @@ -591,7 +606,7 @@ class Environment &lt; ActiveRecord::Base
591 # only one environment can be the default one 606 # only one environment can be the default one
592 validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one') 607 validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one')
593 608
594 - validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |record| ! record.contact_email.blank? }) 609 + validates_format_of :contact_email, :noreply_email, :with => Noosfero::Constants::EMAIL_FORMAT, :allow_blank => true
595 610
596 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' 611 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation'
597 612
@@ -677,6 +692,16 @@ class Environment &lt; ActiveRecord::Base @@ -677,6 +692,16 @@ class Environment &lt; ActiveRecord::Base
677 end 692 end
678 end 693 end
679 694
  695 + def update_theme(theme)
  696 + self.theme = theme
  697 + self.save!
  698 + end
  699 +
  700 + def update_layout_template(template)
  701 + self.layout_template = template
  702 + self.save!
  703 + end
  704 +
680 before_create do |env| 705 before_create do |env|
681 env.settings[:themes] ||= %w[ 706 env.settings[:themes] ||= %w[
682 aluminium 707 aluminium
@@ -768,7 +793,7 @@ class Environment &lt; ActiveRecord::Base @@ -768,7 +793,7 @@ class Environment &lt; ActiveRecord::Base
768 end 793 end
769 794
770 def notification_emails 795 def notification_emails
771 - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email) 796 + [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email)
772 end 797 end
773 798
774 after_create :create_templates 799 after_create :create_templates
app/models/environment_statistics_block.rb
  1 +# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  2 +# the Noosfero core soon, see ActionItem3045
  3 +
1 class EnvironmentStatisticsBlock < Block 4 class EnvironmentStatisticsBlock < Block
2 5
3 def self.description 6 def self.description
4 - _('Environment stastistics') 7 + _('Environment stastistics (DEPRECATED)')
5 end 8 end
6 9
7 def default_title 10 def default_title
app/models/event.rb
@@ -38,15 +38,12 @@ class Event &lt; Article @@ -38,15 +38,12 @@ class Event &lt; Article
38 named_scope :next_events_from_month, lambda { |date| 38 named_scope :next_events_from_month, lambda { |date|
39 date_temp = date.strftime("%Y-%m-%d") 39 date_temp = date.strftime("%Y-%m-%d")
40 { :conditions => ["start_date >= ?","#{date_temp}"], 40 { :conditions => ["start_date >= ?","#{date_temp}"],
41 - :limit => 10,  
42 :order => 'start_date ASC' 41 :order => 'start_date ASC'
43 } 42 }
44 } 43 }
45 44
46 named_scope :by_month, lambda { |date| 45 named_scope :by_month, lambda { |date|
47 - date_temp = date.strftime("%Y-%m")  
48 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month], 46 { :conditions => ["EXTRACT(YEAR FROM start_date) = ? AND EXTRACT(MONTH FROM start_date) = ?",date.year,date.month],
49 - :limit => 10,  
50 :order => 'start_date ASC' 47 :order => 'start_date ASC'
51 } 48 }
52 } 49 }
app/models/forum.rb
@@ -5,6 +5,7 @@ class Forum &lt; Folder @@ -5,6 +5,7 @@ class Forum &lt; Folder
5 5
6 settings_items :terms_of_use, :type => :string, :default => "" 6 settings_items :terms_of_use, :type => :string, :default => ""
7 settings_items :has_terms_of_use, :type => :boolean, :default => false 7 settings_items :has_terms_of_use, :type => :boolean, :default => false
  8 + settings_items :allows_members_to_create_topics, :type => :boolean, :default => false
8 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' 9 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
9 10
10 before_save do |forum| 11 before_save do |forum|
@@ -66,4 +67,11 @@ class Forum &lt; Folder @@ -66,4 +67,11 @@ class Forum &lt; Folder
66 self.users_with_agreement.exists? user 67 self.users_with_agreement.exists? user
67 end 68 end
68 69
  70 + def can_create_topic?(user, profile)
  71 + return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics
  72 + end
  73 +
  74 + def allow_create?(user)
  75 + super || can_create_topic?(user, profile)
  76 + end
69 end 77 end
app/models/friendship.rb
1 class Friendship < ActiveRecord::Base 1 class Friendship < ActiveRecord::Base
2 track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person 2 track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person
3 - 3 +
  4 + extend CacheCounterHelper
  5 +
4 belongs_to :person, :foreign_key => :person_id 6 belongs_to :person, :foreign_key => :person_id
5 belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' 7 belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id'
  8 +
  9 + after_create do |friendship|
  10 + update_cache_counter(:friends_count, friendship.person, 1)
  11 + update_cache_counter(:friends_count, friendship.friend, 1)
  12 + end
  13 +
  14 + after_destroy do |friendship|
  15 + update_cache_counter(:friends_count, friendship.person, -1)
  16 + update_cache_counter(:friends_count, friendship.friend, -1)
  17 + end
6 end 18 end
app/models/layout_template.rb
@@ -16,15 +16,15 @@ class LayoutTemplate @@ -16,15 +16,15 @@ class LayoutTemplate
16 end 16 end
17 17
18 def name 18 def name
19 - @config['name'] 19 + _ @config['name']
20 end 20 end
21 21
22 def title 22 def title
23 - @config['title'] 23 + _ @config['title']
24 end 24 end
25 25
26 def description 26 def description
27 - @config['description'] 27 + _ @config['description']
28 end 28 end
29 29
30 def number_of_boxes 30 def number_of_boxes
app/models/link_list_block.rb
@@ -63,13 +63,15 @@ class LinkListBlock &lt; Block @@ -63,13 +63,15 @@ class LinkListBlock &lt; Block
63 def link_html(link) 63 def link_html(link)
64 klass = 'icon-' + link[:icon] if link[:icon] 64 klass = 'icon-' + link[:icon] if link[:icon]
65 sanitize_link( 65 sanitize_link(
66 - link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass) 66 + link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass, :title => link[:title])
67 ) 67 )
68 end 68 end
69 69
70 def expand_address(address) 70 def expand_address(address)
71 add = if owner.respond_to?(:identifier) 71 add = if owner.respond_to?(:identifier)
72 address.gsub('{profile}', owner.identifier) 72 address.gsub('{profile}', owner.identifier)
  73 + elsif owner.is_a?(Environment) && owner.enabled?('use_portal_community') && owner.portal_community
  74 + address.gsub('{portal}', owner.portal_community.identifier)
73 else 75 else
74 address 76 address
75 end 77 end
app/models/mailing.rb
@@ -17,7 +17,7 @@ class Mailing &lt; ActiveRecord::Base @@ -17,7 +17,7 @@ class Mailing &lt; ActiveRecord::Base
17 end 17 end
18 18
19 def generate_from 19 def generate_from
20 - "#{source.name} <#{source.contact_email}>" 20 + "#{source.name} <#{if source.is_a? Environment then source.noreply_email else source.contact_email end}>"
21 end 21 end
22 22
23 def generate_subject 23 def generate_subject
app/models/main_block.rb
@@ -24,7 +24,7 @@ class MainBlock &lt; Block @@ -24,7 +24,7 @@ class MainBlock &lt; Block
24 false 24 false
25 end 25 end
26 26
27 - def display_options 27 + def display_options_available
28 ['always', 'except_home_page'] 28 ['always', 'except_home_page']
29 end 29 end
30 30
app/models/members_block.rb
@@ -36,4 +36,15 @@ class MembersBlock &lt; ProfileListBlock @@ -36,4 +36,15 @@ class MembersBlock &lt; ProfileListBlock
36 } 36 }
37 end 37 end
38 38
  39 + def cache_key(language='en', user=nil)
  40 + logged = ''
  41 + if user
  42 + logged += '-logged-in'
  43 + if user.is_member_of? self.owner
  44 + logged += '-member'
  45 + end
  46 + end
  47 + super + logged
  48 + end
  49 +
39 end 50 end
app/models/organization.rb
@@ -26,18 +26,7 @@ class Organization &lt; Profile @@ -26,18 +26,7 @@ class Organization &lt; Profile
26 26
27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' 27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source'
28 28
29 - named_scope :more_popular,  
30 - :select => "#{Profile.qualified_column_names}, count(resource_id) as total",  
31 - :group => Profile.qualified_column_names,  
32 - :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id",  
33 - :order => "total DESC"  
34 -  
35 - named_scope :more_active,  
36 - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",  
37 - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id",  
38 - :group => Profile.qualified_column_names,  
39 - :order => 'total DESC',  
40 - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] 29 + named_scope :more_popular, :order => 'members_count DESC'
41 30
42 def validation_methodology 31 def validation_methodology
43 self.validation_info ? self.validation_info.validation_methodology : nil 32 self.validation_info ? self.validation_info.validation_methodology : nil
app/models/organization_mailing.rb
1 class OrganizationMailing < Mailing 1 class OrganizationMailing < Mailing
2 2
3 def generate_from 3 def generate_from
4 - "#{person.name} <#{source.environment.contact_email}>" 4 + "#{person.name} <#{source.environment.noreply_email}>"
5 end 5 end
6 6
7 def recipients(offset=0, limit=100) 7 def recipients(offset=0, limit=100)
app/models/pending_task_notifier.rb
@@ -2,7 +2,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base @@ -2,7 +2,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base
2 2
3 def notification(person) 3 def notification(person)
4 recipients person.email 4 recipients person.email
5 - from "#{person.environment.name} <#{person.environment.contact_email}>" 5 + from "#{person.environment.name} <#{person.environment.noreply_email}>"
6 subject _("[%s] Pending tasks") % person.environment.name 6 subject _("[%s] Pending tasks") % person.environment.name
7 body :person => person, 7 body :person => person,
8 :tasks => person.tasks.pending, 8 :tasks => person.tasks.pending,
app/models/person.rb
@@ -71,18 +71,7 @@ class Person &lt; Profile @@ -71,18 +71,7 @@ class Person &lt; Profile
71 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' 71 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
72 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' 72 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
73 73
74 - named_scope :more_popular,  
75 - :select => "#{Profile.qualified_column_names}, count(friend_id) as total",  
76 - :group => Profile.qualified_column_names,  
77 - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id",  
78 - :order => "total DESC"  
79 -  
80 - named_scope :more_active,  
81 - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",  
82 - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id",  
83 - :group => Profile.qualified_column_names,  
84 - :order => 'total DESC',  
85 - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] 74 + named_scope :more_popular, :order => 'friends_count DESC'
86 75
87 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' 76 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*'
88 named_scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*" 77 named_scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*"
@@ -501,6 +490,17 @@ class Person &lt; Profile @@ -501,6 +490,17 @@ class Person &lt; Profile
501 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default) 490 gravatar_profile_image_url(self.email, :size=>20, :d => gravatar_default)
502 end 491 end
503 492
  493 + settings_items :last_notification, :type => DateTime
  494 + settings_items :notification_time, :type => :integer, :default => 0
  495 +
  496 + def notifier
  497 + @notifier ||= PersonNotifier.new(self)
  498 + end
  499 +
  500 + after_update do |person|
  501 + person.notifier.reschedule_next_notification_mail
  502 + end
  503 +
504 protected 504 protected
505 505
506 def followed_by?(profile) 506 def followed_by?(profile)
app/models/person_notifier.rb 0 → 100644
@@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
  1 +class PersonNotifier
  2 +
  3 + def initialize(person)
  4 + @person = person
  5 + end
  6 +
  7 + def self.schedule_all_next_notification_mail
  8 + Delayed::Job.enqueue(NotifyAllJob.new) unless NotifyAllJob.exists?
  9 + end
  10 +
  11 + def schedule_next_notification_mail
  12 + dispatch_notification_mail if !NotifyJob.exists?(@person.id)
  13 + end
  14 +
  15 + def dispatch_notification_mail
  16 + Delayed::Job.enqueue(NotifyJob.new(@person.id), nil, @person.notification_time.hours.from_now) if @person.notification_time>0
  17 + end
  18 +
  19 + def reschedule_next_notification_mail
  20 + return nil unless @person.setting_changed?(:notification_time) || @person.setting_changed?(:last_notification)
  21 + NotifyJob.find(@person.id).delete_all
  22 + schedule_next_notification_mail
  23 + end
  24 +
  25 + def notify
  26 + if @person.notification_time && @person.notification_time > 0
  27 + from = @person.last_notification || DateTime.now - @person.notification_time.hours
  28 + notifications = @person.tracked_notifications.find(:all, :conditions => ["created_at > ?", from])
  29 + Noosfero.with_locale @person.environment.default_language do
  30 + Mailer::deliver_content_summary(@person, notifications) unless notifications.empty?
  31 + end
  32 + @person.settings[:last_notification] = DateTime.now
  33 + @person.save!
  34 + end
  35 + end
  36 +
  37 + class NotifyAllJob
  38 + def self.exists?
  39 + Delayed::Job.where(:handler => "--- !ruby/object:PersonNotifier::NotifyAllJob {}\n\n").count > 0
  40 + end
  41 +
  42 + def perform
  43 + Person.find_each {|person| person.notifier.schedule_next_notification_mail }
  44 + end
  45 + end
  46 +
  47 + class NotifyJob < Struct.new(:person_id)
  48 +
  49 + def self.exists?(person_id)
  50 + !find(person_id).empty?
  51 + end
  52 +
  53 + def self.find(person_id)
  54 + Delayed::Job.where(:handler => "--- !ruby/struct:PersonNotifier::NotifyJob \nperson_id: #{person_id}\n")
  55 + end
  56 +
  57 + def perform
  58 + Person.find(person_id).notifier.notify
  59 + end
  60 +
  61 + def on_permanent_failure
  62 + person = Person.find(person_id)
  63 + person.notifier.dispatch_notification_mail
  64 + end
  65 +
  66 + end
  67 +
  68 + class Mailer < ActionMailer::Base
  69 +
  70 + add_template_helper(PersonNotifierHelper)
  71 +
  72 + def session
  73 + {:theme => nil}
  74 + end
  75 +
  76 + def content_summary(person, notifications)
  77 + @current_theme = 'default'
  78 + @profile = person
  79 + recipients person.email
  80 + from "#{@profile.environment.name} <#{@profile.environment.contact_email}>"
  81 + subject _("[%s] Network Activity") % [@profile.environment.name]
  82 + body :recipient => @profile.nickname || @profile.name,
  83 + :environment => @profile.environment.name,
  84 + :url => @profile.environment.top_url,
  85 + :notifications => notifications
  86 + content_type "text/html"
  87 + end
  88 + end
  89 +end
app/models/profile.rb
@@ -88,8 +88,8 @@ class Profile &lt; ActiveRecord::Base @@ -88,8 +88,8 @@ class Profile &lt; ActiveRecord::Base
88 ScopeTool.union *scopes 88 ScopeTool.union *scopes
89 end 89 end
90 90
91 - def members_count  
92 - members.count 91 + def members_by_name
  92 + members.order(:name)
93 end 93 end
94 94
95 class << self 95 class << self
@@ -114,10 +114,11 @@ class Profile &lt; ActiveRecord::Base @@ -114,10 +114,11 @@ class Profile &lt; ActiveRecord::Base
114 114
115 named_scope :visible, :conditions => { :visible => true } 115 named_scope :visible, :conditions => { :visible => true }
116 named_scope :public, :conditions => { :visible => true, :public_profile => true } 116 named_scope :public, :conditions => { :visible => true, :public_profile => true }
117 - # Subclasses must override these methods 117 +
  118 + # Subclasses must override this method
118 named_scope :more_popular 119 named_scope :more_popular
119 - named_scope :more_active  
120 120
  121 + named_scope :more_active, :order => 'activities_count DESC'
121 named_scope :more_recent, :order => "created_at DESC" 122 named_scope :more_recent, :order => "created_at DESC"
122 123
123 acts_as_trackable :dependent => :destroy 124 acts_as_trackable :dependent => :destroy
@@ -612,10 +613,10 @@ private :generate_url, :url_options @@ -612,10 +613,10 @@ private :generate_url, :url_options
612 # Adds a person as member of this Profile. 613 # Adds a person as member of this Profile.
613 def add_member(person) 614 def add_member(person)
614 if self.has_members? 615 if self.has_members?
615 - if self.closed? && members_count > 0 616 + if self.closed? && members.count > 0
616 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) 617 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
617 else 618 else
618 - self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0 619 + self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0
619 self.affiliate(person, Profile::Roles.member(environment.id)) 620 self.affiliate(person, Profile::Roles.member(environment.id))
620 end 621 end
621 else 622 else
app/models/scrap.rb
@@ -14,7 +14,7 @@ class Scrap &lt; ActiveRecord::Base @@ -14,7 +14,7 @@ class Scrap &lt; ActiveRecord::Base
14 14
15 named_scope :not_replies, :conditions => {:scrap_id => nil} 15 named_scope :not_replies, :conditions => {:scrap_id => nil}
16 16
17 - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target 17 + track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target
18 18
19 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} 19 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver}
20 20
@@ -59,7 +59,7 @@ class Scrap &lt; ActiveRecord::Base @@ -59,7 +59,7 @@ class Scrap &lt; ActiveRecord::Base
59 sender, receiver = scrap.sender, scrap.receiver 59 sender, receiver = scrap.sender, scrap.receiver
60 recipients receiver.email 60 recipients receiver.email
61 61
62 - from "#{sender.environment.name} <#{sender.environment.contact_email}>" 62 + from "#{sender.environment.name} <#{sender.environment.noreply_email}>"
63 subject _("[%s] You received a scrap!") % [sender.environment.name] 63 subject _("[%s] You received a scrap!") % [sender.environment.name]
64 body :recipient => receiver.name, 64 body :recipient => receiver.name,
65 :sender => sender.name, 65 :sender => sender.name,
app/models/task_mailer.rb
@@ -60,7 +60,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -60,7 +60,7 @@ class TaskMailer &lt; ActionMailer::Base
60 end 60 end
61 61
62 def self.generate_from(task) 62 def self.generate_from(task)
63 - "#{task.environment.name} <#{task.environment.contact_email}>" 63 + "#{task.environment.name} <#{task.environment.noreply_email}>"
64 end 64 end
65 65
66 def generate_environment_url(task, url = {}) 66 def generate_environment_url(task, url = {})
app/models/theme.rb
@@ -42,17 +42,25 @@ class Theme @@ -42,17 +42,25 @@ class Theme
42 end 42 end
43 43
44 def approved_themes(owner) 44 def approved_themes(owner)
45 - Dir.glob(File.join(system_themes_dir, '*')).select do |item|  
46 - if File.exists?( File.join(item, 'theme.yml') )  
47 - config = YAML.load_file(File.join(item, 'theme.yml'))  
48 - (config['owner_type'] == owner.class.base_class.name) &&  
49 - (config['owner_id'] == owner.id) || config['public'] 45 + Dir.glob(File.join(system_themes_dir, '*')).map do |item|
  46 + next unless File.exists? File.join(item, 'theme.yml')
  47 + id = File.basename item
  48 + config = YAML.load_file File.join(item, 'theme.yml')
  49 +
  50 + approved = config['public']
  51 + unless approved
  52 + begin
  53 + approved = owner.kind_of?(config['owner_type'].constantize)
  54 + rescue
  55 + end
  56 + approved &&= config['owner_id'] == owner.id if config['owner_id'].present?
50 end 57 end
51 - end.map do |desc|  
52 - new(File.basename(desc)) 58 +
  59 + [id, config] if approved
  60 + end.compact.map do |id, config|
  61 + new id, config
53 end 62 end
54 end 63 end
55 -  
56 end 64 end
57 65
58 class DuplicatedIdentifier < Exception; end 66 class DuplicatedIdentifier < Exception; end
app/models/uploaded_file.rb
@@ -12,15 +12,12 @@ class UploadedFile &lt; Article @@ -12,15 +12,12 @@ class UploadedFile &lt; Article
12 12
13 include ShortFilename 13 include ShortFilename
14 14
15 - settings_items :title, :type => 'string'  
16 - xss_terminate :only => [ :title ]  
17 -  
18 - def title_with_default  
19 - title_without_default || short_filename(name, 60) 15 + def title
  16 + if self.name.present? then self.name else self.filename end
  17 + end
  18 + def title= value
  19 + self.name = value
20 end 20 end
21 - alias_method_chain :title, :default  
22 -  
23 - validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? })  
24 21
25 sanitize_filename 22 sanitize_filename
26 23
@@ -32,10 +29,6 @@ class UploadedFile &lt; Article @@ -32,10 +29,6 @@ class UploadedFile &lt; Article
32 self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil 29 self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil
33 end 30 end
34 31
35 - def display_title  
36 - title.blank? ? name : title  
37 - end  
38 -  
39 def first_paragraph 32 def first_paragraph
40 '' 33 ''
41 end 34 end
@@ -109,7 +102,7 @@ class UploadedFile &lt; Article @@ -109,7 +102,7 @@ class UploadedFile &lt; Article
109 alias :orig_set_filename :filename= 102 alias :orig_set_filename :filename=
110 def filename=(value) 103 def filename=(value)
111 orig_set_filename(value) 104 orig_set_filename(value)
112 - self.name = self.filename 105 + self.name ||= self.filename
113 end 106 end
114 107
115 def download_headers 108 def download_headers
app/models/user.rb
@@ -54,7 +54,7 @@ class User &lt; ActiveRecord::Base @@ -54,7 +54,7 @@ class User &lt; ActiveRecord::Base
54 def activation_email_notify(user) 54 def activation_email_notify(user)
55 user_email = "#{user.login}@#{user.email_domain}" 55 user_email = "#{user.login}@#{user.email_domain}"
56 recipients user_email 56 recipients user_email
57 - from "#{user.environment.name} <#{user.environment.contact_email}>" 57 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
58 subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name } 58 subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name }
59 body :name => user.name, 59 body :name => user.name,
60 :email => user_email, 60 :email => user_email,
@@ -66,12 +66,13 @@ class User &lt; ActiveRecord::Base @@ -66,12 +66,13 @@ class User &lt; ActiveRecord::Base
66 def activation_code(user) 66 def activation_code(user)
67 recipients user.email 67 recipients user.email
68 68
69 - from "#{user.environment.name} <#{user.environment.contact_email}>" 69 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
70 subject _("[%s] Activate your account") % [user.environment.name] 70 subject _("[%s] Activate your account") % [user.environment.name]
71 body :recipient => user.name, 71 body :recipient => user.name,
72 :activation_code => user.activation_code, 72 :activation_code => user.activation_code,
73 :environment => user.environment.name, 73 :environment => user.environment.name,
74 - :url => user.environment.top_url 74 + :url => user.environment.top_url,
  75 + :redirection => (true if user.return_to)
75 end 76 end
76 77
77 def signup_welcome_email(user) 78 def signup_welcome_email(user)
@@ -81,7 +82,7 @@ class User &lt; ActiveRecord::Base @@ -81,7 +82,7 @@ class User &lt; ActiveRecord::Base
81 content_type 'text/html' 82 content_type 'text/html'
82 recipients user.email 83 recipients user.email
83 84
84 - from "#{user.environment.name} <#{user.environment.contact_email}>" 85 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
85 subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject 86 subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject
86 body email_body 87 body email_body
87 end 88 end
@@ -93,7 +94,7 @@ class User &lt; ActiveRecord::Base @@ -93,7 +94,7 @@ class User &lt; ActiveRecord::Base
93 self.person.save! 94 self.person.save!
94 end 95 end
95 end 96 end
96 - 97 +
97 has_one :person, :dependent => :destroy 98 has_one :person, :dependent => :destroy
98 belongs_to :environment 99 belongs_to :environment
99 100
@@ -183,7 +184,7 @@ class User &lt; ActiveRecord::Base @@ -183,7 +184,7 @@ class User &lt; ActiveRecord::Base
183 encryption_methods[sym] = block 184 encryption_methods[sym] = block
184 end 185 end
185 186
186 - # the encryption method used for this instance 187 + # the encryption method used for this instance
187 def encryption_method 188 def encryption_method
188 (password_type || User.system_encryption_method).to_sym 189 (password_type || User.system_encryption_method).to_sym
189 end 190 end
@@ -226,7 +227,7 @@ class User &lt; ActiveRecord::Base @@ -226,7 +227,7 @@ class User &lt; ActiveRecord::Base
226 end 227 end
227 228
228 def remember_token? 229 def remember_token?
229 - remember_token_expires_at && Time.now.utc < remember_token_expires_at 230 + remember_token_expires_at && Time.now.utc < remember_token_expires_at
230 end 231 end
231 232
232 # These create and unset the fields required for remembering users between browser closes 233 # These create and unset the fields required for remembering users between browser closes
@@ -255,7 +256,7 @@ class User &lt; ActiveRecord::Base @@ -255,7 +256,7 @@ class User &lt; ActiveRecord::Base
255 raise IncorrectPassword unless self.authenticated?(current) 256 raise IncorrectPassword unless self.authenticated?(current)
256 self.force_change_password!(new, confirmation) 257 self.force_change_password!(new, confirmation)
257 end 258 end
258 - 259 +
259 # Changes the password of a user without asking for the old password. This 260 # Changes the password of a user without asking for the old password. This
260 # method is intended to be used by the "I forgot my password", and must be 261 # method is intended to be used by the "I forgot my password", and must be
261 # used with care. 262 # used with care.
@@ -326,7 +327,7 @@ class User &lt; ActiveRecord::Base @@ -326,7 +327,7 @@ class User &lt; ActiveRecord::Base
326 end 327 end
327 328
328 protected 329 protected
329 - # before filter 330 + # before filter
330 def encrypt_password 331 def encrypt_password
331 return if password.blank? 332 return if password.blank?
332 self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? 333 self.salt ||= Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
app/sweepers/profile_sweeper.rb
@@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer @@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer
8 end 8 end
9 9
10 def after_create(profile) 10 def after_create(profile)
  11 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  12 + # the Noosfero core soon, see ActionItem3045
11 expire_statistics_block_cache(profile) 13 expire_statistics_block_cache(profile)
12 end 14 end
13 15
@@ -29,6 +31,8 @@ protected @@ -29,6 +31,8 @@ protected
29 expire_blogs(profile) if profile.organization? 31 expire_blogs(profile) if profile.organization?
30 end 32 end
31 33
  34 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  35 + # the Noosfero core soon, see ActionItem3045
32 def expire_statistics_block_cache(profile) 36 def expire_statistics_block_cache(profile)
33 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } 37 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) }
34 BlockSweeper.expire_blocks(blocks) 38 BlockSweeper.expire_blocks(blocks)
app/views/admin_panel/_site_info.rhtml
1 <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %> 1 <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %>
2 <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %> 2 <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %>
  3 +<%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
3 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
4 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> 5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %>
5 <%= required f.text_field(:reports_lower_bound, :size => 3) %> 6 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
app/views/admin_panel/index.rhtml
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 <tr><td><%= link_to _('Environment settings'), :action => 'site_info' %></td></tr> 6 <tr><td><%= link_to _('Environment settings'), :action => 'site_info' %></td></tr>
7 <tr><td><%= link_to _('Features'), :controller => 'features' %></td></tr> 7 <tr><td><%= link_to _('Features'), :controller => 'features' %></td></tr>
8 <tr><td><%= link_to _('Plugins'), :controller => 'plugins' %></td></tr> 8 <tr><td><%= link_to _('Plugins'), :controller => 'plugins' %></td></tr>
  9 + <tr><td><%= link_to _('Appearance'), :controller =>'environment_themes' %></td></tr>
9 <tr><td><%= link_to _('Sideboxes'), :controller => 'environment_design'%></td></tr> 10 <tr><td><%= link_to _('Sideboxes'), :controller => 'environment_design'%></td></tr>
10 <tr><td><%= link_to _('Homepage'), :action => 'set_portal_community' %></td></tr> 11 <tr><td><%= link_to _('Homepage'), :action => 'set_portal_community' %></td></tr>
11 <tr><td><%= link_to _('Licenses'), :controller =>'licenses' %></td></tr> 12 <tr><td><%= link_to _('Licenses'), :controller =>'licenses' %></td></tr>
app/views/blocks/location.html.erb
@@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
3 <div class='the-localization-map'> 3 <div class='the-localization-map'>
4 <img src="https://maps.google.com/maps/api/staticmap?center=<%=profile.lat%>,<%=profile.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=profile.lat%>,<%=profile.lng%>&sensor=false"/> 4 <img src="https://maps.google.com/maps/api/staticmap?center=<%=profile.lat%>,<%=profile.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=profile.lat%>,<%=profile.lng%>&sensor=false"/>
5 </div> 5 </div>
6 -</div>  
7 <% else %> 6 <% else %>
8 <i><%= _('This profile has no geographical position registered.') %></i> 7 <i><%= _('This profile has no geographical position registered.') %></i>
9 <% end %> 8 <% end %>
app/views/blocks/profile_image.rhtml
1 <div class="vcard"> 1 <div class="vcard">
2 2
3 -<p><%= block.title %></p> 3 +<% if block.title.present? %>
  4 + <p><%= block.title %></p>
  5 +<% end %>
4 6
5 <div class="profile-big-image"> 7 <div class="profile-big-image">
6 <div class="profile-big-image-inner1"> 8 <div class="profile-big-image-inner1">
@@ -16,7 +18,7 @@ @@ -16,7 +18,7 @@
16 18
17 <% if !user.nil? and user.has_permission?('edit_profile', profile) %> 19 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
18 <div class='admin-link'> 20 <div class='admin-link'>
19 - <%= link_to _('Control panel'), :controller => 'profile_editor' %> 21 + <%= link_to _('Control panel'), block.owner.admin_url %>
20 </div> 22 </div>
21 <% end %> 23 <% end %>
22 24
app/views/blocks/profile_info.rhtml
@@ -21,7 +21,7 @@ @@ -21,7 +21,7 @@
21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li> 21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li>
22 <% end %> 22 <% end %>
23 <% if !user.nil? and user.has_permission?('edit_profile', profile) %> 23 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
24 - <li><%= link_to _('Control panel'), :controller => 'profile_editor' %></li> 24 + <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
25 <% end %> 25 <% end %>
26 <% if profile.person? %> 26 <% if profile.person? %>
27 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li> 27 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li>
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <% end %> 40 <% end %>
41 41
42 <div class="profile-info-options"> 42 <div class="profile-info-options">
43 - <%= render :file => view_for_profile_actions(@block.owner.class) %> 43 + <%= render :file => view_for_profile_actions(block.owner.class) %>
44 </div> 44 </div>
45 45
46 </div><!-- end class="vcard" --> 46 </div><!-- end class="vcard" -->
app/views/box_organizer/_link_list_block.rhtml
  1 +<%= javascript_include_tag "edit-link-list.js" %>
  2 +
1 <strong><%= _('Links') %></strong> 3 <strong><%= _('Links') %></strong>
2 -<div id='edit-link-list-block' style='width:450px'>  
3 -<table id='links' class='noborder'>  
4 - <tr><th><%= _('Icon') %></th><th><%= _('Name') %></th><th><%= _('Address') %></th><th><%= _('Target') %></th></tr>  
5 - <% for link in @block.links do %>  
6 - <tr>  
7 - <td>  
8 - <%= icon_selector(link['icon']) %>  
9 - </td>  
10 - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>  
11 - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>  
12 - <td>  
13 - <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>  
14 - </td>  
15 - </tr>  
16 - <% end %>  
17 -</table> 4 +<div id='edit-link-list-block'>
  5 + <ul class='link-list-header'>
  6 + <li class='link-list-icon'><%= _('Icon') %></li>
  7 + <li class='link-list-name'><%= _('Name') %></li>
  8 + <li class='link-list-address'><%= _('Address') %></li>
  9 + <li class='link-list-target'><%= _('Target') %></li>
  10 + </ul>
  11 + <ul id="dropable-link-list">
  12 + <% for link in @block.links do %>
  13 + <li>
  14 + <ul class="link-list-row">
  15 + <li>
  16 + <%= icon_selector(link['icon']) %>
  17 + </li>
  18 + <li>
  19 + <%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %>
  20 + </li>
  21 + <li>
  22 + <%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %>
  23 + </li>
  24 + <li>
  25 + <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>
  26 + </li>
  27 + <li>
  28 + <%= button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row") %>
  29 + </li>
  30 + </ul>
  31 + </li>
  32 + <% end %>
  33 + </ul>
  34 + <input type="hidden" id="page_url" value="<%=url_for(:action=>'search_autocomplete')%>" />
18 </div> 35 </div>
19 36
20 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| 37 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page|
21 - page.insert_html :bottom, 'links', content_tag('tr',  
22 - content_tag('td', icon_selector('ok')) +  
23 - content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +  
24 - content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') +  
25 - content_tag('td', select_tag('block[links][][target]',  
26 -options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) 38 + page.insert_html :bottom, 'dropable-link-list', content_tag('li',
  39 + content_tag('ul',
  40 + content_tag('li', icon_selector('ok')) +
  41 + content_tag('li', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
  42 + content_tag('li', text_field_tag('block[links][][address]', nil, :class => 'link-address')) +
  43 + content_tag('li', select_tag('block[links][][target]',
  44 + options_for_select(LinkListBlock::TARGET_OPTIONS, '_self'))) +
  45 + content_tag('li', button_without_text(:delete, _('Delete'), "#" , :class=>"delete-link-list-row")),
  46 + :class=>"link-list-row new_link_row")
27 ) + 47 ) +
28 - javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 48 + javascript_tag("new_link_action()")
29 end %> 49 end %>
app/views/box_organizer/edit.rhtml
@@ -7,13 +7,14 @@ @@ -7,13 +7,14 @@
7 7
8 <%= render :partial => partial_for_class(@block.class) %> 8 <%= render :partial => partial_for_class(@block.class) %>
9 9
10 - <%= labelled_form_field _('Display this block:'), '' %>  
11 - <div style='margin-left: 10px'>  
12 - <% @block.display_options.each do |option| %>  
13 - <%= radio_button(:block, :display, option) %>  
14 - <%= label_tag("block_display_#{option}", _(@block.display_option_label(option))) %>  
15 - <br/>  
16 - <% end %> 10 + <div class="display">
  11 + <%= labelled_form_field _('Display this block:'),
  12 + select_tag('block[display]', options_from_collection_for_select(@block.display_options, :first, :last, @block.display))
  13 + %>
  14 + </div>
  15 + <div class="display_user">
  16 + <%= labelled_form_field _('Display to users:'), '' %>
  17 + <%= select_tag('block[display_user]', options_from_collection_for_select(@block.display_user_options, :first, :last, @block.display_user)) %>
17 </div> 18 </div>
18 19
19 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %> 20 <%= labelled_form_field(_('Show for:'), select(:block, :language, [ [ _('all languages'), 'all']] + environment.locales.map {|key, value| [value, key]} )) %>
app/views/cms/edit.rhtml
1 <%= error_messages_for 'article' %> 1 <%= error_messages_for 'article' %>
2 -<%= javascript_include_tag "article.js" %>  
3 2
4 <div class='<%= (environment.enabled?('media_panel') ? 'with_media_panel' : 'no_media_panel') %>'> 3 <div class='<%= (environment.enabled?('media_panel') ? 'with_media_panel' : 'no_media_panel') %>'>
5 <% labelled_form_for 'article', @article, :html => { :multipart => true, :class => @type } do |f| %> 4 <% labelled_form_for 'article', @article, :html => { :multipart => true, :class => @type } do |f| %>
@@ -63,3 +62,5 @@ @@ -63,3 +62,5 @@
63 <% end %> 62 <% end %>
64 63
65 <br style='clear: both'/> 64 <br style='clear: both'/>
  65 +
  66 +<%= javascript_include_tag "article.js" %>
app/views/comment/_comment.rhtml
@@ -43,6 +43,7 @@ @@ -43,6 +43,7 @@
43 <p/> 43 <p/>
44 <%= txt2html comment.body %> 44 <%= txt2html comment.body %>
45 </div> 45 </div>
  46 + <%= @plugins.dispatch(:comment_extra_contents, local_assigns).collect { |content| instance_eval(&content) }.join("") %>
46 </div> 47 </div>
47 48
48 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>"> 49 <div class="comment_reply post_comment_box closed" id="comment_reply_to_<%= comment.id %>">
app/views/content_viewer/_addthis.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<div id="addThis">
  2 + <script type="text/javascript">
  3 + addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>';
  4 + addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>';
  5 + addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';
  6 + </script>
  7 + <a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a>
  8 +</div>
app/views/content_viewer/_article_toolbar.rhtml
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 <%= expirable_button @page, :spread, content, url if url %> 26 <%= expirable_button @page, :spread, content, url if url %>
27 <% end %> 27 <% end %>
28 28
29 - <% if !@page.gallery? && @page.allow_create?(user) %> 29 + <% if !@page.gallery? && (@page.allow_create?(user) || (@page.parent && @page.parent.allow_create?(user))) %>
30 <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %> 30 <% if @page.translatable? && !@page.native_translation.language.blank? && !remove_content_button(:locale) %>
31 <% content = _('Add translation') %> 31 <% content = _('Add translation') %>
32 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %> 32 <% parent_id = (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)) %>
app/views/content_viewer/view_page.rhtml
@@ -40,32 +40,10 @@ @@ -40,32 +40,10 @@
40 </div> 40 </div>
41 <% end %> 41 <% end %>
42 42
43 -<% if !@page.tags.empty? %>  
44 - <div id="article-tags">  
45 - <%= _("This article's tags:") %>  
46 - <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>  
47 - </div>  
48 -<% end %>  
49 -  
50 -  
51 <%= render :partial => 'shared/disabled_enterprise' %> 43 <%= render :partial => 'shared/disabled_enterprise' %>
52 44
53 <% if NOOSFERO_CONF['addthis_enabled'] %> 45 <% if NOOSFERO_CONF['addthis_enabled'] %>
54 -<div id="addThis">  
55 -<script type="text/javascript">  
56 - addthis_pub = '<%= escape_javascript( NOOSFERO_CONF['addthis_pub'] ) %>';  
57 - addthis_logo = '<%= escape_javascript( NOOSFERO_CONF['addthis_logo'] ) %>';  
58 - addthis_config = {  
59 - services_custom: {  
60 - name: 'Facebook',  
61 - url: '<%= addthis_facebook_url(@page) %>',  
62 - icon: 'http://cache.addthiscdn.com/icons/v1/thumbs/facebook.gif'  
63 - }  
64 - };  
65 - addthis_options = '<%= escape_javascript( NOOSFERO_CONF['addthis_options'] ) %>';  
66 -</script>  
67 -<a href="http://www.addthis.com/bookmark.php" id="bt_addThis" target="_blank" onmouseover="return addthis_open(this, '', '[URL]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><%= addthis_image_tag %></a>  
68 -</div> 46 + <%= render :partial => 'addthis' %>
69 <% end %> 47 <% end %>
70 48
71 <% cache(@page.cache_key(params, user, language)) do %> 49 <% cache(@page.cache_key(params, user, language)) do %>
@@ -83,8 +61,17 @@ @@ -83,8 +61,17 @@
83 </div> 61 </div>
84 <% end %> 62 <% end %>
85 63
  64 +<% if !@page.tags.empty? %>
  65 + <div id="article-tags">
  66 + <%= _("This article's tags:") %>
  67 + <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  68 + </div>
  69 +<% end %>
  70 +
86 <%= display_source_info(@page) %> 71 <%= display_source_info(@page) %>
87 72
  73 +<%= @plugins.dispatch(:article_extra_contents, @page).collect { |content| instance_eval(&content) }.join("") %>
  74 +
88 <div class="comments" id="comments_list"> 75 <div class="comments" id="comments_list">
89 76
90 <% if @page.accept_comments? || @comments_count > 0 %> 77 <% if @page.accept_comments? || @comments_count > 0 %>
@@ -93,8 +80,26 @@ @@ -93,8 +80,26 @@
93 </h3> 80 </h3>
94 <% end %> 81 <% end %>
95 82
96 - <% if @page.accept_comments? && @comments.count > 1 %> 83 + <% if @page.accept_comments? && @comments_count > 1 %>
97 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %> 84 <%= link_to(_('Post a comment'), '#', :class => 'display-comment-form', :id => 'top-post-comment-button', :onclick => "jQuery('#page-comment-form .display-comment-form').first().click();") %>
  85 +
  86 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %>
  87 + <%= javascript_include_tag "comment_order.js" %>
  88 + <div class="comment-order">
  89 + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  90 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  91 + <% end %>
  92 + </div>
  93 + <% end %>
  94 +
  95 + <% if @page.accept_comments? and @comments.count > 1 %>
  96 + <%= hidden_field_tag("page_url", url_for(:controller=>'content_viewer', :action=>'view_page', :profile=>profile.identifier)) %>
  97 + <%= javascript_include_tag "comment_order.js" %>
  98 + <div class="comment-order">
  99 + <% form_tag({:controller=>'content_viewer' , :action=>'view_page'}, {:method=>'get', :id=>"form_order"}) do %>
  100 + <%= select_tag 'comment_order', options_for_select({_('Oldest first')=>'oldest', _('Newest first')=>'newest'}, @comment_order) %>
  101 + <% end %>
  102 + </div>
98 <% end %> 103 <% end %>
99 104
100 <ul class="article-comments-list"> 105 <ul class="article-comments-list">
app/views/environment_themes/index.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%= render :partial => 'themes/select_template' %>
  2 +<%= render :partial => 'themes/select_theme' %>
  3 +
  4 +<br style="clear:both" />
  5 +
  6 +<% button_bar do %>
  7 + <%= button(:back, _('Back'), :controller => 'admin_panel', :action => 'index') %>
  8 +<% end %>
app/views/events/_events.rhtml
1 -<%= list_events(@date, @events) %>  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +<%= list_events(@date, @events) %>
  3 +
  4 +<%= pagination_links @events, :param_name => 'page' %>
app/views/features/_manage_community_fields.rhtml
1 -<h2><%= __('Manage community fields') %></h2>  
2 -  
3 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %> 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %>
4 2
5 <table id='community_fields_conf'> 3 <table id='community_fields_conf'>
@@ -9,21 +7,37 @@ @@ -9,21 +7,37 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on creation?') %></th> 8 <th><%= _('Display on creation?') %></th>
11 </tr> 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="community_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="community_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="community_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 <% @community_fields.each do |field| %> 26 <% @community_fields.each do |field| %>
13 <tr> 27 <tr>
14 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 28 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 29
16 <td> 30 <td>
17 <%= hidden_field_tag "community_fields[#{field}][active]", false %> 31 <%= hidden_field_tag "community_fields[#{field}][active]", false %>
18 - <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "$('community_fields[#{field}][required]').disabled=$('community_fields[#{field}][signup]').disabled=!this.checked;" %> 32 + <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "active_action(this, 'community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
19 </td> 33 </td>
20 <td> 34 <td>
21 <%= hidden_field_tag "community_fields[#{field}][required]", false %> 35 <%= hidden_field_tag "community_fields[#{field}][required]", false %>
22 - <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "if(this.checked) $('community_fields[#{field}][signup]').checked = true;" %> 36 + <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "required_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
23 </td> 37 </td>
24 <td> 38 <td>
25 <%= hidden_field_tag "community_fields[#{field}][signup]", false %> 39 <%= hidden_field_tag "community_fields[#{field}][signup]", false %>
26 - <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "if(!this.checked) $('community_fields[#{field}][required]').checked = false;" %> 40 + <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "signup_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
27 </td> 41 </td>
28 42
29 </tr> 43 </tr>
@@ -31,18 +45,18 @@ @@ -31,18 +45,18 @@
31 </table> 45 </table>
32 46
33 <script type='text/javascript'> 47 <script type='text/javascript'>
34 - var trs = $$('#community_fields_conf tr'); 48 + var trs = jQuery('#community_fields_conf tr');
35 var tr, td2; 49 var tr, td2;
36 - for ( var i=0; tr=trs[i]; i++ ) { 50 + for ( var i=2; tr=trs[i]; i++ ) {
37 if ( td2 = tr.getElementsByTagName('td')[1] ) { 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38 - td2.getElementsByTagName('input')[0].onclick(); 52 + td2.getElementsByTagName('input')[1].onclick();
39 } 53 }
40 } 54 }
41 </script> 55 </script>
42 56
43 <div> 57 <div>
44 <% button_bar do %> 58 <% button_bar do %>
45 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_community_fields") %>
46 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 <% end %> 61 <% end %>
48 </div> 62 </div>
app/views/features/_manage_enterprise_fields.rhtml
1 -<h2><%= __('Manage enterprise fields') %></h2>  
2 -  
3 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %> 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %>
4 2
5 <table id='enterprise_fields_conf'> 3 <table id='enterprise_fields_conf'>
@@ -9,21 +7,37 @@ @@ -9,21 +7,37 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on registration?') %></th> 8 <th><%= _('Display on registration?') %></th>
11 </tr> 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="enterprise_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="enterprise_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="enterprise_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 <% @enterprise_fields.each do |field| %> 26 <% @enterprise_fields.each do |field| %>
13 <tr> 27 <tr>
14 28
15 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 29 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
16 <td> 30 <td>
17 <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %> 31 <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %>
18 - <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "$('enterprise_fields[#{field}][required]').disabled=$('enterprise_fields[#{field}][signup]').disabled=!this.checked;" %> 32 + <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "active_action(this, 'enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
19 </td> 33 </td>
20 <td> 34 <td>
21 <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %> 35 <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %>
22 - <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "if(this.checked) $('enterprise_fields[#{field}][signup]').checked = true;" %> 36 + <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "required_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
23 </td> 37 </td>
24 <td> 38 <td>
25 <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %> 39 <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %>
26 - <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "if(!this.checked) $('enterprise_fields[#{field}][required]').checked = false;" %> 40 + <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "signup_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
27 </td> 41 </td>
28 42
29 </tr> 43 </tr>
@@ -31,18 +45,18 @@ @@ -31,18 +45,18 @@
31 </table> 45 </table>
32 46
33 <script type='text/javascript'> 47 <script type='text/javascript'>
34 - var trs = $$('#enterprise_fields_conf tr'); 48 + var trs = jQuery('#enterprise_fields_conf tr');
35 var tr, td2; 49 var tr, td2;
36 - for ( var i=0; tr=trs[i]; i++ ) { 50 + for ( var i=2; tr=trs[i]; i++ ) {
37 if ( td2 = tr.getElementsByTagName('td')[1] ) { 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38 - td2.getElementsByTagName('input')[0].onclick(); 52 + td2.getElementsByTagName('input')[1].onclick();
39 } 53 }
40 } 54 }
41 </script> 55 </script>
42 56
43 <div> 57 <div>
44 <% button_bar do %> 58 <% button_bar do %>
45 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_enterprise_fields") %>
46 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 <% end %> 61 <% end %>
48 </div> 62 </div>
app/views/features/_manage_person_fields.rhtml
1 -<h2><%= _('Manage person fields') %></h2>  
2 -  
3 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %> 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %>
4 2
5 <table id='person_fields_conf'> 3 <table id='person_fields_conf'>
@@ -9,31 +7,48 @@ @@ -9,31 +7,48 @@
9 <th><%= _('Required') %></th> 7 <th><%= _('Required') %></th>
10 <th><%= _('Display on signup?') %></th> 8 <th><%= _('Display on signup?') %></th>
11 </tr> 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="person_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="person_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="person_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 <% @person_fields.each do |field| %> 26 <% @person_fields.each do |field| %>
13 <tr> 27 <tr>
14 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td> 28 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 <td> 29 <td>
16 <%= hidden_field_tag "person_fields[#{field}][active]", false %> 30 <%= hidden_field_tag "person_fields[#{field}][active]", false %>
17 - <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "$('person_fields[#{field}][required]').disabled=$('person_fields[#{field}][signup]').disabled=!this.checked;" %> 31 + <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "active_action(this, 'person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
18 </td> 32 </td>
19 <td> 33 <td>
20 <%= hidden_field_tag "person_fields[#{field}][required]", false %> 34 <%= hidden_field_tag "person_fields[#{field}][required]", false %>
21 - <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "if(this.checked) $('person_fields[#{field}][signup]').checked = true;" %> 35 + <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "required_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
22 </td> 36 </td>
23 <td> 37 <td>
24 <%= hidden_field_tag "person_fields[#{field}][signup]", false %> 38 <%= hidden_field_tag "person_fields[#{field}][signup]", false %>
25 - <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "if(!this.checked) $('person_fields[#{field}][required]').checked = false;" %> 39 + <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "signup_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
26 </td> 40 </td>
27 </tr> 41 </tr>
28 <% end %> 42 <% end %>
29 </table> 43 </table>
30 44
31 <script type='text/javascript'>// <!-- 45 <script type='text/javascript'>// <!--
32 - var trs = $$('#person_fields_conf tr'); 46 + var trs = jQuery('#person_fields_conf tr');
  47 +
33 var tr, td2; 48 var tr, td2;
34 - for ( var i=0; tr=trs[i]; i++ ) { 49 + for ( var i=2; tr=trs[i]; i++ ) {
35 if ( td2 = tr.getElementsByTagName('td')[1] ) { 50 if ( td2 = tr.getElementsByTagName('td')[1] ) {
36 - td2.getElementsByTagName('input')[0].onclick(); 51 + td2.getElementsByTagName('input')[1].onclick();
37 } 52 }
38 } 53 }
39 // --> 54 // -->
@@ -41,7 +56,7 @@ @@ -41,7 +56,7 @@
41 56
42 <div> 57 <div>
43 <% button_bar do %> 58 <% button_bar do %>
44 - <%= submit_button('save', _('Save changes')) %> 59 + <%= submit_button('save', _('Save changes'), :id=>"save_person_fields") %>
45 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %> 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
46 <% end %> 61 <% end %>
47 </div> 62 </div>
app/views/features/index.rhtml
@@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the @@ -26,9 +26,13 @@ Check all the features you want to enable for your environment, uncheck all the
26 26
27 <h2><%= _('Configure features') %></h2> 27 <h2><%= _('Configure features') %></h2>
28 28
  29 +<h3><%= _('Page to redirect after signup') %></h3>
  30 + <%= select 'environment', 'redirection_after_signup', Environment.signup_redirection_options.map{|key,value|[value,key]} %>
  31 +<hr/>
29 <h3><%= _('Page to redirect after login') %></h3> 32 <h3><%= _('Page to redirect after login') %></h3>
30 <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %> 33 <%= select 'environment', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]} %>
31 <hr/> 34 <hr/>
  35 +
32 <h3><%= _('Organization Approval Method') %></h3> 36 <h3><%= _('Organization Approval Method') %></h3>
33 <%= select_organization_approval_method('environment', 'organization_approval_method') %> 37 <%= select_organization_approval_method('environment', 'organization_approval_method') %>
34 <hr/> 38 <hr/>
app/views/features/manage_fields.rhtml
1 -<%= render :partial => 'manage_person_fields' %> 1 +<h1><%= _('Manage fields displayed for profiles') %></h1>
2 2
3 -<% if !environment.enabled?('disable_asset_enterprises') %>  
4 - <%= render :partial => 'manage_enterprise_fields' %> 3 +<% tabs = [] %>
  4 +<% tabs << {:title => _("Person's fields"), :id => 'person-fields',
  5 + :content => (render :partial => 'manage_person_fields')} %>
  6 +<% tabs << {:title => _("Community's fields"), :id => 'community-fields',
  7 + :content => (render :partial => 'manage_community_fields')} %>
  8 +<% unless environment.enabled?('disable_asset_enterprises') %>
  9 + <% tabs << {:title => _("Enterprise's fields"), :id => 'enterprise-fields',
  10 + :content => (render :partial => 'manage_enterprise_fields')} %>
5 <% end %> 11 <% end %>
6 12
7 -<%= render :partial => 'manage_community_fields' %> 13 +<%= render_tabs(tabs) %>
  14 +
  15 +<%= javascript_include_tag "manage-fields.js" %>
app/views/layouts/application-ng.rhtml
@@ -6,6 +6,27 @@ @@ -6,6 +6,27 @@
6 <!--<meta http-equiv="refresh" content="1"/>--> 6 <!--<meta http-equiv="refresh" content="1"/>-->
7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
8 <meta name="description" content="<%= @environment.name %>" /> 8 <meta name="description" content="<%= @environment.name %>" />
  9 +
  10 + <!-- Twitter Card -->
  11 + <meta name="twitter:card" value="summary">
  12 + <meta name="twitter:title" content="<%= h page_title %>">
  13 + <meta name="twitter:description" content="<%= meta_description_tag(@page) %>">
  14 +
  15 + <!-- Open Graph -->
  16 + <meta property="og:type" content="<%= @page ? 'article' : 'website' %>">
  17 + <meta property="og:url" content="<%= @page ? url_for(@page.url) : @environment.top_url %>">
  18 + <meta property="og:title" content="<%= h page_title %>">
  19 + <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>">
  20 + <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>">
  21 +
  22 + <% if @page %>
  23 + <meta property="article:published_time" content="<%= show_date(@page.published_at) %>">
  24 + <% @page.body_images_paths.each do |img| %>
  25 + <meta name="twitter:image" content="<%= img.to_s %>">
  26 + <meta property="og:image" content="<%= img.to_s %>">
  27 + <% end %>
  28 + <% end %>
  29 +
9 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> 30 <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" />
10 <%= noosfero_javascript %> 31 <%= noosfero_javascript %>
11 <%= noosfero_stylesheets %> 32 <%= noosfero_stylesheets %>
app/views/person_notifier/mailer/_add_member_in_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_comment.rhtml 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +<% Comment %>
  2 +<% Profile %>
  3 +<% Person %>
  4 +
  5 +<table style="background: #f0f0f1;border-bottom: 1px solid #d2d2d2 !important;border-top: 1px solid #fff;margin-bottom: 0;">
  6 +<tr>
  7 + <td>
  8 + <% if comment.author %>
  9 + <%= link_to profile_image(comment.author, :minor),
  10 + comment.author_url,
  11 + :class => 'comment-picture',
  12 + :title => comment.author_name
  13 + %>
  14 + <% end %>
  15 + </td>
  16 + <td>
  17 + <%= comment.author.present? ? link_to(comment.author_name, comment.author.url, :style => "font-size: 12px; color: #333; font-weight: bold; text-decoration: none;") : content_tag('strong', comment.author_name) %>
  18 + <% unless comment.title.blank? %>
  19 + <span style="font-size: 12px;"><%= comment.title %></span><br/>
  20 + <% end %>
  21 + <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/>
  22 + <span style="font-size: 8px; color: #444444"><%= time_ago_as_sentence(comment.created_at) %></span>
  23 + <br style="clear: both;" />
  24 +
  25 + <% unless comment.replies.blank? %>
  26 + <ul class="comment-replies">
  27 + <% comment.replies.each do |reply| %>
  28 + <%= render :partial => 'comment', :locals => { :comment => reply } %>
  29 + <% end %>
  30 + </ul>
  31 + <% end %>
  32 + </td>
  33 +</table>
app/views/person_notifier/mailer/_create_article.rhtml 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +<table>
  2 +<tr>
  3 + <td>
  4 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  5 + </td>
  6 + <td>
  7 + <p style="width:550px">
  8 + <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span>
  9 + <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span>
  10 + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span>
  11 + </p>
  12 + <p>
  13 + <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span>
  14 + <br/>
  15 + <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span>
  16 + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') %>
  17 + </p>
  18 + <p><%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %></p>
  19 + </td>
  20 +</tr>
  21 +<tr>
  22 + <td></td>
  23 + <td>
  24 + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %>
  25 + </td>
  26 +</tr>
  27 +</table>
app/views/person_notifier/mailer/_default_activity.rhtml 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +<table>
  2 +<tr>
  3 + <td>
  4 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  5 + </td>
  6 + <td>
  7 + <p style="width:550px">
  8 + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
  9 + <span style="font-size: 10px; color: #444444; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span>
  10 + </p>
  11 + </td>
  12 +</tr>
  13 +<tr>
  14 + <td></td>
  15 + <td>
  16 + <%= render :partial => 'profile_comments', :locals => { :activity => activity } %>
  17 + </td>
  18 +</tr>
  19 +</table>
app/views/person_notifier/mailer/_join_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_leave_scrap.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_leave_scrap_to_self.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_new_friendship.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity } %>
app/views/person_notifier/mailer/_profile_comments.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<% if activity.comments_count > 2 %>
  2 + <div style="font-size: 10px;">
  3 + <% if activity.params['url'].blank? %>
  4 + <%= _("%s comments") % activity.comments_count %>
  5 + <% else %>
  6 + <%= link_to(_("View all %s comments") % activity.comments_count, activity.params['url']) %>
  7 + <% end %>
  8 + </div>
  9 +<% else %>
  10 + <ul>
  11 + <%= render :partial => 'comment', :collection => activity.comments %>
  12 + </ul>
  13 +<% end %>
app/views/person_notifier/mailer/_reply_scrap_on_self.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/person_notifier/mailer/_upload_image.rhtml 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +<table>
  2 + <tr>
  3 + <td>
  4 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  5 + </td>
  6 + <td>
  7 + <p style="width:550px">
  8 + <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
  9 + <span style="font-size: 10px; color: #444444; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span>
  10 + </p>
  11 + </td>
  12 +</tr>
  13 +</table>
  14 +<div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div>
  15 +<br/>
app/views/person_notifier/mailer/content_summary.rhtml 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +<h3><%= _("%s's network activity") % @profile.name %></h3>
  2 +<br/>
  3 +<div>
  4 +<% @notifications.each do |activity| %>
  5 + <div style="border-left:none;border-right:none;border-top:1px solid #ccc;border-bottom:none;padding:10px;width:600px">
  6 + <%= render :partial => activity.verb, :locals => { :activity => activity } rescue "cannot render notification for #{activity.verb}" %>
  7 + </div>
  8 +<% end %>
  9 +</div>
  10 +
  11 +<div style="color:#444444;font-size:11px;">
  12 +<p><%= _("Greetings,") %></p>
  13 +<br/>
  14 +<p>--</p>
  15 +<p><%= _('%s team.') % @environment %></p>
  16 +<p><%= url_for @url %></p>
  17 +</div>
  18 +<br/>
app/views/profile_editor/_person.rhtml
@@ -19,3 +19,8 @@ @@ -19,3 +19,8 @@
19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %> 19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_eval(&content) }.join("") %>
20 20
21 <%= render :partial => 'person_form', :locals => {:f => f} %> 21 <%= render :partial => 'person_form', :locals => {:f => f} %>
  22 +
  23 + <h2><%= _('Notification options') %></h2>
  24 + <div>
  25 + <%= select_tag 'profile_data[notification_time]', options_for_select([[_('Disabled'), 0], [_('Hourly'), 1], [_('Half Day'), 12], [_('Daily'), 24]], @profile.notification_time) %>
  26 + </div>
app/views/profile_editor/index.rhtml
@@ -22,7 +22,7 @@ @@ -22,7 +22,7 @@
22 22
23 <%= control_panel_button(_('Edit sideboxes'), 'blocks', :controller => 'profile_design', :action => 'index') %> 23 <%= control_panel_button(_('Edit sideboxes'), 'blocks', :controller => 'profile_design', :action => 'index') %>
24 24
25 - <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'themes', :action => 'index') %> 25 + <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'profile_themes', :action => 'index') %>
26 26
27 <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') unless profile.enterprise? && environment.enabled?('disable_header_and_footer') && !user.is_admin?(environment) %> 27 <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') unless profile.enterprise? && environment.enabled?('disable_header_and_footer') && !user.is_admin?(environment) %>
28 28
app/views/profile_members/_members_list.rhtml
1 -<% collection = @collection == :profile_admins ? profile.admins : profile.members %> 1 +<% collection = @collection == :profile_admins ? profile.admins : profile.members_by_name %>
2 <% title = @title ? @title : _('Current members') %> 2 <% title = @title ? @title : _('Current members') %>
3 <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %> 3 <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %>
4 4
app/views/profile_themes/add_css.rhtml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<h2><%= _('Add a CSS file') %></h2>
  2 +
  3 +<% form_tag do %>
  4 + <%= labelled_form_field(_('File name'), text_field_tag('css')) %>
  5 +
  6 + <% button_bar do %>
  7 + <%= submit_button(:add, _('Add')) %>
  8 + <%= lightbox_close_button(_('Cancel')) %>
  9 + <% end %>
  10 +
  11 +<% end %>
app/views/profile_themes/add_image.rhtml 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +<% form_tag({:action => 'add_image', :id => @theme.id}, :multipart => true) do %>
  2 + <%= labelled_form_field(_('Choose the image file'), file_field_tag(:image)) %>
  3 + <% button_bar do %>
  4 + <%= submit_button(:add, _('Add image')) %>
  5 + <% end %>
  6 +<% end %>
app/views/profile_themes/css_editor.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<h2><%= _('CSS code: "%s"') % @css %></h2>
  2 +
  3 +<% form_tag({:action => 'update_css', :id => @theme.id }, :name => 'csscode_form') do %>
  4 + <%= hidden_field_tag('css', @css) %>
  5 + <%= text_area_tag('csscode', @code, :id => "codepressWindow", :class => 'codepress css') %>
  6 + <% button_bar do %>
  7 + <%= submit_button(:save, _('Save')) %>
  8 + <% end %>
  9 +<% end %>
  10 +
  11 +<!--<script type='text/javascript'>-->
  12 + <!--CodePress.run();-->
  13 +<!--</script>-->
app/views/profile_themes/edit.rhtml 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +<form>
  2 + <%# FIXME %>
  3 + <h1 id='theme-name'>
  4 + <%= _('Editing theme "%s"') % @theme.name %>
  5 + <%= button(:eyes, _('Preview this theme'), :action => 'start_test', :id => @theme.id) %>
  6 + <%= button(:back, _('Back'), :action => 'index') %>
  7 + </h1>
  8 +</form>
  9 +
  10 +
  11 +<div id='css-files-list'>
  12 + <h2><%= _('CSS files') %></h2>
  13 + <ul>
  14 + <% for css in @css_files %>
  15 + <li><%= link_to_remote(css, :url => { :action => 'css_editor', :id => @theme.id, :css => css }, :update => { :success => 'css-code' }) %></li>
  16 + <% end %>
  17 + </ul>
  18 + <% button_bar do %>
  19 + <%= lightbox_button(:add, _('New CSS'), :action => 'add_css', :id => @theme.id) %>
  20 + <% end %>
  21 +</div>
  22 +
  23 +<div id='image-files-list'>
  24 + <h2><%= _('Images') %></h2>
  25 + <ul>
  26 + <% for image in @image_files %>
  27 + <li><%= image_tag("/user_themes/#{@theme.id}/images/#{image}") %></li>
  28 + <% end %>
  29 + </ul>
  30 + <% button_bar do %>
  31 + <%= lightbox_button(:add, _('Add image'), :action => 'add_image', :id => @theme.id) %>
  32 + <% end %>
  33 +</div>
  34 +
  35 +<div id='css-code'>
  36 + <center style='padding-top: 5em;'>
  37 + <em><%= _('Select a CSS file to edit') %></em>
  38 + </center>
  39 +</div>
  40 +
  41 +<%# javascript_include_tag 'codepress/codepress' %>
app/views/profile_themes/index.rhtml 0 → 100644
@@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
  1 +<%= render :partial => 'themes/select_template' %>
  2 +<%= render :partial => 'themes/select_theme' %>
  3 +
  4 +<% if environment.enabled?('user_themes') %>
  5 + <div id="user-themes" class="list-options">
  6 +
  7 + <h2><%= _('My themes') %></h2>
  8 +
  9 + <% for themes in profile.themes.in_groups_of(3) %>
  10 + <div class="list-group">
  11 + <% for theme in themes %><%=
  12 + if theme
  13 +
  14 + selected = theme.id == @current_theme
  15 + sel_html = selected ?
  16 + content_tag('big', _('(current)') ) :
  17 + link_to(_('Use this theme'), :action => 'set', :id => theme.id)
  18 +
  19 + content_tag( 'div',
  20 + image_tag(
  21 + '/images/icons-app/design-editor.png',
  22 + :alt => (_('The "%s" theme.') % theme.name)) +
  23 + '<div class="opt-info">' +
  24 + content_tag('strong', theme.name, :class => 'name') +
  25 + ' <br/> '+ sel_html +' <br/> ' +
  26 + link_to(_('Edit this theme'), :action => 'edit', :id => theme.id) +
  27 + ' <br/> ' +
  28 + link_to(_('Test this theme'), :action => 'start_test', :id => theme.id) +
  29 + '</div>',
  30 + :class => 'theme-opt list-opt' + (selected ? ' selected' : '')
  31 + )
  32 +
  33 + end
  34 + %><% end %>
  35 + </div>
  36 + <% end %>
  37 +
  38 + </div><!-- end id="user-themes" -->
  39 +<% end %>
  40 +
  41 +<br style="clear:both" />
  42 +
  43 +<% button_bar do %>
  44 + <% if environment.enabled?('user_themes') %>
  45 + <%= lightbox_button(:add, _('New theme ...'), :action => 'new') %>
  46 + <% end %>
  47 + <%= button(:back, _('Back'), :controller => 'profile_editor', :action => 'index') %>
  48 +<% end %>
app/views/profile_themes/new.rhtml 0 → 100644
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
  1 +<h2><%= _('Create new theme') %></h2>
  2 +
  3 +<% form_tag(:action => 'new') do %>
  4 +
  5 + <%= labelled_form_field(_('Name of the new theme:'), text_field_tag(:name)) %>
  6 +
  7 + <% button_bar do %>
  8 + <%= submit_button(:save, _('Create')) %>
  9 + <% end %>
  10 +<% end %>
app/views/shared/_lead_and_body.rhtml
@@ -33,4 +33,4 @@ @@ -33,4 +33,4 @@
33 <% end %> 33 <% end %>
34 </div> 34 </div>
35 35
36 -<%= javascript_include_tag 'article'%> 36 +<%= javascript_include_tag 'article-lead-and-body'%>
app/views/shared/_select_categories.rhtml
1 -<div id="category-ajax-selector"> 1 +<% extend CategoriesHelper %>
  2 +
2 <% if !@current_category.nil? %> 3 <% if !@current_category.nil? %>
3 - <h3 class="box-title"><%= _('Current category:') %></h3>  
4 <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> 4 <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %>
  5 + <%= hidden_field_tag "#{object_name}[category_ids][]", @current_category.id if multiple %>
  6 + <%= button_to_remote_without_text(:back, _('Back'),
  7 + { :update => "select-categories",
  8 + :url => { :action => 'update_categories', :id => @object },
  9 + :loaded => visual_effect(:highlight, "select-categories")
  10 + },
  11 + :id => 'cancel-category-button') %>
5 <% 12 <%
6 categories = [@current_category] 13 categories = [@current_category]
7 categories.push(@current_category) while @current_category = @current_category.parent 14 categories.push(@current_category) while @current_category = @current_category.parent
8 %> 15 %>
9 <%= categories.compact.reverse.map{|i| 16 <%= categories.compact.reverse.map{|i|
10 - link_to_remote(i.name, 17 + link_to_remote(i.name,
11 :update => "select-categories", 18 :update => "select-categories",
12 :url => { :action => 'update_categories', :category_id => i.id, :id => @object }, 19 :url => { :action => 'update_categories', :category_id => i.id, :id => @object },
13 :loaded => visual_effect(:highlight, "select-categories"), 20 :loaded => visual_effect(:highlight, "select-categories"),
14 :class => 'select-current-category-link')}.join(' &rarr; ') 21 :class => 'select-current-category-link')}.join(' &rarr; ')
15 %> 22 %>
16 - <strong>  
17 - <%= button_to_function_without_text(:save, _('Save'), nil, :id => 'save-category-button') do |page|  
18 - page.insert_html :bottom, 'selected-categories', content_tag('li', categories.first.full_name + 23 + <%= button_to_function_without_text(:add, _('Add'), nil, :id => 'save-category-button') do |page|
  24 + page.insert_html :bottom, 'selected-categories', content_tag('div',
19 hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + 25 hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) +
20 - button_to_function_without_text(:cancel, _('Remove'), nil, :id => "remove-selected-category-#{categories.first.id}-button") {|page| page["selected-category-#{categories.first.id}"].remove}, :id => "selected-category-#{categories.first.id}") 26 + selected_category_link(categories.first), :id => "selected-category-#{categories.first.id}")
  27 + page.replace_html 'select-categories', :partial => 'shared/select_subcategories',
  28 + :locals => {:object_name => object_name, :categories => @toplevel_categories}
21 end if multiple %> 29 end if multiple %>
22 - <%= button_to_remote_without_text(:cancel, _('Cancel'),  
23 - { :update => "select-categories",  
24 - :url => { :action => 'update_categories', :id => @object },  
25 - :loaded => visual_effect(:highlight, "select-categories")  
26 - },  
27 - :id => 'cancel-category-button') %>  
28 - </strong>  
29 -<% else %>  
30 - <h3 class="box-title"><%= _('Select a category:') %></h3>  
31 <% end %> 30 <% end %>
32 31
33 -<% if !@categories.empty? %>  
34 - <h3><%= _('Categories:') %></h3>  
35 - <% @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)}.each do |category| %>  
36 - <%= link_to_remote category.name,  
37 - { :update => "select-categories",  
38 - :url => { :action => "update_categories", :category_id => category.id, :id => @object},  
39 - :loaded => visual_effect(:highlight, "select-categories")  
40 - },  
41 - :class => 'select-subcategory-link',  
42 - :id => "select-category-#{category.id}-link"  
43 - %>  
44 - <% end %> &nbsp;  
45 -<% end %> 32 +<div class="toplevel-categories">
  33 + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %>
46 </div> 34 </div>