Skip to content

Commit

Permalink
Release OpenProject 11.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverguenther committed Mar 23, 2021
2 parents 8e30e24 + e2b0a79 commit a0ea141
Show file tree
Hide file tree
Showing 65 changed files with 1,184 additions and 370 deletions.
13 changes: 7 additions & 6 deletions .pkgr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ targets:
<<: *debian9
ubuntu-20.04:
<<: *debian9
centos-8:
centos-7: &centos7
dependencies:
- unzip
- epel-release
- ImageMagick
centos-7:
dependencies:
- epel-release
- poppler-utils
- unrtf
- tesseract
- catdoc
- ImageMagick
centos-8:
<<: *centos7
sles-12:
build_dependencies:
- sqlite3-devel
Expand Down
45 changes: 25 additions & 20 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ def handle_unverified_request
end

before_action :user_setup,
:set_localization,
:check_if_login_required,
:log_requesting_user,
:reset_i18n_fallbacks,
:set_localization,
:check_session_lifetime,
:stop_if_feeds_disabled,
:set_cache_buster,
Expand Down Expand Up @@ -176,6 +176,7 @@ def reload_mailer_configuration!
def openproject_cookie_missing?
request.cookies[OpenProject::Configuration['session_cookie_name']].nil?
end

helper_method :openproject_cookie_missing?

##
Expand Down Expand Up @@ -330,31 +331,32 @@ def find_object_and_scope
def find_belongs_to_chained_objects(associations, start_object = nil)
associations.inject([start_object].compact) do |instances, association|
scope_name, scope_association = if association.is_a?(Hash)
[association.keys.first.to_s.downcase, association.values.first]
else
[association.to_s.downcase, association.to_s.downcase]
end
[association.keys.first.to_s.downcase, association.values.first]
else
[association.to_s.downcase, association.to_s.downcase]
end

# TODO: Remove this hidden dependency on params
instances << (if instances.last.nil?
scope_name.camelize.constantize.find(params[:"#{scope_name}_id"])
else
instances.last.send(scope_association.to_sym)
end)
instances << (
if instances.last.nil?
scope_name.camelize.constantize.find(params[:"#{scope_name}_id"])
else
instances.last.send(scope_association.to_sym)
end)
instances
end
end

def self.model_object(model, options = {})
self._model_object = model
self._model_scope = Array(options[:scope]) if options[:scope]
self._model_scope = Array(options[:scope]) if options[:scope]
end

# Filter for bulk work package operations
def find_work_packages
@work_packages = WorkPackage.includes(:project)
.where(id: params[:work_package_id] || params[:ids])
.order('id ASC')
.where(id: params[:work_package_id] || params[:ids])
.order('id ASC')
fail ActiveRecord::RecordNotFound if @work_packages.empty?

@projects = @work_packages.map(&:project).compact.uniq
Expand Down Expand Up @@ -452,13 +454,13 @@ def object_errors_to_json(object)
def render_validation_errors(object)
options = { status: :unprocessable_entity, layout: false }
errors = case params[:format]
when 'xml'
{ xml: object.errors }
when 'json'
{ json: { 'errors' => object.errors } } # ActiveResource client compliance
else
fail "Unknown format #{params[:format]} in #render_validation_errors"
end
when 'xml'
{ xml: object.errors }
when 'json'
{ json: { 'errors' => object.errors } } # ActiveResource client compliance
else
fail "Unknown format #{params[:format]} in #render_validation_errors"
end
options.merge! errors
render options
end
Expand Down Expand Up @@ -489,17 +491,20 @@ def default_breadcrumb
I18n.t(label + '_plural',
default: label.to_sym)
end

helper_method :default_breadcrumb

def show_local_breadcrumb
false
end

helper_method :show_local_breadcrumb

def admin_first_level_menu_entry
menu_item = admin_menu_item(current_menu_item)
menu_item.parent
end

helper_method :admin_first_level_menu_entry

def check_session_lifetime
Expand Down
4 changes: 4 additions & 0 deletions app/models/custom_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ def list?
field_format == "list"
end

def formattable?
field_format == "text"
end

def multi_value?
multi_value
end
Expand Down
30 changes: 19 additions & 11 deletions app/models/mail_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,16 @@ def options=(value)

private

MESSAGE_ID_RE = %r{^<?openproject\.([a-z0-9_]+)-(\d+)\.\d+@}
MESSAGE_ID_RE = %r{^<?openproject\.([a-z0-9_]+)-(\d+)-(\d+)\.\d+@}
ISSUE_REPLY_SUBJECT_RE = %r{.+? - .+ #(\d+):}
MESSAGE_REPLY_SUBJECT_RE = %r{\[[^\]]*msg(\d+)\]}

