Commit 364e52a3cfbc1b6a0943d99e31dba1880e1111fa

Authored by Victor Costa
2 parents d66a1bc8 4eb04441

Merge branch 'master' into production

Conflicts:
	lib/noosfero/plugin.rb
Showing 98 changed files with 1013 additions and 451 deletions   Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -105,6 +105,11 @@ class CmsController < MyProfileController @@ -105,6 +105,11 @@ class CmsController < MyProfileController
105 end 105 end
106 end 106 end
107 end 107 end
  108 +
  109 + unless @article.kind_of?(RssFeed)
  110 + @escaped_body = CGI::escapeHTML(@article.body || '')
  111 + @escaped_abstract = CGI::escapeHTML(@article.abstract || '')
  112 + end
108 end 113 end
109 114
110 def new 115 def new
app/controllers/my_profile/manage_products_controller.rb
@@ -35,7 +35,7 @@ class ManageProductsController < ApplicationController @@ -35,7 +35,7 @@ class ManageProductsController < ApplicationController
35 end 35 end
36 36
37 def categories_for_selection 37 def categories_for_selection
38 - @category = Category.find(params[:category_id]) if params[:category_id] 38 + @category = environment.categories.find_by_id params[:category_id]
39 @object_name = params[:object_name] 39 @object_name = params[:object_name]
40 if @category 40 if @category
41 @categories = @category.children 41 @categories = @category.children
@@ -95,6 +95,20 @@ class ManageProductsController < ApplicationController @@ -95,6 +95,20 @@ class ManageProductsController < ApplicationController
95 end 95 end
96 end 96 end
97 97
  98 + def show_category_tree
  99 + @category = environment.categories.find params[:category_id]
  100 + render :partial => 'selected_category_tree'
  101 + end
  102 +
  103 + def search_categories
  104 + @term = params[:term].downcase
  105 + conditions = ['LOWER(name) LIKE ? OR LOWER(name) LIKE ?', "#{@term}%", "% #{@term}%"]
  106 + @categories = ProductCategory.all :conditions => conditions, :limit => 10
  107 + render :json => (@categories.map do |category|
  108 + {:label => category.name, :value => category.id}
  109 + end)
  110 + end
  111 +
98 def add_input 112 def add_input
99 @product = @profile.products.find(params[:id]) 113 @product = @profile.products.find(params[:id])
100 @input = @product.inputs.build 114 @input = @product.inputs.build
app/controllers/my_profile/maps_controller.rb
@@ -16,6 +16,7 @@ class MapsController < MyProfileController @@ -16,6 +16,7 @@ class MapsController < MyProfileController
16 16
17 Profile.transaction do 17 Profile.transaction do
18 if profile.update_attributes!(params[:profile_data]) 18 if profile.update_attributes!(params[:profile_data])
  19 + BlockSweeper.expire_blocks profile.blocks.select{ |b| b.class == LocationBlock }
19 session[:notice] = _('Address was updated successfully!') 20 session[:notice] = _('Address was updated successfully!')
20 redirect_to :action => 'edit_location' 21 redirect_to :action => 'edit_location'
21 end 22 end
app/controllers/public/content_viewer_controller.rb
@@ -15,6 +15,7 @@ class ContentViewerController < ApplicationController @@ -15,6 +15,7 @@ class ContentViewerController < ApplicationController
15 path = get_path(params[:page], params[:format]) 15 path = get_path(params[:page], params[:format])
16 16
17 @version = params[:version].to_i 17 @version = params[:version].to_i
  18 + @npage = params[:npage] || '1'
18 19
19 if path.blank? 20 if path.blank?
20 @page = profile.home_page 21 @page = profile.home_page
@@ -131,7 +132,7 @@ class ContentViewerController < ApplicationController @@ -131,7 +132,7 @@ class ContentViewerController < ApplicationController
131 end 132 end
132 133
133 unless @page.display_to?(user) 134 unless @page.display_to?(user)
134 - if !profile.visible? || profile.secret? || (user && user.follows?(profile)) 135 + if !profile.visible? || profile.secret? || (user && user.follows?(profile)) || user.blank?
135 render_access_denied 136 render_access_denied
136 else #!profile.public? 137 else #!profile.public?
137 private_profile_partial_parameters 138 private_profile_partial_parameters
app/helpers/application_helper.rb
@@ -1226,35 +1226,6 @@ module ApplicationHelper @@ -1226,35 +1226,6 @@ module ApplicationHelper
1226 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort 1226 list.sort.inject(Hash.new(0)){|h,i| h[i] += 1; h }.collect{ |x, n| [n, connector, x].join(" ") }.sort
1227 end 1227 end
1228 1228
1229 - #FIXME Use time_ago_in_words instead of this method if you're using Rails 2.2+  
1230 - def time_ago_as_sentence(from_time, include_seconds = false)  
1231 - to_time = Time.now  
1232 - from_time = Time.parse(from_time.to_s)  
1233 - from_time = from_time.to_time if from_time.respond_to?(:to_time)  
1234 - to_time = to_time.to_time if to_time.respond_to?(:to_time)  
1235 - distance_in_minutes = (((to_time - from_time).abs)/60).round  
1236 - distance_in_seconds = ((to_time - from_time).abs).round  
1237 - case distance_in_minutes  
1238 - when 0..1  
1239 - return (distance_in_minutes == 0) ? _('less than a minute') : _('1 minute') unless include_seconds  
1240 - case distance_in_seconds  
1241 - when 0..4 then _('less than 5 seconds')  
1242 - when 5..9 then _('less than 10 seconds')  
1243 - when 10..19 then _('less than 20 seconds')  
1244 - when 20..39 then _('half a minute')  
1245 - when 40..59 then _('less than a minute')  
1246 - else _('1 minute')  
1247 - end  
1248 -  
1249 - when 2..44 then _('%{distance} minutes ago') % { :distance => distance_in_minutes }  
1250 - when 45..89 then _('about 1 hour ago')  
1251 - when 90..1439 then _('about %{distance} hours ago') % { :distance => (distance_in_minutes.to_f / 60.0).round }  
1252 - when 1440..2879 then _('1 day ago')  
1253 - when 2880..10079 then _('%{distance} days ago') % { :distance => (distance_in_minutes / 1440).round }  
1254 - else show_time(from_time)  
1255 - end  
1256 - end  
1257 -  
1258 def comment_balloon(options = {}, &block) 1229 def comment_balloon(options = {}, &block)
1259 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content') 1230 wrapper = content_tag(:div, capture(&block), :class => 'comment-balloon-content')
1260 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") } 1231 (1..8).to_a.reverse.each { |i| wrapper = content_tag(:div, wrapper, :class => "comment-wrapper-#{i}") }
app/helpers/blog_helper.rb
@@ -22,7 +22,9 @@ module BlogHelper @@ -22,7 +22,9 @@ module BlogHelper
22 :param_name => 'npage', 22 :param_name => 'npage',
23 :previous_label => _('« Newer posts'), 23 :previous_label => _('« Newer posts'),
24 :next_label => _('Older posts »'), 24 :next_label => _('Older posts »'),
25 - :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} 25 + :params => {:action=>"view_page",
  26 + :page=>articles.first.parent.path.split('/'),
  27 + :controller=>"content_viewer"}
26 }) if articles.present? && conf[:paginate] 28 }) if articles.present? && conf[:paginate]
27 content = [] 29 content = []
28 artic_len = articles.length 30 artic_len = articles.length
@@ -44,7 +46,7 @@ module BlogHelper @@ -44,7 +46,7 @@ module BlogHelper
44 end 46 end
45 47
46 def display_post(article, format = 'full') 48 def display_post(article, format = 'full')
47 - no_comments = (format == 'full') ? false : true 49 + no_comments = (format == 'full' || format == 'compact' ) ? false : true
48 title = article_title(article, :no_comments => no_comments) 50 title = article_title(article, :no_comments => no_comments)
49 method = "display_#{format.split('+')[0]}_format" 51 method = "display_#{format.split('+')[0]}_format"
50 html = send(method, FilePresenter.for(article)).html_safe 52 html = send(method, FilePresenter.for(article)).html_safe
@@ -55,8 +57,12 @@ module BlogHelper @@ -55,8 +57,12 @@ module BlogHelper
55 else 57 else
56 '<div class="post-pic" style="background-image:url('+img+')"></div>' 58 '<div class="post-pic" style="background-image:url('+img+')"></div>'
57 end 59 end
58 - end.to_s +  
59 - title + html 60 + end.to_s + title + html
  61 + end
  62 +
  63 + def display_compact_format(article)
  64 + render :file => 'content_viewer/_display_compact_format',
  65 + :locals => { :article => article, :format => "compact" }
60 end 66 end
61 67
62 def display_full_format(article) 68 def display_full_format(article)
app/helpers/comment_helper.rb
1 module CommentHelper 1 module CommentHelper
  2 + include DatesHelper
2 3
3 def article_title(article, args = {}) 4 def article_title(article, args = {})
4 title = article.title 5 title = article.title
app/helpers/content_viewer_helper.rb
@@ -2,6 +2,7 @@ module ContentViewerHelper @@ -2,6 +2,7 @@ module ContentViewerHelper
2 2
3 include BlogHelper 3 include BlogHelper
4 include ForumHelper 4 include ForumHelper
  5 + include DatesHelper
5 6
6 def display_number_of_comments(n) 7 def display_number_of_comments(n)
7 base_str = "<span class='comment-count hide'>#{n}</span>" 8 base_str = "<span class='comment-count hide'>#{n}</span>"
@@ -24,8 +25,9 @@ module ContentViewerHelper @@ -24,8 +25,9 @@ module ContentViewerHelper
24 unless args[:no_comments] || !article.accept_comments 25 unless args[:no_comments] || !article.accept_comments
25 comments = (" - %s") % link_to_comments(article) 26 comments = (" - %s") % link_to_comments(article)
26 end 27 end
  28 + date_format = show_with_right_format_date article
27 title << content_tag('span', 29 title << content_tag('span',
28 - content_tag('span', show_date(article.published_at), :class => 'date') + 30 + date_format +
29 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + 31 content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
30 content_tag('span', comments, :class => 'comments'), 32 content_tag('span', comments, :class => 'comments'),
31 :class => 'created-at' 33 :class => 'created-at'
@@ -34,6 +36,24 @@ module ContentViewerHelper @@ -34,6 +36,24 @@ module ContentViewerHelper
34 title 36 title
35 end 37 end
36 38
  39 + def show_with_right_format_date article
  40 + date_format = article.environment.date_format
  41 + use_numbers = false
  42 + year = true
  43 + left_time = false
  44 + if date_format == 'numbers_with_year'
  45 + use_numbers = true
  46 + elsif date_format == 'numbers'
  47 + use_numbers = true
  48 + year = false
  49 + elsif date_format == 'month_name'
  50 + year = false
  51 + elsif date_format == 'past_time'
  52 + left_time = true
  53 + end
  54 + content_tag('span', show_date(article.published_at, use_numbers , year, left_time), :class => 'date')
  55 + end
  56 +
37 def link_to_comments(article, args = {}) 57 def link_to_comments(article, args = {})
38 return '' unless article.accept_comments? 58 return '' unless article.accept_comments?
39 reference_to_article number_of_comments(article), article, 'comments_list' 59 reference_to_article number_of_comments(article), article, 'comments_list'
app/helpers/dates_helper.rb
@@ -2,6 +2,7 @@ require &#39;noosfero/i18n&#39; @@ -2,6 +2,7 @@ require &#39;noosfero/i18n&#39;
2 2
3 module DatesHelper 3 module DatesHelper
4 4
  5 + include ActionView::Helpers::DateHelper
5 def months 6 def months
6 I18n.t('date.month_names') 7 I18n.t('date.month_names')
7 end 8 end
@@ -15,10 +16,12 @@ module DatesHelper @@ -15,10 +16,12 @@ module DatesHelper
15 end 16 end
16 17
17 # formats a date for displaying. 18 # formats a date for displaying.
18 - def show_date(date, use_numbers = false, year=true) 19 + def show_date(date, use_numbers = false, year = true, left_time = false)
19 if date && use_numbers 20 if date && use_numbers
20 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}') 21 date_format = year ? _('%{month}/%{day}/%{year}') : _('%{month}/%{day}')
21 date_format % { :day => date.day, :month => date.month, :year => date.year } 22 date_format % { :day => date.day, :month => date.month, :year => date.year }
  23 + elsif date && left_time
  24 + date_format = time_ago_in_words(date)
22 elsif date 25 elsif date
23 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}') 26 date_format = year ? _('%{month_name} %{day}, %{year}') : _('%{month_name} %{day}')
24 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year } 27 date_format % { :day => date.day, :month_name => month_name(date.month), :year => date.year }
app/helpers/events_helper.rb
1 module EventsHelper 1 module EventsHelper
2 2
  3 + include DatesHelper
3 def list_events(date, events) 4 def list_events(date, events)
4 title = _('Events for %s') % show_date_month(date) 5 title = _('Events for %s') % show_date_month(date)
5 content_tag('h2', title) + 6 content_tag('h2', title) +
app/helpers/folder_helper.rb
1 -require 'short_filename'  
2 -  
3 module FolderHelper 1 module FolderHelper
4 2
5 - include ShortFilename  
6 include ArticleHelper 3 include ArticleHelper
7 4
8 def list_contents(configure={}) 5 def list_contents(configure={})
@@ -10,8 +7,8 @@ module FolderHelper @@ -10,8 +7,8 @@ module FolderHelper
10 configure[:list_type] ||= :folder 7 configure[:list_type] ||= :folder
11 if !configure[:contents].blank? 8 if !configure[:contents].blank?
12 configure[:contents] = configure[:contents].paginate( 9 configure[:contents] = configure[:contents].paginate(
13 - :order => "updated_at DESC",  
14 - :per_page => 10, 10 + :order => "name ASC",
  11 + :per_page => 30,
15 :page => params[:npage] 12 :page => params[:npage]
16 ) 13 )
17 14
@@ -25,49 +22,32 @@ module FolderHelper @@ -25,49 +22,32 @@ module FolderHelper
25 articles.select {|article| article.display_to?(user)} 22 articles.select {|article| article.display_to?(user)}
26 end 23 end
27 24
28 - def display_content_in_listing(configure={})  
29 - recursive = configure[:recursive] || false  
30 - list_type = configure[:list_type] || :folder  
31 - level = configure[:level] || 0  
32 - content = FilePresenter.for configure[:content] 25 + def display_content_icon(content_item)
  26 + content = FilePresenter.for content_item
33 content_link = if content.image? 27 content_link = if content.image?
34 - link_to('&nbsp;' * (level * 4) +  
35 - image_tag(icon_for_article(content)) + short_filename(content.name), 28 + link_to(
  29 + image_tag(icon_for_article(content, :bigicon)),
36 content.url.merge(:view => true) 30 content.url.merge(:view => true)
37 ) 31 )
38 else 32 else
39 - link_to('&nbsp;' * (level * 4) +  
40 - short_filename(content.name),  
41 - content.url.merge(:view => true), :class => icon_for_article(content) 33 + link_to('',
  34 + content.url.merge(:view => true),
  35 + :class => icon_for_article(content, :bigicon)
42 ) 36 )
43 end 37 end
44 - result = content_tag(  
45 - 'tr',  
46 - content_tag('td', content_link ) +  
47 - content_tag('td', show_date(content.updated_at), :class => 'last-update'),  
48 - :class => "#{list_type}-item"  
49 - )  
50 - if recursive  
51 - result + content.children.map {|item|  
52 - display_content_in_listing :content=>item, :recursive=>recursive,  
53 - :list_type=>list_type, :level=>level+1  
54 - }.join("\n")  
55 - else  
56 - result  
57 - end  
58 end 38 end
59 39
60 - def icon_for_article(article) 40 + def icon_for_article(article, size = 'icon')
61 article = FilePresenter.for article 41 article = FilePresenter.for article
62 - icon = article.respond_to?(:icon_name) ?  
63 - article.icon_name :  
64 - article.class.icon_name(article)  
65 - if (icon =~ /\//)  
66 - icon 42 + if article.respond_to?(:sized_icon)
  43 + article.sized_icon(size)
67 else 44 else
68 - klasses = 'icon ' + [icon].flatten.map{|name| 'icon-'+name}.join(' ') 45 + icon = article.respond_to?(:icon_name) ?
  46 + article.icon_name :
  47 + article.class.icon_name(article)
  48 + klasses = "#{size} " + [icon].flatten.map{|name| "#{size}-"+name}.join(' ')
69 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter) 49 if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter)
70 - klasses += ' icon-upload-file' 50 + klasses += " #{size}-upload-file"
71 end 51 end
72 klasses 52 klasses
73 end 53 end
app/helpers/forum_helper.rb
1 module ForumHelper 1 module ForumHelper
  2 + include ActionView::Helpers::DateHelper
