app/models/theme_asset.rb in locomotive_cms-0.0.3.3 vs app/models/theme_asset.rb in locomotive_cms-0.0.4.beta1
- old
+ new
@@ -1,94 +1,138 @@
class ThemeAsset
-
+
include Locomotive::Mongoid::Document
-
- ## Extensions ##
- include Models::Extensions::Asset::Vignette
-
+
## fields ##
- field :slug
+ field :local_path
field :content_type
field :width, :type => Integer
field :height, :type => Integer
field :size, :type => Integer
+ field :folder, :default => nil
+ field :hidden, :type => Boolean, :default => false
mount_uploader :source, ThemeAssetUploader
-
+
## associations ##
- belongs_to_related :site
-
+ referenced_in :site
+
+ ## indexes ##
+ index :site_id
+ index [[:site_id, Mongo::ASCENDING], [:local_path, Mongo::ASCENDING]]
+
## callbacks ##
- before_validate :sanitize_slug
- before_validate :store_plain_text
- before_save :set_slug
-
+ before_validation :store_plain_text
+ before_save :sanitize_folder
+ before_save :build_local_path
+
## validations ##
- validate :extname_can_not_be_changed
validates_presence_of :site, :source
- validates_presence_of :slug, :if => Proc.new { |a| a.new_record? && a.performing_plain_text? }
- validates_uniqueness_of :slug, :scope => [:site_id, :content_type]
+ validates_presence_of :plain_text_name, :if => Proc.new { |a| a.performing_plain_text? }
+ validates_uniqueness_of :local_path, :scope => :site_id
validates_integrity_of :source
-
+ validate :content_type_can_not_changed
+
+ ## named scopes ##
+ scope :visible, lambda { |all| all ? {} : { :where => { :hidden => false } } }
+
## accessors ##
- attr_accessor :performing_plain_text
-
+ attr_accessor :plain_text_name, :plain_text, :performing_plain_text
+
## methods ##
-
- %w{movie image stylesheet javascript}.each do |type|
+
+ %w{movie image stylesheet javascript font}.each do |type|
define_method("#{type}?") do
self.content_type == type
- end
+ end
end
-
- def plain_text
- @plain_text ||= (if self.stylesheet? || self.javascript?
- self.source.read
+
+ def stylesheet_or_javascript?
+ self.stylesheet? || self.javascript?
+ end
+
+ def local_path(short = false)
+ if short
+ self.read_attribute(:local_path).gsub(/^#{self.content_type.pluralize}\//, '')
else
- nil
- end)
+ self.read_attribute(:local_path)
+ end
end
-
- def plain_text=(source)
- self.performing_plain_text = true if self.performing_plain_text.nil?
- @plain_text = source
+
+ def plain_text_name
+ if not @plain_text_name_changed
+ @plain_text_name ||= self.safe_source_filename
+ end
+ @plain_text_name.gsub(/(\.[a-z0-9A-Z]+)$/, '') rescue nil
end
-
+
+ def plain_text_name=(name)
+ @plain_text_name_changed = true
+ @plain_text_name = name
+ end
+
+ def plain_text
+ @plain_text ||= self.source.read
+ end
+
def performing_plain_text?
- return true if !self.new_record? && !self.image? && !self.movie? && self.errors.empty?
-
- !(self.performing_plain_text.blank? || self.performing_plain_text == 'false' || self.performing_plain_text == false)
+ Boolean.set(self.performing_plain_text) || false
end
-
+
def store_plain_text
- return if self.plain_text.blank?
-
- self.source = CarrierWave::SanitizedFile.new({
- :tempfile => StringIO.new(self.plain_text),
- :filename => "#{self.slug}.#{self.stylesheet? ? 'css' : 'js'}"
+ data = self.performing_plain_text? ? self.plain_text : self.source.read
+
+ return if !self.stylesheet_or_javascript? || self.plain_text_name.blank? || data.blank?
+
+ sanitized_source = self.escape_shortcut_urls(data)
+
+ self.source = CarrierWave::SanitizedFile.new({
+ :tempfile => StringIO.new(sanitized_source),
+ :filename => "#{self.plain_text_name}.#{self.stylesheet? ? 'css' : 'js'}"
})
end
-
+
def to_liquid
{ :url => self.source.url }.merge(self.attributes)
end
-
+
protected
-
- def sanitize_slug
- self.slug.slugify!(:underscore => true) if self.slug.present?
+
+ def safe_source_filename
+ self.source_filename || self.source.send(:original_filename) rescue nil
end
-
- def set_slug
- if self.slug.blank?
- self.slug = File.basename(self.source_filename, File.extname(self.source_filename))
- self.sanitize_slug
+
+ def sanitize_folder
+ self.folder = self.content_type.pluralize if self.folder.blank?
+
+ # no accents, no spaces, no leading and ending trails
+ self.folder = ActiveSupport::Inflector.transliterate(self.folder).gsub(/(\s)+/, '_').gsub(/^\//, '').gsub(/\/$/, '').downcase
+
+ # folder should begin by a root folder
+ if (self.folder =~ /^(stylesheets|javascripts|images|media|fonts)/).nil?
+ self.folder = File.join(self.content_type.pluralize, self.folder)
end
end
-
- def extname_can_not_be_changed
- return if self.new_record?
-
- if File.extname(self.source.file.original_filename) != File.extname(self.source_filename)
- self.errors.add(:source, :extname_changed)
+
+ def build_local_path
+ self.local_path = File.join(self.folder, self.safe_source_filename)
+ end
+
+ def escape_shortcut_urls(text)
+ return if text.blank?
+
+ text.gsub(/[("'](\/(stylesheets|javascripts|images|media)\/((.+)\/)*([a-z_\-0-9]+)\.[a-z]{2,3})[)"']/) do |path|
+
+ sanitized_path = path.gsub(/[("')]/, '').gsub(/^\//, '')
+
+ if asset = self.site.theme_assets.where(:local_path => sanitized_path).first
+ "#{path.first}#{asset.source.url}#{path.last}"
+ else
+ path
+ end
end
end
-end
\ No newline at end of file
+
+ def content_type_can_not_changed
+ self.errors.add(:source, :extname_changed) if !self.new_record? && self.content_type_changed?
+ end
+
+end