Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 84 additions & 32 deletions app/controllers/admin_posts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,44 +1,51 @@
class AdminPostsController < Admin::BaseController

before_action :admin_only, except: [:index, :show]
before_action :load_languages, except: [:show, :destroy]
before_action :load_admin_posts, only: [:index, :drafts]

# GET /admin_posts
def index
if params[:tag]
@tag = AdminPostTag.find_by(id: params[:tag])
if @tag
@admin_posts = @tag.admin_posts
end
end
@admin_posts ||= AdminPost
if params[:language_id].present? && (@language = Language.find_by(short: params[:language_id]))
@admin_posts = @admin_posts.where(language_id: @language.id)
@tags = AdminPostTag.distinct.joins(:admin_posts).where(admin_posts: { language_id: @language.id }).order(:name)
else
@admin_posts = @admin_posts.non_translated
@tags = AdminPostTag.order(:name)
end
@admin_posts = @admin_posts.order('created_at DESC').page(params[:page])
@page_subtitle = t(".page_title")
@pagy, @admin_posts = pagy(@admin_posts.posted.order(published_at: :desc))
end

# GET /admin_posts/drafts
def drafts
authorize AdminPost

@page_subtitle = t(".page_title")
@pagy, @admin_posts = pagy(@admin_posts.unposted.order(created_at: :desc))
end

# GET /admin_posts/1
def show
@admin_post = AdminPost.find(params[:id])
authorize(@admin_post) unless @admin_post.posted?

admin_posts = AdminPost.non_translated
@admin_post = AdminPost.find_by(id: params[:id])
unless @admin_post
raise ActiveRecord::RecordNotFound, "Couldn't find admin post '#{params[:id]}'"
if @admin_post.posted?
@admin_posts = admin_posts.posted.order(published_at: :desc).limit(8)
@previous_admin_post = admin_posts.posted.order(published_at: :desc).where("published_at < ?", @admin_post.published_at).first
@next_admin_post = admin_posts.posted.order(published_at: :asc).where("published_at > ?", @admin_post.published_at).first
else
@admin_posts = admin_posts.unposted.order(created_at: :desc).limit(8)
@previous_admin_post = admin_posts.unposted.order(created_at: :desc).where("created_at < ?", @admin_post.created_at).first
@next_admin_post = admin_posts.unposted.order(created_at: :asc).where("created_at > ?", @admin_post.created_at).first
end
@admin_posts = admin_posts.order('created_at DESC').limit(8)
@previous_admin_post = admin_posts.order('created_at DESC').where('created_at < ?', @admin_post.created_at).first
@next_admin_post = admin_posts.order('created_at ASC').where('created_at > ?', @admin_post.created_at).first
@page_subtitle = @admin_post.title.html_safe
respond_to do |format|
format.html # show.html.erb
format.js
end
end

# GET /admin_posts/1/preview
def preview
@preview_mode = true
@admin_post = AdminPost.find(params[:id])
authorize(@admin_post)
end

# GET /admin_posts/new
# GET /admin_posts/new.xml
def new
Expand All @@ -55,24 +62,55 @@ def edit
# POST /admin_posts
def create
@admin_post = AdminPost.new(admin_post_params)
@admin_post.posted = true if params[:post_button] && !@admin_post&.translated_post&.draft?

authorize @admin_post
if @admin_post.save
flash[:notice] = ts("Admin Post was successfully created.")
redirect_to(@admin_post)
else
render action: "new"
if !params[:edit_button] && @admin_post.valid?
if params[:preview_button]
@preview_mode = true
render action: "preview" and return
elsif !params[:edit_button] && @admin_post.save
flash[:notice] = t(".success")
redirect_to(admin_post_path(@admin_post)) and return
end
end

render action: "new"
end

# PUT /admin_posts/1
def update
@admin_post = AdminPost.find(params[:id])
@admin_post.attributes = admin_post_params
@admin_post.posted = true if params[:post_button] && !@admin_post&.translated_post&.draft?
authorize @admin_post

if !params[:edit_button] && @admin_post.valid?
if params[:preview_button]
@preview_mode = true
render :preview and return
elsif @admin_post.save
flash[:notice] = t(".success")
redirect_to(@admin_post) and return
end
end

render action: "edit"
end

# PUT /admin_posts/1/post
def post
@admin_post = AdminPost.find(params[:id])
authorize @admin_post
if @admin_post.update(admin_post_params)
flash[:notice] = ts("Admin Post was successfully updated.")
redirect_to(@admin_post)

@admin_post.posted = true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also check @admin_post&.translated_post&.draft? like we do in create and update to avoid potential bugs?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a validation to the model to prevent translations from being posted first, which should cover this and also prevent already published posts from turned into translations of a draft post.


