Commit a250f05f662c0ac069893ca63ad2a7c6d109bf41

Authored by Victor Costa
1 parent 5fb014fc

Added whitelist settings fields to attr_accessible

app/models/environment.rb
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
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 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
7 7
8 has_many :users 8 has_many :users
9 9
app/models/environment.rb.orig 0 → 100644
@@ -0,0 +1,940 @@ @@ -0,0 +1,940 @@
  1 +# A Environment is like a website to be hosted in the platform. It may
  2 +# contain multiple Profile's and can be identified by several different
  3 +# domains.
  4 +class Environment < ActiveRecord::Base
  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
  7 +
  8 + has_many :users
  9 +
  10 + self.partial_updates = false
  11 +
  12 + has_many :tasks, :dependent => :destroy, :as => 'target'
  13 +
  14 + IDENTIFY_SCRIPTS = /(php[0-9s]?|[sp]htm[l]?|pl|py|cgi|rb)/
  15 +
  16 + def self.verify_filename(filename)
  17 + filename += '.txt' if File.extname(filename) =~ IDENTIFY_SCRIPTS
  18 + filename
  19 + end
  20 +
  21 + PERMISSIONS['Environment'] = {
  22 + 'view_environment_admin_panel' => N_('View environment admin panel'),
  23 + 'edit_environment_features' => N_('Edit environment features'),
  24 + 'edit_environment_design' => N_('Edit environment design'),
  25 + 'manage_environment_categories' => N_('Manage environment categories'),
  26 + 'manage_environment_roles' => N_('Manage environment roles'),
  27 + 'manage_environment_validators' => N_('Manage environment validators'),
  28 + 'manage_environment_users' => N_('Manage environment users'),
  29 + 'manage_environment_templates' => N_('Manage environment templates'),
  30 + 'manage_environment_licenses' => N_('Manage environment licenses'),
  31 + 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
  32 + 'edit_appearance' => N_('Edit appearance'),
  33 + }
  34 +
  35 + module Roles
  36 + def self.admin(env_id)
  37 + Role.find_by_key_and_environment_id('environment_administrator', env_id)
  38 + end
  39 + end
  40 +
  41 + after_create :create_roles
  42 + def create_roles
  43 + Role.create!(
  44 + :key => 'environment_administrator',
  45 + :name => N_('Environment Administrator'),
  46 + :environment => self,
  47 + :permissions => PERMISSIONS[Environment.name].keys + PERMISSIONS[Profile.name].keys
  48 + )
  49 + Role.create!(
  50 + :key => 'profile_admin',
  51 + :name => N_('Profile Administrator'),
  52 + :environment => self,
  53 + :permissions => PERMISSIONS[Profile.name].keys
  54 + )
  55 + # members for enterprises, communities etc
  56 + Role.create!(
  57 + :key => "profile_member",
  58 + :name => N_('Member'),
  59 + :environment => self,
  60 + :permissions => [
  61 + 'invite_members',
  62 + ]
  63 + )
  64 + # moderators for enterprises, communities etc
  65 + Role.create!(
  66 + :key => 'profile_moderator',
  67 + :name => N_('Moderator'),
  68 + :environment => self,
  69 + :permissions => [
  70 + 'manage_memberships',
  71 + 'edit_profile_design',
  72 + 'manage_products',
  73 + 'manage_friends',
  74 + 'perform_task'
  75 + ]
  76 + )
  77 + end
  78 +
  79 + def add_admin(user)
  80 + self.affiliate(user, Environment::Roles.admin(self.id))
  81 + end
  82 +
  83 + def remove_admin(user)
  84 + self.disaffiliate(user, Environment::Roles.admin(self.id))
  85 + end
  86 +
  87 + def admins
  88 + Person.members_of(self).all(:conditions => ['role_assignments.role_id = ?', Environment::Roles.admin(self).id])
  89 + end
  90 +
  91 + # returns the available features for a Environment, in the form of a
  92 + # hash, with pairs in the form <tt>'feature_name' => 'Feature name'</tt>.
  93 + def self.available_features
  94 + {
  95 + 'disable_asset_articles' => _('Disable search for articles '),
  96 + 'disable_asset_enterprises' => _('Disable search for enterprises'),
  97 + 'disable_asset_people' => _('Disable search for people'),
  98 + 'disable_asset_communities' => _('Disable search for communities'),
  99 + 'disable_asset_products' => _('Disable search for products'),
  100 + 'disable_asset_events' => _('Disable search for events'),
  101 + 'disable_categories' => _('Disable categories'),
  102 + 'disable_header_and_footer' => _('Disable header/footer editing by users'),
  103 + 'disable_gender_icon' => _('Disable gender icon'),
  104 + 'disable_categories_menu' => _('Disable the categories menu'),
  105 + 'disable_select_city_for_contact' => _('Disable state/city select for contact form'),
  106 + 'disable_contact_person' => _('Disable contact for people'),
  107 + 'disable_contact_community' => _('Disable contact for groups/communities'),
  108 +
  109 + 'products_for_enterprises' => _('Enable products for enterprises'),
  110 + 'enterprise_registration' => _('Enterprise registration'),
  111 + 'enterprise_activation' => _('Enable activation of enterprises'),
  112 + 'enterprises_are_disabled_when_created' => _('Enterprises are disabled when created'),
  113 + 'enterprises_are_validated_when_created' => _('Enterprises are validated when created'),
  114 +
  115 + 'media_panel' => _('Media panel in WYSIWYG editor'),
  116 + 'select_preferred_domain' => _('Select preferred domains per profile'),
  117 + 'use_portal_community' => _('Use the portal as news source for front page'),
  118 + 'user_themes' => _('Allow users to create their own themes'),
  119 + 'search_in_home' => _("Display search form in home page"),
  120 +
  121 + 'cant_change_homepage' => _("Don't allow users to change which article to use as homepage"),
  122 + 'display_header_footer_explanation' => _("Display explanation about header and footer"),
  123 + 'articles_dont_accept_comments_by_default' => _("Articles don't accept comments by default"),
  124 + 'organizations_are_moderated_by_default' => _("Organizations have moderated publication by default"),
  125 + 'enable_organization_url_change' => _("Allow organizations to change their URL"),
  126 + 'admin_must_approve_new_communities' => _("Admin must approve creation of communities"),
  127 + 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'),
  128 + 'xmpp_chat' => _('XMPP/Jabber based chat'),
  129 + 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images'),
  130 + 'captcha_for_logged_users' => _('Ask captcha when a logged user comments too'),
  131 + 'skip_new_user_email_confirmation' => _('Skip e-mail confirmation for new users'),
  132 + 'send_welcome_email_to_new_users' => _('Send welcome e-mail to new users'),
  133 + 'allow_change_of_redirection_after_login' => _('Allow users to set the page to redirect after login'),
  134 + 'display_my_communities_on_user_menu' => _('Display on menu the list of communities the user can manage'),
  135 + 'display_my_enterprises_on_user_menu' => _('Display on menu the list of enterprises the user can manage'),
  136 + 'restrict_to_members' => _('Show content only to members')
  137 + }
  138 + end
  139 +
  140 + def self.login_redirection_options
  141 + {
  142 + 'keep_on_same_page' => _('Stays on the same page the user was before login.'),
  143 + 'site_homepage' => _('Redirects the user to the environment homepage.'),
  144 + 'user_profile_page' => _('Redirects the user to his profile page.'),
  145 + 'user_homepage' => _('Redirects the user to his homepage.'),
  146 + 'user_control_panel' => _('Redirects the user to his control panel.')
  147 + }
  148 + end
  149 + validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true
  150 +
  151 + def self.signup_redirection_options
  152 + {
  153 + 'keep_on_same_page' => _('Stays on the same page the user was before signup.'),
  154 + 'site_homepage' => _('Redirects the user to the environment homepage.'),
  155 + 'user_profile_page' => _('Redirects the user to his profile page.'),
  156 + 'user_homepage' => _('Redirects the user to his homepage.'),
  157 + 'user_control_panel' => _('Redirects the user to his control panel.')
  158 + }
  159 + end
  160 + validates_inclusion_of :redirection_after_signup, :in => Environment.signup_redirection_options.keys, :allow_nil => true
  161 +
  162 +
  163 + # #################################################
  164 + # Relationships and applied behaviour
  165 + # #################################################
  166 +
  167 + acts_as_having_boxes
  168 +
  169 + after_create do |env|
  170 + 3.times do
  171 + env.boxes << Box.new
  172 + end
  173 +
  174 + # main area
  175 + env.boxes[0].blocks << MainBlock.new
  176 +
  177 + # "left" area
  178 + env.boxes[1].blocks << LoginBlock.new
  179 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  180 + # the Noosfero core soon, see ActionItem3045
  181 + env.boxes[1].blocks << EnvironmentStatisticsBlock.new
  182 + env.boxes[1].blocks << RecentDocumentsBlock.new
  183 +
  184 + # "right" area
  185 + env.boxes[2].blocks << CommunitiesBlock.new(:limit => 6)
  186 + end
  187 +
  188 + # One Environment can be reached by many domains
  189 + has_many :domains, :as => :owner
  190 + has_many :profiles, :dependent => :destroy
  191 +
  192 + has_many :organizations
  193 + has_many :enterprises
  194 + has_many :products, :through => :enterprises
  195 + has_many :people
  196 + has_many :communities
  197 + has_many :licenses
  198 +
  199 + has_many :categories
  200 + has_many :display_categories, :class_name => 'Category', :conditions => 'display_color is not null and parent_id is null', :order => 'display_color'
  201 +
  202 + has_many :product_categories, :conditions => { :type => 'ProductCategory'}
  203 + has_many :regions
  204 + has_many :states
  205 + has_many :cities
  206 +
  207 + has_many :roles, :dependent => :destroy
  208 +
  209 + has_many :qualifiers
  210 + has_many :certifiers
  211 +
  212 + has_many :mailings, :class_name => 'EnvironmentMailing', :foreign_key => :source_id, :as => 'source'
  213 +
  214 + acts_as_accessible
  215 +
  216 + has_many :units, :order => 'position'
  217 + has_many :production_costs, :as => :owner
  218 +
  219 + def superior_intances
  220 + [self, nil]
  221 + end
  222 + # #################################################
  223 + # Attributes
  224 + # #################################################
  225 +
  226 + # store the Environment settings as YAML-serialized Hash.
  227 + acts_as_having_settings :field => :settings
  228 +
  229 + # the environment's terms of use: every user must accept them before registering.
  230 + settings_items :terms_of_use, :type => String
  231 +
  232 + # the environment's terms of enterprise use: every enterprise member must accept them before
  233 + # registering or activating enterprises.
  234 + settings_items :terms_of_enterprise_use, :type => String
  235 +
  236 + # returns the approval method used for this environment. Possible values are:
  237 + #
  238 + # Defaults to <tt>:admim</tt>.
  239 + settings_items :organization_approval_method, :type => Symbol, :default => :admin
  240 +
  241 + # Whether this environment should force having 'www.' in its domain name or
  242 + # not. Defauls to false.
  243 + #
  244 + # Sets the value of #force_www. <tt>value</tt> must be a boolean.
  245 + #
  246 + # See also #default_hostname
  247 + settings_items :force_www, :default => false
  248 +
  249 + settings_items :message_for_friend_invitation, :type => String
  250 + def message_for_friend_invitation
  251 + settings[:message_for_member_invitation] || InviteFriend.mail_template
  252 + end
  253 +
  254 + settings_items :message_for_member_invitation, :type => String
  255 + def message_for_member_invitation
  256 + settings[:message_for_member_invitation] || InviteMember.mail_template
  257 + end
  258 +
  259 + settings_items :min_signup_delay, :type => Integer, :default => 3 #seconds
  260 + settings_items :activation_blocked_text, :type => String
  261 + settings_items :message_for_disabled_enterprise, :type => String,
  262 + :default => _('This enterprise needs to be enabled.')
  263 + settings_items :location, :type => String
  264 + settings_items :layout_template, :type => String, :default => 'default'
  265 + settings_items :homepage, :type => String
  266 + 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>'
  267 + settings_items :local_docs, :type => Array, :default => []
  268 + settings_items :news_amount_by_folder, :type => Integer, :default => 4
  269 + settings_items :help_message_to_add_enterprise, :type => String, :default => ''
  270 + settings_items :tip_message_enterprise_activation_question, :type => String, :default => ''
  271 +
  272 + settings_items :currency_unit, :type => String, :default => '$'
  273 + settings_items :currency_separator, :type => String, :default => '.'
  274 + settings_items :currency_delimiter, :type => String, :default => ','
  275 +
  276 + settings_items :trusted_sites_for_iframe, :type => Array, :default => %w[
  277 + developer.myspace.com
  278 + itheora.org
  279 + maps.google.com
  280 + platform.twitter.com
  281 + player.vimeo.com
  282 + stream.softwarelivre.org
  283 + tv.softwarelivre.org
  284 + www.facebook.com
  285 + www.flickr.com
  286 + www.gmodules.com
  287 + www.youtube.com
  288 + ] + ('a' .. 'z').map{|i| "#{i}.yimg.com"}
  289 +
  290 + settings_items :enabled_plugins, :type => Array, :default => []
  291 +
  292 + settings_items :search_hints, :type => Hash, :default => {}
  293 +
  294 + # Set to return http forbidden to host not on the allow origin list bellow
  295 + settings_items :restrict_to_access_control_origins, :default => false
  296 + # Set this according to http://www.w3.org/TR/cors/. Headers are set at every response
  297 + # For multiple domains acts as suggested in http://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains
  298 + settings_items :access_control_allow_origin, :type => Array, :default => []
  299 + settings_items :access_control_allow_methods, :type => String
  300 +
  301 +<<<<<<< HEAD
  302 + settings_items :members_whitelist_enabled, :type => :boolean, :default => false
  303 + settings_items :members_whitelist, :type => Array, :default => []
  304 +
  305 + def in_whitelist?(person)
  306 + !members_whitelist_enabled || members_whitelist.include?(person.id)
  307 + end
  308 +
  309 + def members_whitelist=(members)
  310 + settings[:members_whitelist] = members.split(',').map(&:to_i)
  311 +=======
  312 + settings_items :signup_welcome_screen_body, :type => String
  313 +
  314 + def has_custom_welcome_screen?
  315 + settings[:signup_welcome_screen_body].present?
  316 +>>>>>>> rails3
  317 + end
  318 +
  319 + def news_amount_by_folder=(amount)
  320 + settings[:news_amount_by_folder] = amount.to_i
  321 + end
  322 +
  323 + # Enables a feature identified by its name
  324 + def enable(feature, must_save=true)
  325 + self.settings["#{feature}_enabled".to_sym] = true
  326 + self.save! if must_save
  327 + end
  328 +
  329 + def enable_plugin(plugin)
  330 + self.enabled_plugins += [plugin.to_s]
  331 + self.enabled_plugins.uniq!
  332 + self.save!
  333 + end
  334 +
  335 + # Disables a feature identified by its name
  336 + def disable(feature, must_save=true)
  337 + self.settings["#{feature}_enabled".to_sym] = false
  338 + self.save! if must_save
  339 + end
  340 +
  341 + def disable_plugin(plugin)
  342 + self.enabled_plugins.delete(plugin.to_s)
  343 + self.save!
  344 + end
  345 +
  346 + # Tells if a feature, identified by its name, is enabled
  347 + def enabled?(feature)
  348 + self.settings["#{feature}_enabled".to_sym] == true
  349 + end
  350 + def disabled?(feature)
  351 + !self.enabled?(feature)
  352 + end
  353 +
  354 + def plugin_enabled?(plugin)
  355 + enabled_plugins.include?(plugin.to_s)
  356 + end
  357 +
  358 + # enables the features identified by <tt>features</tt>, which is expected to
  359 + # be an Enumarable object containing the identifiers of the desired features.
  360 + # Passing <tt>nil</tt> is the same as passing an empty Array.
  361 + def enabled_features=(features)
  362 + features ||= []
  363 + self.class.available_features.keys.each do |feature|
  364 + if features.include? feature
  365 + self.enable(feature)
  366 + else
  367 + self.disable(feature)
  368 + end
  369 + end
  370 + end
  371 +
  372 + def enabled_features
  373 + features = self.class.available_features
  374 + features.delete_if{ |k, v| !self.enabled?(k) }
  375 + end
  376 +
  377 + DEFAULT_FEATURES = %w(
  378 + disable_asset_products
  379 + disable_gender_icon
  380 + products_for_enterprises
  381 + disable_select_city_for_contact
  382 + enterprise_registration
  383 + media_panel
  384 + organizations_are_moderated_by_default
  385 + show_balloon_with_profile_links_when_clicked
  386 + show_zoom_button_on_article_images
  387 + use_portal_community
  388 + )
  389 +
  390 + before_create :enable_default_features
  391 + def enable_default_features
  392 + DEFAULT_FEATURES.each do |feature|
  393 + enable(feature, false)
  394 + end
  395 + end
  396 +
  397 + # returns <tt>true</tt> if this Environment has terms of use to be
  398 + # accepted by users before registration.
  399 + def has_terms_of_use?
  400 + ! self.terms_of_use.blank?
  401 + end
  402 +
  403 + # returns <tt>true</tt> if this Environment has terms of enterprise use to be
  404 + # accepted by users before registration or activation of enterprises.
  405 + def has_terms_of_enterprise_use?
  406 + ! self.terms_of_enterprise_use.blank?
  407 + end
  408 +
  409 + # Sets the organization_approval_method. Only accepts the following values:
  410 + #
  411 + # * <tt>:admin</tt>: organization registration must be approved by the
  412 + # environment administrator.
  413 + # * <tt>:region</tt>: organization registering must be approved by some other
  414 + # organization asssigned as validator to the Region the new organization
  415 + # belongs to.
  416 + # * <tt>:none</tt>: organization registration is approved by default.
  417 + #
  418 + # Trying to set organization_approval_method to any other value will raise an
  419 + # ArgumentError.
  420 + #
  421 + # The value passed as argument is converted to a Symbol before being actually
  422 + # set to this setting.
  423 + def organization_approval_method=(value)
  424 + actual_value = value.to_sym
  425 +
  426 + accepted_values = %w[
  427 + admin
  428 + region
  429 + none
  430 + ].map(&:to_sym)
  431 + raise ArgumentError unless accepted_values.include?(actual_value)
  432 +
  433 + self.settings[:organization_approval_method] = actual_value
  434 + end
  435 +
  436 + def custom_person_fields
  437 + self.settings[:custom_person_fields].nil? ? {} : self.settings[:custom_person_fields]
  438 + end
  439 +
  440 + def custom_person_fields=(values)
  441 + if values['schooling'] && values['schooling']['active'] == 'true'
  442 + schooling_status = values['schooling']
  443 + end
  444 +
  445 + self.settings[:custom_person_fields] = values.delete_if { |key, value| ! Person.fields.include?(key)}
  446 + self.settings[:custom_person_fields].each_pair do |key, value|
  447 + if value['required'] == 'true'
  448 + self.settings[:custom_person_fields][key]['active'] = 'true'
  449 + self.settings[:custom_person_fields][key]['signup'] = 'true'
  450 + end
  451 + if value['signup'] == 'true'
  452 + self.settings[:custom_person_fields][key]['active'] = 'true'
  453 + end
  454 + end
  455 +
  456 + if schooling_status
  457 + self.settings[:custom_person_fields]['schooling_status'] = schooling_status
  458 + end
  459 + end
  460 +
  461 + def custom_person_field(field, status)
  462 + if (custom_person_fields[field] && custom_person_fields[field][status] == 'true')
  463 + return true
  464 + end
  465 + false
  466 + end
  467 +
  468 + def active_person_fields
  469 + (custom_person_fields.delete_if { |key, value| !custom_person_field(key, 'active')}).keys || []
  470 + end
  471 +
  472 + def required_person_fields
  473 + required_fields = []
  474 + active_person_fields.each do |field|
  475 + required_fields << field if custom_person_fields[field]['required'] == 'true'
  476 + end
  477 + required_fields
  478 + end
  479 +
  480 + def signup_person_fields
  481 + signup_fields = []
  482 + active_person_fields.each do |field|
  483 + signup_fields << field if custom_person_fields[field]['signup'] == 'true'
  484 + end
  485 + signup_fields
  486 + end
  487 +
  488 + def invitation_mail_template(profile)
  489 + if profile.person?
  490 + message_for_friend_invitation
  491 + else
  492 + message_for_member_invitation
  493 + end
  494 + end
  495 +
  496 + def custom_enterprise_fields
  497 + self.settings[:custom_enterprise_fields].nil? ? {} : self.settings[:custom_enterprise_fields]
  498 + end
  499 +
  500 + def custom_enterprise_fields=(values)
  501 + self.settings[:custom_enterprise_fields] = values.delete_if { |key, value| ! Enterprise.fields.include?(key)}
  502 + self.settings[:custom_enterprise_fields].each_pair do |key, value|
  503 + if value['required'] == 'true'
  504 + self.settings[:custom_enterprise_fields][key]['active'] = 'true'
  505 + self.settings[:custom_enterprise_fields][key]['signup'] = 'true'
  506 + end
  507 + if value['signup'] == 'true'
  508 + self.settings[:custom_enterprise_fields][key]['active'] = 'true'
  509 + end
  510 + end
  511 + end
  512 +
  513 + def custom_enterprise_field(field, status)
  514 + if (custom_enterprise_fields[field] && custom_enterprise_fields[field][status] == 'true')
  515 + return true
  516 + end
  517 + false
  518 + end
  519 +
  520 + def active_enterprise_fields
  521 + (custom_enterprise_fields.delete_if { |key, value| !custom_enterprise_field(key, 'active')}).keys || []
  522 + end
  523 +
  524 + def required_enterprise_fields
  525 + required_fields = []
  526 + active_enterprise_fields.each do |field|
  527 + required_fields << field if custom_enterprise_fields[field]['required'] == 'true'
  528 + end
  529 + required_fields
  530 + end
  531 +
  532 + def signup_enterprise_fields
  533 + signup_fields = []
  534 + active_enterprise_fields.each do |field|
  535 + signup_fields << field if custom_enterprise_fields[field]['signup'] == 'true'
  536 + end
  537 + signup_fields
  538 + end
  539 +
  540 + def custom_community_fields
  541 + self.settings[:custom_community_fields].nil? ? {} : self.settings[:custom_community_fields]
  542 + end
  543 + def custom_community_fields=(values)
  544 + self.settings[:custom_community_fields] = values.delete_if { |key, value| ! Community.fields.include?(key) }
  545 + self.settings[:custom_community_fields].each_pair do |key, value|
  546 + if value['required'] == 'true'
  547 + self.settings[:custom_community_fields][key]['active'] = 'true'
  548 + self.settings[:custom_community_fields][key]['signup'] = 'true'
  549 + end
  550 + if value['signup'] == 'true'
  551 + self.settings[:custom_community_fields][key]['active'] = 'true'
  552 + end
  553 + end
  554 + end
  555 +
  556 + def custom_community_field(field, status)
  557 + if (custom_community_fields[field] && custom_community_fields[field][status] == 'true')
  558 + return true
  559 + end
  560 + false
  561 + end
  562 +
  563 + def active_community_fields
  564 + (custom_community_fields.delete_if { |key, value| !custom_community_field(key, 'active')}).keys
  565 + end
  566 +
  567 + def required_community_fields
  568 + required_fields = []
  569 + active_community_fields.each do |field|
  570 + required_fields << field if custom_community_fields[field]['required'] == 'true'
  571 + end
  572 + required_fields
  573 + end
  574 +
  575 + def signup_community_fields
  576 + signup_fields = []
  577 + active_community_fields.each do |field|
  578 + signup_fields << field if custom_community_fields[field]['signup'] == 'true'
  579 + end
  580 + signup_fields
  581 + end
  582 +
  583 + serialize :signup_welcome_text, Hash
  584 + def signup_welcome_text
  585 + self[:signup_welcome_text] ||= {}
  586 + end
  587 +
  588 + def signup_welcome_text_subject
  589 + self.signup_welcome_text[:subject]
  590 + end
  591 +
  592 + def signup_welcome_text_subject=(subject)
  593 + self.signup_welcome_text[:subject] = subject
  594 + end
  595 +
  596 + def signup_welcome_text_body
  597 + self.signup_welcome_text[:body]
  598 + end
  599 +
  600 + def signup_welcome_text_body=(body)
  601 + self.signup_welcome_text[:body] = body
  602 + end
  603 +
  604 + def has_signup_welcome_text?
  605 + signup_welcome_text && !signup_welcome_text_body.blank?
  606 + end
  607 +
  608 + # #################################################
  609 + # Validations
  610 + # #################################################
  611 +
  612 + # <tt>name</tt> is mandatory
  613 + validates_presence_of :name
  614 +
  615 + # only one environment can be the default one
  616 + validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one')
  617 +
  618 + validates_format_of :contact_email, :noreply_email, :with => Noosfero::Constants::EMAIL_FORMAT, :allow_blank => true
  619 +
  620 + xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation'
  621 +
  622 + validates_presence_of :theme
  623 + validates_numericality_of :reports_lower_bound, :allow_nil => false, :only_integer => true, :greater_than_or_equal_to => 0
  624 +
  625 + include WhiteListFilter
  626 + filter_iframes :message_for_disabled_enterprise
  627 + def iframe_whitelist
  628 + trusted_sites_for_iframe
  629 + end
  630 +
  631 + # #################################################
  632 + # Business logic in general
  633 + # #################################################
  634 +
  635 + # the default Environment.
  636 + def self.default
  637 + self.find(:first, :conditions => [ 'is_default = ?', true ] )
  638 + end
  639 +
  640 + # returns an array with the top level categories for this environment.
  641 + def top_level_categories
  642 + Category.top_level_for(self)
  643 + end
  644 +
  645 + # Returns the hostname of the first domain associated to this environment.
  646 + #
  647 + # If #force_www is true, adds 'www.' at the beginning of the hostname. If the
  648 + # environment has not associated domains, returns 'localhost'.
  649 + def default_hostname(email_hostname = false)
  650 + domain = 'localhost'
  651 + unless self.domains(true).empty?
  652 + domain = (self.domains.find_by_is_default(true) || self.domains.find(:first, :order => 'id')).name
  653 + domain = email_hostname ? domain : (force_www ? ('www.' + domain) : domain)
  654 + end
  655 + domain
  656 + end
  657 +
  658 + def admin_url
  659 + { :controller => 'admin_panel', :action => 'index' }
  660 + end
  661 +
  662 + def top_url
  663 + url = 'http://'
  664 + url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
  665 + url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
  666 + url
  667 + end
  668 +
  669 + def to_s
  670 + self.name || '?'
  671 + end
  672 +
  673 + has_many :articles, :through => :profiles
  674 + def recent_documents(limit = 10, options = {}, pagination = true)
  675 + self.articles.recent(limit, options, pagination)
  676 + end
  677 +
  678 + has_many :events, :through => :profiles, :source => :articles, :class_name => 'Event'
  679 +
  680 + has_many :tags, :through => :articles
  681 +
  682 + def tag_counts
  683 + articles.tag_counts.inject({}) do |memo,tag|
  684 + memo[tag.name] = tag.count
  685 + memo
  686 + end
  687 + end
  688 +
  689 + def themes
  690 + if settings[:themes]
  691 + Theme.system_themes.select { |theme| settings[:themes].include?(theme.id) }
  692 + else
  693 + []
  694 + end
  695 + end
  696 +
  697 + def themes=(values)
  698 + settings[:themes] = values
  699 + end
  700 +
  701 + def add_themes(values)
  702 + if settings[:themes].nil?
  703 + self.themes = values
  704 + else
  705 + settings[:themes] += values
  706 + end
  707 + end
  708 +
  709 + def update_theme(theme)
  710 + self.theme = theme
  711 + self.save!
  712 + end
  713 +
  714 + def update_layout_template(template)
  715 + self.layout_template = template
  716 + self.save!
  717 + end
  718 +
  719 + before_create do |env|
  720 + env.settings[:themes] ||= %w[
  721 + aluminium
  722 + butter
  723 + chameleon
  724 + chocolate
  725 + noosfero
  726 + orange
  727 + plum
  728 + scarletred
  729 + skyblue
  730 + ]
  731 + end
  732 +
  733 + def community_template
  734 + template = Community.find_by_id settings[:community_template_id]
  735 + template if template && template.is_template
  736 + end
  737 +
  738 + def community_template=(value)
  739 + settings[:community_template_id] = value.id
  740 + end
  741 +
  742 + def person_template
  743 + template = Person.find_by_id settings[:person_template_id]
  744 + template if template && template.is_template
  745 + end
  746 +
  747 + def person_template=(value)
  748 + settings[:person_template_id] = value.id
  749 + end
  750 +
  751 + def enterprise_template
  752 + template = Enterprise.find_by_id settings[:enterprise_template_id]
  753 + template if template && template.is_template
  754 + end
  755 +
  756 + def enterprise_template=(value)
  757 + settings[:enterprise_template_id] = value.id
  758 + end
  759 +
  760 + def inactive_enterprise_template
  761 + template = Enterprise.find_by_id settings[:inactive_enterprise_template_id]
  762 + template if template && template.is_template
  763 + end
  764 +
  765 + def inactive_enterprise_template=(value)
  766 + settings[:inactive_enterprise_template_id] = value.id
  767 + end
  768 +
  769 + def replace_enterprise_template_when_enable
  770 + settings[:replace_enterprise_template_when_enable] || false
  771 + end
  772 +
  773 + def replace_enterprise_template_when_enable=(value)
  774 + settings[:replace_enterprise_template_when_enable] = value
  775 + end
  776 +
  777 + def portal_community
  778 + Community[settings[:portal_community_identifier]]
  779 + end
  780 +
  781 + def portal_community=(value)
  782 + settings[:portal_community_identifier] = value.nil? ? nil : value.identifier
  783 + end
  784 +
  785 + def unset_portal_community!
  786 + self.portal_community=nil
  787 + self.portal_folders=nil
  788 + self.news_amount_by_folder=nil
  789 + self.disable('use_portal_community')
  790 + self.save
  791 + end
  792 +
  793 + def is_portal_community?(profile)
  794 + portal_community == profile
  795 + end
  796 +
  797 + def portal_folders
  798 + (settings[:portal_folders] || []).map{|fid| portal_community.articles.find(:first, :conditions => { :id => fid }) }.compact
  799 + end
  800 +
  801 + def portal_folders=(folders)
  802 + settings[:portal_folders] = folders ? folders.map(&:id) : nil
  803 + end
  804 +
  805 + def portal_news_cache_key(language='en')
  806 + "home-page-news/#{cache_key}-#{language}"
  807 + end
  808 +
  809 + def notification_emails
  810 + [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email)
  811 + end
  812 +
  813 + after_create :create_templates
  814 +
  815 + def create_templates
  816 + prefix = self.name.to_slug + '_'
  817 +
  818 + enterprise_template = Enterprise.new(
  819 + :name => 'Enterprise template',
  820 + :identifier => prefix + 'enterprise_template'
  821 + )
  822 +
  823 + inactive_enterprise_template = Enterprise.new(
  824 + :name => 'Inactive Enterprise template',
  825 + :identifier => prefix + 'inactive_enterprise_template'
  826 + )
  827 +
  828 + community_template = Community.new(
  829 + :name => 'Community template',
  830 + :identifier => prefix + 'community_template'
  831 + )
  832 +
  833 + [
  834 + enterprise_template,
  835 + inactive_enterprise_template,
  836 + community_template
  837 + ].each do |profile|
  838 + profile.is_template = true
  839 + profile.visible = false
  840 + profile.environment = self
  841 + profile.save!
  842 + end
  843 +
  844 + pass = Digest::MD5.hexdigest rand.to_s
  845 + user = User.new(:login => (prefix + 'person_template'), :email => (prefix + 'template@template.noo'), :password => pass, :password_confirmation => pass)
  846 + user.environment = self
  847 + user.save!
  848 +
  849 + person_template = user.person
  850 + person_template.name = "Person template"
  851 + person_template.is_template = true
  852 + person_template.visible = false
  853 + person_template.save!
  854 +
  855 + self.enterprise_template = enterprise_template
  856 + self.inactive_enterprise_template = inactive_enterprise_template
  857 + self.community_template = community_template
  858 + self.person_template = person_template
  859 + self.save!
  860 + end
  861 +
  862 + after_create :create_default_licenses
  863 + def create_default_licenses
  864 + [
  865 + { :name => 'CC (by)', :url => 'http://creativecommons.org/licenses/by/3.0/legalcode'},
  866 + { :name => 'CC (by-nd)', :url => 'http://creativecommons.org/licenses/by-nd/3.0/legalcode'},
  867 + { :name => 'CC (by-sa)', :url => 'http://creativecommons.org/licenses/by-sa/3.0/legalcode'},
  868 + { :name => 'CC (by-nc)', :url => 'http://creativecommons.org/licenses/by-nc/3.0/legalcode'},
  869 + { :name => 'CC (by-nc-nd)', :url => 'http://creativecommons.org/licenses/by-nc-nd/3.0/legalcode'},
  870 + { :name => 'CC (by-nc-sa)', :url => 'http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode'},
  871 + { :name => 'Free Art', :url => 'http://artlibre.org/licence/lal/en'},
  872 + { :name => 'GNU FDL', :url => 'http://www.gnu.org/licenses/fdl-1.3.txt'},
  873 + ].each do |data|
  874 + license = License.new(data)
  875 + license.environment = self
  876 + license.save!
  877 + end
  878 + end
  879 +
  880 + def highlighted_products_with_image(options = {})
  881 + Product.find(:all, {:conditions => {:highlighted => true, :profile_id => self.enterprises.find(:all, :select => :id) }, :joins => :image}.merge(options))
  882 + end
  883 +
  884 + settings_items :home_cache_in_minutes, :type => :integer, :default => 5
  885 + settings_items :general_cache_in_minutes, :type => :integer, :default => 15
  886 + settings_items :profile_cache_in_minutes, :type => :integer, :default => 15
  887 +
  888 + def image_galleries
  889 + portal_community ? portal_community.image_galleries : []
  890 + end
  891 +
  892 + serialize :languages
  893 +
  894 + before_validation do |environment|
  895 + environment.default_language = nil if environment.default_language.blank?
  896 + end
  897 +
  898 + validate :default_language_available
  899 + validate :languages_available
  900 +
  901 + def locales
  902 + if languages.present?
  903 + languages.inject({}) {|r, l| r.merge({l => Noosfero.locales[l]})}
  904 + else
  905 + Noosfero.locales
  906 + end
  907 + end
  908 +
  909 + def default_locale
  910 + default_language || Noosfero.default_locale
  911 + end
  912 +
  913 + def available_locales
  914 + locales_list = locales.keys
  915 + # move English to the beginning
  916 + if locales_list.include?('en')
  917 + locales_list = ['en'] + (locales_list - ['en']).sort
  918 + end
  919 + locales_list
  920 + end
  921 +
  922 + private
  923 +
  924 + def default_language_available
  925 + if default_language.present? && !available_locales.include?(default_language)
  926 + errors.add(:default_language, _('is not available.'))
  927 + end
  928 + end
  929 +
  930 + def languages_available
  931 + if languages.present?
  932 + languages.each do |language|
  933 + if !Noosfero.available_locales.include?(language)
  934 + errors.add(:languages, _('have unsupported languages.'))
  935 + break
  936 + end
  937 + end
  938 + end
  939 + end
  940 +end