Skip to content

Commit

Permalink
Merge branch '3.2-compat'
Browse files Browse the repository at this point in the history
Conflicts:
	app/controllers/articles_controller.rb
	app/controllers/categories_controller.rb
	app/models/kb_article.rb
	app/views/articles/show.html.erb
	config/routes.rb
	init.rb
  • Loading branch information
alexbevi committed Jun 23, 2016
2 parents 424c023 + f8b82cb commit e6df7d2
Show file tree
Hide file tree
Showing 40 changed files with 609 additions and 72 deletions.
7 changes: 5 additions & 2 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Contributors:
* Daniel Felix
* Messinger
* xarlie
* Rob Spearman
* Eduard Kuleshov
* Axel Kämpfe

Documentation:
* Alan Bowman
Expand Down Expand Up @@ -56,7 +59,7 @@ French:
* myorama
* Xavier Calland
* LabriePierre

German:
* eschsa
* cforce
Expand Down Expand Up @@ -96,7 +99,7 @@ Spanish:
* Carlos Solano
* dtamajon

Swedish:
Swedish:
* Peter Brauner

Turkish:
Expand Down
52 changes: 45 additions & 7 deletions app/controllers/articles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class ArticlesController < ApplicationController
include WatchersHelper

before_filter :find_project_by_project_id, :authorize
before_filter :get_article, :except => [:index, :new, :create, :preview, :comment, :tagged, :rate]
before_filter :get_article, :except => [:index, :new, :create, :preview, :comment, :tagged, :rate, :authored]

rescue_from ActionView::MissingTemplate, :with => :force_404
rescue_from ActiveRecord::RecordNotFound, :with => :force_404
Expand All @@ -27,10 +27,25 @@ def index

@articles_newest = @project.articles.order("created_at DESC").first(summary_limit)
@articles_latest = @project.articles.order("updated_at DESC").first(summary_limit)
@articles_popular = @project.articles.includes(:viewings).limit(summary_limit).sort_by(&:view_count).reverse
@articles_toprated = @project.articles.includes(:ratings).limit(summary_limit).sort_by(&:rated_count).reverse
@articles_popular = @project.articles.includes(:viewings).sort_by(&:view_count).reverse.first(summary_limit)
@articles_toprated = @project.articles.includes(:ratings).sort_by { |a| [a.rating_average, a.rated_count] }.reverse.first(summary_limit)

@tags = @project.articles.tag_counts
@tags = @project.articles.tag_counts.sort { |a, b| a.name.downcase <=> b.name.downcase }
end

def authored

@author_id = params[:author_id]
@articles = @project.articles.where(:author_id => @author_id).order("#{KbArticle.table_name}.#{sort_column} #{sort_direction}")

if params[:tag]
@tag = params[:tag]
@articles = @articles.tagged_with(@tag)
end

@categories = @project.categories.where(:parent_id => nil)

@tags = @articles.tag_counts.sort { |a, b| a.name.downcase <=> b.name.downcase }
end

def new
Expand Down Expand Up @@ -71,7 +86,7 @@ def create

def show
@article.view request.remote_ip, User.current
@attachments = @article.attachments.sort_by(&:created_on)
@attachments = @article.attachments.all.sort_by(&:created_on)
@comments = @article.comments
@versions = @article.versions.select("id, author_id, version_comments, updated_at, version").order('version DESC')

Expand All @@ -83,16 +98,28 @@ def show
end

def edit
@categories=@project.categories
if not @article.editable_by?(User.current)
render_403
return false
end

@categories=@project.categories.all

# don't keep previous comment
@article.version_comments = nil
@article.version = params[:version]
end

def update

if not @article.editable_by?(User.current)
render_403
return false
end

@article.updater_id = User.current.id
params[:article][:category_id] = params[:category_id]
@categories = @project.categories
@categories = @project.categories.all
# don't keep previous comment
@article.version_comments = nil
@article.version_comments = params[:article][:version_comments]
Expand Down Expand Up @@ -129,13 +156,24 @@ def destroy_comment
end

def destroy

if not @article.editable_by?(User.current)
render_403
return false
end

KbMailer.article_destroy(@article).deliver
@article.destroy
flash[:notice] = l(:label_article_removed)
redirect_to({ :controller => 'articles', :action => 'index', :project_id => @project})
end

def add_attachment
if not @article.editable_by?(User.current)
render_403
return false
end

attachments = attach(@article, params[:attachments])
redirect_to({ :action => 'show', :id => @article.id, :project_id => @project })
end
Expand Down
30 changes: 24 additions & 6 deletions app/controllers/categories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,23 @@ class CategoriesController < ApplicationController
rescue_from ActiveRecord::RecordNotFound, :with => :force_404

