Commit eec782d088727df57ad97a60de8992a9c5700add

Authored by Joenio Costa
2 parents 2247304b 05d99f0e

Merge branch 'master' into AI2915-category_color

Showing 137 changed files with 7339 additions and 5846 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 137 files displayed.

AUTHORS
... ... @@ -170,6 +170,7 @@ João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
170 170 Joenio Costa <joenio@colivre.coop.br>
171 171 Josef Spillner <josef.spillner@tu-dresden.de>
172 172 Junior Silva <junior@bajor.localhost.localdomain>
  173 +Junior Silva <junior@sedeantigo.colivre.coop.br>
173 174 Junior Silva <juniorsilva1001@gmail.com>
174 175 Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)>
175 176 Junior Silva <juniorsilva@colivre.coop.br>
... ...
Gemfile
... ... @@ -16,6 +16,7 @@ gem &#39;hpricot&#39;
16 16 gem 'nokogiri'
17 17 gem 'rake', :require => false
18 18 gem 'rest-client'
  19 +gem 'exception_notification'
19 20  
20 21 # FIXME list here all actual dependencies (i.e. the ones in debian/control),
21 22 # with their GEM names (not the Debian package names)
... ... @@ -31,7 +32,6 @@ group :test do
31 32 end
32 33  
33 34 group :cucumber do
34   - gem 'rake'
35 35 gem 'cucumber-rails', :require => false
36 36 gem 'capybara'
37 37 gem 'cucumber'
... ...
Gemfile.lock
... ... @@ -61,7 +61,10 @@ GEM
61 61 database_cleaner (1.2.0)
62 62 diff-lcs (1.1.3)
63 63 erubis (2.7.0)
64   - eventmachine (0.12.11)
  64 + eventmachine (0.12.10)
  65 + exception_notification (4.0.1)
  66 + actionmailer (>= 3.0.4)
  67 + activesupport (>= 3.0.4)
65 68 fast_gettext (0.6.8)
66 69 ffi (1.0.11)
67 70 gherkin (2.4.21)
... ... @@ -167,6 +170,7 @@ DEPENDENCIES
167 170 daemons
168 171 dalli
169 172 database_cleaner
  173 + exception_notification
170 174 fast_gettext
171 175 hpricot
172 176 mocha
... ...
Rakefile
1 1 #!/usr/bin/env rake
  2 +
2 3 # Add your own tasks in files placed in lib/tasks ending in .rake,
3 4 # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4 5  
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -143,6 +143,7 @@ class CmsController &lt; MyProfileController
143 143 end
144 144  
145 145 @article.profile = profile
  146 + @article.author = user
146 147 @article.last_changed_by = user
147 148 @article.created_by = user
148 149  
... ... @@ -195,7 +196,7 @@ class CmsController &lt; MyProfileController
195 196 :profile => profile,
196 197 :parent => @parent,
197 198 :last_changed_by => user,
198   - :created_by => user,
  199 + :author => user,
199 200 },
200 201 :without_protection => true
201 202 )
... ...
app/controllers/public/account_controller.rb
... ... @@ -2,7 +2,7 @@ class AccountController &lt; ApplicationController
2 2  
3 3 no_design_blocks
4 4  
5   - before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise]
  5 + before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise, :change_password]
6 6 before_filter :redirect_if_logged_in, :only => [:login, :signup]
7 7 before_filter :protect_from_bots, :only => :signup
8 8  
... ...
app/controllers/public/catalog_controller.rb
... ... @@ -11,7 +11,7 @@ class CatalogController &lt; PublicController
11 11 protected
12 12  
13 13 def check_enterprise_and_environment
14   - unless profile.kind_of?(Enterprise) && @profile.environment.enabled?('products_for_enterprises')
  14 + unless profile.enterprise? && @profile.environment.enabled?('products_for_enterprises')
15 15 redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index'
16 16 end
17 17 end
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -74,7 +74,7 @@ class ContentViewerController &lt; ApplicationController
74 74 end
75 75  
76 76 def versions_diff
77   - path = params[:page].join('/')
  77 + path = params[:page]
78 78 @page = profile.articles.find_by_path(path)
79 79 @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2])
80 80 end
... ... @@ -216,6 +216,8 @@ class ContentViewerController &lt; ApplicationController
216 216 if @page.has_posts?
217 217 posts = get_posts(params[:year], params[:month])
218 218  
  219 + posts = posts.includes(:parent, {:profile => [:domains, :environment]}, :author)
  220 +
219 221 #FIXME Need to run this before the pagination because this version of
220 222 # will_paginate returns a will_paginate collection instead of a
221 223 # relation.
... ...
app/helpers/application_helper.rb
... ... @@ -312,13 +312,13 @@ module ApplicationHelper
312 312 raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?'
313 313 end
314 314  
315   - def view_for_profile_actions(klass)
316   - raise ArgumentError, 'No profile actions view for this class.' if klass.nil?
317   -
318   - name = klass.name.underscore
319   - return "blocks/profile_info_actions/" + name + '.html.erb' if File.exists?(Rails.root.join('app', 'views', 'blocks', 'profile_info_actions', name + '.html.erb'))
320   -
321   - view_for_profile_actions(klass.superclass)
  315 + def render_profile_actions klass
  316 + name = klass.to_s.underscore
  317 + begin
  318 + render "blocks/profile_info_actions/#{name}"
  319 + rescue ActionView::MissingTemplate
  320 + render_profile_actions klass.superclass
  321 + end
322 322 end
323 323  
324 324 def user
... ... @@ -1095,7 +1095,7 @@ module ApplicationHelper
1095 1095 result
1096 1096 end
1097 1097  
1098   - def manage_link(list, kind)
  1098 + def manage_link(list, kind, title)
1099 1099 if list.present?
1100 1100 link_to_all = nil
1101 1101 if list.count > 5
... ... @@ -1108,19 +1108,19 @@ module ApplicationHelper
1108 1108 if link_to_all
1109 1109 link << link_to_all
1110 1110 end
1111   - render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s}
  1111 + render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s, :title => title}
1112 1112 end
1113 1113 end
1114 1114  
1115 1115 def manage_enterprises
1116 1116 return '' unless user && user.environment.enabled?(:display_my_enterprises_on_user_menu)
1117   - manage_link(user.enterprises, :enterprises).to_s
  1117 + manage_link(user.enterprises, :enterprises, _('My enterprises')).to_s
1118 1118 end
1119 1119  
1120 1120 def manage_communities
1121 1121 return '' unless user && user.environment.enabled?(:display_my_communities_on_user_menu)
1122 1122 administered_communities = user.communities.more_popular.select {|c| c.admins.include? user}
1123   - manage_link(administered_communities, :communities).to_s
  1123 + manage_link(administered_communities, :communities, _('My communities')).to_s
1124 1124 end
1125 1125  
1126 1126 def admin_link
... ... @@ -1225,20 +1225,7 @@ module ApplicationHelper
1225 1225 def add_zoom_to_images
1226 1226 stylesheet_link_tag('jquery.fancybox') +
1227 1227 javascript_include_tag('jquery.fancybox.pack') +
1228   - javascript_tag("jQuery(function($) {
1229   - $(window).load( function() {
1230   - $('#article .article-body img').each( function(index) {
1231   - var original = original_image_dimensions($(this).attr('src'));
1232   - if ($(this).width() < original['width'] || $(this).height() < original['height']) {
1233   - $(this).wrap('<div class=\"zoomable-image\" />');
1234   - $(this).parent('.zoomable-image').attr('style', $(this).attr('style'));
1235   - $(this).attr('style', '');
1236   - $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>');
1237   - }
1238   - });
1239   - $('.zoomify-image').fancybox();
1240   - });
1241   - });" % _('Zoom in'))
  1228 + javascript_tag("apply_zoom_to_images(#{_('Zoom in').to_json})")
1242 1229 end
1243 1230  
1244 1231 def render_dialog_error_messages(instance_name)
... ... @@ -1373,7 +1360,7 @@ module ApplicationHelper
1373 1360 @message = _("The content here is available to %s's friends only.") % profile.short_name
1374 1361 else
1375 1362 @action = :join
1376   - @message = _('The contents in this community is available to members only.')
  1363 + @message = _('The contents in this profile is available to members only.')
1377 1364 end
1378 1365 @no_design_blocks = true
1379 1366 end
... ...
app/helpers/block_helper.rb
... ... @@ -6,19 +6,20 @@ module BlockHelper
6 6 content_tag 'h3', content_tag('span', h(title)), :class => tag_class
7 7 end
8 8  
9   - def highlights_block_config_image_fields(block, image={})
  9 + def highlights_block_config_image_fields(block, image={}, row_number=nil)
10 10 "
11   - <tr class=\"image-data-line\">
  11 + <tr class=\"image-data-line\" data-row-number='#{row_number}'>
12 12 <td>
13 13 #{select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe}
14 14 </td>
15 15 <td>#{text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 20}</td>
16 16 <td>#{text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 1}</td>
17   - </tr><tr class=\"image-title\">
  17 + </tr><tr class=\"image-title\" data-row-number='#{row_number}'>
18 18 <td colspan=\"3\"><label>#{
19 19 content_tag('span', _('Title')) +
20 20 text_field_tag('block[images][][title]', image[:title], :class => 'highlight-title', :size => 45)
21 21 }</label></td>
  22 + <td>#{link_to '', '#', :class=>'button icon-button icon-delete delete-highlight', :confirm=>_('Are you sure you want to remove this highlight')}</td>
22 23 </tr>
23 24 "
24 25 end
... ...
app/helpers/blog_helper.rb
... ... @@ -45,9 +45,9 @@ module BlogHelper
45 45  
46 46 def display_post(article, format = 'full')
47 47 no_comments = (format == 'full') ? false : true
  48 + title = article_title(article, :no_comments => no_comments)
48 49 html = send("display_#{format}_format", FilePresenter.for(article)).html_safe
49   -
50   - article_title(article, :no_comments => no_comments) + html
  50 + title + html
51 51 end
52 52  
53 53 def display_full_format(article)
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -10,7 +10,7 @@ module ContentViewerHelper
10 10 end
11 11  
12 12 def number_of_comments(article)
13   - display_number_of_comments(article.comments.without_spam.count)
  13 + display_number_of_comments(article.comments_count - article.spam_comments_count)