2 3
3 def cms_label_for_new_children 4 def cms_label_for_new_children
4 _('New discussion topic') 5 _('New discussion topic')
@@ -42,9 +43,9 @@ module ForumHelper @@ -42,9 +43,9 @@ module ForumHelper
42 def last_topic_update(article) 43 def last_topic_update(article)
43 info = article.info_from_last_update 44 info = article.info_from_last_update
44 if info[:author_url] 45 if info[:author_url]
45 - time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url]) 46 + time_ago_in_words(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url])
46 else 47 else
47 - time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + info[:author_name] 48 + time_ago_in_words(info[:date]) + ' ' + _('by') + ' ' + info[:author_name]
48 end 49 end
49 end 50 end
50 51
app/helpers/manage_products_helper.rb
@@ -75,9 +75,12 @@ module ManageProductsHelper @@ -75,9 +75,12 @@ module ManageProductsHelper
75 end 75 end
76 76
77 def categories_container(categories_selection_html, hierarchy_html = '') 77 def categories_container(categories_selection_html, hierarchy_html = '')
78 - hidden_field_tag('selected_category_id') +  
79 - content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +  
80 - content_tag('div', categories_selection_html, :id => 'categories_container_wrapper') 78 + content_tag 'div',
  79 + render('categories_autocomplete') +
  80 + hidden_field_tag('selected_category_id') +
  81 + content_tag('div', hierarchy_html, :id => 'hierarchy_navigation') +
  82 + content_tag('div', categories_selection_html, :id => 'categories_container_wrapper'),
  83 + :id => 'categories-container'
81 end 84 end
82 85
83 def select_for_categories(categories, level = 0) 86 def select_for_categories(categories, level = 0)
app/models/article.rb
@@ -28,7 +28,7 @@ class Article &lt; ActiveRecord::Base @@ -28,7 +28,7 @@ class Article &lt; ActiveRecord::Base
28 def initialize(*params) 28 def initialize(*params)
29 super 29 super
30 30
31 - if !params.blank? && params.first.has_key?(:profile) 31 + if !params.blank? && params.first.has_key?(:profile) && !params.first[:profile].blank?
32 profile = params.first[:profile] 32 profile = params.first[:profile]
33 self.published = false unless profile.public? 33 self.published = false unless profile.public?
34 end 34 end
app/models/blog.rb
@@ -76,9 +76,12 @@ class Blog &lt; Folder @@ -76,9 +76,12 @@ class Blog &lt; Folder
76 end 76 end
77 77
78 settings_items :visualization_format, :type => :string, :default => 'full' 78 settings_items :visualization_format, :type => :string, :default => 'full'
79 - validates_inclusion_of :visualization_format, :in => [ 'full', 'short', 'short+pic' ], :if => :visualization_format 79 + validates_inclusion_of :visualization_format,
  80 + :in => [ 'full', 'short', 'short+pic', 'compact'],
  81 + :if => :visualization_format
80 82
81 - settings_items :display_posts_in_current_language, :type => :boolean, :default => false 83 + settings_items :display_posts_in_current_language,
  84 + :type => :boolean, :default => false
82 85
83 alias :display_posts_in_current_language? :display_posts_in_current_language 86 alias :display_posts_in_current_language? :display_posts_in_current_language
84 87
app/models/environment.rb
@@ -3,7 +3,17 @@ @@ -3,7 +3,17 @@
3 # domains. 3 # domains.
4 class Environment < ActiveRecord::Base 4 class Environment < ActiveRecord::Base
5 5
6 - attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound, :noreply_email, :signup_welcome_screen_body, :members_whitelist_enabled, :members_whitelist, :highlighted_news_amount, :portal_news_amount 6 + attr_accessible :name, :is_default, :signup_welcome_text_subject,
  7 + :signup_welcome_text_body, :terms_of_use,
  8 + :message_for_disabled_enterprise, :news_amount_by_folder,
  9 + :default_language, :languages, :description,
  10 + :organization_approval_method, :enabled_plugins,
  11 + :enabled_features, :redirection_after_login,
  12 + :redirection_after_signup, :contact_email, :theme,
  13 + :reports_lower_bound, :noreply_email,
  14 + :signup_welcome_screen_body, :members_whitelist_enabled,
  15 + :members_whitelist, :highlighted_news_amount,
  16 + :portal_news_amount, :date_format
7 17
8 has_many :users 18 has_many :users
9 19
@@ -14,6 +24,12 @@ class Environment &lt; ActiveRecord::Base @@ -14,6 +24,12 @@ class Environment &lt; ActiveRecord::Base
14 24
15 IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/ 25 IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/
16 26
  27 + validates_inclusion_of :date_format,
  28 + :in => [ 'numbers_with_year', 'numbers',
  29 + 'month_name_with_year', 'month_name',
  30 + 'past_time'],
  31 + :if => :date_format
  32 +
17 def self.verify_filename(filename) 33 def self.verify_filename(filename)
18 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS 34 filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS
19 filename 35 filename
app/models/profile.rb
@@ -1006,19 +1006,11 @@ private :generate_url, :url_options @@ -1006,19 +1006,11 @@ private :generate_url, :url_options
1006 self.save 1006 self.save
1007 end 1007 end
1008 1008
1009 - def disabled?  
1010 - !visible  
1011 - end  
1012 -  
1013 def enable 1009 def enable
1014 self.visible = true 1010 self.visible = true
1015 self.save 1011 self.save
1016 end 1012 end
1017 1013
1018 - def enabled?  
1019 - visible  
1020 - end  
1021 -  
1022 def control_panel_settings_button 1014 def control_panel_settings_button
1023 {:title => _('Edit Profile'), :icon => 'edit-profile'} 1015 {:title => _('Edit Profile'), :icon => 'edit-profile'}
1024 end 1016 end
app/models/uploaded_file.rb
1 -require 'short_filename'  
2 -  
3 # Article type that handles uploaded files. 1 # Article type that handles uploaded files.
4 # 2 #
5 # Limitation: only file metadata are versioned. Only the latest version 3 # Limitation: only file metadata are versioned. Only the latest version
@@ -14,8 +12,6 @@ class UploadedFile &lt; Article @@ -14,8 +12,6 @@ class UploadedFile &lt; Article
14 12
15 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent 13 track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :parent
16 14
17 - include ShortFilename  
18 -  
19 def title 15 def title
20 if self.name.present? then self.name else self.filename end 16 if self.name.present? then self.name else self.filename end
21 end 17 end
@@ -65,7 +61,7 @@ class UploadedFile &lt; Article @@ -65,7 +61,7 @@ class UploadedFile &lt; Article
65 # :min_size => 2.megabytes 61 # :min_size => 2.megabytes
66 # :max_size => 5.megabytes 62 # :max_size => 5.megabytes
67 has_attachment :storage => :file_system, 63 has_attachment :storage => :file_system,
68 - :thumbnails => { :icon => [24,24], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' }, 64 + :thumbnails => { :icon => [24,24], :bigicon => [50,50], :thumb => '130x130>', :slideshow => '320x240>', :display => '640X480>' },
69 :thumbnail_class => Thumbnail, 65 :thumbnail_class => Thumbnail,
70 :max_size => self.max_size 66 :max_size => self.max_size
71 67
app/presenters/image.rb
@@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter @@ -4,6 +4,10 @@ class FilePresenter::Image &lt; FilePresenter
4 f.image? ? 10 : nil 4 f.image? ? 10 : nil
5 end 5 end
6 6
  7 + def sized_icon(size)
  8 + public_filename size
  9 + end
  10 +
7 def icon_name 11 def icon_name
8 public_filename :icon 12 public_filename :icon
9 end 13 end
app/views/admin_panel/_site_info.html.erb
@@ -3,6 +3,21 @@ @@ -3,6 +3,21 @@
3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %> 3 <%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %> 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %> 5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %>
  6 +
  7 +<%= labelled_form_field(
  8 + _("Article's date format"),
  9 + select(:environment, :date_format,
  10 + options_for_select([
  11 + [ _('mm/dd/yyyy'), 'numbers_with_year'],
  12 + [ _('mm/dd'), 'numbers'],
  13 + [ _('Month dd, yyyy'), 'month_name_with_year'],
  14 + [ _('Month dd'), 'month_name'],
  15 + [ _('X minutes/hours/days/months/years ago'), 'past_time']
  16 + ], environment.date_format
  17 + )
  18 + )
  19 +) %>
  20 +
6 <%= required f.text_field(:reports_lower_bound, :size => 3) %> 21 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
7 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %> 22 <%= labelled_form_field(_('Default language'), select(:environment, :default_language, environment.locales.invert, { :selected => environment.default_locale, :include_blank => true })) %>
8 <%= label_tag :languages, _('Available languages') %> 23 <%= label_tag :languages, _('Available languages') %>
app/views/cms/_blog.html.erb
@@ -67,7 +67,8 @@ @@ -67,7 +67,8 @@
67 <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [ 67 <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [
68 [ _('Full post'), 'full'], 68 [ _('Full post'), 'full'],
69 [ _('First paragraph'), 'short'], 69 [ _('First paragraph'), 'short'],
70 - [ _('First paragraph, with post picture'), 'short+pic'] 70 + [ _('First paragraph, with post picture'), 'short+pic'],
  71 + [ _("Title, Image, Lead"), 'compact']
71 ])) %> 72 ])) %>
72 73
73 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %> 74 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Blog.posts_per_page_options)) %>
app/views/cms/_view_items.html.erb 0 → 100644
@@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
  1 +<% @articles.each do |article| article = FilePresenter.for article %>
  2 + <tr title="<%= article.title%>" >
  3 + <td class="article-name">
  4 + <%= link_to_article(article) %>
  5 + </td>
  6 + <% short_description = article.respond_to?(:short_description) ?
  7 + article.short_description :
  8 + article.class.short_description %>
  9 + <td class="article-mime" title=<%= short_description.to_json %>>
  10 + <%= short_description %>
  11 + </td>
  12 + <td class="last-update">
  13 + <%= time_ago_in_words article.updated_at %>
  14 + </td>
  15 + <td class="article-controls">
  16 + <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>
  17 + <%= button_without_text :eyes, _('Public view'), article.view_url %>
  18 + <%= display_spread_button(article) unless remove_content_button(:spread, article) %>
  19 + <% if user.can_change_homepage? && !remove_content_button(:home, article) %>
  20 + <% if profile.home_page != article %>
  21 + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  22 + <% else %>
  23 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  24 + <% end %>
  25 + <% end %>
  26 + <%= display_delete_button(article) if !remove_content_button(:delete, article) %>
  27 + </td>
  28 + </tr>
  29 +<% end %>
app/views/cms/view.html.erb
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 <tr> 37 <tr>
38 <th><%= _('Name') %></th> 38 <th><%= _('Name') %></th>
39 <th><%= _('Type') %></th> 39 <th><%= _('Type') %></th>
  40 + <th><%= _('Last update') %></th>
40 <th><%= _('Actions') %></th> 41 <th><%= _('Actions') %></th>
41 </tr> 42 </tr>
42 43
@@ -54,32 +55,7 @@ @@ -54,32 +55,7 @@
54 </tr> 55 </tr>
55 <% end %> 56 <% end %>
56 57
57 - <% @articles.each do |article| article = FilePresenter.for article %>  
58 - <tr title="<%= article.title%>" >  
59 - <td class="article-name">  
60 - <%= link_to_article(article) %>  
61 - </td>  
62 - <% short_description = article.respond_to?(:short_description) ?  
63 - article.short_description :  
64 - article.class.short_description %>  
65 - <td class="article-mime" title=<%= short_description.to_json %>>  
66 - <%= short_description %>  
67 - </td>  
68 - <td class="article-controls">  
69 - <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>  
70 - <%= button_without_text :eyes, _('Public view'), article.view_url %>  
71 - <%= display_spread_button(article) unless remove_content_button(:spread, article) %>  
72 - <% if user.can_change_homepage? && !remove_content_button(:home, article) %>  
73 - <% if profile.home_page != article %>  
74 - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>  
75 - <% else %>  
76 - <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>  
77 - <% end %>  
78 - <% end %>  
79 - <%= display_delete_button(article) if !remove_content_button(:delete, article) %>  
80 - </td>  
81 - </tr>  
82 - <% end %> 58 + <%= render 'view_items' %>
83 59
84 </table> 60 </table>
85 61
app/views/content_viewer/_display_compact_format.html.erb 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +<% if article.image %>
  2 + <% className = "article-compact-abstract-with-image" %>
  3 + <% if article.image.thumbnails_processed? %>
  4 + <% image_file = article.image.public_filename(:big) %>
  5 + <% else %>
  6 + <% image_file = "/images/icons-app/image-loading-thumb.png" %>
  7 + <% end %>
  8 +<% else %>
  9 + <% className = "article-compact-abstract" %>
  10 +<% end %>
  11 +
  12 +<div>
  13 + <% if article.image %>
  14 + <div class = "article-compact-image">
  15 + <%= image_tag(image_file) %>
  16 + </div>
  17 + <% end %>
  18 + <div class = <%= className %> >
  19 + <%= article.abstract.truncate(400) %>
  20 + </div>
  21 +</div>
app/views/content_viewer/blog_page.html.erb
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
8 </div> 8 </div>
9 </div> 9 </div>
10 <hr class="pre-posts"/> 10 <hr class="pre-posts"/>
11 -<div class="blog-posts"> 11 +<div class="blog-posts page-<%= @npage %>">
12 <% paginate = true %> 12 <% paginate = true %>
13 <%= 13 <%=
14 posts = @posts 14 posts = @posts
app/views/content_viewer/folder.html.erb
1 <% unless folder.body.blank? %> 1 <% unless folder.body.blank? %>
2 - <div> 2 + <div class="folder-description">
3 <%= folder.body %> 3 <%= folder.body %>
4 </div> 4 </div>
5 - <hr/>  
6 <% end %> 5 <% end %>
7 6
8 <% if folder.children.empty? %> 7 <% if folder.children.empty? %>
app/views/manage_products/_categories_autocomplete.html.erb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%= text_field_tag 'product_category_id', '', :placeholder => _('type a category for the product') %>
  2 +
  3 +<%= javascript_include_tag '/javascripts/product_categories.js' %>
  4 +<% javascript_tag do %>
  5 + product_categories.autocomplete.search_url = <%= url_for(:controller => :manage_products, :action => :search_categories).to_json %>
  6 + product_categories.autocomplete.select_url = <%= url_for(:controller => :manage_products, :action => :show_category_tree).to_json %>
  7 + product_categories.autocomplete.load('#product_category_id')
  8 +<% end %>
app/views/manage_products/_selected_category_tree.html.erb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +<%= categories_container selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true) %>
  2 +
