mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
FIX: editing a poll/post with a poll wasn't working properly
This commit is contained in:
parent
84c65aeb60
commit
151dea4088
4 changed files with 70 additions and 46 deletions
|
@ -94,8 +94,8 @@ module HasCustomFields
|
|||
!@custom_fields || @custom_fields_orig == @custom_fields
|
||||
end
|
||||
|
||||
def save_custom_fields
|
||||
if !custom_fields_clean?
|
||||
def save_custom_fields(force=false)
|
||||
if force || !custom_fields_clean?
|
||||
dup = @custom_fields.dup
|
||||
|
||||
array_fields = {}
|
||||
|
@ -108,6 +108,12 @@ module HasCustomFields
|
|||
else
|
||||
array_fields[f.name] << f
|
||||
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
|
||||
if dup[f.name] != f.value
|
||||
f.destroy
|
||||
|
|
|
@ -78,12 +78,12 @@ class Plugin::Instance
|
|||
end
|
||||
|
||||
# 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.send(:define_method, attr, &block)
|
||||
klass.send(:define_method, name, &block)
|
||||
|
||||
plugin = self
|
||||
klass.validate(attr, if: -> { plugin.enabled? })
|
||||
klass.validate(name, if: -> { plugin.enabled? })
|
||||
end
|
||||
|
||||
# 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
|
||||
if (!polls) { return; }
|
||||
|
||||
// clean-up if needed
|
||||
this._cleanUpPollViews();
|
||||
|
||||
const pollViews = {};
|
||||
|
||||
// iterate over all polls
|
||||
|
@ -47,14 +50,20 @@ export default {
|
|||
});
|
||||
|
||||
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);
|
||||
}.on("postViewInserted"),
|
||||
}.on("postViewInserted", "postViewUpdated"),
|
||||
|
||||
_cleanUpPollViews: function() {
|
||||
this.messageBus.unsubscribe("/polls/*");
|
||||
this.messageBus.unsubscribe("/polls/" + this.get("post.id"));
|
||||
|
||||
if (this.get("pollViews")) {
|
||||
_.forEach(this.get("pollViews"), v => v.destroy());
|
||||
|
|
|
@ -64,9 +64,9 @@ after_initialize do
|
|||
|
||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||
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 }
|
||||
end
|
||||
|
@ -97,10 +97,9 @@ after_initialize do
|
|||
|
||||
polls[poll_name]["status"] = status
|
||||
|
||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||
post.save_custom_fields
|
||||
post.save_custom_fields(true)
|
||||
|
||||
DiscourseBus.publish("/polls/#{post_id}", { poll: polls[poll_name] })
|
||||
DiscourseBus.publish("/polls/#{post_id}", { polls: polls })
|
||||
|
||||
render json: { poll: polls[poll_name] }
|
||||
end
|
||||
|
@ -120,7 +119,6 @@ after_initialize do
|
|||
Post.class_eval do
|
||||
attr_accessor :polls
|
||||
|
||||
# save the polls when the post is created
|
||||
after_save do
|
||||
next if self.polls.blank? || !self.polls.is_a?(Hash)
|
||||
|
||||
|
@ -129,7 +127,7 @@ after_initialize do
|
|||
|
||||
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post.id}") do
|
||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||
post.save_custom_fields
|
||||
post.save_custom_fields(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -137,7 +135,7 @@ after_initialize do
|
|||
DATA_PREFIX ||= "data-poll-".freeze
|
||||
DEFAULT_POLL_NAME ||= "poll".freeze
|
||||
|
||||
validate(:post, :polls) do
|
||||
validate(:post, :validate_polls) do
|
||||
# only care when raw has changed!
|
||||
return unless self.raw_changed?
|
||||
|
||||
|
@ -200,8 +198,8 @@ after_initialize do
|
|||
polls[poll["name"]] = poll
|
||||
end
|
||||
|
||||
# are we updating a post outside the 5-minute edit window?
|
||||
if self.id.present? && self.created_at < 5.minutes.ago
|
||||
# are we updating a post?
|
||||
if self.id.present?
|
||||
post = self
|
||||
DistributedMutex.synchronize("#{PLUGIN_NAME}-#{post.id}") do
|
||||
# load previous polls
|
||||
|
@ -211,43 +209,54 @@ after_initialize do
|
|||
if polls.keys != previous_polls.keys ||
|
||||
polls.values.map { |p| p["options"] } != previous_polls.values.map { |p| p["options"] }
|
||||
|
||||
# cannot add/remove/change/re-order polls
|
||||
if polls.keys != previous_polls.keys
|
||||
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
||||
return
|
||||
# outside the 5-minute edit window?
|
||||
if post.created_at < 5.minutes.ago
|
||||
# cannot add/remove/change/re-order polls
|
||||
if polls.keys != previous_polls.keys
|
||||
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
||||
return
|
||||
end
|
||||
|
||||
# deal with option changes
|
||||
if User.staff.pluck(:id).include?(post.last_editor_id)
|
||||
# staff can only edit options
|
||||
polls.each_key do |poll_name|
|
||||
if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size
|
||||
post.errors.add(:base, I18n.t("poll.staff_cannot_add_or_remove_options_after_5_minutes"))
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
# OP cannot change polls
|
||||
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# deal with option changes
|
||||
if User.staff.pluck(:id).include?(post.last_editor_id)
|
||||
# staff can only edit options
|
||||
polls.each_key do |poll_name|
|
||||
if polls[poll_name]["options"].size != previous_polls[poll_name]["options"].size
|
||||
post.errors.add(:base, I18n.t("poll.staff_cannot_add_or_remove_options_after_5_minutes"))
|
||||
return
|
||||
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
|
||||
# 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
|
||||
# OP cannot change polls after 5 minutes
|
||||
post.errors.add(:base, I18n.t("poll.cannot_change_polls_after_5_minutes"))
|
||||
return
|
||||
end
|
||||
|
||||
# immediately store the polls
|
||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||
post.save_custom_fields(true)
|
||||
|
||||
# push the changes
|
||||
DiscourseBus.publish("/polls/#{post_id}", { polls: polls })
|
||||
end
|
||||
|
||||
# immediately store the polls
|
||||
post.custom_fields[POLLS_CUSTOM_FIELD] = polls
|
||||
post.save_custom_fields
|
||||
end
|
||||
else
|
||||
# polls will be saved once we have a post id
|
||||
self.polls = polls
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
Post.register_custom_field_type(POLLS_CUSTOM_FIELD, :json)
|
||||
|
|
Loading…
Reference in a new issue