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}
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},
  :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



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

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)


92
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
# File 'app/models/site.rb', line 92

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.instance_variable_set(:@group_ids, nil)

  # =========== 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



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

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



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

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

.setup_master(site) ⇒ Object



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

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.



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

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.



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

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.



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

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.



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

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)


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

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

#auto_publish?Boolean

Return true if the site is configured to automatically publish redactions

Returns:

  • (Boolean)


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

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

#being_created?Boolean

Returns:

  • (Boolean)


422
423
424
# File 'app/models/site.rb', line 422

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.



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

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

#clear_cache(clear_zafu = true) ⇒ Object



466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'app/models/site.rb', line 466

def clear_cache(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)
      Dir.foreach(path) do |elem|
        next unless elem =~ /^(\w\w\.html|\w\w|login\.html)$/
        FileUtils.rmtree(File.join(path, elem))
      end

      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]}"
    end
  end
  
  # Clear zafu
  if clear_zafu
    paths = ["#{SITES_ROOT}#{self.zafu_path}"]
    aliases.each do |site|
      paths << "#{SITES_ROOT}#{site.cache_path}"
    end
    paths.each do |path|
      if File.exist?(path)
        FileUtils.rmtree(path)
      end
    end
  end

  true
end

#create_alias(hostname) ⇒ Object



409
410
411
412
413
414
415
416
417
418
419
# File 'app/models/site.rb', line 409

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.



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

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

#home_idObject



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

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

#home_nodeObject

Return the home node.



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

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

#home_zipObject



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

def home_zip
  home_node.zip
end

#home_zip=(zip) ⇒ Object



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

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)



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

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

#iformatsObject



430
431
432
433
434
435
436
437
438
439
# File 'app/models/site.rb', line 430

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



441
442
443
444
445
446
# File 'app/models/site.rb', line 441

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)


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

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

#is_alias?Boolean

Alias handling

Returns:

  • (Boolean)


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

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

#lang_listObject

Return an array with the languages for the site.



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

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

#languages=(s) ⇒ Object



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

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

#master_hostObject

This is the host of the master site.



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

def master_host
  self[:host]
end

#protected_group_idsObject

ids of the groups that cannot be removed



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

def protected_group_ids
  [site_group_id, public_group_id]
end

#protected_user_idsObject

ids of the users that cannot be removed



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

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.



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

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.



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

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

#rebuild_fullpath(parent_id = nil, parent_fullpath = "", parent_basepath = "", start = []) ⇒ Object

Recreates the fullpath (‘/zip/zip/zip’). TODO: find a way to use SiteWorker (need to remove get_nodes): fix rake when this is done.



522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File 'app/models/site.rb', line 522

def rebuild_fullpath(parent_id = nil, parent_fullpath = "", parent_basepath = "", start=[])
  raise Zena::InvalidRecord, "Infinit loop in 'ancestors' (#{start.inspect} --> #{parent_id})" if start.include?(parent_id)
  start += [parent_id]
  i = 0
  batch_size = 100
  children = []
  while true
    rec = Zena::Db.fetch_attributes(['id', 'fullpath', 'basepath', 'custom_base', 'zip'], 'nodes', "parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"} AND site_id = #{self.id} ORDER BY id ASC LIMIT #{batch_size} OFFSET #{i * batch_size}")
    break if rec.empty?
    rec.each do |rec|
      if parent_id
        rec['fullpath'] = parent_fullpath == '' ? rec['zip'] : "#{parent_fullpath}/#{rec['zip']}"
      else
        # root node
        rec['fullpath'] = ''
      end

      if rec['custom_base'] == Zena::Db::TRUE_RESULT
        rec['basepath'] = rec['fullpath']
      else
        rec['basepath'] = parent_basepath
      end

      id = rec.delete('id')
      children << [id, rec['fullpath'], rec['basepath'], start]
      Zena::Db.execute "UPDATE nodes SET #{rec.map {|k,v| "#{Zena::Db.connection.quote_column_name(k)}=#{Zena::Db.quote(v)}"}.join(', ')} WHERE id = #{id}"
    end
    # 50 more
    i += 1
  end
  children.each do |child|
    rebuild_fullpath(*child)
  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).



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

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.



505
506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'app/models/site.rb', line 505

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”



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

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”



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

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)



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

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).



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

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).



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

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

#ssl_on_authObject



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

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

#virtual_classesObject



448
449
450
451
452
453
454
455
456
457
# File 'app/models/site.rb', line 448

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



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

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