if @admin_post.save
flash[:notice] = t(".success")
redirect_to @admin_post
else
render action: "edit"
flash[:error] = t(".error")
redirect_to(edit_admin_post_path(@admin_post))
end
end

Expand All @@ -81,7 +119,8 @@ def destroy
@admin_post = AdminPost.find(params[:id])
authorize @admin_post
@admin_post.destroy
redirect_to(admin_posts_path)

redirect_to(@admin_post.posted? ? admin_posts_path : drafts_admin_posts_path)
end

protected
Expand All @@ -90,6 +129,19 @@ def load_languages
@news_languages = Language.where(id: Locale.all.map(&:language_id)).default_order
end

def load_admin_posts
@tag = AdminPostTag.find_by(id: params[:tag]) if params[:tag]
@admin_posts = @tag&.admin_posts || AdminPost

if params[:language_id].present? && (@language = Language.find_by(short: params[:language_id]))
@admin_posts = @admin_posts.where(language_id: @language.id)
@tags = AdminPostTag.distinct.joins(:admin_posts).where(admin_posts: { language_id: @language.id }).order(:name)
else
@admin_posts = @admin_posts.non_translated
@tags = AdminPostTag.order(:name)
end
end

private

def admin_post_params
Expand Down
5 changes: 4 additions & 1 deletion app/helpers/admin_post_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module AdminPostHelper
def sorted_translations(admin_post)
admin_post.translations.sort_by do |translation|
translations = admin_post.translations
translations = translations.posted if admin_post.posted?

translations.sort_by do |translation|
language = translation.language
language.sortable_name.blank? ? language.short : language.sortable_name
end
Expand Down
37 changes: 34 additions & 3 deletions app/models/admin_post.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,26 @@ class AdminPost < ApplicationRecord
validate :translated_post_must_exist

validate :translated_post_language_must_differ
validate :translated_post_must_be_posted_first

scope :non_translated, -> { where("translated_post_id IS NULL") }