def show

@articles = @category.articles.order("#{sort_column} #{sort_direction}")

if params[:tag]
@tag = params[:tag]
@articles = @articles.tagged_with(@tag)
end

@categories = @project.categories.where(:parent_id => nil)

@tags = @articles.tag_counts.sort { |a, b| a.name.downcase <=> b.name.downcase }

respond_to do |format|
format.html { render :template => 'categories/show', :layout => !request.xhr? }
format.atom { render_feed(@articles, :title => "#{l(:knowledgebase_title)}: #{l(:label_category)}: #{@category.title}") }
end

end

def new
Expand Down Expand Up @@ -53,15 +63,23 @@ def edit
end

def destroy
@categories=@project.categories
if @category.articles.size == 0
@category.destroy
flash[:notice] = l(:label_category_deleted)
redirect_to({ :controller => :articles, :action => 'index', :project_id => @project})
else
@categories = @project.categories.all

# Do not allow deletion of categories with existing subcategories
@subcategories = @project.categories.where(:parent_id => @category.id)

if @subcategories.size != 0
@articles = @category.articles.all
flash[:error] = l(:label_category_has_subcategory_cannot_delete)
render(:action => 'show')
elsif @category.articles.size != 0
@articles = @category.articles.all
flash[:error] = l(:label_category_not_empty_cannot_delete)
render(:action => 'show')
else
@category.destroy
flash[:notice] = l(:label_category_deleted)
redirect_to({ :controller => :articles, :action => 'index', :project_id => @project})
end
end

Expand Down
51 changes: 39 additions & 12 deletions app/helpers/knowledgebase_helper.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
module KnowledgebaseHelper
include Redmine::Export::PDF
include KnowledgebaseSettingsHelper
include ActionView::Helpers::NumberHelper

def format_article_summary(article, format, options = {})
output = case format
when "normal"
truncate article.summary, :length => options[:truncate]
""
#truncate article.summary, :length => options[:truncate]
when "newest"
l(:label_summary_newest_articles,
:ago => time_ago_in_words(article.created_at),
Expand All @@ -19,15 +21,24 @@ def format_article_summary(article, format, options = {})
:count => article.view_count,
:created => article.created_at.to_date.to_formatted_s(:rfc822))
when "toprated"
l(:label_summary_toprated_articles,
:rating_avg => article.rating_average.to_s,
:rating_max => "5",
:count => article.rated_count)
if article.rating_average.to_i == 0
l(:label_unrated_article)
else
l(:label_summary_toprated_articles,
:rating_avg => article.rating_average.to_s,
:rating_max => "5",
:count => article.rated_count)
end
else
nil
end

content_tag(:div, raw(output), :class => "summary")
sum = ""
unless redmine_knowledgebase_settings_value(:disable_article_summaries)
sum = "<p>" + (truncate article.summary, :length => options[:truncate]) + "</p>"
end

content_tag(:div, raw(sum + output), :class => "summary")
end

def sort_categories?
Expand All @@ -54,7 +65,7 @@ def sortable(column, title = nil)
title ||= column.titleize
css_class = column == sort_column ? "current #{sort_direction}" : nil
direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
link_to title, {:id => params[:id], :sort => column, :direction => direction }, {:class => css_class}
link_to title, {:id => params[:id], :tag => params[:tag], :author_id => params[:author_id], :sort => column, :direction => direction }, {:class => css_class}
end

def article_to_pdf(article, project)
Expand Down Expand Up @@ -94,13 +105,29 @@ def write_article(pdf, article)
end

def article_tabs
tabs = [{:name => 'content', :action => :content, :partial => 'articles/sections/content', :label => :label_content},
{:name => 'comments', :action => :comments, :partial => 'articles/sections/comments', :label => :label_comment_plural},
{:name => 'attachments', :action => :attachments, :partial => 'articles/sections/attachments', :label => :label_attachment_plural},
{:name => 'history', :action => :history, :partial => 'articles/sections/history', :label => :label_history}
]

content = {:name => 'content', :action => :content, :partial => 'articles/sections/content', :label => :label_content}
comments = {:name => 'comments', :action => :comments, :partial => 'articles/sections/comments', :label => :label_comment_plural}
attachments = {:name => 'attachments', :action => :attachments, :partial => 'articles/sections/attachments', :label => :label_attachment_plural}
history = {:name => 'history', :action => :history, :partial => 'articles/sections/history', :label => :label_history}