14 14 end
15 15  
16 16 def article_title(article, args = {})
... ... @@ -26,7 +26,7 @@ module ContentViewerHelper
26 26 end
27 27 title << content_tag('span',
28 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') +
  29 + content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
30 30 content_tag('span', comments, :class => 'comments'),
31 31 :class => 'created-at'
32 32 )
... ...
app/helpers/folder_helper.rb
... ... @@ -5,15 +5,17 @@ module FolderHelper
5 5 include ShortFilename
6 6 include ArticleHelper
7 7  
8   - def list_articles(articles, recursive = false)
9   - if !articles.blank?
10   - articles = articles.paginate(
  8 + def list_contents(configure={})
  9 + configure[:recursive] ||= false
  10 + configure[:list_type] ||= :folder
  11 + if !configure[:contents].blank?
  12 + configure[:contents] = configure[:contents].paginate(
11 13 :order => "updated_at DESC",
12 14 :per_page => 10,
13 15 :page => params[:npage]
14 16 )
15 17  
16   - render :file => 'shared/articles_list', :locals => {:articles => articles, :recursive => recursive}
  18 + render :file => 'shared/content_list', :locals => configure
17 19 else
18 20 content_tag('em', _('(empty folder)'))
19 21 end
... ... @@ -23,21 +25,33 @@ module FolderHelper
23 25 articles.select {|article| article.display_to?(user)}
24 26 end
25 27  
26   - def display_article_in_listing(article, recursive = false, level = 0)
27   - article = FilePresenter.for article
28   - article_link = if article.image?
29   - link_to('&nbsp;' * (level * 4) + image_tag(icon_for_article(article)) + short_filename(article.name), article.url.merge(:view => true))
  28 + def display_content_in_listing(configure={})
  29 + recursive = configure[:recursive] || false
  30 + list_type = configure[:list_type] || :folder
  31 + level = configure[:level] || 0
  32 + content = FilePresenter.for configure[:content]
  33 + content_link = if content.image?
  34 + link_to('&nbsp;' * (level * 4) +
  35 + image_tag(icon_for_article(content)) + short_filename(content.name),
  36 + content.url.merge(:view => true)
  37 + )
30 38 else
31   - link_to('&nbsp;' * (level * 4) + short_filename(article.name), article.url.merge(:view => true), :class => icon_for_article(article))
  39 + link_to('&nbsp;' * (level * 4) +
  40 + short_filename(content.name),
  41 + content.url.merge(:view => true), :class => icon_for_article(content)
  42 + )
32 43 end
33 44 result = content_tag(
34 45 'tr',
35   - content_tag('td', article_link )+
36   - content_tag('td', show_date(article.updated_at), :class => 'last-update'),
37   - :class => 'sitemap-item'
  46 + content_tag('td', content_link ) +
  47 + content_tag('td', show_date(content.updated_at), :class => 'last-update'),
  48 + :class => "#{list_type}-item"
38 49 )
39 50 if recursive
40   - result + article.children.map {|item| display_article_in_listing(item, recursive, level + 1) }.join('')
  51 + result + content.children.map {|item|
  52 + display_content_in_listing :content=>item, :recursive=>recursive,
  53 + :list_type=>list_type, :level=>level+1
  54 + }.join("\n")
41 55 else
42 56 result
43 57 end
... ...
app/models/article.rb
... ... @@ -40,6 +40,12 @@ class Article &lt; ActiveRecord::Base
40 40 # xss_terminate plugin can't sanitize array fields
41 41 before_save :sanitize_tag_list
42 42  
  43 + before_create do |article|
  44 + if article.author
  45 + article.author_name = article.author.name
  46 + end
  47 + end
  48 +
43 49 belongs_to :profile
44 50 validates_presence_of :profile_id, :name
45 51 validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? }
... ... @@ -48,6 +54,7 @@ class Article &lt; ActiveRecord::Base
48 54  
49 55 validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? }
50 56  
  57 + belongs_to :author, :class_name => 'Person'
51 58 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
52 59 belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id'
53 60  
... ... @@ -456,10 +463,10 @@ class Article &lt; ActiveRecord::Base
456 463 ['TextArticle', 'TextileArticle', 'TinyMceArticle']
457 464 end
458 465  
459   - scope :published, :conditions => { :published => true }
460   - scope :folders, lambda {|profile|{:conditions => { :type => profile.folder_types} }}
461   - scope :no_folders, lambda {|profile|{:conditions => ['type NOT IN (?)', profile.folder_types]}}
462   - scope :galleries, :conditions => { :type => 'Gallery' }
  466 + scope :published, :conditions => ['articles.published = ?', true]
  467 + scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }}
  468 + scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}}
  469 + scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ]
463 470 scope :images, :conditions => { :is_image => true }
464 471 scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ]
465 472 scope :with_types, lambda { |types| { :conditions => [ 'articles.type IN (?)', types ] } }
... ... @@ -469,7 +476,7 @@ class Article &lt; ActiveRecord::Base
469 476 scope :more_recent, :order => "created_at DESC"
470 477  
471 478 def self.display_filter(user, profile)
472   - return {:conditions => ['published = ?', true]} if !user
  479 + return {:conditions => ['articles.published = ?', true]} if !user
473 480 {:conditions => [" articles.published = ? OR
474 481 articles.last_changed_by_id = ? OR
475 482 articles.profile_id = ? OR
... ... @@ -496,6 +503,7 @@ class Article &lt; ActiveRecord::Base
496 503 end
497 504  
498 505 def allow_post_content?(user = nil)
  506 + return true if allow_edit_topic?(user)
499 507 user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == author))
500 508 end
501 509  
... ... @@ -515,9 +523,14 @@ class Article &lt; ActiveRecord::Base
515 523 end
516 524  
517 525 def allow_edit?(user)
  526 + return true if allow_edit_topic?(user)
518 527 allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile)
519 528 end
520 529  
  530 + def allow_edit_topic?(user)
  531 + self.belongs_to_forum? && (user == author) && user.present? && user.is_member_of?(profile)
  532 + end
  533 +
521 534 def moderate_comments?
522 535 moderate_comments == true
523 536 end
... ... @@ -632,35 +645,36 @@ class Article &lt; ActiveRecord::Base
632 645 can_display_versions? && display_versions
633 646 end
634 647  
635   - def author(version_number = nil)
636   - if version_number
637   - version = self.versions.find_by_version(version_number)
638   - author_id = version.last_changed_by_id if version
639   - else
640   - author_id = self.created_by_id
641   - end
  648 + def get_version(version_number = nil)
  649 + version_number ? versions.find(:first, :order => 'version', :offset => version_number - 1) : versions.earliest
  650 + end
642 651  
643   - environment.people.find_by_id(author_id)
  652 + def author_by_version(version_number = nil)
  653 + version_number ? profile.environment.people.find_by_id(get_version(version_number).author_id) : author
644 654 end
645 655  
646 656 def author_name(version_number = nil)
647   - person = author(version_number)
648   - person ? person.name : (setting[:author_name] || _('Unknown'))
  657 + person = author_by_version(version_number)
  658 + if version_number
  659 + person ? person.name : _('Unknown')
  660 + else
  661 + person ? person.name : (setting[:author_name] || _('Unknown'))
  662 + end
649 663 end
650 664  
651 665 def author_url(version_number = nil)
652   - person = author(version_number)
  666 + person = author_by_version(version_number)
653 667 person ? person.url : nil
654 668 end
655 669  
656 670 def author_id(version_number = nil)
657   - person = author(version_number)
  671 + person = author_by_version(version_number)
658 672 person ? person.id : nil
659 673 end
660 674  
661 675 def version_license(version_number = nil)
662 676 return license if version_number.nil?
663   - profile.environment.licenses.find_by_id(versions.find_by_version(version_number).license_id)
  677 + profile.environment.licenses.find_by_id(get_version(version_number).license_id)
664 678 end
665 679  
666 680 alias :active_record_cache_key :cache_key
... ...
app/models/comment.rb
... ... @@ -109,14 +109,17 @@ class Comment &lt; ActiveRecord::Base
109 109 include Noosfero::Plugin::HotSpot
110 110  
111 111 include Spammable
  112 + include CacheCounterHelper
112 113  
113 114 def after_spam!
114 115 SpammerLogger.log(ip_address, self)
115 116 Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam))
  117 + update_cache_counter(:spam_comments_count, source, 1) if source.kind_of?(Article)
116 118 end
117 119  
118 120 def after_ham!
119 121 Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_ham))
  122 + update_cache_counter(:spam_comments_count, source, -1) if source.kind_of?(Article)
120 123 end
121 124  
122 125 def verify_and_notify
... ...
app/models/domain.rb
... ... @@ -2,7 +2,7 @@ require &#39;noosfero/multi_tenancy&#39;
2 2  
3 3 class Domain < ActiveRecord::Base
4 4  
5   - attr_accessible :name, :owner
  5 + attr_accessible :name, :owner, :is_default
6 6  
7 7 # relationships
8 8 ###############
... ...
app/models/enterprise.rb
... ... @@ -25,7 +25,10 @@ class Enterprise &lt; Organization
25 25 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code')
26 26  
27 27 settings_items :organization_website, :historic_and_current_context, :activities_short_description
  28 +
28 29 settings_items :products_per_catalog_page, :type => :integer, :default => 6
  30 + alias_method :products_per_catalog_page_before_type_cast, :products_per_catalog_page
  31 + validates_numericality_of :products_per_catalog_page, :allow_nil => true, :greater_than => 0
29 32  
30 33 extend SetProfileRegionFromCityState::ClassMethods
31 34 set_profile_region_from_city_state
... ...
app/models/featured_products_block.rb
1 1 class FeaturedProductsBlock < Block
2 2  
  3 + attr_accessible :product_ids, :groups_of, :speed, :reflect
  4 +
3 5 settings_items :product_ids, :type => Array, :default => []
4 6 settings_items :groups_of, :type => :integer, :default => 3
5 7 settings_items :speed, :type => :integer, :default => 1000
... ...
app/models/highlights_block.rb
1 1 class HighlightsBlock < Block
2 2  
3   - attr_accessible :images
  3 + attr_accessible :images, :interval, :shuffle, :navigation
4 4  
5 5 settings_items :images, :type => Array, :default => []
6 6 settings_items :interval, :type => 'integer', :default => 4
... ...
app/models/location_block.rb
1 1 class LocationBlock < Block
2 2  
  3 + attr_accessible :zoom, :map_type
  4 +
3 5 settings_items :zoom, :type => :integer, :default => 4
4 6 settings_items :map_type, :type => :string, :default => 'roadmap'
5 7  
... ...
app/models/product_categories_block.rb
... ... @@ -33,7 +33,7 @@ class ProductCategoriesBlock &lt; Block
33 33 end
34 34 end
35 35  
36   - DISPLAY_OPTIONS['catalog_only'] = _('Only on the catalog')
  36 + DISPLAY_OPTIONS = DISPLAY_OPTIONS.merge('catalog_only' => _('Only on the catalog'))
37 37  
38 38 def display
39 39 settings[:display].nil? ? 'catalog_only' : super
... ...
app/models/products_block.rb
... ... @@ -49,17 +49,10 @@ class ProductsBlock &lt; Block
49 49  
50 50 def products(reload = false)
51 51 if product_ids.blank?
52   - products_list = owner.products(reload)
53   - result = []
54   - [4, products_list.size].min.times do
55   - p = products_list.sample
56   - result << p
57   - products_list -= [p]
58   - end
59   - result
  52 + owner.products.order('RANDOM()').limit([4,owner.products.count].min)
60 53 else
61   - product_ids.map {|item| owner.products.find(item) }
62   - end
  54 + owner.products.where(:id => product_ids)
  55 + end.compact
63 56 end
64 57  
65 58 end
... ...
app/models/rss_feed.rb
1 1 class RssFeed < Article
2 2  
3   - attr_accessible :limit, :enabled, :language, :include
  3 + attr_accessible :limit, :enabled, :language, :include, :feed_item_description
4 4  
5 5 def self.type_name
6 6 _('RssFeed')
... ...
app/models/user.rb
... ... @@ -5,7 +5,7 @@ require &#39;user_activation_job&#39;
5 5 # Rails generator.
6 6 class User < ActiveRecord::Base
7 7  
8   - attr_accessible :login, :email, :password, :password_confirmation
  8 + attr_accessible :login, :email, :password, :password_confirmation, :activated_at