scope :for_homepage, -> { order("created_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) }
scope :for_homepage, -> { posted.order(published_at: :desc).limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) }

scope :unposted, -> { where(posted: false) }
scope :posted, -> { where(posted: true) }

before_save :inherit_translated_post_comment_permissions, :inherit_translated_post_tags
after_save :expire_cached_home_admin_posts, :update_translation_comment_permissions, :update_translation_tags
before_save :set_published_at, if: :posted_changed?
after_destroy :expire_cached_home_admin_posts
after_save :expire_cached_home_admin_posts, :update_translation_comment_permissions, :update_translation_tags
after_save :post_translations, if: :saved_change_to_posted?

# Return the name to link comments to for this object
def commentable_name
self.title
end

def commentable_owners
begin
[Admin.find(self.admin_id)]
Expand All @@ -54,6 +61,10 @@ def commentable_owners
end
end

def draft?
!self.posted?
end

def tag_list
tags.map{ |t| t.name }.join(", ")
end
Expand All @@ -75,10 +86,16 @@ def translated_post_must_exist
def translated_post_language_must_differ
return if translated_post.blank?
return unless translated_post.language == language

errors.add(:translated_post_id, "cannot be same language as original post")
end

def translated_post_must_be_posted_first
return if translated_post.blank?

errors.add(:translated_post_id, :must_be_posted_first) if translated_post.draft? && self.posted?
end

####################
# DELAYED JOBS
####################
Expand Down Expand Up @@ -137,4 +154,18 @@ def update_translation_tags
end
end
end

def set_published_at
self.published_at = Time.current if self.posted && !self.published_at
end

def post_translations
return if translations.blank? || !self.posted

transaction do
translations.find_each do |post|
post.update(posted: true, published_at: self.published_at)
end
end
end
end
22 changes: 17 additions & 5 deletions app/policies/admin_post_policy.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
class AdminPostPolicy < ApplicationPolicy
POSTING_ROLES = %w[superadmin board board_assistants_team communications support translation].freeze
DRAFTING_ROLES = %w[policy_and_abuse].freeze

def can_post?
user_has_roles?(POSTING_ROLES)
end

alias new? can_post?
alias edit? can_post?
alias create? can_post?
alias update? can_post?
alias destroy? can_post?
def can_draft?
user_has_roles?(DRAFTING_ROLES) || can_post?
end

def edit?
can_post? || (@record&.draft? && can_draft?)
end

alias new? can_draft?
alias show? can_draft?
alias create? edit?
alias update? edit?
alias destroy? edit?
alias post? can_post?
alias drafts? can_draft?
alias preview? edit?
end
9 changes: 9 additions & 0 deletions app/views/admin/_admin_nav.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@
<li>
<%= span_if_current t(".ao3_news"), admin_posts_path %>
</li>
<% if policy(AdminPost).can_draft? %>
<li>
<%= span_if_current t(".ao3_news_drafts"), drafts_admin_posts_path %>
</li>
<% end %>
<% if policy(AdminPost).can_post? %>
<li>
<%= span_if_current t(".post_ao3_news"), new_admin_post_path %>
</li>
<% elsif policy(AdminPost).can_draft? %>
<li>
<%= span_if_current t(".draft_ao3_news"), new_admin_post_path %>
</li>
<% end %>
<% if params[:controller] == "admin_posts" && params[:action] == "edit" %>
<li>
Expand Down
5 changes: 5 additions & 0 deletions app/views/admin/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@
<%= link_to t(".nav.posts.admin_posts"), admin_posts_path %>
<ul class="menu">
<li><%= link_to t(".nav.posts.news"), admin_posts_path %></li>
<% if policy(AdminPost).can_draft? %>
<li><%= link_to t(".nav.posts.news_drafts"), drafts_admin_posts_path %></li>
<% end %>
<% if policy(AdminPost).can_post? %>
<li><%= link_to t(".nav.posts.post_news"), new_admin_post_path %></li>
<% elsif policy(AdminPost).can_draft? %>
<li><%= link_to t(".nav.posts.draft_news"), new_admin_post_path %></li>
<% end %>
<% if policy(ArchiveFaq).translation_access? %>
<li><%= link_to t(".nav.posts.faqs"), archive_faqs_path %></li>
Expand Down
18 changes: 4 additions & 14 deletions app/views/admin_posts/_admin_index.html.erb
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
<!--Descriptive page name, messages and instructions-->
<h2 class="heading"><%= ts("AO3 News (includes Release Notes)") %></h2>
<h2 class="heading"><%= t(".page_heading") %></h2>
<!--/descriptions-->
<!--subnav-->
<%= render 'filters' %>
<%= render :partial => 'admin/admin_nav' %>
<!--/subnav-->

<!--main content-->
<h3 class="heading"><%= ts("Manage News Postings") %></h3>
<h3 class="landmark heading"><%= t(".landmark") %></h3>
<dl class="news index group">
<% @admin_posts.each do |admin_post| %>
<dt><%= link_to admin_post.title.html_safe, admin_post %></dt>
<dd>
<p class="datetime"><%= ts("Created at %{created_date} and updated at %{updated_date}", :created_date => admin_post.created_at, :updated_date => admin_post.updated_at) %></p>
<ul class="actions">
<li><%= link_to ts("Show"), admin_post %></li>
<li><%= link_to ts("Edit"), edit_admin_post_path(admin_post) %></li>
<li><%= link_to ts("Delete"), admin_post, data: {confirm: 'Are you sure?'}, :method => :delete %></li>
</ul>
</dd>
<% end %>
<%= render partial: "admin_post_blurb", collection: @admin_posts, as: :admin_post %>
</dl>
<!--/content-->
<!--subnav-->
<%= will_paginate @admin_posts %>
<%== pagy_nav @pagy %>
<!--/subnav-->
13 changes: 9 additions & 4 deletions app/views/admin_posts/_admin_post.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@
<h4 class="landmark heading"><%= ts("Post Header") %></h4>
<div class="wrapper">
<dl class="meta">
<dt class="published"><%= ts("Published:") %></dt>
<dd class="published"><%= admin_post.created_at %></dd>
<% if admin_post.posted? %>
<dt class="published"><%= t(".published") %></dt>
<dd class="published"><%= admin_post.published_at %></dd>
<% end %>
<% if admin_post.translated_post %>
<dt class="original translations"><%= ts("Original:") %></dt>
<dd class="original translations"><%= link_to admin_post.translated_post.title, admin_post.translated_post %></dd>
<% elsif !admin_post.translations.empty? %>
<% else %>
<% translations = sorted_translations(admin_post) %>
<% unless translations.blank? %>
<dt class="translations"><%= ts("Translations:") %></dt>
<dd class="translations">
<ul class="languages commas">
<% for translation in sorted_translations(admin_post) %>
<% translations.each do |translation| %>
<li><%= link_to translation.language.name, translation, lang: translation.language.short %></li>
<% end %>
</ul>
</dd>
<% end %>
<% end %>
<% if admin_post.tags.length > 0 %>
<dt class="tags"><%= ts("Tags:") %></dt>
Expand Down
Loading
Loading