diff --git a/Gemfile b/Gemfile
index 80e9f287d4f..978f767a1c7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -15,7 +15,6 @@ gem 'simple_handlebars_rails', path: 'vendor/gems/simple_handlebars_rails'
gem 'redcarpet', require: false
gem 'activerecord-postgres-hstore'
-gem 'acts_as_paranoid'
gem 'active_attr' # until we get ActiveModel::Model with Rails 4
gem 'airbrake', '3.1.2', require: false # errbit is broken with 3.1.3 for now
gem 'clockwork', require: false
@@ -135,7 +134,9 @@ gem 'lru_redux'
gem 'rack-mini-profiler', require: false # require: false #, git: 'git://github.com/SamSaffron/MiniProfiler'
# used for caching, optional
-gem 'redis-rack-cache', require: false
+# redis-rack-cache is missing a sane expiry policy, it hogs redis
+# https://github.com/jodosha/redis-store/pull/183
+gem 'redis-rack-cache', :git => 'git://github.com/SamSaffron/redis-rack-cache.git', require: false
gem 'rack-cache', require: false
gem 'rack-cors', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 8e97a4263b5..eb0467d2bcb 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -6,6 +6,14 @@ GIT
rake
rake-compiler
+GIT
+ remote: git://github.com/SamSaffron/redis-rack-cache.git
+ revision: 379ef30e31d4e185cb1d7f8badca0cc06403eba2
+ specs:
+ redis-rack-cache (1.2.1)
+ rack-cache (~> 1.2)
+ redis-store (~> 1.1.0)
+
GIT
remote: git://github.com/SamSaffron/sprockets.git
revision: bacf2ec4d4d10cd8d1ab25a6360740314c512237
@@ -120,8 +128,6 @@ GEM
activesupport (3.2.12)
i18n (~> 0.6)
multi_json (~> 1.0)
- acts_as_paranoid (0.4.1)
- activerecord (~> 3.2)
airbrake (3.1.2)
activesupport
builder
@@ -352,9 +358,6 @@ GEM
redis-rack (1.4.2)
rack (~> 1.4.1)
redis-store (~> 1.1.0)
- redis-rack-cache (1.2.1)
- rack-cache (~> 1.2)
- redis-store (~> 1.1.0)
redis-rails (3.2.3)
redis-actionpack (~> 3.2.3)
redis-activesupport (~> 3.2.3)
@@ -448,7 +451,6 @@ DEPENDENCIES
active_attr
active_model_serializers!
activerecord-postgres-hstore
- acts_as_paranoid
airbrake (= 3.1.2)
barber (= 0.3.0)
better_errors
@@ -507,7 +509,7 @@ DEPENDENCIES
rb-inotify (~> 0.9)
redcarpet
redis
- redis-rack-cache
+ redis-rack-cache!
redis-rails
rest-client
rinku
diff --git a/app/assets/javascripts/discourse/components/click_track.js b/app/assets/javascripts/discourse/components/click_track.js
index fb116163814..45ca15827ac 100644
--- a/app/assets/javascripts/discourse/components/click_track.js
+++ b/app/assets/javascripts/discourse/components/click_track.js
@@ -53,9 +53,12 @@ Discourse.ClickTrack = {
if (!ownLink) {
var $badge = $('span.badge', $link);
if ($badge.length === 1) {
- // don't update counts in oneboxes (except when we force it)
- if ($link.closest(".onebox-result").length === 0 || $link.hasClass("track-link")) {
- $badge.html(parseInt($badge.html(), 10) + 1);
+ // don't update counts in category badge
+ if ($link.closest('.badge-category').length === 0) {
+ // nor in oneboxes (except when we force it)
+ if ($link.closest(".onebox-result").length === 0 || $link.hasClass("track-link")) {
+ $badge.html(parseInt($badge.html(), 10) + 1);
+ }
}
}
}
diff --git a/app/assets/javascripts/discourse/controllers/topic_controller.js b/app/assets/javascripts/discourse/controllers/topic_controller.js
index 4ae25599036..1cc55eeb123 100644
--- a/app/assets/javascripts/discourse/controllers/topic_controller.js
+++ b/app/assets/javascripts/discourse/controllers/topic_controller.js
@@ -432,7 +432,7 @@ Discourse.TopicController = Discourse.ObjectController.extend({
deletePost: function(post) {
// Moderators can delete posts. Regular users can only create a deleted at message.
- if (Discourse.get('currentUser.moderator')) {
+ if (Discourse.get('currentUser.staff')) {
post.set('deleted_at', new Date());
} else {
post.set('cooked', Discourse.Markdown.cook(Em.String.i18n("post.deleted_by_author")));
diff --git a/app/assets/javascripts/discourse/models/composer.js b/app/assets/javascripts/discourse/models/composer.js
index 50eb2cbc62a..914b94ce190 100644
--- a/app/assets/javascripts/discourse/models/composer.js
+++ b/app/assets/javascripts/discourse/models/composer.js
@@ -67,7 +67,7 @@ Discourse.Composer = Discourse.Model.extend({
togglePreview: function() {
this.toggleProperty('showPreview');
- Discourse.KeyValueStore.set({ key: 'showPreview', value: this.get('showPreview') });
+ Discourse.KeyValueStore.set({ key: 'composer.showPreview', value: this.get('showPreview') });
},
// Import a quote from the post
diff --git a/app/assets/javascripts/discourse/views/post_view.js b/app/assets/javascripts/discourse/views/post_view.js
index 739ffbaf44b..081ff88b00b 100644
--- a/app/assets/javascripts/discourse/views/post_view.js
+++ b/app/assets/javascripts/discourse/views/post_view.js
@@ -171,9 +171,12 @@ Discourse.PostView = Discourse.View.extend({
postView.$(".cooked a[href]").each(function() {
var link = $(this);
if (link.attr('href') === lc.url) {
- // don't display badge counts in oneboxes (except when we force it)
- if (link.closest(".onebox-result").length === 0 || link.hasClass("track-link")) {
- link.append("" + lc.clicks + "");
+ // don't display badge counts on category badge
+ if (link.closest('.badge-category').length === 0) {
+ // nor in oneboxes (except when we force it)
+ if (link.closest(".onebox-result").length === 0 || link.hasClass("track-link")) {
+ link.append("" + lc.clicks + "");
+ }
}
}
});
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index 9d2bec01d30..dbaf94e7fb2 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -33,7 +33,7 @@ class InvitesController < ApplicationController
invite = Invite.where(invited_by_id: current_user.id, email: params[:email]).first
raise Discourse::InvalidParameters.new(:email) if invite.blank?
- invite.destroy
+ invite.trash!
render nothing: true
end
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index 774a4dcd5b8..cfc5971fd64 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -128,7 +128,7 @@ class PostsController < ApplicationController
def recover
post = find_post_from_params
guardian.ensure_can_recover_post!(post)
- post.recover
+ post.recover!
render nothing: true
end
@@ -186,8 +186,8 @@ class PostsController < ApplicationController
def find_post_from_params
finder = Post.where(id: params[:id] || params[:post_id])
- # Include deleted posts if the user is a moderator
- finder = finder.with_deleted if current_user.try(:moderator?)
+ # Include deleted posts if the user is staff
+ finder = finder.with_deleted if current_user.try(:staff?)
post = finder.first
guardian.ensure_can_see!(post)
diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb
index 74014b41a4b..ae966f8dc3b 100644
--- a/app/controllers/topics_controller.rb
+++ b/app/controllers/topics_controller.rb
@@ -100,7 +100,7 @@ class TopicsController < ApplicationController
def destroy
topic = Topic.where(id: params[:id]).first
guardian.ensure_can_delete!(topic)
- topic.destroy
+ topic.trash!
render nothing: true
end
diff --git a/app/models/invite.rb b/app/models/invite.rb
index 8427afccd9b..6a8c737a881 100644
--- a/app/models/invite.rb
+++ b/app/models/invite.rb
@@ -1,4 +1,7 @@
+require_dependency 'trashable'
+
class Invite < ActiveRecord::Base
+ include Trashable
belongs_to :user
belongs_to :topic
@@ -9,8 +12,6 @@ class Invite < ActiveRecord::Base
validates_presence_of :email
validates_presence_of :invited_by_id
- acts_as_paranoid
-
before_create do
self.invite_key ||= SecureRandom.hex
end
diff --git a/app/models/post.rb b/app/models/post.rb
index c4500a7470d..d5c1724ea32 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -3,19 +3,19 @@ require_dependency 'pretty_text'
require_dependency 'rate_limiter'
require_dependency 'post_revisor'
require_dependency 'enum'
+require_dependency 'trashable'
require 'archetype'
require 'digest/sha1'
class Post < ActiveRecord::Base
include RateLimiter::OnCreateRecord
+ include Trashable
versioned if: :raw_changed?
rate_limit
- acts_as_paranoid
- after_recover :update_flagged_posts_count
belongs_to :user
belongs_to :topic, counter_cache: :posts_count
@@ -52,6 +52,11 @@ class Post < ActiveRecord::Base
@types ||= Enum.new(:regular, :moderator_action)
end
+ def recover!
+ super
+ update_flagged_posts_count
+ end
+
def raw_quality
sentinel = TextSentinel.body_sentinel(raw)
errors.add(:raw, I18n.t(:is_invalid)) unless sentinel.valid?
diff --git a/app/models/post_action.rb b/app/models/post_action.rb
index 0167ad38910..59b3cd12b43 100644
--- a/app/models/post_action.rb
+++ b/app/models/post_action.rb
@@ -1,10 +1,12 @@
require_dependency 'rate_limiter'
require_dependency 'system_message'
+require_dependency 'trashable'
class PostAction < ActiveRecord::Base
class AlreadyActed < StandardError; end
include RateLimiter::OnCreateRecord
+ include Trashable
attr_accessible :post_action_type_id, :post_id, :user_id, :post, :user, :post_action_type, :message, :related_post_id
@@ -12,8 +14,6 @@ class PostAction < ActiveRecord::Base
belongs_to :user
belongs_to :post_action_type
- acts_as_paranoid
-
rate_limit :post_action_rate_limiter
validate :message_quality
@@ -114,8 +114,7 @@ class PostAction < ActiveRecord::Base
def self.remove_act(user, post, post_action_type_id)
if action = where(post_id: post.id, user_id: user.id, post_action_type_id: post_action_type_id).first
- action.destroy
- action.deleted_at = Time.zone.now
+ action.trash!
action.run_callbacks(:save)
end
end
diff --git a/app/models/topic.rb b/app/models/topic.rb
index 1fa8e1d9398..eef3bb19a7e 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -4,10 +4,12 @@ require_dependency 'topic_view'
require_dependency 'rate_limiter'
require_dependency 'text_sentinel'
require_dependency 'text_cleaner'
+require_dependency 'trashable'
class Topic < ActiveRecord::Base
include ActionView::Helpers
include RateLimiter::OnCreateRecord
+ include Trashable
def self.max_sort_order
2**31 - 1
@@ -18,9 +20,17 @@ class Topic < ActiveRecord::Base
end
versioned if: :new_version_required?
- acts_as_paranoid
- after_recover :update_flagged_posts_count
- after_destroy :update_flagged_posts_count
+
+
+ def trash!
+ super
+ update_flagged_posts_count
+ end
+
+ def recover!
+ super
+ update_flagged_posts_count
+ end
rate_limit :default_rate_limiter
rate_limit :limit_topics_per_day
diff --git a/app/models/user.rb b/app/models/user.rb
index 1d70b503656..fb9f8916dc9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -442,11 +442,11 @@ class User < ActiveRecord::Base
posts.order("post_number desc").each do |p|
if p.post_number == 1
- p.topic.destroy
+ p.topic.trash!
# TODO: But the post is not destroyed. Why?
else
# TODO: This should be using the PostDestroyer!
- p.destroy
+ p.trash!
end
end
end
diff --git a/app/serializers/listable_topic_serializer.rb b/app/serializers/listable_topic_serializer.rb
index 25bca68bf7c..2ec23383c18 100644
--- a/app/serializers/listable_topic_serializer.rb
+++ b/app/serializers/listable_topic_serializer.rb
@@ -21,11 +21,11 @@ class ListableTopicSerializer < BasicTopicSerializer
def age
AgeWords.age_words(Time.now - (object.created_at || Time.now))
end
-
+
def bumped
object.created_at < object.bumped_at
end
-
+
def bumped_age
return nil if object.bumped_at.blank?
AgeWords.age_words(Time.now - object.bumped_at)
diff --git a/config/initializers/99-rack-cache.rb b/config/initializers/99-rack-cache.rb
index 292d310d0fb..822d1e328ce 100644
--- a/config/initializers/99-rack-cache.rb
+++ b/config/initializers/99-rack-cache.rb
@@ -2,6 +2,10 @@ if Rails.configuration.respond_to?(:enable_rack_cache) && Rails.configuration.en
require 'rack-cache'
require 'redis-rack-cache'
+ # by default we will cache up to 3 minutes in redis, if you want to cut down on redis usage
+ # cut down this number
+ RedisRackCache.max_cache_seconds = 60 * 3
+
url = DiscourseRedis.url
class Rack::Cache::Discourse < Rack::Cache::Context
diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml
index 09e0290e643..d98acc0771b 100644
--- a/config/locales/client.nl.yml
+++ b/config/locales/client.nl.yml
@@ -34,6 +34,7 @@ nl:
you: Jij
or: of
now: zonet
+ read_more: lees verder
suggested_topics:
title: Aanbevolen topics
@@ -75,8 +76,8 @@ nl:
"2": "Likes ontvangen"
"3": "Bladwijzers"
"4": "Topics"
- "5": "Berichten"
- "6": "Responses"
+ "5": "Antwoorden"
+ "6": "Reacties"
"7": "Genoemd"
"9": "Citaten"
"10": "Favorieten"
@@ -100,6 +101,9 @@ nl:
external_links_in_new_tab: Open alle externe links in een nieuw tabblad
enable_quoting: Activeer antwoord-met-citaat voor geselecteerde tekst
+ moderator: "{{user}} is een moderator"
+ admin: "{{user}} is een admin"
+
change_password:
action: wijzig
success: (e-mail verzonden)
@@ -248,7 +252,7 @@ nl:
disable: "Schakel naar normale weergave"
private_message_info:
- title: 'Privé-conversatie'
+ title: 'Privé-bericht'
invite: Nodig anderen uit...
email: E-mail
@@ -375,9 +379,9 @@ nl:
edited: " {{username}} {{link}}"
liked: " {{username}} {{link}}"
private_message: " {{username}} {{link}}"
- invited_to_private_message: "{{username}} heeft je uitgenodigd voor een privé-conversatie: {{link}}"
+ invited_to_private_message: " {{username}} {{link}}"
invitee_accepted: " {{username}} heeft je uitnodiging geaccepteerd en heeft zich ingeschreven om deel te nemen."
- moved_post: " {{username}} heeft je post verplaast naar {{link}}"
+ moved_post: " {{username}} verplaatst naar {{link}}"
total_flagged: aantal gemarkeerde berichten
image_selector:
@@ -437,7 +441,7 @@ nl:
create_in: "Maak een {{categoryName}} topic"
create: Maak topic
create_long: Maak een nieuw topic
- private_message: Start een privé-gesprek
+ private_message: Stuur een privé-bericht
list: Topics
new: nieuw topic
title: Topic
@@ -535,11 +539,11 @@ nl:
inviting: Uitnodigen...
invite_private:
- title: Nodig uit voor privé-conversatie
+ title: Stuur een privé-bericht
email_or_username: E-mail of gebruikersnaam van genodigde
email_or_username_placeholder: e-mailadres of gebruikersnaam
action: Uitnodigen
- success: "Bedankt! We hebben deze persoon uitgenodigd om deel te nemen aan deze privé-conversatie."
+ success: "Bedankt! We hebben deze persoon dit privé-bericht gestuurd."
error: "Sorry, er is iets misgegaan bij het uitnodigen van deze persoon"
invite_reply:
@@ -656,8 +660,8 @@ nl:
inappropriate: "{{icons}} markeerden dit als ongepast"
notify_moderators: "{{icons}} lichtte moderators in"
notify_moderators_with_url: "{{icons}} lichtte moderators in"
- notify_user: "{{icons}} begonnen een privé-conversatie"
- notify_user_with_url: "{{icons}} begonnen een privé-conversatie"
+ notify_user: "{{icons}} verstuurde een privé-bericht"
+ notify_user_with_url: "{{icons}} verstuurde een privé-bericht"
bookmark: "{{icons}} voegden dit toe aan hun favorieten"
like: "{{icons}} vinden dit leuk"
vote: "{{icons}} hebben hier op gestemd"
@@ -666,7 +670,7 @@ nl:
spam: Jij markeerde dit als spam
inappropriate: Jij markeerde dit als ongepast
notify_moderators: Jij markeerde dit voor moderatie
- notify_user: Jij begon een privé-conversatie met deze persoon
+ notify_user: Jij stuurde een privé-bericht naar deze persoon
bookmark: Jij voegde dit bericht toe aan je favorieten
like: Jij vindt dit leuk
vote: Jij hebt op dit bericht gestemd
@@ -684,8 +688,8 @@ nl:
one: "Jij en iemand anders markeerden dit voor moderatie"
other: "Jij en {{count}} anderen markeerden dit voor moderatie"
notify_user:
- one: "Jij en iemand anders begonnen een privé-conversatie met deze persoon"
- other: "Jij en {{count}} anderen begonnen een privé-conversatie met deze persoon"
+ one: "Jij en iemand anders stuurden een privé-bericht naar deze persoon"
+ other: "Jij en {{count}} anderen stuurden een privé-bericht naar deze persoon"
bookmark:
one: "Jij en iemand anders voegden dit bericht toe aan de favorieten"
other: "Jij en {{count}} anderen voegden dit bericht toe aan de favorieten"
@@ -709,8 +713,8 @@ nl:
one: "Iemand heeft dit bericht gemarkeerd voor moderatie"
other: "{{count}} Mensen hebben dit bericht gemarkeerd voor moderatie"
notify_user:
- one: "Iemand is een privé-conversatie begonnen met deze persoon"
- other: "{{count}} Mensen zijn een privé-conversatie begonnen met deze persoon"
+ one: "Iemand stuurde een privé-bericht naar deze persoon"
+ other: "{{count}} Mensen stuurden een privé-bericht naar deze persoon"
bookmark:
one: "Iemand heeft dit bericht toegevoegd aan zijn favorieten"
other: "{{count}} Mensen hebben dit bericht toegevoegd aan hun favorieten"
@@ -735,11 +739,13 @@ nl:
none: (geen categorie)
edit: bewerk
edit_long: Bewerk categorie
+ edit_uncategorized: "Wijzig ongecategoriseerd"
view: Bekijk topics in categorie
delete: Verwijder categorie
create: Maak categorie
save: Bewaar categorie
creation_error: Er ging bij het maken van de categorie iets mis.
+ save_error: Er ging iets mis bij het opslaan van de categorie.
more_posts: "bekijk alle {{posts}}..."
name: Naam categorie
description: Omschrijving
diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml
index 3e3cb3c5e59..73109097231 100644
--- a/config/locales/server.nl.yml
+++ b/config/locales/server.nl.yml
@@ -242,7 +242,7 @@ nl:
email_body: "%{link}\n\n%{message}"
notify_moderators:
title: "Licht moderatoren in"
- description: "Dit bericht moet door een moderator bekeken worden. Dit vanwege de FAQ, TOS of een andere reden hier nog niet genoemd."
+ description: "Dit bericht moet door een moderator bekeken worden. Dit vanwege de FAQ, TOS of een andere reden hier nog niet genoemd."
long_form: moderatoren ingelicht
email_title: "Graag aandacht voor een bericht in '%{title}'"
email_body: "%{link}\n\n%{message}"
@@ -340,6 +340,21 @@ nl:
title: Licht persoon in
xaxis: Dag
yaxis: Aantal privé-berichten
+ top_referrers:
+ title: Top verwijzingen
+ xaxis: Lid
+ num_clicks: Clicks
+ num_topics: Topics
+ top_traffic_sources:
+ title: Top trafficbronnen
+ xaxis: Domein
+ num_clicks: Clicks
+ num_topics: Topics
+ num_users: Leden
+ top_referred_topics:
+ title: Top doorverwezen topics
+ xaxis: Topic
+ num_clicks: Clicks
dashboard:
rails_env_warning: "Je server draait in %{env} modus."
@@ -400,11 +415,12 @@ nl:
company_domain: "De domeinnaam van het bedrijf dat deze site draait. Wordt gebruikt in juridische delen van de site, zoals /tos"
api_key: "De beveiligde API-sleutel wordt gebruikt om topics te maken en bij te werken. Gebruik /admin/api om deze in te stellen"
access_password: "Wanneer beperkte toegang aan staat, moet dit wachtwoord worden opgegeven."
- queue_jobs: "Zet verschillende taken in een queue binnen sidekiq, als ongeldige queues zich op dezelfde lijn bevinden"
+ queue_jobs: "Zet verschillende taken in een queue binnen sidekiq, bij 'false' worden taken ineens uitgevoerd"
crawl_images: Zet het ophalen van afbeeldingen van externe bronnen aan
ninja_edit_window: "Hoe snel je een aanpassing kan maken zonder dat er een nieuwe versie wordt opgeslagen, in seconden."
enable_imgur: "Gebruik de imgur API voor uploads en sla afbeeldingen niet lokaal op"
- imgur_api_key: "imgur.com API-sleutel - nodig om afbeeldingen te kunnen uploaden naar imgur"
+ imgur_client_id: "Je imgur.com client ID, nodig om afbeeldingen te kunnen uploaden naar imgur"
+ imgur_client_secret: "Je imgur.com client secret. Is nog niet nodig voor het uploaden van afbeeldingen, maar dat zou in de toekomst kunnen veranderen."
imgur_endpoint: "End point voor het uploaden van imgur.com-afbeeldingen"
max_image_width: Maximale breedte voor een afbeelding in een bericht
category_featured_topics: Aantal topics dat wordt weergegeven in de categorielijst
@@ -439,10 +455,11 @@ nl:
flags_required_to_hide_post: "Berichten zullen automatisch worden verborgen zodra het aantal meldingen maximaal dit aantal is (0 voor nooit)"
cooldown_minutes_after_hiding_posts: "Hoeveel minuten moet iemand wachten voordat zij hun bericht kunnen wijzigen nadat het is verborgen door meldingen"
- traditional_markdown_linebreaks: "Gebruik traditionele regeleinden in Markdown, omloop is impliciet tenzij er 2 spaties aan vooraf gaan"
+ traditional_markdown_linebreaks: "Gebruik traditionele regeleinden in Markdown, gebruik 2 spaties voor een nieuw regeleinde"
post_undo_action_window_mins: "Het tijdsbestek waarin iemand een actie binnen een bericht kan terugdraaien (zoals 'vind ik leuk')"
must_approve_users: "De eigenaars van een forum moeten de leden accepteren voordat zij toegang krijgen."
ga_tracking_code: "Google analytics trackingcode, zie: http://google.com/analytics"
+ ga_domain_name: "Google analytics domeinnaam, bijv. mijnsite.nl; zie http://google.com/analytics"
top_menu: "De volgorde en selectie van items in het hoofdmenu. Bijvoorbeeld latest|hot|read|favorited|unread|new|posted|categories"
post_menu: "De volgorde en selectie van items in het berichtmenu. Bijvoorbeeld like|edit|flag|delete|share|bookmark|reply"
share_links: "De volgorde en selectie van items in het deelmenu. Bijvoorbeeld twitter|facebook|google+"
@@ -475,7 +492,7 @@ nl:
facebook_app_id: "app_id (registreer op https://developers.facebook.com/apps)"
facebook_app_secret: "app_secret (registreer op https://developers.facebook.com/apps)"
- enable_github_logins: Zet inloggen met Facebook aan. Hiervoor heb je een facebook_app_id en facebook_app_secret nodig.
+ enable_github_logins: Zet inloggen met Github aan. Hiervoor heb je een github_client_id en github_client_secret nodig.
github_client_id: "github_client_id (registreer op https://github.com/settings/applications)"
github_client_secret: "github_client_secret (registreer op https://github.com/settings/applications)"
@@ -487,9 +504,11 @@ nl:
previous_visit_timeout_hours: "Hoe lang een bezoek duurt voordat we het als het 'vorige' bezoek beschouwen, in uren."
uncategorized_name: De naam voor ongecategoriseerde topics in de categorielijst
+ uncategorized_color: De achtergrondkleur van de badge voor de categorie met topics zonder categorie
+ uncategorized_text_color: De tekstkleur van de badge voor de categorie met topics zonder categorie
- rate_limit_create_topic: "Hoeveel seconden voordat je een ander topic kan aanmaken"
- rate_limit_create_post: "Hoeveel seconden voordat je een ander bericht kan aanmaken"
+ rate_limit_create_topic: Hoeveel seconden voordat je een ander topic kan aanmaken
+ rate_limit_create_post: Hoeveel seconden voordat je een ander bericht kan aanmaken
max_likes_per_day: Het maximaal aantal keren per dag dat een lid berichten leuk kan vinden
max_flags_per_day: Het maximaal aantal moderatie-meldingen dat een lid per dag kan geven
@@ -583,7 +602,7 @@ nl:
archived_disabled: "Deze topic is niet langer gearchiveerd en kan weer veranderd worden."
closed_enabled: "Deze topic is nu gesloten. Nieuwe reacties worden niet langer geaccepteerd."
closed_disabled: "Deze topic is nu geopend. Nieuwe reacties worden weer geaccepteerd."
- pinned_enabled: "Deze topic is nu gepind en zal bovenaan de lijst van topics in zijn categorie staan."
+ pinned_enabled: "Deze topic is nu gepind en zal bovenaan de lijst van topics in zijn categorie staan. Wanneer iemand op 'Verwijder pin' drukt, zal de topic voor diegene niet meer bovenaan staan."
pinned_disabled: "Deze topic is niet langer gepind en zal niet meer bovenaan de lijst van topics in zijn categorie staan."
visible_enabled: "Deze topic is nu zichtbaar en zal weer worden weergegeven in topiclijsten."
visible_disabled: "Deze topic is nu onzichtbaar en zal niet worden weergegeven in topiclijsten, en kan alleen via een directe link worden bezocht."
@@ -613,9 +632,9 @@ nl:
not_allowed: "is niet toegestaan vanaf die e-mailprovider. Gebruik een ander e-mailadres."
invite_mailer:
- subject_template: "[%{site_name}] %{invitee_name} heeft je uitgenodigd om aan een discussie deel te nemen op %{site_name}"
+ subject_template: "[%{site_name}] %{invitee_name} heeft je uitgenodigd om op een privé-bericht te reageren op %{site_name}"
text_body_template: |
- %{invitee_name} heeft je uitgenodigd voor deze topic: "%{topic_title}" op %{site_name}.
+ %{invitee_name} heeft je uitgenodigd voor dit bericht: "%{topic_title}" op %{site_name}.
Mocht je geïnteresseerd zijn, klik dan op de link hieronder om naar de discussie te gaan:
diff --git a/docs/SOFTWARE.md b/docs/SOFTWARE.md
index a13d104ebac..bfe79c6f584 100644
--- a/docs/SOFTWARE.md
+++ b/docs/SOFTWARE.md
@@ -14,7 +14,6 @@ The following Ruby Gems are used in Discourse:
* [rack-mini-profiler](https://rubygems.org/gems/rack-mini-profiler)
* [sass](https://rubygems.org/gems/sass)
* [rest-client](https://rubygems.org/gems/rest-client)
-* [rails3_acts_as_paranoid](https://rubygems.org/gems/rails3_acts_as_paranoid)
* [activerecord-postgres-hstore](https://rubygems.org/gems/activerecord-postgres-hstore)
* [fastimage](https://rubygems.org/gems/fastimage)
* [seed-fu](https://rubygems.org/gems/seed-fu)
diff --git a/lib/post_destroyer.rb b/lib/post_destroyer.rb
index c5a2515b011..52c88ee3564 100644
--- a/lib/post_destroyer.rb
+++ b/lib/post_destroyer.rb
@@ -37,8 +37,7 @@ class PostDestroyer
# Feature users in the topic
Jobs.enqueue(:feature_topic_users, topic_id: @post.topic_id, except_post_id: @post.id)
- # Actually soft-delete the post :)
- @post.destroy
+ @post.trash!
Topic.reset_highest(@post.topic_id)
@post.update_flagged_posts_count
diff --git a/lib/trashable.rb b/lib/trashable.rb
new file mode 100644
index 00000000000..eabc4882423
--- /dev/null
+++ b/lib/trashable.rb
@@ -0,0 +1,46 @@
+module Trashable
+ extend ActiveSupport::Concern
+
+ included do
+ default_scope where(with_deleted_scope_sql)
+
+ # scope unscoped does not work
+ end
+
+
+ module ClassMethods
+ def with_deleted
+ # lifted from acts_as_paranoid, works around https://github.com/rails/rails/issues/4306
+ #
+ # with this in place Post.limit(10).with_deleted, will work as expected
+ #
+ scope = self.scoped.with_default_scope
+ scope.where_values.delete(with_deleted_scope_sql)
+ scope
+ end
+
+ def with_deleted_scope_sql
+ scoped.table[:deleted_at].eq(nil).to_sql
+ end
+ end
+
+ def trash!
+ # note, an argument could be made that the column should probably called trashed_at
+ # however, deleted_at is the terminology used in the UI
+ #
+ # we could hijack use a delete! and delete - redirecting the originals elsewhere, but that is
+ # confusing as well. So for now, we go with trash!
+ #
+ update_column(:deleted_at, DateTime.now)
+ end
+
+ def recover!
+ # see: https://github.com/rails/rails/issues/8436
+ #
+ # Fixed in Rails 4
+ #
+ self.class.unscoped.update_all({deleted_at: nil}, id: self.id)
+ raw_write_attribute :deleted_at, nil
+ end
+
+end
diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb
index ff9e70875ea..ef461a0de93 100644
--- a/spec/components/guardian_spec.rb
+++ b/spec/components/guardian_spec.rb
@@ -222,14 +222,14 @@ describe Guardian do
it 'correctly handles post visibility' do
Guardian.new(user).can_see?(post).should be_true
- post.destroy
+ post.trash!
post.reload
Guardian.new(user).can_see?(post).should be_false
Guardian.new(admin).can_see?(post).should be_true
- post.recover
+ post.recover!
post.reload
- topic.destroy
+ topic.trash!
topic.reload
Guardian.new(user).can_see?(post).should be_false
Guardian.new(admin).can_see?(post).should be_true
diff --git a/spec/components/topic_view_spec.rb b/spec/components/topic_view_spec.rb
index e5eb30348e0..5ebf3f004e0 100644
--- a/spec/components/topic_view_spec.rb
+++ b/spec/components/topic_view_spec.rb
@@ -196,7 +196,7 @@ describe TopicView do
describe "filter_posts_after" do
it "returns undeleted posts after a post" do
- topic_view.filter_posts_after(p1.post_number).should == [p2, p3, p5]
+ topic_view.filter_posts_after(p1.post_number).map(&:id).should == [p2.id, p3.id, p5.id]
topic_view.should_not be_initial_load
topic_view.index_offset.should == 1
topic_view.index_reverse.should be_false
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index 56feee6437f..473553cf2d8 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -29,7 +29,7 @@ describe InvitesController do
end
it "destroys the invite" do
- Invite.any_instance.expects(:destroy)
+ Invite.any_instance.expects(:trash!)
delete :destroy, email: invite.email
end
diff --git a/spec/controllers/post_actions_controller_spec.rb b/spec/controllers/post_actions_controller_spec.rb
index a0a1dd2544b..29a782a7f9c 100644
--- a/spec/controllers/post_actions_controller_spec.rb
+++ b/spec/controllers/post_actions_controller_spec.rb
@@ -120,7 +120,7 @@ describe PostActionsController do
end
it "works with a deleted post" do
- flagged_post.destroy
+ flagged_post.trash!
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam]
response.should be_success
end
diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb
index 9d067207fd4..2456d952a7c 100644
--- a/spec/controllers/posts_controller_spec.rb
+++ b/spec/controllers/posts_controller_spec.rb
@@ -30,7 +30,7 @@ describe PostsController do
context "deleted post" do
before do
- post.destroy
+ post.trash!
end
it "can't find deleted posts as an anonymous user" do
@@ -121,7 +121,7 @@ describe PostsController do
end
it "calls recover" do
- Post.any_instance.expects(:recover)
+ Post.any_instance.expects(:recover!)
xhr :put, :recover, post_id: post.id
end
diff --git a/spec/models/post_action_spec.rb b/spec/models/post_action_spec.rb
index 980d75a5f72..edab1bd98b1 100644
--- a/spec/models/post_action_spec.rb
+++ b/spec/models/post_action_spec.rb
@@ -78,7 +78,7 @@ describe PostAction do
it "should reset counts when a topic is deleted" do
PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
- post.topic.destroy
+ post.topic.trash!
PostAction.flagged_posts_count.should == 0
end
diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb
index 8e9be27b614..1816d3716d1 100644
--- a/spec/models/post_spec.rb
+++ b/spec/models/post_spec.rb
@@ -50,7 +50,7 @@ describe Post do
let(:post) { Fabricate(:post, post_args) }
before do
- post.destroy
+ post.trash!
post.reload
end
@@ -60,7 +60,7 @@ describe Post do
describe "recovery" do
before do
- post.recover
+ post.recover!
post.reload
end
diff --git a/spec/models/user_action_spec.rb b/spec/models/user_action_spec.rb
index 8782ffdf096..8a1c3644937 100644
--- a/spec/models/user_action_spec.rb
+++ b/spec/models/user_action_spec.rb
@@ -58,7 +58,7 @@ describe UserAction do
other_stats.should == expecting
- public_topic.destroy
+ public_topic.trash!
stats_for_user.should == []
stream_count.should == 0
@@ -66,7 +66,7 @@ describe UserAction do
category = Fabricate(:category, secure: true)
- public_topic.recover
+ public_topic.recover!
public_topic.category = category
public_topic.save