app/views/manage_products/edit_category.html.erb
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 16
17 <h3><%= _('Edit category of this product:') %></h3> 17 <h3><%= _('Edit category of this product:') %></h3>
18 18
19 - <%= categories_container(selects_for_all_ancestors(@category), hierarchy_category_navigation(@category, :make_links => true)) %> 19 + <%= render 'manage_products/selected_category_tree' %>
20 20
21 <div id='categories_selection_actionbar'> 21 <div id='categories_selection_actionbar'>
22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %> 22 <%= button(:back, _('Back to product'), :action => 'show', :id => @product) %>
app/views/person_notifier/mailer/_comment.html.erb
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 <span style="font-size: 12px;"><%= comment.title %></span><br/> 19 <span style="font-size: 12px;"><%= comment.title %></span><br/>
20 <% end %> 20 <% end %>
21 <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/> 21 <span style="font-size: 10px;"><%= txt2html comment.body %></span><br/>
22 - <span style="font-size: 8px; color: #929292"><%= time_ago_as_sentence(comment.created_at) %></span> 22 + <span style="font-size: 8px; color: #929292"><%= time_ago_in_words(comment.created_at) %></span>
23 <br style="clear: both;" /> 23 <br style="clear: both;" />
24 24
25 <% unless comment.replies.blank? %> 25 <% unless comment.replies.blank? %>
app/views/person_notifier/mailer/_create_article.html.erb
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.short_name(20), activity.user.url %></span>
8 <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span> 8 <span style="font-size: 14px;"><%= _("has published on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url, :style => "color: #333; font-weight: bold; text-decoration: none;") if activity.target.profile.is_a?(Community) %></span>
9 - <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> 9 + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_in_words(activity.created_at) %></span>
10 </p> 10 </p>
11 <p> 11 <p>
12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span> 12 <span style="font-size: 14px;"><%= link_to(activity.params['name'], activity.params['url'], :style => "color: #333; font-weight: bold; text-decoration: none;") %></span>
app/views/person_notifier/mailer/_default_activity.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <td> 5 <td>
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
8 - <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(activity.created_at) %></span> 8 + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(activity.created_at) %></span>
9 </p> 9 </p>
10 </td> 10 </td>
11 </tr> 11 </tr>
app/views/person_notifier/mailer/_task.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <span style="font-size: 14px"> 12 <span style="font-size: 14px">
13 <%= task_information(task) %> 13 <%= task_information(task) %>
14 </span> 14 </span>
15 - <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_as_sentence(task.created_at) %></span> 15 + <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(task.created_at) %></span>
16 </div> 16 </div>
17 </td> 17 </td>
18 </tr> 18 </tr>
app/views/person_notifier/mailer/_upload_image.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <td> 5 <td>
6 <p> 6 <p>
7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> 7 <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span>
8 - <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_as_sentence(activity.created_at) %></span> 8 + <span style="font-size: 10px; color: #929292; float:right;"><%= time_ago_in_words(activity.created_at) %></span>
9 </p> 9 </p>
10 </td> 10 </td>
11 </tr> 11 </tr>
app/views/profile/_comment.html.erb
@@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
40 <%= txt2html comment.body %> 40 <%= txt2html comment.body %>
41 </div> 41 </div>
42 <div class="profile-activity-time"> 42 <div class="profile-activity-time">
43 - <%= time_ago_as_sentence(comment.created_at) %> 43 + <%= time_ago_in_words(comment.created_at) %>
44 </div> 44 </div>
45 </div> 45 </div>
46 46
app/views/profile/_create_article.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small> 12 <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).gsub(/(\xC2\xA0|\s)+/, ' ').gsub(/^\s+/, '') unless activity.params['lead'].blank? %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small>
13 </div> 13 </div>
14 <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %> 14 <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %>
15 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 15 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
16 <div class='profile-wall-actions'> 16 <div class='profile-wall-actions'>
17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %> 17 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
18 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :only_hide => true, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 18 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :only_hide => true, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
app/views/profile/_default_activity.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 </div> 3 </div>
4 <div class='profile-activity-description'> 4 <div class='profile-activity-description'>
5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
6 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 6 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
7 <div class='profile-wall-actions'> 7 <div class='profile-wall-actions'>
8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %> 8 <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
app/views/profile/_leave_scrap.html.erb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 </div> 3 </div>
4 <div class='profile-activity-description'> 4 <div class='profile-activity-description'>
5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 5 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
6 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 6 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
7 <div class='profile-wall-actions'> 7 <div class='profile-wall-actions'>
8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
9 </div> 9 </div>
app/views/profile/_profile_scrap.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 <p class='profile-activity-text'><%= txt2html scrap.content %></p> 7 <p class='profile-activity-text'><%= txt2html scrap.content %></p>
8 - <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> 8 + <p class='profile-activity-time'><%= time_ago_in_words(scrap.created_at) %></p>
9 <div class='profile-wall-actions'> 9 <div class='profile-wall-actions'>
10 <% if logged_in? && current_person.follows?(scrap.sender) %> 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 <span class='profile-activity-send-reply'> 11 <span class='profile-activity-send-reply'>
@@ -22,5 +22,5 @@ @@ -22,5 +22,5 @@
22 <% end %> 22 <% end %>
23 </ul> 23 </ul>
24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %> 24 <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
25 - <hr /> 25 + <hr />
26 </li> 26 </li>
app/views/profile/_profile_scraps.html.erb
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 6 <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
7 <p class='profile-activity-text'><%= txt2html scrap.content %></p> 7 <p class='profile-activity-text'><%= txt2html scrap.content %></p>
8 - <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p> 8 + <p class='profile-activity-time'><%= time_ago_in_words(scrap.created_at) %></p>
9 <div class='profile-wall-actions'> 9 <div class='profile-wall-actions'>
10 <% if logged_in? && current_person.follows?(scrap.sender) %> 10 <% if logged_in? && current_person.follows?(scrap.sender) %>
11 <span class='profile-activity-send-reply'> 11 <span class='profile-activity-send-reply'>
app/views/profile/_upload_image.html.erb
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 </div> 4 </div>
5 <div class='profile-activity-description'> 5 <div class='profile-activity-description'>
6 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p> 6 <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
7 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p> 7 + <p class='profile-activity-time'><%= time_ago_in_words(activity.created_at) %></p>
8 <div class='profile-wall-actions'> 8 <div class='profile-wall-actions'>
9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
10 </div> 10 </div>
app/views/shared/_content_item.html.erb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<div id="list-item">
  2 + <div class="item-info">
  3 + <div class="item-icon" >
  4 + <%= display_content_icon(content) %>
  5 + </div>
  6 + <span class="item-description">
  7 + <%= link_to(content.name, content.url) %>
  8 + </span>
  9 + <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span>
  10 + </div>
  11 +</div>
app/views/shared/_lead_and_body.html.erb
@@ -19,17 +19,27 @@ @@ -19,17 +19,27 @@
19 19
20 <div class='article-lead' id="article-lead-<%=lead_id.to_s%>"> 20 <div class='article-lead' id="article-lead-<%=lead_id.to_s%>">
21 21
  22 + <% abstract_options = {:style => 'width: 100%; height: 200px;', :class => editor_type} %>
22 <% if f %> 23 <% if f %>
23 - <%= labelled_form_field(_(abstract_label), f.text_area(abstract_method, :style => 'width: 100%; height: 200px;', :class => editor_type)) %> 24 + <%= labelled_form_field(_(abstract_label), f.text_area(abstract_method, abstract_options)) %>
24 <% else %> 25 <% else %>
25 - <%= labelled_form_field(_(abstract_label), text_area(object, abstract_method, :style => 'width: 100%; height: 200px;', :class => editor_type)) %> 26 + <% if @article.kind_of?(Article) %>
  27 + <%= labelled_form_field(_(abstract_label), text_area_tag("article[abstract]", @escaped_abstract, abstract_options)) %>
  28 + <% else %>
  29 + <%= labelled_form_field(_(abstract_label), text_area(object, abstract_method, abstract_options)) %>
  30 + <% end %>
26 <% end %> 31 <% end %>
27 </div> 32 </div>
28 <div style="margin-top: 10px;"> 33 <div style="margin-top: 10px;">
  34 + <% body_options = {:style => 'width: 100%; height: 400px;', :class => editor_type} %>
29 <% if f %> 35 <% if f %>
30 - <%= labelled_form_field(_(body_label), f.text_area(body_method, :style => 'width: 100%; height: 400px;', :class => editor_type)) %> 36 + <%= labelled_form_field(_(body_label), f.text_area(body_method, body_options)) %>
31 <% else %> 37 <% else %>
32 - <%= labelled_form_field(_(body_label), text_area(object, body_method, :style => 'width: 100%; height: 400px;', :class => editor_type)) %> 38 + <% if @article.kind_of?(Article) %>
  39 + <%= labelled_form_field(_(body_label), text_area_tag("article[body]", @escaped_body, body_options)) %>
  40 + <% else %>
  41 + <%= labelled_form_field(_(body_label), text_area(object, body_method, body_options)) %>
  42 + <% end %>
33 <% end %> 43 <% end %>
34 </div> 44 </div>
35 45
app/views/shared/content_list.html.erb
1 -<table class="<%= list_type %>-content">  
2 - <tr>  
3 - <th><%= _('Title') %></th>  
4 - <th><%= _('Last update') %></th>  
5 - </tr> 1 +<ul class="<%= list_type %>-content">
6 <% contents.each do |content| %> 2 <% 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 %> 3 + <li class="<%= list_type %>-item">
  4 + <% if content.display_to?(user) %>
  5 + <%= render :partial => 'shared/content_item', :locals => { :content => content } %>
  6 + <% end %>
  7 + </li>
10 <% end %> 8 <% end %>
11 -</table> 9 +</ul>
12 10
13 <p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p> 11 <p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p>
app/views/tasks/_abuse_complaint_accept_details.html.erb
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <% task.abuse_reports.each do |abuse_report| %> 2 <% task.abuse_reports.each do |abuse_report| %>
3 <div> 3 <div>
4 <strong style="word-wrap: break-word; display: block; padding-right: 40px">"<%= abuse_report.reason %>"</strong> <br /> 4 <strong style="word-wrap: break-word; display: block; padding-right: 40px">"<%= abuse_report.reason %>"</strong> <br />
5 - <i><%= _('Reported by %{reporter} %{time}.') % {:reporter => abuse_report.reporter.name, :time => time_ago_as_sentence(abuse_report.created_at) }%></i> <br /> 5 + <i><%= _('Reported by %{reporter} %{time}.') % {:reporter => abuse_report.reporter.name, :time => time_ago_in_words(abuse_report.created_at) }%></i> <br />
6 <% if !abuse_report.content.blank? %> 6 <% if !abuse_report.content.blank? %>
7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button> 7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button>
8 <div style='display: none' id=<%= 'abuse-report-details-'+abuse_report.id.to_s %> class="abuse-report-details"> 8 <div style='display: none' id=<%= 'abuse-report-details-'+abuse_report.id.to_s %> class="abuse-report-details">
config/initializers/noosfero_extensions.rb
1 require 'noosfero/role_assignment_ext' 1 require 'noosfero/role_assignment_ext'
2 require 'noosfero/action_tracker_ext' 2 require 'noosfero/action_tracker_ext'
  3 +require 'noosfero/vote_ext'
db/migrate/20140708123314_index_role_assignments_filtered_fields.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +class IndexRoleAssignmentsFilteredFields < ActiveRecord::Migration
  2 +
  3 + def self.up
  4 + add_index :role_assignments, [:accessor_id, :accessor_type]
  5 + add_index :role_assignments, [:accessor_id, :accessor_type, :role_id], name: :index_on_role_assigments_accessor_role
  6 + add_index :role_assignments, [:resource_id, :resource_type]
  7 + add_index :role_assignments, [:resource_id, :resource_type, :role_id], name: :index_on_role_assigments_resource_role
  8 + add_index :role_assignments, [:accessor_id, :accessor_type, :resource_id, :resource_type], name: :index_on_role_assigments_accessor_resource_role
  9 + add_index :profiles, [:type]
  10 + add_index :profiles, [:visible]
  11 + add_index :profiles, [:enabled]
  12 + add_index :profiles, [:validated]
  13 + end
  14 +
  15 +end
db/migrate/20150423203352_fix_tags_case_differences.rb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +class FixTagsCaseDifferences < ActiveRecord::Migration
  2 + def up
  3 + tags = ActsAsTaggableOn::Tag.joins('LEFT JOIN tags as b on LOWER(tags.name) = b.name').where('b.id is null')
  4 + tags.find_each do |tag|
  5 + unless ActsAsTaggableOn::Tag.exists?(:name => tag.name.mb_chars.downcase)
  6 + ActsAsTaggableOn::Tag.create(:name => tag.name.mb_chars.downcase)
  7 + end
  8 + end
  9 +
  10 + execute("UPDATE taggings SET tag_id = new.id FROM taggings AS t INNER JOIN tags AS old ON t.tag_id = old.id INNER JOIN tags AS new ON LOWER(old.name) = new.name WHERE old.id != new.id AND taggings.id = t.id")
  11 +
  12 + execute("UPDATE tags SET taggings_count = (SELECT COUNT(*) FROM taggings WHERE taggings.tag_id = tags.id)")
  13 + execute("DELETE FROM tags WHERE taggings_count = 0")
  14 + end
  15 +
  16 + def down
  17 + say 'This migration is irreversible.'
  18 + end
  19 +end
db/migrate/20150529180110_add_date_format_to_environment.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddDateFormatToEnvironment < ActiveRecord::Migration
  2 + def up
  3 + add_column :environments, :date_format, :string, :default => 'month_name_with_year'
  4 + end
  5 +
  6 + def down
  7 + remove_column :environments, :date_format
  8 + end
  9 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20150525101430) do 14 +ActiveRecord::Schema.define(:version => 20150602142030) do
15 15
16 create_table "abuse_reports", :force => true do |t| 16 create_table "abuse_reports", :force => true do |t|
17 t.integer "reporter_id" 17 t.integer "reporter_id"
@@ -321,17 +321,18 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do @@ -321,17 +321,18 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do
321 t.text "design_data" 321 t.text "design_data"
322 t.text "custom_header" 322 t.text "custom_header"
323 t.text "custom_footer" 323 t.text "custom_footer"
324 - t.string "theme", :default => "default", :null => false 324 + t.string "theme", :default => "default", :null => false
325 t.text "terms_of_use_acceptance_text" 325 t.text "terms_of_use_acceptance_text"
326 t.datetime "created_at" 326 t.datetime "created_at"
327 t.datetime "updated_at" 327 t.datetime "updated_at"
328 - t.integer "reports_lower_bound", :default => 0, :null => false 328 + t.integer "reports_lower_bound", :default => 0, :null => false
329 t.string "redirection_after_login", :default => "keep_on_same_page" 329 t.string "redirection_after_login", :default => "keep_on_same_page"
330 t.text "signup_welcome_text" 330 t.text "signup_welcome_text"
331 t.string "languages" 331 t.string "languages"
332 t.string "default_language" 332 t.string "default_language"
333 t.string "noreply_email" 333 t.string "noreply_email"
334 t.string "redirection_after_signup", :default => "keep_on_same_page" 334 t.string "redirection_after_signup", :default => "keep_on_same_page"
  335 + t.string "date_format", :default => "month_name_with_year"
335 end 336 end
336 337
337 create_table "external_feeds", :force => true do |t| 338 create_table "external_feeds", :force => true do |t|
@@ -692,6 +693,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do @@ -692,6 +693,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150525101430) do
692 t.integer "image_id" 693 t.integer "image_id"
693 t.boolean "spam", :default => false 694 t.boolean "spam", :default => false
694 t.integer "responsible_id" 695 t.integer "responsible_id"
  696 + t.integer "closed_by_id"
695 end 697 end
696 698
697 add_index "tasks", ["requestor_id"], :name => "index_tasks_on_requestor_id" 699 add_index "tasks", ["requestor_id"], :name => "index_tasks_on_requestor_id"
features/approve_article.feature
@@ -62,7 +62,8 @@ Feature: approve article @@ -62,7 +62,8 @@ Feature: approve article
62 And I press "Spread this" 62 And I press "Spread this"
63 And I follow "Delete" 63 And I follow "Delete"
64 And I confirm the browser dialog 64 And I confirm the browser dialog
65 - When I am logged in as "joaosilva" 65 + And I follow "Logout"
  66 + And I am logged in as "joaosilva"