def dispatch
headers = [email.in_reply_to, email.references].flatten.compact
if headers.detect { |h| h.to_s =~ MESSAGE_ID_RE }
klass = $1
object_id = $2.to_i
method_name = "receive_#{klass}_reply"
if self.class.private_instance_methods.map(&:to_s).include?(method_name)
send method_name, object_id
end
elsif m = email.subject.match(ISSUE_REPLY_SUBJECT_RE)
if (m, object_id = dispatch_target_from_message_id)
m.call(object_id)
elsif (m = email.subject.match(ISSUE_REPLY_SUBJECT_RE))
receive_work_package_reply(m[1].to_i)
elsif m = email.subject.match(MESSAGE_REPLY_SUBJECT_RE)
elsif (m = email.subject.match(MESSAGE_REPLY_SUBJECT_RE))
receive_message_reply(m[1].to_i)
else
dispatch_to_default
Expand All @@ -172,6 +166,20 @@ def dispatch_to_default
receive_work_package
end

##
# Find a matching method to dispatch to given the mail's message ID
def dispatch_target_from_message_id
headers = [email.references, email.in_reply_to].flatten.compact
if headers.detect { |h| h.to_s =~ MESSAGE_ID_RE }
klass = $1
object_id = $3.to_i
method_name = :"receive_#{klass}_reply"
if self.class.private_instance_methods.include?(method_name)
return method(method_name), object_id
end
end
end

# Creates a new work package
def receive_work_package
project = target_project
Expand Down
8 changes: 7 additions & 1 deletion app/models/wiki_page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ class WikiPage < ApplicationRecord

attr_accessor :redirect_existing_links

validates_presence_of :title
validates :title, presence: true
validates :slug,
presence: {
message: ->(object, _) {
I18n.t('activerecord.errors.models.wiki_page.attributes.slug.undeducible', title: object.title)
}
}
validates_associated :content

validate :validate_consistency_of_parent_title
Expand Down
103 changes: 0 additions & 103 deletions app/models/work_package/pdf_export/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,109 +79,6 @@ def configure_markup
}
end

##
# Writes the formatted work package description into the document.
#
# A border (without one on the top) is painted around the area painted by the description.
#
# @param work_package [WorkPackage] The work package for which the description is to be printed.
# @param label [boolean] Whether a label is to be printed in a column preceding the description.
def write_description!(work_package, label = true)
height = write_description_html!(work_package, label)

data = make_description_label_row(label) +
make_description_border_rows(height, label)

pdf.table(data, column_widths: column_widths)
end

def write_description_html!(work_package, label)
float_with_height_indicator do
pdf.move_down(cell_padding[1])

pdf.indent(description_padding_left(label), cell_padding[3]) do
pdf.markup(formatted_description_text(work_package))
end
end
end

def float_with_height_indicator
former_position = new_position = current_y_position

pdf.float do
yield

new_position = current_y_position
end

position_diff(former_position, new_position)
end

def make_description_label_row(label)
if label
[[make_description_label, pdf.make_cell('', borders: [:right], colspan: description_colspan)].compact]
else
[[pdf.make_cell('', borders: %i[right left], colspan: description_colspan)]]
end
end

def description_padding_left(label)
if label
column_widths.first + cell_padding[1]
else
cell_padding[1]
end
end

def description_padding_right
cell_padding[3]
end

def formatted_description_text(work_package)
format_text(work_package.description.to_s, object: work_package, format: :html)
end

def make_description_border_rows(height, label)
border_row_height = 10

(height / border_row_height).ceil.times.map do |index|
make_description_border_row(border_row_height,
label,
index == (height / border_row_height).ceil - 1)
end
end

def make_description_border_row(border_row_height, label, last)
border_left = if label
[:left]
else
%i[left right]
end

border_right = [:right]

if last
border_left << :bottom
border_right << :bottom
end

if label
[pdf.make_cell('', height: border_row_height, borders: border_left, colspan: 1),
pdf.make_cell('', height: border_row_height, borders: border_right, colspan: description_colspan)]
else
[pdf.make_cell('', height: border_row_height, borders: border_left, colspan: description_colspan)]
end
end

def make_description_label
text = WorkPackage.human_attribute_name(:description) + ':'
pdf.make_cell(text, borders: [:left], font_style: :bold, padding: cell_padding)
end

def description_colspan
raise NotImplementedError, 'to be implemented where included'
end

def current_y_position
OpenStruct.new y: pdf.y, page: pdf.page_number
end
Expand Down
Loading

0 comments on commit a0ea141

Please sign in to comment.