mirror of
https://github.com/discourse/discourse.git
synced 2025-05-25 00:32:52 +08:00
Allow theme field object model to support uploads
This commit is contained in:
@ -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|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user