67 lines
2.8 KiB
Ruby
67 lines
2.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Copyright (C) 2017 - present Instructure, Inc.
|
|
#
|
|
# This file is part of Canvas.
|
|
#
|
|
# Canvas is free software: you can redistribute it and/or modify it under
|
|
# the terms of the GNU Affero General Public License as published by the Free
|
|
# Software Foundation, version 3 of the License.
|
|
#
|
|
# Canvas 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 Affero General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License along
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
module DuplicatingObjects
|
|
# Lowercases title and replaces spaces with hyphens (to allow to check for
|
|
# matching titles that differ only in case or space/hyphens)
|
|
def normalize_title(title)
|
|
title.tr(" ", "-").downcase
|
|
end
|
|
|
|
# Given a title, returns the first "non-conflicting" title. "entity"
|
|
# should provide a function "get_potentially_conflicting_titles" that
|
|
# returns a set of titles that might conflict with the entity's title.
|
|
#
|
|
# If the given title ends in "#{copy_suffix} #" (or without the number),
|
|
# tries incrementing from # (or 2 if no number is given) until one is
|
|
# found that isn't in the set returned by entity.get_potentially_conflicting_titles
|
|
#
|
|
# If not, then first tries just appending copy_suffix, and if that has a
|
|
# conflict, increments from 2 as above.
|
|
#
|
|
# For the purposes of matching, conflicts are case-insensitive and also
|
|
# treats hyphens and spaces as the same thing.
|
|
def get_copy_title(entity, copy_suffix, entity_title)
|
|
is_multiple_copy = !(normalize_title(entity_title) =~
|
|
/#{Regexp.quote(copy_suffix.downcase)}-[0-9]*$/).nil?
|
|
normalized_suffix = normalize_title(copy_suffix)
|
|
if normalize_title(entity_title).end_with?(normalized_suffix) || is_multiple_copy
|
|
potential_title = entity_title
|
|
possible_num_to_try = normalize_title(entity_title).scan(/\d+$/).first
|
|
num_to_try = possible_num_to_try ? possible_num_to_try.to_i + 1 : 2
|
|
else
|
|
potential_title = "#{entity_title} #{copy_suffix}"
|
|
num_to_try = 2
|
|
end
|
|
title_base = is_multiple_copy ? potential_title.gsub(/\d+$/, "") : potential_title + " "
|
|
title_search_term = title_base[0...-1]
|
|
conflicting_titles = entity.get_potentially_conflicting_titles(title_search_term).map do |x|
|
|
normalize_title(x)
|
|
end
|
|
return potential_title unless conflicting_titles.include?(normalize_title(potential_title))
|
|
|
|
loop do
|
|
title_attempt = "#{title_base}#{num_to_try}"
|
|
num_to_try = num_to_try.succ
|
|
return title_attempt unless conflicting_titles.include?(normalize_title(title_attempt))
|
|
end
|
|
end
|
|
end
|