Commit d35779c07490f70c33e688afa945036e075a90f2
Exists in
master
and in
29 other branches
Merge branch 'master' into rails-2.3.5
Conflicts: app/controllers/admin_controller.rb app/controllers/application.rb app/controllers/public/account_controller.rb app/controllers/public/content_viewer_controller.rb lib/noosfero/i18n.rb test/functional/account_controller_test.rb test/functional/admin_controller_test.rb test/unit/contact_test.rb test/unit/profile_test.rb
Showing
842 changed files
with
113986 additions
and
21393 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 842 files displayed.
.mailmap
@@ -3,7 +3,8 @@ Antonio Terceiro <terceiro@colivre.coop.br> <terceiro@softwarelivre.org> | @@ -3,7 +3,8 @@ Antonio Terceiro <terceiro@colivre.coop.br> <terceiro@softwarelivre.org> | ||
3 | Aurelio A. Heckert <aurelio@colivre.coop.br> <AurelioAHeckert@3f533792-8f58-4932-b0fe-aaf55b0a4547> | 3 | Aurelio A. Heckert <aurelio@colivre.coop.br> <AurelioAHeckert@3f533792-8f58-4932-b0fe-aaf55b0a4547> |
4 | Aurelio A. Heckert <aurelio@colivre.coop.br> <aurelio@colivre.coop.br> | 4 | Aurelio A. Heckert <aurelio@colivre.coop.br> <aurelio@colivre.coop.br> |
5 | Aurelio A. Heckert <aurelio@colivre.coop.br> <aurium@gmail.com> | 5 | Aurelio A. Heckert <aurelio@colivre.coop.br> <aurium@gmail.com> |
6 | -Caio SBA <caiosba@gmail.com> <caiosba@safernet.org.br> | 6 | +Caio SBA <caio@colivre.coop.br> <caiosba@gmail.com> |
7 | +Caio SBA <caio@colivre.coop.br> <caiosba@safernet.org.br> | ||
7 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> <DanielaFeitosa@3f533792-8f58-4932-b0fe-aaf55b0a4547> | 8 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> <DanielaFeitosa@3f533792-8f58-4932-b0fe-aaf55b0a4547> |
8 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> <danielafeitosa@colivre.coop.br> | 9 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> <danielafeitosa@colivre.coop.br> |
9 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> <daniela@sede.colivre.coop.br> | 10 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> <daniela@sede.colivre.coop.br> |
AUTHORS
@@ -8,8 +8,9 @@ Developers | @@ -8,8 +8,9 @@ Developers | ||
8 | 8 | ||
9 | Antonio Terceiro <terceiro@colivre.coop.br> | 9 | Antonio Terceiro <terceiro@colivre.coop.br> |
10 | Aurelio A. Heckert <aurelio@colivre.coop.br> | 10 | Aurelio A. Heckert <aurelio@colivre.coop.br> |
11 | +Braulio Bhavamitra <brauliobo@gmail.com> | ||
11 | Bráulio Bhavamitra <brauliobo@gmail.com> | 12 | Bráulio Bhavamitra <brauliobo@gmail.com> |
12 | -Caio SBA <caiosba@gmail.com> | 13 | +Caio SBA <caio@colivre.coop.br> |
13 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | 14 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
14 | Daniel Cunha <daniel@colivre.coop.br> | 15 | Daniel Cunha <daniel@colivre.coop.br> |
15 | Fernanda Lopes <nanda.listas+psl@gmail.com> | 16 | Fernanda Lopes <nanda.listas+psl@gmail.com> |
@@ -23,6 +24,7 @@ LinguÁgil 2010 <linguagil.bahia@gmail.com> | @@ -23,6 +24,7 @@ LinguÁgil 2010 <linguagil.bahia@gmail.com> | ||
23 | Martín Olivera <molivera@solar.org.ar> | 24 | Martín Olivera <molivera@solar.org.ar> |
24 | Moises Machado <moises@colivre.coop.br> | 25 | Moises Machado <moises@colivre.coop.br> |
25 | Nanda Lopes <nanda.listas+psl@gmail.com> | 26 | Nanda Lopes <nanda.listas+psl@gmail.com> |
27 | +Rafael Gomes <rafaelgomes@techfree.com.br> | ||
26 | Raphaël Rousseau <raph@r4f.org> | 28 | Raphaël Rousseau <raph@r4f.org> |
27 | Raquel Lira <raquel.lira@gmail.com> | 29 | Raquel Lira <raquel.lira@gmail.com> |
28 | Rodrigo Souto <rodrigo@colivre.coop.br> | 30 | Rodrigo Souto <rodrigo@colivre.coop.br> |
HACKING
@@ -31,11 +31,13 @@ You can copy and paste the commands below into a terminal (please review the | @@ -31,11 +31,13 @@ You can copy and paste the commands below into a terminal (please review the | ||
31 | commands and make sure you understand what you are doing): | 31 | commands and make sure you understand what you are doing): |
32 | 32 | ||
33 | # checkout the code from repository | 33 | # checkout the code from repository |
34 | - git clone git://git.colivre.coop.br/noosfero.git | 34 | + git clone git://gitorious.org/noosfero/noosfero.git |
35 | # enter the directory | 35 | # enter the directory |
36 | cd noosfero | 36 | cd noosfero |
37 | # copy a sample config file | 37 | # copy a sample config file |
38 | cp config/database.yml.sqlite3 config/database.yml | 38 | cp config/database.yml.sqlite3 config/database.yml |
39 | + # create tmp directory if it doesn't exist | ||
40 | + mkdir tmp | ||
39 | # create the development database | 41 | # create the development database |
40 | rake db:schema:load | 42 | rake db:schema:load |
41 | # run pending migrations | 43 | # run pending migrations |
@@ -59,8 +61,8 @@ another port than 3000, you can use the -p option of ./script/server: | @@ -59,8 +61,8 @@ another port than 3000, you can use the -p option of ./script/server: | ||
59 | 61 | ||
60 | The above command makes the server available at http://localhost:9999/ | 62 | The above command makes the server available at http://localhost:9999/ |
61 | 63 | ||
62 | -The sample-data data scripts creates one administrator user with login "ze" and | ||
63 | -password "test". | 64 | +The sample-data data scripts creates two administrator users with login "ze" and |
65 | +password "test" and login "adminuser" and password "admin". | ||
64 | 66 | ||
65 | Note that some operations, like generating image thumbnails, sending e-mails, | 67 | Note that some operations, like generating image thumbnails, sending e-mails, |
66 | etc, are done in background in the context of a service independent from the | 68 | etc, are done in background in the context of a service independent from the |
@@ -84,3 +86,7 @@ you want to enable it then you need to change some files: | @@ -84,3 +86,7 @@ you want to enable it then you need to change some files: | ||
84 | 86 | ||
85 | 3) Add in config/noosfero.yml at development section: | 87 | 3) Add in config/noosfero.yml at development section: |
86 | exception_recipients: [admin@example.com] | 88 | exception_recipients: [admin@example.com] |
89 | + | ||
90 | +== Releasing and building Debian package | ||
91 | + | ||
92 | +See RELEASING file. |
INSTALL
@@ -43,6 +43,9 @@ case will need do install hicolor-icon-theme as well bacause tango-icon-theme | @@ -43,6 +43,9 @@ case will need do install hicolor-icon-theme as well bacause tango-icon-theme | ||
43 | depends on it. After that you can try the command line above again, but | 43 | depends on it. After that you can try the command line above again, but |
44 | without "tango-icon-theme". | 44 | without "tango-icon-theme". |
45 | 45 | ||
46 | +More Informations to install the tango-icon-theme on Debian Lenny: | ||
47 | +* http://packages.debian.org/en/lenny/all/tango-icon-theme/download | ||
48 | + | ||
46 | If you manage to install Noosfero successfully on other systems than Debian, | 49 | If you manage to install Noosfero successfully on other systems than Debian, |
47 | please feel free to contact the Noosfero development mailing with the | 50 | please feel free to contact the Noosfero development mailing with the |
48 | instructions for doing so, and we'll include it here. | 51 | instructions for doing so, and we'll include it here. |
@@ -98,7 +101,7 @@ downloading from git | @@ -98,7 +101,7 @@ downloading from git | ||
98 | Here we are cloning the noosfero repository from git. Note: you will need to | 101 | Here we are cloning the noosfero repository from git. Note: you will need to |
99 | install git before. | 102 | install git before. |
100 | 103 | ||
101 | -$ git clone git://git.colivre.coop.br/noosfero.git current | 104 | +$ git clone git://gitorious.org/noosfero/noosfero.git current |
102 | $ cd current | 105 | $ cd current |
103 | $ git checkout -b stable origin/stable | 106 | $ git checkout -b stable origin/stable |
104 | 107 |
INSTALL.chat
@@ -221,16 +221,19 @@ Note: module proxy_http must be enabled: | @@ -221,16 +221,19 @@ Note: module proxy_http must be enabled: | ||
221 | 221 | ||
222 | # a2enmod proxy_http | 222 | # a2enmod proxy_http |
223 | 223 | ||
224 | - | ||
225 | 8. DNS configuration | 224 | 8. DNS configuration |
226 | 225 | ||
227 | - * /etc/bind/db.colivre: | 226 | +For this point, we assume you are using BIND as your DNS server. You need to |
227 | +add the following entries to the DNS zone file corresponding to the domain | ||
228 | +of your noosfero site: | ||
228 | 229 | ||
229 | _xmpp-client._tcp SRV 5 100 5222 master | 230 | _xmpp-client._tcp SRV 5 100 5222 master |
230 | -(...) | ||
231 | conference CNAME master | 231 | conference CNAME master |
232 | _xmpp-client._tcp.conference SRV 5 100 5222 master | 232 | _xmpp-client._tcp.conference SRV 5 100 5222 master |
233 | 233 | ||
234 | +If you are running a DNS server other than BIND, you will have to figure out | ||
235 | +how to create equivalente rules for your zone file. Patches to this | ||
236 | +documentation are welcome. | ||
234 | 237 | ||
235 | 9. Testing this Setup | 238 | 9. Testing this Setup |
236 | 239 |
@@ -0,0 +1,163 @@ | @@ -0,0 +1,163 @@ | ||
1 | +== Multitenancy support | ||
2 | + | ||
3 | +Multitenancy refers to a principle in software architecture where a | ||
4 | +single instance of the software runs on a server, serving multiple | ||
5 | +client organizations (tenants). Multitenancy is contrasted with a | ||
6 | +multi-instance architecture where separate software instances (or | ||
7 | +hardware systems) are set up for different client organizations. With | ||
8 | +a multitenant architecture, a software application is designed to | ||
9 | +virtually partition its data and configuration, and each client | ||
10 | +organization works with a customized virtual application instance. | ||
11 | + | ||
12 | +Today this feature is available only for PostgreSQL databases. | ||
13 | + | ||
14 | +This document assumes that you have a new fully PostgresSQL default Noosfero | ||
15 | +installation as explained at the INSTALL file. | ||
16 | + | ||
17 | +== Separated data | ||
18 | + | ||
19 | +The items below are separated for each hosted environment: | ||
20 | + | ||
21 | +* Uploaded files | ||
22 | +* Database | ||
23 | +* Ferret index | ||
24 | +* ActiveRecord#cache_key | ||
25 | +* Feed updater | ||
26 | +* Delayed Job Workers | ||
27 | + | ||
28 | +== Database configuration file | ||
29 | + | ||
30 | +The file config/database.yml must follow a structure in order to | ||
31 | +achieve multitenancy support. In this example, we will set 3 | ||
32 | +different environments: env1, env2 and env3. | ||
33 | + | ||
34 | +Each "hosted" environment must have an entry like this: | ||
35 | + | ||
36 | +env1_production: | ||
37 | + adapter: postgresql | ||
38 | + encoding: unicode | ||
39 | + database: noosfero | ||
40 | + schema_search_path: public | ||
41 | + username: noosfero | ||
42 | + domains: | ||
43 | + - env1.com | ||
44 | + - env1.org | ||
45 | + | ||
46 | +env2_production: | ||
47 | + adapter: postgresql | ||
48 | + encoding: unicode | ||
49 | + database: noosfero | ||
50 | + schema_search_path: env2 | ||
51 | + username: noosfero | ||
52 | + domains: | ||
53 | + - env2.com | ||
54 | + - env2.org | ||
55 | + | ||
56 | +env3_production: | ||
57 | + adapter: postgresql | ||
58 | + encoding: unicode | ||
59 | + database: noosfero | ||
60 | + schema_search_path: env3 | ||
61 | + username: noosfero | ||
62 | + domains: | ||
63 | + - env3.com | ||
64 | + - env3.net | ||
65 | + | ||
66 | +The "hosted" environments define, besides the schema_search_path, a | ||
67 | +list of domains that, when accessed, tells which database the | ||
68 | +application should use. Also, the environment name must end with | ||
69 | +'_hosting', where 'hosting' is the name of the hosting environment. | ||
70 | + | ||
71 | +You must also tell the application which is the default environment. | ||
72 | + | ||
73 | +production: | ||
74 | + env1_production | ||
75 | + | ||
76 | +On the example above there are only three hosted environments, but it | ||
77 | +can be more than three. The schemas 'env2' and 'env3' must already | ||
78 | +exist in the same database of the hosting environment. As postgres | ||
79 | +user, you can create them typing: | ||
80 | + | ||
81 | +$ psql database_name -c "CREATE SCHEMA env2 AUTHORIZATION database_user" | ||
82 | +$ psql database_name -c "CREATE SCHEMA env3 AUTHORIZATION database_user" | ||
83 | + | ||
84 | +Replace database_name and database_user above with your stuff. | ||
85 | + | ||
86 | +So, yet on this same example, when a user accesses http://env2.com or | ||
87 | +http://env2.org, the Noosfero application running on production will | ||
88 | +turn the database schema to 'env2'. When the access is from domains | ||
89 | +http://env3.com or http://env3.net, the schema to be loaded will be | ||
90 | +'env3'. | ||
91 | + | ||
92 | +There is an example of this file in config/database.yml.multitenancy | ||
93 | + | ||
94 | +== Preparing the database | ||
95 | + | ||
96 | +Now create the environments: | ||
97 | + | ||
98 | +$ RAILS_ENV=production rake multitenancy:create | ||
99 | + | ||
100 | +This command above will create the hosted environment files equal to | ||
101 | +their hosting environment, here called 'production'. | ||
102 | + | ||
103 | +Run db:schema:load for each other environment: | ||
104 | + | ||
105 | +$ RAILS_ENV=env2_production rake db:schema:load | ||
106 | +$ RAILS_ENV=env3_production rake db:schema:load | ||
107 | + | ||
108 | +Then run the migrations for the hosting environment, and it will | ||
109 | +run for each of its hosted environments: | ||
110 | + | ||
111 | +RAILS_ENV=production rake db:migrate | ||
112 | + | ||
113 | +== Start Noosfero | ||
114 | + | ||
115 | +Run Noosfero init file as root: | ||
116 | + | ||
117 | +# invoke-rc.d noosfero start | ||
118 | + | ||
119 | +== Ferret | ||
120 | + | ||
121 | +It's necessary to run only one instance of ferret_server. Don't worry | ||
122 | +about this, Noosfero initializer had already done this for you. | ||
123 | + | ||
124 | +== Feed updater & Delayed job | ||
125 | + | ||
126 | +Just for your information, a daemon of feed-updater and delayed_job | ||
127 | +must be running for each environment. Noosfero initializer do this, | ||
128 | +relax. | ||
129 | + | ||
130 | +== Uploaded files | ||
131 | + | ||
132 | +When running with PostgreSQL, Noosfero uploads stuff to a folder named | ||
133 | +the same way as the running schema. Inside the upload folder root, for | ||
134 | +example, will be public/image_uploads/env2 and public/image_uploads/env3. | ||
135 | + | ||
136 | +== Adding multitenancy support to an existing Noosfero environment | ||
137 | + | ||
138 | +If you already have a Noosfero environment, you can turn it multitenant | ||
139 | +by following the steps below in addition to the previous steps: | ||
140 | + | ||
141 | +1. Reindex your database | ||
142 | + | ||
143 | +Rebuild the Ferret index by running the following task just | ||
144 | +for your hosting environment, do this as noosfero user: | ||
145 | + | ||
146 | +$ RAILS_ENV=production rake multitenancy:reindex | ||
147 | + | ||
148 | +2. Move the uploaded files to the right place | ||
149 | + | ||
150 | +Add a directory with the same name as your schema name (by default this | ||
151 | +name is 'public') in the root of each upload directory, for example, | ||
152 | +public/articles/0000 will be moved to public/articles/public/0000. Do this | ||
153 | +with the directories public/image_uploads, public/articles and public/thumbnails. | ||
154 | + | ||
155 | +3. Fix paths on activities | ||
156 | + | ||
157 | +The profile activities store static paths to the images, so it's necessary to fix | ||
158 | +these paths. You can do this easily by setting an alias on your webserver. | ||
159 | +On Apache you can add the three rules below, where 'public' is the schema name: | ||
160 | + | ||
161 | + RewriteRule ^/articles(.+) /articles/public$1 | ||
162 | + RewriteRule ^/image_uploads(.+) /image_uploads/public$1 | ||
163 | + RewriteRule ^/thumbnails(.+) /thumbnails/public$1 |
INSTALL.varnish
@@ -50,14 +50,22 @@ apache-compatible format. You should change your statistics generation software | @@ -50,14 +50,22 @@ apache-compatible format. You should change your statistics generation software | ||
50 | 50 | ||
51 | # invoke-rc.d varnish restart | 51 | # invoke-rc.d varnish restart |
52 | 52 | ||
53 | -6) Configure varnish to store separate caches for each language | 53 | +6) Configure varnish to fit noosfero |
54 | +(assuming Noosfero is installed in /var/lib/noosfero) | ||
54 | 55 | ||
55 | -6a) Add the following line to your /etc/varnish/default.vcl file (assuming | ||
56 | -Noosfero is installed in /var/lib/noosfero): | 56 | +6a) Configure noosfero to do specific routines to varnish |
57 | + | ||
58 | +Add the following line to your /etc/varnish/default.vcl file: | ||
59 | + | ||
60 | + include "/var/lib/noosfero/etc/noosfero/varnish-noosfero.vcl"; | ||
61 | + | ||
62 | +6b) Configure varnish to store separate caches for each language | ||
63 | + | ||
64 | +Add the following line to your /etc/varnish/default.vcl file: | ||
57 | 65 | ||
58 | include "/var/lib/noosfero/etc/noosfero/varnish-accept-language.vcl"; | 66 | include "/var/lib/noosfero/etc/noosfero/varnish-accept-language.vcl"; |
59 | 67 | ||
60 | -6b) Restart Varnish | 68 | +7) Restart Varnish |
61 | 69 | ||
62 | # invoke-rc.d varnish restart | 70 | # invoke-rc.d varnish restart |
63 | 71 |
RELEASING
@@ -12,28 +12,28 @@ This file documents release-related activities. | @@ -12,28 +12,28 @@ This file documents release-related activities. | ||
12 | 12 | ||
13 | == Releasing noosfero | 13 | == Releasing noosfero |
14 | 14 | ||
15 | +Considering you are on a Debian GNU/Linux or Debian-based system | ||
16 | + # apt-get install devscripts debhelper | ||
17 | + | ||
15 | To prepare a release of noosfero, you must follow the steps below: | 18 | To prepare a release of noosfero, you must follow the steps below: |
16 | 19 | ||
17 | -* finish all requirements and bugs assigned to the to-be-released version | ||
18 | -* make sure all tests pass | ||
19 | -* write release notes at the version's wiki topic. | ||
20 | -* generate package with <tt>rake package</tt>. Your tarball will be under the pkg/ | ||
21 | - directory, named as noosfero-${VERSION}.tar.gz | ||
22 | -* test that the package contains everything that is needed: explode the tarball | ||
23 | - in a temporary directory, copy config/database.yml.sqlite3 to | ||
24 | - config/database.yml, and make <tt>rake db:migrate</tt> and <tt>rake test</tt>. If | ||
25 | - everything is ok, you are done. If not, maybe some files are not going into | ||
26 | - the tarball. See lib/tasks/package.rake, probably you'll need to change it. | ||
27 | -* Go to the version's wiki topic and edit it to reflect the new reality. | ||
28 | -* Attach the generated package to that topic. Before attaching calculate the md5 of the package (with mu5sum and paste the MD5 hash as comment in the attachment form) | 20 | +* Finish all requirements and bugs assigned to the to-be-released version |
21 | +* Make sure all tests pass | ||
22 | +* Change the version in lib/noosfero.rb and debian/changelog to the | ||
23 | + to-be-released version (e.g. 0.2.0, 0.3.1) | ||
24 | +* Write release notes at the version's wiki topic | ||
25 | +* Generate packages with <tt>rake noosfero:release</tt>. Your tarball and deb | ||
26 | + pkg will be under the pkg/ directory. This task will create a git tag too. | ||
27 | +* Test that the tarball and deb package are ok | ||
28 | +* Go to the version's wiki topic and edit it to reflect the new reality | ||
29 | +* Edit the topic WebPreferences and update DEBIAN_REPOSITORY_TOPICS setting | ||
30 | +* Attach the generated packages to that topic. Before attaching calculate the | ||
31 | + sha1 of the package (with sha1sum and paste the SHA1 hash as comment in the | ||
32 | + attachment form) | ||
29 | * Download the attached and verify the MD5 hash | 33 | * Download the attached and verify the MD5 hash |
30 | -* create a git tag for the released version with <tt>git tag</tt>. | ||
31 | -* IMMEDIATELY change the version in lib/noosfero.rb to the next version. (e.g. | ||
32 | - 0.2.0 -> 0.3.0) | ||
33 | -* update an eventual demonstration version that you run. | ||
34 | -* write an announcement e-mail to the relevant maimling lists pointing to the release notes, and maybe to the demonstration version. | 34 | +* Update an eventual demonstration version that you run. |
35 | +* Write an announcement e-mail to the relevant mailing lists pointing to the | ||
36 | + release notes, and maybe to the demonstration version. | ||
35 | 37 | ||
36 | If you had any problem during these steps, you can do <tt>rake clobber_package</tt> to | 38 | If you had any problem during these steps, you can do <tt>rake clobber_package</tt> to |
37 | completely delete the generated packages and start the process again. | 39 | completely delete the generated packages and start the process again. |
38 | - | ||
39 | - |
app/controllers/admin/admin_panel_controller.rb
1 | class AdminPanelController < AdminController | 1 | class AdminPanelController < AdminController |
2 | 2 | ||
3 | - before_filter :login_required | ||
4 | - | ||
5 | protect 'view_environment_admin_panel', :environment | 3 | protect 'view_environment_admin_panel', :environment |
6 | 4 | ||
7 | def boxes_holder | 5 | def boxes_holder |
@@ -11,6 +9,7 @@ class AdminPanelController < AdminController | @@ -11,6 +9,7 @@ class AdminPanelController < AdminController | ||
11 | def site_info | 9 | def site_info |
12 | if request.post? | 10 | if request.post? |
13 | if @environment.update_attributes(params[:environment]) | 11 | if @environment.update_attributes(params[:environment]) |
12 | + session[:notice] = _('Environment settings updated') | ||
14 | redirect_to :action => 'index' | 13 | redirect_to :action => 'index' |
15 | end | 14 | end |
16 | end | 15 | end |
app/controllers/admin/categories_controller.rb
@@ -10,11 +10,16 @@ class CategoriesController < AdminController | @@ -10,11 +10,16 @@ class CategoriesController < AdminController | ||
10 | @product_categories = environment.product_categories.find(:all, :conditions => {:parent_id => nil}) | 10 | @product_categories = environment.product_categories.find(:all, :conditions => {:parent_id => nil}) |
11 | end | 11 | end |
12 | 12 | ||
13 | + def get_children | ||
14 | + children = Category.find(params[:id]).children | ||
15 | + render :partial => 'category_children', :locals => {:children => children} | ||
16 | + end | ||
17 | + | ||
13 | ALLOWED_TYPES = CategoriesHelper::TYPES.map {|item| item[1] } | 18 | ALLOWED_TYPES = CategoriesHelper::TYPES.map {|item| item[1] } |
14 | 19 | ||
15 | # posts back | 20 | # posts back |
16 | def new | 21 | def new |
17 | - type = (params[:type] || 'Category') | 22 | + type = (params[:type] || params[:parent_type] || 'Category') |
18 | raise 'Type not allowed' unless ALLOWED_TYPES.include?(type) | 23 | raise 'Type not allowed' unless ALLOWED_TYPES.include?(type) |
19 | 24 | ||
20 | @category = type.constantize.new(params[:category]) | 25 | @category = type.constantize.new(params[:category]) |
app/controllers/admin/plugins_controller.rb
1 | class PluginsController < AdminController | 1 | class PluginsController < AdminController |
2 | + protect 'edit_environment_features', :environment | ||
2 | 3 | ||
3 | def index | 4 | def index |
4 | @active_plugins = Noosfero::Plugin.all.map {|plugin_name| plugin_name.constantize }.compact | 5 | @active_plugins = Noosfero::Plugin.all.map {|plugin_name| plugin_name.constantize }.compact |
app/controllers/admin/role_controller.rb
@@ -9,21 +9,6 @@ class RoleController < AdminController | @@ -9,21 +9,6 @@ class RoleController < AdminController | ||
9 | @role = environment.roles.find(params[:id]) | 9 | @role = environment.roles.find(params[:id]) |
10 | end | 10 | end |
11 | 11 | ||
12 | - def new | ||
13 | - @role = Role.new | ||
14 | - end | ||
15 | - | ||
16 | - def create | ||
17 | - @role = Role.new(params[:role]) | ||
18 | - @role.environment = environment | ||
19 | - if @role.save | ||
20 | - redirect_to :action => 'show', :id => @role | ||
21 | - else | ||
22 | - session[:notice] = _('Failed to create role') | ||
23 | - render :action => 'new' | ||
24 | - end | ||
25 | - end | ||
26 | - | ||
27 | def edit | 12 | def edit |
28 | @role = environment.roles.find(params[:id]) | 13 | @role = environment.roles.find(params[:id]) |
29 | end | 14 | end |
@@ -38,13 +23,4 @@ class RoleController < AdminController | @@ -38,13 +23,4 @@ class RoleController < AdminController | ||
38 | end | 23 | end |
39 | end | 24 | end |
40 | 25 | ||
41 | - def destroy | ||
42 | - @role = environment.roles.find(params[:id]) | ||
43 | - if @role.destroy | ||
44 | - redirect_to :action => 'index' | ||
45 | - else | ||
46 | - session[:notice] = _('Failed to edit role') | ||
47 | - redirect_to :action => 'index' | ||
48 | - end | ||
49 | - end | ||
50 | end | 26 | end |
app/controllers/admin_controller.rb
app/controllers/box_organizer_controller.rb
@@ -82,7 +82,7 @@ class BoxOrganizerController < ApplicationController | @@ -82,7 +82,7 @@ class BoxOrganizerController < ApplicationController | ||
82 | def save | 82 | def save |
83 | @block = boxes_holder.blocks.find(params[:id]) | 83 | @block = boxes_holder.blocks.find(params[:id]) |
84 | @block.update_attributes(params[:block]) | 84 | @block.update_attributes(params[:block]) |
85 | - expire_timeout_fragment(@block.cache_keys) | 85 | + expire_timeout_fragment(@block.cache_key) |
86 | redirect_to :action => 'index' | 86 | redirect_to :action => 'index' |
87 | end | 87 | end |
88 | 88 | ||
@@ -93,7 +93,7 @@ class BoxOrganizerController < ApplicationController | @@ -93,7 +93,7 @@ class BoxOrganizerController < ApplicationController | ||
93 | def remove | 93 | def remove |
94 | @block = Block.find(params[:id]) | 94 | @block = Block.find(params[:id]) |
95 | if @block.destroy | 95 | if @block.destroy |
96 | - expire_timeout_fragment(@block.cache_keys) | 96 | + expire_timeout_fragment(@block.cache_key) |
97 | redirect_to :action => 'index' | 97 | redirect_to :action => 'index' |
98 | else | 98 | else |
99 | session[:notice] = _('Failed to remove block') | 99 | session[:notice] = _('Failed to remove block') |
app/controllers/my_profile/cms_controller.rb
@@ -43,6 +43,9 @@ class CmsController < MyProfileController | @@ -43,6 +43,9 @@ class CmsController < MyProfileController | ||
43 | if @parent && @parent.blog? | 43 | if @parent && @parent.blog? |
44 | articles -= Article.folder_types.map(&:constantize) | 44 | articles -= Article.folder_types.map(&:constantize) |
45 | end | 45 | end |
46 | + if user.is_admin?(profile.environment) | ||
47 | + articles << RawHTMLArticle | ||
48 | + end | ||
46 | articles | 49 | articles |
47 | end | 50 | end |
48 | 51 | ||
@@ -168,8 +171,7 @@ class CmsController < MyProfileController | @@ -168,8 +171,7 @@ class CmsController < MyProfileController | ||
168 | @article = @parent = check_parent(params[:parent_id]) | 171 | @article = @parent = check_parent(params[:parent_id]) |
169 | @target = @parent ? ('/%s/%s' % [profile.identifier, @parent.full_name]) : '/%s' % profile.identifier | 172 | @target = @parent ? ('/%s/%s' % [profile.identifier, @parent.full_name]) : '/%s' % profile.identifier |
170 | @folders = Folder.find(:all, :conditions => { :profile_id => profile }) | 173 | @folders = Folder.find(:all, :conditions => { :profile_id => profile }) |
171 | - @media_listing = params[:media_listing] | ||
172 | - if @article && !@media_listing | 174 | + if @article |
173 | record_coming | 175 | record_coming |
174 | end | 176 | end |
175 | if request.post? && params[:uploaded_files] | 177 | if request.post? && params[:uploaded_files] |
@@ -178,26 +180,14 @@ class CmsController < MyProfileController | @@ -178,26 +180,14 @@ class CmsController < MyProfileController | ||
178 | end | 180 | end |
179 | @errors = @uploaded_files.select { |f| f.errors.any? } | 181 | @errors = @uploaded_files.select { |f| f.errors.any? } |
180 | if @errors.any? | 182 | if @errors.any? |
181 | - if @media_listing | ||
182 | - flash[:notice] = _('Could not upload all files') | ||
183 | - redirect_to :action => 'media_listing' | ||
184 | - else | ||
185 | - render :action => 'upload_files', :parent_id => @parent_id | ||
186 | - end | 183 | + render :action => 'upload_files', :parent_id => @parent_id |
187 | else | 184 | else |
188 | - if @media_listing | ||
189 | - flash[:notice] = _('All files were uploaded successfully') | ||
190 | - redirect_to :action => 'media_listing' | 185 | + if @back_to |
186 | + redirect_to @back_to | ||
187 | + elsif @parent | ||
188 | + redirect_to :action => 'view', :id => @parent.id | ||
191 | else | 189 | else |
192 | - if @back_to | ||
193 | - redirect_to @back_to | ||
194 | - else | ||
195 | - redirect_to( if @parent | ||
196 | - {:action => 'view', :id => @parent.id} | ||
197 | - else | ||
198 | - {:action => 'index'} | ||
199 | - end) | ||
200 | - end | 190 | + redirect_to :action => 'index' |
201 | end | 191 | end |
202 | end | 192 | end |
203 | end | 193 | end |
@@ -286,44 +276,28 @@ class CmsController < MyProfileController | @@ -286,44 +276,28 @@ class CmsController < MyProfileController | ||
286 | @task = SuggestArticle.new(params[:task]) | 276 | @task = SuggestArticle.new(params[:task]) |
287 | if request.post? | 277 | if request.post? |
288 | @task.target = profile | 278 | @task.target = profile |
289 | - if @task.save | 279 | + if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save |
290 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') | 280 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') |
291 | redirect_to @back_to | 281 | redirect_to @back_to |
292 | end | 282 | end |
293 | end | 283 | end |
294 | end | 284 | end |
295 | 285 | ||
296 | - def media_listing | ||
297 | - if params[:image_folder_id] | ||
298 | - folder = profile.articles.find(params[:image_folder_id]) if !params[:image_folder_id].blank? | ||
299 | - @images = (folder ? folder.children : profile.top_level_articles).images | ||
300 | - elsif params[:document_folder_id] | ||
301 | - folder = profile.articles.find(params[:document_folder_id]) if !params[:document_folder_id].blank? | ||
302 | - @documents = (folder ? folder.children : profile.top_level_articles) | ||
303 | - else | ||
304 | - @documents = profile.articles | ||
305 | - @images = @documents.images | ||
306 | - @documents -= @images | ||
307 | - end | ||
308 | - | ||
309 | - @images = @images.paginate(:per_page => per_page, :page => params[:ipage], :order => "updated_at desc") if @images | ||
310 | - @documents = @documents.paginate(:per_page => per_page, :page => params[:dpage], :order => "updated_at desc", :conditions => {:is_image => false}) if @documents | ||
311 | - | ||
312 | - @folders = profile.folders | ||
313 | - @image_folders = @folders.select {|f| f.children.any? {|c| c.image?} } | ||
314 | - @document_folders = @folders.select {|f| f.children.any? {|c| !c.image? && c.kind_of?(UploadedFile) } } | ||
315 | - | ||
316 | - @media_listing = true | ||
317 | - | ||
318 | - respond_to do |format| | ||
319 | - format.html { render :layout => false} | ||
320 | - format.js { | ||
321 | - render :update do |page| | ||
322 | - page.replace_html 'media-listing-folder-images', :partial => 'image_thumb', :locals => {:images => @images } if !@images.blank? | ||
323 | - page.replace_html 'media-listing-folder-documents', :partial => 'document_link', :locals => {:documents => @documents } if !@documents.blank? | ||
324 | - end | ||
325 | - } | 286 | + def search |
287 | + query = params[:q] | ||
288 | + results = query.blank? ? [] : profile.articles.published.find_by_contents(query) | ||
289 | + render :text => article_list_to_json(results), :content_type => 'application/json' | ||
290 | + end | ||
291 | + def media_upload | ||
292 | + files_uploaded = [] | ||
293 | + parent = check_parent(params[:parent_id]) | ||
294 | + files = [:file1,:file2, :file3].map { |f| params[f] }.compact | ||
295 | + if request.post? | ||
296 | + files.each do |file| | ||
297 | + files_uploaded << UploadedFile.create(:uploaded_data => file, :profile => profile, :parent => parent) unless file == '' | ||
298 | + end | ||
326 | end | 299 | end |
300 | + render :text => article_list_to_json(files_uploaded), :content_type => 'text/plain' | ||
327 | end | 301 | end |
328 | 302 | ||
329 | protected | 303 | protected |
@@ -353,7 +327,7 @@ class CmsController < MyProfileController | @@ -353,7 +327,7 @@ class CmsController < MyProfileController | ||
353 | end | 327 | end |
354 | 328 | ||
355 | def refuse_blocks | 329 | def refuse_blocks |
356 | - if ['TinyMceArticle', 'Event', 'EnterpriseHomepage'].include?(@type) | 330 | + if ['TinyMceArticle', 'TextileArticle', 'Event', 'EnterpriseHomepage'].include?(@type) |
357 | @no_design_blocks = true | 331 | @no_design_blocks = true |
358 | end | 332 | end |
359 | end | 333 | end |
@@ -367,5 +341,21 @@ class CmsController < MyProfileController | @@ -367,5 +341,21 @@ class CmsController < MyProfileController | ||
367 | @selected_locale = @article.language || FastGettext.locale | 341 | @selected_locale = @article.language || FastGettext.locale |
368 | end | 342 | end |
369 | 343 | ||
344 | + def article_list_to_json(list) | ||
345 | + list.map do |item| | ||
346 | + { | ||
347 | + 'title' => item.title, | ||
348 | + 'url' => item.image? ? item.public_filename(:uploaded) : url_for(item.url), | ||
349 | + :icon => icon_for_article(item), | ||
350 | + :content_type => item.mime_type, | ||
351 | + :error => item.errors.any? ? _('%s could not be uploaded') % item.title : nil, | ||
352 | + } | ||
353 | + end.to_json | ||
354 | + end | ||
355 | + | ||
356 | + def content_editor? | ||
357 | + true | ||
358 | + end | ||
359 | + | ||
370 | end | 360 | end |
371 | 361 |
app/controllers/my_profile/manage_products_controller.rb
@@ -4,6 +4,7 @@ class ManageProductsController < ApplicationController | @@ -4,6 +4,7 @@ class ManageProductsController < ApplicationController | ||
4 | protect 'manage_products', :profile, :except => [:show] | 4 | protect 'manage_products', :profile, :except => [:show] |
5 | before_filter :check_environment_feature | 5 | before_filter :check_environment_feature |
6 | before_filter :login_required, :except => [:show] | 6 | before_filter :login_required, :except => [:show] |
7 | + before_filter :create_product?, :only => [:new] | ||
7 | 8 | ||
8 | protected | 9 | protected |
9 | 10 | ||
@@ -14,6 +15,13 @@ class ManageProductsController < ApplicationController | @@ -14,6 +15,13 @@ class ManageProductsController < ApplicationController | ||
14 | end | 15 | end |
15 | end | 16 | end |
16 | 17 | ||
18 | + def create_product? | ||
19 | + if !profile.create_product? | ||
20 | + render_access_denied | ||
21 | + return | ||
22 | + end | ||
23 | + end | ||
24 | + | ||
17 | public | 25 | public |
18 | 26 | ||
19 | def index | 27 | def index |
@@ -40,8 +48,8 @@ class ManageProductsController < ApplicationController | @@ -40,8 +48,8 @@ class ManageProductsController < ApplicationController | ||
40 | end | 48 | end |
41 | 49 | ||
42 | def new | 50 | def new |
43 | - @product = @profile.products.build(:product_category_id => params[:selected_category_id]) | ||
44 | - @category = @product.product_category | 51 | + @category = params[:selected_category_id] ? Category.find(params[:selected_category_id]) : nil |
52 | + @product = @profile.products.build(:product_category => @category) | ||
45 | @categories = ProductCategory.top_level_for(environment) | 53 | @categories = ProductCategory.top_level_for(environment) |
46 | @level = 0 | 54 | @level = 0 |
47 | if request.post? | 55 | if request.post? |
@@ -50,7 +58,7 @@ class ManageProductsController < ApplicationController | @@ -50,7 +58,7 @@ class ManageProductsController < ApplicationController | ||
50 | render :partial => 'shared/redirect_via_javascript', | 58 | render :partial => 'shared/redirect_via_javascript', |
51 | :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) } | 59 | :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) } |
52 | else | 60 | else |
53 | - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } | 61 | + render_dialog_error_messages 'product' |
54 | end | 62 | end |
55 | end | 63 | end |
56 | end | 64 | end |
@@ -72,7 +80,7 @@ class ManageProductsController < ApplicationController | @@ -72,7 +80,7 @@ class ManageProductsController < ApplicationController | ||
72 | 80 | ||
73 | def edit_category | 81 | def edit_category |
74 | @product = @profile.products.find(params[:id]) | 82 | @product = @profile.products.find(params[:id]) |
75 | - @category = @product.product_category | 83 | + @category = @product.product_category || ProductCategory.first |
76 | @categories = ProductCategory.top_level_for(environment) | 84 | @categories = ProductCategory.top_level_for(environment) |
77 | @edit = true | 85 | @edit = true |
78 | @level = @category.level | 86 | @level = @category.level |
@@ -81,7 +89,7 @@ class ManageProductsController < ApplicationController | @@ -81,7 +89,7 @@ class ManageProductsController < ApplicationController | ||
81 | render :partial => 'shared/redirect_via_javascript', | 89 | render :partial => 'shared/redirect_via_javascript', |
82 | :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) } | 90 | :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) } |
83 | else | 91 | else |
84 | - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } | 92 | + render_dialog_error_messages 'product' |
85 | end | 93 | end |
86 | end | 94 | end |
87 | end | 95 | end |
@@ -96,7 +104,7 @@ class ManageProductsController < ApplicationController | @@ -96,7 +104,7 @@ class ManageProductsController < ApplicationController | ||
96 | @inputs = @product.inputs | 104 | @inputs = @product.inputs |
97 | render :partial => 'display_inputs' | 105 | render :partial => 'display_inputs' |
98 | else | 106 | else |
99 | - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } | 107 | + render_dialog_error_messages 'product' |
100 | end | 108 | end |
101 | else | 109 | else |
102 | render :partial => 'add_input' | 110 | render :partial => 'add_input' |
@@ -147,7 +155,7 @@ class ManageProductsController < ApplicationController | @@ -147,7 +155,7 @@ class ManageProductsController < ApplicationController | ||
147 | @inputs = @product.inputs | 155 | @inputs = @product.inputs |
148 | render :partial => 'display_inputs' | 156 | render :partial => 'display_inputs' |
149 | else | 157 | else |
150 | - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'input' } | 158 | + render_dialog_error_messages 'input' |
151 | end | 159 | end |
152 | end | 160 | end |
153 | end | 161 | end |
app/controllers/my_profile/profile_design_controller.rb
@@ -25,6 +25,7 @@ class ProfileDesignController < BoxOrganizerController | @@ -25,6 +25,7 @@ class ProfileDesignController < BoxOrganizerController | ||
25 | blocks << DisabledEnterpriseMessageBlock | 25 | blocks << DisabledEnterpriseMessageBlock |
26 | blocks << HighlightsBlock | 26 | blocks << HighlightsBlock |
27 | blocks << FeaturedProductsBlock | 27 | blocks << FeaturedProductsBlock |
28 | + blocks << FansBlock | ||
28 | end | 29 | end |
29 | 30 | ||
30 | # product block exclusive for enterprises in environments that permits it | 31 | # product block exclusive for enterprises in environments that permits it |
@@ -37,6 +38,10 @@ class ProfileDesignController < BoxOrganizerController | @@ -37,6 +38,10 @@ class ProfileDesignController < BoxOrganizerController | ||
37 | blocks << BlogArchivesBlock | 38 | blocks << BlogArchivesBlock |
38 | end | 39 | end |
39 | 40 | ||
41 | + if user.is_admin?(profile.environment) | ||
42 | + blocks << RawHTMLBlock | ||
43 | + end | ||
44 | + | ||
40 | blocks | 45 | blocks |
41 | end | 46 | end |
42 | 47 |
app/controllers/my_profile/profile_editor_controller.rb
@@ -4,7 +4,7 @@ class ProfileEditorController < MyProfileController | @@ -4,7 +4,7 @@ class ProfileEditorController < MyProfileController | ||
4 | protect 'destroy_profile', :profile, :only => [:destroy_profile] | 4 | protect 'destroy_profile', :profile, :only => [:destroy_profile] |
5 | 5 | ||
6 | def index | 6 | def index |
7 | - @pending_tasks = profile.all_pending_tasks.select{|i| user.has_permission?(i.permission, profile)} | 7 | + @pending_tasks = Task.to(profile).pending.select{|i| user.has_permission?(i.permission, profile)} |
8 | end | 8 | end |
9 | 9 | ||
10 | helper :profile | 10 | helper :profile |
app/controllers/my_profile/profile_members_controller.rb
1 | class ProfileMembersController < MyProfileController | 1 | class ProfileMembersController < MyProfileController |
2 | protect 'manage_memberships', :profile | 2 | protect 'manage_memberships', :profile |
3 | - no_design_blocks | ||
4 | 3 | ||
5 | def index | 4 | def index |
6 | @members = profile.members | 5 | @members = profile.members |
@@ -15,29 +14,25 @@ class ProfileMembersController < MyProfileController | @@ -15,29 +14,25 @@ class ProfileMembersController < MyProfileController | ||
15 | rescue ActiveRecord::RecordNotFound | 14 | rescue ActiveRecord::RecordNotFound |
16 | @person = nil | 15 | @person = nil |
17 | end | 16 | end |
18 | - if !params[:confirmation] && @person && @person.is_last_admin_leaving?(profile, @roles) | ||
19 | - redirect_to :action => :last_admin, :roles => params[:roles], :person => @person | ||
20 | - else | ||
21 | - if @person && @person.define_roles(@roles, profile) | 17 | + |
18 | + if @person | ||
19 | + if@person.is_last_admin_leaving?(profile, @roles) | ||
20 | + redirect_to :action => :last_admin | ||
21 | + elsif @person.define_roles(@roles, profile) | ||
22 | session[:notice] = _('Roles successfuly updated') | 22 | session[:notice] = _('Roles successfuly updated') |
23 | + redirect_to :controller => 'profile_editor' | ||
23 | else | 24 | else |
24 | session[:notice] = _('Couldn\'t change the roles') | 25 | session[:notice] = _('Couldn\'t change the roles') |
26 | + redirect_to :action => 'index' | ||
25 | end | 27 | end |
26 | - if params[:confirmation] | ||
27 | - redirect_to profile.url | ||
28 | - else | ||
29 | - redirect_to :action => :index | ||
30 | - end | 28 | + else |
29 | + redirect_to :action => 'index' | ||
31 | end | 30 | end |
32 | end | 31 | end |
33 | - | 32 | + |
34 | def last_admin | 33 | def last_admin |
35 | - @person = params[:person] | ||
36 | - @roles = params[:roles] || [] | ||
37 | - @members = profile.members.select {|member| !profile.admins.include?(member)} | ||
38 | - @title = _('Current admins') | ||
39 | - @collection = :profile_admins | ||
40 | - @remove_action = {:action => 'remove_admin'} | 34 | + @roles = [Profile::Roles.admin(environment.id)] |
35 | + @pre_population = [].to_json | ||
41 | end | 36 | end |
42 | 37 | ||
43 | def add_role | 38 | def add_role |
@@ -90,6 +85,7 @@ class ProfileMembersController < MyProfileController | @@ -90,6 +85,7 @@ class ProfileMembersController < MyProfileController | ||
90 | end | 85 | end |
91 | 86 | ||
92 | def add_members | 87 | def add_members |
88 | + @roles = Profile::Roles.organization_member_roles(environment.id) | ||
93 | end | 89 | end |
94 | 90 | ||
95 | def add_member | 91 | def add_member |
@@ -122,19 +118,42 @@ class ProfileMembersController < MyProfileController | @@ -122,19 +118,42 @@ class ProfileMembersController < MyProfileController | ||
122 | render :layout => false | 118 | render :layout => false |
123 | end | 119 | end |
124 | 120 | ||
125 | - def find_users | ||
126 | - if !params[:query] || params[:query].length <= 2 | ||
127 | - @users_found = [] | ||
128 | - elsif params[:scope] == 'all_users' | ||
129 | - @users_found = Person.find_by_contents(params[:query] + '*').select {|user| !profile.members.include?(user)} | ||
130 | - @button_alt = _('Add member') | ||
131 | - @add_action = {:action => 'add_member'} | ||
132 | - elsif params[:scope] == 'new_admins' | ||
133 | - @users_found = Person.find_by_contents(params[:query] + '*').select {|user| profile.members.include?(user) && !profile.admins.include?(user)} | ||
134 | - @button_alt = _('Add member') | ||
135 | - @add_action = {:action => 'add_admin'} | 121 | + def search_user |
122 | + role = Role.find(params[:role]) | ||
123 | + render :text => environment.people.find(:all, :conditions => ['LOWER(name) LIKE ? OR LOWER(identifier) LIKE ?', "%#{params['q_'+role.key]}%", "%#{params['q_'+role.key]}%"]). | ||
124 | + select { |person| !profile.members_by_role(role).include?(person) }. | ||
125 | + map {|person| {:id => person.id, :name => person.name} }. | ||
126 | + to_json | ||
127 | + end | ||
128 | + | ||
129 | + def save_associations | ||
130 | + error = false | ||
131 | + roles = Profile::Roles.organization_member_roles(environment.id) | ||
132 | + roles.select { |role| params['q_'+role.key] }.each do |role| | ||
133 | + people = [Person.find(params['q_'+role.key].split(','))].flatten | ||
134 | + to_remove = profile.members_by_role(role) - people | ||
135 | + to_add = people - profile.members_by_role(role) | ||
136 | + | ||
137 | + begin | ||
138 | + to_remove.each { |person| profile.disaffiliate(person, role) } | ||
139 | + to_add.each { |person| profile.affiliate(person, role) } | ||
140 | + rescue Exception => ex | ||
141 | + logger.info ex | ||
142 | + error = true | ||
143 | + end | ||
144 | + end | ||
145 | + | ||
146 | + if error | ||
147 | + session[:notice] = _('The members list couldn\'t be updated. Please contact the administrator.') | ||
148 | + redirect_to :action => 'add_members' | ||
149 | + else | ||
150 | + if profile.admins.blank? && !params[:last_admin] | ||
151 | + redirect_to :action => 'last_admin' | ||
152 | + else | ||
153 | + session[:notice] = _('The members list was updated.') | ||
154 | + redirect_to :controller => 'profile_editor' | ||
155 | + end | ||
136 | end | 156 | end |
137 | - render :layout => false | ||
138 | end | 157 | end |
139 | 158 | ||
140 | def send_mail | 159 | def send_mail |
app/controllers/my_profile/tasks_controller.rb
@@ -3,12 +3,13 @@ class TasksController < MyProfileController | @@ -3,12 +3,13 @@ class TasksController < MyProfileController | ||
3 | protect 'perform_task', :profile | 3 | protect 'perform_task', :profile |
4 | 4 | ||
5 | def index | 5 | def index |
6 | - @tasks = profile.all_pending_tasks.sort_by(&:created_at) | 6 | + @filter = params[:filter_type].blank? ? nil : params[:filter_type] |
7 | + @tasks = Task.to(profile).pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | ||
7 | @failed = params ? params[:failed] : {} | 8 | @failed = params ? params[:failed] : {} |
8 | end | 9 | end |
9 | 10 | ||
10 | def processed | 11 | def processed |
11 | - @tasks = profile.all_finished_tasks.sort_by(&:created_at) | 12 | + @tasks = Task.to(profile).finished.sort_by(&:created_at) |
12 | end | 13 | end |
13 | 14 | ||
14 | VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] | 15 | VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] |
app/controllers/public/account_controller.rb
@@ -4,7 +4,6 @@ class AccountController < ApplicationController | @@ -4,7 +4,6 @@ class AccountController < ApplicationController | ||
4 | 4 | ||
5 | inverse_captcha :field => 'e_mail' | 5 | inverse_captcha :field => 'e_mail' |
6 | 6 | ||
7 | - | ||
8 | before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] | 7 | before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] |
9 | before_filter :redirect_if_logged_in, :only => [:login, :signup] | 8 | before_filter :redirect_if_logged_in, :only => [:login, :signup] |
10 | 9 | ||
@@ -15,6 +14,17 @@ class AccountController < ApplicationController | @@ -15,6 +14,17 @@ class AccountController < ApplicationController | ||
15 | end | 14 | end |
16 | end | 15 | end |
17 | 16 | ||
17 | + def activate | ||
18 | + @user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code] | ||
19 | + if @user and @user.activate | ||
20 | + @message = _("Your account has been activated, now you can log in!") | ||
21 | + render :action => 'login', :userlogin => @user.login | ||
22 | + else | ||
23 | + session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?") | ||
24 | + redirect_to :controller => :home | ||
25 | + end | ||
26 | + end | ||
27 | + | ||
18 | # action to perform login to the application | 28 | # action to perform login to the application |
19 | def login | 29 | def login |
20 | @user = User.new | 30 | @user = User.new |
@@ -57,9 +67,8 @@ class AccountController < ApplicationController | @@ -57,9 +67,8 @@ class AccountController < ApplicationController | ||
57 | @user.person_data = params[:profile_data] | 67 | @user.person_data = params[:profile_data] |
58 | @person = Person.new(params[:profile_data]) | 68 | @person = Person.new(params[:profile_data]) |
59 | @person.environment = @user.environment | 69 | @person.environment = @user.environment |
60 | - if request.post? && params[self.icaptcha_field].blank? | 70 | + if request.post? |
61 | @user.signup! | 71 | @user.signup! |
62 | - self.current_user = @user | ||
63 | owner_role = Role.find_by_name('owner') | 72 | owner_role = Role.find_by_name('owner') |
64 | @user.person.affiliate(@user.person, [owner_role]) if owner_role | 73 | @user.person.affiliate(@user.person, [owner_role]) if owner_role |
65 | invitation = Task.find_by_code(@invitation_code) | 74 | invitation = Task.find_by_code(@invitation_code) |
@@ -67,8 +76,7 @@ class AccountController < ApplicationController | @@ -67,8 +76,7 @@ class AccountController < ApplicationController | ||
67 | invitation.update_attributes!({:friend => @user.person}) | 76 | invitation.update_attributes!({:friend => @user.person}) |
68 | invitation.finish | 77 | invitation.finish |
69 | end | 78 | end |
70 | - session[:notice] = _("Thanks for signing up!") | ||
71 | - go_to_initial_page if redirect? | 79 | + @register_pending = true |
72 | end | 80 | end |
73 | rescue ActiveRecord::RecordInvalid | 81 | rescue ActiveRecord::RecordInvalid |
74 | @person.valid? | 82 | @person.valid? |
@@ -223,6 +231,8 @@ class AccountController < ApplicationController | @@ -223,6 +231,8 @@ class AccountController < ApplicationController | ||
223 | session[:notice] = nil # consume the notice | 231 | session[:notice] = nil # consume the notice |
224 | end | 232 | end |
225 | 233 | ||
234 | + @plugins.enabled_plugins.each { |plugin| user_data.merge!(plugin.user_data_extras) } | ||
235 | + | ||
226 | render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" | 236 | render :text => user_data.to_json, :layout => false, :content_type => "application/javascript" |
227 | end | 237 | end |
228 | 238 |
app/controllers/public/browse_controller.rb
@@ -6,6 +6,8 @@ class BrowseController < PublicController | @@ -6,6 +6,8 @@ class BrowseController < PublicController | ||
6 | more_recent | 6 | more_recent |
7 | more_active | 7 | more_active |
8 | more_popular | 8 | more_popular |
9 | + more_comments | ||
10 | + more_views | ||
9 | ) | 11 | ) |
10 | 12 | ||
11 | def per_page | 13 | def per_page |
@@ -36,6 +38,18 @@ class BrowseController < PublicController | @@ -36,6 +38,18 @@ class BrowseController < PublicController | ||
36 | @results = @results.compact.paginate(:per_page => per_page, :page => params[:page]) | 38 | @results = @results.compact.paginate(:per_page => per_page, :page => params[:page]) |
37 | end | 39 | end |
38 | 40 | ||
41 | + def contents | ||
42 | + @filter = filter | ||
43 | + @title = self.filter_description(params[:action] + '_' + @filter ) | ||
44 | + | ||
45 | + @results = @environment.articles.published.text_articles.send(@filter) | ||
46 | + | ||
47 | + if !params[:query].blank? | ||
48 | + @results = @results.find_by_contents(params[:query]) | ||
49 | + end | ||
50 | + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page]) | ||
51 | + end | ||
52 | + | ||
39 | protected | 53 | protected |
40 | 54 | ||
41 | def filter | 55 | def filter |
@@ -54,6 +68,9 @@ class BrowseController < PublicController | @@ -54,6 +68,9 @@ class BrowseController < PublicController | ||
54 | 'communities_more_recent' => _('More recent communities'), | 68 | 'communities_more_recent' => _('More recent communities'), |
55 | 'communities_more_active' => _('More active communities'), | 69 | 'communities_more_active' => _('More active communities'), |
56 | 'communities_more_popular' => _('More popular communities'), | 70 | 'communities_more_popular' => _('More popular communities'), |
71 | + 'contents_more_recent' => _('More recent contents'), | ||
72 | + 'contents_more_views' => _('Most viewed contents'), | ||
73 | + 'contents_more_comments' => _('Most commented contents'), | ||
57 | }[str] || str | 74 | }[str] || str |
58 | end | 75 | end |
59 | 76 |
app/controllers/public/contact_controller.rb
@@ -4,10 +4,9 @@ class ContactController < PublicController | @@ -4,10 +4,9 @@ class ContactController < PublicController | ||
4 | 4 | ||
5 | needs_profile | 5 | needs_profile |
6 | 6 | ||
7 | - inverse_captcha :field => 'e_mail' | ||
8 | def new | 7 | def new |
9 | @contact | 8 | @contact |
10 | - if request.post? && params[self.icaptcha_field].blank? && params[:confirm] == 'true' | 9 | + if request.post? && params[:confirm] == 'true' |
11 | @contact = user.build_contact(profile, params[:contact]) | 10 | @contact = user.build_contact(profile, params[:contact]) |
12 | @contact.city = (!params[:city].blank? && City.exists?(params[:city])) ? City.find(params[:city]).name : nil | 11 | @contact.city = (!params[:city].blank? && City.exists?(params[:city])) ? City.find(params[:city]).name : nil |
13 | @contact.state = (!params[:state].blank? && State.exists?(params[:state])) ? State.find(params[:state]).name : nil | 12 | @contact.state = (!params[:state].blank? && State.exists?(params[:state])) ? State.find(params[:state]).name : nil |
app/controllers/public/content_viewer_controller.rb
@@ -2,8 +2,6 @@ class ContentViewerController < ApplicationController | @@ -2,8 +2,6 @@ class ContentViewerController < ApplicationController | ||
2 | 2 | ||
3 | needs_profile | 3 | needs_profile |
4 | 4 | ||
5 | - inverse_captcha :field => 'e_mail' | ||
6 | - | ||
7 | helper ProfileHelper | 5 | helper ProfileHelper |
8 | helper TagsHelper | 6 | helper TagsHelper |
9 | 7 | ||
@@ -68,8 +66,13 @@ class ContentViewerController < ApplicationController | @@ -68,8 +66,13 @@ class ContentViewerController < ApplicationController | ||
68 | 66 | ||
69 | @form_div = params[:form] | 67 | @form_div = params[:form] |
70 | 68 | ||
71 | - if request.post? && params[:comment] && params[self.icaptcha_field].blank? && params[:confirm] == 'true' && @page.accept_comments? | ||
72 | - add_comment | 69 | + if params[:comment] && params[:confirm] == 'true' |
70 | + @comment = Comment.new(params[:comment]) | ||
71 | + if request.post? && @page.accept_comments? | ||
72 | + add_comment | ||
73 | + end | ||
74 | + else | ||
75 | + @comment = Comment.new | ||
73 | end | 76 | end |
74 | 77 | ||
75 | if request.post? && params[:remove_comment] | 78 | if request.post? && params[:remove_comment] |
@@ -106,11 +109,10 @@ class ContentViewerController < ApplicationController | @@ -106,11 +109,10 @@ class ContentViewerController < ApplicationController | ||
106 | protected | 109 | protected |
107 | 110 | ||
108 | def add_comment | 111 | def add_comment |
109 | - @comment = Comment.new(params[:comment]) | ||
110 | @comment.author = user if logged_in? | 112 | @comment.author = user if logged_in? |
111 | @comment.article = @page | 113 | @comment.article = @page |
112 | - if @comment.save | ||
113 | - @page.update_attribute(:updated_at, Time.now) | 114 | + if (logged_in? || verify_recaptcha(:model => @comment, :message => _('Please type the words correctly'))) && @comment.save |
115 | + @page.touch | ||
114 | @comment = nil # clear the comment form | 116 | @comment = nil # clear the comment form |
115 | redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view] | 117 | redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view] |
116 | else | 118 | else |
app/controllers/public/profile_controller.rb
@@ -2,8 +2,8 @@ class ProfileController < PublicController | @@ -2,8 +2,8 @@ class ProfileController < PublicController | ||
2 | 2 | ||
3 | needs_profile | 3 | needs_profile |
4 | before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] | 4 | before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] |
5 | - before_filter :store_before_join, :only => [:join, :join_not_logged] | ||
6 | - before_filter :login_required, :only => [:add, :join, :join_not_logged, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_scraps, :view_more_activities, :view_more_network_activities] | 5 | + before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse] |
6 | + before_filter :login_required, :only => [:add, :join, :join_not_logged, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_scraps, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report] | ||
7 | 7 | ||
8 | helper TagsHelper | 8 | helper TagsHelper |
9 | 9 | ||
@@ -44,7 +44,7 @@ class ProfileController < PublicController | @@ -44,7 +44,7 @@ class ProfileController < PublicController | ||
44 | tagged, | 44 | tagged, |
45 | :title => _("%s's contents tagged with \"%s\"") % [profile.name, @tag], | 45 | :title => _("%s's contents tagged with \"%s\"") % [profile.name, @tag], |
46 | :description => _("%s's contents tagged with \"%s\"") % [profile.name, @tag], | 46 | :description => _("%s's contents tagged with \"%s\"") % [profile.name, @tag], |
47 | - :link => url_for(:action => 'tags') | 47 | + :link => url_for(profile.url) |
48 | ) | 48 | ) |
49 | render :text => data, :content_type => "text/xml" | 49 | render :text => data, :content_type => "text/xml" |
50 | end | 50 | end |
@@ -71,6 +71,10 @@ class ProfileController < PublicController | @@ -71,6 +71,10 @@ class ProfileController < PublicController | ||
71 | end | 71 | end |
72 | end | 72 | end |
73 | 73 | ||
74 | + def fans | ||
75 | + @fans = profile.fans | ||
76 | + end | ||
77 | + | ||
74 | def favorite_enterprises | 78 | def favorite_enterprises |
75 | @favorite_enterprises = profile.favorite_enterprises | 79 | @favorite_enterprises = profile.favorite_enterprises |
76 | end | 80 | end |
@@ -96,7 +100,7 @@ class ProfileController < PublicController | @@ -96,7 +100,7 @@ class ProfileController < PublicController | ||
96 | if request.post? | 100 | if request.post? |
97 | profile.add_member(user) | 101 | profile.add_member(user) |
98 | session[:notice] = _('%s administrator still needs to accept you as member.') % profile.name if profile.closed? | 102 | session[:notice] = _('%s administrator still needs to accept you as member.') % profile.name if profile.closed? |
99 | - redirect_to_before_join | 103 | + redirect_to_previous_location |
100 | else | 104 | else |
101 | if user.memberships.include?(profile) | 105 | if user.memberships.include?(profile) |
102 | session[:notice] = _('You are already a member of %s.') % profile.name | 106 | session[:notice] = _('You are already a member of %s.') % profile.name |
@@ -223,6 +227,52 @@ class ProfileController < PublicController | @@ -223,6 +227,52 @@ class ProfileController < PublicController | ||
223 | end | 227 | end |
224 | end | 228 | end |
225 | 229 | ||
230 | + def report_abuse | ||
231 | + @abuse_report = AbuseReport.new | ||
232 | + render :layout => false | ||
233 | + end | ||
234 | + | ||
235 | + def register_report | ||
236 | + if !verify_recaptcha | ||
237 | + render :text => { | ||
238 | + :ok => false, | ||
239 | + :error => { | ||
240 | + :code => 1, | ||
241 | + :message => _('You could not answer the captcha.') | ||
242 | + } | ||
243 | + }.to_json | ||
244 | + else | ||
245 | + begin | ||
246 | + abuse_report = AbuseReport.new(params[:abuse_report]) | ||
247 | + if !params[:content_type].blank? | ||
248 | + article = params[:content_type].constantize.find(params[:content_id]) | ||
249 | + abuse_report.content = instance_eval(&article.reported_version) | ||
250 | + end | ||
251 | + | ||
252 | + user.register_report(abuse_report, profile) | ||
253 | + | ||
254 | + if !params[:content_type].blank? | ||
255 | + abuse_report = AbuseReport.find_by_reporter_id_and_abuse_complaint_id(user.id, profile.opened_abuse_complaint.id) | ||
256 | + Delayed::Job.enqueue DownloadReportedImagesJob.new(abuse_report, article) | ||
257 | + end | ||
258 | + | ||
259 | + render :text => { | ||
260 | + :ok => true, | ||
261 | + :message => _('Your abuse report was registered. The administrators are reviewing your report.'), | ||
262 | + }.to_json | ||
263 | + rescue Exception => exception | ||
264 | + logger.error(exception.to_s) | ||
265 | + render :text => { | ||
266 | + :ok => false, | ||
267 | + :error => { | ||
268 | + :code => 2, | ||
269 | + :message => _('Your report couldn\'t be saved due to some problem. Please contact the administrator.') | ||
270 | + } | ||
271 | + }.to_json | ||
272 | + end | ||
273 | + end | ||
274 | + end | ||
275 | + | ||
226 | protected | 276 | protected |
227 | 277 | ||
228 | def check_access_to_profile | 278 | def check_access_to_profile |
@@ -231,16 +281,16 @@ class ProfileController < PublicController | @@ -231,16 +281,16 @@ class ProfileController < PublicController | ||
231 | end | 281 | end |
232 | end | 282 | end |
233 | 283 | ||
234 | - def store_before_join | ||
235 | - if session[:before_join].nil? | ||
236 | - session[:before_join] = request.referer | 284 | + def store_location |
285 | + if session[:previous_location].nil? | ||
286 | + session[:previous_location] = request.referer | ||
237 | end | 287 | end |
238 | end | 288 | end |
239 | 289 | ||
240 | - def redirect_to_before_join | ||
241 | - back = session[:before_join] | 290 | + def redirect_to_previous_location |
291 | + back = session[:previous_location] | ||
242 | if back | 292 | if back |
243 | - session[:before_join] = nil | 293 | + session[:previous_location] = nil |
244 | redirect_to back | 294 | redirect_to back |
245 | else | 295 | else |
246 | redirect_to profile.url | 296 | redirect_to profile.url |
@@ -259,7 +309,7 @@ class ProfileController < PublicController | @@ -259,7 +309,7 @@ class ProfileController < PublicController | ||
259 | end | 309 | end |
260 | 310 | ||
261 | def invisible_profile | 311 | def invisible_profile |
262 | - render_access_denied(_("Sorry, this profile was defined as private by its owner. You'll not be able to view content here unless the profile owner adds adds you."), _("Oops ... you cannot go ahead here")) | 312 | + render_access_denied(_("This profile is inaccessible. You don't have the permission to view the content here."), _("Oops ... you cannot go ahead here")) |
263 | end | 313 | end |
264 | 314 | ||
265 | def per_page | 315 | def per_page |
app/helpers/application_helper.rb
@@ -209,7 +209,11 @@ module ApplicationHelper | @@ -209,7 +209,11 @@ module ApplicationHelper | ||
209 | the_class << ' ' << html_options[:class] | 209 | the_class << ' ' << html_options[:class] |
210 | end | 210 | end |
211 | the_title = html_options[:title] || label | 211 | the_title = html_options[:title] || label |
212 | - link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title)) | 212 | + if html_options[:disabled] |
213 | + content_tag('a', ' '+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title)) | ||
214 | + else | ||
215 | + link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title)) | ||
216 | + end | ||
213 | end | 217 | end |
214 | 218 | ||
215 | def button_to_function(type, label, js_code, html_options = {}, &block) | 219 | def button_to_function(type, label, js_code, html_options = {}, &block) |
@@ -257,30 +261,59 @@ module ApplicationHelper | @@ -257,30 +261,59 @@ module ApplicationHelper | ||
257 | concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options))) | 261 | concat(content_tag('div', capture(&block) + tag('br', :style => 'clear: left;'), { :class => 'button-bar' }.merge(options))) |
258 | end | 262 | end |
259 | 263 | ||
260 | - def partial_for_class(klass) | ||
261 | - if klass.nil? | ||
262 | - raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' | ||
263 | - end | 264 | + VIEW_EXTENSIONS = %w[.rhtml .html.erb] |
264 | 265 | ||
266 | + def partial_for_class_in_view_path(klass, view_path) | ||
267 | + return nil if klass.nil? | ||
265 | name = klass.name.underscore | 268 | name = klass.name.underscore |
266 | - if File.exists?(File.join(RAILS_ROOT, 'app', 'views', params[:controller], "_#{name}.rhtml")) | ||
267 | - name | 269 | + |
270 | + search_name = String.new(name) | ||
271 | + if search_name.include?("/") | ||
272 | + search_name.gsub!(/(\/)([^\/]*)$/,'\1_\2') | ||
273 | + name = File.join(params[:controller], name) if defined?(params) && params[:controller] | ||
268 | else | 274 | else |
269 | - partial_for_class(klass.superclass) | 275 | + search_name = "_" + search_name |
276 | + end | ||
277 | + | ||
278 | + VIEW_EXTENSIONS.each do |ext| | ||
279 | + path = defined?(params) && params[:controller] ? File.join(view_path, params[:controller], search_name+ext) : File.join(view_path, search_name+ext) | ||
280 | + return name if File.exists?(File.join(path)) | ||
270 | end | 281 | end |
282 | + | ||
283 | + partial_for_class_in_view_path(klass.superclass, view_path) | ||
271 | end | 284 | end |
272 | 285 | ||
273 | - def partial_for_task_class(klass, action) | ||
274 | - if klass.nil? | ||
275 | - raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' | 286 | + def partial_for_class(klass) |
287 | + raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? | ||
288 | + name = klass.name.underscore | ||
289 | + @controller.view_paths.each do |view_path| | ||
290 | + partial = partial_for_class_in_view_path(klass, view_path) | ||
291 | + return partial if partial | ||
276 | end | 292 | end |
277 | 293 | ||
294 | + raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' | ||
295 | + end | ||
296 | + | ||
297 | + def partial_for_task_class(klass, action) | ||
298 | + raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? | ||
299 | + | ||
278 | name = "#{klass.name.underscore}_#{action.to_s}" | 300 | name = "#{klass.name.underscore}_#{action.to_s}" |
279 | - if File.exists?(File.join(RAILS_ROOT, 'app', 'views', params[:controller], "_#{name}.rhtml")) | ||
280 | - name | ||
281 | - else | ||
282 | - partial_for_task_class(klass.superclass, action) | 301 | + VIEW_EXTENSIONS.each do |ext| |
302 | + return name if File.exists?(File.join(RAILS_ROOT, 'app', 'views', params[:controller], '_'+name+ext)) | ||
303 | + end | ||
304 | + | ||
305 | + partial_for_task_class(klass.superclass, action) | ||
306 | + end | ||
307 | + | ||
308 | + def view_for_profile_actions(klass) | ||
309 | + raise ArgumentError, 'No profile actions view for this class.' if klass.nil? | ||
310 | + | ||
311 | + name = klass.name.underscore | ||
312 | + VIEW_EXTENSIONS.each do |ext| | ||
313 | + return "blocks/profile_info_actions/"+name+ext if File.exists?(File.join(RAILS_ROOT, 'app', 'views', 'blocks', 'profile_info_actions', name+ext)) | ||
283 | end | 314 | end |
315 | + | ||
316 | + view_for_profile_actions(klass.superclass) | ||
284 | end | 317 | end |
285 | 318 | ||
286 | def user | 319 | def user |
@@ -556,17 +589,18 @@ module ApplicationHelper | @@ -556,17 +589,18 @@ module ApplicationHelper | ||
556 | 589 | ||
557 | def gravatar_url_for(email, options = {}) | 590 | def gravatar_url_for(email, options = {}) |
558 | # Ta dando erro de roteamento | 591 | # Ta dando erro de roteamento |
592 | + default = theme_option['gravatar'] || NOOSFERO_CONF['gravatar'] || nil | ||
559 | url_for( { :gravatar_id => Digest::MD5.hexdigest(email), | 593 | url_for( { :gravatar_id => Digest::MD5.hexdigest(email), |
560 | :host => 'www.gravatar.com', | 594 | :host => 'www.gravatar.com', |
561 | :protocol => 'http://', | 595 | :protocol => 'http://', |
562 | :only_path => false, | 596 | :only_path => false, |
563 | :controller => 'avatar.php', | 597 | :controller => 'avatar.php', |
564 | - :d => NOOSFERO_CONF['gravatar'] ? NOOSFERO_CONF['gravatar'] : nil | 598 | + :d => default |
565 | }.merge(options) ) | 599 | }.merge(options) ) |
566 | end | 600 | end |
567 | 601 | ||
568 | def str_gravatar_url_for(email, options = {}) | 602 | def str_gravatar_url_for(email, options = {}) |
569 | - default = NOOSFERO_CONF['gravatar'] ? NOOSFERO_CONF['gravatar'] : nil | 603 | + default = theme_option['gravatar'] || NOOSFERO_CONF['gravatar'] || nil |
570 | url = 'http://www.gravatar.com/avatar.php?gravatar_id=' + | 604 | url = 'http://www.gravatar.com/avatar.php?gravatar_id=' + |
571 | Digest::MD5.hexdigest(email) | 605 | Digest::MD5.hexdigest(email) |
572 | { | 606 | { |
@@ -870,7 +904,7 @@ module ApplicationHelper | @@ -870,7 +904,7 @@ module ApplicationHelper | ||
870 | 904 | ||
871 | def template_stylesheet_path | 905 | def template_stylesheet_path |
872 | if profile.nil? | 906 | if profile.nil? |
873 | - '/designs/templates/default/stylesheets/style.css' | 907 | + "/designs/templates/#{environment.layout_template}/stylesheets/style.css" |
874 | else | 908 | else |
875 | "/designs/templates/#{profile.layout_template}/stylesheets/style.css" | 909 | "/designs/templates/#{profile.layout_template}/stylesheets/style.css" |
876 | end | 910 | end |
@@ -947,8 +981,10 @@ module ApplicationHelper | @@ -947,8 +981,10 @@ module ApplicationHelper | ||
947 | 'thickbox', | 981 | 'thickbox', |
948 | 'lightbox', | 982 | 'lightbox', |
949 | 'colorpicker', | 983 | 'colorpicker', |
984 | + colorbox_stylesheet_path, | ||
950 | pngfix_stylesheet_path, | 985 | pngfix_stylesheet_path, |
951 | - ] | 986 | + ] + |
987 | + tokeninput_stylesheets | ||
952 | end | 988 | end |
953 | 989 | ||
954 | # DEPRECATED. Do not use this· | 990 | # DEPRECATED. Do not use this· |
@@ -960,6 +996,14 @@ module ApplicationHelper | @@ -960,6 +996,14 @@ module ApplicationHelper | ||
960 | 'iepngfix/iepngfix.css' | 996 | 'iepngfix/iepngfix.css' |
961 | end | 997 | end |
962 | 998 | ||
999 | + def colorbox_stylesheet_path | ||
1000 | + 'colorbox/colorbox.css' | ||
1001 | + end | ||
1002 | + | ||
1003 | + def tokeninput_stylesheets | ||
1004 | + ['token-input', 'token-input-facebook', 'token-input-mac'] | ||
1005 | + end | ||
1006 | + | ||
963 | def noosfero_layout_features | 1007 | def noosfero_layout_features |
964 | render :file => 'shared/noosfero_layout_features' | 1008 | render :file => 'shared/noosfero_layout_features' |
965 | end | 1009 | end |
@@ -975,7 +1019,10 @@ module ApplicationHelper | @@ -975,7 +1019,10 @@ module ApplicationHelper | ||
975 | def article_to_html(article, options = {}) | 1019 | def article_to_html(article, options = {}) |
976 | options.merge!(:page => params[:npage]) | 1020 | options.merge!(:page => params[:npage]) |
977 | content = article.to_html(options) | 1021 | content = article.to_html(options) |
978 | - return self.instance_eval(&content) if content.kind_of?(Proc) | 1022 | + content = content.kind_of?(Proc) ? self.instance_eval(&content) : content |
1023 | + @plugins && @plugins.enabled_plugins.each do |plugin| | ||
1024 | + content = plugin.parse_content(content) | ||
1025 | + end | ||
979 | content | 1026 | content |
980 | end | 1027 | end |
981 | 1028 | ||
@@ -1083,6 +1130,17 @@ module ApplicationHelper | @@ -1083,6 +1130,17 @@ module ApplicationHelper | ||
1083 | link_to(content_tag(:span, _('Communities Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger') | 1130 | link_to(content_tag(:span, _('Communities Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger') |
1084 | end | 1131 | end |
1085 | 1132 | ||
1133 | + def browse_contents_menu | ||
1134 | + links = [ | ||
1135 | + {s_('contents|More Comments') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_comments'})}}, | ||
1136 | + {s_('contents|More Views') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_views'})}}, | ||
1137 | + {s_('contents|More Recent') => {:href => url_for({:controller => 'browse', :action => 'contents', :filter => 'more_recent'})}} | ||
1138 | + ] | ||
1139 | + | ||
1140 | + link_to(content_tag(:span, _('Contents'), :class => 'icon-blog'), {:controller => "browse", :action => 'contents'}, :id => 'submenu-contents') + | ||
1141 | + link_to(content_tag(:span, _('Contents Menu')), '#', :onclick => "toggleSubmenu(this,'',#{links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-contents-trigger') | ||
1142 | + end | ||
1143 | + | ||
1086 | def pagination_links(collection, options={}) | 1144 | def pagination_links(collection, options={}) |
1087 | options = {:prev_label => '« ' + _('Previous'), :next_label => _('Next') + ' »'}.merge(options) | 1145 | options = {:prev_label => '« ' + _('Previous'), :next_label => _('Next') + ' »'}.merge(options) |
1088 | will_paginate(collection, options) | 1146 | will_paginate(collection, options) |
@@ -1099,16 +1157,27 @@ module ApplicationHelper | @@ -1099,16 +1157,27 @@ module ApplicationHelper | ||
1099 | result | 1157 | result |
1100 | end | 1158 | end |
1101 | 1159 | ||
1160 | + def manage_enterprises | ||
1161 | + if user && !user.enterprises.empty? | ||
1162 | + enterprises_link = user.enterprises.map do |enterprise| | ||
1163 | + link_to(content_tag('strong', [_('<span>Manage</span> %s') % enterprise.short_name(25)]), @environment.top_url + "/myprofile/#{enterprise.identifier}", :class => "icon-menu-"+enterprise.class.identification.underscore, :title => [_('Manage %s') % enterprise.short_name]) | ||
1164 | + end | ||
1165 | + render :partial => 'shared/manage_enterprises', :locals => {:enterprises_link => enterprises_link} | ||
1166 | + end | ||
1167 | + end | ||
1168 | + | ||
1102 | def usermenu_logged_in | 1169 | def usermenu_logged_in |
1103 | pending_tasks_count = '' | 1170 | pending_tasks_count = '' |
1104 | - if user && user.all_pending_tasks.count > 0 | ||
1105 | - pending_tasks_count = link_to(user.all_pending_tasks.count.to_s, '/myprofile/{login}/tasks', :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) | 1171 | + count = user ? Task.to(user).pending.count : -1 |
1172 | + if count > 0 | ||
1173 | + pending_tasks_count = link_to(count.to_s, @environment.top_url + '/myprofile/{login}/tasks', :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) | ||
1106 | end | 1174 | end |
1107 | 1175 | ||
1108 | - (_('Welcome, %s') % link_to('<i></i><strong>{login}</strong>', '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) + | 1176 | + (_("<span class='welcome'>Welcome,</span> %s") % link_to('<i></i><strong>{login}</strong>', @environment.top_url + '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) + |
1109 | render_environment_features(:usermenu) + | 1177 | render_environment_features(:usermenu) + |
1110 | - link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', { :controller => 'admin_panel', :action => 'index' }, :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + | ||
1111 | - link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) + | 1178 | + link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', @environment.top_url + '/admin', :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + |
1179 | + manage_enterprises.to_s + | ||
1180 | + link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', @environment.top_url + '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) + | ||
1112 | pending_tasks_count + | 1181 | pending_tasks_count + |
1113 | link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) | 1182 | link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) |
1114 | end | 1183 | end |
@@ -1206,4 +1275,39 @@ module ApplicationHelper | @@ -1206,4 +1275,39 @@ module ApplicationHelper | ||
1206 | end | 1275 | end |
1207 | end | 1276 | end |
1208 | 1277 | ||
1278 | + def render_dialog_error_messages(instance_name) | ||
1279 | + render :partial => 'shared/dialog_error_messages', :locals => { :object_name => instance_name } | ||
1280 | + end | ||
1281 | + | ||
1282 | + def report_abuse(profile, type, content=nil) | ||
1283 | + return if !user || user == profile | ||
1284 | + | ||
1285 | + url = { :controller => 'profile', | ||
1286 | + :action => 'report_abuse', | ||
1287 | + :profile => profile.identifier } | ||
1288 | + url.merge!({:content_type => content.class.name, :content_id => content.id}) if content | ||
1289 | + text = content_tag('span', _('Report abuse')) | ||
1290 | + klass = 'report-abuse-action' | ||
1291 | + already_reported_message = _('You already reported this profile.') | ||
1292 | + report_profile_message = _('Report this profile for abusive behaviour') | ||
1293 | + | ||
1294 | + if type == :button | ||
1295 | + if user.already_reported?(profile) | ||
1296 | + button(:alert, text, url, :class => klass+' disabled', :disabled => true, :title => already_reported_message) | ||
1297 | + else | ||
1298 | + button(:alert, text, url, :class => klass, :title => report_profile_message) | ||
1299 | + end | ||
1300 | + elsif type == :link | ||
1301 | + if user.already_reported?(profile) | ||
1302 | + content_tag('a', text, :class => klass + ' disabled button with-text icon-alert', :title => already_reported_message) | ||
1303 | + else | ||
1304 | + link_to(text, url, :class => klass + ' button with-text icon-alert', :title => report_profile_message) | ||
1305 | + end | ||
1306 | + elsif type == :comment_link | ||
1307 | + (user.already_reported?(profile) ? | ||
1308 | + content_tag('a', text, :class => klass + ' disabled comment-footer comment-footer-link', :title => already_reported_message) : | ||
1309 | + link_to(text, url, :class => klass + ' comment-footer comment-footer-link', :title => report_profile_message) | ||
1310 | + ) + content_tag('span', ' | ', :class => 'comment-footer comment-footer-hide') | ||
1311 | + end | ||
1312 | + end | ||
1209 | end | 1313 | end |
app/helpers/boxes_helper.rb
@@ -99,7 +99,9 @@ module BoxesHelper | @@ -99,7 +99,9 @@ module BoxesHelper | ||
99 | unless block.visible? | 99 | unless block.visible? |
100 | options[:title] = _("This block is invisible. Your visitors will not see it.") | 100 | options[:title] = _("This block is invisible. Your visitors will not see it.") |
101 | end | 101 | end |
102 | - | 102 | + @controller.send(:content_editor?) || @plugins.enabled_plugins.each do |plugin| |
103 | + result = plugin.parse_content(result) | ||
104 | + end | ||
103 | box_decorator.block_target(block.box, block) + | 105 | box_decorator.block_target(block.box, block) + |
104 | content_tag('div', | 106 | content_tag('div', |
105 | content_tag('div', | 107 | content_tag('div', |
app/helpers/catalog_helper.rb
@@ -5,16 +5,24 @@ include ManageProductsHelper | @@ -5,16 +5,24 @@ include ManageProductsHelper | ||
5 | 5 | ||
6 | def display_products_list(profile, products) | 6 | def display_products_list(profile, products) |
7 | data = '' | 7 | data = '' |
8 | + extra_content = [] | ||
9 | + extra_content_list = [] | ||
8 | products.each { |product| | 10 | products.each { |product| |
9 | - | 11 | + extra_content = @plugins.map(:catalog_item_extras, product).collect { |content| instance_eval(&content) } if @plugins |
12 | + extra_content_list = @plugins.map(:catalog_list_item_extras, product).collect { |content| instance_eval(&content) } if @plugins | ||
10 | data << content_tag('li', | 13 | data << content_tag('li', |
11 | - link_to_product(product, :class => 'product-pic', :style => 'background-image:url(%s)' % ( product.image ? product.image.public_filename(:portrait) : '/images/icons-app/product-default-pic-portrait.png' )) + | 14 | + link_to_product(product, :class => 'product-pic', :style => 'background-image:url(%s)' % product.default_image(:portrait) ) + |
12 | content_tag('h3', link_to_product(product)) + | 15 | content_tag('h3', link_to_product(product)) + |
13 | content_tag('ul', | 16 | content_tag('ul', |
14 | (product.price ? content_tag('li', _('Price: %s') % ( "%.2f" % product.price), :class => 'product_price') : '') + | 17 | (product.price ? content_tag('li', _('Price: %s') % ( "%.2f" % product.price), :class => 'product_price') : '') + |
15 | - content_tag('li', product_category_name(profile, product.product_category), :class => 'product_category') | 18 | + content_tag('li', product_category_name(profile, product.product_category), :class => 'product_category') + |
19 | + extra_content_list.map { |content| content_tag('li', content)}.join("\n") | ||
16 | ) + | 20 | ) + |
17 | - (product.description ? content_tag('div', txt2html(product.description), :class => 'description') : tag('br', :style => 'clear:both')), | 21 | + (product.description ? content_tag('div', |
22 | + txt2html(product.description), | ||
23 | + :class => 'description') : tag('br', | ||
24 | + :style => 'clear:both')) + | ||
25 | + extra_content.join("\n"), | ||
18 | :class => 'product') | 26 | :class => 'product') |
19 | } | 27 | } |
20 | content_tag('h1', _('Products/Services')) + content_tag('ul', data, :id => 'product_list') | 28 | content_tag('h1', _('Products/Services')) + content_tag('ul', data, :id => 'product_list') |
app/helpers/content_viewer_helper.rb
@@ -22,9 +22,14 @@ module ContentViewerHelper | @@ -22,9 +22,14 @@ module ContentViewerHelper | ||
22 | end | 22 | end |
23 | comments = '' | 23 | comments = '' |
24 | unless args[:no_comments] || !article.accept_comments | 24 | unless args[:no_comments] || !article.accept_comments |
25 | - comments = ("- %s") % link_to_comments(article) | 25 | + comments = (" - %s") % link_to_comments(article) |
26 | end | 26 | end |
27 | - title << content_tag('span', _("%s, by %s %s") % [show_date(article.published_at), link_to(article.author_name, article.author.url), comments], :class => 'created-at') | 27 | + title << content_tag('span', |
28 | + content_tag('span', show_date(article.published_at), :class => 'date') + | ||
29 | + content_tag('span', [_(", by %s") % link_to(article.author_name, article.author.url)], :class => 'author') + | ||
30 | + content_tag('span', comments, :class => 'comments'), | ||
31 | + :class => 'created-at' | ||
32 | + ) | ||
28 | end | 33 | end |
29 | title | 34 | title |
30 | end | 35 | end |
@@ -46,4 +51,21 @@ module ContentViewerHelper | @@ -46,4 +51,21 @@ module ContentViewerHelper | ||
46 | end | 51 | end |
47 | end | 52 | end |
48 | 53 | ||
54 | + def addthis_facebook_url(article) | ||
55 | + "http://www.facebook.com/sharer.php?s=100&p[title]=%{title}&p[summary]=%{summary}&p[url]=%{url}&p[images][0]=%{image}" % { | ||
56 | + :title => CGI.escape(article.title), | ||
57 | + :url => CGI.escape(url_for(article.url)), | ||
58 | + :summary => CGI.escape(truncate(strip_tags(article.body.to_s), 300)), | ||
59 | + :image => CGI.escape(article.body_images_paths.first.to_s) | ||
60 | + } | ||
61 | + end | ||
62 | + | ||
63 | + def addthis_image_tag | ||
64 | + if File.exists?(File.join(Rails.root, 'public', theme_path, 'images', 'addthis.gif')) | ||
65 | + image_tag(File.join(theme_path, 'images', 'addthis.gif'), :border => 0, :alt => '') | ||
66 | + else | ||
67 | + image_tag("/images/bt-bookmark.gif", :width => 53, :height => 16, :border => 0, :alt => '') | ||
68 | + end | ||
69 | + end | ||
70 | + | ||
49 | end | 71 | end |
app/helpers/dates_helper.rb
@@ -42,11 +42,11 @@ module DatesHelper | @@ -42,11 +42,11 @@ module DatesHelper | ||
42 | end | 42 | end |
43 | end | 43 | end |
44 | 44 | ||
45 | - def show_period(date1, date2 = nil) | 45 | + def show_period(date1, date2 = nil, use_numbers = false) |
46 | if (date1 == date2) || (date2.nil?) | 46 | if (date1 == date2) || (date2.nil?) |
47 | - show_date(date1) | 47 | + show_date(date1, use_numbers) |
48 | else | 48 | else |
49 | - _('from %{date1} to %{date2}') % {:date1 => show_date(date1), :date2 => show_date(date2)} | 49 | + _('from %{date1} to %{date2}') % {:date1 => show_date(date1, use_numbers), :date2 => show_date(date2, use_numbers)} |
50 | end | 50 | end |
51 | end | 51 | end |
52 | 52 |
app/helpers/display_helper.rb
@@ -27,14 +27,18 @@ module DisplayHelper | @@ -27,14 +27,18 @@ module DisplayHelper | ||
27 | end | 27 | end |
28 | 28 | ||
29 | def txt2html(txt) | 29 | def txt2html(txt) |
30 | - txt. | ||
31 | - gsub( /\n\s*\n/, ' <p/> ' ). | ||
32 | - gsub( /\n/, ' <br/> ' ). | ||
33 | - gsub( /(^|\s)(www\.[^\s])/, '\1http://\2' ). | ||
34 | - gsub( /(https?:\/\/([^\s]+))/ ) do | ||
35 | - href, content = $1, $2.scan(/.{4}/).join('​') | ||
36 | - content_tag(:a, content, :href => href, :target => '_blank', :rel => 'nofolow', | ||
37 | - :onclick => "return confirm('%s')" % escape_javascript(_('Are you sure you want to visit this web site?'))) | 30 | + txt.strip. |
31 | + gsub( /\s*\n\s*\n\s*/, "\r<p/>\r" ). | ||
32 | + gsub( /\s*\n\s*/, "\n<br/>\n" ). | ||
33 | + gsub( /\r/, "\n" ). | ||
34 | + gsub( /(^|\s)(www\.[^\s]+|https?:\/\/[^\s]+)/ ) do | ||
35 | + pre_char, href = $1, $2 | ||
36 | + href = 'http://'+href if ! href.match /^https?:/ | ||
37 | + content = href.gsub(/^https?:\/\//, '').scan(/.{1,4}/).join('​') | ||
38 | + pre_char + | ||
39 | + content_tag(:a, content, :href => href, :target => '_blank', | ||
40 | + :rel => 'nofolow', :onclick => "return confirm('%s')" % | ||
41 | + _('Are you sure you want to visit this web site?')) | ||
38 | end | 42 | end |
39 | end | 43 | end |
40 | end | 44 | end |
app/helpers/events_helper.rb
@@ -21,14 +21,13 @@ module EventsHelper | @@ -21,14 +21,13 @@ module EventsHelper | ||
21 | end | 21 | end |
22 | 22 | ||
23 | def populate_calendar(selected_date, events) | 23 | def populate_calendar(selected_date, events) |
24 | + events.reject! {|event| !event.display_to?(user)} | ||
24 | calendar = Event.date_range(selected_date.year, selected_date.month).map do |date| | 25 | calendar = Event.date_range(selected_date.year, selected_date.month).map do |date| |
25 | [ | 26 | [ |
26 | # the day itself | 27 | # the day itself |
27 | date, | 28 | date, |
28 | # is there any events in this date? | 29 | # is there any events in this date? |
29 | - events.select {|event| event.display_to?(user)}.any? do |event| | ||
30 | - event.date_range.include?(date) | ||
31 | - end, | 30 | + events.any? {|event| event.date_range.include?(date)}, |
32 | # is this date in the current month? | 31 | # is this date in the current month? |
33 | true | 32 | true |
34 | ] | 33 | ] |
app/helpers/profile_editor_helper.rb
@@ -104,8 +104,8 @@ module ProfileEditorHelper | @@ -104,8 +104,8 @@ module ProfileEditorHelper | ||
104 | @country_helper ||= CountriesHelper.instance | 104 | @country_helper ||= CountriesHelper.instance |
105 | end | 105 | end |
106 | 106 | ||
107 | - def select_country(title, object, method, options) | ||
108 | - labelled_form_field(title, select(object, method, [[_('[Select ...]'), nil]] + country_helper.countries, {}, options)) | 107 | + def select_country(title, object, method, html_options = {}, options = {}) |
108 | + labelled_form_field(title, select(object, method, [[_('[Select ...]'), nil]] + country_helper.countries, options, html_options)) | ||
109 | end | 109 | end |
110 | 110 | ||
111 | def select_schooling(object, method, options) | 111 | def select_schooling(object, method, options) |
app/helpers/sweeper_helper.rb
@@ -22,7 +22,7 @@ module SweeperHelper | @@ -22,7 +22,7 @@ module SweeperHelper | ||
22 | 22 | ||
23 | # friends blocks | 23 | # friends blocks |
24 | blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} | 24 | blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} |
25 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 25 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
26 | end | 26 | end |
27 | 27 | ||
28 | def expire_communities(profile) | 28 | def expire_communities(profile) |
@@ -34,13 +34,13 @@ module SweeperHelper | @@ -34,13 +34,13 @@ module SweeperHelper | ||
34 | 34 | ||
35 | # communities block | 35 | # communities block |
36 | blocks = profile.blocks.select{|b| b.kind_of?(CommunitiesBlock)} | 36 | blocks = profile.blocks.select{|b| b.kind_of?(CommunitiesBlock)} |
37 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 37 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
38 | end | 38 | end |
39 | 39 | ||
40 | def expire_enterprises(profile) | 40 | def expire_enterprises(profile) |
41 | # enterprises and favorite enterprises blocks | 41 | # enterprises and favorite enterprises blocks |
42 | blocks = profile.blocks.select {|b| [EnterprisesBlock, FavoriteEnterprisesBlock].any?{|klass| b.kind_of?(klass)} } | 42 | blocks = profile.blocks.select {|b| [EnterprisesBlock, FavoriteEnterprisesBlock].any?{|klass| b.kind_of?(klass)} } |
43 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 43 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
44 | end | 44 | end |
45 | 45 | ||
46 | def expire_profile_index(profile) | 46 | def expire_profile_index(profile) |
app/helpers/tags_helper.rb
@@ -28,7 +28,6 @@ module TagsHelper | @@ -28,7 +28,6 @@ module TagsHelper | ||
28 | # courtesy of Aurelio: http://www.colivre.coop.br/Aurium/Nuvem | 28 | # courtesy of Aurelio: http://www.colivre.coop.br/Aurium/Nuvem |
29 | # (pt_BR only). | 29 | # (pt_BR only). |
30 | def tag_cloud(tags, tagname_option, url, options = {}) | 30 | def tag_cloud(tags, tagname_option, url, options = {}) |
31 | - | ||
32 | 31 | ||
33 | return content_tag('em', _('No tags yet.')) + | 32 | return content_tag('em', _('No tags yet.')) + |
34 | ' <a href="' + _('http://en.wikipedia.org/wiki/Tag_%28metadata%29') + | 33 | ' <a href="' + _('http://en.wikipedia.org/wiki/Tag_%28metadata%29') + |
@@ -42,7 +41,7 @@ module TagsHelper | @@ -42,7 +41,7 @@ module TagsHelper | ||
42 | max = tags.values.max.to_f | 41 | max = tags.values.max.to_f |
43 | min = tags.values.min.to_f | 42 | min = tags.values.min.to_f |
44 | 43 | ||
45 | - tags.map do |tag,count| | 44 | + tags.sort_by{ |k,v| k.downcase }.map do |tag,count| |
46 | if ( max == min ) | 45 | if ( max == min ) |
47 | v = 0.5 | 46 | v = 0.5 |
48 | else | 47 | else |
@@ -0,0 +1,75 @@ | @@ -0,0 +1,75 @@ | ||
1 | +class AbuseComplaint < Task | ||
2 | + has_many :abuse_reports, :dependent => :destroy | ||
3 | + belongs_to :reported, :class_name => "Profile", :foreign_key => "requestor_id" | ||
4 | + | ||
5 | + validates_presence_of :reported | ||
6 | + alias :requestor :reported | ||
7 | + | ||
8 | + def initialize(*args) | ||
9 | + super | ||
10 | + self.status = (args.first ? args.first[:status] : nil) || Task::Status::HIDDEN | ||
11 | + end | ||
12 | + | ||
13 | + after_update do |abuse_complaint| | ||
14 | + if abuse_complaint.reported.environment.reports_lower_bound < abuse_complaint.abuse_reports.count && abuse_complaint.status == Task::Status::HIDDEN | ||
15 | + abuse_complaint.activate | ||
16 | + end | ||
17 | + end | ||
18 | + | ||
19 | + def target | ||
20 | + reported.environment | ||
21 | + end | ||
22 | + | ||
23 | + def environment | ||
24 | + target | ||
25 | + end | ||
26 | + | ||
27 | + def title | ||
28 | + abuse_reports.count > 1 ? (_('Abuse complaint (%s)') % abuse_reports.count) :_('Abuse complaint') | ||
29 | + end | ||
30 | + | ||
31 | + def linked_subject | ||
32 | + {:text => reported.name, :url => reported.url} | ||
33 | + end | ||
34 | + | ||
35 | + def information | ||
36 | + {:message => _('%{linked_subject} was reported due to inappropriate behavior.')} | ||
37 | + end | ||
38 | + | ||
39 | + def accept_details | ||
40 | + true | ||
41 | + end | ||
42 | + | ||
43 | + def reject_details | ||
44 | + true | ||
45 | + end | ||
46 | + | ||
47 | + def icon | ||
48 | + {:type => :profile_image, :profile => reported, :url => reported.url} | ||
49 | + end | ||
50 | + | ||
51 | + def default_decision | ||
52 | + 'skip' | ||
53 | + end | ||
54 | + | ||
55 | + def perform | ||
56 | + reported.disable | ||
57 | + end | ||
58 | + | ||
59 | + def task_activated_message | ||
60 | + _('Your profile was reported by the users of %s due to inappropriate behavior. The administrators of the environment are now reviewing the report. To solve this misunderstanding, please contact the administrators.') % environment.name | ||
61 | + end | ||
62 | + | ||
63 | + def task_finished_message | ||
64 | + _('Your profile was disabled by the administrators of %s due to inappropriate behavior. To solve this misunderstanding please contact them.') % environment.name | ||
65 | + end | ||
66 | + | ||
67 | + def target_notification_description | ||
68 | + _('%s was reported due to inappropriate behavior.') % reported.name | ||
69 | + end | ||
70 | + | ||
71 | + def target_notification_message | ||
72 | + _('The users of %{environment} reported %{reported} due to inappropriate behavior. A task was created with all the reports including the reasons and contents reported by these users. Please verify the reports and decide whether this profile must be disabled or not.') % {:environment => environment.name, :reported => reported.name} | ||
73 | + end | ||
74 | + | ||
75 | +end |
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +class AbuseReport < ActiveRecord::Base | ||
2 | + | ||
3 | + belongs_to :reporter, :class_name => 'Person' | ||
4 | + belongs_to :abuse_complaint | ||
5 | + has_many :reported_images, :dependent => :destroy | ||
6 | + | ||
7 | + validates_presence_of :reporter, :abuse_complaint, :reason | ||
8 | + validates_uniqueness_of :reporter_id, :scope => :abuse_complaint_id | ||
9 | + | ||
10 | + xss_terminate :sanitize => [:reason] | ||
11 | + | ||
12 | + after_create do |abuse_report| | ||
13 | + abuse_report.abuse_complaint.save! | ||
14 | + end | ||
15 | +end |
app/models/approve_article.rb
@@ -77,6 +77,10 @@ class ApproveArticle < Task | @@ -77,6 +77,10 @@ class ApproveArticle < Task | ||
77 | true | 77 | true |
78 | end | 78 | end |
79 | 79 | ||
80 | + def reject_details | ||
81 | + true | ||
82 | + end | ||
83 | + | ||
80 | def default_decision | 84 | def default_decision |
81 | if article | 85 | if article |
82 | 'skip' | 86 | 'skip' |
@@ -90,7 +94,11 @@ class ApproveArticle < Task | @@ -90,7 +94,11 @@ class ApproveArticle < Task | ||
90 | end | 94 | end |
91 | 95 | ||
92 | def target_notification_description | 96 | def target_notification_description |
93 | - _('%{requestor} wants to publish the article: %{article}.') % {:requestor => requestor.name, :article => article.name} | 97 | + if article |
98 | + _('%{requestor} wants to publish the article: %{article}.') % {:requestor => requestor.name, :article => article.name} | ||
99 | + else | ||
100 | + _('%{requestor} wanted to publish an article but it was removed.') % {:requestor => requestor.name} | ||
101 | + end | ||
94 | end | 102 | end |
95 | 103 | ||
96 | def target_notification_message | 104 | def target_notification_message |
@@ -107,4 +115,11 @@ class ApproveArticle < Task | @@ -107,4 +115,11 @@ class ApproveArticle < Task | ||
107 | end | 115 | end |
108 | end | 116 | end |
109 | 117 | ||
118 | + def task_cancelled_message | ||
119 | + message = _('Your request for publishing the article "{article}" was rejected.') | ||
120 | + if !reject_explanation.blank? | ||
121 | + message += " " + _("Here is the reject explanation left by the administrator who rejected your article: \n\n%{reject_explanation}") % {:reject_explanation => reject_explanation} | ||
122 | + end | ||
123 | + end | ||
124 | + | ||
110 | end | 125 | end |
app/models/article.rb
@@ -188,6 +188,14 @@ class Article < ActiveRecord::Base | @@ -188,6 +188,14 @@ class Article < ActiveRecord::Base | ||
188 | body || '' | 188 | body || '' |
189 | end | 189 | end |
190 | 190 | ||
191 | + include ApplicationHelper | ||
192 | + def reported_version(options = {}) | ||
193 | + article = self | ||
194 | + search_path = File.join(Rails.root, 'app', 'views', 'shared', 'reported_versions') | ||
195 | + partial_path = File.join('shared', 'reported_versions', partial_for_class_in_view_path(article.class, search_path)) | ||
196 | + lambda { render_to_string(:partial => partial_path, :locals => {:article => article}) } | ||
197 | + end | ||
198 | + | ||
191 | # returns the data of the article. Must be overriden in each subclass to | 199 | # returns the data of the article. Must be overriden in each subclass to |
192 | # provide the correct content for the article. | 200 | # provide the correct content for the article. |
193 | def data | 201 | def data |
@@ -265,6 +273,10 @@ class Article < ActiveRecord::Base | @@ -265,6 +273,10 @@ class Article < ActiveRecord::Base | ||
265 | false | 273 | false |
266 | end | 274 | end |
267 | 275 | ||
276 | + def uploaded_file? | ||
277 | + false | ||
278 | + end | ||
279 | + | ||
268 | def has_posts? | 280 | def has_posts? |
269 | false | 281 | false |
270 | end | 282 | end |
@@ -343,11 +355,20 @@ class Article < ActiveRecord::Base | @@ -343,11 +355,20 @@ class Article < ActiveRecord::Base | ||
343 | ['Folder', 'Blog', 'Forum', 'Gallery'] | 355 | ['Folder', 'Blog', 'Forum', 'Gallery'] |
344 | end | 356 | end |
345 | 357 | ||
358 | + def self.text_article_types | ||
359 | + ['TextArticle', 'TextileArticle', 'TinyMceArticle'] | ||
360 | + end | ||
361 | + | ||
346 | named_scope :published, :conditions => { :published => true } | 362 | named_scope :published, :conditions => { :published => true } |
347 | named_scope :folders, :conditions => { :type => folder_types} | 363 | named_scope :folders, :conditions => { :type => folder_types} |
348 | named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types] | 364 | named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types] |
349 | named_scope :galleries, :conditions => { :type => 'Gallery' } | 365 | named_scope :galleries, :conditions => { :type => 'Gallery' } |
350 | named_scope :images, :conditions => { :is_image => true } | 366 | named_scope :images, :conditions => { :is_image => true } |
367 | + named_scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] | ||
368 | + | ||
369 | + named_scope :more_comments, :order => "comments_count DESC" | ||
370 | + named_scope :more_views, :order => "hits DESC" | ||
371 | + named_scope :more_recent, :order => "created_at DESC" | ||
351 | 372 | ||
352 | def self.display_filter(user, profile) | 373 | def self.display_filter(user, profile) |
353 | return {:conditions => ['published = ?', true]} if !user | 374 | return {:conditions => ['published = ?', true]} if !user |
@@ -509,6 +530,35 @@ class Article < ActiveRecord::Base | @@ -509,6 +530,35 @@ class Article < ActiveRecord::Base | ||
509 | self.parent && self.parent.accept_uploads? | 530 | self.parent && self.parent.accept_uploads? |
510 | end | 531 | end |
511 | 532 | ||
533 | + def body_images_paths | ||
534 | + require 'uri' | ||
535 | + Hpricot(self.body.to_s).search('img[@src]').collect do |i| | ||
536 | + (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, URI.escape(i.attributes['src'])).to_s : i.attributes['src'] | ||
537 | + end | ||
538 | + end | ||
539 | + | ||
540 | + def more_comments_label | ||
541 | + amount = self.comments_count | ||
542 | + { | ||
543 | + 0 => _('no comments'), | ||
544 | + 1 => _('one comment') | ||
545 | + }[amount] || _("%s comments") % amount | ||
546 | + | ||
547 | + end | ||
548 | + | ||
549 | + def more_views_label | ||
550 | + amount = self.hits | ||
551 | + { | ||
552 | + 0 => _('no views'), | ||
553 | + 1 => _('one view') | ||
554 | + }[amount] || _("%s views") % amount | ||
555 | + | ||
556 | + end | ||
557 | + | ||
558 | + def more_recent_label | ||
559 | + _('Created at: ') | ||
560 | + end | ||
561 | + | ||
512 | private | 562 | private |
513 | 563 | ||
514 | def sanitize_tag_list | 564 | def sanitize_tag_list |
app/models/block.rb
@@ -34,6 +34,12 @@ class Block < ActiveRecord::Base | @@ -34,6 +34,12 @@ class Block < ActiveRecord::Base | ||
34 | else | 34 | else |
35 | return context[:request_path] == '/' | 35 | return context[:request_path] == '/' |
36 | end | 36 | end |
37 | + elsif display == 'except_home_page' | ||
38 | + if context[:article] | ||
39 | + return context[:article] != owner.home_page | ||
40 | + else | ||
41 | + return context[:request_path] != '/' + owner.identifier | ||
42 | + end | ||
37 | end | 43 | end |
38 | end | 44 | end |
39 | true | 45 | true |
@@ -45,6 +51,8 @@ class Block < ActiveRecord::Base | @@ -45,6 +51,8 @@ class Block < ActiveRecord::Base | ||
45 | # * <tt>'never'</tt>: the block is hidden (it does not appear for visitors) | 51 | # * <tt>'never'</tt>: the block is hidden (it does not appear for visitors) |
46 | # * <tt>'home_page_only'</tt> the block is displayed only when viewing the | 52 | # * <tt>'home_page_only'</tt> the block is displayed only when viewing the |
47 | # homepage of its owner. | 53 | # homepage of its owner. |
54 | + # * <tt>'except_home_page'</tt> the block is displayed only when viewing | ||
55 | + # the homepage of its owner. | ||
48 | settings_items :display, :type => :string, :default => 'always' | 56 | settings_items :display, :type => :string, :default => 'always' |
49 | 57 | ||
50 | # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: | 58 | # The block can be configured to be displayed in all languages or in just one language. It can assume any locale of the environment: |
@@ -119,10 +127,6 @@ class Block < ActiveRecord::Base | @@ -119,10 +127,6 @@ class Block < ActiveRecord::Base | ||
119 | true | 127 | true |
120 | end | 128 | end |
121 | 129 | ||
122 | - def cache_keys | ||
123 | - "block-id-#{id}" | ||
124 | - end | ||
125 | - | ||
126 | def timeout | 130 | def timeout |
127 | 4.hours | 131 | 4.hours |
128 | end | 132 | end |
app/models/blog.rb
@@ -72,4 +72,8 @@ class Blog < Folder | @@ -72,4 +72,8 @@ class Blog < Folder | ||
72 | 72 | ||
73 | alias :display_posts_in_current_language? :display_posts_in_current_language | 73 | alias :display_posts_in_current_language? :display_posts_in_current_language |
74 | 74 | ||
75 | + def empty? | ||
76 | + posts.empty? | ||
77 | + end | ||
78 | + | ||
75 | end | 79 | end |
app/models/comment.rb
@@ -2,7 +2,7 @@ class Comment < ActiveRecord::Base | @@ -2,7 +2,7 @@ class Comment < ActiveRecord::Base | ||
2 | 2 | ||
3 | track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target | 3 | track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target |
4 | 4 | ||
5 | - validates_presence_of :title, :body | 5 | + validates_presence_of :body |
6 | belongs_to :article, :counter_cache => true | 6 | belongs_to :article, :counter_cache => true |
7 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' | 7 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' |
8 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy | 8 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy |
@@ -98,6 +98,16 @@ class Comment < ActiveRecord::Base | @@ -98,6 +98,16 @@ class Comment < ActiveRecord::Base | ||
98 | root | 98 | root |
99 | end | 99 | end |
100 | 100 | ||
101 | + include ApplicationHelper | ||
102 | + def reported_version(options = {}) | ||
103 | + comment = self | ||
104 | + lambda { render_to_string(:partial => 'shared/reported_versions/comment', :locals => {:comment => comment}) } | ||
105 | + end | ||
106 | + | ||
107 | + def to_html(option={}) | ||
108 | + body || '' | ||
109 | + end | ||
110 | + | ||
101 | class Notifier < ActionMailer::Base | 111 | class Notifier < ActionMailer::Base |
102 | def mail(comment) | 112 | def mail(comment) |
103 | profile = comment.article.profile | 113 | profile = comment.article.profile |
app/models/community.rb
app/models/contact.rb
@@ -23,23 +23,26 @@ class Contact < ActiveRecord::Base #WithoutTable | @@ -23,23 +23,26 @@ class Contact < ActiveRecord::Base #WithoutTable | ||
23 | 23 | ||
24 | class Sender < ActionMailer::Base | 24 | class Sender < ActionMailer::Base |
25 | def mail(contact) | 25 | def mail(contact) |
26 | + content_type 'text/html' | ||
26 | emails = contact.dest.notification_emails | 27 | emails = contact.dest.notification_emails |
27 | recipients emails | 28 | recipients emails |
28 | - from "#{contact.name} <#{contact.email}>" | 29 | + from "#{contact.name} <#{contact.dest.environment.contact_email}>" |
30 | + reply_to contact.email | ||
29 | if contact.sender | 31 | if contact.sender |
30 | headers 'X-Noosfero-Sender' => contact.sender.identifier | 32 | headers 'X-Noosfero-Sender' => contact.sender.identifier |
31 | end | 33 | end |
32 | if contact.receive_a_copy | 34 | if contact.receive_a_copy |
33 | cc "#{contact.name} <#{contact.email}>" | 35 | cc "#{contact.name} <#{contact.email}>" |
34 | end | 36 | end |
35 | - subject contact.subject | 37 | + subject "[#{contact.dest.short_name(30)}] " + contact.subject |
36 | body :name => contact.name, | 38 | body :name => contact.name, |
37 | :email => contact.email, | 39 | :email => contact.email, |
38 | :city => contact.city, | 40 | :city => contact.city, |
39 | :state => contact.state, | 41 | :state => contact.state, |
40 | :message => contact.message, | 42 | :message => contact.message, |
41 | :environment => contact.dest.environment.name, | 43 | :environment => contact.dest.environment.name, |
42 | - :url => url_for(:host => contact.dest.environment.default_hostname, :controller => 'home') | 44 | + :url => url_for(:host => contact.dest.environment.default_hostname, :controller => 'home'), |
45 | + :target => contact.dest.name | ||
43 | end | 46 | end |
44 | end | 47 | end |
45 | 48 |
app/models/domain.rb
@@ -10,7 +10,7 @@ class Domain < ActiveRecord::Base | @@ -10,7 +10,7 @@ class Domain < ActiveRecord::Base | ||
10 | 10 | ||
11 | # <tt>name</tt> must be a sequence of word characters (a to z, plus 0 to 9, | 11 | # <tt>name</tt> must be a sequence of word characters (a to z, plus 0 to 9, |
12 | # plus '_'). Letters must be lowercase | 12 | # plus '_'). Letters must be lowercase |
13 | - validates_format_of :name, :with => /^([a-z0-9_]+\.)+[a-z0-9_]+$/, :message => N_('%{fn} must be composed only of lowercase latters (a to z), numbers (0 to 9) and "_"') | 13 | + validates_format_of :name, :with => /^([a-z0-9_-]+\.)+[a-z0-9_-]+$/, :message => N_('%{fn} must be composed only of lowercase latters (a to z), numbers (0 to 9), "_" and "-"') |
14 | 14 | ||
15 | # checks validations that could not be expressed using Rails' predefined | 15 | # checks validations that could not be expressed using Rails' predefined |
16 | # validations. In particular: | 16 | # validations. In particular: |
app/models/enterprise.rb
@@ -7,6 +7,8 @@ class Enterprise < Organization | @@ -7,6 +7,8 @@ class Enterprise < Organization | ||
7 | has_many :products, :dependent => :destroy, :order => 'name ASC' | 7 | has_many :products, :dependent => :destroy, :order => 'name ASC' |
8 | has_many :inputs, :through => :products | 8 | has_many :inputs, :through => :products |
9 | 9 | ||
10 | + has_and_belongs_to_many :fans, :class_name => 'Person', :join_table => 'favorite_enteprises_people' | ||
11 | + | ||
10 | extra_data_for_index :product_categories | 12 | extra_data_for_index :product_categories |
11 | 13 | ||
12 | N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') | 14 | N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') |
@@ -145,6 +147,7 @@ class Enterprise < Organization | @@ -145,6 +147,7 @@ class Enterprise < Organization | ||
145 | end | 147 | end |
146 | 148 | ||
147 | before_create do |enterprise| | 149 | before_create do |enterprise| |
150 | + enterprise.validated = enterprise.environment.enabled?('enterprises_are_validated_when_created') | ||
148 | if enterprise.environment.enabled?('enterprises_are_disabled_when_created') | 151 | if enterprise.environment.enabled?('enterprises_are_disabled_when_created') |
149 | enterprise.enabled = false | 152 | enterprise.enabled = false |
150 | end | 153 | end |
@@ -165,4 +168,12 @@ class Enterprise < Organization | @@ -165,4 +168,12 @@ class Enterprise < Organization | ||
165 | enable_contact_us | 168 | enable_contact_us |
166 | end | 169 | end |
167 | 170 | ||
171 | + def control_panel_settings_button | ||
172 | + {:title => __('Enterprise Info and settings'), :icon => 'edit-profile-enterprise'} | ||
173 | + end | ||
174 | + | ||
175 | + def create_product? | ||
176 | + true | ||
177 | + end | ||
178 | + | ||
168 | end | 179 | end |
app/models/environment.rb
@@ -9,6 +9,13 @@ class Environment < ActiveRecord::Base | @@ -9,6 +9,13 @@ class Environment < ActiveRecord::Base | ||
9 | 9 | ||
10 | has_many :tasks, :dependent => :destroy, :as => 'target' | 10 | has_many :tasks, :dependent => :destroy, :as => 'target' |
11 | 11 | ||
12 | + IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/ | ||
13 | + | ||
14 | + def self.verify_filename(filename) | ||
15 | + filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS | ||
16 | + filename | ||
17 | + end | ||
18 | + | ||
12 | PERMISSIONS['Environment'] = { | 19 | PERMISSIONS['Environment'] = { |
13 | 'view_environment_admin_panel' => N_('View environment admin panel'), | 20 | 'view_environment_admin_panel' => N_('View environment admin panel'), |
14 | 'edit_environment_features' => N_('Edit environment features'), | 21 | 'edit_environment_features' => N_('Edit environment features'), |
@@ -67,6 +74,10 @@ class Environment < ActiveRecord::Base | @@ -67,6 +74,10 @@ class Environment < ActiveRecord::Base | ||
67 | self.affiliate(user, Environment::Roles.admin(self.id)) | 74 | self.affiliate(user, Environment::Roles.admin(self.id)) |
68 | end | 75 | end |
69 | 76 | ||
77 | + def remove_admin(user) | ||
78 | + self.disaffiliate(user, Environment::Roles.admin(self.id)) | ||
79 | + end | ||
80 | + | ||
70 | def admins | 81 | def admins |
71 | Person.members_of(self).all(:conditions => ['role_assignments.role_id = ?', Environment::Roles.admin(self).id]) | 82 | Person.members_of(self).all(:conditions => ['role_assignments.role_id = ?', Environment::Roles.admin(self).id]) |
72 | end | 83 | end |
@@ -106,6 +117,7 @@ class Environment < ActiveRecord::Base | @@ -106,6 +117,7 @@ class Environment < ActiveRecord::Base | ||
106 | 'enable_organization_url_change' => _("Allow organizations to change their URL"), | 117 | 'enable_organization_url_change' => _("Allow organizations to change their URL"), |
107 | 'admin_must_approve_new_communities' => _("Admin must approve creation of communities"), | 118 | 'admin_must_approve_new_communities' => _("Admin must approve creation of communities"), |
108 | 'enterprises_are_disabled_when_created' => __('Enterprises are disabled when created'), | 119 | 'enterprises_are_disabled_when_created' => __('Enterprises are disabled when created'), |
120 | + 'enterprises_are_validated_when_created' => __('Enterprises are validated when created'), | ||
109 | 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'), | 121 | 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'), |
110 | 'xmpp_chat' => _('XMPP/Jabber based chat'), | 122 | 'xmpp_chat' => _('XMPP/Jabber based chat'), |
111 | 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images') | 123 | 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images') |
@@ -218,7 +230,19 @@ class Environment < ActiveRecord::Base | @@ -218,7 +230,19 @@ class Environment < ActiveRecord::Base | ||
218 | settings_items :currency_separator, :type => String, :default => '.' | 230 | settings_items :currency_separator, :type => String, :default => '.' |
219 | settings_items :currency_delimiter, :type => String, :default => ',' | 231 | settings_items :currency_delimiter, :type => String, :default => ',' |
220 | 232 | ||
221 | - settings_items :trusted_sites_for_iframe, :type => Array, :default => ['itheora.org', 'tv.softwarelivre.org', 'stream.softwarelivre.org'] | 233 | + settings_items :trusted_sites_for_iframe, :type => Array, :default => %w[ |
234 | + developer.myspace.com | ||
235 | + itheora.org | ||
236 | + maps.google.com | ||
237 | + platform.twitter.com | ||
238 | + player.vimeo.com | ||
239 | + stream.softwarelivre.org | ||
240 | + tv.softwarelivre.org | ||
241 | + www.facebook.com | ||
242 | + www.flickr.com | ||
243 | + www.gmodules.com | ||
244 | + www.youtube.com | ||
245 | + ] + ('a' .. 'z').map{|i| "#{i}.yimg.com"} | ||
222 | 246 | ||
223 | settings_items :enabled_plugins, :type => Array, :default => [] | 247 | settings_items :enabled_plugins, :type => Array, :default => [] |
224 | 248 | ||
@@ -228,17 +252,28 @@ class Environment < ActiveRecord::Base | @@ -228,17 +252,28 @@ class Environment < ActiveRecord::Base | ||
228 | 252 | ||
229 | # Enables a feature identified by its name | 253 | # Enables a feature identified by its name |
230 | def enable(feature) | 254 | def enable(feature) |
231 | - self.settings["#{feature}_enabled"] = true | 255 | + self.settings["#{feature}_enabled".to_sym] = true |
256 | + end | ||
257 | + | ||
258 | + def enable_plugin(plugin) | ||
259 | + self.enabled_plugins += [plugin] | ||
260 | + self.enabled_plugins.uniq! | ||
261 | + self.save! | ||
232 | end | 262 | end |
233 | 263 | ||
234 | # Disables a feature identified by its name | 264 | # Disables a feature identified by its name |
235 | def disable(feature) | 265 | def disable(feature) |
236 | - self.settings["#{feature}_enabled"] = false | 266 | + self.settings["#{feature}_enabled".to_sym] = false |
267 | + end | ||
268 | + | ||
269 | + def disable_plugin(plugin) | ||
270 | + self.enabled_plugins.delete(plugin) | ||
271 | + self.save! | ||
237 | end | 272 | end |
238 | 273 | ||
239 | # Tells if a feature, identified by its name, is enabled | 274 | # Tells if a feature, identified by its name, is enabled |
240 | def enabled?(feature) | 275 | def enabled?(feature) |
241 | - self.settings["#{feature}_enabled"] == true | 276 | + self.settings["#{feature}_enabled".to_sym] == true |
242 | end | 277 | end |
243 | 278 | ||
244 | # enables the features identified by <tt>features</tt>, which is expected to | 279 | # enables the features identified by <tt>features</tt>, which is expected to |
@@ -494,6 +529,7 @@ class Environment < ActiveRecord::Base | @@ -494,6 +529,7 @@ class Environment < ActiveRecord::Base | ||
494 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' | 529 | xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation' |
495 | 530 | ||
496 | validates_presence_of :theme | 531 | validates_presence_of :theme |
532 | + validates_numericality_of :reports_lower_bound, :allow_nil => false, :only_integer => true, :greater_than_or_equal_to => 0 | ||
497 | 533 | ||
498 | include WhiteListFilter | 534 | include WhiteListFilter |
499 | filter_iframes :message_for_disabled_enterprise, :whitelist => lambda { trusted_sites_for_iframe } | 535 | filter_iframes :message_for_disabled_enterprise, :whitelist => lambda { trusted_sites_for_iframe } |
@@ -517,12 +553,12 @@ class Environment < ActiveRecord::Base | @@ -517,12 +553,12 @@ class Environment < ActiveRecord::Base | ||
517 | # If #force_www is true, adds 'www.' at the beginning of the hostname. If the | 553 | # If #force_www is true, adds 'www.' at the beginning of the hostname. If the |
518 | # environment has not associated domains, returns 'localhost'. | 554 | # environment has not associated domains, returns 'localhost'. |
519 | def default_hostname(email_hostname = false) | 555 | def default_hostname(email_hostname = false) |
520 | - if self.domains(true).empty? | ||
521 | - 'localhost' | ||
522 | - else | 556 | + domain = 'localhost' |
557 | + unless self.domains(true).empty? | ||
523 | domain = (self.domains.find_by_is_default(true) || self.domains.find(:first, :order => 'id')).name | 558 | domain = (self.domains.find_by_is_default(true) || self.domains.find(:first, :order => 'id')).name |
524 | - email_hostname ? domain : (force_www ? ('www.' + domain) : domain) | 559 | + domain = email_hostname ? domain : (force_www ? ('www.' + domain) : domain) |
525 | end | 560 | end |
561 | + domain | ||
526 | end | 562 | end |
527 | 563 | ||
528 | def top_url | 564 | def top_url |
@@ -671,13 +707,14 @@ class Environment < ActiveRecord::Base | @@ -671,13 +707,14 @@ class Environment < ActiveRecord::Base | ||
671 | def create_templates | 707 | def create_templates |
672 | pre = self.name.to_slug + '_' | 708 | pre = self.name.to_slug + '_' |
673 | ent_id = Enterprise.create!(:name => 'Enterprise template', :identifier => pre + 'enterprise_template', :environment => self, :visible => false).id | 709 | ent_id = Enterprise.create!(:name => 'Enterprise template', :identifier => pre + 'enterprise_template', :environment => self, :visible => false).id |
710 | + inactive_enterprise_tmpl = Enterprise.create!(:name => 'Inactive Enterprise template', :identifier => pre + 'inactive_enterprise_template', :environment => self, :visible => false) | ||
674 | com_id = Community.create!(:name => 'Community template', :identifier => pre + 'community_template', :environment => self, :visible => false).id | 711 | com_id = Community.create!(:name => 'Community template', :identifier => pre + 'community_template', :environment => self, :visible => false).id |
675 | pass = Digest::MD5.hexdigest rand.to_s | 712 | pass = Digest::MD5.hexdigest rand.to_s |
676 | user = User.create!(:login => (pre + 'person_template'), :email => (pre + 'template@template.noo'), :password => pass, :password_confirmation => pass, :environment => self).person | 713 | user = User.create!(:login => (pre + 'person_template'), :email => (pre + 'template@template.noo'), :password => pass, :password_confirmation => pass, :environment => self).person |
677 | - user.visible = false | ||
678 | - user.save! | 714 | + user.update_attributes(:visible => false, :name => "Person template") |
679 | usr_id = user.id | 715 | usr_id = user.id |
680 | self.settings[:enterprise_template_id] = ent_id | 716 | self.settings[:enterprise_template_id] = ent_id |
717 | + self.inactive_enterprise_template = inactive_enterprise_tmpl | ||
681 | self.settings[:community_template_id] = com_id | 718 | self.settings[:community_template_id] = com_id |
682 | self.settings[:person_template_id] = usr_id | 719 | self.settings[:person_template_id] = usr_id |
683 | self.save! | 720 | self.save! |
@@ -685,7 +722,7 @@ class Environment < ActiveRecord::Base | @@ -685,7 +722,7 @@ class Environment < ActiveRecord::Base | ||
685 | 722 | ||
686 | after_destroy :destroy_templates | 723 | after_destroy :destroy_templates |
687 | def destroy_templates | 724 | def destroy_templates |
688 | - [enterprise_template, community_template, person_template].compact.each do |template| | 725 | + [enterprise_template, inactive_enterprise_template, community_template, person_template].compact.each do |template| |
689 | template.destroy | 726 | template.destroy |
690 | end | 727 | end |
691 | end | 728 | end |
@@ -701,6 +738,4 @@ class Environment < ActiveRecord::Base | @@ -701,6 +738,4 @@ class Environment < ActiveRecord::Base | ||
701 | def image_galleries | 738 | def image_galleries |
702 | portal_community ? portal_community.image_galleries : [] | 739 | portal_community ? portal_community.image_galleries : [] |
703 | end | 740 | end |
704 | - | ||
705 | end | 741 | end |
706 | - |
@@ -0,0 +1,31 @@ | @@ -0,0 +1,31 @@ | ||
1 | +class FansBlock < ProfileListBlock | ||
2 | + | ||
3 | + def self.description | ||
4 | + _('Displays the people who like the enterprise') | ||
5 | + end | ||
6 | + | ||
7 | + def default_title | ||
8 | + n__('{#} fan', '{#} fans', profile_count) | ||
9 | + end | ||
10 | + | ||
11 | + def help | ||
12 | + _('This block presents the fans of an enterprise.') | ||
13 | + end | ||
14 | + | ||
15 | + def footer | ||
16 | + profile = self.owner | ||
17 | + lambda do | ||
18 | + link_to _('View all'), :profile => profile.identifier, :controller => | ||
19 | + 'profile', :action => 'fans' | ||
20 | + end | ||
21 | + end | ||
22 | + | ||
23 | + def profiles | ||
24 | + owner.fans | ||
25 | + end | ||
26 | + | ||
27 | + def profile_count | ||
28 | + profiles.visible.count | ||
29 | + end | ||
30 | + | ||
31 | +end |
app/models/folder.rb
@@ -29,7 +29,7 @@ class Folder < Article | @@ -29,7 +29,7 @@ class Folder < Article | ||
29 | def to_html(options = {}) | 29 | def to_html(options = {}) |
30 | folder = self | 30 | folder = self |
31 | lambda do | 31 | lambda do |
32 | - render :file => 'content_viewer/folder', :locals => { :folder => folder } | 32 | + render :file => 'content_viewer/folder', :locals => {:folder => folder} |
33 | end | 33 | end |
34 | end | 34 | end |
35 | 35 |
app/models/image.rb
1 | class Image < ActiveRecord::Base | 1 | class Image < ActiveRecord::Base |
2 | - belongs_to :owner, :polymorphic => true | ||
3 | 2 | ||
4 | def self.max_size | 3 | def self.max_size |
5 | Image.attachment_options[:max_size] | 4 | Image.attachment_options[:max_size] |
6 | end | 5 | end |
7 | 6 | ||
7 | + sanitize_filename | ||
8 | + | ||
8 | has_attachment :content_type => :image, | 9 | has_attachment :content_type => :image, |
9 | :storage => :file_system, | 10 | :storage => :file_system, |
10 | :path_prefix => 'public/image_uploads', | 11 | :path_prefix => 'public/image_uploads', |
@@ -20,4 +21,6 @@ class Image < ActiveRecord::Base | @@ -20,4 +21,6 @@ class Image < ActiveRecord::Base | ||
20 | 21 | ||
21 | delay_attachment_fu_thumbnails | 22 | delay_attachment_fu_thumbnails |
22 | 23 | ||
24 | + postgresql_attachment_fu | ||
25 | + | ||
23 | end | 26 | end |
app/models/invitation.rb
@@ -27,6 +27,10 @@ class Invitation < Task | @@ -27,6 +27,10 @@ class Invitation < Task | ||
27 | TaskMailer.deliver_invitation_notification(task) unless task.friend | 27 | TaskMailer.deliver_invitation_notification(task) unless task.friend |
28 | end | 28 | end |
29 | 29 | ||
30 | + def title | ||
31 | + _('Invitation') | ||
32 | + end | ||
33 | + | ||
30 | def validate | 34 | def validate |
31 | super | 35 | super |
32 | email = friend ? friend.user.email : friend_email | 36 | email = friend ? friend.user.email : friend_email |
app/models/invite_friend.rb
app/models/link_list_block.rb
@@ -57,7 +57,7 @@ class LinkListBlock < Block | @@ -57,7 +57,7 @@ class LinkListBlock < Block | ||
57 | def link_html(link) | 57 | def link_html(link) |
58 | klass = 'icon-' + link[:icon] if link[:icon] | 58 | klass = 'icon-' + link[:icon] if link[:icon] |
59 | sanitize_link( | 59 | sanitize_link( |
60 | - link_to(_(link[:name]), expand_address(link[:address]), :class => klass) | 60 | + link_to(link[:name], expand_address(link[:address]), :class => klass) |
61 | ) | 61 | ) |
62 | end | 62 | end |
63 | 63 |
app/models/organization.rb
@@ -95,12 +95,12 @@ class Organization < Profile | @@ -95,12 +95,12 @@ class Organization < Profile | ||
95 | [] | 95 | [] |
96 | end | 96 | end |
97 | 97 | ||
98 | - N_('Display name'); N_('Description'); N_('Contact person'); N_('Contact email'); N_('Acronym'); N_('Foundation year'); N_('Legal form'); N_('Economic activity'); N_('Management information'); N_('Validated'); N_('Tag list') | ||
99 | - settings_items :display_name, :description, :contact_person, :contact_email, :acronym, :foundation_year, :legal_form, :economic_activity, :management_information, :validated, :cnpj | 98 | + N_('Display name'); N_('Description'); N_('Contact person'); N_('Contact email'); N_('Acronym'); N_('Foundation year'); N_('Legal form'); N_('Economic activity'); N_('Management information'); N_('Tag list') |
99 | + settings_items :display_name, :description, :contact_person, :contact_email, :acronym, :foundation_year, :legal_form, :economic_activity, :management_information | ||
100 | 100 | ||
101 | validates_format_of :foundation_year, :with => Noosfero::Constants::INTEGER_FORMAT | 101 | validates_format_of :foundation_year, :with => Noosfero::Constants::INTEGER_FORMAT |
102 | - | ||
103 | validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |org| !org.contact_email.blank? }) | 102 | validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |org| !org.contact_email.blank? }) |
103 | + validates_as_cnpj :cnpj | ||
104 | 104 | ||
105 | xss_terminate :only => [ :acronym, :contact_person, :contact_email, :legal_form, :economic_activity, :management_information ], :on => 'validation' | 105 | xss_terminate :only => [ :acronym, :contact_person, :contact_email, :legal_form, :economic_activity, :management_information ], :on => 'validation' |
106 | 106 | ||
@@ -149,4 +149,12 @@ class Organization < Profile | @@ -149,4 +149,12 @@ class Organization < Profile | ||
149 | false | 149 | false |
150 | end | 150 | end |
151 | 151 | ||
152 | + def members_to_json | ||
153 | + members.map { |member| {:id => member.id, :name => member.name} }.to_json | ||
154 | + end | ||
155 | + | ||
156 | + def members_by_role_to_json(role) | ||
157 | + members_by_role(role).map { |member| {:id => member.id, :name => member.name} }.to_json | ||
158 | + end | ||
159 | + | ||
152 | end | 160 | end |
app/models/person.rb
@@ -17,6 +17,8 @@ class Person < Profile | @@ -17,6 +17,8 @@ class Person < Profile | ||
17 | 17 | ||
18 | has_many :requested_tasks, :class_name => 'Task', :foreign_key => :requestor_id, :dependent => :destroy | 18 | has_many :requested_tasks, :class_name => 'Task', :foreign_key => :requestor_id, :dependent => :destroy |
19 | 19 | ||
20 | + has_many :abuse_reports, :foreign_key => 'reporter_id', :dependent => :destroy | ||
21 | + | ||
20 | has_many :mailings | 22 | has_many :mailings |
21 | 23 | ||
22 | has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy | 24 | has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy |
@@ -116,6 +118,8 @@ class Person < Profile | @@ -116,6 +118,8 @@ class Person < Profile | ||
116 | description | 118 | description |
117 | ] | 119 | ] |
118 | 120 | ||
121 | + validates_multiparameter_assignments | ||
122 | + | ||
119 | def self.fields | 123 | def self.fields |
120 | FIELDS | 124 | FIELDS |
121 | end | 125 | end |
@@ -387,6 +391,21 @@ class Person < Profile | @@ -387,6 +391,21 @@ class Person < Profile | ||
387 | leave_hash.to_json | 391 | leave_hash.to_json |
388 | end | 392 | end |
389 | 393 | ||
394 | + def already_reported?(profile) | ||
395 | + abuse_reports.any? { |report| report.abuse_complaint.reported == profile && report.abuse_complaint.opened? } | ||
396 | + end | ||
397 | + | ||
398 | + def register_report(abuse_report, profile) | ||
399 | + AbuseComplaint.create!(:reported => profile, :target => profile.environment) if !profile.opened_abuse_complaint | ||
400 | + abuse_report.abuse_complaint = profile.opened_abuse_complaint | ||
401 | + abuse_report.reporter = self | ||
402 | + abuse_report.save! | ||
403 | + end | ||
404 | + | ||
405 | + def control_panel_settings_button | ||
406 | + {:title => _('Profile Info and settings'), :icon => 'edit-profile'} | ||
407 | + end | ||
408 | + | ||
390 | protected | 409 | protected |
391 | 410 | ||
392 | def followed_by?(profile) | 411 | def followed_by?(profile) |
app/models/product.rb
@@ -66,7 +66,7 @@ class Product < ActiveRecord::Base | @@ -66,7 +66,7 @@ class Product < ActiveRecord::Base | ||
66 | end | 66 | end |
67 | 67 | ||
68 | def default_image(size='thumb') | 68 | def default_image(size='thumb') |
69 | - '/images/icons-app/product-default-pic-%s.png' % size | 69 | + image ? image.public_filename(size) : '/images/icons-app/product-default-pic-%s.png' % size |
70 | end | 70 | end |
71 | 71 | ||
72 | def category_full_name | 72 | def category_full_name |
@@ -149,4 +149,8 @@ class Product < ActiveRecord::Base | @@ -149,4 +149,8 @@ class Product < ActiveRecord::Base | ||
149 | unit.blank? ? name : "#{name} - #{unit.name.downcase}" | 149 | unit.blank? ? name : "#{name} - #{unit.name.downcase}" |
150 | end | 150 | end |
151 | 151 | ||
152 | + def display_supplier_on_search? | ||
153 | + true | ||
154 | + end | ||
155 | + | ||
152 | end | 156 | end |
app/models/products_block.rb
@@ -20,7 +20,15 @@ class ProductsBlock < Block | @@ -20,7 +20,15 @@ class ProductsBlock < Block | ||
20 | block_title(title) + | 20 | block_title(title) + |
21 | content_tag( | 21 | content_tag( |
22 | 'ul', | 22 | 'ul', |
23 | - products.map {|product| content_tag('li', link_to(product.name, product.url, :style => 'background-image:url(%s)' % ( product.image ? product.image.public_filename(:minor) : product.default_image('minor'))), :class => 'product' )} | 23 | + products.map {|product| |
24 | + content_tag('li', | ||
25 | + link_to( product.name, | ||
26 | + product.url, | ||
27 | + :style => 'background-image:url(%s)' % product.default_image('minor') | ||
28 | + ), | ||
29 | + :class => 'product' | ||
30 | + ) | ||
31 | + } | ||
24 | ) | 32 | ) |
25 | end | 33 | end |
26 | 34 |
app/models/profile.rb
@@ -52,8 +52,9 @@ class Profile < ActiveRecord::Base | @@ -52,8 +52,9 @@ class Profile < ActiveRecord::Base | ||
52 | acts_as_accessible | 52 | acts_as_accessible |
53 | 53 | ||
54 | named_scope :memberships_of, lambda { |person| { :select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.accessor_type = ? AND role_assignments.accessor_id = ?', person.class.base_class.name, person.id ] } } | 54 | named_scope :memberships_of, lambda { |person| { :select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.accessor_type = ? AND role_assignments.accessor_id = ?', person.class.base_class.name, person.id ] } } |
55 | - named_scope :enterprises, :conditions => "profiles.type = 'Enterprise'" | ||
56 | - named_scope :communities, :conditions => "profiles.type = 'Community'" | 55 | + #FIXME: these will work only if the subclass is already loaded |
56 | + named_scope :enterprises, lambda { {:conditions => (Enterprise.send(:subclasses).map(&:name) << 'Enterprise').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} } | ||
57 | + named_scope :communities, lambda { {:conditions => (Community.send(:subclasses).map(&:name) << 'Community').map { |klass| "profiles.type = '#{klass}'"}.join(" OR ")} } | ||
57 | 58 | ||
58 | def members | 59 | def members |
59 | Person.members_of(self) | 60 | Person.members_of(self) |
@@ -163,34 +164,19 @@ class Profile < ActiveRecord::Base | @@ -163,34 +164,19 @@ class Profile < ActiveRecord::Base | ||
163 | 164 | ||
164 | has_many :events, :source => 'articles', :class_name => 'Event', :order => 'name' | 165 | has_many :events, :source => 'articles', :class_name => 'Event', :order => 'name' |
165 | 166 | ||
166 | - %w[ pending finished ].each do |status| | ||
167 | - class_eval <<-CODE | ||
168 | - def all_#{status}_tasks | ||
169 | - env_tasks = [] | ||
170 | - if self.person? | ||
171 | - env_tasks = Environment.find(:all).select{ |env| self.is_admin?(env) }.map{ |env| env.tasks.#{status} }.flatten | ||
172 | - end | ||
173 | - tasks.#{status} + env_tasks | ||
174 | - end | ||
175 | - CODE | ||
176 | - end | ||
177 | - | ||
178 | def find_in_all_tasks(task_id) | 167 | def find_in_all_tasks(task_id) |
179 | - if tasks.exists?(task_id) | ||
180 | - return tasks.find(task_id) | ||
181 | - else | ||
182 | - if self.person? | ||
183 | - environments_admin = Environment.find(:all).select{ |env| self.is_admin?(env) } | ||
184 | - task = environments_admin.select{ |env| env.tasks.exists?(task_id) }.map{ |i| i.tasks.find(task_id) } | ||
185 | - return task.first unless task.empty? | ||
186 | - end | 168 | + begin |
169 | + Task.to(self).find(task_id) | ||
170 | + rescue | ||
171 | + nil | ||
187 | end | 172 | end |
188 | - return nil | ||
189 | end | 173 | end |
190 | 174 | ||
191 | has_many :profile_categorizations, :conditions => [ 'categories_profiles.virtual = ?', false ] | 175 | has_many :profile_categorizations, :conditions => [ 'categories_profiles.virtual = ?', false ] |
192 | has_many :categories, :through => :profile_categorizations | 176 | has_many :categories, :through => :profile_categorizations |
193 | 177 | ||
178 | + has_many :abuse_complaints, :foreign_key => 'requestor_id' | ||
179 | + | ||
194 | def interests | 180 | def interests |
195 | categories.select {|item| !item.is_a?(Region)} | 181 | categories.select {|item| !item.is_a?(Region)} |
196 | end | 182 | end |
@@ -564,9 +550,7 @@ private :generate_url, :url_options | @@ -564,9 +550,7 @@ private :generate_url, :url_options | ||
564 | if self.closed? && members_count > 0 | 550 | if self.closed? && members_count > 0 |
565 | AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) | 551 | AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) |
566 | else | 552 | else |
567 | - if members_count == 0 | ||
568 | - self.affiliate(person, Profile::Roles.admin(environment.id)) | ||
569 | - end | 553 | + self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0 |
570 | self.affiliate(person, Profile::Roles.member(environment.id)) | 554 | self.affiliate(person, Profile::Roles.member(environment.id)) |
571 | end | 555 | end |
572 | else | 556 | else |
@@ -809,6 +793,34 @@ private :generate_url, :url_options | @@ -809,6 +793,34 @@ private :generate_url, :url_options | ||
809 | "#{jid(options)}/#{short_name}" | 793 | "#{jid(options)}/#{short_name}" |
810 | end | 794 | end |
811 | 795 | ||
796 | + def is_on_homepage?(url, page=nil) | ||
797 | + if page | ||
798 | + page == self.home_page | ||
799 | + else | ||
800 | + url == '/' + self.identifier | ||
801 | + end | ||
802 | + end | ||
803 | + | ||
804 | + def opened_abuse_complaint | ||
805 | + abuse_complaints.opened.first | ||
806 | + end | ||
807 | + | ||
808 | + def disable | ||
809 | + self.visible = false | ||
810 | + user.password = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{identifier}--") | ||
811 | + user.password_confirmation = user.password | ||
812 | + save! | ||
813 | + user.save! | ||
814 | + end | ||
815 | + | ||
816 | + def control_panel_settings_button | ||
817 | + {:title => _('Profile Info and settings'), :icon => 'edit-profile'} | ||
818 | + end | ||
819 | + | ||
820 | + def self.identification | ||
821 | + name | ||
822 | + end | ||
823 | + | ||
812 | protected | 824 | protected |
813 | 825 | ||
814 | def followed_by?(person) | 826 | def followed_by?(person) |
app/models/profile_list_block.rb
1 | class ProfileListBlock < Block | 1 | class ProfileListBlock < Block |
2 | 2 | ||
3 | settings_items :limit, :type => :integer, :default => 6 | 3 | settings_items :limit, :type => :integer, :default => 6 |
4 | - settings_items :prioritize_profiles_with_image, :type => :boolean, :default => false | 4 | + settings_items :prioritize_profiles_with_image, :type => :boolean, :default => true |
5 | 5 | ||
6 | def self.description | 6 | def self.description |
7 | _('Random profiles') | 7 | _('Random profiles') |
@@ -13,21 +13,21 @@ class ProfileListBlock < Block | @@ -13,21 +13,21 @@ class ProfileListBlock < Block | ||
13 | end | 13 | end |
14 | 14 | ||
15 | def profile_list | 15 | def profile_list |
16 | - profiles.visible.all(:limit => limit, :select => 'DISTINCT profiles.*, ' + image_prioritizer + randomizer, :joins => "LEFT OUTER JOIN images ON images.owner_id = profiles.id", :order => image_prioritizer + randomizer) | 16 | + result = nil |
17 | + if !prioritize_profiles_with_image | ||
18 | + result = profiles.visible.all(:limit => limit, :order => 'updated_at DESC').sort_by{ rand } | ||
19 | + elsif profiles.visible.with_image.count >= limit | ||
20 | + result = profiles.visible.with_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand } | ||
21 | + else | ||
22 | + result = profiles.visible.with_image.sort_by{ rand } + profiles.visible.without_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand } | ||
23 | + end | ||
24 | + result.slice(0..limit-1) | ||
17 | end | 25 | end |
18 | 26 | ||
19 | def profile_count | 27 | def profile_count |
20 | profiles.visible.count('DISTINCT(profiles.id)') | 28 | profiles.visible.count('DISTINCT(profiles.id)') |
21 | end | 29 | end |
22 | 30 | ||
23 | - def randomizer | ||
24 | - @randomizer ||= "(profiles.id % #{rand(profile_count) + 1})" | ||
25 | - end | ||
26 | - | ||
27 | - def image_prioritizer | ||
28 | - prioritize_profiles_with_image ? '(images.id is null),' : '' | ||
29 | - end | ||
30 | - | ||
31 | # the title of the block. Probably will be overriden in subclasses. | 31 | # the title of the block. Probably will be overriden in subclasses. |
32 | def default_title | 32 | def default_title |
33 | _('{#} People or Groups') | 33 | _('{#} People or Groups') |
app/models/suggest_article.rb
1 | class SuggestArticle < Task | 1 | class SuggestArticle < Task |
2 | 2 | ||
3 | - has_captcha | ||
4 | - | ||
5 | validates_presence_of :target_id, :article_name, :email, :name, :article_body | 3 | validates_presence_of :target_id, :article_name, :email, :name, :article_body |
6 | 4 | ||
7 | settings_items :email, :type => String | 5 | settings_items :email, :type => String |
app/models/task.rb
@@ -20,11 +20,14 @@ class Task < ActiveRecord::Base | @@ -20,11 +20,14 @@ class Task < ActiveRecord::Base | ||
20 | # the status of a task that was cancelled. | 20 | # the status of a task that was cancelled. |
21 | CANCELLED = 2 | 21 | CANCELLED = 2 |
22 | 22 | ||
23 | - # the status os a task that was successfully finished | 23 | + # the status of a task that was successfully finished |
24 | FINISHED = 3 | 24 | FINISHED = 3 |
25 | 25 | ||
26 | + # the status of a task that was created but is not displayed yet | ||
27 | + HIDDEN = 4 | ||
28 | + | ||
26 | def self.names | 29 | def self.names |
27 | - [nil, N_('Active'), N_('Cancelled'), N_('Finished')] | 30 | + [nil, N_('Active'), N_('Cancelled'), N_('Finished'), N_('Hidden')] |
28 | end | 31 | end |
29 | end | 32 | end |
30 | 33 | ||
@@ -38,7 +41,7 @@ class Task < ActiveRecord::Base | @@ -38,7 +41,7 @@ class Task < ActiveRecord::Base | ||
38 | 41 | ||
39 | def initialize(*args) | 42 | def initialize(*args) |
40 | super | 43 | super |
41 | - self.status ||= Task::Status::ACTIVE | 44 | + self.status = (args.first ? args.first[:status] : nil) || Task::Status::ACTIVE |
42 | end | 45 | end |
43 | 46 | ||
44 | attr_accessor :code_length | 47 | attr_accessor :code_length |
@@ -52,20 +55,26 @@ class Task < ActiveRecord::Base | @@ -52,20 +55,26 @@ class Task < ActiveRecord::Base | ||
52 | end | 55 | end |
53 | 56 | ||
54 | after_create do |task| | 57 | after_create do |task| |
55 | - begin | ||
56 | - task.send(:send_notification, :created) | ||
57 | - rescue NotImplementedError => ex | ||
58 | - RAILS_DEFAULT_LOGGER.info ex.to_s | ||
59 | - end | ||
60 | - | ||
61 | - begin | ||
62 | - target_msg = task.target_notification_message | ||
63 | - TaskMailer.deliver_target_notification(task, target_msg) if target_msg | ||
64 | - rescue NotImplementedError => ex | ||
65 | - RAILS_DEFAULT_LOGGER.info ex.to_s | 58 | + unless task.status == Task::Status::HIDDEN |
59 | + begin | ||
60 | + task.send(:send_notification, :created) | ||
61 | + rescue NotImplementedError => ex | ||
62 | + RAILS_DEFAULT_LOGGER.info ex.to_s | ||
63 | + end | ||
64 | + | ||
65 | + begin | ||
66 | + target_msg = task.target_notification_message | ||
67 | + TaskMailer.deliver_target_notification(task, target_msg) if target_msg | ||
68 | + rescue NotImplementedError => ex | ||
69 | + RAILS_DEFAULT_LOGGER.info ex.to_s | ||
70 | + end | ||
66 | end | 71 | end |
67 | end | 72 | end |
68 | 73 | ||
74 | + def self.all_types | ||
75 | + %w[Invitation EnterpriseActivation AddMember Ticket SuggestArticle AddFriend CreateCommunity AbuseComplaint ApproveArticle CreateEnterprise ChangePassword EmailActivation InviteFriend InviteMember] | ||
76 | + end | ||
77 | + | ||
69 | # this method finished the task. It calls #perform, which must be overriden | 78 | # this method finished the task. It calls #perform, which must be overriden |
70 | # by subclasses. At the end a message (as returned by #finish_message) is | 79 | # by subclasses. At the end a message (as returned by #finish_message) is |
71 | # sent to the requestor with #notify_requestor. | 80 | # sent to the requestor with #notify_requestor. |
@@ -175,6 +184,12 @@ class Task < ActiveRecord::Base | @@ -175,6 +184,12 @@ class Task < ActiveRecord::Base | ||
175 | raise NotImplementedError, "#{self} does not implement #task_cancelled_message" | 184 | raise NotImplementedError, "#{self} does not implement #task_cancelled_message" |
176 | end | 185 | end |
177 | 186 | ||
187 | + # The message that will be sent to the requestor of the task when its | ||
188 | + # activated. | ||
189 | + def task_activated_message | ||
190 | + raise NotImplementedError, "#{self} does not implement #task_cancelled_message" | ||
191 | + end | ||
192 | + | ||
178 | # The message that will be sent to the *target* of the task when it is | 193 | # The message that will be sent to the *target* of the task when it is |
179 | # created. The indent of this message is to notify the target about the | 194 | # created. The indent of this message is to notify the target about the |
180 | # request that was just created for him/her. | 195 | # request that was just created for him/her. |
@@ -199,6 +214,23 @@ class Task < ActiveRecord::Base | @@ -199,6 +214,23 @@ class Task < ActiveRecord::Base | ||
199 | self.target.environment unless self.target.nil? | 214 | self.target.environment unless self.target.nil? |
200 | end | 215 | end |
201 | 216 | ||
217 | + def activate | ||
218 | + self.status = Task::Status::ACTIVE | ||
219 | + save! | ||
220 | + begin | ||
221 | + self.send(:send_notification, :activated) | ||
222 | + rescue NotImplementedError => ex | ||
223 | + RAILS_DEFAULT_LOGGER.info ex.to_s | ||
224 | + end | ||
225 | + | ||
226 | + begin | ||
227 | + target_msg = target_notification_message | ||
228 | + TaskMailer.deliver_target_notification(self, target_msg) if target_msg | ||
229 | + rescue NotImplementedError => ex | ||
230 | + RAILS_DEFAULT_LOGGER.info ex.to_s | ||
231 | + end | ||
232 | + end | ||
233 | + | ||
202 | protected | 234 | protected |
203 | 235 | ||
204 | # This method must be overrided in subclasses, and its implementation must do | 236 | # This method must be overrided in subclasses, and its implementation must do |
@@ -232,6 +264,23 @@ class Task < ActiveRecord::Base | @@ -232,6 +264,23 @@ class Task < ActiveRecord::Base | ||
232 | 264 | ||
233 | named_scope :pending, :conditions => { :status => Task::Status::ACTIVE } | 265 | named_scope :pending, :conditions => { :status => Task::Status::ACTIVE } |
234 | named_scope :finished, :conditions => { :status => [Task::Status::CANCELLED, Task::Status::FINISHED] } | 266 | named_scope :finished, :conditions => { :status => [Task::Status::CANCELLED, Task::Status::FINISHED] } |
267 | + named_scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] } | ||
268 | + named_scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } | ||
269 | + named_scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } | ||
270 | + | ||
271 | + named_scope :to, lambda { |profile| | ||
272 | + environment_condition = nil | ||
273 | + if profile.person? | ||
274 | + envs_ids = Environment.find(:all).select{ |env| profile.is_admin?(env) }.map { |env| "target_id = #{env.id}"}.join(' OR ') | ||
275 | + environment_condition = envs_ids.blank? ? nil : "(target_type = 'Environment' AND (#{envs_ids}))" | ||
276 | + end | ||
277 | + profile_condition = "(target_type = 'Profile' AND target_id = #{profile.id})" | ||
278 | + { :conditions => [environment_condition, profile_condition].compact.join(' OR ') } | ||
279 | + } | ||
280 | + | ||
281 | + def opened? | ||
282 | + status == Task::Status::ACTIVE || status == Task::Status::HIDDEN | ||
283 | + end | ||
235 | 284 | ||
236 | class << self | 285 | class << self |
237 | 286 | ||
@@ -254,6 +303,10 @@ class Task < ActiveRecord::Base | @@ -254,6 +303,10 @@ class Task < ActiveRecord::Base | ||
254 | self.find(:first, :conditions => { :code => code, :status => Task::Status::ACTIVE }) | 303 | self.find(:first, :conditions => { :code => code, :status => Task::Status::ACTIVE }) |
255 | end | 304 | end |
256 | 305 | ||
306 | + def per_page | ||
307 | + 15 | ||
308 | + end | ||
309 | + | ||
257 | end | 310 | end |
258 | 311 | ||
259 | end | 312 | end |
app/models/text_article.rb
1 | # a base class for all text article types. | 1 | # a base class for all text article types. |
2 | class TextArticle < Article | 2 | class TextArticle < Article |
3 | 3 | ||
4 | - xss_terminate :only => [ :name, :abstract, :body ], :on => 'validation' | 4 | + xss_terminate :only => [ :name ], :on => 'validation' |
5 | 5 | ||
6 | include Noosfero::TranslatableContent | 6 | include Noosfero::TranslatableContent |
7 | 7 |
app/models/textile_article.rb
@@ -9,11 +9,28 @@ class TextileArticle < TextArticle | @@ -9,11 +9,28 @@ class TextileArticle < TextArticle | ||
9 | end | 9 | end |
10 | 10 | ||
11 | def to_html(options ={}) | 11 | def to_html(options ={}) |
12 | - RedCloth.new(self.body|| '').to_html | 12 | + convert_to_html(body) |
13 | + end | ||
14 | + | ||
15 | + def lead | ||
16 | + if abstract.blank? | ||
17 | + super | ||
18 | + else | ||
19 | + convert_to_html(abstract) | ||
20 | + end | ||
13 | end | 21 | end |
14 | 22 | ||
15 | def notifiable? | 23 | def notifiable? |
16 | true | 24 | true |
17 | end | 25 | end |
18 | 26 | ||
27 | + protected | ||
28 | + | ||
29 | + def convert_to_html(textile) | ||
30 | + @@sanitizer ||= HTML::WhiteListSanitizer.new | ||
31 | + converter = RedCloth.new(textile|| '') | ||
32 | + converter.hard_breaks = false | ||
33 | + @@sanitizer.sanitize(converter.to_html) | ||
34 | + end | ||
35 | + | ||
19 | end | 36 | end |
app/models/thumbnail.rb
@@ -2,4 +2,8 @@ class Thumbnail < ActiveRecord::Base | @@ -2,4 +2,8 @@ class Thumbnail < ActiveRecord::Base | ||
2 | has_attachment :storage => :file_system, | 2 | has_attachment :storage => :file_system, |
3 | :content_type => :image, :max_size => 5.megabytes | 3 | :content_type => :image, :max_size => 5.megabytes |
4 | validates_as_attachment | 4 | validates_as_attachment |
5 | + | ||
6 | + sanitize_filename | ||
7 | + | ||
8 | + postgresql_attachment_fu | ||
5 | end | 9 | end |
app/models/ticket.rb
app/models/uploaded_file.rb
@@ -18,6 +18,8 @@ class UploadedFile < Article | @@ -18,6 +18,8 @@ class UploadedFile < Article | ||
18 | 18 | ||
19 | validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? }) | 19 | validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? }) |
20 | 20 | ||
21 | + sanitize_filename | ||
22 | + | ||
21 | before_create do |uploaded_file| | 23 | before_create do |uploaded_file| |
22 | uploaded_file.is_image = true if uploaded_file.image? | 24 | uploaded_file.is_image = true if uploaded_file.image? |
23 | end | 25 | end |
@@ -52,6 +54,8 @@ class UploadedFile < Article | @@ -52,6 +54,8 @@ class UploadedFile < Article | ||
52 | 54 | ||
53 | delay_attachment_fu_thumbnails | 55 | delay_attachment_fu_thumbnails |
54 | 56 | ||
57 | + postgresql_attachment_fu | ||
58 | + | ||
55 | def self.icon_name(article = nil) | 59 | def self.icon_name(article = nil) |
56 | if article | 60 | if article |
57 | article.image? ? article.public_filename(:icon) : (article.mime_type ? article.mime_type.gsub(/[\/+.]/, '-') : 'upload-file') | 61 | article.image? ? article.public_filename(:icon) : (article.mime_type ? article.mime_type.gsub(/[\/+.]/, '-') : 'upload-file') |
@@ -132,4 +136,8 @@ class UploadedFile < Article | @@ -132,4 +136,8 @@ class UploadedFile < Article | ||
132 | def gallery? | 136 | def gallery? |
133 | self.parent && self.parent.folder? && self.parent.gallery? | 137 | self.parent && self.parent.folder? && self.parent.gallery? |
134 | end | 138 | end |
139 | + | ||
140 | + def uploaded_file? | ||
141 | + true | ||
142 | + end | ||
135 | end | 143 | end |
app/models/user.rb
@@ -21,6 +21,8 @@ class User < ActiveRecord::Base | @@ -21,6 +21,8 @@ class User < ActiveRecord::Base | ||
21 | end | 21 | end |
22 | end | 22 | end |
23 | 23 | ||
24 | + before_create :make_activation_code | ||
25 | + | ||
24 | before_create do |user| | 26 | before_create do |user| |
25 | if user.environment.nil? | 27 | if user.environment.nil? |
26 | user.environment = Environment.default | 28 | user.environment = Environment.default |
@@ -31,8 +33,11 @@ class User < ActiveRecord::Base | @@ -31,8 +33,11 @@ class User < ActiveRecord::Base | ||
31 | user.person ||= Person.new | 33 | user.person ||= Person.new |
32 | user.person.attributes = user.person_data.merge(:identifier => user.login, :user_id => user.id, :environment_id => user.environment_id) | 34 | user.person.attributes = user.person_data.merge(:identifier => user.login, :user_id => user.id, :environment_id => user.environment_id) |
33 | user.person.name ||= user.login | 35 | user.person.name ||= user.login |
36 | + user.person.visible = false unless user.activated? | ||
34 | user.person.save! | 37 | user.person.save! |
35 | end | 38 | end |
39 | + after_create :deliver_activation_code | ||
40 | + after_create :delay_activation_check | ||
36 | 41 | ||
37 | attr_writer :person_data | 42 | attr_writer :person_data |
38 | def person_data | 43 | def person_data |
@@ -55,6 +60,17 @@ class User < ActiveRecord::Base | @@ -55,6 +60,17 @@ class User < ActiveRecord::Base | ||
55 | :environment => user.environment.name, | 60 | :environment => user.environment.name, |
56 | :url => url_for(:host => user.environment.default_hostname, :controller => 'home') | 61 | :url => url_for(:host => user.environment.default_hostname, :controller => 'home') |
57 | end | 62 | end |
63 | + | ||
64 | + def activation_code(user) | ||
65 | + recipients user.email | ||
66 | + | ||
67 | + from "#{user.environment.name} <#{user.environment.contact_email}>" | ||
68 | + subject _("[%s] Activate your account") % [user.environment.name] | ||
69 | + body :recipient => user.name, | ||
70 | + :activation_code => user.activation_code, | ||
71 | + :environment => user.environment.name, | ||
72 | + :url => user.environment.top_url | ||
73 | + end | ||
58 | end | 74 | end |
59 | 75 | ||
60 | def signup! | 76 | def signup! |
@@ -67,6 +83,8 @@ class User < ActiveRecord::Base | @@ -67,6 +83,8 @@ class User < ActiveRecord::Base | ||
67 | has_one :person, :dependent => :destroy | 83 | has_one :person, :dependent => :destroy |
68 | belongs_to :environment | 84 | belongs_to :environment |
69 | 85 | ||
86 | + attr_protected :activated_at | ||
87 | + | ||
70 | # Virtual attribute for the unencrypted password | 88 | # Virtual attribute for the unencrypted password |
71 | attr_accessor :password | 89 | attr_accessor :password |
72 | 90 | ||
@@ -87,10 +105,22 @@ class User < ActiveRecord::Base | @@ -87,10 +105,22 @@ class User < ActiveRecord::Base | ||
87 | # Authenticates a user by their login name and unencrypted password. Returns the user or nil. | 105 | # Authenticates a user by their login name and unencrypted password. Returns the user or nil. |
88 | def self.authenticate(login, password, environment = nil) | 106 | def self.authenticate(login, password, environment = nil) |
89 | environment ||= Environment.default | 107 | environment ||= Environment.default |
90 | - u = find_by_login_and_environment_id(login, environment.id) # need to get the salt | 108 | + u = first :conditions => ['login = ? AND environment_id = ? AND activated_at IS NOT NULL', login, environment.id] # need to get the salt |
91 | u && u.authenticated?(password) ? u : nil | 109 | u && u.authenticated?(password) ? u : nil |
92 | end | 110 | end |
93 | 111 | ||
112 | + # Activates the user in the database. | ||
113 | + def activate | ||
114 | + self.activated_at = Time.now.utc | ||
115 | + self.activation_code = nil | ||
116 | + self.person.visible = true | ||
117 | + self.person.save! && self.save | ||
118 | + end | ||
119 | + | ||
120 | + def activated? | ||
121 | + self.activation_code.nil? && !self.activated_at.nil? | ||
122 | + end | ||
123 | + | ||
94 | class UnsupportedEncryptionType < Exception; end | 124 | class UnsupportedEncryptionType < Exception; end |
95 | 125 | ||
96 | def self.system_encryption_method | 126 | def self.system_encryption_method |
@@ -195,7 +225,7 @@ class User < ActiveRecord::Base | @@ -195,7 +225,7 @@ class User < ActiveRecord::Base | ||
195 | end | 225 | end |
196 | 226 | ||
197 | def name | 227 | def name |
198 | - person.name | 228 | + person ? person.name : login |
199 | end | 229 | end |
200 | 230 | ||
201 | def enable_email! | 231 | def enable_email! |
@@ -253,4 +283,16 @@ class User < ActiveRecord::Base | @@ -253,4 +283,16 @@ class User < ActiveRecord::Base | ||
253 | def password_required? | 283 | def password_required? |
254 | crypted_password.blank? || !password.blank? | 284 | crypted_password.blank? || !password.blank? |
255 | end | 285 | end |
286 | + | ||
287 | + def make_activation_code | ||
288 | + self.activation_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by{rand}.join) | ||
289 | + end | ||
290 | + | ||
291 | + def deliver_activation_code | ||
292 | + User::Mailer.deliver_activation_code(self) unless self.activation_code.blank? | ||
293 | + end | ||
294 | + | ||
295 | + def delay_activation_check | ||
296 | + Delayed::Job.enqueue(UserActivationJob.new(self.id), 0, 72.hours.from_now) | ||
297 | + end | ||
256 | end | 298 | end |
app/sweepers/article_sweeper.rb
@@ -21,7 +21,7 @@ protected | @@ -21,7 +21,7 @@ protected | ||
21 | blocks = article.profile.blocks | 21 | blocks = article.profile.blocks |
22 | blocks += article.profile.environment.blocks if article.profile.environment | 22 | blocks += article.profile.environment.blocks if article.profile.environment |
23 | blocks = blocks.select{|b|[RecentDocumentsBlock, BlogArchivesBlock].any?{|c| b.kind_of?(c)}} | 23 | blocks = blocks.select{|b|[RecentDocumentsBlock, BlogArchivesBlock].any?{|c| b.kind_of?(c)}} |
24 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 24 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
25 | env = article.profile.environment | 25 | env = article.profile.environment |
26 | if env && (env.portal_community == article.profile) | 26 | if env && (env.portal_community == article.profile) |
27 | expire_fragment(env.portal_news_cache_key) | 27 | expire_fragment(env.portal_news_cache_key) |
app/sweepers/friendship_sweeper.rb
@@ -35,7 +35,7 @@ protected | @@ -35,7 +35,7 @@ protected | ||
35 | end | 35 | end |
36 | 36 | ||
37 | blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} | 37 | blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} |
38 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 38 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
39 | end | 39 | end |
40 | 40 | ||
41 | end | 41 | end |
app/sweepers/profile_sweeper.rb
@@ -23,12 +23,25 @@ protected | @@ -23,12 +23,25 @@ protected | ||
23 | expire_profile_index(profile) if profile.person? | 23 | expire_profile_index(profile) if profile.person? |
24 | 24 | ||
25 | profile.blocks.each do |block| | 25 | profile.blocks.each do |block| |
26 | - expire_timeout_fragment(block.cache_keys) | 26 | + expire_timeout_fragment(block.cache_key) |
27 | end | 27 | end |
28 | + | ||
29 | + expire_blogs(profile) if profile.organization? | ||
28 | end | 30 | end |
29 | 31 | ||
30 | def expire_statistics_block_cache(profile) | 32 | def expire_statistics_block_cache(profile) |
31 | blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } | 33 | blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } |
32 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 34 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
33 | end | 35 | end |
36 | + | ||
37 | + def expire_blogs(profile) | ||
38 | + profile.blogs.select{|b| !b.empty?}.each do |blog| | ||
39 | + pages = blog.posts.count / blog.posts_per_page + 1 | ||
40 | + ([nil] + (1..pages).to_a).each do |i| | ||
41 | + expire_timeout_fragment(blog.cache_key({:npage => i})) | ||
42 | + expire_timeout_fragment(blog.cache_key({:npage => i}, profile)) | ||
43 | + end | ||
44 | + end | ||
45 | + end | ||
46 | + | ||
34 | end | 47 | end |
app/sweepers/role_assignment_sweeper.rb
@@ -25,7 +25,7 @@ protected | @@ -25,7 +25,7 @@ protected | ||
25 | 25 | ||
26 | profile.blocks_to_expire_cache.each { |block| | 26 | profile.blocks_to_expire_cache.each { |block| |
27 | blocks = profile.blocks.select{|b| b.kind_of?(block)} | 27 | blocks = profile.blocks.select{|b| b.kind_of?(block)} |
28 | - blocks.map(&:cache_keys).each{|ck|expire_timeout_fragment(ck)} | 28 | + blocks.map(&:cache_key).each{|ck|expire_timeout_fragment(ck)} |
29 | } | 29 | } |
30 | end | 30 | end |
31 | 31 |
app/views/account/_signup_form.rhtml
@@ -7,8 +7,7 @@ | @@ -7,8 +7,7 @@ | ||
7 | </div> | 7 | </div> |
8 | <% end %> | 8 | <% end %> |
9 | 9 | ||
10 | -<% labelled_form_for :user, @user do |f| %> | ||
11 | -<%= icaptcha_field() %> | 10 | +<% labelled_form_for :user, @user, :html => { :multipart => true } do |f| %> |
12 | 11 | ||
13 | <%= hidden_field_tag :invitation_code, @invitation_code %> | 12 | <%= hidden_field_tag :invitation_code, @invitation_code %> |
14 | 13 |
app/views/account/login.rhtml
@@ -5,9 +5,11 @@ | @@ -5,9 +5,11 @@ | ||
5 | <% @user ||= User.new %> | 5 | <% @user ||= User.new %> |
6 | <% is_thickbox ||= false %> | 6 | <% is_thickbox ||= false %> |
7 | 7 | ||
8 | +<%= @message %> | ||
9 | + | ||
8 | <% labelled_form_for :user, @user, :url => login_url do |f| %> | 10 | <% labelled_form_for :user, @user, :url => login_url do |f| %> |
9 | 11 | ||
10 | - <%= f.text_field :login, :id => 'main_user_login', :onchange => 'this.value = convToValidLogin( this.value )' %> | 12 | + <%= f.text_field :login, :id => 'main_user_login', :onchange => 'this.value = convToValidLogin( this.value )', :value => params[:userlogin] %> |
11 | 13 | ||
12 | <%= f.password_field :password %> | 14 | <%= f.password_field :password %> |
13 | 15 |
app/views/account/signup.rhtml
1 | <h1><%= _('Signup') %></h1> | 1 | <h1><%= _('Signup') %></h1> |
2 | -<%= render :partial => 'signup_form' %> | 2 | +<% if @register_pending %> |
3 | + <%= _('Thanks for signing up! Now check your e-mail to activate your account!') %> | ||
4 | + <p style="text-align: center"><%= link_to(_('Go to the homepage'), '/') %></p> | ||
5 | +<% else %> | ||
6 | + <%= render :partial => 'signup_form' %> | ||
7 | +<% end %> |
app/views/admin_panel/edit_templates.rhtml
1 | <h1><%= _('Edit Templates') %></h1> | 1 | <h1><%= _('Edit Templates') %></h1> |
2 | 2 | ||
3 | <ul> | 3 | <ul> |
4 | -<li><%= link_to _('Edit Person Template'), :controller => 'profile_editor', :profile => environment.person_template.identifier %></li> | ||
5 | -<li><%= link_to _('Edit Community Template'), :controller => 'profile_editor', :profile => environment.community_template.identifier %></li> | ||
6 | -<li><%= link_to __('Edit Enterprise Template'), :controller => 'profile_editor', :profile => environment.enterprise_template.identifier %></li> | 4 | +<% [[_('Edit Person Template'), environment.person_template], |
5 | + [_('Edit Community Template'), environment.community_template], | ||
6 | + [__('Edit Enterprise Template'), environment.enterprise_template], | ||
7 | + [__('Edit Inactive Enterprise Template'), environment.inactive_enterprise_template]].select{|i| i[1]}.each do |row| %> | ||
8 | +<li><%= link_to row[0], :controller => 'profile_editor', :profile => row[1].identifier %></li> | ||
9 | +<% end %> | ||
7 | </ul> | 10 | </ul> |
app/views/admin_panel/index.rhtml
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | <p><%= _('You, as an environment administrator, has the following options:')%></p> | 3 | <p><%= _('You, as an environment administrator, has the following options:')%></p> |
4 | 4 | ||
5 | <table> | 5 | <table> |
6 | - <tr><td><%= link_to _('Edit site info'), :action => 'site_info' %></td></tr> | 6 | + <tr><td><%= link_to _('Edit environment settings'), :action => 'site_info' %></td></tr> |
7 | <tr><td><%= link_to __('Edit message for disabled enterprises'), :action => 'message_for_disabled_enterprise' %></td></tr> | 7 | <tr><td><%= link_to __('Edit message for disabled enterprises'), :action => 'message_for_disabled_enterprise' %></td></tr> |
8 | <tr><td><%= link_to _('Enable/disable features'), :controller => 'features' %></td></tr> | 8 | <tr><td><%= link_to _('Enable/disable features'), :controller => 'features' %></td></tr> |
9 | <tr><td><%= link_to _('Enable/disable plugins'), :controller => 'plugins' %></td></tr> | 9 | <tr><td><%= link_to _('Enable/disable plugins'), :controller => 'plugins' %></td></tr> |
@@ -16,4 +16,7 @@ | @@ -16,4 +16,7 @@ | ||
16 | <tr><td><%= link_to _('Manage Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr> | 16 | <tr><td><%= link_to _('Manage Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr> |
17 | <tr><td><%= link_to _('Set Portal'), :action => 'set_portal_community' %></td></tr> | 17 | <tr><td><%= link_to _('Set Portal'), :action => 'set_portal_community' %></td></tr> |
18 | <tr><td><%= link_to _('Terms of use'), :action => 'terms_of_use' %></td></tr> | 18 | <tr><td><%= link_to _('Terms of use'), :action => 'terms_of_use' %></td></tr> |
19 | + <% @plugins.map(:admin_panel_links).each do |link| %> | ||
20 | + <tr><td><%= link_to link[:title], link[:url] %></td></tr> | ||
21 | + <% end %> | ||
19 | </table> | 22 | </table> |
app/views/admin_panel/site_info.rhtml
1 | -<h2><%= _('Site info') %></h2> | 1 | +<h2><%= _('Environment settings') %></h2> |
2 | 2 | ||
3 | -<%= render :file => 'shared/tiny_mce' %> | ||
4 | - | ||
5 | -<% labelled_form_for :environment, @environment do |f| %> | 3 | +<%= error_messages_for :environment %> |
6 | 4 | ||
7 | - <%= labelled_form_field(_('Site name'), text_field(:environment, :name)) %> | 5 | +<%= render :file => 'shared/tiny_mce' %> |
8 | 6 | ||
7 | +<% labelled_form_for :environment, @environment, :url => {:host => @environment.default_hostname} do |f| %> | ||
8 | + <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %> | ||
9 | + <%= required f.text_field(:reports_lower_bound, :size => 3) %> | ||
9 | <%= labelled_form_field _('Homepage content'), text_area(:environment, :description, :cols => 40, :style => 'width: 90%', :class => 'mceEditor') %> | 10 | <%= labelled_form_field _('Homepage content'), text_area(:environment, :description, :cols => 40, :style => 'width: 90%', :class => 'mceEditor') %> |
10 | 11 | ||
11 | <% button_bar do %> | 12 | <% button_bar do %> |
12 | - <%= submit_button(:save, _('Save')) %> | ||
13 | - <%= button(:cancel, _('Cancel'), :action => 'index') %> | 13 | + <%= submit_button(:save, _('Save'), :cancel => {:action => 'index'}) %> |
14 | <% end %> | 14 | <% end %> |
15 | - | ||
16 | <% end %> | 15 | <% end %> |
app/views/blocks/my_network.rhtml
@@ -6,7 +6,7 @@ | @@ -6,7 +6,7 @@ | ||
6 | <li><%= link_to(__('Homepage'), owner.url, :class => 'url') %></li> | 6 | <li><%= link_to(__('Homepage'), owner.url, :class => 'url') %></li> |
7 | <li><%= link_to(_('View profile'), owner.public_profile_url) %></li> | 7 | <li><%= link_to(_('View profile'), owner.public_profile_url) %></li> |
8 | <% if !user.nil? and owner.organization? and user.has_permission?('edit_profile', profile) %> | 8 | <% if !user.nil? and owner.organization? and user.has_permission?('edit_profile', profile) %> |
9 | - <li><%= link_to _('Control panel'), :controller => 'profile_editor' %></li> | 9 | + <li><%= link_to _('Control panel'), :controller => 'profile_editor', :profile => profile.identifier %></li> |
10 | <% end %> | 10 | <% end %> |
11 | </ul> | 11 | </ul> |
12 | 12 |
app/views/blocks/profile_image.rhtml
@@ -20,5 +20,5 @@ | @@ -20,5 +20,5 @@ | ||
20 | 20 | ||
21 | </div><!-- end class="vcard" --> | 21 | </div><!-- end class="vcard" --> |
22 | <script type="text/javascript"> | 22 | <script type="text/javascript"> |
23 | - <%= remote_function :url => { :controller => 'profile', :action => 'profile_info', :block_id => block.id } %> | 23 | + <%= remote_function :url => { :controller => 'profile', :profile => profile.identifier, :action => 'profile_info', :block_id => block.id } %> |
24 | </script> | 24 | </script> |
app/views/blocks/profile_info.rhtml
@@ -41,5 +41,5 @@ | @@ -41,5 +41,5 @@ | ||
41 | 41 | ||
42 | </div><!-- end class="vcard" --> | 42 | </div><!-- end class="vcard" --> |
43 | <script type="text/javascript"> | 43 | <script type="text/javascript"> |
44 | - <%= remote_function :url => { :controller => 'profile', :action => 'profile_info', :block_id => block.id } %> | 44 | + <%= remote_function :url => { :controller => 'profile', :profile => profile.identifier, :action => 'profile_info', :block_id => block.id } %> |
45 | </script> | 45 | </script> |
app/views/blocks/profile_info_actions/community.rhtml
1 | <ul> | 1 | <ul> |
2 | <% if logged_in? %> | 2 | <% if logged_in? %> |
3 | - | ||
4 | <% if profile.members.include?(user) %> | 3 | <% if profile.members.include?(user) %> |
5 | <li> | 4 | <li> |
6 | - <%= button(:delete, content_tag('span', __('Leave')), profile.leave_url, :class => 'leave-community', :title => _("Leave community"), :style => 'position: relative;') %> | ||
7 | - <%= button(:add, content_tag('span', __('Join')), profile.join_url, :class => 'join-community', :title => _("Join community"), :style => 'position: relative; display: none;') %> | 5 | + <%= button(:delete, content_tag('span', __('Leave')), profile.leave_url, |
6 | + :class => 'leave-community', | ||
7 | + :title => _("Leave community"), | ||
8 | + :style => 'position: relative;') %> | ||
9 | + <%= button(:add, content_tag('span', __('Join')), profile.join_url, | ||
10 | + :class => 'join-community', | ||
11 | + :title => _("Join community"), | ||
12 | + :style => 'position: relative; display: none;') %> | ||
8 | </li> | 13 | </li> |
9 | <% else %> | 14 | <% else %> |
10 | <% unless profile.already_request_membership?(user) %> | 15 | <% unless profile.already_request_membership?(user) %> |
11 | <li> | 16 | <li> |
12 | - <%= button(:delete, content_tag('span', __('Leave')), profile.leave_url, :class => 'leave-community', :title => _("Leave community"), :style => 'position: relative; display: none;') %> | ||
13 | - <%= button(:add, content_tag('span', __('Join')), profile.join_url, :class => 'join-community', :title => _("Join community"), :style => 'position: relative;') %> | 17 | + <%= button(:delete, content_tag('span', __('Leave')), profile.leave_url, |
18 | + :class => 'leave-community', | ||
19 | + :title => _("Leave community"), | ||
20 | + :style => 'position: relative; display: none;') %> | ||
21 | + <%= button(:add, content_tag('span', __('Join')), profile.join_url, | ||
22 | + :class => 'join-community', | ||
23 | + :title => _("Join community"), | ||
24 | + :style => 'position: relative;') %> | ||
14 | </li> | 25 | </li> |
15 | <% end %> | 26 | <% end %> |
16 | <% end %> | 27 | <% end %> |
28 | + | ||
17 | <% if profile.enable_contact? %> | 29 | <% if profile.enable_contact? %> |
18 | <li> | 30 | <li> |
19 | - <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> | 31 | + <%= link_to content_tag('span', _('Send an e-mail')), |
32 | + { :profile => profile.identifier, | ||
33 | + :controller => 'contact', | ||
34 | + :action => 'new' }, | ||
35 | + :class => 'button with-text icon-menu-mail' %> | ||
20 | </li> | 36 | </li> |
21 | <% end %> | 37 | <% end %> |
22 | - <%= render_environment_features(:profile_actions) %> | ||
23 | 38 | ||
24 | - <% else %> | 39 | + <li><%= report_abuse(profile, :button) %></li> |
25 | 40 | ||
41 | + <%= render_environment_features(:profile_actions) %> | ||
42 | + <% else %> | ||
26 | <li> | 43 | <li> |
27 | - <%= link_to content_tag('span', _('Join')), profile.join_not_logged_url, :class => 'button with-text icon-add', :title => _('Join this community') %> | 44 | + <%= link_to content_tag('span', _('Join')), profile.join_not_logged_url, |
45 | + :class => 'button with-text icon-add', | ||
46 | + :title => _('Join this community') %> | ||
28 | </li> | 47 | </li> |
29 | - | ||
30 | <% end %> | 48 | <% end %> |
31 | </ul> | 49 | </ul> |
app/views/blocks/profile_info_actions/enterprise.rhtml
@@ -7,4 +7,6 @@ | @@ -7,4 +7,6 @@ | ||
7 | <% if profile.enable_contact? %> | 7 | <% if profile.enable_contact? %> |
8 | <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button', :class => 'button with-text icon-menu-mail'} %> </li> | 8 | <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button', :class => 'button with-text icon-menu-mail'} %> </li> |
9 | <% end %> | 9 | <% end %> |
10 | + | ||
11 | + <li><%= report_abuse(profile, :button) %></li> | ||
10 | </ul> | 12 | </ul> |
app/views/blocks/profile_info_actions/person.rhtml
@@ -11,5 +11,6 @@ | @@ -11,5 +11,6 @@ | ||
11 | <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> </li> | 11 | <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> </li> |
12 | <% end %> | 12 | <% end %> |
13 | 13 | ||
14 | + <li><%= report_abuse(profile, :button) %></li> | ||
14 | <% end %> | 15 | <% end %> |
15 | </ul> | 16 | </ul> |
app/views/box_organizer/_article_block.rhtml
@@ -5,6 +5,6 @@ | @@ -5,6 +5,6 @@ | ||
5 | </p> | 5 | </p> |
6 | <% else %> | 6 | <% else %> |
7 | <% articles = @block.available_articles.select {|article| !article.folder? } %> | 7 | <% articles = @block.available_articles.select {|article| !article.folder? } %> |
8 | - <%= select_tag('block[article_id]', options_for_select_with_title(articles.map {|item| [item.path, item.id]})) %> | 8 | + <%= select_tag('block[article_id]', options_for_select_with_title(articles.map {|item| [item.path, item.id]}, @block.article ? @block.article.id : nil)) %> |
9 | <% end %> | 9 | <% end %> |
10 | </div> | 10 | </div> |
app/views/box_organizer/edit.rhtml
@@ -14,6 +14,9 @@ | @@ -14,6 +14,9 @@ | ||
14 | <%= radio_button(:block, :display, 'home_page_only') %> | 14 | <%= radio_button(:block, :display, 'home_page_only') %> |
15 | <%= label_tag('block_display_home_page_only', _('Only in the homepage')) %> | 15 | <%= label_tag('block_display_home_page_only', _('Only in the homepage')) %> |
16 | <br/> | 16 | <br/> |
17 | + <%= radio_button(:block, :display, 'except_home_page') %> | ||
18 | + <%= label_tag('block_display_except_home_page', _('In all pages, except in the homepage')) %> | ||
19 | + <br/> | ||
17 | <%= radio_button(:block, :display, 'never') %> | 20 | <%= radio_button(:block, :display, 'never') %> |
18 | <%= label_tag('block_display_never', _("Don't display")) %> | 21 | <%= label_tag('block_display_never', _("Don't display")) %> |
19 | </div> | 22 | </div> |
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +<li class="<%= 'browse-results-type-content ' + icon_for_article(result) %>"> | ||
2 | + <strong><%= link_to(result.title, result.view_url) %></strong> | ||
3 | + <div class="item_meta"> | ||
4 | + <span class="item_by"> | ||
5 | + <%= _('by %s') % link_to(result.author.name, result.author.url) %> | ||
6 | + </span> | ||
7 | + <span class="extra-info"> | ||
8 | + <%= (@filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label')) %> | ||
9 | + </span> | ||
10 | + </div> | ||
11 | +</li> |
app/views/browse/_display_results.rhtml
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | <% end %> | 8 | <% end %> |
9 | <ul class='common-profile-list-block'> | 9 | <ul class='common-profile-list-block'> |
10 | <% @results.each do |result| %> | 10 | <% @results.each do |result| %> |
11 | - <%= render :partial => partial_for_class(result.class), :locals => {:profile => result} %> | 11 | + <%= render :partial => partial_for_class(result.class), :locals => {:result => result} %> |
12 | <% end %> | 12 | <% end %> |
13 | </ul> | 13 | </ul> |
14 | <br style='clear: both;'> | 14 | <br style='clear: both;'> |
app/views/browse/_person.rhtml
1 | -<%= profile_image_link profile, :portrait, 'li', | ||
2 | - "<span class='adr'>#{profile.city}</span>" + | ||
3 | - (@filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label')) %> | 1 | +<%= profile_image_link result, :portrait, 'li', |
2 | + "<span class='adr'>#{result.city}</span>" + | ||
3 | + (@filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label')) %> |
app/views/browse/_profile.rhtml
1 | -<%= profile_image_link profile, :portrait, 'li', @filter == 'more_recent' ? profile.send(@filter + '_label') + show_date(profile.created_at) : profile.send(@filter + '_label') %> | 1 | +<%= profile_image_link result, :portrait, 'li', @filter == 'more_recent' ? result.send(@filter + '_label') + show_date(result.created_at) : result.send(@filter + '_label') %> |
app/views/categories/_category.rhtml
@@ -2,12 +2,12 @@ | @@ -2,12 +2,12 @@ | ||
2 | <div class='treeitem'> | 2 | <div class='treeitem'> |
3 | <%= display_color_for_category(category) %> | 3 | <%= display_color_for_category(category) %> |
4 | <%= category.name %> | 4 | <%= category.name %> |
5 | - <div class='button' id="show_button_<%= category.id %>"> | ||
6 | - <%= link_to_function(_('Show'), "['category_#{category.id}','hide_button_#{category.id}'].each(Element.show); Element.hide('show_button_#{category.id}');") unless category.children.empty? %> | ||
7 | - </div> | ||
8 | - <div class='button' id="hide_button_<%= category.id %>" style='display:none;'> | ||
9 | - <%= link_to_function(_('Hide'), "['category_#{category.id}','hide_button_#{category.id}'].each(Element.hide); Element.show('show_button_#{category.id}') ") %> | ||
10 | - </div> | 5 | + <% if category.children.count > 0 %> |
6 | + <div class='button' id="category-loading-<%= category.id %>" style="position: relative;"> | ||
7 | + <a href="#" id="show-button-<%= category.id %>" class="show-button" onclick="return false;" data-category="<%= category.id %>"><%= _('Show') %></a> | ||
8 | + </div> | ||
9 | + <a href="#" id="hide-button-<%= category.id %>" class="hide-button" onclick="return false;" data-category="<%= category.id %>" style="display: none;"><%= _('Hide') %></a> | ||
10 | + <% end %> | ||
11 | 11 | ||
12 | <div> | 12 | <div> |
13 | <%= link_to _('Add subcategory'), :action => 'new', :parent_id => category %> | 13 | <%= link_to _('Add subcategory'), :action => 'new', :parent_id => category %> |
@@ -16,12 +16,6 @@ | @@ -16,12 +16,6 @@ | ||
16 | </div> | 16 | </div> |
17 | </div> | 17 | </div> |
18 | 18 | ||
19 | - <div id="category_<%= category.id %>" style='display:none;'> | ||
20 | - <% unless category.children.empty? %> | ||
21 | - <ul class='tree'> | ||
22 | - <%= render :partial => 'category', :collection => category.children %> | ||
23 | - </ul> | ||
24 | - <% end %> | ||
25 | - </div> | 19 | +<ul id="category-sub-items-<%= category.id %>" class="tree" style='display:none;'></ul> |
26 | 20 | ||
27 | </li> | 21 | </li> |
app/views/categories/index.rhtml
app/views/cms/_blog.rhtml
@@ -50,7 +50,7 @@ | @@ -50,7 +50,7 @@ | ||
50 | %> | 50 | %> |
51 | </div> | 51 | </div> |
52 | 52 | ||
53 | -<%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %> | 53 | +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 10)) %> |
54 | 54 | ||
55 | <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ [ _('Full post'), 'full'], [ _('First paragraph'), 'short'] ])) %> | 55 | <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ [ _('Full post'), 'full'], [ _('First paragraph'), 'short'] ])) %> |
56 | 56 |
app/views/cms/_document_link.rhtml
@@ -1,10 +0,0 @@ | @@ -1,10 +0,0 @@ | ||
1 | -<div id='media-listing-folder-documents' > | ||
2 | - <ul> | ||
3 | - <% documents.each do |document| %> | ||
4 | - <li><%= link_to(document.name, document.view_url, :class => icon_for_article(document)) %></li> | ||
5 | - <% end %> | ||
6 | - </ul> | ||
7 | - <div id='pagination-documents'> | ||
8 | - <%= pagination_links documents, :param_name => 'dpage', :params => {:document_folder_id => params[:document_folder_id]} %> | ||
9 | - </div> | ||
10 | -</div> |
app/views/cms/_image_thumb.rhtml
@@ -1,10 +0,0 @@ | @@ -1,10 +0,0 @@ | ||
1 | -<div id='media-listing-folder-images' > | ||
2 | - <ul> | ||
3 | - <% images.each do |image| %> | ||
4 | - <li><%= image_tag image.public_filename %></li> | ||
5 | - <% end %> | ||
6 | - </ul> | ||
7 | - <div id='pagination-images'> | ||
8 | - <%= pagination_links images, :param_name => 'ipage', :params => {:image_folder_id => params[:image_folder_id]} %> | ||
9 | - </div> | ||
10 | -</div> |
app/views/cms/_media_listing.rhtml