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