diff options
Diffstat (limited to 'lib/redmine')
-rw-r--r-- | lib/redmine/ciphering.rb | 6 | ||||
-rw-r--r-- | lib/redmine/core_ext/active_record.rb | 43 | ||||
-rw-r--r-- | lib/redmine/core_ext/string.rb | 4 | ||||
-rw-r--r-- | lib/redmine/hook.rb | 16 | ||||
-rw-r--r-- | lib/redmine/plugin.rb | 137 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/cvs_adapter.rb | 4 | ||||
-rw-r--r-- | lib/redmine/themes.rb | 8 | ||||
-rw-r--r-- | lib/redmine/utils.rb | 6 | ||||
-rw-r--r-- | lib/redmine/version.rb | 6 | ||||
-rw-r--r-- | lib/redmine/views/api_template_handler.rb | 6 | ||||
-rw-r--r-- | lib/redmine/views/builders/xml.rb | 4 | ||||
-rw-r--r-- | lib/redmine/views/labelled_form_builder.rb | 4 | ||||
-rw-r--r-- | lib/redmine/views/my_page/block.rb | 2 | ||||
-rw-r--r-- | lib/redmine/wiki_formatting.rb | 7 |
14 files changed, 198 insertions, 55 deletions
diff --git a/lib/redmine/ciphering.rb b/lib/redmine/ciphering.rb index 3dd5df826..186709016 100644 --- a/lib/redmine/ciphering.rb +++ b/lib/redmine/ciphering.rb @@ -72,7 +72,7 @@ module Redmine all.each do |object| clear = object.send(attribute) object.send "#{attribute}=", clear - raise(ActiveRecord::Rollback) unless object.save(false) + raise(ActiveRecord::Rollback) unless object.save(:validation => false) end end ? true : false end @@ -81,8 +81,8 @@ module Redmine transaction do all.each do |object| clear = object.send(attribute) - object.write_attribute attribute, clear - raise(ActiveRecord::Rollback) unless object.save(false) + object.send :write_attribute, attribute, clear + raise(ActiveRecord::Rollback) unless object.save(:validation => false) end end end ? true : false diff --git a/lib/redmine/core_ext/active_record.rb b/lib/redmine/core_ext/active_record.rb index f881f90a5..5f84e144f 100644 --- a/lib/redmine/core_ext/active_record.rb +++ b/lib/redmine/core_ext/active_record.rb @@ -16,38 +16,25 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. module ActiveRecord - class Base - def self.find_ids(options={}) - find_ids_with_associations(options) + module FinderMethods + def find_ids(*args) + find_ids_with_associations end - end - module Associations - module ClassMethods - def find_ids_with_associations(options = {}) - catch :invalid_query do - join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(self, merge_includes(scope(:find, :include), options[:include]), options[:joins]) - return connection.select_values(construct_ids_finder_sql_with_included_associations(options, join_dependency)).map(&:to_i) - end + private + + def find_ids_with_associations + join_dependency = construct_join_dependency_for_association_find + relation = construct_relation_for_association_find_ids(join_dependency) + rows = connection.select_all(relation, 'SQL', relation.bind_values) + rows.map {|row| row["id"].to_i} + rescue ThrowResult [] - end - - def construct_ids_finder_sql_with_included_associations(options, join_dependency) - scope = scope(:find) - sql = "SELECT #{table_name}.id FROM #{(scope && scope[:from]) || options[:from] || quoted_table_name} " - sql << join_dependency.join_associations.collect{|join| join.association_join }.join - - add_joins!(sql, options[:joins], scope) - add_conditions!(sql, options[:conditions], scope) - add_limited_ids_condition!(sql, options, join_dependency) if !using_limitable_reflections?(join_dependency.reflections) && ((scope && scope[:limit]) || options[:limit]) - - add_group!(sql, options[:group], options[:having], scope) - add_order!(sql, options[:order], scope) - add_limit!(sql, options, scope) if using_limitable_reflections?(join_dependency.reflections) - add_lock!(sql, options, scope) + end - return sanitize_sql(sql) - end + def construct_relation_for_association_find_ids(join_dependency) + relation = except(:includes, :eager_load, :preload, :select).select("#{table_name}.id") + apply_join_dependency(relation, join_dependency) end end end diff --git a/lib/redmine/core_ext/string.rb b/lib/redmine/core_ext/string.rb index 2da5ffef9..c865284ac 100644 --- a/lib/redmine/core_ext/string.rb +++ b/lib/redmine/core_ext/string.rb @@ -4,4 +4,8 @@ require File.dirname(__FILE__) + '/string/inflections' class String #:nodoc: include Redmine::CoreExtensions::String::Conversions include Redmine::CoreExtensions::String::Inflections + + def is_binary_data? + ( self.count( "^ -~", "^\r\n" ).fdiv(self.size) > 0.3 || self.index( "\x00" ) ) unless empty? + end end diff --git a/lib/redmine/hook.rb b/lib/redmine/hook.rb index dba36a91a..f0a95f020 100644 --- a/lib/redmine/hook.rb +++ b/lib/redmine/hook.rb @@ -17,7 +17,7 @@ module Redmine module Hook - include ActionController::UrlWriter + #include ActionController::UrlWriter @@listener_classes = [] @@listeners = nil @@ -88,12 +88,12 @@ module Redmine include ActionView::Helpers::FormTagHelper include ActionView::Helpers::FormOptionsHelper include ActionView::Helpers::JavaScriptHelper - include ActionView::Helpers::PrototypeHelper + #include ActionView::Helpers::PrototypeHelper include ActionView::Helpers::NumberHelper include ActionView::Helpers::UrlHelper include ActionView::Helpers::AssetTagHelper include ActionView::Helpers::TextHelper - include ActionController::UrlWriter + include Rails.application.routes.url_helpers include ApplicationHelper # Default to creating links using only the path. Subclasses can @@ -113,6 +113,14 @@ module Redmine context[:controller].send(:render_to_string, {:locals => context}.merge(options)) end end + + def controller + nil + end + + def config + ActionController::Base.config + end end # Helper module included in ApplicationHelper and ActionController so that @@ -143,7 +151,7 @@ module Redmine default_context = { :project => @project } default_context[:controller] = controller if respond_to?(:controller) default_context[:request] = request if respond_to?(:request) - Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ') + Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe end end end diff --git a/lib/redmine/plugin.rb b/lib/redmine/plugin.rb index 5c13e3d1f..1f57c4d0c 100644 --- a/lib/redmine/plugin.rb +++ b/lib/redmine/plugin.rb @@ -43,6 +43,9 @@ module Redmine #:nodoc: # # When rendered, the plugin settings value is available as the local variable +settings+ class Plugin + cattr_accessor :directory + self.directory = File.join(Rails.root, 'plugins') + cattr_accessor :public_directory self.public_directory = File.join(Rails.root, 'public', 'plugin_assets') @@ -70,9 +73,22 @@ module Redmine #:nodoc: p.instance_eval(&block) # Set a default name if it was not provided during registration p.name(id.to_s.humanize) if p.name.nil? + # Adds plugin locales if any # YAML translation files should be found under <plugin>/config/locales/ - ::I18n.load_path += Dir.glob(File.join(Rails.root, 'vendor', 'plugins', id.to_s, 'config', 'locales', '*.yml')) + ::I18n.load_path += Dir.glob(File.join(p.directory, 'config', 'locales', '*.yml')) + + # Prepends the app/views directory of the plugin to the view path + view_path = File.join(p.directory, 'app', 'views') + if File.directory?(view_path) + ActionController::Base.prepend_view_path(view_path) + end + + # Adds the app/{controllers,helpers,models} directories of the plugin to the autoload path + Dir.glob File.expand_path(File.join(p.directory, 'app', '{controllers,helpers,models}')) do |dir| + ActiveSupport::Dependencies.autoload_paths += [dir] + end + registered_plugins[id] = p end @@ -100,10 +116,38 @@ module Redmine #:nodoc: registered_plugins[id.to_sym].present? end + def self.load + Dir.glob(File.join(self.directory, '*')).sort.each do |directory| + if File.directory?(directory) + lib = File.join(directory, "lib") + if File.directory?(lib) + $:.unshift lib + ActiveSupport::Dependencies.autoload_paths += [lib] + end + initializer = File.join(directory, "init.rb") + if File.file?(initializer) + require initializer + end + end + end + end + def initialize(id) @id = id.to_sym end + def directory + File.join(self.class.directory, id.to_s) + end + + def public_directory + File.join(self.class.public_directory, id.to_s) + end + + def assets_directory + File.join(directory, 'assets') + end + def <=>(plugin) self.id.to_s <=> plugin.id.to_s end @@ -277,5 +321,96 @@ module Redmine #:nodoc: def configurable? settings && settings.is_a?(Hash) && !settings[:partial].blank? end + + def mirror_assets + source = assets_directory + destination = public_directory + return unless File.directory?(source) + + source_files = Dir[source + "/**/*"] + source_dirs = source_files.select { |d| File.directory?(d) } + source_files -= source_dirs + + unless source_files.empty? + base_target_dir = File.join(destination, File.dirname(source_files.first).gsub(source, '')) + FileUtils.mkdir_p(base_target_dir) + end + + source_dirs.each do |dir| + # strip down these paths so we have simple, relative paths we can + # add to the destination + target_dir = File.join(destination, dir.gsub(source, '')) + begin + FileUtils.mkdir_p(target_dir) + rescue Exception => e + raise "Could not create directory #{target_dir}: \n" + e + end + end + + source_files.each do |file| + begin + target = File.join(destination, file.gsub(source, '')) + unless File.exist?(target) && FileUtils.identical?(file, target) + FileUtils.cp(file, target) + end + rescue Exception => e + raise "Could not copy #{file} to #{target}: \n" + e + end + end + end + + # The directory containing this plugin's migrations (<tt>plugin/db/migrate</tt>) + def migration_directory + File.join(Rails.root, 'plugins', id.to_s, 'db', 'migrate') + end + + # Returns the version number of the latest migration for this plugin. Returns + # nil if this plugin has no migrations. + def latest_migration + migrations.last + end + + # Returns the version numbers of all migrations for this plugin. + def migrations + migrations = Dir[migration_directory+"/*.rb"] + migrations.map { |p| File.basename(p).match(/0*(\d+)\_/)[1].to_i }.sort + end + + # Migrate this plugin to the given version + def migrate(version = nil) + Redmine::Plugin::Migrator.migrate_plugin(self, version) + end + + class Migrator < ActiveRecord::Migrator + # We need to be able to set the 'current' plugin being migrated. + cattr_accessor :current_plugin + + class << self + # Runs the migrations from a plugin, up (or down) to the version given + def migrate_plugin(plugin, version) + self.current_plugin = plugin + return if current_version(plugin) == version + migrate(plugin.migration_directory, version) + end + + def current_version(plugin=current_plugin) + # Delete migrations that don't match .. to_i will work because the number comes first + ::ActiveRecord::Base.connection.select_values( + "SELECT version FROM #{schema_migrations_table_name}" + ).delete_if{ |v| v.match(/-#{plugin.id}/) == nil }.map(&:to_i).max || 0 + end + end + + def migrated + sm_table = self.class.schema_migrations_table_name + ::ActiveRecord::Base.connection.select_values( + "SELECT version FROM #{sm_table}" + ).delete_if{ |v| v.match(/-#{current_plugin.id}/) == nil }.map(&:to_i).sort + end + + def record_version_state_after_migrating(version) + super(version.to_s + "-" + current_plugin.id.to_s) + end + end end end diff --git a/lib/redmine/scm/adapters/cvs_adapter.rb b/lib/redmine/scm/adapters/cvs_adapter.rb index 9bcee71a6..3a0d27c34 100644 --- a/lib/redmine/scm/adapters/cvs_adapter.rb +++ b/lib/redmine/scm/adapters/cvs_adapter.rb @@ -222,8 +222,8 @@ module Redmine :author => author, :message => commit_log.chomp, :paths => [{ - :revision => revision, - :branch => revBranch, + :revision => revision.dup, + :branch => revBranch.dup, :path => scm_iconv('UTF-8', @path_encoding, entry_path), :name => scm_iconv('UTF-8', @path_encoding, entry_name), :kind => 'file', diff --git a/lib/redmine/themes.rb b/lib/redmine/themes.rb index 71d237e67..51b974fd7 100644 --- a/lib/redmine/themes.rb +++ b/lib/redmine/themes.rb @@ -118,6 +118,14 @@ module ApplicationHelper stylesheet_path source end + def stylesheet_link_tag(source, *args) + if current_theme && current_theme.stylesheets.include?(source) + super current_theme.stylesheet_path(source), *args + else + super + end + end + # Returns the header tags for the current theme def heads_for_theme if current_theme && current_theme.javascripts.include?('theme') diff --git a/lib/redmine/utils.rb b/lib/redmine/utils.rb index 96580168f..b04bbaa47 100644 --- a/lib/redmine/utils.rb +++ b/lib/redmine/utils.rb @@ -22,7 +22,7 @@ module Redmine def relative_url_root ActionController::Base.respond_to?('relative_url_root') ? ActionController::Base.relative_url_root.to_s : - ActionController::AbstractRequest.relative_url_root.to_s + ActionController::Base.config.relative_url_root.to_s end # Sets the relative root url of the application @@ -30,7 +30,7 @@ module Redmine if ActionController::Base.respond_to?('relative_url_root=') ActionController::Base.relative_url_root=arg else - ActionController::AbstractRequest.relative_url_root=arg + ActionController::Base.config.relative_url_root = arg end end @@ -38,7 +38,7 @@ module Redmine # Example: # random_hex(4) # => "89b8c729" def random_hex(n) - ActiveSupport::SecureRandom.hex(n) + SecureRandom.hex(n) end end end diff --git a/lib/redmine/version.rb b/lib/redmine/version.rb index 45c405988..c473160db 100644 --- a/lib/redmine/version.rb +++ b/lib/redmine/version.rb @@ -2,9 +2,9 @@ require 'rexml/document' module Redmine module VERSION #:nodoc: - MAJOR = 1 - MINOR = 4 - TINY = 1 + MAJOR = 2 + MINOR = 0 + TINY = 0 # Branch values: # * official release: nil diff --git a/lib/redmine/views/api_template_handler.rb b/lib/redmine/views/api_template_handler.rb index f603c433c..298a20d0b 100644 --- a/lib/redmine/views/api_template_handler.rb +++ b/lib/redmine/views/api_template_handler.rb @@ -17,10 +17,8 @@ module Redmine module Views - class ApiTemplateHandler < ActionView::TemplateHandler - include ActionView::TemplateHandlers::Compilable - - def compile(template) + class ApiTemplateHandler + def self.call(template) "Redmine::Views::Builders.for(params[:format]) do |api|; #{template.source}; self.output_buffer = api.output; end" end end diff --git a/lib/redmine/views/builders/xml.rb b/lib/redmine/views/builders/xml.rb index 5814d00cb..dc2707d66 100644 --- a/lib/redmine/views/builders/xml.rb +++ b/lib/redmine/views/builders/xml.rb @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'builder' + module Redmine module Views module Builders @@ -29,7 +31,7 @@ module Redmine end def method_missing(sym, *args, &block) - if args.size == 1 && args.first.is_a?(Time) + if args.size == 1 && args.first.is_a?(::Time) __send__ sym, args.first.xmlschema, &block else super diff --git a/lib/redmine/views/labelled_form_builder.rb b/lib/redmine/views/labelled_form_builder.rb index 857ac066a..bdf5ffb11 100644 --- a/lib/redmine/views/labelled_form_builder.rb +++ b/lib/redmine/views/labelled_form_builder.rb @@ -24,14 +24,14 @@ class Redmine::Views::LabelledFormBuilder < ActionView::Helpers::FormBuilder %w(date_select)).each do |selector| src = <<-END_SRC def #{selector}(field, options = {}) - label_for_field(field, options) + super(field, options.except(:label)) + label_for_field(field, options) + super(field, options.except(:label)).html_safe end END_SRC class_eval src, __FILE__, __LINE__ end def select(field, choices, options = {}, html_options = {}) - label_for_field(field, options) + super(field, choices, options, html_options.except(:label)) + label_for_field(field, options) + super(field, choices, options, html_options.except(:label)).html_safe end # Returns a label tag for the given field diff --git a/lib/redmine/views/my_page/block.rb b/lib/redmine/views/my_page/block.rb index 06f532dde..793686755 100644 --- a/lib/redmine/views/my_page/block.rb +++ b/lib/redmine/views/my_page/block.rb @@ -20,7 +20,7 @@ module Redmine module MyPage module Block def self.additional_blocks - @@additional_blocks ||= Dir.glob("#{Rails.root}/vendor/plugins/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file| + @@additional_blocks ||= Dir.glob("#{Redmine::Plugin.directory}/*/app/views/my/blocks/_*.{rhtml,erb}").inject({}) do |h,file| name = File.basename(file).split('.').first.gsub(/^_/, '') h[name] = name.to_sym h diff --git a/lib/redmine/wiki_formatting.rb b/lib/redmine/wiki_formatting.rb index 63914e8ce..f1d8378f5 100644 --- a/lib/redmine/wiki_formatting.rb +++ b/lib/redmine/wiki_formatting.rb @@ -115,8 +115,9 @@ module Redmine url=url[0..-2] # discard closing parenth from url post = ")"+post # add closing parenth to post end - tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external') - %(#{leading}#{tag}#{post}) + content = proto + url + href = "#{proto=="www."?"http://www.":proto}#{url}" + %(#{leading}<a class="external" href="#{ERB::Util.html_escape href}">#{ERB::Util.html_escape content}</a>#{post}).html_safe end end end @@ -128,7 +129,7 @@ module Redmine if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) mail else - content_tag('a', mail, :href => "mailto:#{mail}", :class => "email") + %(<a class="email" href="mailto:#{ERB::Util.html_escape mail}">#{ERB::Util.html_escape mail}</a>).html_safe end end end |