diff --git a/app/assets/javascripts/discourse/controllers/composer_controller.js b/app/assets/javascripts/discourse/controllers/composer_controller.js
index c4ed025c071..7a3b86831ba 100644
--- a/app/assets/javascripts/discourse/controllers/composer_controller.js
+++ b/app/assets/javascripts/discourse/controllers/composer_controller.js
@@ -382,7 +382,10 @@ Discourse.ComposerController = Discourse.Controller.extend({
archetype: this.get('model.archetype'),
metaData: this.get('model.metaData')
})) : void 0;
- }
+ },
+
+ canEdit: function() {
+ return this.get("model.action") === "edit" && Discourse.User.current().get("can_edit");
+ }.property("model.action")
+
});
-
-
diff --git a/app/assets/javascripts/discourse/models/composer.js b/app/assets/javascripts/discourse/models/composer.js
index 289542c5de5..c0c1c889f7f 100644
--- a/app/assets/javascripts/discourse/models/composer.js
+++ b/app/assets/javascripts/discourse/models/composer.js
@@ -412,6 +412,7 @@ Discourse.Composer = Discourse.Model.extend({
post.setProperties({
raw: this.get('reply'),
+ editReason: this.get('editReason'),
imageSizes: opts.imageSizes,
cooked: $('#wmd-preview').html()
});
diff --git a/app/assets/javascripts/discourse/models/post.js b/app/assets/javascripts/discourse/models/post.js
index a336dfb478c..fcaa533a6f0 100644
--- a/app/assets/javascripts/discourse/models/post.js
+++ b/app/assets/javascripts/discourse/models/post.js
@@ -155,7 +155,7 @@ Discourse.Post = Discourse.Model.extend({
return Discourse.ajax("/posts/" + (this.get('id')), {
type: 'PUT',
data: {
- post: { raw: this.get('raw') },
+ post: { raw: this.get('raw'), edit_reason: this.get('editReason') },
image_sizes: this.get('imageSizes')
}
}).then(function(result) {
diff --git a/app/assets/javascripts/discourse/templates/composer.js.handlebars b/app/assets/javascripts/discourse/templates/composer.js.handlebars
index e2776ee0672..fe4a76f89d4 100644
--- a/app/assets/javascripts/discourse/templates/composer.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/composer.js.handlebars
@@ -24,7 +24,7 @@
{{/if}}
- {{textField value=model.title tabindex="2" id="reply-title" maxlength="255" class="span8" placeholderKey="composer.title_placeholder"}}
+ {{textField value=model.title tabindex="2" id="reply-title" maxlength="255" placeholderKey="composer.title_placeholder"}}
{{popupInputTip validation=view.titleValidation shownAt=view.showTitleTip}}
@@ -39,6 +39,11 @@
{{#if model.showAdminOptions}}
{{/if}}
+ {{#if canEdit}}
+
+ {{textField value=model.editReason tabindex="5" id="edit-reason" maxlength="255" placeholderKey="composer.edit_reason_placeholder"}}
+
+ {{/if}}
{{/unless}}
diff --git a/app/assets/javascripts/discourse/templates/modal/history.js.handlebars b/app/assets/javascripts/discourse/templates/modal/history.js.handlebars
index ba1f4b6a760..2a5bb997f33 100644
--- a/app/assets/javascripts/discourse/templates/modal/history.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/modal/history.js.handlebars
@@ -29,6 +29,10 @@
optionValuePath="content.number"
selectionBinding="versionRight"}}
+ {{#if postRight.edit_reason}}
+ {{i18n post.edit_reason}}{{postRight.edit_reason}}
+ {{/if}}
+
{{#if diff}}
{{{diff}}}
@@ -41,4 +45,4 @@
{{/if}}
{{/if}}
-
\ No newline at end of file
+
diff --git a/app/assets/stylesheets/desktop/compose.scss b/app/assets/stylesheets/desktop/compose.scss
index 05592c8ca56..6e10d16c576 100644
--- a/app/assets/stylesheets/desktop/compose.scss
+++ b/app/assets/stylesheets/desktop/compose.scss
@@ -238,12 +238,12 @@
height: 400px;
}
.contents {
- input#reply-title {
+ input#reply-title, input#edit-reason {
padding: 7px 10px;
margin: 6px 10px 3px 0;
- width: 400px;
-
}
+ input#reply-title { width: 400px; }
+ input#edit-reason { width: 200px; }
.wmd-controls {
@include transition(top 0.3s ease);
top: 100px;
@@ -283,7 +283,7 @@
}
}
}
- #reply-title {
+ #reply-title, #edit-reason {
margin-right: 10px;
float: left;
&:disabled {
@@ -324,7 +324,7 @@
bottom: 8px;
}
}
- .title-input, .category-input {
+ .title-input, .category-input, .edit-reason-input {
position: relative;
display: inline;
}
@@ -357,7 +357,6 @@ div.ac-wrap {
background-color: $white;
border: 1px solid #cccccc;
padding: 5px 10px;
- @include border-radius-all(3px);
div.item {
float: left;
margin-right: 10px;
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index 990d233ad2c..64925ac30e4 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -82,7 +82,7 @@ class PostsController < ApplicationController
end
revisor = PostRevisor.new(post)
- if revisor.revise!(current_user, params[:post][:raw])
+ if revisor.revise!(current_user, params[:post][:raw], edit_reason: params[:post][:edit_reason])
TopicLink.extract_from(post)
end
diff --git a/app/jobs/regular/pull_hotlinked_images.rb b/app/jobs/regular/pull_hotlinked_images.rb
index 9016de6d561..90f9b447146 100644
--- a/app/jobs/regular/pull_hotlinked_images.rb
+++ b/app/jobs/regular/pull_hotlinked_images.rb
@@ -27,7 +27,7 @@ module Jobs
# have we already downloaded that file?
if !downloaded_urls.include?(src)
hotlinked = download(src)
- if hotlinked.size <= @max_size
+ if hotlinked.try(:size) <= @max_size
filename = File.basename(URI.parse(src).path)
file = ActionDispatch::Http::UploadedFile.new(tempfile: hotlinked, filename: filename)
upload = Upload.create_for(post.user_id, file, hotlinked.size, src)
@@ -64,7 +64,10 @@ module Jobs
# TODO: make sure the post hasnĀ“t changed while we were downloading remote images
if raw != post.raw
- options = { force_new_version: true }
+ options = {
+ force_new_version: true,
+ edit_reason: I18n.t("upload.edit_reason")
+ }
post.revise(Discourse.system_user, raw, options)
end
diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb
index d65215b0110..234cff159ae 100644
--- a/app/serializers/post_serializer.rb
+++ b/app/serializers/post_serializer.rb
@@ -1,13 +1,13 @@
class PostSerializer < BasicPostSerializer
# To pass in additional information we might need
- attr_accessor :topic_slug
- attr_accessor :topic_view
- attr_accessor :parent_post
- attr_accessor :add_raw
- attr_accessor :single_post_link_counts
- attr_accessor :draft_sequence
- attr_accessor :post_actions
+ attr_accessor :topic_slug,
+ :topic_view,
+ :parent_post,
+ :add_raw,
+ :single_post_link_counts,
+ :draft_sequence,
+ :post_actions
attributes :post_number,
:post_type,
@@ -43,7 +43,8 @@ class PostSerializer < BasicPostSerializer
:trust_level,
:deleted_at,
:deleted_by,
- :user_deleted
+ :user_deleted,
+ :edit_reason
def moderator?
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 97aab706fab..e17dfc48441 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -479,6 +479,7 @@ en:
users_placeholder: "Add a user"
title_placeholder: "Type your title here. What is this discussion about in one brief sentence?"
+ edit_reason_placeholder: "Short reason of your edit"
reply_placeholder: "Type here. Use Markdown or BBCode to format. Drag or paste an image to upload it."
view_new_post: "View your new post."
saving: "Saving..."
@@ -798,6 +799,7 @@ en:
reply_topic: "Reply to {{link}}"
quote_reply: "quote reply"
edit: "Editing {{link}} by {{replyAvatar}} {{username}}"
+ edit_reason: "Reason: "
post_number: "post {{number}}"
in_reply_to: "in reply to"
last_edited_on: "post last edited on"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 0cdc618ac63..4225b622c4b 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -1178,6 +1178,7 @@ en:
deleted: 'deleted'
upload:
+ edit_reason: "We have downloaded a copy of the remotes images"
unauthorized: "Sorry, the file you are trying to upload is not authorized (authorized extensions: %{authorized_extensions})."
pasted_image_filename: "Pasted image"
attachments:
diff --git a/db/migrate/20131115165105_add_edit_reason_to_posts.rb b/db/migrate/20131115165105_add_edit_reason_to_posts.rb
new file mode 100644
index 00000000000..1650f9d99ae
--- /dev/null
+++ b/db/migrate/20131115165105_add_edit_reason_to_posts.rb
@@ -0,0 +1,5 @@
+class AddEditReasonToPosts < ActiveRecord::Migration
+ def change
+ add_column :posts, :edit_reason, :string
+ end
+end
diff --git a/lib/post_revisor.rb b/lib/post_revisor.rb
index 97e545c1ec2..93a7d988a4a 100644
--- a/lib/post_revisor.rb
+++ b/lib/post_revisor.rb
@@ -70,6 +70,7 @@ class PostRevisor
@post.raw = @new_raw
@post.updated_by = @user
@post.last_editor_id = @user.id
+ @post.edit_reason = @opts[:edit_reason] if @opts[:edit_reason]
if @post.hidden && @post.hidden_reason_id == Post.hidden_reasons[:flag_threshold_reached]
@post.hidden = false
diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb
index 1280ebe8589..ef1c495e608 100644
--- a/spec/controllers/posts_controller_spec.rb
+++ b/spec/controllers/posts_controller_spec.rb
@@ -217,9 +217,11 @@ describe PostsController do
let(:post) { Fabricate(:post, user: log_in) }
let(:update_params) do
- {id: post.id,
- post: {raw: 'edited body'},
- image_sizes: {'http://image.com/image.jpg' => {'width' => 123, 'height' => 456}}}
+ {
+ id: post.id,
+ post: { raw: 'edited body', edit_reason: 'typo' },
+ image_sizes: { 'http://image.com/image.jpg' => {'width' => 123, 'height' => 456} },
+ }
end
it 'passes the image sizes through' do
@@ -227,6 +229,11 @@ describe PostsController do
xhr :put, :update, update_params
end
+ it 'passes the edit reason through' do
+ Post.any_instance.expects(:edit_reason=)
+ xhr :put, :update, update_params
+ end
+
it "raises an error when the post parameter is missing" do
update_params.delete(:post)
lambda {
@@ -241,7 +248,7 @@ describe PostsController do
end
it "calls revise with valid parameters" do
- PostRevisor.any_instance.expects(:revise!).with(post.user, 'edited body')
+ PostRevisor.any_instance.expects(:revise!).with(post.user, 'edited body', edit_reason: 'typo')
xhr :put, :update, update_params
end