9 9  
10 10 N_('Password')
11 11 N_('Password confirmation')
... ...
app/presenters/image.rb
... ... @@ -11,4 +11,9 @@ class FilePresenter::Image &lt; FilePresenter
11 11 def short_description
12 12 _('Image (%s)') % content_type.split('/')[1].upcase
13 13 end
  14 +
  15 + #Overwriting method from FilePresenter to allow download of images
  16 + def download?(view = nil)
  17 + view.blank? || view == 'false'
  18 + end
14 19 end
... ...
app/views/account/_signup_form.html.erb
... ... @@ -136,8 +136,6 @@
136 136 <script type="text/javascript">
137 137 jQuery(function($) {
138 138  
139   - $('#signup-form #user_login').css('width', 335 - $('#signup-domain').outerWidth());
140   -
141 139 $('#signup-form input[type=text], #signup-form textarea').each(function() {
142 140 $(this).bind('blur', function() {
143 141 if ($(this).val() == '') {
... ...
app/views/blocks/my_network.html.erb
1 1 <%= block_title(title) %>
2 2  
3   -<%= render :file => 'blocks/my_network/' + owner.class.name.underscore, :locals => { :owner => owner } %>
  3 +<%= render_profile_actions owner.class %>
4 4  
5 5 <ul>
6 6 <li><%= link_to(_('Homepage'), owner.url, :class => 'url') %></li>
... ... @@ -11,5 +11,5 @@
11 11 </ul>
12 12  
13 13 <div class="my-network-actions">
14   - <%= render :file => 'blocks/profile_info_actions/' + owner.class.name.underscore %>
  14 + <%= render 'blocks/profile_info_actions/' + owner.class.name.underscore %>
15 15 </div>
... ...
app/views/blocks/profile_image.html.erb
... ... @@ -23,6 +23,6 @@
23 23 <% end %>
24 24  
25 25 <div class="profile-info-options">
26   - <%= render :file => view_for_profile_actions(block.owner.class) %>
  26 + <%= render_profile_actions block.owner.class %>
27 27 </div>
28 28 </div><!-- end class="vcard" -->
... ...
app/views/blocks/profile_info.html.erb
... ... @@ -40,7 +40,7 @@
40 40 <% end %>
41 41  
42 42 <div class="profile-info-options">
43   - <%= render :file => view_for_profile_actions(block.owner.class) %>
  43 + <%= render_profile_actions block.owner.class %>
44 44 </div>
45 45  
46 46 </div><!-- end class="vcard" -->
... ...
app/views/blocks/profile_info_actions/_community.html.erb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +<ul>
  2 + <li>
  3 + <%= render "blocks/profile_info_actions/join_leave_community" %>
  4 + </li>
  5 + <% if logged_in? %>
  6 + <% if profile.enable_contact? %>
  7 + <li>
  8 + <%= link_to content_tag('span', _('Send an e-mail')),
  9 + { :profile => profile.identifier,
  10 + :controller => 'contact',
  11 + :action => 'new' },
  12 + {:class => 'button with-text icon-menu-mail', :title => _('Send an e-mail to the administrators')} %>
  13 + </li>
  14 + <% end %>
  15 +
  16 + <li><%= report_abuse(profile, :button) %></li>
  17 +
  18 + <%= render_environment_features(:profile_actions) %>
  19 + <% end %>
  20 +</ul>
... ...
app/views/blocks/profile_info_actions/_enterprise.html.erb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<ul>
  2 + <%if logged_in? %>
  3 + <%if !user.favorite_enterprises.include?(profile) %>
  4 + <li><%= link_to content_tag('span', _('Add as favorite')), { :profile => user.identifier, :controller => 'favorite_enterprises', :action => 'add', :id => profile.id }, :class => 'button with-text icon-add', :title => _('Add enterprise as favorite') %></li>
  5 + <% end %>
  6 + <% end %>
  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>
  9 + <% end %>
  10 +
  11 + <li><%= report_abuse(profile, :button) %></li>
  12 +</ul>
... ...
app/views/blocks/profile_info_actions/_organization.html.erb 0 → 100644
app/views/blocks/profile_info_actions/_person.html.erb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<ul>
  2 + <%if logged_in? && (user != profile) %>
  3 +
  4 + <% if !user.already_request_friendship?(profile) and !user.is_a_friend?(profile) %>
  5 + <li>
  6 + <%= button(:add, content_tag('span', _('Add friend')), profile.add_url, :class => 'add-friend', :title => _("Add friend"), :style => 'position: relative;') %>
  7 + </li>
  8 + <% end %>
  9 +
  10 + <% if user.is_a_friend?(profile) && profile.enable_contact? %>
  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 %>
  13 +
  14 + <li><%= report_abuse(profile, :button) %></li>
  15 + <% end %>
  16 +</ul>
... ...
app/views/blocks/profile_info_actions/community.html.erb
... ... @@ -1,20 +0,0 @@
1   -<ul>
2   - <li>
3   - <%= render "blocks/profile_info_actions/join_leave_community" %>
4   - </li>
5   - <% if logged_in? %>
6   - <% if profile.enable_contact? %>
7   - <li>
8   - <%= link_to content_tag('span', _('Send an e-mail')),
9   - { :profile => profile.identifier,
10   - :controller => 'contact',
11   - :action => 'new' },
12   - {:class => 'button with-text icon-menu-mail', :title => _('Send an e-mail to the administrators')} %>
13   - </li>
14   - <% end %>
15   -
16   - <li><%= report_abuse(profile, :button) %></li>
17   -
18   - <%= render_environment_features(:profile_actions) %>
19   - <% end %>
20   -</ul>
app/views/blocks/profile_info_actions/enterprise.html.erb
... ... @@ -1,12 +0,0 @@
1   -<ul>
2   - <%if logged_in? %>
3   - <%if !user.favorite_enterprises.include?(profile) %>
4   - <li><%= link_to content_tag('span', _('Add as favorite')), { :profile => user.identifier, :controller => 'favorite_enterprises', :action => 'add', :id => profile.id }, :class => 'button with-text icon-add', :title => _('Add enterprise as favorite') %></li>
5   - <% end %>
6   - <% end %>
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>
9   - <% end %>
10   -
11   - <li><%= report_abuse(profile, :button) %></li>
12   -</ul>
app/views/blocks/profile_info_actions/organization.html.erb
app/views/blocks/profile_info_actions/person.html.erb
... ... @@ -1,16 +0,0 @@
1   -<ul>
2   - <%if logged_in? && (user != profile) %>
3   -
4   - <% if !user.already_request_friendship?(profile) and !user.is_a_friend?(profile) %>
5   - <li>
6   - <%= button(:add, content_tag('span', _('Add friend')), profile.add_url, :class => 'add-friend', :title => _("Add friend"), :style => 'position: relative;') %>
7   - </li>
8   - <% end %>
9   -
10   - <% if user.is_a_friend?(profile) && profile.enable_contact? %>
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 %>
13   -
14   - <li><%= report_abuse(profile, :button) %></li>
15   - <% end %>
16   -</ul>
app/views/box_organizer/_highlights_block.html.erb
  1 +<%= javascript_include_tag "highlight_block" %>
  2 +
1 3 <strong><%= _('Highlights') %></strong>
2 4  
3 5 <table class="noborder"><tbody id="highlights-data-table">
4 6 <tr><th><%= _('Image') %></th><th><%= _('Address') %></th><th><%= _('Position') %></th></tr>
5   - <% for image in @block.images do %>
6   - <%= highlights_block_config_image_fields @block, image %>
  7 + <% @block.images.each_with_index do |image, index| %>
  8 + <%= highlights_block_config_image_fields @block, image, index %>
7 9 <% end %>
8 10 </tbody></table>
9 11  
10   -<%= link_to_function(_('New highlight'), nil, :class => 'button icon-add with-text') do |page|
11   - page.insert_html :bottom, 'highlights-data-table', highlights_block_config_image_fields(@block)
12   -end %>
  12 +<table class="hidden highlight-table-row">
  13 + <tbody>
  14 + <%= highlights_block_config_image_fields(@block) %>
  15 + </tbody>
  16 +</table>
  17 +
  18 +<%= link_to(_('New highlight'), '#', :class => 'button icon-add with-text new-highlight-button')%>
13 19  
14 20 <%= labelled_form_field _('Image transition:'), select('block', 'interval', [[_('No automatic transition'), 0]] + [1, 2, 3, 4, 5, 10, 20, 30, 60].map {|item| [n_('Every 1 second', 'Every %d seconds', item) % item, item]}) %>
15 21  
... ...
app/views/comment/_comment_form.html.erb
... ... @@ -31,7 +31,7 @@ function check_captcha(button, confirm_action) {
31 31 return true;
32 32 <% else %>
33 33 jQuery('#recaptcha-container').show();
34   - jQuery.colorbox({ inline : true, href : '#recaptcha-container', maxWidth : '600px', maxHeight : '300px' });
  34 + jQuery.colorbox({ html: jQuery('#recaptcha-container').html(), maxWidth : '600px', maxHeight : '300px' });
35 35 jQuery('#confirm-captcha').unbind('click');
36 36 jQuery('#confirm-captcha').bind('click', function() {
37 37 jQuery.colorbox.close();
... ...
app/views/content_viewer/article_versions.html.erb
1 1 <div class="article-versions">
2   - <%= button(:back, _('Go back to latest version'), {:action => 'view_page'}) %>
  2 + <%= button(:back, _('Go back to latest version'), @page.url) %>
3 3 </div>
4 4  
5 5 <%= article_title(@page, :no_link => true) %>
6 6  
7 7 <p><%= _('This is the list of all versions of this content. Select a version to see it and then revert to it.') %>.</p>
8 8  
9   -<%= form_tag({:controller => 'content_viewer', :action => 'versions_diff', :profile => profile.identifier, :page => @page.path.split('/')}, :method => 'get') do %>
  9 +<%= form_tag({:controller => 'content_viewer', :action => 'versions_diff', :profile => profile.identifier, :page => @page.path}, :method => 'get') do %>
10 10 <ul id="article-versions">
11 11 <% @versions.each do |v| %>
12 12 <li>
... ...
app/views/content_viewer/folder.html.erb
... ... @@ -8,5 +8,5 @@
8 8 <% if folder.children.empty? %>
9 9 <em><%= _('(empty folder)') %></em>
10 10 <% else %>
11   - <%= list_articles(folder.children) %>
  11 + <%= list_contents(:contents=>folder.children) %>
12 12 <% end %>
... ...
app/views/content_viewer/versioned_article.html.erb
... ... @@ -23,7 +23,6 @@
23 23 <p id="no-current-version">
24 24 <%= _('This is not the latest version of this content.') %>
25 25 </p>
26   -</div>
27 26  
28 27 <% version_license = @page.version_license(@version) %>
29 28 <%# This seemingly doubled verification exists because the article-sub-header
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -40,8 +40,6 @@
40 40 </div>
41 41 <% end %>
42 42  
43   -<%= render :partial => 'shared/disabled_enterprise' %>
44   -
45 43 <% if NOOSFERO_CONF['addthis_enabled'] %>
46 44 <%= render :partial => 'addthis' %>
47 45 <% end %>
... ...
app/views/profile/index.html.erb
1   -<%= render :partial => 'shared/disabled_enterprise' %>
2   -
3 1 <h1><%= h profile.name %></h1>
4 2  
5 3 <% if @action %>
... ...
app/views/profile/sitemap.html.erb
1 1 <h1><%= _("%s: site map") % profile.name %></h1>
2 2  
3   -<%= list_articles(available_articles(@articles, user), false) %>
  3 +<%= list_contents :contents=>available_articles(@articles, user), :list_type=>:sitemap %>
... ...
app/views/profile_editor/index.html.erb
... ... @@ -24,7 +24,7 @@
24 24  
25 25 <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'profile_themes', :action => 'index') %>
26 26  
27   - <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') unless profile.enterprise? && environment.enabled?('disable_header_and_footer') && !user.is_admin?(environment) %>
  27 + <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') if user.is_admin?(environment) || (!profile.enterprise? && !environment.enabled?('disable_header_and_footer')) %>
28 28  
29 29 <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %>
30 30  
... ...
app/views/shared/_disabled_enterprise.html.erb
... ... @@ -1,10 +0,0 @@
1   -<% if profile.enterprise? && !profile.enabled? && !profile.blocks.select {|b| b.class == DisabledEnterpriseMessageBlock}.any? %>
2   - <div id='profile-disabled'>
3   - <%= environment.message_for_disabled_enterprise %>
4   - <% if profile.blocked? && user && user.is_admin?(profile.environment) %>
5   - <div class='unlock-button'>
6   - <%= button :lock, _('Unblock'), {:controller => 'profile', :action => 'unblock'} %>
7   - </div>
8   - <% end %>
9   - </div>
10   -<% end %>
app/views/shared/_manage_link.html.erb
1 1 <div id=<%= "manage-#{kind}" %> class="manage-groups">
2   - <a href="#" id=<%= "manage-#{kind}-link" %> class="simplemenu-trigger" title="<%= _('Manage %s') % kind %>"><i class=<%= "icon-menu-#{kind.singularize}" %>></i><strong><%= ui_icon('ui-icon-triangle-1-s') + _('My %s') % kind %></strong></a>
  2 + <a href="#" id=<%= "manage-#{kind}-link" %> class="simplemenu-trigger" title="<%= _('Manage %s') % _(kind) %>"><i class=<%= "icon-menu-#{kind.singularize}" %>></i><strong><%= ui_icon('ui-icon-triangle-1-s') + title %></strong></a>
3 3 <ul class="simplemenu-submenu">
4 4 <% link.each do |link| %>
5 5 <li class="simplemenu-item"><%= link %></li>
... ...
app/views/shared/articles_list.html.erb
... ... @@ -1,14 +0,0 @@
1   -<table>
2   -
3   - <tr>
4   - <th><%= _('Title') %></th>
5   - <th><%= _('Last update') %></th>
6   - </tr>
7   - <% articles.each do |article| %>
8   - <% if article.display_to?(user) %>
9   - <%= display_article_in_listing(article, recursive, 0) %>
10   - <% end %>
11   - <% end %>
12   -</table>
13   -
14   -<p><%= pagination_links(articles, {:param_name => 'npage', :page_links => true}) %></p>
app/views/shared/content_list.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<table class="<%= list_type %>-content">
  2 + <tr>
  3 + <th><%= _('Title') %></th>
  4 + <th><%= _('Last update') %></th>
  5 + </tr>
  6 + <% contents.each do |content| %>
  7 + <% if content.display_to?(user) %>
  8 + <%= display_content_in_listing :content=>content, :list_type=>list_type, :recursive=>recursive %>
  9 + <% end %>
  10 + <% end %>
  11 +</table>
  12 +
  13 +<p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p>
... ...
config/environment.rb
1 1 # Load the rails application
2 2 require File.expand_path('../application', __FILE__)
3 3  
  4 +#FIXME Necessary hack to avoid the need of downgrading rubygems on rails 2.3.5
  5 +# http://stackoverflow.com/questions/5564251/uninitialized-constant-activesupportdependenciesmutex
  6 +require 'thread'
  7 +
4 8 # Uncomment below to force Rails into production mode when
5 9 # you don't control web/app server and can't set it the proper way
6 10 #ENV['RAILS_ENV'] ||= 'production'
... ...
config/initializers/exception_notification.rb
1 1 unless NOOSFERO_CONF['exception_recipients'].blank?
2   - require 'noosfero.rb'
3   - require 'exception_notification.rb'
4   - ExceptionNotifier.sender_address = "noreply@#{Noosfero.default_hostname}"
5   - ExceptionNotifier.email_prefix = "[Noosfero ERROR] "
6   - ExceptionNotifier.exception_recipients = NOOSFERO_CONF['exception_recipients']
7   - ActionController::Base.send :include, ExceptionNotifiable
  2 + Noosfero::Application.config.middleware.use ExceptionNotification::Rack,
  3 + :email => {
  4 + :sender_address => "noreply@#{Noosfero.default_hostname}",
  5 + :email_prefix => "[Noosfero ERROR] ",
  6 + :exception_recipients => NOOSFERO_CONF['exception_recipients']
  7 + }
8 8 end
... ...
config/routes.rb
... ... @@ -131,7 +131,7 @@ Noosfero::Application.routes.draw do
131 131 match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new
132 132 match '*page/versions', :controller => 'content_viewer', :action => 'article_versions'
133 133  
134   - match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } }
  134 + match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :constraints => EnvironmentDomainConstraint.new
135 135 match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff'
136 136  
137 137 # match requests for profiles that don't have a custom domain
... ...
db/migrate/20140501171906_index_filtered_fields_on_task.rb 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +class IndexFilteredFieldsOnTask < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :tasks, :requestor_id
  4 + add_index :tasks, :target_id
  5 + add_index :tasks, :target_type
  6 + add_index :tasks, [:target_id, :target_type]
  7 + add_index :tasks, :status
  8 + end
  9 +
  10 + def self.down
  11 + remove_index :tasks, :requestor_id
  12 + remove_index :tasks, :target_id
  13 + remove_index :tasks, :target_type
  14 + remove_index :tasks, [:target_id, :target_type]
  15 + remove_index :tasks, :status
  16 + end
  17 +end
... ...
db/migrate/20140709212646_add_spam_comments_counter_cache_to_articles.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class AddSpamCommentsCounterCacheToArticles < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :spam_comments_count, :integer, :default => 0
  4 + add_column :article_versions, :spam_comments_count, :integer, :default => 0
  5 + execute "update articles set spam_comments_count = (select count(*) from comments where comments.source_id = articles.id and comments.source_type = 'Article' and comments.spam = 't');"
  6 + end
  7 +
  8 + def self.down
  9 + remove_column :articles, :spam_comments_count
  10 + remove_column :article_versions, :spam_comments_count
  11 + end
  12 +end
... ...
db/migrate/20140709224246_create_real_relation_between_article_and_author.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class CreateRealRelationBetweenArticleAndAuthor < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :author_id, :integer
  4 + add_column :article_versions, :author_id, :integer
  5 +
  6 + # Set article's author as the first version's last_changed_by_id.
  7 + execute "update articles set author_id = (select article_versions.last_changed_by_id from article_versions where article_versions.article_id = articles.id and article_versions.version = 1 limit 1)"
  8 + end
  9 +
  10 + def self.down
  11 + remove_column :articles, :author_id
  12 + remove_column :article_versions, :author_id
  13 + end
  14 +end
... ...
db/migrate/20140808185510_update_default_tagging_context.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class UpdateDefaultTaggingContext < ActiveRecord::Migration
  2 +
  3 + def self.up
  4 + ActsAsTaggableOn::Tagging.where(:taggable_type => Article, :context => nil).update_all(:context => 'tags')
  5 + end
  6 +
  7 + def self.down
  8 + ActsAsTaggableOn::Tagging.where(:taggable_type => Article, :context => 'tags').update_all(:context => nil)
  9 + end
  10 +
  11 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended to check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(:version => 20140724134601) do
  14 +ActiveRecord::Schema.define(:version => 20140808185510) do
15 15  
16 16 create_table "abuse_reports", :force => true do |t|
17 17 t.integer "reporter_id"
... ... @@ -96,6 +96,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
96 96 t.integer "image_id"
97 97 t.integer "position"
98 98 t.integer "created_by_id"
  99 + t.integer "spam_comments_count", :default => 0
  100 + t.integer "author_id"
99 101 end
100 102  
101 103 add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id"
... ... @@ -142,6 +144,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
142 144 t.integer "image_id"
143 145 t.integer "position"
144 146 t.integer "created_by_id"
  147 + t.integer "spam_comments_count", :default => 0
  148 + t.integer "author_id"
145 149 end
146 150  
147 151 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
... ... @@ -597,7 +601,12 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
597 601 t.boolean "spam", :default => false
598 602 end
599 603  
  604 + add_index "tasks", ["requestor_id"], :name => "index_tasks_on_requestor_id"
600 605 add_index "tasks", ["spam"], :name => "index_tasks_on_spam"
  606 + add_index "tasks", ["status"], :name => "index_tasks_on_status"
  607 + add_index "tasks", ["target_id", "target_type"], :name => "index_tasks_on_target_id_and_target_type"
  608 + add_index "tasks", ["target_id"], :name => "index_tasks_on_target_id"
  609 + add_index "tasks", ["target_type"], :name => "index_tasks_on_target_type"
601 610  
602 611 create_table "terms_forum_people", :id => false, :force => true do |t|
603 612 t.integer "forum_id"
... ...
debian/changelog
... ... @@ -4,6 +4,18 @@ noosfero (0.99.0~rc20140618202455) wheezy-test; urgency=low
4 4  
5 5 -- Rodrigo Souto <rodrigo@colivre.coop.br> Wed, 18 Jun 2014 20:25:01 +0000
6 6  
  7 +noosfero (0.47.3) unstable; urgency=low
  8 +
  9 + * Bugfixes release
  10 +
  11 + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Fri, 20 Jun 2014 03:13:29 +0000
  12 +
  13 +noosfero (0.47.2) unstable; urgency=low
  14 +
  15 + * Bugfix release
  16 +
  17 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Fri, 13 Jun 2014 15:19:28 +0000
  18 +
7 19 noosfero (0.47.1) unstable; urgency=low
8 20  
9 21 * Bugfix release
... ...
debian/control
... ... @@ -32,10 +32,10 @@ Package: noosfero
32 32 Architecture: all
33 33 Depends:
34 34 rails3 (>= 3.2.6-1~),
35   - ruby,
36   - ruby1.9.3,
  35 + ruby (>= 1:1.9.3),
37 36 rake,
38 37 ruby-dalli,
  38 + ruby-exception-notification,
39 39 ruby-fast-gettext,
40 40 ruby-pg,
41 41 ruby-rmagick,
... ...
features/highlights_block.feature 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +Feature: Edit Highlight Block
  2 + As a user
  3 + I want to edit the highlight block
  4 +
  5 + Background:
  6 + Given I am on the homepage
  7 + And the following users
  8 + | login | name |
  9 + | jose | Jose Silva |
  10 + And I am logged in as "jose"
  11 +
  12 + @selenium
  13 + Scenario: Add new highlight
  14 + Given I follow "Control panel"
  15 + And I follow "Edit sideboxes"
  16 + And I follow "Add a block"
  17 + And I choose "Highlights"
  18 + And I press "Add"
  19 + And I follow "Edit" within ".highlights-block"#Need to hover the mouse on the box
  20 + And I follow "New highlight"
  21 + And I fill in "block_images__address" with "/"
  22 + And I fill in "block_images__position" with "0"
  23 + And I fill in "block_images__title" with "test highlights"
  24 + And I press "Save"
  25 + And I follow "Edit" within ".highlights-block"
  26 + Then I should see "Title"
  27 +
  28 + @selenium-fixme
  29 + Scenario: Remove one saved highlight
  30 + Given I follow "Control panel"
  31 + And I follow "Edit sideboxes"
  32 + And I follow "Add a block"
  33 + And I choose "Highlights"
  34 + And I press "Add"
  35 + And I follow "Edit" within ".highlights-block"
  36 + And I follow "New highlight"
  37 + And I fill in "block_images__address" with "/"
  38 + And I fill in "block_images__position" with "0"
  39 + And I fill in "block_images__title" with "test highlights"#Need to hover the mouse on the box
  40 + And I press "Save"
  41 + And I follow "Edit" within ".highlights-block"
  42 + And I follow "" within ".delete-highlight"
  43 + And I confirm the browser dialog
  44 + Then I should not see "Title"
0 45 \ No newline at end of file
... ...
lib/file_presenter.rb
... ... @@ -6,7 +6,9 @@ class FilePresenter
6 6 # one accepts it. That behave allow to give any model to this class,
7 7 # like a Article and have no trouble with that.
8 8 def self.for(f)
9   - return f if f.is_a? FilePresenter
  9 + #FIXME This check after the || is redundant but increases the blog_page
  10 + # speed considerably.
  11 + return f if f.is_a?(FilePresenter ) || (!f.kind_of?(UploadedFile) && !f.kind_of?(Image))
10 12 klass = FilePresenter.subclasses.sort_by {|class_instance|
11 13 class_instance.accepts?(f) || 0
12 14 }.last
... ...
lib/noosfero/plugin/routes.rb
1   -plugins_root = Rails.env.test? ? 'plugins' : File.join('config', 'plugins')
  1 +plugins_root = Rails.env.test? ? 'plugins' : '{baseplugins,config/plugins}'
2 2  
3 3 Dir.glob(Rails.root.join(plugins_root, '*', 'controllers')) do |controllers_dir|
4 4 prefixes_by_folder = {'public' => 'plugin',
... ...
lib/tasks/doc.rake
... ... @@ -137,7 +137,6 @@ namespace :noosfero do
137 137 desc "Translates Noosfero online documentation (does not touch PO files)"
138 138 task :translate => [:link_plugins_textiles, :do_translation]
139 139 task :do_translation => english_xhtml do
140   - require_dependency 'noosfero'
141 140 languages = Noosfero.locales.keys - ['en']
142 141 languages.each do |lang|
143 142 po = "po/#{lang}/noosfero-doc.po"
... ...
lib/tasks/translation.rake
... ... @@ -5,7 +5,7 @@ namespace :noosfero do
5 5 task :update => ['updatepo', 'noosfero:doc:rebuild']
6 6  
7 7 desc 'Compiles all translations'
8   - task :compile => ['makemo', 'noosfero:doc:translate']
  8 + task :compile => ['makemo', 'environment', 'noosfero:doc:translate']
9 9  
10 10 end
11 11 end
... ...
plugins/custom_forms/controllers/custom_forms_plugin_myprofile_controller.rb
... ... @@ -65,10 +65,8 @@ class CustomFormsPluginMyprofileController &lt; MyProfileController
65 65  
66 66 def submissions
67 67 @form = CustomFormsPlugin::Form.find(params[:id])
68   - @submissions = @form.submissions
69   -
70   - @sort_by = params[:sort_by]
71   - @submissions = @submissions.sort_by { |s| s.profile.present? ? s.profile.name : s.author_name } if @sort_by == 'author'
  68 + @sort_by = params[:sort_by] == 'author_name' ? 'author_name' : 'created_at'
  69 + @submissions = @form.submissions.order(@sort_by)
72 70  
73 71 respond_to do |format|
74 72 format.html
... ...
plugins/custom_forms/controllers/custom_forms_plugin_profile_controller.rb
... ... @@ -6,40 +6,26 @@ class CustomFormsPluginProfileController &lt; ProfileController
6 6  
7 7 @form = CustomFormsPlugin::Form.find(params[:id])
8 8 if user
9   - @submission ||= CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
  9 + @submission = CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
10 10 @submission ||= CustomFormsPlugin::Submission.new(:form => @form, :profile => user)
11 11 else
12   - @submission ||= CustomFormsPlugin::Submission.new(:form => @form)
  12 + @submission = CustomFormsPlugin::Submission.new(:form => @for)
13 13 end
14 14  
15 15 # build the answers
16   - @submission.answers.push(*(answers = build_answers(params[:submission], @form))) if params[:submission]
  16 + @answers = if params[:submission] then @submission.build_answers params[:submission] else @submission.answers end
17 17  
18 18 if request.post?
19 19 begin
20 20 raise 'Submission already present!' if user.present? && CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
21 21 raise 'Form expired!' if @form.expired?
22 22  
23   - # @submission.answers for some reason has the same answer twice
24   - failed_answers = answers.select {|answer| !answer.valid? }
25   -
26   - if failed_answers.empty?
27   - # Save the submission
28   - ActiveRecord::Base.transaction do
29   - if !user
30   - @submission.author_name = params[:author_name]
31   - @submission.author_email = params[:author_email]
32   - end
33   - @submission.save!
34   - end
35   - else
36   - @submission.errors.clear
37   - failed_answers.each do |answer|
38   - answer.valid?
39   - answer.errors.each do |attribute, msg|
40   - @submission.errors.add(answer.field.id.to_s.to_sym, msg)
41   - end
42   - end
  23 + if !user
  24 + @submission.author_name = params[:author_name]
  25 + @submission.author_email = params[:author_email]
  26 + end
  27 +
  28 + if not @submission.save
43 29 raise 'Submission failed: answers not valid'
44 30 end
45 31 session[:notice] = _('Submission saved')
... ...
plugins/custom_forms/db/migrate/20131107125327_add_admission_to_form.rb
... ... @@ -4,10 +4,7 @@ class AddAdmissionToForm &lt; ActiveRecord::Migration
4 4 t.boolean :for_admission, :default => false
5 5 end
6 6  
7   - CustomFormsPlugin::Form.find_each do |f|
8   - f.for_admission = false
9   - f.save!
10   - end
  7 + execute('update custom_forms_plugin_forms set for_admission = (1<0)')
11 8 end
12 9  
13 10 def self.down
... ...
plugins/custom_forms/db/migrate/20140619213950_remove_forms_without_profile.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class RemoveFormsWithoutProfile < ActiveRecord::Migration
  2 + def self.up
  3 + CustomFormsPlugin::Form.find_each do |form|
  4 + form.destroy if form.profile.nil?
  5 + end
  6 + end
  7 +
  8 + def self.down
  9 + say "This migration is irreversible."
  10 + end
  11 +end
... ...
plugins/custom_forms/db/migrate/20140807042217_fill_in_author_name_on_submission.rb 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +class FillInAuthorNameOnSubmission < ActiveRecord::Migration
  2 + def up
  3 + CustomFormsPlugin::Submission.find_each do |submission|
  4 + unless submission.profile.nil?
  5 + submission.author_name = submission.profile.name
  6 + submission.save
  7 + end
  8 + end
  9 + end
  10 +
  11 + def down
  12 + CustomFormsPlugin::Submission.find_each do |submission|
  13 + unless submission.profile.nil?
  14 + submission.author_name = nil
  15 + submission.save
  16 + end
  17 + end
  18 + end
  19 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/alternative.rb
... ... @@ -5,6 +5,6 @@ class CustomFormsPlugin::Alternative &lt; ActiveRecord::Base
5 5  
6 6 belongs_to :field, :class_name => 'CustomFormsPlugin::Field'
7 7  
8   - attr_accessible :label, :field, :position
  8 + attr_accessible :label, :field, :position, :selected_by_default
9 9 end
10 10  
... ...
plugins/custom_forms/lib/custom_forms_plugin/form.rb
... ... @@ -21,7 +21,7 @@ class CustomFormsPlugin::Form &lt; Noosfero::Plugin::ActiveRecord
21 21 end
22 22  
23 23 after_destroy do |form|
24   - tasks = CustomFormsPlugin::MembershipSurvey.from(form.profile).opened.select { |t| t.form_id == form.id }
  24 + tasks = CustomFormsPlugin::MembershipSurvey.opened.select { |t| t.form_id == form.id }
25 25 tasks.each {|task| task.cancel}
26 26 end
27 27  
... ...
plugins/custom_forms/lib/custom_forms_plugin/helper.rb
1 1 module CustomFormsPlugin::Helper
  2 +
  3 + protected
  4 +
2 5 def html_for_field(builder, association, klass)
3 6 new_object = klass.new
4 7 builder.fields_for(association, new_object, :child_index => "new_#{association}") do |f|
... ... @@ -117,22 +120,4 @@ module CustomFormsPlugin::Helper
117 120 type_for_options(field.class) == 'select_field' && field.select_field_type == 'check_box'
118 121 end
119 122  
120   - def build_answers(submission, form)
121   - answers = []
122   - form.fields.each do |field|
123   - final_value = ''
124   - if submission.has_key?(field.id.to_s)
125   - value = submission[field.id.to_s]
126   - if value.kind_of?(String)
127   - final_value = value
128   - elsif value.kind_of?(Array)
129   - final_value = value.join(',')
130   - elsif value.kind_of?(Hash)
131   - final_value = value.map {|option, present| present == '1' ? option : nil}.compact.join(',')
132   - end
133   - end
134   - answers << CustomFormsPlugin::Answer.new(:field => field, :value => final_value)
135   - end
136   - answers
137   - end
138 123 end
... ...
plugins/custom_forms/lib/custom_forms_plugin/membership_survey.rb
... ... @@ -11,23 +11,9 @@ class CustomFormsPlugin::MembershipSurvey &lt; Task
11 11 form = CustomFormsPlugin::Form.find(form_id)
12 12 raise 'Form expired' if form.expired?
13 13  
14   - answers = build_answers(submission, form)
15 14 s = CustomFormsPlugin::Submission.create!(:form => form, :profile => target)
16   - s.answers.push(*answers)
17   -
18   - failed_answers = answers.select {|answer| !answer.valid? }
19   - if failed_answers.empty?
20   - s.save!
21   - else
22   - s.errors.clear
23   - answers.each do |answer|
24   - answer.valid?
25   - answer.errors.each do |attribute, msg|
26   - s.errors.add(answer.field.id.to_s.to_sym, msg)
27   - end
28   - end
29   - raise ActiveRecord::RecordInvalid, s
30   - end
  15 + s.build_answers submission
  16 + s.save!
31 17 end
32 18  
33 19 def title
... ...
plugins/custom_forms/lib/custom_forms_plugin/submission.rb
... ... @@ -2,7 +2,8 @@ class CustomFormsPlugin::Submission &lt; Noosfero::Plugin::ActiveRecord
2 2 belongs_to :form, :class_name => 'CustomFormsPlugin::Form'
3 3 belongs_to :profile
4 4  
5   - has_many :answers, :class_name => 'CustomFormsPlugin::Answer', :dependent => :destroy
  5 + # validation is done manually, see below
  6 + has_many :answers, :class_name => 'CustomFormsPlugin::Answer', :dependent => :destroy, :validate => false
6 7  
7 8 attr_accessible :form, :profile
8 9  
... ... @@ -10,6 +11,7 @@ class CustomFormsPlugin::Submission &lt; Noosfero::Plugin::ActiveRecord
10 11 validates_presence_of :author_name, :author_email, :if => lambda {|submission| submission.profile.nil?}
11 12 validates_uniqueness_of :author_email, :scope => :form_id, :allow_nil => true
12 13 validates_format_of :author_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|submission| !submission.author_email.blank?})
  14 + validate :check_answers
13 15  
14 16 def self.human_attribute_name(attrib)
15 17 if /\d+/ =~ attrib and (f = CustomFormsPlugin::Field.find_by_id(attrib.to_i))
... ... @@ -19,5 +21,40 @@ class CustomFormsPlugin::Submission &lt; Noosfero::Plugin::ActiveRecord
19 21 end
20 22 end
21 23  
22   -end
  24 + before_create do |submission|
  25 + if submission.profile
  26 + submission.author_name = profile.name
  27 + end
  28 + end
  29 +
  30 + def build_answers submission
  31 + self.form.fields.each do |field|
  32 + next unless value = submission[field.id.to_s]
  33 +
  34 + final_value = ''
  35 + if value.kind_of?(String)
  36 + final_value = value
  37 + elsif value.kind_of?(Array)
  38 + final_value = value.join(',')
  39 + elsif value.kind_of?(Hash)
  40 + final_value = value.map {|option, present| present == '1' ? option : nil}.compact.join(',')
  41 + end
  42 +
  43 + self.answers.build :field => field, :value => final_value
  44 + end
23 45  
  46 + self.answers
  47 + end
  48 +
  49 + protected
  50 +
  51 + def check_answers
  52 + self.answers.each do |answer|
  53 + answer.valid?
  54 + answer.errors.each do |attribute, msg|
  55 + self.errors.add answer.field.id.to_s.to_sym, msg
  56 + end
  57 + end
  58 + end
  59 +
  60 +end
... ...
plugins/custom_forms/lib/ext/profile.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +require_dependency 'profile'
  2 +
  3 +class Profile
  4 +
  5 + has_many :forms, :class_name => 'CustomFormsPlugin::Form', :dependent => :destroy
  6 +
  7 +end
... ...
plugins/custom_forms/public/order.js 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +jQuery("select.filter").change(function(){
  2 + var filter = jQuery(this).find("option:selected").val();
  3 + var attribute = jQuery(this).attr('name');
  4 + redirect_to('?' + attribute + '=' + filter);
  5 +});
... ...
plugins/custom_forms/test/functional/custom_forms_plugin_myprofile_controller_test.rb
... ... @@ -220,7 +220,7 @@ class CustomFormsPluginMyprofileControllerTest &lt; ActionController::TestCase
220 220 assert_not_nil assigns(:sort_by)
221 221 assert_select 'table.action-table', /Author\W*Time\W*john[\W\dh]*bob[\W\dh]*/
222 222  
223   - get :submissions, :profile => profile.identifier, :id => form.id, :sort_by => 'author'
  223 + get :submissions, :profile => profile.identifier, :id => form.id, :sort_by => 'author_name'
224 224 assert_not_nil assigns(:sort_by)
225 225 assert_select 'table.action-table', /Author\W*Time\W*bob[\W\dh]*john[\W\dh]*/
226 226 end
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/form_test.rb
... ... @@ -274,4 +274,15 @@ class CustomFormsPlugin::FormTest &lt; ActiveSupport::TestCase
274 274 s2.reload
275 275 end
276 276 end
  277 +
  278 + should 'destroy forms after profile is destroyed' do
  279 + profile = fast_create(Profile)
  280 + form = CustomFormsPlugin::Form.create!(:profile => profile, :name => 'Free Software')
  281 + profile.destroy
  282 +
  283 + assert_raise ActiveRecord::RecordNotFound do
  284 + CustomFormsPlugin::Form.find(form.id)
  285 + end
  286 + end
  287 +
277 288 end
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/submission_test.rb
1 1 require File.dirname(__FILE__) + '/../../../../../test/test_helper'
2 2  
3 3 class CustomFormsPlugin::SubmissionTest < ActiveSupport::TestCase
  4 + def setup
  5 + @profile = fast_create(Profile)
  6 + end
  7 + attr_reader :profile
  8 +
4 9 should 'validates presence of form' do
5 10 submission = CustomFormsPlugin::Submission.new
6 11 submission.valid?
7 12 assert submission.errors.include?(:form)
8 13  
9   - form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  14 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => profile)
10 15 submission.form = form
11 16 submission.valid?
12 17 assert !submission.errors.include?(:form)
13 18 end
14 19  
15 20 should 'belong to a profile' do
16   - profile = fast_create(Profile)
17 21 submission = CustomFormsPlugin::Submission.new
18 22 submission.profile = profile
19 23 assert_equal profile, submission.profile
... ... @@ -33,14 +37,21 @@ class CustomFormsPlugin::SubmissionTest &lt; ActiveSupport::TestCase
33 37 end
34 38  
35 39 should 'have answers' do
36   - form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => fast_create(Profile))
  40 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => profile)
37 41 field = CustomFormsPlugin::Field.create!(:name => 'License', :form => form)
38   - submission = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
39   - a1 = CustomFormsPlugin::Answer.create!(:field => field, :submission => submission)
40   - a2 = CustomFormsPlugin::Answer.create!(:field => field, :submission => submission)
  42 + submission = CustomFormsPlugin::Submission.create!(:form => form, :profile => profile)
  43 + a1 = submission.answers.create!(:field => field, :submission => submission)
  44 + a2 = submission.answers.create!(:field => field, :submission => submission)
41 45  
42 46 assert_includes submission.answers, a1
43 47 assert_includes submission.answers, a2
44 48 end
  49 +
  50 + should 'store profile name as author' do
  51 + form = CustomFormsPlugin::Form.create!(:name => 'Free Software', :profile => profile)
  52 + submission = CustomFormsPlugin::Submission.create(:form => form, :profile => profile)
  53 +
  54 + assert_equal profile.name, submission.author_name
  55 + end
45 56 end
46 57  
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/_field.html.erb
... ... @@ -12,7 +12,7 @@
12 12 <%= f.hidden_field(:position) %>
13 13  
14 14 <%= f.hidden_field :_destroy, :class => 'destroy-field' %>
15   - <%= button_to_function :delete, _('Remove field'), "customFormsPlugin.removeFieldBox(this, #{j _('Are you sure you want to remove this field?').to_json})" %>
  15 + <%= button_to_function :delete, _('Remove field'), "customFormsPlugin.removeFieldBox(this, #{CGI::escapeHTML(_('Are you sure you want to remove this field?').to_json)})" %>
16 16 <%= yield %>
17 17 </div>
18 18 </fieldset>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/_form.html.erb
... ... @@ -31,8 +31,8 @@
31 31 </ul>
32 32  
33 33 <div class="addition-buttons">
34   - <%= button(:add, _('Add a new text field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{j html_for_field(f, :fields, CustomFormsPlugin::TextField).to_json}); return false")%>
35   - <%= button(:add, _('Add a new select field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{j html_for_field(f, :fields, CustomFormsPlugin::SelectField).to_json}); return false")%>
  34 + <%= button(:add, _('Add a new text field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{CGI::escapeHTML(html_for_field(f, :fields, CustomFormsPlugin::TextField).to_json)}); return false")%>
  35 + <%= button(:add, _('Add a new select field'), '#', :onclick => "customFormsPlugin.addFields(this, 'fields', #{CGI::escapeHTML(html_for_field(f, :fields, CustomFormsPlugin::SelectField).to_json)}); return false")%>
36 36 </div>
37 37  
38 38 <% button_bar do %>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_alternative.html.erb
... ... @@ -7,6 +7,6 @@
7 7  
8 8 <td>
9 9 <%= f.hidden_field :_destroy, :class => 'destroy-field' %>
10   - <%= button_to_function_without_text :remove, _('Remove alternative'), "customFormsPlugin.removeAlternative(this, #{j _('Are you sure you want to remove this alternative?').to_json})", :class => 'remove-field', :title => _('Remove alternative') %>
  10 + <%= button_to_function_without_text :remove, _('Remove alternative'), "customFormsPlugin.removeAlternative(this, #{CGI::escapeHTML(_('Are you sure you want to remove this alternative?').to_json)})", :class => 'remove-field', :title => _('Remove alternative') %>
11 11 </td>
12 12 </tr>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/custom_forms_plugin/_select_field.html.erb
... ... @@ -22,7 +22,7 @@
22 22 <tfoot>
23 23 <tr class="addition-buttons">
24 24 <td colspan="3">
25   - <%= button(:add, _('Add a new alternative'), '#', :onclick => "customFormsPlugin.addFields(this, 'alternatives', #{j html_for_field(f, :alternatives, CustomFormsPlugin::Alternative).to_json}); return false") %>
  25 + <%= button(:add, _('Add a new alternative'), '#', :onclick => "customFormsPlugin.addFields(this, 'alternatives', #{CGI::escapeHTML(html_for_field(f, :alternatives, CustomFormsPlugin::Alternative).to_json)}); return false") %>
26 26 </td>
27 27 </tr>
28 28 </tfoot>
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/show_submission.html.erb
1 1 <h1><%= @form.name %></h1>
2 2 <p><%= @form.description %></p>
3 3  
4   -<% fields_for :submission, @submission do |f| %>
  4 +<%= fields_for :submission, @submission do |f| %>
5 5 <%= render :partial => 'shared/form_submission', :locals => {:f => f} %>
6 6 <% end %>
7 7  
... ...
plugins/custom_forms/views/custom_forms_plugin_myprofile/submissions.html.erb
... ... @@ -10,7 +10,7 @@
10 10 <%= link_to '[CSV]', :format => 'csv' %>
11 11 </p>
12 12 <p>
13   - <%= labelled_select(_('Sort by')+': ', :sort_by, :first, :last, @sort_by, [['time', _('Time')], ['author', _('Author')]], :onchange => 'document.location.href = "?sort_by="+this.value') %>
  13 + <%= labelled_select(_('Sort by')+': ', :sort_by, :first, :last, @sort_by, [['created_at', _('Time')], ['author_name', _('Author')]], :class => 'filter') %>
14 14 </p>
15 15 <table class="action-table">
16 16 <tr>
... ... @@ -30,3 +30,5 @@
30 30 <% button_bar do %>
31 31 <%= button :back, _('Back to forms'), :action => 'index' %>
32 32 <% end %>
  33 +
  34 +<%= javascript_include_tag '../plugins/custom_forms/order' %>
... ...
plugins/shopping_cart/controllers/shopping_cart_plugin_controller.rb
... ... @@ -28,8 +28,8 @@ class ShoppingCartPluginController &lt; PublicController
28 28  
29 29 def add
30 30 product = find_product(params[:id])
31   - if product && enterprise = validate_same_enterprise(product)
32   - self.cart = { :profile_id => enterprise.id, :items => {} } if self.cart.nil?
  31 + if product && profile = validate_same_profile(product)
  32 + self.cart = { :profile_id => profile.id, :items => {} } if self.cart.nil?
33 33 self.cart[:items][product.id] = 0 if self.cart[:items][product.id].nil?
34 34 self.cart[:items][product.id] += 1
35 35 render :text => {
... ... @@ -38,7 +38,7 @@ class ShoppingCartPluginController &lt; PublicController
38 38 :products => [{
39 39 :id => product.id,
40 40 :name => product.name,
41   - :price => get_price(product, enterprise.environment),
  41 + :price => get_price(product, profile.environment),
42 42 :description => product.description,
43 43 :picture => product.default_image(:minor),
44 44 :quantity => self.cart[:items][product.id]
... ... @@ -97,8 +97,8 @@ class ShoppingCartPluginController &lt; PublicController
97 97 @customer = user || Person.new
98 98 if validate_cart_presence
99 99 @cart = cart
100   - @enterprise = environment.enterprises.find(cart[:profile_id])
101   - @settings = Noosfero::Plugin::Settings.new(@enterprise, ShoppingCartPlugin)
  100 + @profile = environment.profiles.find(cart[:profile_id])
  101 + @settings = Noosfero::Plugin::Settings.new(@profile, ShoppingCartPlugin)
102 102 render :layout => false
103 103 end
104 104 end
... ... @@ -106,9 +106,9 @@ class ShoppingCartPluginController &lt; PublicController
106 106 def send_request
107 107 register_order(params[:customer], self.cart[:items])
108 108 begin
109   - enterprise = environment.enterprises.find(cart[:profile_id])
110   - ShoppingCartPlugin::Mailer.customer_notification(params[:customer], enterprise, self.cart[:items], params[:delivery_option]).deliver
111   - ShoppingCartPlugin::Mailer.supplier_notification(params[:customer], enterprise, self.cart[:items], params[:delivery_option]).deliver
  109 + profile = environment.profiles.find(cart[:profile_id])
  110 + ShoppingCartPlugin::Mailer.customer_notification(params[:customer], profile, self.cart[:items], params[:delivery_option]).deliver
  111 + ShoppingCartPlugin::Mailer.supplier_notification(params[:customer], profile, self.cart[:items], params[:delivery_option]).deliver
112 112 self.cart = nil
113 113 render :text => {
114 114 :ok => true,
... ... @@ -169,8 +169,8 @@ class ShoppingCartPluginController &lt; PublicController
169 169 end
170 170  
171 171 def update_delivery_option
172   - enterprise = environment.enterprises.find(cart[:profile_id])
173   - settings = Noosfero::Plugin::Settings.new(enterprise, ShoppingCartPlugin)
  172 + profile = environment.profiles.find(cart[:profile_id])
  173 + settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin)
174 174 delivery_price = settings.delivery_options[params[:delivery_option]]
175 175 delivery = Product.new(:name => params[:delivery_option], :price => delivery_price)
176 176 delivery.save(false)
... ... @@ -189,7 +189,7 @@ class ShoppingCartPluginController &lt; PublicController
189 189  
190 190 private
191 191  
192   - def validate_same_enterprise(product)
  192 + def validate_same_profile(product)
193 193 if self.cart && self.cart[:profile_id] && product.profile_id != self.cart[:profile_id]
194 194 render :text => {
195 195 :ok => false,
... ... @@ -200,7 +200,7 @@ class ShoppingCartPluginController &lt; PublicController
200 200 }.to_json
201 201 return nil
202 202 end
203   - product.enterprise
  203 + product.profile
204 204 end
205 205  
206 206 def validate_cart_presence
... ... @@ -269,7 +269,7 @@ class ShoppingCartPluginController &lt; PublicController
269 269 new_items[id] = {:quantity => quantity, :price => price, :name => product.name}
270 270 end
271 271 purchase_order = ShoppingCartPlugin::PurchaseOrder.new
272   - purchase_order.seller = Enterprise.find(cart[:profile_id])
  272 + purchase_order.seller = environment.profiles.find(cart[:profile_id])
273 273 purchase_order.customer = user
274 274 purchase_order.status = ShoppingCartPlugin::PurchaseOrder::Status::OPENED
275 275 purchase_order.products_list = new_items
... ... @@ -326,7 +326,7 @@ class ShoppingCartPluginController &lt; PublicController
326 326 if product
327 327 { :id => product.id,
328 328 :name => product.name,
329   - :price => get_price(product, product.enterprise.environment),
  329 + :price => get_price(product, product.profile.environment),
330 330 :description => product.description,
331 331 :picture => product.default_image(:minor),
332 332 :quantity => quantity
... ...
plugins/shopping_cart/controllers/shopping_cart_plugin_myprofile_controller.rb
1   -include ShoppingCartPlugin::CartHelper
2   -
3 1 class ShoppingCartPluginMyprofileController < MyProfileController
4   - append_view_path File.join(File.dirname(__FILE__) + '/../views')
5   -
6 2 def edit
7 3 params[:settings] = treat_cart_options(params[:settings])
8 4  
... ...
plugins/shopping_cart/lib/shopping_cart_plugin.rb
... ... @@ -23,8 +23,8 @@ class ShoppingCartPlugin &lt; Noosfero::Plugin
23 23 end
24 24  
25 25 def add_to_cart_button(item)
26   - enterprise = item.enterprise
27   - settings = Noosfero::Plugin::Settings.new(enterprise, ShoppingCartPlugin)
  26 + profile = item.profile
  27 + settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin)
28 28 if settings.enabled && item.available
29 29 lambda {
30 30 link_to(_('Add to basket'), "add:#{item.name}",
... ...
plugins/shopping_cart/public/buy.js
... ... @@ -11,7 +11,7 @@ jQuery(document).ready(function(){
11 11 jQuery('#delivery_option').change(function(){
12 12 jQuery('#cboxLoadingGraphic').show();
13 13 me = this;
14   - enterprise = jQuery(me).attr('data-profile-identifier');
  14 + profile = jQuery(me).attr('data-profile-identifier');
15 15 option = jQuery(me).val();
16 16 jQuery.ajax({
17 17 url: '/plugin/shopping_cart/update_delivery_option',
... ...
plugins/shopping_cart/test/functional/shopping_cart_plugin_controller_test.rb
... ... @@ -10,10 +10,10 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
10 10 @controller = ShoppingCartPluginController.new
11 11 @request = ActionController::TestRequest.new
12 12 @response = ActionController::TestResponse.new
13   - @enterprise = fast_create(Enterprise)
14   - @product = fast_create(Product, :profile_id => @enterprise.id)
  13 + @profile = fast_create(Enterprise)
  14 + @product = fast_create(Product, :profile_id => @profile.id)
15 15 end
16   - attr_reader :enterprise
  16 + attr_reader :profile
17 17 attr_reader :product
18 18  
19 19 should 'force cookie expiration with explicit path for an empty cart' do
... ... @@ -62,7 +62,7 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
62 62 end
63 63  
64 64 should 'just remove product if there are other products on cart' do
65   - another_product = fast_create(Product, :profile_id => enterprise.id)
  65 + another_product = fast_create(Product, :profile_id => profile.id)
66 66 get :add, :id => product.id
67 67 get :add, :id => another_product.id
68 68  
... ... @@ -135,7 +135,7 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
135 135 end
136 136  
137 137 should 'clean the cart' do
138   - another_product = fast_create(Product, :profile_id => enterprise.id)
  138 + another_product = fast_create(Product, :profile_id => profile.id)
139 139 get :add, :id => product.id
140 140 get :add, :id => another_product.id
141 141  
... ... @@ -150,9 +150,9 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
150 150 end
151 151  
152 152 should 'register order on send request' do
153   - product1 = fast_create(Product, :profile_id => enterprise.id, :price => 1.99)
154   - product2 = fast_create(Product, :profile_id => enterprise.id, :price => 2.23)
155   - @controller.stubs(:cart).returns({ :profile_id => enterprise.id, :items => {product1.id => 1, product2.id => 2}})
  153 + product1 = fast_create(Product, :profile_id => profile.id, :price => 1.99)
  154 + product2 = fast_create(Product, :profile_id => profile.id, :price => 2.23)
  155 + @controller.stubs(:cart).returns({ :profile_id => profile.id, :items => {product1.id => 1, product2.id => 2}})
156 156 assert_difference 'ShoppingCartPlugin::PurchaseOrder.count', 1 do
157 157 post :send_request,
158 158 :customer => {:name => "Manuel", :email => "manuel@ceu.com"}
... ... @@ -168,8 +168,8 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
168 168 end
169 169  
170 170 should 'register order on send request and not crash if product is not defined' do
171   - product1 = fast_create(Product, :profile_id => enterprise.id)
172   - @controller.stubs(:cart).returns({ :profile_id => enterprise.id, :items => {product1.id => 1}})
  171 + product1 = fast_create(Product, :profile_id => profile.id)
  172 + @controller.stubs(:cart).returns({ :profile_id => profile.id, :items => {product1.id => 1}})
173 173 assert_difference 'ShoppingCartPlugin::PurchaseOrder.count', 1 do
174 174 post :send_request,
175 175 :customer => {:name => "Manuel", :email => "manuel@ceu.com"}
... ... @@ -181,7 +181,7 @@ class ShoppingCartPluginControllerTest &lt; ActionController::TestCase
181 181 end
182 182  
183 183 should 'clean the cart after placing the order' do
184   - product1 = fast_create(Product, :profile_id => enterprise.id)
  184 + product1 = fast_create(Product, :profile_id => profile.id)
185 185 post :add, :id => product1.id
186 186 post :send_request, :customer => { :name => "Manuel", :email => "manuel@ceu.com" }
187 187 assert !cart?, "cart expected to be empty!"
... ...
plugins/shopping_cart/test/functional/shopping_cart_plugin_myprofile_controller_test.rb
... ... @@ -5,17 +5,17 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
5 5 TIME_FORMAT = '%Y-%m-%d'
6 6  
7 7 def setup
8   - @enterprise = fast_create(Enterprise)
  8 + @profile = fast_create(Enterprise)
9 9 @admin = create_user('admin').person
10   - @enterprise.add_admin(@admin)
  10 + @profile.add_admin(@admin)
11 11 login_as(@admin.identifier)
12 12 end
13   - attr_reader :enterprise
  13 + attr_reader :profile
14 14  
15 15 should 'be able to enable shopping cart' do
16 16 settings.enabled = false
17 17 settings.save!
18   - post :edit, :profile => enterprise.identifier, :settings => {:enabled => '1'}
  18 + post :edit, :profile => profile.identifier, :settings => {:enabled => '1'}
19 19  
20 20 assert settings.enabled
21 21 end
... ... @@ -23,7 +23,7 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
23 23 should 'be able to disable shopping cart' do
24 24 settings.enabled = true
25 25 settings.save!
26   - post :edit, :profile => enterprise.identifier, :settings => {:enabled => '0'}
  26 + post :edit, :profile => profile.identifier, :settings => {:enabled => '0'}
27 27  
28 28 assert !settings.enabled
29 29 end
... ... @@ -31,7 +31,7 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
31 31 should 'be able to enable shopping cart delivery' do
32 32 settings.delivery = false
33 33 settings.save!
34   - post :edit, :profile => enterprise.identifier, :settings => {:delivery => '1'}
  34 + post :edit, :profile => profile.identifier, :settings => {:delivery => '1'}
35 35  
36 36 assert settings.delivery
37 37 end
... ... @@ -39,37 +39,37 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
39 39 should 'be able to disable shopping cart delivery' do
40 40 settings.delivery = true
41 41 settings.save!
42   - post :edit, :profile => enterprise.identifier, :settings => {:delivery => '0'}
  42 + post :edit, :profile => profile.identifier, :settings => {:delivery => '0'}
43 43  
44 44 assert !settings.delivery
45 45 end
46 46  
47 47 should 'be able to choose the delivery price' do
48 48 price = 4.35
49   - post :edit, :profile => enterprise.identifier, :settings => {:delivery_price => price}
  49 + post :edit, :profile => profile.identifier, :settings => {:delivery_price => price}
50 50  
51 51 assert settings.delivery_price == price.to_s
52 52 end
53 53  
54 54 should 'be able to choose delivery_options' do
55 55 delivery_options = {:options => ['car', 'bike'], :prices => ['20', '5']}
56   - post :edit, :profile => enterprise.identifier, :settings => {:delivery_options => delivery_options}
  56 + post :edit, :profile => profile.identifier, :settings => {:delivery_options => delivery_options}
57 57  
58 58 assert_equal '20', settings.delivery_options['car']
59 59 assert_equal '5', settings.delivery_options['bike']
60 60 end
61 61  
62 62 should 'filter the reports correctly' do
63   - another_enterprise = fast_create(Enterprise)
64   - po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
65   - po2 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::SHIPPED)
66   - po3 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
  63 + another_profile = fast_create(Enterprise)
  64 + po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => profile, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
  65 + po2 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => profile, :status => ShoppingCartPlugin::PurchaseOrder::Status::SHIPPED)
  66 + po3 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => profile, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
67 67 po3.created_at = 1.year.ago
68 68 po3.save!
69   - po4 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => another_enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
  69 + po4 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => another_profile, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
70 70  
71 71 post :reports,
72   - :profile => enterprise.identifier,
  72 + :profile => profile.identifier,
73 73 :from => (Time.now - 1.day).strftime(TIME_FORMAT),
74 74 :to => (Time.now + 1.day).strftime(TIME_FORMAT),
75 75 :filter_status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED
... ... @@ -81,16 +81,16 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
81 81 end
82 82  
83 83 should 'group filtered orders products and quantities' do
84   - p1 = fast_create(Product, :profile_id => enterprise.id, :price => 1, :name => 'p1')
85   - p2 = fast_create(Product, :profile_id => enterprise.id, :price => 2, :name => 'p2')
86   - p3 = fast_create(Product, :profile_id => enterprise.id, :price => 3)
  84 + p1 = fast_create(Product, :profile_id => profile.id, :price => 1, :name => 'p1')
  85 + p2 = fast_create(Product, :profile_id => profile.id, :price => 2, :name => 'p2')
  86 + p3 = fast_create(Product, :profile_id => profile.id, :price => 3)
87 87 po1_products = {p1.id => {:quantity => 1, :price => p1.price, :name => p1.name}, p2.id => {:quantity => 2, :price => p2.price, :name => p2.name }}
88 88 po2_products = {p2.id => {:quantity => 1, :price => p2.price, :name => p2.name }, p3.id => {:quantity => 2, :price => p3.price, :name => p3.name}}
89   - po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :products_list => po1_products, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
90   - po2 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :products_list => po2_products, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
  89 + po1 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => profile, :products_list => po1_products, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
  90 + po2 = ShoppingCartPlugin::PurchaseOrder.create!(:seller => profile, :products_list => po2_products, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
91 91  
92 92 post :reports,
93   - :profile => enterprise.identifier,
  93 + :profile => profile.identifier,
94 94 :from => (Time.now - 1.day).strftime(TIME_FORMAT),
95 95 :to => (Time.now + 1.day).strftime(TIME_FORMAT),
96 96 :filter_status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED
... ... @@ -107,10 +107,10 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
107 107 end
108 108  
109 109 should 'be able to update the order status' do
110   - po = ShoppingCartPlugin::PurchaseOrder.create!(:seller => enterprise, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
  110 + po = ShoppingCartPlugin::PurchaseOrder.create!(:seller => profile, :status => ShoppingCartPlugin::PurchaseOrder::Status::OPENED)
111 111  
112 112 post :update_order_status,
113   - :profile => enterprise.identifier,
  113 + :profile => profile.identifier,
114 114 :order_id => po.id,
115 115 :order_status => ShoppingCartPlugin::PurchaseOrder::Status::CONFIRMED
116 116 po.reload
... ... @@ -120,7 +120,7 @@ class ShoppingCartPluginMyprofileControllerTest &lt; ActionController::TestCase
120 120 private
121 121  
122 122 def settings
123   - @enterprise.reload
124   - Noosfero::Plugin::Settings.new(@enterprise, ShoppingCartPlugin)
  123 + @profile.reload
  124 + Noosfero::Plugin::Settings.new(@profile, ShoppingCartPlugin)
125 125 end
126 126 end
... ...
plugins/shopping_cart/test/unit/shopping_cart_plugin_test.rb
... ... @@ -19,16 +19,16 @@ class ShoppingCartPluginTest &lt; ActiveSupport::TestCase
19 19 end
20 20  
21 21 should 'not add button if product unavailable' do
22   - enterprise = fast_create(:enterprise)
23   - product = fast_create(Product, :available => false, :profile_id => enterprise.id)
24   - enterprise.stubs(:shopping_cart).returns(true)
  22 + profile = fast_create(:enterprise)
  23 + product = fast_create(Product, :available => false, :profile_id => profile.id)
  24 + profile.stubs(:shopping_cart).returns(true)
25 25  
26 26 assert_nil shopping_cart.add_to_cart_button(product)
27 27 end
28 28  
29 29 should 'be disabled by default on the enterprise' do
30   - enterprise = fast_create(Enterprise)
31   - settings = Noosfero::Plugin::Settings.new(enterprise, ShoppingCartPlugin)
  30 + profile = fast_create(Enterprise)
  31 + settings = Noosfero::Plugin::Settings.new(profile, ShoppingCartPlugin)
32 32 assert !settings.enabled
33 33 end
34 34 end
... ...
plugins/shopping_cart/views/shopping_cart_plugin/buy.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <%= labelled_form_field('* ' + _("Name"), f.text_field(:name, :class => 'required') ) %>
6 6 <%= labelled_form_field('* ' + _("Email"), f.text_field(:email, :class => 'required email') ) %>
7 7 <%= labelled_form_field('* ' + _("Contact phone"), f.text_field(:contact_phone, :class => 'required') ) %>
8   - <%= labelled_form_field(_('Delivery option'), select_tag(:delivery_option, options_for_select(select_delivery_options(@settings.delivery_options, environment)), 'data-profile-identifier' => @enterprise.identifier)) unless !@settings.delivery || (@settings.free_delivery_price && get_total(@cart[:items]) >= @settings.free_delivery_price) %>
  8 + <%= labelled_form_field(_('Delivery option'), select_tag(:delivery_option, options_for_select(select_delivery_options(@settings.delivery_options, environment)), 'data-profile-identifier' => @profile.identifier)) unless !@settings.delivery || (@settings.free_delivery_price && get_total(@cart[:items]) >= @settings.free_delivery_price) %>
9 9 <%= labelled_form_field(_('Payment'), select_tag('customer[payment]', options_for_select([[_("Money"), :money],[_('shopping_cart|Check'), :check]]))) %>
10 10 <%= labelled_form_field(s_('shopping_cart|Change'), text_field_tag('customer[change]')) %>
11 11 </div>
... ... @@ -23,7 +23,7 @@
23 23 </div>
24 24 <% end %>
25 25 <% delivery_option = @settings.delivery_options.first && @settings.delivery_options.first.first %>
26   - <%= items_table(@cart[:items], @enterprise, delivery_option) %>
  26 + <%= items_table(@cart[:items], @profile, delivery_option) %>
27 27 <%= link_to '', '#', :onclick => "Cart.colorbox_close(this);", :class => 'cart-box-close icon-cancel' %>
28 28 </div>
29 29  
... ...
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/reports.html.erb
1 1 <h1> <%= _('Purchase Reports') %> </h1>
2 2  
3 3 <% extend ProfileHelper %>
  4 +<% extend ShoppingCartPlugin::CartHelper %>
4 5  
5 6 <% status = ShoppingCartPlugin::PurchaseOrder::Status.name; pos=-1 %>
6 7 <% status_collection = [[nil, _('All')]] %>
... ...
plugins/solr/lib/ext/article.rb
... ... @@ -40,6 +40,7 @@ class Article
40 40 :if => proc{ |a| ! ['RssFeed'].include?(a.class.name) }
41 41  
42 42 handle_asynchronously :solr_save
  43 + handle_asynchronously :solr_destroy
43 44  
44 45 def solr_plugin_comments_updated
45 46 solr_save
... ...
plugins/solr/lib/ext/category.rb
... ... @@ -15,6 +15,7 @@ class Category
15 15 ]
16 16  
17 17 handle_asynchronously :solr_save
  18 + handle_asynchronously :solr_destroy
18 19  
19 20 private
20 21  
... ...
plugins/solr/lib/ext/facets_browse.rb
  1 +Object.send :remove_const, :SearchController if defined? SearchController and not ActionController::Base.perform_caching
1 2 require_dependency 'search_controller'
2 3  
3 4 module SolrPlugin::FacetsBrowse
... ...
plugins/solr/lib/ext/product.rb
... ... @@ -43,6 +43,7 @@ class Product
43 43 :boost => proc{ |p| boost = 1; SolrPlugin::Boosts.each{ |b| boost = boost * (1 - ((1 - b[2].call(p)) * b[1])) }; boost}
44 44  
45 45 handle_asynchronously :solr_save
  46 + handle_asynchronously :solr_destroy
46 47  
47 48 private
48 49  
... ...
plugins/solr/lib/ext/profile.rb
... ... @@ -14,10 +14,11 @@ class Profile
14 14 :solr_plugin_f_enabled => {:label => _('Situation'), :type_if => proc { |klass| klass.kind_of?(Enterprise) },
15 15 :proc => proc { |id| solr_plugin_f_enabled_proc(id) }},
16 16 :solr_plugin_f_region => {:label => _('City'), :proc => proc { |id| solr_plugin_f_region_proc(id) }},
  17 + :solr_plugin_f_profile_type => {:label => _('Type'), :proc => proc{|klass| solr_plugin_f_profile_type_proc(klass)}},
17 18 :solr_plugin_f_categories => {:multi => true, :proc => proc {|facet, id| solr_plugin_f_categories_proc(facet, id)},
18 19 :label => proc { |env| solr_plugin_f_categories_label_proc(env) }, :label_abbrev => proc{ |env| solr_plugin_f_categories_label_abbrev_proc(env) }},
19 20 }, :category_query => proc { |c| "solr_plugin_category_filter:#{c.id}" },
20   - :order => [:solr_plugin_f_region, :solr_plugin_f_categories, :solr_plugin_f_enabled]
  21 + :order => [:solr_plugin_f_region, :solr_plugin_f_categories, :solr_plugin_f_enabled, :solr_plugin_f_profile_type]
21 22  
22 23 acts_as_searchable :fields => facets_fields_for_solr + [:solr_plugin_extra_data_for_index,
23 24 # searched fields
... ... @@ -39,6 +40,7 @@ class Profile
39 40 :boost => proc{ |p| 10 if p.enabled }
40 41  
41 42 handle_asynchronously :solr_save
  43 + handle_asynchronously :solr_destroy
42 44  
43 45 class_inheritable_accessor :solr_plugin_extra_index_methods
44 46 self.solr_plugin_extra_index_methods = []
... ... @@ -116,4 +118,13 @@ class Profile
116 118 def solr_plugin_name_sortable
117 119 name
118 120 end
  121 +
  122 + def solr_plugin_f_profile_type
  123 + self.class.name
  124 + end
  125 +
  126 + def self.solr_plugin_f_profile_type_proc klass
  127 + klass.constantize.type_name
  128 + end
  129 +
119 130 end
... ...