66 And I go to sample-community's control panel 67 And I go to sample-community's control panel
67 And I follow "Process requests" 68 And I follow "Process requests"
68 And I choose "Reject" 69 And I choose "Reject"
features/article_visualization.feature 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +Feature: article visualization
  2 + As a user
  3 + I want to change view modes
  4 + In order to see articles in fullscreen or not in fullscreen
  5 +
  6 + Background:
  7 + Given the following users
  8 + | login | name |
  9 + | joaosilva | Joao Silva |
  10 + And "joaosilva" has no articles
  11 + And the following articles
  12 + | owner | name | body |
  13 + | joaosilva | Sample Article | This is an article |
  14 + And I am logged in as "joaosilva"
  15 +
  16 + @selenium
  17 + Scenario: viewing the article in fullscreen by default
  18 + Given I go to /joaosilva/sample-article?fullscreen=1
  19 + Then I should see "Exit full screen"
  20 +
  21 + @selenium
  22 + Scenario: viewing the article not in fullscreen by default
  23 + Given I go to /joaosilva/sample-article
  24 + Then I should see "Full screen"
  25 +
  26 + @selenium
  27 + Scenario: changing the view mode from not in fullscreen to fullscreen
  28 + Given I go to /joaosilva/sample-article
  29 + And I follow "Full screen"
  30 + Then I should see "Exit full screen"
features/balloon.feature
@@ -41,19 +41,19 @@ Feature: balloon @@ -41,19 +41,19 @@ Feature: balloon
41 @selenium 41 @selenium
42 Scenario: I should not see trigger if not enabled on page 42 Scenario: I should not see trigger if not enabled on page
43 Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment 43 Given feature "show_balloon_with_profile_links_when_clicked" is disabled on environment
44 - When I go to /assets/people 44 + When I go to /search/people
45 Then I should not see "Profile links" 45 Then I should not see "Profile links"
46 46
47 @selenium 47 @selenium
48 Scenario: I should not see trigger by default on page 48 Scenario: I should not see trigger by default on page
49 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment 49 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
50 - When I go to /assets/communities 50 + When I go to /search/communities
51 Then I should not see "Members" 51 Then I should not see "Members"
52 52
53 @selenium 53 @selenium
54 Scenario: I should see balloon when clicked on page trigger 54 Scenario: I should see balloon when clicked on page trigger
55 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment 55 Given feature "show_balloon_with_profile_links_when_clicked" is enabled on environment
56 - And I go to /assets/communities 56 + And I go to /search/communities
57 And display ".community-trigger" 57 And display ".community-trigger"
58 When I follow "Profile links" 58 When I follow "Profile links"
59 Then I should see "Members" 59 Then I should see "Members"
features/browse_enterprises.feature
@@ -13,20 +13,20 @@ Scenario: show all enterprises @@ -13,20 +13,20 @@ Scenario: show all enterprises
13 Given the following enterprises 13 Given the following enterprises
14 | identifier | name | 14 | identifier | name |
15 | shop2 | Fruits Shop | 15 | shop2 | Fruits Shop |
16 - Given I am on /assets/enterprises 16 + Given I am on /search/enterprises
17 Then I should see "Enterprises" 17 Then I should see "Enterprises"
18 And I should see "Shoes Shop" 18 And I should see "Shoes Shop"
19 And I should see "Fruits Shop" 19 And I should see "Fruits Shop"
20 20
21 Scenario: show profile links button 21 Scenario: show profile links button
22 - Given I am on /assets/enterprises 22 + Given I am on /search/enterprises
23 Then I should see "Profile links" within "a.enterprise-trigger" 23 Then I should see "Profile links" within "a.enterprise-trigger"
24 And I should not see "Members" 24 And I should not see "Members"
25 And I should not see "Agenda" 25 And I should not see "Agenda"
26 26
27 @selenium-fixme 27 @selenium-fixme
28 Scenario: show profile links when clicked 28 Scenario: show profile links when clicked
29 - Given I am on /assets/enterprises 29 + Given I am on /search/enterprises
30 When I follow "Profile links" 30 When I follow "Profile links"
31 Then I should see "Products" within "ul.menu-submenu-list" 31 Then I should see "Products" within "ul.menu-submenu-list"
32 And I should see "Members" within "ul.menu-submenu-list" 32 And I should see "Members" within "ul.menu-submenu-list"
@@ -34,7 +34,7 @@ Scenario: show profile links when clicked @@ -34,7 +34,7 @@ Scenario: show profile links when clicked
34 34
35 @selenium-fixme 35 @selenium-fixme
36 Scenario: go to catalog when click on products link 36 Scenario: go to catalog when click on products link
37 - Given I am on /assets/enterprises 37 + Given I am on /search/enterprises
38 When I follow "Profile links" 38 When I follow "Profile links"
39 And I follow "Products" and wait 39 And I follow "Products" and wait
40 Then I should be exactly on /catalog/shop1 40 Then I should be exactly on /catalog/shop1
features/change_appearance.feature
@@ -14,7 +14,7 @@ Feature: Change appearance @@ -14,7 +14,7 @@ Feature: Change appearance
14 And I should not see an element ".box-4" 14 And I should not see an element ".box-4"
15 And I go to joaosilva's control panel 15 And I go to joaosilva's control panel
16 And I follow "Edit Appearance" 16 And I follow "Edit Appearance"
17 - And I follow "Left Top and Right" 17 + And I follow "Top and Side Bars"
18 And I go to joaosilva's control panel 18 And I go to joaosilva's control panel
19 And I follow "Edit sideboxes" 19 And I follow "Edit sideboxes"
20 And I should see an element ".box-4" 20 And I should see an element ".box-4"
features/events.feature
@@ -17,7 +17,7 @@ Feature: events @@ -17,7 +17,7 @@ Feature: events
17 Then I should see "November 2009" within ".current-month" 17 Then I should see "November 2009" within ".current-month"
18 18
19 Scenario: go to next month in global agenda 19 Scenario: go to next month in global agenda
20 - Given I am on /assets/events?year=2009&month=11 20 + Given I am on /search/events?year=2009&month=11
21 When I follow "December" 21 When I follow "December"
22 Then I should see "December 2009" within ".current-month" 22 Then I should see "December 2009" within ".current-month"
23 23
@@ -27,7 +27,7 @@ Feature: events @@ -27,7 +27,7 @@ Feature: events
27 Then I should see "September 2009" within ".current-month" 27 Then I should see "September 2009" within ".current-month"
28 28
29 Scenario: go to previous month in global agenda 29 Scenario: go to previous month in global agenda
30 - Given I am on /assets/events?year=2009&month=11 30 + Given I am on /search/events?year=2009&month=11
31 When I follow "October" 31 When I follow "October"
32 Then I should see "October 2009" within ".current-month" 32 Then I should see "October 2009" within ".current-month"
33 33
@@ -43,7 +43,7 @@ Feature: events @@ -43,7 +43,7 @@ Feature: events
43 43
44 Scenario: go to specific day in global agenda 44 Scenario: go to specific day in global agenda
45 Given I am on the homepage 45 Given I am on the homepage
46 - When I am on /assets/events?year=2009&month=11&day=12 46 + When I am on /search/events?year=2009&month=11&day=12
47 Then I should see "Events for November, 2009" 47 Then I should see "Events for November, 2009"
48 48
49 Scenario: list events for specific day 49 Scenario: list events for specific day
@@ -88,7 +88,7 @@ Feature: events @@ -88,7 +88,7 @@ Feature: events
88 And the following events 88 And the following events
89 | owner | name | start_date | 89 | owner | name | start_date |
90 | josemanuel | Manuel Birthday | 2009-10-24 | 90 | josemanuel | Manuel Birthday | 2009-10-24 |
91 - When I am on /assets/events?year=2009&month=10&day=24 91 + When I am on /search/events?year=2009&month=10&day=24
92 Then I should see "Another Conference" 92 Then I should see "Another Conference"
93 And I should see "Manuel Birthday" 93 And I should see "Manuel Birthday"
94 94
@@ -157,7 +157,7 @@ Feature: events @@ -157,7 +157,7 @@ Feature: events
157 Then I should not see "New events" link 157 Then I should not see "New events" link
158 158
159 Scenario: display environment name in global agenda 159 Scenario: display environment name in global agenda
160 - When I am on /assets/events 160 + When I am on /search/events
161 Then I should see "Colivre.net's Events" 161 Then I should see "Colivre.net's Events"
162 162
163 @selenium 163 @selenium
features/profile_domain.feature
@@ -21,9 +21,7 @@ Feature: domain for profile @@ -21,9 +21,7 @@ Feature: domain for profile
21 Scenario: access profile control panel through profile blocks 21 Scenario: access profile control panel through profile blocks
22 Given I am logged in as "joaosilva" 22 Given I am logged in as "joaosilva"
23 When I go to joaosilva's homepage 23 When I go to joaosilva's homepage
24 - And I follow "Control panel" within ".profile-info-block"  
25 - Then I should see "Joao Silva" within "span.control-panel-title"  
26 - When I follow "Control panel" within ".profile-image-block" 24 + And I follow "Control panel" within ".profile-image-block"
27 Then I should see "Joao Silva" within "span.control-panel-title" 25 Then I should see "Joao Silva" within "span.control-panel-title"
28 26
29 @selenium 27 @selenium
features/profile_search.feature
@@ -36,7 +36,7 @@ Feature: search inside a profile @@ -36,7 +36,7 @@ Feature: search inside a profile
36 | joaosilva | ProfileSearchBlock | 36 | joaosilva | ProfileSearchBlock |
37 When I go to joaosilva's profile 37 When I go to joaosilva's profile
38 And I fill in "q" with "bees" within ".profile-search-block" 38 And I fill in "q" with "bees" within ".profile-search-block"
39 - And I press "Search" 39 + And I press "Search" within ".profile-search-block"
40 Then I should see "bees and butterflies" within ".main-block" 40 Then I should see "bees and butterflies" within ".main-block"
41 41
42 Scenario: not display unpublished articles 42 Scenario: not display unpublished articles
features/register_enterprise.feature
@@ -203,5 +203,5 @@ Feature: register enterprise @@ -203,5 +203,5 @@ Feature: register enterprise
203 203
204 Scenario: a user cant see button to register new enterprise if enterprise_registration disabled 204 Scenario: a user cant see button to register new enterprise if enterprise_registration disabled
205 Given feature "enterprise_registration" is disabled on environment 205 Given feature "enterprise_registration" is disabled on environment
206 - When I am on /assets/enterprises 206 + When I am on /search/enterprises
207 Then I should not see "New enterprise" link 207 Then I should not see "New enterprise" link
features/search_enterprises.feature
@@ -56,7 +56,7 @@ Feature: search enterprises @@ -56,7 +56,7 @@ Feature: search enterprises
56 | owner | name | body | homepage | 56 | owner | name | body | homepage |
57 | shop1 | Shoes home | This is the <i>homepage</i> of Shoes shop! It has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. We should probably talk about shoes. | true | 57 | shop1 | Shoes home | This is the <i>homepage</i> of Shoes shop! It has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. We should probably talk about shoes. | true |
58 When I search enterprises for "shoes" 58 When I search enterprises for "shoes"
59 - And I choose the search filter "Full" 59 + And I select "Full" from "display"
60 Then I should see "This is the homepage of" within ".search-enterprise-description" 60 Then I should see "This is the homepage of" within ".search-enterprise-description"
61 And I should see "about sho..." within ".search-enterprise-description" 61 And I should see "about sho..." within ".search-enterprise-description"
62 62
@@ -66,7 +66,7 @@ Feature: search enterprises @@ -66,7 +66,7 @@ Feature: search enterprises
66 | identifier | name | description | 66 | identifier | name | description |
67 | shop4 | Clothes shop | This <b>clothes</b> shop also sells shoes! This too has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. Clothes are a really important part of our lives. | 67 | shop4 | Clothes shop | This <b>clothes</b> shop also sells shoes! This too has a very long and pretty vague description, just so we can test wether the system will correctly create an excerpt of this text. Clothes are a really important part of our lives. |
68 When I search enterprises for "clothes" 68 When I search enterprises for "clothes"
69 - And I choose the search filter "Full" 69 + And I select "Full" from "display"
70 And I should see "This clothes shop" within ".search-enterprise-description" 70 And I should see "This clothes shop" within ".search-enterprise-description"
71 And I should see "really import..." within ".search-enterprise-description" 71 And I should see "really import..." within ".search-enterprise-description"
72 72
features/step_definitions/noosfero_steps.rb
@@ -94,7 +94,7 @@ Given /^the following blocks$/ do |table| @@ -94,7 +94,7 @@ Given /^the following blocks$/ do |table|
94 owner.boxes<< Box.new 94 owner.boxes<< Box.new
95 owner.boxes.first.blocks << MainBlock.new 95 owner.boxes.first.blocks << MainBlock.new
96 end 96 end
97 - box = owner.boxes.where(:position => 3).first 97 + box = owner.boxes.first
98 klass.constantize.create!(item.merge(:box => box)) 98 klass.constantize.create!(item.merge(:box => box))
99 end 99 end
100 end 100 end
features/suggest_article.feature
@@ -14,9 +14,12 @@ Feature: suggest article @@ -14,9 +14,12 @@ Feature: suggest article
14 14
15 @selenium 15 @selenium
16 Scenario: highlight an article before approval of a suggested article 16 Scenario: highlight an article before approval of a suggested article
17 - Given someone suggested the following article to be published  
18 - | target | article_name | article_body | name | email |  
19 - | sample-community | A suggested article | this is an article about whales | jose | jose@example.org | 17 + Given I am on Sample Community's blog
  18 + And I follow "Suggest an article"
  19 + And I fill in "Title" with "Suggestion"
  20 + And I fill in "Your name" with "Some Guy"
  21 + And I fill in "Email" with "someguy@somewhere.com"
  22 + And I press "Save"
20 When I am logged in as "joaosilva" 23 When I am logged in as "joaosilva"
21 And I go to sample-community's control panel 24 And I go to sample-community's control panel
22 And I follow "Process requests" 25 And I follow "Process requests"
lib/noosfero/plugin.rb
1 require_dependency 'noosfero' 1 require_dependency 'noosfero'
  2 +require 'noosfero/plugin/parent_methods'
2 3
3 class Noosfero::Plugin 4 class Noosfero::Plugin
4 5
@@ -14,13 +15,9 @@ class Noosfero::Plugin @@ -14,13 +15,9 @@ class Noosfero::Plugin
14 15
15 class << self 16 class << self
16 17
17 - attr_writer :should_load 18 + include Noosfero::Plugin::ParentMethods
18 19
19 - # Called for each ActiveRecord class with parents  
20 - # See http://apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/full_table_name_prefix  
21 - def table_name_prefix  
22 - @table_name_prefix ||= "#{name.to_s.underscore}_"  
23 - end 20 + attr_writer :should_load
24 21
25 def should_load 22 def should_load
26 @should_load.nil? && true || @boot 23 @should_load.nil? && true || @boot
@@ -92,8 +89,14 @@ class Noosfero::Plugin @@ -92,8 +89,14 @@ class Noosfero::Plugin
92 end 89 end
93 end 90 end
94 91
95 - def load_plugin(plugin_name)  
96 - (plugin_name.to_s.camelize + 'Plugin').constantize 92 + def load_plugin_identifier identifier
  93 + klass = identifier.to_s.camelize.constantize
  94 + klass = klass.const_get :Base if klass.class == Module
  95 + klass
  96 + end
  97 +
  98 + def load_plugin public_name
  99 + load_plugin_identifier "#{public_name.to_s.camelize}Plugin"
