mirror of
https://github.com/discourse/discourse.git
synced 2025-05-23 18:01:09 +08:00
FIX: editing a poll/post with a poll wasn't working properly
This commit is contained in:
@ -94,8 +94,8 @@ module HasCustomFields
|
|||||||
!@custom_fields || @custom_fields_orig == @custom_fields
|
!@custom_fields || @custom_fields_orig == @custom_fields
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_custom_fields
|
def save_custom_fields(force=false)
|
||||||
if !custom_fields_clean?
|
if force || !custom_fields_clean?
|
||||||
dup = @custom_fields.dup
|
dup = @custom_fields.dup
|
||||||
|
|
||||||
array_fields = {}
|
array_fields = {}
|
||||||
@ -108,6 +108,12 @@ module HasCustomFields
|
|||||||
else
|
else
|
||||||
array_fields[f.name] << f
|
array_fields[f.name] << f
|
||||||
end
|
end
|
||||||
|
elsif dup[f.name].is_a? Hash
|
||||||
|
if dup[f.name].to_json != f.value
|
||||||
|
f.destroy
|
||||||
|
else
|
||||||
|
dup.delete(f.name)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if dup[f.name] != f.value
|
if dup[f.name] != f.value
|
||||||
f.destroy
|
f.destroy
|
||||||
|
@ -78,12 +78,12 @@ class Plugin::Instance
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Add validation method but check that the plugin is enabled
|
# Add validation method but check that the plugin is enabled
|
||||||
def validate(klass, attr, &block)
|
def validate(klass, name, &block)
|
||||||
klass = klass.to_s.classify.constantize
|
klass = klass.to_s.classify.constantize
|
||||||
klass.send(:define_method, attr, &block)
|
klass.send(:define_method, name, &block)
|
||||||
|
|
||||||
plugin = self
|
plugin = self
|
||||||
klass.validate(attr, if: -> { plugin.enabled? })
|
klass.validate(name, if: -> { plugin.enabled? })
|
||||||
end
|
end
|
||||||
|
|
||||||
# will make sure all the assets this plugin needs are registered
|
# will make sure all the assets this plugin needs are registered
|
||||||
|
@ -32,6 +32,9 @@ export default {
|
|||||||
// don't even bother when there's no poll
|
// don't even bother when there's no poll
|
||||||
if (!polls) { return; }
|
if (!polls) { return; }
|
||||||
|
|
||||||
|
// clean-up if needed
|
||||||
|
this._cleanUpPollViews();
|
||||||
|
|
||||||
const pollViews = {};
|
const pollViews = {};
|
||||||
|
|
||||||
// iterate over all polls
|
// iterate over all polls
|
||||||
@ -47,14 +50,20 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.messageBus.subscribe("/polls/" + this.get("post.id"), results => {
|
this.messageBus.subscribe("/polls/" + this.get("post.id"), results => {
|
||||||
pollViews[results.poll.name].get("controller").set("model", Em.Object.create(results.poll));
|
if (results && results.polls) {
|
||||||
|
_.forEach(results.polls, poll => {
|
||||||
|
if (pollViews[poll.name]) {
|
||||||
|
pollViews[poll.name].get("controller").set("model", Em.Object.create(poll));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.set("pollViews", pollViews);
|
this.set("pollViews", pollViews);
|
||||||
}.on("postViewInserted"),
|
}.on("postViewInserted", "postViewUpdated"),
|
||||||
|
|
||||||
_cleanUpPollViews: function() {
|
_cleanUpPollViews: function() {
|
||||||
this.messageBus.unsubscribe("/polls/*");
|
this.messageBus.unsubscribe("/polls/" + this.get("post.id"));
|
||||||
|
|
||||||
if (this.get("pollViews")) {
|
if (this.get("pollViews")) {
|
||||||
_.forEach(this.get("pollViews"), v => v.destroy());
|
_.forEach(this.get("pollViews"), v => v.destroy());
|
||||||
|
@ -64,9 +64,9 @@ after_initialize do
|
|||||||
|
|
||||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||||
post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] = votes
|
post.custom_fields["#{VOTES_CUSTOM_FIELD}-#{user_id}"] = votes
|
||||||
post.save_custom_fields
|
post.save_custom_fields(true)
|
||||||
|
|
||||||
DiscourseBus.publish("/polls/#{post_id}", { poll: poll })
|
DiscourseBus.publish("/polls/#{post_id}", { polls: polls })
|
||||||
|
|
||||||
render json: { poll: poll, vote: options }
|
render json: { poll: poll, vote: options }
|
||||||
end
|
end
|
||||||
@ -97,10 +97,9 @@ after_initialize do
|
|||||||
|
|
||||||
polls[poll_name]["status"] = status
|
polls[poll_name]["status"] = status
|
||||||
|
|
||||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
post.save_custom_fields(true)
|
||||||
post.save_custom_fields
|
|
||||||
|
|
||||||
DiscourseBus.publish("/polls/#{post_id}", { poll: polls[poll_name] })
|
DiscourseBus.publish("/polls/#{post_id}", { polls: polls })
|
||||||
|
|
||||||
render json: { poll: polls[poll_name] }
|
render json: { poll: polls[poll_name] }
|
||||||
end
|
end
|
||||||
@ -120,7 +119,6 @@ after_initialize do
|
|||||||
Post.class_eval do
|
Post.class_eval do
|
||||||
attr_accessor :polls
|
attr_accessor :polls
|
||||||
|
|
||||||
# save the polls when the post is created
|
|
||||||
after_save do
|
after_save do
|
||||||
next if self.polls.blank? || !self.polls.is_a?(Hash)
|
next if self.polls.blank? || !self.polls.is_a?(Hash)
|
||||||
|
|
||||||
@ -129,7 +127,7 @@ after_initialize do
|
|||||||
|
|
||||||
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post.id}") do
|
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post.id}") do
|
||||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||||
post.save_custom_fields
|
post.save_custom_fields(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -137,7 +135,7 @@ after_initialize do
|
|||||||
DATA_PREFIX ||= "data-poll-".freeze
|
DATA_PREFIX ||= "data-poll-".freeze
|
||||||
DEFAULT_POLL_NAME ||= "poll".freeze
|
DEFAULT_POLL_NAME ||= "poll".freeze
|
||||||
|
|
||||||
validate(:post, :polls) do
|
validate(:post, :validate_polls) do
|
||||||
# only care when raw has changed!
|
# only care when raw has changed!
|
||||||
return unless self.raw_changed?
|
return unless self.raw_changed?
|
||||||
|
|
||||||
@ -200,8 +198,8 @@ after_initialize do
|
|||||||
polls[poll["name"]] = poll
|
polls[poll["name"]] = poll
|
||||||
end
|
end
|
||||||
|
|
||||||
# are we updating a post outside the 5-minute edit window?
|
# are we updating a post?
|
||||||
if self.id.present? && self.created_at < 5.minutes.ago
|
if self.id.present?
|
||||||
post = self
|
post = self
|
||||||
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post.id}") do
|
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post.id}") do
|
||||||
# load previous polls
|
# load previous polls
|
||||||
@ -211,6 +209,8 @@ after_initialize do
|
|||||||
if polls.keys != previous_polls.keys ||
|
if polls.keys != previous_polls.keys ||
|
||||||
polls.values.map { |p| p["options"] } != previous_polls.values.map { |p| p["options"] }
|
polls.values.map { |p| p["options"] } != previous_polls.values.map { |p| p["options"] }
|
||||||
|
|
||||||
|
# outside the 5-minute edit window?
|
||||||
|
if post.created_at < 5.minutes.ago
|
||||||
# cannot add/remove/change/re-order polls
|
# cannot add/remove/change/re-order polls
|
||||||
if polls.keys != previous_polls.keys
|
if polls.keys != previous_polls.keys
|
||||||
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
||||||
@ -226,28 +226,37 @@ after_initialize do
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# merge votes
|
|
||||||
polls.each_key do |poll_name|
|
|
||||||
polls[poll_name]["total_votes"] = previous_polls[poll_name]["total_votes"]
|
|
||||||
for o in 0...polls[poll_name]["options"].size
|
|
||||||
polls[poll_name]["options"][o]["votes"] = previous_polls[poll_name]["options"][o]["votes"]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
# OP cannot change polls after 5 minutes
|
# OP cannot change polls
|
||||||
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# merge votes when same number of options
|
||||||
|
polls.each_key do |poll_name|
|
||||||
|
next unless previous_polls.has_key?(poll_name)
|
||||||
|
next unless polls[poll_name]["options"].size == previous_polls[poll_name]["options"].size
|
||||||
|
|
||||||
|
polls[poll_name]["total_votes"] = previous_polls[poll_name]["total_votes"]
|
||||||
|
for o in 0...polls[poll_name]["options"].size
|
||||||
|
polls[poll_name]["options"][o]["votes"] = previous_polls[poll_name]["options"][o]["votes"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# immediately store the polls
|
# immediately store the polls
|
||||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||||
post.save_custom_fields
|
post.save_custom_fields(true)
|
||||||
|
|
||||||
|
# push the changes
|
||||||
|
DiscourseBus.publish("/polls/#{post_id}", { polls: polls })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# polls will be saved once we have a post id
|
|
||||||
self.polls = polls
|
self.polls = polls
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
Post.register_custom_field_type(POLLS_CUSTOM_FIELD, :json)
|
Post.register_custom_field_type(POLLS_CUSTOM_FIELD, :json)
|
||||||
|
Reference in New Issue
Block a user