Class: Site

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Property, Property::Serialization::JSON, RubyLess, Zena::Use::MLIndex::SiteMethods
Defined in:
app/models/site.rb

Overview

A zena installation supports many sites. Each site is uniquely identified by it’s host name. The #Site model holds configuration information for a site:

host

Unique host name. (teti.ch, zenadmin.org, dev.example.org, …)

root_id

Site seed node id. This is the only node in the site without a parent.

home_id

This is the apparent root of the site (home page).

anon_id

Anonymous user id. This user is the ‘public’ user of the site. Even if authorize is set to true, this user is needed to configure the defaults for all newly created users.

public_group_id

Id of the ‘public’ group. Every user of the site (with ‘anonymous user’) belongs to this group.

site_group_id

Id of the ‘site’ group. Every user except anonymous are part of this group. This group can be seen as the ‘logged in users’ group.

name

Site name (used to display grouped information for cross sites users).

authorize

If this is set to true a login is required: anonymous visitor will not be allowed to browse the site as there is no login/password for the ‘anonymous user’.

languages

A comma separated list of the languages used for the current site. Do not insert spaces in this list.

default_lang

The default language of the site.

Constant Summary collapse

CLEANUP_SQL =
[
  ['attachments'         , 'site_id = ?'],
  ['cached_pages'        , 'site_id = ?'],
  ['cached_pages_nodes'  , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['caches'              , 'site_id = ?'],
  ['columns'             , 'site_id = ?'],
  ['comments'            , 'site_id = ?'],
  ['data_entries'        , 'site_id = ?'],
  ['discussions'         , 'site_id = ?'],
  ['groups_users'        , 'group_id IN (SELECT id FROM groups WHERE site_id = ?)'],
  ['groups'              , 'site_id = ?'],

  ['idx_nodes_datetimes' , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['idx_nodes_floats'    , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['idx_nodes_integers'  , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['idx_nodes_ml_strings', 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['idx_nodes_strings'   , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['idx_projects'        , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['idx_templates'       , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],

  ['iformats'            , 'site_id = ?'],
  ['links'               , 'source_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['links'               , 'target_id IN (SELECT id FROM nodes WHERE site_id = ?)'],

  ['nodes_roles'         , 'node_id IN (SELECT id FROM nodes WHERE site_id = ?)'],
  ['relations'           , 'site_id = ?'],
  ['roles'               , 'site_id = ?'],
  ['sites'               , 'id = ?'],
  ['users'               , 'site_id = ?'],
  ['versions'            , 'site_id = ?'],
  ['zips'                , 'site_id = ?'],
  ['nodes'               , 'site_id = ?'],
]
ACTIONS =
%w{clear_cache rebuild_index rebuild_fullpath}
PUBLIC_PATH =
Bricks.raw_config['public_path'] || '/public'
CACHE_PATH =
Bricks.raw_config['cache_path']  || '/public'
@@attributes_for_form =
{
  :bool => %w{authentication http_auth auto_publish ssl_on_auth site_readonly},
  :text => %w{languages default_lang},
}
@@alias_attributes_for_form =
{
  :bool => %w{authentication auto_publish ssl_on_auth},
  :text => %w{},
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Zena::Use::MLIndex::SiteMethods

included

Instance Attribute Details

#aliasObject

site alias (different settings + domain)



20
21
22
# File 'app/models/site.rb', line 20

def alias
  @alias
end

Class Method Details

.attributes_for_form(is_alias = false) ⇒ Object

List of attributes that can be configured in the admin form



250
251
252
# File 'app/models/site.rb', line 250

def attributes_for_form(is_alias = false)
  is_alias ? @@alias_attributes_for_form : @@attributes_for_form
end

.create_for_host(host, su_password, opts = {}) ⇒ Object

Create a new site in the database. This should not be called directly. Use rake zena:mksite HOST= instead

Raises:

  • (Exception)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'app/models/site.rb', line 93

def create_for_host(host, su_password, opts={})
  params = {
    :name                      => host.split('.').first,
    :authentication            => false,
    :auto_publish              => true,
    :redit_time                => '2h',
    :languages                 => '',
    :default_lang              => "en",
    :usr_prototype_attributes  => "{'klass' => 'Contact'}"
  }.merge(opts)
  langs = params[:languages].split(',').map(&:strip)
  langs += [params[:default_lang]] unless langs.include?(params[:default_lang])
  params[:languages] = langs.map{|l| l[0..1]}.join(',')
  params[:default_lang] = params[:default_lang][0..1]


  site      = self.new(params)
  site.host = host
  site.save
  site.instance_variable_set(:@being_created, true)

  if site.new_record?
    return site
  end

  # =========== CREATE zip counter ==========================
  connection.execute "INSERT INTO zips (site_id, zip) VALUES (#{site[:id]},0)"

  # =========== CREATE Admin User ===========================

  # create admin user
  admin_user = User.new_no_defaults(
    :login => 'admin',           :password => su_password,
    :lang  => site.default_lang, :status => User::Status[:admin])
  admin_user.site = site

  setup_visitor(admin_user, site)

  unless admin_user.save
    # rollback
    Zena::Db.execute "DELETE FROM #{Site.table_name} WHERE id = #{site.id}"
    Zena::Db.execute "DELETE FROM zips WHERE site_id = #{site.id}"
    raise Exception.new("Could not create admin user for site [#{host}] (site#{site[:id]})\n#{admin_user.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}")
  end

  # =========== CREATE PUBLIC, ADMIN, SITE GROUPS ===========
  # create public group
  pub = site.send(:secure,Group) { Group.create(:name => 'public') }
  raise Exception.new("Could not create public group for site [#{host}] (site#{site[:id]})\n#{pub.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if pub.new_record?

  # create admin group
  editors = site.send(:secure,Group) { Group.create( :name => 'editors') }
  raise Exception.new("Could not create editors group for site [#{host}] (site#{site[:id]})\n#{editors.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if editors.new_record?

  # add admin to the 'editors group'
  editors.users << admin_user

  # create site group
  sgroup = site.send(:secure,Group) { Group.create( :name => 'logged-in') }
  raise Exception.new("Could not create logged-in group for site [#{host}] (site#{site[:id]})\n#{sgroup.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if sgroup.new_record?

  site.public_group_id = pub[:id]
  site.site_group_id   = sgroup[:id]
  site.groups << pub << sgroup << editors

  # Reload group_ids in admin
  admin_user.reload_groups!

  # =========== CREATE Anonymous User =====================
  # create anon user

  anon = site.send(:secure, User) do
    User.new_no_defaults( :login => nil, :password => nil,
    :lang => site.default_lang, :status => User::Status[:moderated])
  end

  anon.site = site
  raise Exception.new("Could not create anonymous user for site [#{host}] (site#{site[:id]})\n#{anon.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") unless anon.save
  site[:anon_id] = anon[:id]

  # =========== CREATE ROOT NODE ============================

  root = site.send(:secure,Project) do
    Project.create( :title => site.name, :rgroup_id => pub[:id], :wgroup_id => sgroup[:id], :dgroup_id => editors[:id], :title => site.name, :v_status => Zena::Status::Pub)
  end

  raise Exception.new("Could not create root node for site [#{host}] (site#{site[:id]})\n#{root.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") if root.new_record?

  Node.connection.execute "UPDATE nodes SET section_id = id, project_id = id WHERE id = '#{root[:id]}'"

  raise Exception.new("Could not publish root node for site [#{host}] (site#{site[:id]})\n#{root.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") unless (root.v_status == Zena::Status::Pub || root.publish)

  site.home_id = root[:id]
  site.root_id = root[:id]
  
  # Make sure safe definitions on Time/Array/String are available on prop_eval validation.
  Zena::Use::ZafuSafeDefinitions
  # Should not be needed since we load PropEval in Node, but it does not work
  # without when doing 'mksite' (works in tests).
  Node.safe_method :now => {:class => Time, :method => 'Time.now'}

  # =========== UPDATE SITE =================================
  # save site definition
  raise Exception.new("Could not save site definition for site [#{host}] (site#{site[:id]})\n#{site.errors.map{|k,v| "[#{k}] #{v}"}.join("\n")}") unless site.save

  # =========== LOAD INITIAL DATA (default skin + roles) =============

  nodes = site.send(:secure, Node) { Node.create_nodes_from_folder(:folder => File.join(Zena::ROOT, 'db', 'init', 'base'), :parent_id => root[:id], :defaults => { :v_status => Zena::Status::Pub, :rgroup_id => pub[:id], :wgroup_id => sgroup[:id], :dgroup_id => editors[:id] } ) }.values
  # == set skin id to 'default' for all elements in the site == #
  skin = nodes.detect {|n| n.kind_of?(Skin) }
  Node.connection.execute "UPDATE nodes SET skin_id = '#{skin.id}' WHERE site_id = '#{site[:id]}'"

  # =========== CREATE CONTACT PAGES ==============
  {
    admin_user => {'first_name' => 'Admin',     'last_name' => 'User'},
    anon       => {'first_name' => 'Anonymous', 'last_name' => 'User'}
  }.each do |user, attrs|
    # forces @node creation
    user.node_attributes = attrs
    user.send(:create_node)
    user.save!
  end

  # == done.
  Site.logger.info "=========================================================="
  Site.logger.info "  NEW SITE CREATED FOR [#{host}] (site#{site[:id]})"
  Site.logger.info "=========================================================="

  site.instance_variable_set(:@being_created, false)
  site
end

.find_by_host(host) ⇒ Object



229
230
231
232
233
234
235
236
# File 'app/models/site.rb', line 229

def find_by_host(host)
  host = $1 if host =~ /^(.*)\.$/
  if site = self.find(:first, :conditions => ['host = ?', host]) rescue nil
    setup_master(site)
  else
    nil
  end
end

.master_sitesObject



225
226
227
# File 'app/models/site.rb', line 225

def master_sites
  Site.all(:conditions => ['master_id is NULL'])
end

.setup_master(site) ⇒ Object



238
239
240
241
242
243
244
245
246
247
# File 'app/models/site.rb', line 238

def setup_master(site)
  if id = site.master_id
    # The loaded site is an alias, load master site.
    master = self.find(:first, :conditions => ['id = ?', id])
    master.alias = site
    master
  else
    site
  end
end

Instance Method Details

#admin_user_idsObject

Return the ids of the administrators of the current site.



330
331
332
333
# File 'app/models/site.rb', line 330

def admin_user_ids
  # TODO: PERFORMANCE admin_user_ids could be cached in the 'site' record.
  @admin_user_ids ||= secure!(User) { User.find(:all, :conditions => "status >= #{User::Status[:admin]}") }.map {|r| r[:id]}
end

#anonObject

Return the anonymous user, the one used by anonymous visitors to visit the public part of the site.



289
290
291
# File 'app/models/site.rb', line 289

def anon
  @anon ||= User.find_by_id_and_site_id(self[:anon_id], self.id)
end

#any_adminObject

Return an admin user, this user is used to rebuild index/vhash/etc.



294
295
296
# File 'app/models/site.rb', line 294

def any_admin
  @any_admin ||= User.find_by_status_and_site_id(User::Status[:admin], self.id)
end

#api_groupObject

Return the API group: the one in which API visitors must be to use the API.



320
321
322
# File 'app/models/site.rb', line 320

def api_group
  @api_group ||= secure(Group) { Group.find_by_id(self[:api_group_id]) }
end

#authentication?Boolean

Return true if the site is configured to force authentication

Returns:

  • (Boolean)


390
391
392
# File 'app/models/site.rb', line 390

def authentication?
  @alias && @alias[:authentication] || self[:authentication]
end

#auto_publish?Boolean

Return true if the site is configured to automatically publish redactions

Returns:

  • (Boolean)


385
386
387
# File 'app/models/site.rb', line 385

def auto_publish?
  @alias && @alias[:auto_publish] || self[:auto_publish]
end

#being_created?Boolean

Returns:

  • (Boolean)


447
448
449
# File 'app/models/site.rb', line 447

def being_created?
  @being_created
end

#cache_pathObject

This is the place where cached files should be stored in case we do not want to store the cached file inside the public directory.



272
273
274
# File 'app/models/site.rb', line 272

def cache_path
  "/#{host}#{CACHE_PATH}"
end

#clear_cache(should_clear_zafu = true) ⇒ Object



491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'app/models/site.rb', line 491

def clear_cache(should_clear_zafu = true)
  paths = ["#{SITES_ROOT}#{self.cache_path}"]
  aliases = Site.all(:conditions => {:master_id => self.id})
  aliases.each do |site|
    paths << "#{SITES_ROOT}#{site.cache_path}"
  end
  Site.logger.error("\n-----------------\nCLEAR CACHE FOR SITE #{host} (#{aliases.map(&:host).join(', ')})\n-----------------\n")

  paths.each do |path|
    if File.exist?(path)
      # First remove DB entries so that we do not risk race condition where a cached page is created during
      # filesystem operation and before.
      Zena::Db.execute "DELETE FROM caches WHERE site_id = #{self[:id]}"
      Zena::Db.execute "DELETE FROM cached_pages_nodes WHERE cached_pages_nodes.node_id IN (SELECT nodes.id FROM nodes WHERE nodes.site_id = #{self[:id]})"
      Zena::Db.execute "DELETE FROM cached_pages WHERE site_id = #{self[:id]}"
    
      Dir.foreach(path) do |elem|
        next unless elem =~ /^(\w\w\.html|\w\w|login\.html)$/
        FileUtils.rmtree(File.join(path, elem))
      end
    end
  end
  
  clear_zafu if should_clear_zafu

  true
end

#clear_zafuObject



519
520
521
522
523
524
# File 'app/models/site.rb', line 519

def clear_zafu
  path = "#{SITES_ROOT}#{self.zafu_path}"
  if File.exist?(path)
    FileUtils.rmtree(path)
  end
end

#create_alias(hostname) ⇒ Object



434
435
436
437
438
439
440
441
442
443
444
# File 'app/models/site.rb', line 434

def create_alias(hostname)
  raise "Hostname '#{hostname}' already exists" if Site.find_by_host(hostname)
  ali = Site.new(self.attributes)
  ali.host = hostname
  ali.master_id = self.id
  ali.root_id   = self.root_id
  ali.home_id   = self.home_id
  ali.prop      = self.prop
  ali.save
  ali
end

#data_pathObject

Return path for documents data: RAILS_ROOT/sites/host/data You can symlink the ‘data’ directory if you need to keep the data in some other place.



278
279
280
# File 'app/models/site.rb', line 278

def data_path
  "/#{master_host}/data"
end

#home_idObject



394
395
396
# File 'app/models/site.rb', line 394

def home_id
  @home_id ||= @alias && @alias[:home_id] || self[:home_id] || self[:root_id]
end

#home_nodeObject

Return the home node.



305
306
307
# File 'app/models/site.rb', line 305

def home_node
  @home ||= secure(Node) { Node.find(home_id) } || Node.new(:title => host)
end

#home_zipObject



398
399
400
# File 'app/models/site.rb', line 398

def home_zip
  home_node.zip
end

#home_zip=(zip) ⇒ Object



402
403
404
405
406
407
408
# File 'app/models/site.rb', line 402

def home_zip=(zip)
  if id = secure(Node) { Node.translate_pseudo_id(zip) }
    self[:home_id] = id
  else
    @home_zip_error = _('could not be found')
  end
end

#hostObject

Host with aliasing (returns alias host if alias is loaded)



376
377
378
# File 'app/models/site.rb', line 376

def host
  @alias && @alias.host || master_host
end

#iformatsObject



455
456
457
458
459
460
461
462
463
464
# File 'app/models/site.rb', line 455

def iformats
 @iformats ||= begin
   $iformats ||= {} # mem cache
   site_formats = $iformats[self[:id]]
   if !site_formats || self[:formats_updated_at] != site_formats[:updated_at]
     site_formats = $iformats[self[:id]] = Iformat.formats_for_site(self[:id]) # reload
   end
   site_formats
  end
end

#iformats_updated!Object



466
467
468
469
470
471
# File 'app/models/site.rb', line 466

def iformats_updated!
  Zena::Db.execute "UPDATE sites SET formats_updated_at = (SELECT updated_at FROM iformats WHERE site_id = #{self[:id]} ORDER BY iformats.updated_at DESC LIMIT 1) WHERE id = #{self[:id]}"
  if $iformats
    $iformats[self[:id]] = @iformats = nil
  end
end

#is_admin?(user) ⇒ Boolean

Return true if the given user is an administrator for this site.

Returns:

  • (Boolean)


325
326
327
# File 'app/models/site.rb', line 325

def is_admin?(user)
  admin_user_ids.include?(user[:id])
end

#is_alias?Boolean

Alias handling

Returns:

  • (Boolean)


366
367
368
# File 'app/models/site.rb', line 366

def is_alias?
  !self[:master_id].blank?
end

#lang_listObject

Return an array with the languages for the site.



361
362
363
# File 'app/models/site.rb', line 361

def lang_list
  (self[:languages] || "").split(',').map(&:strip)
end

#languages=(s) ⇒ Object



451
452
453
# File 'app/models/site.rb', line 451

def languages=(s)
  self[:languages] = s.split(',').map(&:strip).join(',')
end

#master_hostObject

This is the host of the master site.



371
372
373
# File 'app/models/site.rb', line 371

def master_host
  self[:host]
end

#protected_group_idsObject

ids of the groups that cannot be removed



351
352
353
# File 'app/models/site.rb', line 351

def protected_group_ids
  [site_group_id, public_group_id]
end

#protected_user_idsObject

ids of the users that cannot be removed



356
357
358
# File 'app/models/site.rb', line 356

def protected_user_ids
  [anon_id, visitor.id] # cannot remove self
end

#public_groupObject

Return the public group: the one in which every visitor belongs.



310
311
312
# File 'app/models/site.rb', line 310

def public_group
  @public_group ||= secure(Group) { Group.find(self[:public_group_id]) }
end

#public_pathObject

Return path for static/cached content served by proxy: RAILS_ROOT/sites/host/public If you need to serve from another directory, we do not store the path into the sites table for security reasons. The easiest way around this limitation is to symlink the ‘public’ directory.



266
267
268
# File 'app/models/site.rb', line 266

def public_path
  "/#{host}#{PUBLIC_PATH}"
end

#rebuild_fullpath(nodes = nil, page = nil, page_count = nil) ⇒ Object

Rebuild fullpath cache for the Site. This method uses the Worker thread to rebuild.

The visitor used during index rebuild should be an admin user.



546
547
548
549
550
551
552
553
554
555
556
557
558
# File 'app/models/site.rb', line 546

def rebuild_fullpath(nodes = nil, page = nil, page_count = nil)
  if !page
    Zena::SiteWorker.perform(self, :rebuild_fullpath)
  else
    if page == 1
      Site.logger.error("\n----------------- REBUILD FULLPATH FOR SITE #{host} (#{Node.count(:conditions => {:site_id => id})} nodes)-----------------\n")
      # Rebuild all paths at once (no pagination because of recursion)
      Zena::Use::Ancestry.rebuild_all_paths(root_node)
    end
  end

  true
end

#rebuild_index(nodes = nil, page = nil, page_count = nil) ⇒ Object

Rebuild property indices for the Site. This method uses the Worker thread to rebuild and works on chunks of 50 nodes.

The visitor used during index rebuild should be an admin user (to index unpublished templates).



565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
# File 'app/models/site.rb', line 565

def rebuild_index(nodes = nil, page = nil, page_count = nil)
  if !page
    Zena::SiteWorker.perform(self, :rebuild_index)
  else
    if page == 1
      Site.logger.error("\n----------------- REBUILD INDEX FOR SITE #{host} -----------------\n")
      # Reset reference to cache origin to make sure it is always overwritten
      Zena::Use::ScopeIndex::AVAILABLE_MODELS.each do |klass|
        changes = klass.column_names.select{|n| n =~ %r{(.*)_id}}.reject {|n| %w{node_id site_id}.include?(n)}.map do |c|
          "#{c} = NULL"
        end.join(', ')
        Site.logger.error("#{klass.name}: reset #{changes}\n")
        Zena::Db.execute "UPDATE #{klass.table_name} SET #{changes} WHERE site_id = #{id}"
      end
    end
    # do things
    nodes.each do |node|
      node.rebuild_index!
    end
  end

  true
end

#rebuild_vhash(nodes = nil, page = nil, page_count = nil) ⇒ Object

Rebuild vhash indices for the Site. This method uses the Worker thread to rebuild and works on chunks of 50 nodes.



528
529
530
531
532
533
534
535
536
537
538
539
540
541
# File 'app/models/site.rb', line 528

def rebuild_vhash(nodes = nil, page = nil, page_count = nil)
  if !nodes
    Site.logger.error("\n----------------- REBUILD VHASH FOR SITE #{host} -----------------\n")
    Zena::SiteWorker.perform(self, :rebuild_vhash)
  else
    # do things
    nodes.each do |node|
      node.rebuild_vhash
      Node.connection.execute "UPDATE nodes SET publish_from = #{Node.connection.quote(node.publish_from)}, vhash = #{Node.connection.quote(node.vhash.to_json)} WHERE id = #{node.id}"
    end
  end

  true
end

#redit_timeObject

Return the time between version updates below which no new version is created. This returns a string of the form “3 hours 45 minutes”



346
347
348
# File 'app/models/site.rb', line 346

def redit_time
  (self[:redit_time] || 0).as_duration
end

#redit_time=(val) ⇒ Object

Set redit time from a string of the form “1d 4h 5s” or “4 days”



336
337
338
339
340
341
342
# File 'app/models/site.rb', line 336

def redit_time=(val)
  if val.kind_of?(String)
    self[:redit_time] = val.to_duration
  else
    self[:redit_time] = val
  end
end

#remove_from_dbObject

This is only called from the console (not accessible through controllers)



590
591
592
593
594
595
596
597
598
599
600
601
602
# File 'app/models/site.rb', line 590

def remove_from_db
  node_cleanup = nil
  site_id = self.id.to_s
  CLEANUP_SQL.each do |table, clause|
    clause = clause.gsub('?', site_id)
    begin
      Zena::Db.execute("DELETE FROM #{table} WHERE (#{clause})")
    rescue => err
      puts clause
      puts err
    end
  end
end

#root_nodeObject

Return the root node or a dummy if the visitor cannot view root node (such as during a 404 or login rendering).



300
301
302
# File 'app/models/site.rb', line 300

def root_node
  @root ||= secure(Node) { Node.find(root_id) } || Node.new(:title => host)
end

#site_groupObject

Return the site group: the one in which every visitor except ‘anonymous’ belongs (= all logged in users).



315
316
317
# File 'app/models/site.rb', line 315

def site_group
  @site_group ||= secure(Group) { Group.find(self[:site_group_id]) }
end

#skinObject



426
427
428
# File 'app/models/site.rb', line 426

def skin
  secure(Skin) { Skin.find_by_id(skin_id) }
end

#skin_idObject



430
431
432
# File 'app/models/site.rb', line 430

def skin_id
  @alias && @alias[:skin_id] || self[:skin_id]
end

#skin_zipObject



410
411
412
# File 'app/models/site.rb', line 410

def skin_zip
  skin ? skin.zip : nil
end

#skin_zip=(zip) ⇒ Object



414
415
416
417
418
419
420
421
422
423
424
# File 'app/models/site.rb', line 414

def skin_zip=(zip)
  if zip.blank?
    self[:skin_id] = nil
  else
    if id = secure(Node) { Node.translate_pseudo_id(zip) }
      self[:skin_id] = id
    else
      @skin_zip_error = _('could not be found')
    end
  end
end

#ssl_on_authObject



380
381
382
# File 'app/models/site.rb', line 380

def ssl_on_auth
  @alias && @alias.prop['ssl_on_auth'] || self.prop['ssl_on_auth']
end

#virtual_classesObject



473
474
475
476
477
478
479
480
481
482
# File 'app/models/site.rb', line 473

def virtual_classes
 @iformats ||= begin
   $iformats ||= {} # mem cache
   site_formats = $iformats[self[:id]]
   if !site_formats || self[:formats_updated_at] != site_formats[:updated_at]
     site_formats = $iformats[self[:id]] = Iformat.formats_for_site(self[:id]) # reload
   end
   site_formats
  end
end

#zafu_pathObject

Return the path for zafu rendered templates: RAILS_ROOT/sites/host/zafu



283
284
285
# File 'app/models/site.rb', line 283

def zafu_path
  "/#{master_host}/zafu"
end