97 end 100 end
98 101
99 # This is a generic method that initialize any possible filter defined by a 102 # This is a generic method that initialize any possible filter defined by a
@@ -135,7 +138,7 @@ class Noosfero::Plugin @@ -135,7 +138,7 @@ class Noosfero::Plugin
135 filters = [filters] 138 filters = [filters]
136 end 139 end
137 filters.each do |plugin_filter| 140 filters.each do |plugin_filter|
138 - filter_method = (plugin.name.underscore.gsub('/','_') + '_' + plugin_filter[:method_name]).to_sym 141 + filter_method = "#{plugin.identifier}_#{plugin_filter[:method_name]}".to_sym
139 controller_class.send(plugin_filter[:type], filter_method, (plugin_filter[:options] || {})) 142 controller_class.send(plugin_filter[:type], filter_method, (plugin_filter[:options] || {}))
140 controller_class.send(:define_method, filter_method) do 143 controller_class.send(:define_method, filter_method) do
141 instance_exec(&plugin_filter[:block]) if environment.plugin_enabled?(plugin) 144 instance_exec(&plugin_filter[:block]) if environment.plugin_enabled?(plugin)
lib/noosfero/plugin/manager.rb
@@ -76,7 +76,7 @@ class Noosfero::Plugin::Manager @@ -76,7 +76,7 @@ class Noosfero::Plugin::Manager
76 76
77 def enabled_plugins 77 def enabled_plugins
78 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| 78 @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin|
79 - plugin.constantize.new(context) 79 + Noosfero::Plugin.load_plugin_identifier(plugin).new context
80 end 80 end
81 end 81 end
82 82
lib/noosfero/plugin/parent_methods.rb 0 → 100644
@@ -0,0 +1,62 @@ @@ -0,0 +1,62 @@
  1 +class Noosfero::Plugin
  2 +
  3 + # Plugins that are defined as modules should extend
  4 + # this module manually, for example:
  5 + # module MyPlugin
  6 + # extend Noosfero::Plugin::ParentMethods
  7 + # end
  8 + module ParentMethods
  9 +
  10 + def identifier
  11 + @identifier ||= (if self.parents.first.instance_of? Module then self.parents.first else self end).name.underscore
  12 + end
  13 +
  14 + def public_name
  15 + @public_name ||= self.identifier.gsub '_plugin', ''
  16 + end
  17 +
  18 + # Here the developer should specify the meta-informations that the plugin can
  19 + # inform.
  20 + def plugin_name
  21 + self.identifier.humanize
  22 + end
  23 + def plugin_description
  24 + _("No description informed.")
  25 + end
  26 +
  27 + # Called for each ActiveRecord model with parents
  28 + # See http://apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/full_table_name_prefix
  29 + def table_name_prefix
  30 + @table_name_prefix ||= "#{self.identifier}_"
  31 + end
  32 +
  33 + def public_path file = '', relative=false
  34 + File.join "#{if relative then '' else '/' end}plugins", public_name, file
  35 + end
  36 +
  37 + def root_path
  38 + Rails.root.join('plugins', public_name)
  39 + end
  40 +
  41 + def view_path
  42 + File.join(root_path,'views')
  43 + end
  44 +
  45 + def admin_url
  46 + {:controller => "#{self.identifier}_admin", :action => 'index'}
  47 + end
  48 +
  49 + def has_admin_url?
  50 + File.exists?(File.join(root_path, 'controllers', "#{self.identifier}_admin_controller.rb"))
  51 + end
  52 +
  53 + def controllers
  54 + @controllers ||= Dir.glob("#{self.root_path}/controllers/*/*").map do |controller_file|
  55 + next unless controller_file =~ /_controller.rb$/
  56 + controller = File.basename(controller_file).gsub(/.rb$/, '').camelize
  57 + end.compact
  58 + end
  59 +
  60 + end
  61 +
  62 +end
lib/noosfero/vote_ext.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +require_dependency 'models/vote'
  2 +
  3 +class Vote
  4 +
  5 + validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id], :if => :allow_duplicated_vote?
  6 +
  7 + def allow_duplicated_vote?
  8 + voter.present?
  9 + end
  10 +
  11 +end
lib/short_filename.rb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -module ShortFilename  
2 -  
3 - def short_filename(filename, limit_chars = 43)  
4 - return filename if filename.size <= limit_chars  
5 - extname = File.extname(filename)  
6 - basename = File.basename(filename,extname)  
7 - str_complement = '(...)'  
8 - return basename[0..(limit_chars - extname.size - str_complement.size - 1)] + str_complement + extname  
9 - end  
10 -  
11 -end  
plugins/comment_classification/views/comment_classification_plugin_myprofile/add_status.html.erb
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 <ul> 13 <ul>
14 <% @comment.comment_classification_plugin_comment_status_users.each do |relation| %> 14 <% @comment.comment_classification_plugin_comment_status_users.each do |relation| %>
15 <li> 15 <li>
16 - <%= _("<i>%{user}</i> added the status <i>%{status_name}</i> at <i>%{created_at}</i>.") % { :user => relation.profile.name, :status_name => relation.status.name, :created_at => time_ago_as_sentence(relation.created_at)} %> 16 + <%= _("<i>%{user}</i> added the status <i>%{status_name}</i> at <i>%{created_at}</i>.") % { :user => relation.profile.name, :status_name => relation.status.name, :created_at => time_ago_in_words(relation.created_at)} %>
17 <% unless relation.reason.blank? %> 17 <% unless relation.reason.blank? %>
18 <p><%= _("<i>Reason:</i> %s") % relation.reason %></p> 18 <p><%= _("<i>Reason:</i> %s") % relation.reason %></p>
19 <% end %> 19 <% end %>
plugins/context_content/views/blocks/context_content.html.erb
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 <%= instance_eval(&block.content_image(content)) if block.show_image %> 6 <%= instance_eval(&block.content_image(content)) if block.show_image %>
7 </div> 7 </div>
8 <% if block.show_name %> 8 <% if block.show_name %>
9 - <div class="name"><%= short_filename(content.name, 30) %></div> 9 + <div class="name"><%= content.name %></div>
10 <% end %> 10 <% end %>
11 </a> 11 </a>
12 </span> 12 </span>
plugins/custom_forms/views/custom_forms_plugin_profile/show.html.erb
@@ -14,8 +14,8 @@ @@ -14,8 +14,8 @@
14 14
15 <%= form_for :submission do |f| %> 15 <%= form_for :submission do |f| %>
16 <% if !user %> 16 <% if !user %>
17 - <%= required labelled_form_field _('Author name'), text_field_tag(:author_name, @submission.author_name) %>  
18 - <%= required labelled_form_field _('Author email'), text_field_tag(:author_email, @submission.author_email) %> 17 + <%= required labelled_form_field _('Name'), text_field_tag(:author_name, @submission.author_name) %>
  18 + <%= required labelled_form_field _('Email'), text_field_tag(:author_email, @submission.author_email) %>
19 <% end %> 19 <% end %>
20 20
21 <%= render :partial => 'shared/form_submission', :locals => {:f => f} %> 21 <%= render :partial => 'shared/form_submission', :locals => {:f => f} %>
plugins/metadata/lib/metadata_plugin.rb
@@ -23,7 +23,7 @@ class MetadataPlugin &lt; Noosfero::Plugin @@ -23,7 +23,7 @@ class MetadataPlugin &lt; Noosfero::Plugin
23 }, 23 },
24 content_viewer: { 24 content_viewer: {
25 variable: proc do 25 variable: proc do
26 - if profile and profile.home_page_id == @page.id 26 + if profile and @page and profile.home_page_id == @page.id
27 @profile 27 @profile
28 elsif @page.respond_to? :encapsulated_file 28 elsif @page.respond_to? :encapsulated_file
29 @page.encapsulated_file 29 @page.encapsulated_file
plugins/metadata/test/functional/content_viewer_controller_test.rb
@@ -48,4 +48,13 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -48,4 +48,13 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
48 assert_tag tag: 'meta', attributes: { property: 'og:image', content: /\/images\/x.png/ } 48 assert_tag tag: 'meta', attributes: { property: 'og:image', content: /\/images\/x.png/ }
49 end 49 end
50 50
  51 + should 'render not_found page properly' do
  52 + assert_equal false, Article.exists?(:slug => 'non-existing-page')
  53 + assert_nothing_raised do
  54 + get :view_page, profile: profile.identifier, page: [ 'non-existing-page' ]
  55 + assert_response 404 # not found
  56 + assert_template 'not_found'
  57 + end
  58 + end
  59 +
51 end 60 end
plugins/vote/lib/ext/vote.rb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -require_dependency 'models/vote'  
2 -  
3 -class Vote  
4 -  
5 - validates_uniqueness_of :voteable_id, :scope => [:voteable_type, :voter_type, :voter_id], :if => :allow_duplicated_vote?  
6 -  
7 - def allow_duplicated_vote?  
8 - voter.present?  
9 - end  
10 -  
11 -end  
public/designs/icons/tango/style.css
@@ -117,6 +117,107 @@ @@ -117,6 +117,107 @@
117 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) } 117 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
118 .icon-fullscreen { background-image: url(Tango/16x16/actions/view-fullscreen.png) } 118 .icon-fullscreen { background-image: url(Tango/16x16/actions/view-fullscreen.png) }
119 119
  120 +/******************BIG ICONS************************/
  121 +.bigicon-embed { background-image: url(Tango/scalable/apps/utilities-terminal.svg) }
  122 +.bigicon-edit { background-image: url(Tango/scalable/apps/text-editor.svg) }
  123 +.bigicon-undo { background-image: url(Tango/scalable/actions/edit-undo.svg) }
  124 +.bigicon-home { background-image: url(Tango/scalable/actions/go-home.svg) }
  125 +.bigicon-home-not { background-image: url(mod/scalable/actions/go-home-not.svg) }
  126 +.bigicon-new,
  127 +.bigicon-suggest { background-image: url(Tango/scalable/actions/filenew.svg) }
  128 +.bigicon-close { background-image: url(Tango/scalable/actions/gtk-cancel.svg) }
  129 +.bigicon-newfolder { background-image: url(Tango/scalable/actions/folder-new.svg) }
  130 +.bigicon-folder { background-image: url(Tango/scalable/places/folder.svg) }
  131 +.bigicon-parent-folder { background-image: url(Tango/scalable/places/folder_home.svg) }
  132 +.bigicon-newblog { background-image: url(mod/scalable/apps/text-editor.svg) }
  133 +.bigicon-blog { background-image: url(mod/scalable/apps/text-editor.svg) }
  134 +.bigicon-save { background-image: url(Tango/scalable/actions/filesave.svg) }
  135 +.bigicon-send { background-image: url(Tango/scalable/actions/stock_mail-forward.svg) }
  136 +.bigicon-cancel { background-image: url(Tango/scalable/actions/gtk-cancel.svg) }
  137 +.bigicon-person { background-image: url(Tango/scalable/apps/system-config-users.svg) }
  138 +.bigicon-product { background-image: url(Tango/scalable/mimetypes/package.svg) }
  139 +.bigicon-delete { background-image: url(Tango/scalable/places/user-trash.svg) }
  140 +.bigicon-back { background-image: url(Tango/scalable/actions/back.svg) }
  141 +.bigicon-next { background-image: url(Tango/scalable/actions/go-next.svg) }
  142 +.bigicon-add { background-image: url(Tango/scalable/actions/add.svg) }
  143 +.bigicon-remove { background-image: url(Tango/scalable/actions/gtk-remove.svg) }
  144 +.bigicon-more { background-image: url(Tango/scalable/actions/add.svg) }
  145 +.bigicon-up { background-image: url(Tango/scalable/actions/go-up.svg) }
  146 +.bigicon-down { background-image: url(Tango/scalable/actions/go-down.svg) }
  147 +.bigicon-left { background-image: url(Tango/scalable/actions/go-previous.svg) }
  148 +.bigicon-right { background-image: url(Tango/scalable/actions/go-next.svg) }
  149 +.bigicon-up-disabled { background-image: url(Tango/scalable/actions/go-up.svg); opacity: 0.25; filter:alpha(opacity=25); }
  150 +.bigicon-down-disabled { background-image: url(Tango/scalable/actions/go-down.svg); opacity: 0.25; filter:alpha(opacity=25); }
  151 +.bigicon-left-disabled { background-image: url(Tango/scalable/actions/go-previous.svg); opacity: 0.25; filter:alpha(opacity=25); }
  152 +.bigicon-right-disabled { background-image: url(Tango/scalable/actions/go-next.svg); opacity: 0.25; filter:alpha(opacity=25); }
  153 +.bigicon-up-red { background-image: url(mod/scalable/actions/go-up-red.svg) }
  154 +.bigicon-forward { background-image: url(Tango/scalable/actions/go-next.svg) }
  155 +.bigicon-search { background-image: url(Tango/scalable/actions/search.svg) }
  156 +.bigicon-ok { background-image: url(Tango/scalable/actions/media-playback-start.svg) }
  157 +.bigicon-login { background-image: url(mod/scalable/actions/log-in.svg) }
  158 +.bigicon-help { background-image: url(Tango/scalable/apps/gnome-help.svg) }
  159 +.bigicon-help32on { background-image: url(Tango/scalable/apps/gnome-help.svg) }
  160 +.bigicon-help32off { background-image: url(mod/scalable/apps/gnome-help-red.svg) }
  161 +.bigicon-spread { background-image: url(mod/scalable/actions/spread.svg) }
  162 +.bigicon-todo { background-image: url(Tango/scalable/actions/stock_paste.svg) }
  163 +.bigicon-eyes { background-image: url(Tango/scalable/actions/find.svg) }
  164 +.bigicon-menu-home { background-image: url(Tango/scalable/actions/go-home.svg) }
  165 +.bigicon-menu-product { background-image: url(Tango/scalable/mimetypes/package.svg) }
  166 +.bigicon-menu-enterprise { background-image: url(Tango/scalable/actions/go-home.svg) }
  167 +.bigicon-menu-community { background-image: url(Tango/scalable/apps/system-config-users.svg) }
  168 +.bigicon-menu-ctrl-panel { background-image: url(Tango/scalable/categories/preferences-desktop.svg) }
  169 +.bigicon-menu-admin { background-image: url(Tango/scalable/categories/preferences-system.svg) }
  170 +.bigicon-menu-my-groups { background-image: url(Tango/scalable/apps/system-config-users.svg) }
  171 +.bigicon-menu-login { background-image: url(mod/scalable/actions/log-in.svg) }
  172 +.bigicon-menu-logout { background-image: url(mod/scalable/actions/log-out.svg) }
  173 +.bigicon-menu-search { background-image: url(Tango/scalable/actions/search.svg) }
  174 +.bigicon-menu-events { background-image: url(Tango/scalable/mimetypes/stock_calendar.svg) }
  175 +.bigicon-event { background-image: url(Tango/scalable/mimetypes/stock_calendar.svg) }
  176 +.bigicon-newevent { background-image: url(Tango/scalable/mimetypes/stock_calendar.svg) }
  177 +.bigicon-menu-articles { background-image: url(Tango/scalable/apps/text-editor.svg) }
  178 +.bigicon-menu-people { background-image: url(mod/scalable/apps/user.svg) }
  179 +.bigicon-menu-mail { background-image: url(Tango/scalable/apps/email.svg) }
  180 +.bigicon-upload-file { background-image: url(Tango/scalable/actions/filesave.svg) }
  181 +.bigicon-newupload-file { background-image: url(Tango/scalable/actions/filesave.svg) }
  182 +.bigicon-slideshow { background-image: url(Tango/scalable/mimetypes/x-office-presentation.svg) }
  183 +.bigicon-photos { background-image: url(Tango/scalable/devices/camera-photo.svg) }
  184 +.bigicon-vertical-toggle { background-image: url(Tango/scalable/actions/mail-send-receive.svg) }
  185 +.bigicon-text-html { background-image: url(Tango/scalable/mimetypes/text-html.svg) }
  186 +.bigicon-text-plain { background-image: url(Tango/scalable/mimetypes/text-x-generic.svg) }
  187 +.bigicon-image-svg-xml { background-image: url(Tango/scalable/mimetypes/image-x-generic.svg) }
  188 +.bigicon-application-octet-stream { background-image: url(Tango/scalable/mimetypes/binary.svg) }
  189 +.bigicon-application-x-gzip { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-x-gzip.svg) }
  190 +.bigicon-application-postscript { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-postscript.svg) }
  191 +.bigicon-application-pdf { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-pdf.svg) }
  192 +.bigicon-application-ogg { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-ogg.svg) }
  193 +.bigicon-video, .icon-video-mpeg { background-image: url(Tango/scalable/mimetypes/video-x-generic.svg) }
  194 +.bigicon-application-vnd-oasis-opendocument-text { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-vnd.oasis.opendocument.text.svg) }
  195 +.bigicon-application-vnd-oasis-opendocument-spreadsheet { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-vnd.oasis.opendocument.spreadsheet.svg) }
  196 +.bigicon-application-vnd-oasis-opendocument-presentation { background-image: url(Tango/scalable/mimetypes/gnome-mime-application-vnd.oasis.opendocument.presentation.svg) }
  197 +.bigicon-welcome-page { background-image: url(mod/scalable/mimetypes/welcome-page.svg) }
  198 +.bigicon-blocks { background-image: url(mod/scalable/mimetypes/blocks.svg) }
  199 +.bigicon-header-footer { background-image: url(mod/scalable/mimetypes/header-footer.svg) }
  200 +.bigicon-appearance { background-image: url(Tango/scalable/apps/preferences-desktop-wallpaper.svg) }
  201 +.bigicon-media-pause { background-image: url(Tango/scalable/actions/media-playback-pause.svg) }
  202 +.bigicon-media-play { background-image: url(Tango/scalable/actions/media-playback-start.svg) }
  203 +.bigicon-media-prev { background-image: url(Tango/scalable/actions/media-skip-backward.svg) }
  204 +.bigicon-media-next { background-image: url(Tango/scalable/actions/media-skip-forward.svg) }
  205 +.bigicon-lock { background-image: url(Tango/scalable/actions/lock.svg) }
  206 +.bigicon-chat { background-image: url(Tango/scalable/apps/internet-group-chat.svg); background-repeat: no-repeat }
  207 +.bigicon-reply { background-image: url(Tango/scalable/actions/mail-reply-sender.svg) }
  208 +.bigicon-newforum { background-image: url(Tango/scalable/apps/internet-group-chat.svg) }
  209 +.bigicon-forum { background-image: url(Tango/scalable/apps/system-users.svg) }
  210 +.bigicon-gallery { background-image: url(Tango/scalable/mimetypes/image-x-generic.svg) }
  211 +.bigicon-newgallery { background-image: url(Tango/scalable/mimetypes/image-x-generic.svg) }
  212 +.bigicon-locale { background-image: url(Tango/scalable/apps/preferences-desktop-locale.svg) }
  213 +.bigicon-user-removed { background-image: url(Tango/scalable/actions/gtk-cancel.svg) }
  214 +.bigicon-user-unknown { background-image: url(Tango/scalable/status/dialog-error.svg) }
  215 +.bigicon-alert { background-image: url(Tango/scalable/status/dialog-warning.svg) }
  216 +.bigicon-clone { background-image: url(Tango/scalable/actions/edit-copy.svg) }
  217 +.bigicon-activate-user { background-image: url(Tango/scalable/emblems/emblem-system.svg) }
  218 +.bigicon-deactivate-user { background-image: url(Tango/scalable/emblems/emblem-unreadable.svg) }
  219 +.bigicon-clock { background-image: url(Tango/scalable/actions/appointment.svg) }
  220 +
