trabajo-afectivo/app/models/link.rb
2022-01-01 14:38:12 +01:00

292 lines
8 KiB
Ruby

# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
class Link < ApplicationModel
belongs_to :link_type, class_name: 'Link::Type', optional: true
belongs_to :link_object, class_name: 'Link::Object', optional: true
after_destroy :touch_link_references
@map = {
'normal' => 'normal',
'parent' => 'child',
'child' => 'parent',
}
=begin
links = Link.list(
link_object: 'Ticket',
link_object_value: 1
)
=end
def self.list(data)
linkobject = link_object_get(name: data[:link_object])
return if !linkobject
items = []
# get links for one site
list = Link.where(
'link_object_source_id = ? AND link_object_source_value = ?', linkobject.id, data[:link_object_value]
)
list.each do |item|
link = {}
link['link_type'] = @map[ Link::Type.find(item.link_type_id).name ]
link['link_object'] = Link::Object.find(item.link_object_target_id).name
link['link_object_value'] = item.link_object_target_value
items.push link
end
# get links for the other site
list = Link.where(
'link_object_target_id = ? AND link_object_target_value = ?', linkobject.id, data[:link_object_value]
)
list.each do |item|
link = {}
link['link_type'] = Link::Type.find(item.link_type_id).name
link['link_object'] = Link::Object.find(item.link_object_source_id).name
link['link_object_value'] = item.link_object_source_value
items.push link
end
return items if data[:user].blank?
items.select do |item|
authorized_item?(data[:user], item)
end
end
=begin
Link.add(
link_type: 'normal',
link_object_source: 'Ticket',
link_object_source_value: 6,
link_object_target: 'Ticket',
link_object_target_value: 31
)
Link.add(
link_types_id: 12,
link_object_source_id: 1,
link_object_source_value: 1,
link_object_target_id: 1,
link_object_target_value: 1
)
=end
def self.add(data)
if data.key?(:link_type)
linktype = link_type_get(name: data[:link_type])
data[:link_type_id] = linktype.id
data.delete(:link_type)
end
if data.key?(:link_object_source)
linkobject = link_object_get(name: data[:link_object_source])
data[:link_object_source_id] = linkobject.id
touch_reference_by_params(
object: data[:link_object_source],
o_id: data[:link_object_source_value],
)
data.delete(:link_object_source)
end
if data.key?(:link_object_target)
linkobject = link_object_get(name: data[:link_object_target])
data[:link_object_target_id] = linkobject.id
touch_reference_by_params(
object: data[:link_object_target],
o_id: data[:link_object_target_value],
)
data.delete(:link_object_target)
end
Link.create(data)
end
=begin
Link.remove(
link_type: 'normal',
link_object_source: 'Ticket',
link_object_source_value: 6,
link_object_target: 'Ticket',
link_object_target_value: 31
)
=end
def self.remove(data)
if data.key?(:link_object_source)
linkobject = link_object_get(name: data[:link_object_source])
data[:link_object_source_id] = linkobject.id
end
if data.key?(:link_object_target)
linkobject = link_object_get(name: data[:link_object_target])
data[:link_object_target_id] = linkobject.id
end
# from one site
if data.key?(:link_type)
linktype = link_type_get(name: data[:link_type])
data[:link_type_id] = linktype.id
end
Link.where(
link_type_id: data[:link_type_id],
link_object_source_id: data[:link_object_source_id],
link_object_source_value: data[:link_object_source_value],
link_object_target_id: data[:link_object_target_id],
link_object_target_value: data[:link_object_target_value]
).destroy_all
# from the other site
if data.key?(:link_type)
linktype = link_type_get(name: @map[ data[:link_type] ])
data[:link_type_id] = linktype.id
end
Link.where(
link_type_id: data[:link_type_id],
link_object_target_id: data[:link_object_source_id],
link_object_target_value: data[:link_object_source_value],
link_object_source_id: data[:link_object_target_id],
link_object_source_value: data[:link_object_target_value]
).destroy_all
end
=begin
Link.remove_all(
link_object: 'Ticket',
link_object_value: 6,
)
=end
def self.remove_all(data)
if data.key?(:link_object)
linkobject = link_object_get(name: data[:link_object])
data[:link_object_id] = linkobject.id
end
Link.where(
link_object_target_id: data[:link_object_id],
link_object_target_value: data[:link_object_value],
).destroy_all
Link.where(
link_object_source_id: data[:link_object_id],
link_object_source_value: data[:link_object_value],
).destroy_all
true
end
def touch_link_references
Link.touch_reference_by_params(
object: Link::Object.lookup(id: link_object_source_id).name,
o_id: link_object_source_value,
)
Link.touch_reference_by_params(
object: Link::Object.lookup(id: link_object_target_id).name,
o_id: link_object_target_value,
)
end
def self.link_type_get(data)
linktype = Link::Type.find_by(name: data[:name])
if !linktype
linktype = Link::Type.create(name: data[:name])
end
linktype
end
def self.link_object_get(data)
linkobject = Link::Object.find_by(name: data[:name])
if !linkobject
linkobject = Link::Object.create(name: data[:name])
end
linkobject
end
=begin
Update assets according to given references list
@param assets [Hash] hash with assets
@param link_references [Array<Hash>] @see #list
@return [Hash] assets including linked items
@example Link.reduce_assets(assets, link_references)
=end
def self.reduce_assets(assets, link_references)
link_items = link_references
.filter_map { |elem| lookup_linked_object(elem) }
ApplicationModel::CanAssets.reduce(link_items, assets)
end
def self.lookup_linked_object(elem)
klass = elem['link_object'].safe_constantize
id = elem['link_object_value']
case klass.to_s
when KnowledgeBase::Answer::Translation.to_s
Setting.get('kb_active') ? klass.lookup(id: id) : nil
else
klass&.lookup(id: id)
end
end
def self.duplicates(object1_id:, object1_value:, object2_value:, object2_id: nil)
if !object2_id
object2_id = object1_id
end
Link.joins(', links as linksb').where('
(
links.link_type_id = linksb.link_type_id
AND links.link_object_source_id = linksb.link_object_source_id
AND links.link_object_source_value = linksb.link_object_source_value
AND links.link_object_target_id = ?
AND linksb.link_object_target_id = ?
AND links.link_object_target_value = ?
AND linksb.link_object_target_value = ?
)
OR
(
links.link_type_id = linksb.link_type_id
AND links.link_object_target_id = linksb.link_object_target_id
AND links.link_object_target_value = linksb.link_object_target_value
AND links.link_object_source_id = ?
AND linksb.link_object_source_id = ?
AND links.link_object_source_value = ?
AND linksb.link_object_source_value = ?
)
', object1_id, object2_id, object1_value, object2_value, object1_id, object2_id, object1_value, object2_value)
end
def self.authorized_item?(user, item)
record = item['link_object'].constantize.lookup(id: item['link_object_value'])
# non-ID records are not checked for authorization
return true if record.blank?
Pundit.authorize(user, record, :show?).present?
rescue Pundit::NotAuthorizedError
false
rescue NameError, Pundit::NotDefinedError
# NameError: no Model means no authorization check possible
# Pundit::NotDefinedError: no Policy means no authorization check necessary
true
end
end