Allow theme field object model to support uploads

This commit is contained in:
Sam
2017-05-08 11:38:48 -04:00
parent 26209354e3
commit f709899a1d
6 changed files with 53 additions and 6 deletions

View File

@ -23,12 +23,13 @@ module Jobs
.joins("LEFT JOIN user_profiles up ON up.profile_background = uploads.url OR up.card_background = uploads.url") .joins("LEFT JOIN user_profiles up ON up.profile_background = uploads.url OR up.card_background = uploads.url")
.joins("LEFT JOIN categories c ON c.uploaded_logo_id = uploads.id OR c.uploaded_background_id = uploads.id") .joins("LEFT JOIN categories c ON c.uploaded_logo_id = uploads.id OR c.uploaded_background_id = uploads.id")
.joins("LEFT JOIN custom_emojis ce ON ce.upload_id = uploads.id") .joins("LEFT JOIN custom_emojis ce ON ce.upload_id = uploads.id")
.joins("LEFT JOIN theme_fields tf ON tf.upload_id = uploads.id")
.where("pu.upload_id IS NULL") .where("pu.upload_id IS NULL")
.where("u.uploaded_avatar_id IS NULL") .where("u.uploaded_avatar_id IS NULL")
.where("ua.gravatar_upload_id IS NULL AND ua.custom_upload_id IS NULL") .where("ua.gravatar_upload_id IS NULL AND ua.custom_upload_id IS NULL")
.where("up.profile_background IS NULL AND up.card_background IS NULL") .where("up.profile_background IS NULL AND up.card_background IS NULL")
.where("c.uploaded_logo_id IS NULL AND c.uploaded_background_id IS NULL") .where("c.uploaded_logo_id IS NULL AND c.uploaded_background_id IS NULL")
.where("ce.upload_id IS NULL") .where("ce.upload_id IS NULL AND tf.upload_id IS NULL")
.where("uploads.url NOT IN (?)", ignore_urls) .where("uploads.url NOT IN (?)", ignore_urls)
result.find_each do |upload| result.find_each do |upload|

View File

@ -243,7 +243,7 @@ class Theme < ActiveRecord::Base
@changed_colors ||= [] @changed_colors ||= []
end end
def set_field(target:, name:, value:, type: nil, type_id: nil) def set_field(target:, name:, value: nil, type: nil, type_id: nil, upload_id: nil)
name = name.to_s name = name.to_s
target_id = Theme.targets[target.to_sym] target_id = Theme.targets[target.to_sym]
@ -252,6 +252,12 @@ class Theme < ActiveRecord::Base
type_id ||= type ? ThemeField.types[type.to_sym] : ThemeField.guess_type(name) type_id ||= type ? ThemeField.types[type.to_sym] : ThemeField.guess_type(name)
raise "Unknown type #{type} passed to set field" unless type_id raise "Unknown type #{type} passed to set field" unless type_id
if upload_id && !value
value = ""
end
raise "Missing value for theme field" unless value
field = theme_fields.find{|f| f.name==name && f.target_id == target_id && f.type_id == type_id} field = theme_fields.find{|f| f.name==name && f.target_id == target_id && f.type_id == type_id}
if field if field
if value.blank? if value.blank?
@ -263,7 +269,7 @@ class Theme < ActiveRecord::Base
end end
end end
else else
theme_fields.build(target_id: target_id, value: value, name: name, type_id: type_id) if value.present? theme_fields.build(target_id: target_id, value: value, name: name, type_id: type_id, upload_id: upload_id) if value.present? || upload_id.present?
end end
end end

View File

@ -1,5 +1,7 @@
class ThemeField < ActiveRecord::Base class ThemeField < ActiveRecord::Base
belongs_to :upload
def self.types def self.types
@types ||= Enum.new(html: 0, @types ||= Enum.new(html: 0,
scss: 1, scss: 1,

View File

@ -7,6 +7,13 @@ module GlobalPath
"#{GlobalSetting.cdn_url}#{path(p)}" "#{GlobalSetting.cdn_url}#{path(p)}"
end end
def upload_cdn_path(p)
if SiteSetting.s3_cdn_url.present?
p = p.sub(Discourse.store.absolute_base_url, SiteSetting.s3_cdn_url)
end
p =~ /^http/ ? p : cdn_path(p)
end
def cdn_relative_path(path) def cdn_relative_path(path)
if (cdn_url = GlobalSetting.cdn_url).present? if (cdn_url = GlobalSetting.cdn_url).present?
URI.parse(cdn_url).path + path URI.parse(cdn_url).path + path

View File

@ -1,7 +1,9 @@
require_dependency 'stylesheet/common' require_dependency 'stylesheet/common'
require_dependency 'global_path'
module Stylesheet module Stylesheet
class Importer < SassC::Importer class Importer < SassC::Importer
include GlobalPath
@special_imports = {} @special_imports = {}
@ -40,10 +42,17 @@ module Stylesheet
contents << "$#{n}: ##{hex} !default;\n" contents << "$#{n}: ##{hex} !default;\n"
end end
theme&.theme_fields&.where(type_id: ThemeField.theme_var_type_ids)&.each do |field| theme&.theme_fields&.where(type_id: ThemeField.theme_var_type_ids)&.each do |field|
if field.type_id == ThemeField.types[:theme_upload_var]
if upload = field.upload
url = upload_cdn_path(upload.url)
contents << "$#{field.name}: unquote(\"#{url}\");\n"
end
else
escaped = field.value.gsub('"', "\\22") escaped = field.value.gsub('"', "\\22")
escaped.gsub!("\n", "\\A") escaped.gsub!("\n", "\\A")
contents << "$#{field.name}: unquote(\"#{escaped}\");\n" contents << "$#{field.name}: unquote(\"#{escaped}\");\n"
end end
end
Import.new("theme_variable.scss", source: contents) Import.new("theme_variable.scss", source: contents)
end end

View File

@ -164,6 +164,28 @@ HTML
expect(scss).to include("red") expect(scss).to include("red")
expect(scss).to include('"Sam\'s Test"') expect(scss).to include('"Sam\'s Test"')
end end
let :image do
file_from_fixtures("logo.png")
end
it 'can handle uploads based of ThemeField' do
theme = Theme.new(name: 'theme', user_id: -1)
upload = Upload.create_for(-1, image, "logo.png", File.size(image))
theme.set_field(target: :common, name: :logo, upload_id: upload.id, type: :theme_upload_var)
theme.set_field(target: :common, name: :scss, value: 'body {background-image: url($logo)}')
theme.save!
# make sure we do not nuke it
freeze_time (SiteSetting.clean_orphan_uploads_grace_period_hours + 1).hours.from_now
Jobs::CleanUpUploads.new.execute(nil)
expect(Upload.where(id: upload.id)).to be_exist
scss,_map = Stylesheet::Compiler.compile('@import "theme_variables"; @import "desktop_theme"; ', "theme.scss", theme_id: theme.id)
expect(scss).to include(upload.url)
end
end end
it 'correctly caches theme keys' do it 'correctly caches theme keys' do