120 /******************LARGE ICONS********************/ 221 /******************LARGE ICONS********************/
121 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) } 222 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) }
122 .image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) } 223 .image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) }
public/designs/themes/base/style.css
@@ -1401,3 +1401,17 @@ table.profile th { @@ -1401,3 +1401,17 @@ table.profile th {
1401 table#recaptcha_table tr:hover td { 1401 table#recaptcha_table tr:hover td {
1402 background-color: #fff; 1402 background-color: #fff;
1403 } 1403 }
  1404 +
  1405 +/* product cateogories */
  1406 +#categories-container #product_category_id {
  1407 + font-size: 18px;
  1408 + width: 100%;
  1409 + margin-bottom: 8px;
  1410 +}
  1411 +#categories-container #product_category_id:focus {
  1412 + outline: none;
  1413 + border-color: green;
  1414 + box-shadow: 0 0 10px green;
  1415 + color:#333;
  1416 +}
  1417 +
public/images/icons-app/image-loading-bigicon.png 0 → 100644

3.24 KB

public/javascripts/application.js
@@ -1230,7 +1230,10 @@ window.isHidden = function isHidden() { return (typeof(document.hidden) != &#39;unde @@ -1230,7 +1230,10 @@ window.isHidden = function isHidden() { return (typeof(document.hidden) != &#39;unde
1230 1230
1231 function $_GET(id){ 1231 function $_GET(id){
1232 var a = new RegExp(id+"=([^&#=]*)"); 1232 var a = new RegExp(id+"=([^&#=]*)");
1233 - return decodeURIComponent(a.exec(window.location.search)[1]); 1233 + var result_of_search = a.exec(window.location.search)
  1234 + if(result_of_search != null){
  1235 + return decodeURIComponent(result_of_search[1]);
  1236 + }
1234 } 1237 }
1235 1238
1236 var fullwidth=false; 1239 var fullwidth=false;
@@ -1258,4 +1261,3 @@ function fullscreenPageLoad(itemId){ @@ -1258,4 +1261,3 @@ function fullscreenPageLoad(itemId){
1258 } 1261 }
1259 }); 1262 });
1260 } 1263 }
1261 -  
public/javascripts/media-panel.js
1 -var file_id = 1;  
2 -  
3 -jQuery('.view-all-media').on('click', '.pagination a', function(event) {  
4 - jQuery.ajax({  
5 - url: this.href,  
6 - beforeSend: function(){jQuery('.view-all-media').addClass('fetching')},  
7 - complete: function() {jQuery('.view-all-media').removeClass('fetching')},  
8 - dataType: 'script' 1 +(function($) {
  2 + "use strict";
  3 +
  4 + var file_id = 1;
  5 +
  6 + $('.view-all-media').on('click', '.pagination a', function(event) {
  7 + $.ajax({
  8 + url: this.href,
  9 + beforeSend: function(){$('.view-all-media').addClass('fetching')},
  10 + complete: function() {$('.view-all-media').removeClass('fetching')},
  11 + dataType: 'script'
  12 + });
  13 + return false;
9 }); 14 });
10 - return false;  
11 -});  
12 -  
13 -jQuery('#file').fileupload({  
14 - add: function(e, data){  
15 - data.files[0].id = file_id;  
16 - file_id++;  
17 - data.context = jQuery(tmpl("template-upload", data.files[0]));  
18 - jQuery('#media-upload-form').append(data.context);  
19 - data.submit();  
20 - },  
21 - progress: function (e, data) {  
22 - if (jQuery('#hide-uploads').data('bootstraped') == false) {  
23 - jQuery('#hide-uploads').show();  
24 - jQuery('#hide-uploads').data('bootstraped', true);  
25 - }  
26 - if (data.context) {  
27 - progress = parseInt(data.loaded / data.total * 100, 10);  
28 - data.context.find('.bar').css('width', progress + '%');  
29 - data.context.find('.percentage').text(progress + '%');  
30 - }  
31 - },  
32 - fail: function(e, data){  
33 - var file_id = '#file-'+data.files[0].id;  
34 - jQuery(file_id).find('.progress .bar').addClass('error');  
35 - jQuery(file_id).append("<div class='error-message'>" + data.jqXHR.responseText + "</div>")  
36 - }  
37 -});  
38 -  
39 -jQuery('#hide-uploads').click(function(){  
40 - jQuery('#hide-uploads').hide();  
41 - jQuery('#show-uploads').show();  
42 - jQuery('.upload').slideUp();  
43 - return false;  
44 -});  
45 -  
46 -jQuery('#show-uploads').click(function(){  
47 - jQuery('#hide-uploads').show();  
48 - jQuery('#show-uploads').hide();  
49 - jQuery('.upload').slideDown();  
50 - return false;  
51 -});  
52 -  
53 -function loadPublishedMedia() {  
54 - var parent_id = jQuery('#published-media #parent_id').val();  
55 - var q = jQuery('#published-media #q').val();  
56 - var url = jQuery('#published-media').data('url');  
57 -  
58 - jQuery('#published-media .items').addClass('fetching');  
59 - jQuery.ajax({  
60 - url: url,  
61 - data: {'parent_id': parent_id, 'q': q},  
62 - dataType: 'html',  
63 - success: function(response) {  
64 - jQuery("#published-media .items").html(response);  
65 - jQuery('#published-media .items').removeClass('fetching');  
66 - updateViewAllLinks(); 15 +
  16 +
  17 + $('#file').fileupload({
  18 + add: function(e, data){
  19 + data.files[0].id = file_id;
  20 + file_id++;
  21 + data.context = $(tmpl("template-upload", data.files[0]));
  22 + $('#media-upload-form').append(data.context);
  23 + data.submit();
  24 + },
  25 + progress: function (e, data) {
  26 + if ($('#hide-uploads').data('bootstraped') == false) {
  27 + $('#hide-uploads').show();
  28 + $('#hide-uploads').data('bootstraped', true);
  29 + }
  30 + if (data.context) {
  31 + var progress = parseInt(data.loaded / data.total * 100, 10);
  32 + data.context.find('.bar').css('width', progress + '%');
  33 + data.context.find('.percentage').text(progress + '%');
  34 + }
67 }, 35 },
68 - error: function(response, textStatus, xhr) {  
69 - console.log(response);  
70 - console.log(textStatus); 36 + fail: function(e, data){
  37 + var file_id = '#file-'+data.files[0].id;
  38 + $(file_id).find('.progress .bar').addClass('error');
  39 + $(file_id).append("<div class='error-message'>" + data.jqXHR.responseText + "</div>")
71 } 40 }
72 }); 41 });
73 -}  
74 -  
75 -function updateViewAllLinks() {  
76 - var parent_id = jQuery('#published-media #parent_id').val();  
77 - var q = jQuery('#published-media #q').val();  
78 - jQuery('#published-media .view-all').each(function(){  
79 - var key = jQuery(this).data('key');  
80 - var params = {parent_id: parent_id, q: q, key: key}  
81 - var href = jQuery(this).attr('href');  
82 - href = href.replace(/\?.*/, '?'+jQuery.param(params));  
83 - jQuery(this).attr('href', href); 42 +
  43 +
  44 + $('#hide-uploads').click(function(){
  45 + $('#hide-uploads').hide();
  46 + $('#show-uploads').show();
  47 + $('.upload').slideUp();
  48 + return false;
  49 + });
  50 +
  51 +
  52 + $('#show-uploads').click(function(){
  53 + $('#hide-uploads').show();
  54 + $('#show-uploads').hide();
  55 + $('.upload').slideDown();
  56 + return false;
84 }); 57 });
85 -}  
86 -  
87 -jQuery('#published-media #parent_id').change(function(){ loadPublishedMedia() });  
88 -  
89 -jQuery("#published-media #q").typeWatch({  
90 - callback: function (value) { loadPublishedMedia() },  
91 - wait: 750,  
92 - highlight: true,  
93 - captureLength: 2  
94 -});  
95 -  
96 -jQuery("#published-media #q").bind('notext', function(){ loadPublishedMedia() });  
97 -  
98 -jQuery("#new-folder-dialog").submit(function( event ) {  
99 - var name = jQuery('#new_folder').val();  
100 - var parent_id = jQuery("#new-folder-dialog #parent_id").val();  
101 - jQuery.ajax({  
102 - url: this.action,  
103 - type: 'POST',  
104 - data: {  
105 - 'parent_id': parent_id,  
106 - 'article': {'name': name, 'published': true},  
107 - 'type': jQuery('input[name=folder_type]:checked').val() },  
108 - dataType: 'json',  
109 - beforeSend: function(){jQuery("#new-folder-dialog").addClass('fetching')},  
110 - success: function(response) {  
111 - var option_selected = "<option value='"+ response.id +"' selected='selected'>"+ response.full_name +"</options>"  
112 - var option = "<option value='"+ response.id +"'>"+ response.full_name +"</options>"  
113 - jQuery('#media-upload-form #parent_id').append(option_selected);  
114 - jQuery('#published-media #parent_id').append(option);  
115 - jQuery('#new_folder').val('');  
116 - },  
117 - error: function(response, textStatus, xhr) {  
118 - console.log(response);  
119 - console.log(textStatus);  
120 - },  
121 - complete: function(response){  
122 - jQuery("#new-folder-dialog").removeClass('fetching');  
123 - jQuery("#new-folder-dialog").dialog('close');  
124 - } 58 +
  59 +
  60 + function loadPublishedMedia() {
  61 + var parent_id = $('#published-media #parent_id').val();
  62 + var q = $('#published-media #q').val();
  63 + var url = $('#published-media').data('url');
  64 +
  65 + $('#published-media .items').addClass('fetching');
  66 + $.ajax({
  67 + url: url,
  68 + data: {'parent_id': parent_id, 'q': q},
  69 + dataType: 'html',
  70 + success: function(response) {
  71 + $("#published-media .items").html(response);
  72 + $('#published-media .items').removeClass('fetching');
  73 + updateViewAllLinks();
  74 + },
  75 + error: function(response, textStatus, xhr) {
  76 + console.log(response);
  77 + console.log(textStatus);
  78 + }
  79 + });
  80 + }
  81 + // make it global for usage in media_upload.js.erb
  82 + window.loadPublishedMedia = loadPublishedMedia;
  83 +
  84 +
  85 + function updateViewAllLinks() {
  86 + var parent_id = $('#published-media #parent_id').val();
  87 + var q = $('#published-media #q').val();
  88 + $('#published-media .view-all').each(function(){
  89 + var key = $(this).data('key');
  90 + var params = {parent_id: parent_id, q: q, key: key}
  91 + var href = $(this).attr('href');
  92 + href = href.replace(/\?.*/, '?'+$.param(params));
  93 + $(this).attr('href', href);
  94 + });
  95 + }
  96 +
  97 +
  98 + $('#published-media #parent_id').change(function(){
  99 + loadPublishedMedia()
  100 + });
  101 +
  102 +
  103 + // Using a immediate function to make timer variable only visible for the keyup event
  104 + (function() {
  105 + var timer = null;
  106 +
  107 + $("#published-media #q").keyup(function() {
  108 + if(this.value.length > 2) {
  109 + timer = setTimeout(loadPublishedMedia, 750);
  110 + }
  111 + }).keydown(function() {
  112 + clearTimeout(timer);
  113 + });
  114 + }) ();
  115 +
  116 +
  117 + $("#published-media #q").bind('notext', function(){
  118 + loadPublishedMedia()
  119 + });
  120 +
  121 +
  122 + $("#new-folder-dialog").submit(function( event ) {
  123 + var name = $('#new_folder').val();
  124 + var parent_id = $("#new-folder-dialog #parent_id").val();
  125 + $.ajax({
  126 + url: this.action,
  127 + type: 'POST',
  128 + data: {
  129 + 'parent_id': parent_id,
  130 + 'article': {'name': name, 'published': true},
  131 + 'type': $('input[name=folder_type]:checked').val() },
  132 + dataType: 'json',
  133 + beforeSend: function(){$("#new-folder-dialog").addClass('fetching')},
  134 + success: function(response) {
  135 + var option_selected = "<option value='"+ response.id +"' selected='selected'>"+ response.full_name +"</options>"
  136 + var option = "<option value='"+ response.id +"'>"+ response.full_name +"</options>"
  137 + $('#media-upload-form #parent_id').append(option_selected);
  138 + $('#published-media #parent_id').append(option);
  139 + $('#new_folder').val('');
  140 + },
  141 + error: function(response, textStatus, xhr) {
  142 + console.log(response);
  143 + console.log(textStatus);
  144 + },
  145 + complete: function(response){
  146 + $("#new-folder-dialog").removeClass('fetching');
  147 + $("#new-folder-dialog").dialog('close');
  148 + }
  149 + });
  150 + return false;
  151 + });
  152 +
  153 + $('.icon-vertical-toggle').click(function(){
  154 + $('#content').toggleClass('show-media-panel');
  155 + return false;
125 }); 156 });
126 - return false;  
127 -});  
128 -  
129 -jQuery('.text-editor-sidebar .header .icon-vertical-toggle').click(function(){  
130 - jQuery('#content').toggleClass('show-media-panel');  
131 - return false;  
132 -});  
133 -  
134 -jQuery('#new-folder-button').click(function(){  
135 - jQuery('#new-folder-dialog').dialog({modal: true});  
136 - return false;  
137 -}); 157 +
  158 +
  159 + $('#new-folder-button').click(function(){
  160 + $('#new-folder-dialog').dialog({modal: true});
  161 + return false;
  162 + });
  163 +
  164 +}) (jQuery);