unless redmine_knowledgebase_settings_value(:show_attachments_first)

tabs = [content, comments, attachments, history]
else

tabs = [attachments, content, comments, history]
end

# Do not show History if no permission
unless User.current.allowed_to?(:view_article_history, @project)
tabs.pop(1)
end

# TODO permissions?
# tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}

return tabs
end

def create_preview_link
Expand Down
41 changes: 29 additions & 12 deletions app/models/kb_article.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,39 @@ class KbArticle < ActiveRecord::Base
acts_as_versioned :if_changed => [:title, :content, :summary]
self.non_versioned_columns << 'comments_count'

acts_as_searchable :columns => [ "#{table_name}.title", "#{table_name}.content"],
:scope => preload(:project),
:date_column => "created_at"

acts_as_event :title => Proc.new {|o| status = (o.new_status ? "(#{l(:label_new_article)})" : nil ); "#{status} #{l(:label_title_articles)} ##{o.id} - #{o.title}" },
:description => :content,
:datetime => :updated_at,
:type => Proc.new { |o| 'article-' + (o.new_status ? 'add' : 'edit') },
:url => Proc.new { |o| {:controller => 'articles', :action => 'show', :id => o.id, :project_id => o.project} }

acts_as_activity_provider :scope => preload(:project),
:author_key => :author_id,
:type => 'kb_articles',
:timestamp => :updated_at
# Redmine 3.1.X
if ActiveRecord::VERSION::MAJOR >= 4
acts_as_activity_provider :scope => joins(:project),
:permission => :view_kb_articles,
:author_key => :author_id,
:type => 'kb_articles',
:timestamp => :updated_at

acts_as_searchable :columns => [ "#{table_name}.title", "#{table_name}.summary", "#{table_name}.content"],
:preload => [ :project ],
:date_column => "#{table_name}.created_at"
else
acts_as_activity_provider :find_options => {:include => :project},
:author_key => :author_id,
:type => 'kb_articles',
:timestamp => :updated_at

acts_as_searchable :columns => [ "#{table_name}.title", "#{table_name}.summary", "#{table_name}.content"],
:include => [ :project ],
:order_column => "#{table_name}.id",
:date_column => "#{table_name}.created_at"
end

has_many :comments, -> { order 'created_on DESC' }, :as => :commented, :dependent => :delete_all
has_many :comments, -> { order 'created_on DESC' }, :as => :commented, :dependent => :destroy

scope :visible, ->(*args) { joins(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_kb_articles, *args)) }
scope :visible, lambda {|*args| { :include => :project,
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_kb_articles, *args) } }

def recipients
notified = []
Expand All @@ -54,8 +69,10 @@ def recipients
notified.collect(&:mail)
end

def editable_by?(user)
user.allowed_to?(:edit_articles, self.project)
def editable_by?(user = User.current)
return user.allowed_to?(:edit_articles, self.project) ||
user.allowed_to?(:manage_articles, self.project) ||
(user.allowed_to?(:manage_own_articles, self.project) && self.author_id == user.id)
end

def attachments_deletable?(user = User.current)
Expand Down
11 changes: 11 additions & 0 deletions app/views/articles/_breadcrumb.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@


<p class="breadcrumb list-breadcrumb">
<% article.category.ancestors.each do |ancestor| %>
&nbsp;&raquo;&nbsp;
<%= link_to ancestor.title, { :controller => 'categories', :action => 'show', :id => ancestor.id, :project_id => @project} %>
<% end %>
&nbsp;&raquo;&nbsp;
<%= link_to article.category.title, { :controller => 'categories', :action => 'show', :id => article.category.id, :project_id => @project} %>
</p>

11 changes: 10 additions & 1 deletion app/views/articles/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@
<p><%= f.text_field :tag_list, :size => 80, :value => "#{@article.tag_list.join(",")}" %></p>
<p><%= f.text_field :version_comments, :size => 120, :label => l(:field_version_comments) %></p>
</div>

<% if @article.attachments.exists? %>
<div class="box">
<p><label><%= l(:label_attachment_plural) %></label>
<%= render :partial => "articles/sections/attachments" %>
</p>
</div>
<% end %>

<div class="box">
<p><label><%=l(:label_attachment_plural)%></label><%= render :partial => 'attachments/form' %></p>
<p><label><%=l(:label_attachment_add)%></label><%= render :partial => 'attachments/form' %></p>
</div>

<%= wikitoolbar_for 'article_content' %>
Loading

0 comments on commit e6df7d2

Please sign in to comment.