GitLab's annual major release is around the corner. Along with a lot of new and exciting features, there will be a few breaking changes. Learn more here.

Commit d168d5b8 authored by Leandro Nunes's avatar Leandro Nunes
Browse files

Merge branch 'master' into article_datetime

parents 4cdda51f b439f1f7
......@@ -17,11 +17,13 @@ Ana Losnak <analosnak@gmail.com>
Ana Paula Vargas <anapaulavnoronha@gmail.com>
Andre Bedran <bedran.fleck@gmail.com>
André Guedes <andrebsguedes@gmail.com>
Andrey Aleksanyants <aaleksanyants@yahoo.com>
Antonio Terceiro <terceiro@colivre.coop.br>
Arthur Del Esposte <arthurmde@gmail.com>
Athos Ribeiro <athoscribeiro@gmail.com>
Aurelio A. Heckert <aurelio@colivre.coop.br>
Braulio Bhavamitra <braulio@eita.org.br>
Brenddon Gontijo <brenddongontijo@msn.com>
Caio Formiga <caio.formiga@gmail.com>
Caio Salgado <caio.csalgado@gmail.com>
Caio SBA <caio@colivre.coop.br>
......
......@@ -7,7 +7,10 @@ class ApplicationController < ActionController::Base
before_filter :detect_stuff_by_domain
before_filter :init_noosfero_plugins
before_filter :allow_cross_domain_access
before_filter :login_from_cookie
before_filter :login_required, :if => :private_environment?
before_filter :verify_members_whitelist, :if => [:private_environment?, :user]
before_filter :redirect_to_current_user
......
class EnterpriseValidationController < MyProfileController
protect 'validate_enterprise', :profile
def index
@pending_validations = profile.pending_validations
end
......@@ -27,7 +27,7 @@ class EnterpriseValidationController < MyProfileController
post_only :reject
def reject
@pending = profile.find_pending_validation(params[:id])
if @pending
if @pending
@pending.reject_explanation = params[:reject_explanation]
begin
@pending.reject
......
......@@ -5,6 +5,7 @@ class ProfileEditorController < MyProfileController
before_filter :access_welcome_page, :only => [:welcome_page]
before_filter :back_to
before_filter :forbid_destroy_profile, :only => [:destroy_profile]
helper_method :has_welcome_page
def index
......@@ -109,7 +110,7 @@ class ProfileEditorController < MyProfileController
profile = environment.profiles.find(params[:id])
if profile.disable
profile.save
session[:notice] = _("The profile '#{profile.name}' was deactivated.")
session[:notice] = _("The profile '%s' was deactivated.") % profile.name
else
session[:notice] = _('Could not deactivate profile.')
end
......@@ -123,7 +124,7 @@ class ProfileEditorController < MyProfileController
profile = environment.profiles.find(params[:id])
if profile.enable
session[:notice] = _("The profile '#{profile.name}' was activated.")
session[:notice] = _("The profile '%s' was activated.") % profile.name
else
session[:notice] = _('Could not activate the profile.')
end
......@@ -155,4 +156,10 @@ class ProfileEditorController < MyProfileController
end
end
def forbid_destroy_profile
if environment.enabled?('forbid_destroy_profile') && !current_person.is_admin?(environment)
session[:notice] = _('You can not destroy the profile.')
redirect_to_previous_location
end
end
end
......@@ -16,7 +16,7 @@ class AccountController < ApplicationController
def activate
@user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code]
if @user
unless @user.environment.enabled?('admin_must_approve_new_users')
unless @user.environment.enabled?('admin_must_approve_new_users')
if @user.activate
@message = _("Your account has been activated, now you can log in!")
check_redirection
......@@ -30,7 +30,7 @@ class AccountController < ApplicationController
@user.activation_code = nil
@user.save!
redirect_to :controller => :home
end
end
end
else
session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?")
......@@ -50,10 +50,12 @@ class AccountController < ApplicationController
if logged_in?
check_join_in_community(self.current_user)
if params[:remember_me] == "1"
self.current_user.remember_me
cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
cookies[:auth_token] = {value: self.current_user.remember_token, expires: self.current_user.remember_token_expires_at}
end
if redirect?
go_to_initial_page
session[:notice] = _("Logged in successfully")
......@@ -92,6 +94,7 @@ class AccountController < ApplicationController
@invitation_code = params[:invitation_code]
begin
@user = User.new(params[:user])
@user.session = session
@user.terms_of_use = environment.terms_of_use
@user.environment = environment
@terms_of_use = environment.terms_of_use
......@@ -435,7 +438,7 @@ class AccountController < ApplicationController
end
def go_to_signup_initial_page
check_redirection_options(user, user.environment.redirection_after_signup, user.url)
check_redirection_options user, user.environment.redirection_after_signup, user.url, signup: true
end
def redirect_if_logged_in
......@@ -455,8 +458,11 @@ class AccountController < ApplicationController
protected
def check_redirection_options(user, condition, default)
case condition
def check_redirection_options user, condition, default, options={}
if options[:signup] and target = session.delete(:after_signup_redirect_to)
redirect_to target
else
case condition
when 'keep_on_same_page'
redirect_back_or_default(user.admin_url)
when 'site_homepage'
......@@ -469,8 +475,11 @@ class AccountController < ApplicationController
redirect_to user.admin_url
when 'welcome_page'
redirect_to :controller => :home, :action => :welcome, :template_id => (user.template && user.template.id)
else
redirect_back_or_default(default)
when 'custom_url'
if (url = user.custom_url_redirection).present? then redirect_to url else redirect_back_or_default default end
else
redirect_back_or_default(default)
end
end
end
......
......@@ -6,6 +6,7 @@ class ProfileController < PublicController
before_filter :login_required, :only => [:add, :join, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail]
helper TagsHelper
helper ActionTrackerHelper
protect 'send_mail_to_members', :profile, :only => [:send_mail]
......
module ActionTrackerHelper
def create_article_description ta
_('published an article: %{title}') % { title: link_to(truncate(ta.get_name), ta.get_url) }
end
def new_friendship_description ta
n_('has made 1 new friend:<br />%{name}', 'has made %{num} new friends:<br />%{name}', ta.get_friend_name.size) % {
num: ta.get_friend_name.size,
name: ta.collect_group_with_index(:friend_name) do |n,i|
link_to image_tag(ta.get_friend_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/person-icon.png")),
ta.get_friend_url[i], title: n
end.join
}
end
def join_community_description ta
n_('has joined 1 community:<br />%{name}', 'has joined %{num} communities:<br />%{name}', ta.get_resource_name.size) % {
num: ta.get_resource_name.size,
name: ta.collect_group_with_index(:resource_name) do |n,i|
link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")),
ta.get_resource_url[i], title: n
end.join
}
end
def add_member_in_community_description ta
_('has joined the community.')
end
def upload_image_description ta
total = ta.get_view_url.size
(n_('uploaded 1 image', 'uploaded %d images', total) % total) +
tag(:br) +
ta.collect_group_with_index(:thumbnail_path) do |t,i|
if total == 1
link_to image_tag(t), ta.get_view_url[i], class: 'upimg'
else
pos = total-i;
morethen2 = pos>2 ? 'morethen2' : ''
morethen5 = pos>5 ? 'morethen5' : ''
t = t.gsub(/(.*)(display)(.*)/, '\\1thumb\\3')
link_to '&nbsp;'.html_safe, ta.get_view_url[i],
style: "background-image:url(#{t})",
class: "upimg pos#{pos} #{morethen2} #{morethen5}"
end
end.reverse.join +
if total <= 5 then ''.html_safe else content_tag :span, '&hellip;'.html_safe,
class: 'more', onclick: "this.parentNode.className+=' show-all'" end +
tag(:br, style: 'clear: both')
end
def reply_scrap_description ta
_('sent a message to %{receiver}: <br /> "%{message}"') % {
receiver: link_to(ta.get_receiver_name, ta.get_receiver_url),
message: auto_link_urls(ta.get_content)
}
end
alias :leave_scrap_description :reply_scrap_description
alias :reply_scrap_on_self_description :reply_scrap_description
def leave_scrap_to_self_description ta
_('wrote: <br /> "%{text}"') % {
text: auto_link_urls(ta.get_content)
}
end
def create_product_description
_('created the product %{title}') % {
title: link_to(truncate(ta.get_name), ta.get_url),
}
end
def update_product_description
_('updated the product %{title}') % {
title: link_to(truncate(ta.get_name), ta.get_url),
}
end
def remove_product_description
_('removed the product %{title}') % {
title: truncate(ta.get_name),
}
end
def favorite_enterprise_description ta
_('favorited enterprise %{title}') % {
title: link_to(truncate(ta.get_enterprise_name), ta.get_enterprise_url),
}
end
end
......@@ -77,15 +77,8 @@ module LayoutHelper
def icon_theme_stylesheet_path
icon_themes = []
theme_icon_themes = theme_option(:icon_theme) || []
for icon_theme in theme_icon_themes do
theme_path = "designs/icons/#{icon_theme}/style.css"
if File.exists?(Rails.root.join('public', theme_path))
icon_themes << theme_path
end
end
icon_themes
theme_icon_themes.map{ |it| "designs/icons/#{it}/style.css" }
end
def jquery_ui_theme_stylesheet_path
......
class ScrapNotifier < ActionMailer::Base
def notification(scrap)
sender, receiver = scrap.sender, scrap.receiver
# for tests
return unless receiver.email
@recipient = receiver.name
@sender = sender.name
@sender_link = sender.url
......
......@@ -26,7 +26,8 @@ class AddMember < Task
end
def information
{:message => _('%{requestor} wants to be a member of this community.')}
{:message => _("%{requestor} wants to be a member of '%{organization}'."),
variables: {requestor: requestor.name, organization: organization.name}}
end
def accept_details
......@@ -42,7 +43,7 @@ class AddMember < Task
end
def target_notification_description
_('%{requestor} wants to be a member of this community.') % {:requestor => requestor.name}
_("%{requestor} wants to be a member of '%{organization}'.") % {:requestor => requestor.name, :organization => organization.name}
end
def target_notification_message
......
......@@ -86,8 +86,8 @@ class Community < Organization
{:title => _('Community Info and settings'), :icon => 'edit-profile-group'}
end
def activities
Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.target_id = #{self.id} and action_tracker.verb != 'join_community' and action_tracker.verb != 'leave_scrap' UNION SELECT at.id, at.updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} at INNER JOIN articles a ON at.target_id = a.id WHERE a.profile_id = #{self.id} AND at.target_type = 'Article' ORDER BY updated_at DESC")
def exclude_verbs_on_activities
%w[join_community leave_scrap]
end
end
......@@ -15,12 +15,15 @@ class Enterprise < Organization
N_('Enterprise')
has_many :products, :foreign_key => :profile_id, :dependent => :destroy, :order => 'name ASC'
acts_as_trackable after_add: proc{ |p, t| notify_activity t }
has_many :products, :foreign_key => :profile_id, :dependent => :destroy
has_many :product_categories, :through => :products
has_many :inputs, :through => :products
has_many :production_costs, :as => :owner
has_many :favorite_enterprise_people
has_many :fans, through: :favorite_enterprise_people, source: :person
has_many :fans, source: :person, through: :favorite_enterprise_people
def product_categories
ProductCategory.by_enterprise(self)
......@@ -194,10 +197,6 @@ class Enterprise < Organization
true
end
def activities
Scrap.find_by_sql("SELECT id, updated_at, 'Scrap' AS klass FROM scraps WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, 'ActionTracker::Record' AS klass FROM action_tracker WHERE action_tracker.target_id = #{self.id} UNION SELECT action_tracker.id, action_tracker.updated_at, 'ActionTracker::Record' AS klass FROM action_tracker INNER JOIN articles ON action_tracker.target_id = articles.id WHERE articles.profile_id = #{self.id} AND action_tracker.target_type = 'Article' ORDER BY updated_at DESC")
end
def catalog_url
{ :profile => identifier, :controller => 'catalog'}
end
......@@ -206,4 +205,9 @@ class Enterprise < Organization
''
end
def followed_by? person
super or self.fans.where(id: person.id).count > 0
end
end
......@@ -128,6 +128,7 @@ class Environment < ActiveRecord::Base
'disable_select_city_for_contact' => _('Disable state/city select for contact form'),
'disable_contact_person' => _('Disable contact for people'),
'disable_contact_community' => _('Disable contact for groups/communities'),
'forbid_destroy_profile' => _('Forbid users of removing profiles'),
'products_for_enterprises' => _('Enable products for enterprises'),
'enterprise_registration' => _('Enterprise registration'),
......@@ -167,7 +168,8 @@ class Environment < ActiveRecord::Base
'site_homepage' => _('Redirects the user to the environment homepage.'),
'user_profile_page' => _('Redirects the user to his profile page.'),
'user_homepage' => _('Redirects the user to his homepage.'),
'user_control_panel' => _('Redirects the user to his control panel.')
'user_control_panel' => _('Redirects the user to his control panel.'),
'custom_url' => _('Specify the URL to redirect to:'),
}
end
validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true
......@@ -248,6 +250,9 @@ class Environment < ActiveRecord::Base
# store the Environment settings as YAML-serialized Hash.
acts_as_having_settings :field => :settings
# introduce and explain to users something about the signup
settings_items :signup_intro, :type => String
# the environment's terms of use: every user must accept them before registering.
settings_items :terms_of_use, :type => String
......@@ -282,7 +287,20 @@ class Environment < ActiveRecord::Base
settings_items :activation_blocked_text, :type => String
settings_items :message_for_disabled_enterprise, :type => String,
:default => _('This enterprise needs to be enabled.')
settings_items :location, :type => String
settings_items :contact_phone, type: String
settings_items :address, type: String
settings_items :city, type: String
settings_items :state, type: String
settings_items :country_name, type: String
settings_items :lat, type: Float
settings_items :lng, type: Float
settings_items :postal_code, type: String
settings_items :location, type: String
alias_method :zip_code=, :postal_code
alias_method :zip_code, :postal_code
settings_items :layout_template, :type => String, :default => 'default'
settings_items :homepage, :type => String
settings_items :description, :type => String, :default => '<div style="text-align: center"><a href="http://noosfero.org/"><img src="/images/noosfero-network.png" alt="Noosfero"/></a></div>'
......
class FavoriteEnterprisePerson < ActiveRecord::Base
self.table_name = :favorite_enteprises_people
attr_accessible :person, :enterprise
track_actions :favorite_enterprise, :after_create, keep_params: [:enterprise_name, :enterprise_url], if: proc{ |f| f.is_trackable? }
belongs_to :enterprise
belongs_to :person
protected
def is_trackable?
self.enterprise.public?
end
def enterprise_name
self.enterprise.short_name(nil)
end
def enterprise_url
self.enterprise.url
end
end
......@@ -35,6 +35,10 @@ class Organization < Profile
validate :presence_of_required_fieds, :unless => :is_template
def self.notify_activity tracked_action
Delayed::Job.enqueue NotifyActivityToProfilesJob.new(tracked_action.id)
end
def presence_of_required_fieds
self.required_fields.each do |field|
if self.send(field).blank?
......
......@@ -81,6 +81,9 @@ roles] }
has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy
has_many :favorite_enterprise_people
has_many :favorite_enterprises, source: :enterprise, through: :favorite_enterprise_people
has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
......@@ -315,8 +318,6 @@ roles] }
]
end
has_and_belongs_to_many :favorite_enterprises, :class_name => 'Enterprise', :join_table => 'favorite_enteprises_people'
def email_domain
user && user.email_domain || environment.default_hostname(true)
end
......@@ -496,8 +497,8 @@ roles] }
user.save!
end
def activities
Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.user_id = #{self.id} and action_tracker.verb != 'leave_scrap_to_self' and action_tracker.verb != 'add_member_in_community' and action_tracker.verb != 'reply_scrap_on_self' ORDER BY updated_at DESC")
def exclude_verbs_on_activities
%w[leave_scrap_to_self add_member_in_community reply_scrap_on_self]
end
# by default, all fields are private
......
......@@ -76,7 +76,8 @@ class PersonNotifier
class Mailer < ActionMailer::Base
add_template_helper(ApplicationHelper)
helper ApplicationHelper
helper ActionTrackerHelper
def session
{:theme => nil}
......
......@@ -17,13 +17,14 @@ class Product < ActiveRecord::Base
'full'
end
belongs_to :enterprise, :foreign_key => :profile_id, :class_name => 'Profile'
belongs_to :profile
# backwards compatibility
belongs_to :enterprise, :foreign_key => :profile_id, :class_name => 'Profile'
alias_method :enterprise=, :profile=
alias_method :enterprise, :profile
has_one :region, :through => :enterprise
validates_presence_of :enterprise
has_one :region, :through => :profile
validates_presence_of :profile
belongs_to :product_category
......@@ -37,6 +38,10 @@ class Product < ActiveRecord::Base
acts_as_having_settings :field => :data
track_actions :create_product, :after_create, :keep_params => [:name, :url ], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user
track_actions :update_product, :before_update, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user
track_actions :remove_product, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user
validates_uniqueness_of :name, :scope => :profile_id, :allow_nil => true, :if => :validate_uniqueness_of_column_name?
validates_presence_of :product_category_id
......@@ -54,10 +59,10 @@ class Product < ActiveRecord::Base
after_update :save_image
def lat
self.enterprise.lat
self.profile.lat
end
def lng
self.enterprise.lng
self.profile.lng
end
xss_terminate :only => [ :name ], :on => 'validation'
......@@ -71,7 +76,7 @@ class Product < ActiveRecord::Base
filter_iframes :description
def iframe_whitelist
enterprise && enterprise.environment && enterprise.environment.trusted_sites_for_iframe
self.profile && self.profile.environment && self.profile.environment.trusted_sites_for_iframe
end
def name
......@@ -109,16 +114,16 @@ class Product < ActiveRecord::Base
end
def url
enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => id)
self.profile.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => id)
end
def public?
enterprise.public?
self.profile.public?
end
def formatted_value(method)
value = self[method] || self.send(method)
("%.2f" % value).to_s.gsub('.', enterprise.environment.currency_separator) if value
("%.2f" % value).to_s.gsub('.', self.profile.environment.currency_separator) if value
end
def price_with_discount
......@@ -223,16 +228,16 @@ class Product < ActiveRecord::Base
end
def available_production_costs
self.enterprise.environment.production_costs + self.enterprise.production_costs
self.profile.environment.production_costs + self.profile.production_costs
end
include Rails.application.routes.url_helpers
def price_composition_bar_display_url
url_for({:host => enterprise.default_hostname, :controller => 'manage_products', :action => 'display_price_composition_bar', :profile => enterprise.identifier, :id => self.id }.merge(Noosfero.url_options))
url_for({:host => self.profile.default_hostname, :controller => 'manage_products', :action => 'display_price_composition_bar', :profile => self.profile.identifier, :id => self.id }.merge(Noosfero.url_options))
end
def inputs_cost_update_url
url_for({:host => enterprise.default_hostname, :controller => 'manage_products', :action => 'display_inputs_cost', :profile => enterprise.identifier, :id => self.id }.merge(Noosfero.url_options))
url_for({:host => self.profile.default_hostname, :controller => 'manage_products', :action => 'display_inputs_cost', :profile => self.profile.identifier, :id => self.id }.merge(Noosfero.url_options))
end
def percentage_from_solidarity_economy
......@@ -249,7 +254,7 @@ class Product < ActiveRecord::Base
end
end
delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise
delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :profile, allow_nil: true
protected
......@@ -257,4 +262,13 @@ class Product < ActiveRecord::Base
true