public/javascripts/product_categories.js 0 → 100644
@@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
  1 +product_categories = {
  2 +
  3 + autocomplete: {
  4 + search_url: '',
  5 + select_url: '',
  6 +
  7 + load: function(elem) {
  8 + elem = jQuery(elem)
  9 +
  10 + elem.autocomplete({
  11 + minLength: 3,
  12 + selectFirst: true,
  13 +
  14 + //define callback to retrieve results
  15 + source: function(req, add) {
  16 + //pass request to server
  17 + //The alt attribute contains the wordpress callback action
  18 + var params = { term: req.term };
  19 + jQuery.getJSON(product_categories.autocomplete.search_url, params, function(data) {
  20 + add(data);
  21 + });
  22 + },
  23 +
  24 + focus: function( event, ui ) {
  25 + jQuery(this).val(ui.item.label);
  26 + return false;
  27 + },
  28 +
  29 + select: function(e, ui) {
  30 + jQuery('#categories-container').load(product_categories.autocomplete.select_url, {category_id: ui.item.value})
  31 +
  32 + jQuery(this).val("")
  33 + },
  34 +
  35 + });
  36 +
  37 + },
  38 + },
  39 +
  40 +};
public/stylesheets/application.css
@@ -1560,6 +1560,32 @@ div.article-body p img { @@ -1560,6 +1560,32 @@ div.article-body p img {
1560 #content .blog-post .read-more a { 1560 #content .blog-post .read-more a {
1561 margin: 0 10px; 1561 margin: 0 10px;
1562 } 1562 }
  1563 +
  1564 +#content #article .blog-posts .blog-post .article-compact-abstract{
  1565 + position: relative;
  1566 + float:left;
  1567 + margin-left: 10px;
  1568 + width: 100%;
  1569 + word-wrap: break-word;
  1570 +}
  1571 +
  1572 +#content #article .blog-posts .blog-post .article-compact-image{
  1573 + position:relative;
  1574 + float:left;
  1575 + width: 27%;
  1576 + display: table-cell;
  1577 + vertical-align: middle;
  1578 + text-align: center;
  1579 + margin-top: 15px;
  1580 +}
  1581 +
  1582 +#content #article .blog-posts .blog-post .article-compact-abstract-with-image{
  1583 + position: relative;
  1584 + float:left;
  1585 + margin-left: 10px;
  1586 + width: 70%;
  1587 + word-wrap: break-word;
  1588 +}
1563 /* NOT PUBLISHED BLOG POSTS */ 1589 /* NOT PUBLISHED BLOG POSTS */
1564 1590
1565 .blog-post.not-published { 1591 .blog-post.not-published {
@@ -3829,6 +3855,11 @@ table.cms-articles .icon:hover { @@ -3829,6 +3855,11 @@ table.cms-articles .icon:hover {
3829 3855
3830 /* Folders */ 3856 /* Folders */
3831 3857
  3858 +.article-body ul.folder-content {
  3859 + list-style-type: none;
  3860 + padding: 0;
  3861 +}
  3862 +
3832 .folder-content .folder-item img { 3863 .folder-content .folder-item img {
3833 vertical-align: middle; 3864 vertical-align: middle;
3834 position: relative; 3865 position: relative;
@@ -3894,6 +3925,62 @@ table.cms-articles .icon:hover { @@ -3894,6 +3925,62 @@ table.cms-articles .icon:hover {
3894 right: auto; 3925 right: auto;
3895 left: auto; 3926 left: auto;
3896 } 3927 }
  3928 +
  3929 +/**************Folder Style**********************/
  3930 +
  3931 +.list-item{
  3932 + font-family: arial;
  3933 + color: #172738;
  3934 +}
  3935 +
  3936 +div.folder-description {
  3937 + padding-bottom: 15px;
  3938 +}
  3939 +
  3940 +.list-item h2{
  3941 + border-bottom:1px solid #ccc;
  3942 + margin:0px;
  3943 +}
  3944 +
  3945 +.item-info{
  3946 + border-top: 1px solid #ccc;
  3947 + line-height: 25px;
  3948 + padding:25px 20px;
  3949 +}
  3950 +
  3951 +.item-info a{
  3952 + text-decoration: none !important;
  3953 + font-size: 16px;
  3954 + font-weight: bold;
  3955 +}
  3956 +
  3957 +.item-icon a {
  3958 + float: left;
  3959 + width: 50px;
  3960 + height: 50px;
  3961 + background-repeat: no-repeat;
  3962 + background-position: center center;
  3963 +}
  3964 +
  3965 +span.item-type {
  3966 + font-size: 12px;
  3967 +}
  3968 +
  3969 +.item-description{
  3970 + display: block;
  3971 + position:relative;
  3972 + margin-left: 15%;
  3973 + padding-left: 10px;
  3974 +}
  3975 +
  3976 +.item-date{
  3977 + display:block;
  3978 + position:relative;
  3979 + font-size: 12px;
  3980 + margin-left: 15%;
  3981 + padding-left: 10px;
  3982 +}
  3983 +
3897 /************* enterprise homepage style *****************/ 3984 /************* enterprise homepage style *****************/
3898 3985
3899 div.event-info { 3986 div.event-info {
test/functional/admin_panel_controller_test.rb
@@ -130,6 +130,19 @@ class AdminPanelControllerTest &lt; ActionController::TestCase @@ -130,6 +130,19 @@ class AdminPanelControllerTest &lt; ActionController::TestCase
130 assert_equal "This <strong>is</strong> my new environment", Environment.default.message_for_disabled_enterprise 130 assert_equal "This <strong>is</strong> my new environment", Environment.default.message_for_disabled_enterprise
131 end 131 end
132 132
  133 + should 'save site article date format option' do
  134 + post :site_info, :environment => { :date_format => "numbers_with_year" }
  135 + assert_redirected_to :action => 'index'
  136 +
  137 + assert_equal "numbers_with_year", Environment.default.date_format
  138 + end
  139 +
  140 + should 'dont save site article date format option when a invalid option is passed' do
  141 + post :site_info, :environment => { :date_format => "invalid_format" }
  142 +
  143 + assert_not_equal "invalid_format", Environment.default.date_format
  144 + end
  145 +
133 should 'set portal community' do 146 should 'set portal community' do
134 e = Environment.default 147 e = Environment.default
135 @controller.stubs(:environment).returns(e) 148 @controller.stubs(:environment).returns(e)
test/functional/application_controller_test.rb
@@ -484,7 +484,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -484,7 +484,7 @@ class ApplicationControllerTest &lt; ActionController::TestCase
484 should 'change postgresql schema' do 484 should 'change postgresql schema' do
485 uses_host 'schema1.com' 485 uses_host 'schema1.com'
486 Noosfero::MultiTenancy.expects(:on?).returns(true) 486 Noosfero::MultiTenancy.expects(:on?).returns(true)
487 - Noosfero::MultiTenancy.expects(:mapping).returns({ 'schema1.com' => 'schema1' }) 487 + Noosfero::MultiTenancy.expects(:mapping).returns({ 'schema1.com' => 'schema1' }).at_least_once
488 exception = assert_raise(ActiveRecord::StatementInvalid) { get :index } 488 exception = assert_raise(ActiveRecord::StatementInvalid) { get :index }
489 assert_match /SET search_path TO schema1/, exception.message 489 assert_match /SET search_path TO schema1/, exception.message
490 end 490 end
test/functional/content_viewer_controller_test.rb
@@ -275,7 +275,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -275,7 +275,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
275 275
276 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ] 276 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ]
277 277
278 - assert_template "profile/_private_profile" 278 + assert_template "shared/access_denied"
279 end 279 end
280 280
281 should 'not give access to private articles if logged in but not member' do 281 should 'not give access to private articles if logged in but not member' do
@@ -1540,12 +1540,12 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1540,12 +1540,12 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1540 should 'use context method in extra toolbar actions on article from plugins' do 1540 should 'use context method in extra toolbar actions on article from plugins' do
1541 class Plugin1 < Noosfero::Plugin 1541 class Plugin1 < Noosfero::Plugin
1542 def article_extra_toolbar_buttons(article) 1542 def article_extra_toolbar_buttons(article)
1543 - if current_person.public? 1543 + if profile.public?
1544 {:title => 'some_title', :icon => 'some_icon', :url => '/someurl'} 1544 {:title => 'some_title', :icon => 'some_icon', :url => '/someurl'}
1545 else 1545 else
1546 {:title => 'another_title', :icon => 'another_icon', :url => '/anotherurl'} 1546 {:title => 'another_title', :icon => 'another_icon', :url => '/anotherurl'}
1547 end 1547 end
1548 - end 1548 + end
1549 end 1549 end
1550 Noosfero::Plugin.stubs(:all).returns([Plugin1.name]) 1550 Noosfero::Plugin.stubs(:all).returns([Plugin1.name])
1551 1551
@@ -1560,4 +1560,31 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1560,4 +1560,31 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1560 assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :href => "/anotherurl" }} 1560 assert_tag :tag => 'div', :attributes => { :id => 'article-actions' }, :descendant => { :tag => 'a', :attributes => { :href => "/anotherurl" }}
1561 end 1561 end
1562 1562
  1563 + should 'show lead,image and title in compact blog visualization' do
  1564 + community = Community.create(:name => 'test-community')
  1565 + community.add_member(@profile)
  1566 + community.save!
  1567 +
  1568 + blog = community.articles.find_by_name("Blog")
  1569 + blog.visualization_format = 'compact'
  1570 + blog.save!
  1571 +
  1572 + article = TinyMceArticle.create(:name => 'Article to be shared with images',
  1573 + :body => 'This article should be shared with all social networks',
  1574 + :profile => @profile,
  1575 + :published => false,
  1576 + :abstract => "teste teste teste",
  1577 + :show_to_followers => true,
  1578 + :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')} )
  1579 + article.parent = blog
  1580 + article.save!
  1581 +
  1582 + login_as(@profile.identifier)
  1583 +
  1584 +
  1585 + get :view_page, :profile => community.identifier, "page" => 'blog'
  1586 +
  1587 + assert_tag :tag => 'div', :attributes => { :class => 'article-compact-image' }
  1588 + assert_tag :tag => 'div', :attributes => { :class => 'article-compact-abstract-with-image' }
  1589 + end
1563 end 1590 end
test/functional/organizations_controller_test.rb
@@ -86,22 +86,22 @@ class OrganizationsControllerTest &lt; ActionController::TestCase @@ -86,22 +86,22 @@ class OrganizationsControllerTest &lt; ActionController::TestCase
86 86
87 should 'activate organization profile' do 87 should 'activate organization profile' do
88 organization = fast_create(Organization, :visible => false, :environment_id => environment.id) 88 organization = fast_create(Organization, :visible => false, :environment_id => environment.id)
89 - assert organization.disabled? 89 + assert !organization.visible?
90 90
91 get :activate, {:id => organization.id} 91 get :activate, {:id => organization.id}
92 organization.reload 92 organization.reload
93 93
94 - assert organization.enabled? 94 + assert organization.visible
95 end 95 end
96 96
97 should 'deactivate organization profile' do 97 should 'deactivate organization profile' do
98 organization = fast_create(Organization, :visible => true, :environment_id => environment.id) 98 organization = fast_create(Organization, :visible => true, :environment_id => environment.id)
99 - assert organization.enabled? 99 + assert organization.visible
100 100
101 get :deactivate, {:id => organization.id} 101 get :deactivate, {:id => organization.id}
102 organization.reload 102 organization.reload
103 103
104 - assert organization.disabled? 104 + assert !organization.visible
105 end 105 end
106 106
107 should 'destroy organization profile' do 107 should 'destroy organization profile' do
test/functional/profile_controller_test.rb
@@ -508,11 +508,15 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -508,11 +508,15 @@ class ProfileControllerTest &lt; ActionController::TestCase
508 end 508 end
509 509
510 should 'show description of person' do 510 should 'show description of person' do
  511 + environment = Environment.default
  512 + environment.custom_person_fields = {:description => { :active => true, :required => false, :signup => false }}
  513 + environment.save!
  514 + environment.reload
511 login_as(@profile.identifier) 515 login_as(@profile.identifier)
512 - @profile.description = 'Person\'s description'  
513 - @profile.save 516 + @profile.description = 'Person description'
  517 + @profile.save!
514 get :index, :profile => @profile.identifier 518 get :index, :profile => @profile.identifier
515 - assert_tag :tag => 'div', :attributes => { :class => 'public-profile-description' }, :content => /Person\'s description/ 519 + assert_tag :tag => 'div', :attributes => { :class => 'public-profile-description' }, :content => /Person description/
516 end 520 end
517 521
518 should 'not show description of orgarnization if not filled' do 522 should 'not show description of orgarnization if not filled' do
test/integration/routing_test.rb
@@ -135,7 +135,7 @@ class RoutingTest &lt; ActionController::IntegrationTest @@ -135,7 +135,7 @@ class RoutingTest &lt; ActionController::IntegrationTest
135 end 135 end
136 136
137 def test_assets_routing 137 def test_assets_routing
138 - assert_routing('/assets/my-asset/a/b/c', :controller => 'search', :action => 'assets', :asset => 'my-asset', :category_path => 'a/b/c') 138 + assert_routing('/search/assets/a/b/c', :controller => 'search', :action => 'assets', :category_path => 'a/b/c')
139 end 139 end
140 140
141 def test_content_view_with_dot 141 def test_content_view_with_dot
test/test_helper.rb
@@ -262,10 +262,6 @@ module NoosferoTestHelper @@ -262,10 +262,6 @@ module NoosferoTestHelper
262 arg 262 arg
263 end 263 end
264 264
265 - def show_date(date)  
266 - date.to_s  
267 - end  
268 -  
269 def strip_tags(html) 265 def strip_tags(html)
270 html.gsub(/<[^>]+>/, '') 266 html.gsub(/<[^>]+>/, '')
271 end 267 end
test/unit/application_helper_test.rb
@@ -564,18 +564,6 @@ class ApplicationHelperTest &lt; ActionView::TestCase @@ -564,18 +564,6 @@ class ApplicationHelperTest &lt; ActionView::TestCase
564 assert_equal environment.theme, current_theme 564 assert_equal environment.theme, current_theme
565 end 565 end
566 566
567 - should 'trunc to 15 chars the big filename' do  
568 - assert_equal 'AGENDA(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15)  
569 - end  
570 -  
571 - should 'trunc to default limit the big filename' do  
572 - assert_equal 'AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3')  
573 - end  
574 -  
575 - should 'does not trunc short filename' do  
576 - assert_equal 'filename.mp3', short_filename('filename.mp3')  
577 - end  
578 -  
579 should 'return nil when :show_balloon_with_profile_links_when_clicked is not enabled in environment' do 567 should 'return nil when :show_balloon_with_profile_links_when_clicked is not enabled in environment' do
580 env = Environment.default 568 env = Environment.default
581 env.stubs(:enabled?).with(:show_balloon_with_profile_links_when_clicked).returns(false) 569 env.stubs(:enabled?).with(:show_balloon_with_profile_links_when_clicked).returns(false)
test/unit/blog_test.rb
@@ -161,7 +161,16 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -161,7 +161,16 @@ class BlogTest &lt; ActiveSupport::TestCase
161 assert_equal 'short', p.blog.visualization_format 161 assert_equal 'short', p.blog.visualization_format
162 end 162 end
163 163
164 - should 'allow only full and short as visualization_format' do 164 + should 'update visualization_format setting to compact' do
  165 + p = create_user('testuser').person
  166 + p.articles << build(Blog, :profile => p, :name => 'Blog test')
  167 + blog = p.blog
  168 + blog.visualization_format = 'compact'
  169 + assert blog.save!
  170 + assert_equal 'compact', p.blog.visualization_format
  171 + end
  172 +
  173 + should 'allow only full, short or compact as visualization_format' do
165 blog = build(Blog, :name => 'blog') 174 blog = build(Blog, :name => 'blog')
166 blog.visualization_format = 'wrong_format' 175 blog.visualization_format = 'wrong_format'
167 blog.valid? 176 blog.valid?
@@ -174,6 +183,10 @@ class BlogTest &lt; ActiveSupport::TestCase @@ -174,6 +183,10 @@ class BlogTest &lt; ActiveSupport::TestCase
174 blog.visualization_format = 'full' 183 blog.visualization_format = 'full'
175 blog.valid? 184 blog.valid?
176 assert !blog.errors[:visualization_format.to_s].present? 185 assert !blog.errors[:visualization_format.to_s].present?
  186 +
  187 + blog.visualization_format = 'compact'
  188 + blog.valid?
  189 + assert !blog.errors[:visualization_format.to_s].present?
177 end 190 end
178 191
179 should 'have posts' do 192 should 'have posts' do
test/unit/content_viewer_helper_test.rb
@@ -18,7 +18,7 @@ class ContentViewerHelperTest &lt; ActionView::TestCase @@ -18,7 +18,7 @@ class ContentViewerHelperTest &lt; ActionView::TestCase
18 result = article_title(post) 18 result = article_title(post)
19 assert_tag_in_string result, :tag => 'span', :content => show_date(post.published_at) 19 assert_tag_in_string result, :tag => 'span', :content => show_date(post.published_at)
20 end 20 end
21 - 21 +
22 should 'display published-at for forum posts' do 22 should 'display published-at for forum posts' do
23 forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id) 23 forum = fast_create(Forum, :name => 'Forum test', :profile_id => profile.id)
24 post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => forum) 24 post = TextileArticle.create!(:name => 'post test', :profile => profile, :parent => forum)
@@ -112,6 +112,42 @@ class ContentViewerHelperTest &lt; ActionView::TestCase @@ -112,6 +112,42 @@ class ContentViewerHelperTest &lt; ActionView::TestCase
112 assert_match 'bt-bookmark.gif', addthis_image_tag 112 assert_match 'bt-bookmark.gif', addthis_image_tag
113 end 113 end
114 114
  115 + should 'show date with mm/dd/yyyy' do
  116 + Environment.any_instance.stubs(:date_format).returns('numbers_with_year')
  117 + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile)
  118 + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45)
  119 + article.save!
  120 + result = show_with_right_format_date article
  121 + assert_match /2\/1\/2007/, result
  122 + end
  123 +
  124 + should 'show date with mm/dd' do
  125 + Environment.any_instance.stubs(:date_format).returns('numbers')
  126 + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile)
  127 + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45)
  128 + article.save!
  129 + result = show_with_right_format_date article
  130 + assert_match /2\/1/, result
  131 + end
  132 +
  133 + should 'show date with month name' do
  134 + Environment.any_instance.stubs(:date_format).returns('month_name')
  135 + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile)
  136 + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45)
  137 + article.save!
  138 + result = show_with_right_format_date article
  139 + assert_match /February 1/, result
  140 + end
  141 +
  142 + should 'show date with month name and year' do
  143 + Environment.any_instance.stubs(:date_format).returns('month_name_with_year')
  144 + article = TextileArticle.new(:name => 'post for test', :body => 'post for test', :profile => profile)
  145 + article.published_at = Time.zone.local(2007, 2, 1, 15, 30, 45)
  146 + article.save!
  147 + result = show_with_right_format_date article
  148 + assert_match /February 1, 2007/, result
  149 + end
  150 +
