Created
June 1, 2023 09:01
-
-
Save keineahnung2345/5431ffbde8f62698533c3ad5d9ffb840 to your computer and use it in GitHub Desktop.
Global wiki feature for Redmine 5.0.5, adapted from draft-feature-1040-r20825.patch by Mizuki ISHIKAWA on https://www.redmine.org/issues/1040#note-66
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
app/controllers/attachments_controller.rb | 4 +- | |
app/controllers/wiki_controller.rb | 41 +++++++++++++------ | |
app/helpers/application_helper.rb | 16 +++----- | |
app/helpers/wiki_helper.rb | 14 +++++-- | |
app/models/wiki.rb | 21 ++++++++-- | |
app/models/wiki_content.rb | 6 ++- | |
app/models/wiki_page.rb | 14 +++++-- | |
app/views/wiki/_new_modal.html.erb | 2 +- | |
app/views/wiki/annotate.html.erb | 4 +- | |
app/views/wiki/date_index.html.erb | 2 +- | |
app/views/wiki/diff.html.erb | 4 +- | |
app/views/wiki/edit.html.erb | 2 +- | |
app/views/wiki/history.html.erb | 4 +- | |
app/views/wiki/index.html.erb | 2 +- | |
app/views/wiki/new.html.erb | 2 +- | |
app/views/wiki/rename.html.erb | 4 +- | |
app/views/wiki/show.html.erb | 22 +++++----- | |
config/routes.rb | 24 +++++++++++ | |
...9083854_allow_wiki_project_id_to_be_nil.rb | 8 ++++ | |
.../lib/acts_as_attachable.rb | 2 +- | |
.../lib/acts_as_searchable.rb | 16 ++++++++ | |
lib/redmine/preparation.rb | 9 ++++ | |
lib/redmine/wiki_formatting/macros.rb | 4 +- | |
23 files changed, 164 insertions(+), 63 deletions(-) | |
create mode 100644 db/migrate/20200729083854_allow_wiki_project_id_to_be_nil.rb | |
diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb | |
index c991fce..1564cea 100644 | |
--- a/app/controllers/attachments_controller.rb | |
+++ b/app/controllers/attachments_controller.rb | |
@@ -176,8 +176,10 @@ class AttachmentsController < ApplicationController | |
@attachment.destroy | |
end | |
+ container = @attachment.try(:container) || @container | |
respond_to do |format| | |
- format.html {redirect_to_referer_or project_path(@project)} | |
+ # redirect to project or global wiki page | |
+ format.html {redirect_to_referer_or @project ? project_path(@project) : wiki_index_path(container)} | |
format.js | |
format.api {render_api_ok} | |
end | |
diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb | |
index 4a7c0a6..f31e76c 100644 | |
--- a/app/controllers/wiki_controller.rb | |
+++ b/app/controllers/wiki_controller.rb | |
@@ -33,7 +33,7 @@ | |
# TODO: still being worked on | |
class WikiController < ApplicationController | |
default_search_scope :wiki_pages | |
- before_action :find_wiki, :authorize | |
+ before_action :find_wiki, :authorize_global | |
before_action :find_existing_or_new_page, :only => [:show, :edit] | |
before_action :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version] | |
before_action :find_attachments, :only => [:preview] | |
@@ -41,11 +41,13 @@ class WikiController < ApplicationController | |
helper :attachments | |
include AttachmentsHelper | |
+ include WikiHelper | |
helper :watchers | |
include Redmine::Export::PDF | |
# List of pages, sorted alphabetically and by parent (hierarchy) | |
def index | |
+ authorize if params[:project_id] | |
load_pages_for_index | |
respond_to do |format| | |
@@ -64,7 +66,7 @@ class WikiController < ApplicationController | |
def new | |
@page = WikiPage.new(:wiki => @wiki, :title => params[:title]) | |
- unless User.current.allowed_to?(:edit_wiki_pages, @project) | |
+ unless @wiki.allowed_to_permission?(:view_wiki_edits) | |
render_403 | |
return | |
end | |
@@ -72,7 +74,7 @@ class WikiController < ApplicationController | |
@page.title = '' unless editable? | |
@page.validate | |
if @page.errors[:title].blank? | |
- path = project_wiki_page_path(@project, @page.title, :parent => params[:parent]) | |
+ path = wiki_page_action_path('show', @page, {:parent => params[:parent]}) | |
respond_to do |format| | |
format.html {redirect_to path} | |
format.js {render :js => "window.location = #{path.to_json}"} | |
@@ -83,13 +85,13 @@ class WikiController < ApplicationController | |
# display a page (in editing mode if it doesn't exist) | |
def show | |
- if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project) | |
+ if params[:version] && !@wiki.allowed_to_permission?(:view_wiki_edits) | |
deny_access | |
return | |
end | |
@content = @page.content_for_version(params[:version]) | |
if @content.nil? | |
- if params[:version].blank? && User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request? | |
+ if params[:version].blank? && @wiki.allowed_to_permission?(:view_wiki_edits) && editable? && !api_request? | |
edit | |
render :action => 'edit' | |
else | |
@@ -186,11 +188,11 @@ class WikiController < ApplicationController | |
respond_to do |format| | |
format.html do | |
anchor = @section ? "section-#{@section}" : nil | |
- redirect_to project_wiki_page_path(@project, @page.title, :anchor => anchor) | |
+ redirect_to wiki_page_action_path('show', @page, {:anchor => anchor}) | |
end | |
format.api do | |
if was_new_page | |
- render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title) | |
+ render :action => 'show', :status => :created, :location => wiki_page_action_path('show', @page) | |
else | |
render_api_ok | |
end | |
@@ -224,13 +226,13 @@ class WikiController < ApplicationController | |
@page.safe_attributes = params[:wiki_page] | |
if request.post? && @page.save | |
flash[:notice] = l(:notice_successful_update) | |
- redirect_to project_wiki_page_path(@page.project, @page.title) | |
+ redirect_to wiki_page_action_path('show', @page) | |
end | |
end | |
def protect | |
@page.update_attribute :protected, params[:protected] | |
- redirect_to project_wiki_page_path(@project, @page.title) | |
+ redirect_to wiki_page_action_path('show', @page) | |
end | |
# show page history | |
@@ -289,7 +291,11 @@ class WikiController < ApplicationController | |
respond_to do |format| | |
format.html do | |
flash[:notice] = l(:notice_successful_delete) | |
- redirect_to project_wiki_index_path(@project) | |
+ if @project | |
+ redirect_to project_wiki_index_path(@project) | |
+ else | |
+ redirect_to wiki_index_path | |
+ end | |
end | |
format.api {render_api_ok} | |
end | |
@@ -300,7 +306,7 @@ class WikiController < ApplicationController | |
if content = @page.content.versions.find_by_version(params[:version]) | |
content.destroy | |
- redirect_to_referer_or history_project_wiki_page_path(@project, @page.title) | |
+ redirect_to_referer_or wiki_page_action_path('history', @page) | |
else | |
render_404 | |
end | |
@@ -346,13 +352,22 @@ class WikiController < ApplicationController | |
private | |
def find_wiki | |
- @project = Project.find(params[:project_id]) | |
- @wiki = @project.wiki | |
+ if params[:project_id] | |
+ @project = Project.find(params[:project_id]) | |
+ @wiki = @project.wiki | |
+ else | |
+ @wiki = Wiki.find_by(:project_id => nil) | |
+ Wiki.create(:project => nil, :start_page => 'Wiki') if @wiki.nil? | |
+ end | |
render_404 unless @wiki | |
rescue ActiveRecord::RecordNotFound | |
render_404 | |
end | |
+ def global_wiki? | |
+ @wiki.project.nil? | |
+ end | |
+ | |
# Finds the requested page or a new page if it doesn't exist | |
def find_existing_or_new_page | |
@page = @wiki.find_or_new_page(params[:id]) | |
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb | |
index 61f62ae..d9fe11c 100644 | |
--- a/app/helpers/application_helper.rb | |
+++ b/app/helpers/application_helper.rb | |
@@ -223,7 +223,7 @@ module ApplicationHelper | |
lambda do |wiki_page| | |
link_to( | |
wiki_page.pretty_title, | |
- project_wiki_page_path(wiki_page.project, wiki_page.title) | |
+ url_for({:controller => 'wiki', :action => 'show', project_id: wiki_page.project, id: wiki_page.title}) | |
) | |
end | |
} | |
@@ -311,11 +311,6 @@ module ApplicationHelper | |
end | |
end | |
- def wiki_page_path(page, options={}) | |
- url_for({:controller => 'wiki', :action => 'show', :project_id => page.project, | |
- :id => page.title}.merge(options)) | |
- end | |
- | |
def thumbnail_tag(attachment) | |
thumbnail_size = Setting.thumbnails_size.to_i | |
link_to( | |
@@ -979,13 +974,14 @@ module ApplicationHelper | |
next link_to(title.present? ? title.html_safe : h(page), url, :class => 'wiki-page') | |
end | |
- if page =~ /^([^\:]+)\:(.*)$/ | |
+ if page =~ /^(.*)\:(.*)$/ | |
identifier, page = $1, $2 | |
link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier) | |
title ||= identifier if page.blank? | |
end | |
- | |
- if link_project && link_project.wiki && User.current.allowed_to?(:view_wiki_pages, link_project) | |
+ wiki = Wiki.find_by(:project => link_project) | |
+ if wiki && wiki.allowed_to_permission?(:view_wiki_pages) && | |
+ (link_project || (wiki.global? && link_project.nil?)) | |
# extract anchor | |
anchor = nil | |
if page =~ /^(.+?)\#(.+)$/ | |
@@ -993,7 +989,7 @@ module ApplicationHelper | |
end | |
anchor = sanitize_anchor_name(anchor) if anchor.present? | |
# check if page exists | |
- wiki_page = link_project.wiki.find_page(page) | |
+ wiki_page = wiki.find_page(page) | |
url = | |
if anchor.present? && wiki_page.present? && | |
(obj.is_a?(WikiContent) || obj.is_a?(WikiContentVersion)) && | |
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb | |
index 0b5f3b8..7efafe5 100644 | |
--- a/app/helpers/wiki_helper.rb | |
+++ b/app/helpers/wiki_helper.rb | |
@@ -63,15 +63,23 @@ module WikiHelper | |
def wiki_page_edit_cancel_path(page) | |
if page.new_record? | |
if parent = page.parent | |
- project_wiki_page_path(parent.project, parent.title) | |
+ wiki_page_action_path('show', parent) | |
else | |
- project_wiki_index_path(page.project) | |
+ if page.project | |
+ project_wiki_index_path(page.project) | |
+ else | |
+ wiki_index_path | |
+ end | |
end | |
else | |
- project_wiki_page_path(page.project, page.title) | |
+ wiki_page_action_path('show', page) | |
end | |
end | |
+ def wiki_page_action_path(action_name, page=nil, options={}) | |
+ url_for({:controller => 'wiki', :action => action_name, :project_id => (page.wiki.project if page), :id => (page.title if page)}.merge(options)) | |
+ end | |
+ | |
def wiki_content_update_info(content) | |
l(:label_updated_time_by, :author => link_to_user(content.author), :age => time_tag(content.updated_on)).html_safe | |
end | |
diff --git a/app/models/wiki.rb b/app/models/wiki.rb | |
index 726dcea..231bef8 100644 | |
--- a/app/models/wiki.rb | |
+++ b/app/models/wiki.rb | |
@@ -34,7 +34,7 @@ class Wiki < ActiveRecord::Base | |
safe_attributes 'start_page' | |
def visible?(user=User.current) | |
- !user.nil? && user.allowed_to?(:view_wiki_pages, project) | |
+ !user.nil? && user.allowed_to?(:view_wiki_pages, project, global: self.global?) | |
end | |
# Returns the wiki page that acts as the sidebar content | |
@@ -85,12 +85,13 @@ class Wiki < ActiveRecord::Base | |
# Wiki.find_page("foo:bar") | |
def self.find_page(title, options = {}) | |
project = options[:project] | |
- if title.to_s =~ %r{^([^\:]+)\:(.*)$} | |
+ if title.to_s =~ %r{^(.*):(.*)$} | |
project_identifier, title = $1, $2 | |
project = Project.find_by_identifier(project_identifier) || Project.find_by_name(project_identifier) | |
end | |
- if project && project.wiki | |
- page = project.wiki.find_page(title) | |
+ wiki = project_identifier.present? ? (project && project.wiki) : Wiki.find_by(project: nil) | |
+ if wiki | |
+ page = wiki.find_page(title) | |
if page && page.content | |
page | |
end | |
@@ -105,4 +106,16 @@ class Wiki < ActiveRecord::Base | |
title = (title.slice(0..0).upcase + (title.slice(1..-1) || '')) if title | |
title | |
end | |
+ | |
+ def global? | |
+ self.project.nil? | |
+ end | |
+ | |
+ def allowed_to_permission?(permission, user=User.current) | |
+ user.allowed_to?(permission, self.project, :global => self.global?) | |
+ end | |
+ | |
+ def allowed_to_action?(action) | |
+ User.current.allowed_to?({:controller => 'wiki', :action => action}, self.project, :global => self.global?) | |
+ end | |
end | |
diff --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb | |
index d6a317a..789ad88 100644 | |
--- a/app/models/wiki_content.rb | |
+++ b/app/models/wiki_content.rb | |
@@ -56,7 +56,7 @@ class WikiContent < ActiveRecord::Base | |
end | |
def notified_users | |
- project.notified_users.reject {|user| !visible?(user)} | |
+ self.global? ? [] : project.notified_users.reject {|user| !visible?(user)} | |
end | |
# Returns the mail addresses of users that should be notified | |
@@ -82,6 +82,10 @@ class WikiContent < ActiveRecord::Base | |
end | |
end | |
+ def global? | |
+ self.project.nil? | |
+ end | |
+ | |
private | |
def create_version | |
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb | |
index 594c44b..1fbab31 100644 | |
--- a/app/models/wiki_page.rb | |
+++ b/app/models/wiki_page.rb | |
@@ -69,10 +69,10 @@ class WikiPage < ActiveRecord::Base | |
DEFAULT_PROTECTED_PAGES = %w(sidebar) | |
safe_attributes 'parent_id', 'parent_title', 'title', 'redirect_existing_links', 'wiki_id', | |
- :if => lambda {|page, user| page.new_record? || user.allowed_to?(:rename_wiki_pages, page.project)} | |
+ :if => lambda {|page, user| page.new_record? || user.allowed_to?(:rename_wiki_pages, page.project, global: page.wiki.global?)} | |
safe_attributes 'is_start_page', | |
- :if => lambda {|page, user| user.allowed_to?(:manage_wiki, page.project)} | |
+ :if => lambda {|page, user| user.allowed_to?(:manage_wiki, page.project, global: page.wiki.global?)} | |
safe_attributes 'deleted_attachment_ids', | |
:if => lambda {|page, user| page.attachments_deletable?(user)} | |
@@ -85,7 +85,13 @@ class WikiPage < ActiveRecord::Base | |
end | |
def visible?(user=User.current) | |
- !user.nil? && user.allowed_to?(:view_wiki_pages, project) | |
+ !user.nil? && | |
+ user.allowed_to?(:view_wiki_pages, self.project, global: self.wiki.global?) | |
+ end | |
+ | |
+ def attachments_visible?(user=User.current) | |
+ (respond_to?(:visible?) ? visible?(user) : true) && | |
+ user.allowed_to?(self.class.attachable_options[:view_permission], self.project, global: self.wiki.global?) | |
end | |
def title=(value) | |
@@ -206,7 +212,7 @@ class WikiPage < ActiveRecord::Base | |
# Returns true if usr is allowed to edit the page, otherwise false | |
def editable_by?(usr) | |
- !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project) | |
+ !protected? || self.wiki.allowed_to_permission?(:protect_wiki_pages, usr) | |
end | |
def attachments_deletable?(usr=User.current) | |
diff --git a/app/views/wiki/_new_modal.html.erb b/app/views/wiki/_new_modal.html.erb | |
index 108c6ad..02f014b 100644 | |
--- a/app/views/wiki/_new_modal.html.erb | |
+++ b/app/views/wiki/_new_modal.html.erb | |
@@ -1,7 +1,7 @@ | |
<h3 class="title"><%=l(:label_wiki_page_new)%></h3> | |
<%= labelled_form_for :page, @page, | |
- :url => new_project_wiki_page_path(@project), | |
+ :url => wiki_page_action_path('new', @page), | |
:method => 'post', | |
:remote => true do |f| %> | |
diff --git a/app/views/wiki/annotate.html.erb b/app/views/wiki/annotate.html.erb | |
index 1b48f5d..7738c80 100644 | |
--- a/app/views/wiki/annotate.html.erb | |
+++ b/app/views/wiki/annotate.html.erb | |
@@ -6,8 +6,8 @@ | |
<%= wiki_page_breadcrumb(@page) %> | |
-<%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)], | |
- [l(:label_history), history_project_wiki_page_path(@page.project, @page.title)], | |
+<%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})], | |
+ [l(:label_history), wiki_page_action_path('history', @page)], | |
"#{l(:label_version)} #{@annotate.content.version}" %> | |
<p> | |
diff --git a/app/views/wiki/date_index.html.erb b/app/views/wiki/date_index.html.erb | |
index 496411b..9e7efaa 100644 | |
--- a/app/views/wiki/date_index.html.erb | |
+++ b/app/views/wiki/date_index.html.erb | |
@@ -1,6 +1,6 @@ | |
<div class="contextual"> | |
<% if User.current.allowed_to?(:edit_wiki_pages, @project) %> | |
-<%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project), :remote => true, :class => 'icon icon-add' %> | |
+<%= link_to l(:label_wiki_page_new), wiki_page_action_path('new', @page), :remote => true, :class => 'icon icon-add' %> | |
<% end %> | |
<%= watcher_link(@wiki, User.current) %> | |
<% if User.current.allowed_to?(:manage_wiki, @project) %> | |
diff --git a/app/views/wiki/diff.html.erb b/app/views/wiki/diff.html.erb | |
index 765e51a..153af89 100644 | |
--- a/app/views/wiki/diff.html.erb | |
+++ b/app/views/wiki/diff.html.erb | |
@@ -5,8 +5,8 @@ | |
<%= wiki_page_breadcrumb(@page) %> | |
-<%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)], | |
- [l(:label_history), history_project_wiki_page_path(@page.project, @page.title)], | |
+<%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})], | |
+ [l(:label_history), wiki_page_action_path('history', @page)], | |
"#{l(:label_revision)} #{@diff.content_to.version}" %> | |
<p> | |
diff --git a/app/views/wiki/edit.html.erb b/app/views/wiki/edit.html.erb | |
index 7e9cf42..1597cb7 100644 | |
--- a/app/views/wiki/edit.html.erb | |
+++ b/app/views/wiki/edit.html.erb | |
@@ -63,7 +63,7 @@ | |
<%= submit_tag l(:button_save) %> | |
<%= link_to l(:button_cancel), wiki_page_edit_cancel_path(@page) %> | |
</p> | |
-<%= wikitoolbar_for 'content_text', preview_project_wiki_page_path(:project_id => @project, :id => @page.title) %> | |
+<%= wikitoolbar_for 'content_text', wiki_page_action_path('preview', @page) %> | |
<% if User.current.allowed_to?(:add_wiki_page_watchers, @project)%> | |
<%= update_data_sources_for_auto_complete({users: watchers_autocomplete_for_mention_path(project_id: @project, q: '', object_type: 'wiki_page', object_id: @page.id)}) %> | |
diff --git a/app/views/wiki/history.html.erb b/app/views/wiki/history.html.erb | |
index 3e638a8..dea9c58 100644 | |
--- a/app/views/wiki/history.html.erb | |
+++ b/app/views/wiki/history.html.erb | |
@@ -1,6 +1,6 @@ | |
<%= wiki_page_breadcrumb(@page) %> | |
-<%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)], l(:label_history) %> | |
+<%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})], l(:label_history) %> | |
<%= form_tag({:controller => 'wiki', :action => 'diff', | |
:project_id => @page.project, :id => @page.title}, | |
@@ -31,7 +31,7 @@ | |
<td class="comments"><%= ver.comments %></td> | |
<td class="buttons"> | |
<%= link_to l(:button_annotate), :action => 'annotate', :id => @page.title, :version => ver.version %> | |
- <%= delete_link wiki_page_path(@page, :version => ver.version) if User.current.allowed_to?(:delete_wiki_pages, @page.project) && @version_count > 1 %> | |
+ <%= delete_link wiki_page_action_path('show', @page, {:version => ver.version}) if @page.wiki.allowed_to_permission?(:delete_wiki_pages) && @version_count > 1 %> | |
</td> | |
</tr> | |
<% line_num += 1 %> | |
diff --git a/app/views/wiki/index.html.erb b/app/views/wiki/index.html.erb | |
index 3c7f55d..2880979 100644 | |
--- a/app/views/wiki/index.html.erb | |
+++ b/app/views/wiki/index.html.erb | |
@@ -1,6 +1,6 @@ | |
<div class="contextual"> | |
<% if User.current.allowed_to?(:edit_wiki_pages, @project) %> | |
-<%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project), :remote => true, :class => 'icon icon-add' %> | |
+<%= link_to l(:label_wiki_page_new), wiki_page_action_path('new'), :remote => true, :class => 'icon icon-add' %> | |
<% end %> | |
<%= watcher_link(@wiki, User.current) %> | |
<% if User.current.allowed_to?(:manage_wiki, @project) %> | |
diff --git a/app/views/wiki/new.html.erb b/app/views/wiki/new.html.erb | |
index d067420..1ad2f78 100644 | |
--- a/app/views/wiki/new.html.erb | |
+++ b/app/views/wiki/new.html.erb | |
@@ -1,7 +1,7 @@ | |
<%= title l(:label_wiki_page_new) %> | |
<%= labelled_form_for :page, @page, | |
- :url => new_project_wiki_page_path(@project) do |f| %> | |
+ :url => wiki_page_action_path('new', @page) do |f| %> | |
<%= render_error_messages @page.errors.full_messages_for(:title) %> | |
diff --git a/app/views/wiki/rename.html.erb b/app/views/wiki/rename.html.erb | |
index 13fb41a..46e9295 100644 | |
--- a/app/views/wiki/rename.html.erb | |
+++ b/app/views/wiki/rename.html.erb | |
@@ -13,7 +13,7 @@ | |
<p><%= f.check_box :is_start_page, :label => :field_start_page, :disabled => @page.is_start_page %></p> | |
<% end %> | |
<p><%= f.check_box :redirect_existing_links %></p> | |
-<% if @page.safe_attribute? 'wiki_id' %> | |
+<% if @page.safe_attribute? 'wiki_id' && !@page.wiki.global? %> | |
<p><%= f.select :wiki_id, wiki_page_wiki_options_for_select(@page), :label => :label_project %></p> | |
<% end %> | |
<p><%= f.select :parent_id, | |
@@ -30,7 +30,7 @@ | |
<%= javascript_tag do %> | |
$('#wiki_page_wiki_id').change(function() { | |
$.ajax({ | |
- url: '<%= rename_project_wiki_page_path(@wiki, :format => 'js') %>', | |
+ url: '<%= wiki_page_action_path('rename', @page, {:format => 'js'}) %>', | |
type: 'get', | |
data: { 'wiki_page[wiki_id]': $('#wiki_page_wiki_id').val() } | |
}); | |
diff --git a/app/views/wiki/show.html.erb b/app/views/wiki/show.html.erb | |
index 6a02458..b95f831 100644 | |
--- a/app/views/wiki/show.html.erb | |
+++ b/app/views/wiki/show.html.erb | |
@@ -2,27 +2,27 @@ | |
<% if @editable %> | |
<% if @content.current_version? %> | |
- <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %> | |
+ <%= link_to(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @page.wiki.allowed_to_action?('edit') %> | |
<%= watcher_link(@page, User.current) %> | |
<% end %> | |
<% end %> | |
<%= actions_dropdown do %> | |
- <%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %> | |
+ <%= link_to(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') if @page.wiki.allowed_to_action?('history') %> | |
<% if @editable %> | |
<% if @content.current_version? %> | |
- <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %> | |
- <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %> | |
- <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %> | |
- <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %> | |
+ <%= link_to(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? && @page.wiki.allowed_to_action?('protect') %> | |
+ <%= link_to(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? && @page.wiki.allowed_to_action?('protect') %> | |
+ <%= link_to(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @page.wiki.allowed_to_action?('rename') %> | |
+ <%= link_to(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') if @page.wiki.allowed_to_action?('destroy') %> | |
<% else %> | |
- <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') %> | |
+ <%= link_to(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @page.wiki.allowed_to_action?('edit') %> | |
<% end %> | |
<% end %> | |
- <% if User.current.allowed_to?(:edit_wiki_pages, @project) %> | |
- <%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project, :parent => @page.title), :remote => true, :class => 'icon icon-add' %> | |
+ <% if @page.wiki.allowed_to_permission?(:edit_wiki_pages) %> | |
+ <%= link_to l(:label_wiki_page_new), wiki_page_action_path('new', @page, {:parent => @page.title}), :remote => true, :class => 'icon icon-add' %> | |
<% end %> | |
<% end %> | |
</div> | |
@@ -30,8 +30,8 @@ | |
<%= wiki_page_breadcrumb(@page) %> | |
<% unless @content.current_version? %> | |
- <%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)], | |
- [l(:label_history), history_project_wiki_page_path(@page.project, @page.title)], | |
+ <%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})], | |
+ [l(:label_history), wiki_page_action_path('history', @page)], | |
"#{l(:label_revision)} #{@content.version}" %> | |
<p> | |
diff --git a/config/routes.rb b/config/routes.rb | |
index 1a920b1..ade44e4 100644 | |
--- a/config/routes.rb | |
+++ b/config/routes.rb | |
@@ -207,6 +207,30 @@ Rails.application.routes.draw do | |
get 'wiki/:id/:version/annotate', :to => 'wiki#annotate' | |
get 'wiki/:id/:version/diff', :to => 'wiki#diff' | |
end | |
+ match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get | |
+ resources :wiki, :except => [:index, :create, :show], :as => 'wiki_page' do | |
+ member do | |
+ get 'wiki', :as => 'show_wiki_page' | |
+ get 'rename' | |
+ post 'rename' | |
+ get 'history' | |
+ get 'diff' | |
+ match 'preview', :via => [:post, :put, :patch] | |
+ post 'protect' | |
+ post 'add_attachment' | |
+ end | |
+ collection do | |
+ get 'export' | |
+ get 'date_index' | |
+ post 'new' | |
+ end | |
+ end | |
+ match 'wiki', :controller => 'wiki', :action => 'show', :via => :get | |
+ get 'wiki/:id/:version', :to => 'wiki#show', :constraints => {:version => /\d+/} | |
+ delete 'wiki/:id/:version', :to => 'wiki#destroy_version' | |
+ get 'wiki/:id/:version/annotate', :to => 'wiki#annotate' | |
+ get 'wiki/:id/:version/diff', :to => 'wiki#diff' | |
+ match 'wiki/:id/destroy', :to => 'wikis#destroy', :via => [:get, :post] | |
resources :issues do | |
member do | |
diff --git a/db/migrate/20200729083854_allow_wiki_project_id_to_be_nil.rb b/db/migrate/20200729083854_allow_wiki_project_id_to_be_nil.rb | |
new file mode 100644 | |
index 0000000..7312d08 | |
--- /dev/null | |
+++ b/db/migrate/20200729083854_allow_wiki_project_id_to_be_nil.rb | |
@@ -0,0 +1,8 @@ | |
+class AllowWikiProjectIdToBeNil < ActiveRecord::Migration[5.2] | |
+ def up | |
+ change_column_null :wikis, :project_id, true | |
+ end | |
+ def down | |
+ change_column_null :wikis, :project_id, false | |
+ end | |
+end | |
diff --git a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb | |
index 4a06998..100a5aa 100644 | |
--- a/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb | |
+++ b/lib/plugins/acts_as_attachable/lib/acts_as_attachable.rb | |
@@ -58,7 +58,7 @@ module Redmine | |
def attachments_deletable?(user=User.current) | |
(respond_to?(:visible?) ? visible?(user) : true) && | |
- user.allowed_to?(self.class.attachable_options[:delete_permission], self.project) | |
+ user.allowed_to?(self.class.attachable_options[:delete_permission], self.project, :global => ((self.is_a? WikiPage) ? self.wiki.global?: false)) | |
end | |
def saved_attachments | |
diff --git a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb | |
index f272029..1297262 100644 | |
--- a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb | |
+++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb | |
@@ -196,6 +196,22 @@ module Redmine | |
if projects | |
scope = scope.where("#{searchable_options[:project_key]} IN (?)", projects.map(&:id)) | |
+ elsif scope.table_name == "wiki_pages" && options[:params][:wiki_pages] == "1" | |
+ # including global wiki | |
+ scope_global_wikis = WikiPage.joins(:wiki).where("wikis.project_id is null") | |
+ # Method 1: | |
+ # ArgumentError (Relation passed to #or must be structurally compatible. Incompatible values: [:joins]) | |
+ #scope = scope.or(scope_global_wikis) | |
+ # Method 2: | |
+ # TypeError (Cannot visit WikiPage::ActiveRecord_Relation) | |
+ #wiki_page_table = WikiPage.arel_table | |
+ #combined = Arel::Nodes::UnionAll.new(scope, scope_global_wikis) | |
+ #scope = WikiPage.from(Arel::Nodes::As.new(combined, wiki_page_table)) | |
+ # Method 3: | |
+ # https://stackoverflow.com/questions/57491185/obtain-union-all-result-in-activerecord | |
+ # https://stackoverflow.com/questions/17331862/converting-an-array-of-objects-to-activerecordrelation | |
+ scope_array = WikiPage.find_by_sql("#{scope.to_sql} UNION #{scope_global_wikis.to_sql}") | |
+ scope = WikiPage.where(id: scope_array.map(&:id)).joins(:content) #.joins({:wiki => :project}) | |
end | |
scope | |
end | |
diff --git a/lib/redmine/preparation.rb b/lib/redmine/preparation.rb | |
index 1c91074..0d3c81b 100644 | |
--- a/lib/redmine/preparation.rb | |
+++ b/lib/redmine/preparation.rb | |
@@ -236,6 +236,15 @@ module Redmine | |
end, | |
:caption => :label_news_plural | |
) | |
+ menu.push( | |
+ :wiki, | |
+ {:controller => 'wiki', :action => 'show'}, | |
+ :if => | |
+ Proc.new do | |
+ User.current.allowed_to?(:view_wiki_pages, nil, :global => true) | |
+ end, | |
+ :caption => :label_wiki | |
+ ) | |
end | |
MenuManager.map :admin_menu do |menu| | |
diff --git a/lib/redmine/wiki_formatting/macros.rb b/lib/redmine/wiki_formatting/macros.rb | |
index 61218d9..13b3f67 100644 | |
--- a/lib/redmine/wiki_formatting/macros.rb | |
+++ b/lib/redmine/wiki_formatting/macros.rb | |
@@ -207,7 +207,7 @@ module Redmine | |
else | |
raise t(:error_childpages_macro_no_argument) | |
end | |
- raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) | |
+ raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project, global: page.wiki.global?) | |
pages = page.self_and_descendants(options[:depth]).group_by(&:parent_id) | |
render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id) | |
@@ -218,7 +218,7 @@ module Redmine | |
"{{include(projectname:Foo)}} -- to include a page of a specific project wiki" | |
macro :include do |obj, args| | |
page = Wiki.find_page(args.first.to_s, :project => @project) | |
- raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) | |
+ raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project, global: page.wiki.global?) | |
@included_wiki_pages ||= [] | |
raise t(:error_circular_inclusion) if @included_wiki_pages.include?(page.id) | |
-- | |
2.25.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment