FEATURE: Category setting to allow unlimited first post edits by the owner of the topic (#12690)

FEATURE: Category setting to allow unlimited first post edits by the owner of the topic (#12690)

This PR adds a new category setting which is a column in the categories table, allow_unlimited_owner_edits_on_first_post.

What this does is:

  • Inside the can_edit_post? method of PostGuardian, if the current user editing a post is the owner of the post, it is the first post, and the topic’s category has allow_unlimited_owner_edits_on_first_post, then we bypass the check for LimitedEdit#edit_time_limit_expired? on that post.
  • Also, similar to wiki topics, in PostActionNotifier#after_create_post_revision we send a notification to all users watching a topic when the OP is edited in a topic with the category setting allow_unlimited_owner_edits_on_first_post enabled.

This is useful for forums where there is a Marketplace or similar category, where topics are created and then updated indefinitely by the OP rather than the OP making new topics or additional replies. In a way this acts similar to a wiki that only one person can edit.

diff --git a/app/assets/javascripts/discourse/app/models/category.js b/app/assets/javascripts/discourse/app/models/category.js
index 9ed3517..4de28e4 100644
--- a/app/assets/javascripts/discourse/app/models/category.js
+++ b/app/assets/javascripts/discourse/app/models/category.js
@@ -204,6 +204,8 @@ const Category = RestModel.extend({
         custom_fields: this.custom_fields,
         topic_template: this.topic_template,
         all_topics_wiki: this.all_topics_wiki,
+        allow_unlimited_owner_edits_on_first_post: this
+          .allow_unlimited_owner_edits_on_first_post,
         allowed_tags: this.allowed_tags,
         allowed_tag_groups: this.allowed_tag_groups,
         allow_global_tags: this.allow_global_tags,
diff --git a/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs b/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs
index bf8eac3..78c3414 100644
--- a/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs
@@ -77,6 +77,13 @@
       {{i18n "category.all_topics_wiki"}}
     </label>
   </section>
+
+  <section class="field allow-unlimited-owner-edits-on-first-post">
+    <label>
+      {{input type="checkbox" checked=category.allow_unlimited_owner_edits_on_first_post}}
+      {{i18n "category.allow_unlimited_owner_edits_on_first_post"}}
+    </label>
+  </section>
 </section>
 
 <section>
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
index b632d6b..7250809 100644
--- a/app/controllers/categories_controller.rb
+++ b/app/controllers/categories_controller.rb
@@ -296,6 +296,7 @@ class CategoriesController < ApplicationController
         :email_in_allow_strangers,
         :mailinglist_mirror,
         :all_topics_wiki,
+        :allow_unlimited_owner_edits_on_first_post,
         :parent_category_id,
         :auto_close_hours,
         :auto_close_based_on_last_post,
diff --git a/app/models/category.rb b/app/models/category.rb
index 7085aa3..315a4fa 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -957,67 +957,68 @@ end
 #
 # Table name: categories
 #
-#  id                                :integer          not null, primary key
-#  name                              :string(50)       not null
-#  color                             :string(6)        default("0088CC"), not null
-#  topic_id                          :integer
-#  topic_count                       :integer          default(0), not null
-#  created_at                        :datetime         not null
-#  updated_at                        :datetime         not null
-#  user_id                           :integer          not null
-#  topics_year                       :integer          default(0)
-#  topics_month                      :integer          default(0)
-#  topics_week                       :integer          default(0)
-#  slug                              :string           not null
-#  description                       :text
-#  text_color                        :string(6)        default("FFFFFF"), not null
-#  read_restricted                   :boolean          default(FALSE), not null
-#  auto_close_hours                  :float
-#  post_count                        :integer          default(0), not null
-#  latest_post_id                    :integer
-#  latest_topic_id                   :integer
-#  position                          :integer
-#  parent_category_id                :integer
-#  posts_year                        :integer          default(0)
-#  posts_month                       :integer          default(0)
-#  posts_week                        :integer          default(0)
-#  email_in                          :string
-#  email_in_allow_strangers          :boolean          default(FALSE)
-#  topics_day                        :integer          default(0)
-#  posts_day                         :integer          default(0)
-#  allow_badges                      :boolean          default(TRUE), not null
-#  name_lower                        :string(50)       not null
-#  auto_close_based_on_last_post     :boolean          default(FALSE)
-#  topic_template                    :text
-#  contains_messages                 :boolean
-#  sort_order                        :string
-#  sort_ascending                    :boolean
-#  uploaded_logo_id                  :integer
-#  uploaded_background_id            :integer
-#  topic_featured_link_allowed       :boolean          default(TRUE)
-#  all_topics_wiki                   :boolean          default(FALSE), not null
-#  show_subcategory_list             :boolean          default(FALSE)
-#  num_featured_topics               :integer          default(3)
-#  default_view                      :string(50)
-#  subcategory_list_style            :string(50)       default("rows_with_featured_topics")
-#  default_top_period                :string(20)       default("all")
-#  mailinglist_mirror                :boolean          default(FALSE), not null
-#  minimum_required_tags             :integer          default(0), not null
-#  navigate_to_first_post_after_read :boolean          default(FALSE), not null
-#  search_priority                   :integer          default(0)
-#  allow_global_tags                 :boolean          default(FALSE), not null
-#  reviewable_by_group_id            :integer
-#  required_tag_group_id             :integer
-#  min_tags_from_required_group      :integer          default(1), not null
-#  read_only_banner                  :string
-#  default_list_filter               :string(20)       default("all")
+#  id                                        :integer          not null, primary key
+#  name                                      :string(50)       not null
+#  color                                     :string(6)        default("0088CC"), not null
+#  topic_id                                  :integer
+#  topic_count                               :integer          default(0), not null
+#  created_at                                :datetime         not null
+#  updated_at                                :datetime         not null
+#  user_id                                   :integer          not null
+#  topics_year                               :integer          default(0)
+#  topics_month                              :integer          default(0)
+#  topics_week                               :integer          default(0)
+#  slug                                      :string           not null
+#  description                               :text
+#  text_color                                :string(6)        default("FFFFFF"), not null
+#  read_restricted                           :boolean          default(FALSE), not null
+#  auto_close_hours                          :float
+#  post_count                                :integer          default(0), not null
+#  latest_post_id                            :integer
+#  latest_topic_id                           :integer
+#  position                                  :integer
+#  parent_category_id                        :integer
+#  posts_year                                :integer          default(0)
+#  posts_month                               :integer          default(0)
+#  posts_week                                :integer          default(0)
+#  email_in                                  :string
+#  email_in_allow_strangers                  :boolean          default(FALSE)
+#  topics_day                                :integer          default(0)
+#  posts_day                                 :integer          default(0)
+#  allow_badges                              :boolean          default(TRUE), not null
+#  name_lower                                :string(50)       not null
+#  auto_close_based_on_last_post             :boolean          default(FALSE)

[... diff too long, it was truncated ...]

GitHub sha: eeaecd4f

This commit appears in #12690 which was approved by SamSaffron. It was merged by martin.