Class: DocumentContent

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
RubyLess, Zena::Refactor::ActAsContent
Defined in:
app/models/document_content.rb

Overview

Used by Document and Image to store file data. See the documentation on these classes for more information.

Attributes

Provides the following attributes to Document and Image :

size

file size

ext

file extension

content_type

file content_type

Direct Known Subclasses

ImageContent, TextDocumentContent

Instance Method Summary collapse

Instance Method Details

#can_destroy?Boolean

Return true if this content is not used by any version.

Returns:

  • (Boolean)


86
87
88
# File 'app/models/document_content.rb', line 86

def can_destroy?
  0 == self.class.count_by_sql("SELECT COUNT(*) FROM versions WHERE id = #{self[:version_id]} OR content_id = #{self[:version_id]}")
end

#changed?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'app/models/document_content.rb', line 61

def changed?
  @new_file || super
end

#cloneObject



45
46
47
48
49
# File 'app/models/document_content.rb', line 45

def clone
  new_obj = super
  new_obj.instance_variable_set(:@loaded_file, self.file)
  new_obj
end

#file(mode = nil) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'app/models/document_content.rb', line 51

def file(mode=nil)
  if mode.nil? && @new_file
    @new_file
  elsif File.exist?(filepath(mode))
    @loaded_file ||= File.new(filepath(mode))
  else
    raise IOError, "File not found"
  end
end

#file=(file) ⇒ Object



41
42
43
# File 'app/models/document_content.rb', line 41

def file=(file)
  @new_file = file
end

#filepath(format = nil) ⇒ Object

Path to store the data. The path is build with the version id so we can do the security checks when uploading data.

Raises:

  • (StandardError)


76
77
78
79
80
81
82
83
# File 'app/models/document_content.rb', line 76

def filepath(format=nil)
  raise StandardError, "Cannot build filepath for unsaved document_content." if new_record?
  mode   = format ? (format[:size] == :keep ? 'full' : format[:name]) : 'full'
  digest = Digest::SHA1.hexdigest(self[:id].to_s)
  # make sure name is not corrupted
  fname = name.gsub(/[^a-zA-Z\-_0-9]/,'')
  "#{SITES_ROOT}#{current_site.data_path}/#{mode}/#{digest[0..0]}/#{digest[1..1]}/#{digest[2..2]}/#{fname}"
end

#size(mode = nil) ⇒ Object



66
67
68
69
70
71
72
73
# File 'app/models/document_content.rb', line 66

def size(mode=nil)
  return self[:size] if self[:size]
  if !new_record? && File.exist?(filepath)
    self[:size] = File.stat(filepath).size
    self.save
  end
  self[:size]
end

#size=(s) ⇒ Object

protect access to size.

Raises:

  • (StandardError)


37
38
39
# File 'app/models/document_content.rb', line 37

def size=(s)
  raise StandardError, "Size cannot be set. It is defined by the file size."
end

#would_edit?(new_attrs) ⇒ Boolean

Return true if the version would be edited by the attributes

Returns:

  • (Boolean)


91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'app/models/document_content.rb', line 91

def would_edit?(new_attrs)
  new_attrs.each do |k,v|
    if k == 'file'
      return true if (v.respond_to?(:size) ? v.size : File.size(v.path)) != self.size
      same = v.read(24) == self.file.read(24) && v.read == self.file.read
      v.rewind
      self.file.rewind
      return true if !same
    elsif type = self.class.safe_method_type([k])
      return true if field_changed?(k, self.send(type[:method]), v)
    end
  end
  false
end