Merge branch 'master' into plugin-hooks
Conflicts: lib/redmine/plugin.rb
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
require 'redmine/access_control'
|
||||
require 'redmine/menu_manager'
|
||||
require 'redmine/activity'
|
||||
require 'redmine/mime_type'
|
||||
require 'redmine/core_ext'
|
||||
require 'redmine/themes'
|
||||
@@ -132,3 +133,13 @@ Redmine::MenuManager.map :project_menu do |menu|
|
||||
:if => Proc.new { |p| p.repository && !p.repository.new_record? }
|
||||
menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
|
||||
end
|
||||
|
||||
Redmine::Activity.map do |activity|
|
||||
activity.register :issues, :class_name => %w(Issue Journal)
|
||||
activity.register :changesets
|
||||
activity.register :news
|
||||
activity.register :documents, :class_name => %w(Document Attachment)
|
||||
activity.register :files, :class_name => 'Attachment'
|
||||
activity.register :wiki_pages, :class_name => 'WikiContent::Version', :default => false
|
||||
activity.register :messages, :default => false
|
||||
end
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
module Redmine
|
||||
module Activity
|
||||
|
||||
mattr_accessor :available_event_types, :default_event_types, :providers
|
||||
|
||||
@@available_event_types = []
|
||||
@@default_event_types = []
|
||||
@@providers = Hash.new {|h,k| h[k]=[] }
|
||||
|
||||
class << self
|
||||
def map(&block)
|
||||
yield self
|
||||
end
|
||||
|
||||
# Registers an activity provider
|
||||
def register(event_type, options={})
|
||||
options.assert_valid_keys(:class_name, :default)
|
||||
|
||||
event_type = event_type.to_s
|
||||
providers = options[:class_name] || event_type.classify
|
||||
providers = ([] << providers) unless providers.is_a?(Array)
|
||||
|
||||
@@available_event_types << event_type unless @@available_event_types.include?(event_type)
|
||||
@@default_event_types << event_type unless options[:default] == false
|
||||
@@providers[event_type] += providers
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
module Redmine
|
||||
module Activity
|
||||
# Class used to retrieve activity events
|
||||
class Fetcher
|
||||
attr_reader :user, :project, :scope
|
||||
|
||||
# Needs to be unloaded in development mode
|
||||
@@constantized_providers = Hash.new {|h,k| h[k] = Redmine::Activity.providers[k].collect {|t| t.constantize } }
|
||||
|
||||
def initialize(user, options={})
|
||||
options.assert_valid_keys(:project, :with_subprojects)
|
||||
@user = user
|
||||
@project = options[:project]
|
||||
@options = options
|
||||
|
||||
@scope = event_types
|
||||
end
|
||||
|
||||
# Returns an array of available event types
|
||||
def event_types
|
||||
return @event_types unless @event_types.nil?
|
||||
|
||||
@event_types = Redmine::Activity.available_event_types
|
||||
@event_types = @event_types.select {|o| @user.allowed_to?("view_#{o}".to_sym, @project)} if @project
|
||||
@event_types
|
||||
end
|
||||
|
||||
# Yields to filter the activity scope
|
||||
def scope_select(&block)
|
||||
@scope = @scope.select {|t| yield t }
|
||||
end
|
||||
|
||||
# Sets the scope
|
||||
def scope=(s)
|
||||
@scope = s & event_types
|
||||
end
|
||||
|
||||
# Resets the scope to the default scope
|
||||
def default_scope!
|
||||
@scope = Redmine::Activity.default_event_types
|
||||
end
|
||||
|
||||
# Returns an array of events for the given date range
|
||||
def events(from, to)
|
||||
e = []
|
||||
|
||||
@scope.each do |event_type|
|
||||
constantized_providers(event_type).each do |provider|
|
||||
e += provider.find_events(event_type, @user, from, to, @options)
|
||||
end
|
||||
end
|
||||
e
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def constantized_providers(event_type)
|
||||
@@constantized_providers[event_type]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -128,6 +128,32 @@ module Redmine #:nodoc:
|
||||
def add_hook(hook_name, method)
|
||||
Redmine::Plugin::Hook::Manager.add_listener(hook_name, method)
|
||||
end
|
||||
|
||||
# Registers an activity provider.
|
||||
#
|
||||
# Options:
|
||||
# * <tt>:class_name</tt> - one or more model(s) that provide these events (inferred from event_type by default)
|
||||
# * <tt>:default</tt> - setting this option to false will make the events not displayed by default
|
||||
#
|
||||
# A model can provide several activity event types.
|
||||
#
|
||||
# Examples:
|
||||
# register :news
|
||||
# register :scrums, :class_name => 'Meeting'
|
||||
# register :issues, :class_name => ['Issue', 'Journal']
|
||||
#
|
||||
# Retrieving events:
|
||||
# Associated model(s) must implement the find_events class method.
|
||||
# ActiveRecord models can use acts_as_activity_provider as a way to implement this class method.
|
||||
#
|
||||
# The following call should return all the scrum events visible by current user that occured in the 5 last days:
|
||||
# Meeting.find_events('scrums', User.current, 5.days.ago, Date.today)
|
||||
# Meeting.find_events('scrums', User.current, 5.days.ago, Date.today, :project => foo) # events for project foo only
|
||||
#
|
||||
# Note that :view_scrums permission is required to view these events in the activity view.
|
||||
def activity_provider(*args)
|
||||
Redmine::Activity.register(*args)
|
||||
end
|
||||
|
||||
# Returns +true+ if the plugin can be configured.
|
||||
def configurable?
|
||||
|
||||
@@ -65,10 +65,22 @@ module Redmine
|
||||
|
||||
# Patch to add 'table of content' support to RedCloth
|
||||
def textile_p_withtoc(tag, atts, cite, content)
|
||||
if tag =~ /^h(\d)$/
|
||||
@toc << [$1.to_i, content]
|
||||
# removes wiki links from the item
|
||||
toc_item = content.gsub(/(\[\[|\]\])/, '')
|
||||
# removes styles
|
||||
# eg. %{color:red}Triggers% => Triggers
|
||||
toc_item.gsub! %r[%\{[^\}]*\}([^%]+)%], '\\1'
|
||||
|
||||
# replaces non word caracters by dashes
|
||||
anchor = toc_item.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
|
||||
|
||||
unless anchor.blank?
|
||||
if tag =~ /^h(\d)$/
|
||||
@toc << [$1.to_i, anchor, toc_item]
|
||||
end
|
||||
atts << " id=\"#{anchor}\""
|
||||
content = content + "<a href=\"##{anchor}\" class=\"wiki-anchor\">¶</a>"
|
||||
end
|
||||
content = "<a name=\"#{@toc.length}\" class=\"wiki-page\"></a>" + content
|
||||
textile_p(tag, atts, cite, content)
|
||||
end
|
||||
|
||||
@@ -82,13 +94,9 @@ module Redmine
|
||||
div_class << ' right' if $1 == '>'
|
||||
div_class << ' left' if $1 == '<'
|
||||
out = "<ul class=\"#{div_class}\">"
|
||||
@toc.each_with_index do |heading, index|
|
||||
# remove wiki links from the item
|
||||
toc_item = heading.last.gsub(/(\[\[|\]\])/, '')
|
||||
# remove styles
|
||||
# eg. %{color:red}Triggers% => Triggers
|
||||
toc_item.gsub! %r[%\{[^\}]*\}([^%]+)%], '\\1'
|
||||
out << "<li class=\"heading#{heading.first}\"><a href=\"##{index+1}\">#{toc_item}</a></li>\n"
|
||||
@toc.each do |heading|
|
||||
level, anchor, toc_item = heading
|
||||
out << "<li class=\"heading#{level}\"><a href=\"##{anchor}\">#{toc_item}</a></li>\n"
|
||||
end
|
||||
out << '</ul>'
|
||||
out
|
||||
|
||||
@@ -77,6 +77,12 @@ module Redmine
|
||||
content_tag('dl', out)
|
||||
end
|
||||
|
||||
desc "Displays a list of child pages."
|
||||
macro :child_pages do |obj, args|
|
||||
raise 'This macro applies to wiki pages only.' unless obj.is_a?(WikiContent)
|
||||
render_page_hierarchy(obj.page.descendants.group_by(&:parent_id), obj.page.id)
|
||||
end
|
||||
|
||||
desc "Include a wiki page. Example:\n\n !{{include(Foo)}}\n\nor to include a page of a specific project wiki:\n\n !{{include(projectname:Foo)}}"
|
||||
macro :include do |obj, args|
|
||||
project = @project
|
||||
|
||||
Reference in New Issue
Block a user