115 protected 151 protected
116 include NoosferoTestHelper 152 include NoosferoTestHelper
117 include ActionView::Helpers::TextHelper 153 include ActionView::Helpers::TextHelper
test/unit/dates_helper_test.rb
@@ -146,4 +146,9 @@ class DatesHelperTest &lt; ActiveSupport::TestCase @@ -146,4 +146,9 @@ class DatesHelperTest &lt; ActiveSupport::TestCase
146 assert_equal Date.new(Date.today.year, Date.today.month, 1), build_date('', '') 146 assert_equal Date.new(Date.today.year, Date.today.month, 1), build_date('', '')
147 end 147 end
148 148
  149 + should 'show how long it has passed since a specific date' do
  150 + date = Time.zone.now
  151 + assert_equal show_date(date, false, false, true), time_ago_in_words(date)
  152 + end
  153 +
149 end 154 end
test/unit/environment_test.rb
@@ -1703,4 +1703,32 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -1703,4 +1703,32 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
1703 assert !e.has_license? 1703 assert !e.has_license?
1704 end 1704 end
1705 1705
  1706 + should 'validates_inclusion_of date format' do
  1707 + environment = fast_create(Environment)
  1708 +
  1709 + environment.date_format = "invalid_format"
  1710 + environment.valid?
  1711 + assert environment.errors[:date_format.to_s].present?
  1712 +
  1713 + environment.date_format = "numbers_with_year"
  1714 + environment.valid?
  1715 + assert !environment.errors[:date_format.to_s].present?
  1716 +
  1717 + environment.date_format = "numbers"
  1718 + environment.valid?
  1719 + assert !environment.errors[:date_format.to_s].present?
  1720 +
  1721 + environment.date_format = "month_name_with_year"
  1722 + environment.valid?
  1723 + assert !environment.errors[:date_format.to_s].present?
  1724 +
  1725 + environment.date_format = "month_name"
  1726 + environment.valid?
  1727 + assert !environment.errors[:date_format.to_s].present?
  1728 +
  1729 + environment.date_format = "past_time"
  1730 + environment.valid?
  1731 + assert !environment.errors[:date_format.to_s].present?
  1732 + end
  1733 +
1706 end 1734 end
test/unit/events_helper_test.rb
@@ -8,27 +8,13 @@ class EventsHelperTest &lt; ActiveSupport::TestCase @@ -8,27 +8,13 @@ class EventsHelperTest &lt; ActiveSupport::TestCase
8 user = create_user('userwithevents').person 8 user = create_user('userwithevents').person
9 stubs(:user).returns(user) 9 stubs(:user).returns(user)
10 10
11 - expects(:show_date_month).returns('')  
12 - expects(:_).with('Events for %s').returns('').once  
13 - expects(:_).with(' to ').returns('').twice  
14 - expects(:_).with('Place: ').returns('').twice  
15 - expects(:_).with('No events for this month').returns('').never  
16 -  
17 - event1 = mock;  
18 - event1.expects(:display_to?).with(anything).returns(true).once;  
19 - event1.expects(:start_date).returns(Date.today).once  
20 - event1.expects(:end_date).returns(Date.today + 1.day).twice  
21 - event1.expects(:name).returns('Event 1').once  
22 - event1.expects(:url).returns({}).once  
23 - event1.expects(:address).returns('The Shire').times(3)  
24 -  
25 - event2 = mock;  
26 - event2.expects(:display_to?).with(anything).returns(true).once  
27 - event2.expects(:start_date).returns(Date.today).once  
28 - event2.expects(:end_date).returns(Date.today + 1.day).twice  
29 - event2.expects(:name).returns('Event 2').once  
30 - event2.expects(:url).returns({}).once  
31 - event2.expects(:address).returns('Valfenda').times(3) 11 + event1 = Event.new(name: "Event 1", start_date: Date.today, end_date: (Date.today + 1.day), address: 'The Shire')
  12 + event1.profile = user
  13 + event1.save
  14 +
  15 + event2 = Event.new(name: 'Event 2', start_date: Date.today, end_date: (Date.today + 1.day), address: 'Valfenda')
  16 + event2.profile = user
  17 + event2.save
32 18
33 result = list_events(Date.today, [event1, event2]) 19 result = list_events(Date.today, [event1, event2])
34 20
test/unit/folder_helper_test.rb
@@ -89,27 +89,14 @@ class FolderHelperTest &lt; ActionView::TestCase @@ -89,27 +89,14 @@ class FolderHelperTest &lt; ActionView::TestCase
89 assert_not_includes result, article 89 assert_not_includes result, article
90 end 90 end
91 91
92 - should 'list subitems as HTML content' do 92 + should 'display the proper content icon' do
93 profile = create_user('folder-owner').person 93 profile = create_user('folder-owner').person
94 folder = fast_create(Folder, {:name => 'Parent Folder', :profile_id => profile.id}) 94 folder = fast_create(Folder, {:name => 'Parent Folder', :profile_id => profile.id})
95 article1 = fast_create(Article, {:name => 'Article1', :parent_id => folder.id, :profile_id => profile.id, :updated_at => DateTime.now }) 95 article1 = fast_create(Article, {:name => 'Article1', :parent_id => folder.id, :profile_id => profile.id, :updated_at => DateTime.now })
96 article2 = fast_create(Article, {:name => 'Article2', :parent_id => folder.id, :profile_id => profile.id, :updated_at => DateTime.now }) 96 article2 = fast_create(Article, {:name => 'Article2', :parent_id => folder.id, :profile_id => profile.id, :updated_at => DateTime.now })
97 - self.stubs(:params).returns({:npage => nil})  
98 -  
99 - contents = folder.children.order('updated_at DESC').paginate(:per_page => 10, :page => params[:npage])  
100 - expects(:user).returns(profile).at_least_once  
101 - expects(:list_type).returns(:folder).at_least_once  
102 - expects(:recursive).returns(false).at_least_once  
103 - expects(:pagination_links).with(anything, anything).returns('')  
104 - list = render 'shared/content_list', binding  
105 - expects(:render).with(:file => 'shared/content_list',  
106 - :locals => { :contents => contents, :recursive => false, :list_type => :folder }  
107 - ).returns(list)  
108 -  
109 - result = list_contents(:contents=>contents)  
110 -  
111 - assert_tag_in_string result, :tag => 'td', :descendant => { :tag => 'a', :attributes => { :href => /.*\/folder-owner\/my-article-[0-9]*(\?|$)/ } }, :content => /Article1/  
112 - assert_tag_in_string result, :tag => 'td', :descendant => { :tag => 'a', :attributes => { :href => /.*\/folder-owner\/my-article-[0-9]*(\?|$)/ } }, :content => /Article2/ 97 +
  98 + assert_tag_in_string display_content_icon(article1), :tag => 'a', :attributes => { :href => /.*\/folder-owner\/my-article-[0-9]*(\?|$)/ }
  99 + assert_tag_in_string display_content_icon(article2), :tag => 'a', :attributes => { :href => /.*\/folder-owner\/my-article-[0-9]*(\?|$)/ }
113 end 100 end
114 101
115 should 'explictly advise if empty' do 102 should 'explictly advise if empty' do
test/unit/forum_helper_test.rb
@@ -7,6 +7,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase @@ -7,6 +7,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase
7 include ContentViewerHelper 7 include ContentViewerHelper
8 include ActionView::Helpers::AssetTagHelper 8 include ActionView::Helpers::AssetTagHelper
9 include ApplicationHelper 9 include ApplicationHelper
  10 + include ActionView::Helpers::DateHelper
10 11
11 def setup 12 def setup
12 @environment = Environment.default 13 @environment = Environment.default
@@ -41,7 +42,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase @@ -41,7 +42,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase
41 some_post = create(TextileArticle, :name => 'First post', :profile => profile, :parent => forum, :published => true, :author => author) 42 some_post = create(TextileArticle, :name => 'First post', :profile => profile, :parent => forum, :published => true, :author => author)
42 assert some_post.comments.empty? 43 assert some_post.comments.empty?
43 out = last_topic_update(some_post) 44 out = last_topic_update(some_post)
44 - assert_match some_post.updated_at.to_s, out 45 + assert_match time_ago_in_words(some_post.updated_at), out
45 assert_match /forum test author/, out 46 assert_match /forum test author/, out
46 end 47 end
47 48
@@ -53,10 +54,11 @@ class ForumHelperTest &lt; ActiveSupport::TestCase @@ -53,10 +54,11 @@ class ForumHelperTest &lt; ActiveSupport::TestCase
53 c = Comment.last 54 c = Comment.last
54 assert_equal 2, some_post.comments.count 55 assert_equal 2, some_post.comments.count
55 out = last_topic_update(some_post) 56 out = last_topic_update(some_post)
56 - assert_match c.created_at.to_s, out 57 + result = time_ago_in_words(c.created_at)
  58 + assert_match result, out
57 assert_match 'a2', out 59 assert_match 'a2', out
58 60
59 - assert_match(/#{Regexp.escape(c.created_at.to_s)} by <a href='[^']+'>a2<\/a>/, last_topic_update(some_post)) 61 + assert_match(/#{result} by <a href='[^']+'>a2<\/a>/, last_topic_update(some_post))
60 end 62 end
61 63
62 should "return last comment author's name from unauthenticated user" do 64 should "return last comment author's name from unauthenticated user" do
@@ -64,18 +66,15 @@ class ForumHelperTest &lt; ActiveSupport::TestCase @@ -64,18 +66,15 @@ class ForumHelperTest &lt; ActiveSupport::TestCase
64 some_post.comments << build(Comment, :name => 'John', :email => 'lenon@example.com', :title => 'test', :body => 'test') 66 some_post.comments << build(Comment, :name => 'John', :email => 'lenon@example.com', :title => 'test', :body => 'test')
65 c = Comment.last 67 c = Comment.last
66 out = last_topic_update(some_post) 68 out = last_topic_update(some_post)
67 - assert_match "#{c.created_at.to_s} by John", out 69 + result = time_ago_in_words(c.created_at)
  70 + assert_match "#{result} by John", out
68 assert_match 'John', out 71 assert_match 'John', out
69 72
70 - assert_match(/#{Regexp.escape(c.created_at.to_s)} by John/m, last_topic_update(some_post)) 73 + assert_match(/#{result} by John/m, last_topic_update(some_post))
71 end 74 end
72 75
73 protected 76 protected
74 77
75 include NoosferoTestHelper 78 include NoosferoTestHelper
76 79
77 - def time_ago_as_sentence(t = Time.now)  
78 - t.to_s  
79 - end  
80 -  
81 end 80 end
test/unit/plugin_test.rb
@@ -23,7 +23,7 @@ class PluginTest &lt; ActiveSupport::TestCase @@ -23,7 +23,7 @@ class PluginTest &lt; ActiveSupport::TestCase
23 end 23 end
24 24
25 should 'returns empty hash for class method extra_blocks by default if no blocks are defined on plugin' do 25 should 'returns empty hash for class method extra_blocks by default if no blocks are defined on plugin' do
26 - 26 +
27 class SomePlugin1 < Noosfero::Plugin 27 class SomePlugin1 < Noosfero::Plugin
28 end 28 end
29 29
test/unit/short_filename_test.rb
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -require_relative "../test_helper"  
2 -  
3 -class NoosferoFilenamesTest < ActiveSupport::TestCase  
4 -  
5 - include ShortFilename  
6 -  
7 - should 'trunc to 15 chars the big filename' do  
8 - assert_equal 'AGENDA(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3',15)  
9 - end  
10 -  
11 - should 'trunc to default limit the big filename' do  
12 - assert_equal 'AGENDA_CULTURA_-_FESTA_DE_VAQUEIRO(...).mp3', short_filename('AGENDA_CULTURA_-_FESTA_DE_VAQUEIROS_PONTO_DE_SERRA_PRETA_BAIXA.mp3')  
13 - end  
14 -  
15 - should 'does not trunc short filename' do  
16 - assert_equal 'filename.mp3', short_filename('filename.mp3')  
17 - end  
18 -  
19 -end  
20 -  
vendor/plugins/access_control/lib/permission_check.rb
@@ -26,7 +26,7 @@ module PermissionCheck @@ -26,7 +26,7 @@ module PermissionCheck
26 end 26 end
27 27
28 def render_access_denied(c) 28 def render_access_denied(c)
29 - if c.respond_to?(:render_access_denied) 29 + if c.respond_to?(:render_access_denied, true)
30 c.send(:render_access_denied) 30 c.send(:render_access_denied)
31 else 31 else
32 c.send(:render, :template => access_denied_template_path, :status => 403) 32 c.send(:render, :template => access_denied_template_path, :status => 403)