mirror of
https://github.com/discourse/discourse.git
synced 2024-12-16 00:44:16 +08:00
FIX: ignore and log bad json values for custom fields
This commit is contained in:
parent
f31758cc70
commit
74eec1849d
|
@ -42,13 +42,20 @@ module HasCustomFields
|
||||||
case type
|
case type
|
||||||
when :boolean then !!CUSTOM_FIELD_TRUE.include?(value)
|
when :boolean then !!CUSTOM_FIELD_TRUE.include?(value)
|
||||||
when :integer then value.to_i
|
when :integer then value.to_i
|
||||||
when :json then ::JSON.parse(value)
|
when :json then parse_json_value(value, key)
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
array ? [result] : result
|
array ? [result] : result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.parse_json_value(value, key)
|
||||||
|
::JSON.parse(value)
|
||||||
|
rescue JSON::ParserError
|
||||||
|
Rails.logger.warn("Value '#{value}' for custom field '#{key}' is not json, it is being ignored.")
|
||||||
|
{}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
included do
|
included do
|
||||||
|
@ -85,6 +92,11 @@ module HasCustomFields
|
||||||
@custom_field_types[name] = type
|
@custom_field_types[name] = type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.get_custom_field_type(name)
|
||||||
|
@custom_field_types ||= {}
|
||||||
|
@custom_field_types[name]
|
||||||
|
end
|
||||||
|
|
||||||
def self.preload_custom_fields(objects, fields)
|
def self.preload_custom_fields(objects, fields)
|
||||||
if objects.present?
|
if objects.present?
|
||||||
map = {}
|
map = {}
|
||||||
|
@ -186,7 +198,7 @@ module HasCustomFields
|
||||||
array_fields = {}
|
array_fields = {}
|
||||||
|
|
||||||
_custom_fields.reload.each do |f|
|
_custom_fields.reload.each do |f|
|
||||||
if dup[f.name].is_a? Array
|
if dup[f.name].is_a?(Array)
|
||||||
# we need to collect Arrays fully before we can compare them
|
# we need to collect Arrays fully before we can compare them
|
||||||
if !array_fields.has_key?(f.name)
|
if !array_fields.has_key?(f.name)
|
||||||
array_fields[f.name] = [f]
|
array_fields[f.name] = [f]
|
||||||
|
@ -221,12 +233,14 @@ module HasCustomFields
|
||||||
end
|
end
|
||||||
|
|
||||||
dup.each do |k, v|
|
dup.each do |k, v|
|
||||||
if v.is_a? Array
|
field_type = self.class.get_custom_field_type(k)
|
||||||
|
|
||||||
|
if v.is_a?(Array) && field_type != :json
|
||||||
v.each { |subv| _custom_fields.create!(name: k, value: subv) }
|
v.each { |subv| _custom_fields.create!(name: k, value: subv) }
|
||||||
else
|
else
|
||||||
_custom_fields.create!(
|
_custom_fields.create!(
|
||||||
name: k,
|
name: k,
|
||||||
value: v.is_a?(Hash) ? v.to_json : v
|
value: v.is_a?(Hash) || field_type == :json ? v.to_json : v
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -187,6 +187,47 @@ describe HasCustomFields do
|
||||||
expect(test_item2.custom_fields).to eq("sixto" => "rodriguez", "de" => "la playa")
|
expect(test_item2.custom_fields).to eq("sixto" => "rodriguez", "de" => "la playa")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "supports arrays in json fields" do
|
||||||
|
field_type = "json_array"
|
||||||
|
CustomFieldsTestItem.register_custom_field_type(field_type, :json)
|
||||||
|
|
||||||
|
item = CustomFieldsTestItem.new
|
||||||
|
item.custom_fields = {
|
||||||
|
"json_array" => [{ a: "test" }, { b: "another" }]
|
||||||
|
}
|
||||||
|
item.save
|
||||||
|
|
||||||
|
item.reload
|
||||||
|
|
||||||
|
expect(item.custom_fields[field_type]).to eq(
|
||||||
|
[{ "a" => "test" }, { "b" => "another" }]
|
||||||
|
)
|
||||||
|
|
||||||
|
item.custom_fields["json_array"] = ['a', 'b']
|
||||||
|
item.save
|
||||||
|
|
||||||
|
item.reload
|
||||||
|
|
||||||
|
expect(item.custom_fields[field_type]).to eq(["a", "b"])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "will not fail to load custom fields if json is corrupt" do
|
||||||
|
|
||||||
|
field_type = "bad_json"
|
||||||
|
CustomFieldsTestItem.register_custom_field_type(field_type, :json)
|
||||||
|
|
||||||
|
item = CustomFieldsTestItem.create!
|
||||||
|
|
||||||
|
CustomFieldsTestItemCustomField.create!(
|
||||||
|
custom_fields_test_item_id: item.id,
|
||||||
|
name: field_type,
|
||||||
|
value: "{test"
|
||||||
|
)
|
||||||
|
|
||||||
|
item = item.reload
|
||||||
|
expect(item.custom_fields[field_type]).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
it "supports bulk retrieval with a list of ids" do
|
it "supports bulk retrieval with a list of ids" do
|
||||||
item1 = CustomFieldsTestItem.new
|
item1 = CustomFieldsTestItem.new
|
||||||
item1.custom_fields = { "a" => ["b", "c", "d"], 'not_whitelisted' => 'secret' }
|
item1.custom_fields = { "a" => ["b", "c", "d"], 'not_whitelisted' => 'secret' }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user