@@ -8,7 +8,7 @@ module Metrics
88 #
99 # Usage:
1010 # BetterTogether::Metrics::RichTextLinkIdentifier.call
11- class RichTextLinkIdentifier
11+ class RichTextLinkIdentifier # rubocop:disable Metrics/ClassLength
1212 def self . call ( rich_texts : nil )
1313 new ( rich_texts : rich_texts ) . call
1414 end
@@ -17,121 +17,128 @@ def initialize(rich_texts: nil)
1717 @rich_texts = rich_texts
1818 end
1919
20+ # rubocop:disable Metrics/MethodLength
2021 def call
2122 texts = rich_texts || ActionText ::RichText . includes ( :record ) . where . not ( body : nil )
2223 valid_count = 0
2324 invalid_count = 0
2425
2526 if texts . respond_to? ( :find_each )
26- texts . find_each do |rt |
27- v , i = process_rich_text ( rt )
27+ texts . find_each do |rich_text |
28+ v , i = process_rich_text ( rich_text )
2829 valid_count += v
2930 invalid_count += i
3031 end
3132 else
32- Array ( texts ) . each do |rt |
33- v , i = process_rich_text ( rt )
33+ Array ( texts ) . each do |rich_text |
34+ v , i = process_rich_text ( rich_text )
3435 valid_count += v
3536 invalid_count += i
3637 end
3738 end
3839
3940 { valid : valid_count , invalid : invalid_count }
4041 end
42+ # rubocop:enable Metrics/MethodLength
4143
4244 private
4345
4446 attr_reader :rich_texts
4547
46- def extract_links ( rt )
48+ def extract_links ( rich_text )
4749 # ActionText stores HTML; use the body helper to extract hrefs
48- rt . body . links . uniq
50+ rich_text . body . links . uniq
4951 rescue StandardError
5052 [ ]
5153 end
5254
53- def process_rich_text ( rt )
55+ # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
56+ def process_rich_text ( rich_text )
5457 valid_count = 0
5558 invalid_count = 0
56- links = extract_links ( rt )
59+ links = extract_links ( rich_text )
5760 return [ 0 , 0 ] if links . empty?
5861
5962 links . each_with_index do |link , index |
60- uri = parse_uri ( link )
61- if uri . nil?
62- create_invalid ( rt , index , link , 'undetermined' )
63+ uri_obj = parse_uri ( link )
64+ if uri_obj . nil?
65+ create_invalid ( rich_text , index , link , 'undetermined' )
6366 invalid_count += 1
6467 next
6568 end
6669
67- canonical_host = uri . host
68- if canonical_host . nil? && uri . scheme . nil?
70+ canonical_host = uri_obj . host
71+ if canonical_host . nil? && uri_obj . scheme . nil?
6972 if link . start_with? ( '/' )
7073 canonical_host = rt_platform_host
7174 else
72- create_invalid ( rt , index , link , 'undetermined' )
75+ create_invalid ( rich_text , index , link , 'undetermined' )
7376 invalid_count += 1
7477 next
7578 end
7679 end
7780
78- bt_link = BetterTogether ::Content ::Link . find_or_initialize_by ( url : link )
79- bt_link . host ||= canonical_host
80- bt_link . scheme ||= uri . scheme
81- bt_link . external = ( canonical_host . present? && ( rt_platform_host != canonical_host ) )
82- bt_link . save! if bt_link . changed?
83-
84- # Persist the RichTextLink depending on the schema available.
85- if BetterTogether ::Metrics ::RichTextLink . column_names . include? ( 'link_id' )
86- attrs = {
87- link_id : bt_link . id ,
88- rich_text_id : rt . id ,
89- rich_text_record_id : rt . record_id ,
90- rich_text_record_type : rt . record_type ,
91- position : index ,
92- locale : rt . locale
93- }
94-
95- BetterTogether ::Metrics ::RichTextLink . find_or_create_by! ( attrs )
96- else
97- # Fallback schema: metrics rich_text_links store URL and metadata inline
98- # Some legacy schemas use column names (for example `valid`) that clash
99- # with Active Record method names. To avoid DangerousAttributeError we
100- # perform a raw INSERT unless a record already exists for this
101- # (rich_text_id, url) tuple.
102- model = BetterTogether ::Metrics ::RichTextLink
103- unless model . where ( rich_text_id : rt . id , url : link ) . exists?
104- conn = model . connection
105- table = model . table_name
106- now = Time . current
107- cols = %w[ rich_text_id url link_type external valid host error_message created_at updated_at ]
108- vals = [ rt . id , link , bt_link . link_type || 'website' , bt_link . external || false ,
109- bt_link . valid_link || false , bt_link . host , bt_link . error_message , now , now ]
110- sql = "INSERT INTO #{ table } (#{ cols . join ( ',' ) } ) VALUES (#{ vals . map { |v | conn . quote ( v ) } . join ( ',' ) } )"
111- conn . execute ( sql )
112- end
113- end
114-
81+ persist_link_and_rich_text_link ( rich_text , link , index , canonical_host , uri_obj )
11582 valid_count += 1
11683 rescue URI ::InvalidURIError
117- create_invalid ( rt , index , link , 'invalid_uri' )
84+ create_invalid ( rich_text , index , link , 'invalid_uri' )
11885 invalid_count += 1
11986 end
12087
12188 [ valid_count , invalid_count ]
12289 end
90+ # rubocop:enable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
91+
92+ # rubocop:disable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
93+ def persist_link_and_rich_text_link ( rich_text , link , index , canonical_host , uri_obj )
94+ bt_link = BetterTogether ::Content ::Link . find_or_initialize_by ( url : link )
95+ bt_link . host ||= canonical_host
96+ bt_link . scheme ||= uri_obj . scheme
97+ bt_link . external = ( canonical_host . present? && ( rt_platform_host != canonical_host ) )
98+ bt_link . save! if bt_link . changed?
99+
100+ # Persist the RichTextLink depending on the schema available.
101+ if BetterTogether ::Metrics ::RichTextLink . column_names . include? ( 'link_id' )
102+ attrs = {
103+ link_id : bt_link . id ,
104+ rich_text_id : rich_text . id ,
105+ rich_text_record_id : rich_text . record_id ,
106+ rich_text_record_type : rich_text . record_type ,
107+ position : index ,
108+ locale : rich_text . locale
109+ }
110+
111+ BetterTogether ::Metrics ::RichTextLink . find_or_create_by! ( attrs )
112+ else
113+ # Fallback schema: metrics rich_text_links store URL and metadata inline.
114+ model = BetterTogether ::Metrics ::RichTextLink
115+ unless model . where ( rich_text_id : rich_text . id , url : link ) . exists?
116+ conn = model . connection
117+ table = model . table_name
118+ now = Time . current
119+ cols = %w[ rich_text_id url link_type external valid host error_message created_at updated_at ]
120+ vals = [ rich_text . id , link , bt_link . link_type || 'website' , bt_link . external || false ,
121+ bt_link . valid_link || false , bt_link . host , bt_link . error_message , now , now ]
122+ sql = "INSERT INTO #{ table } (#{ cols . join ( ',' ) } ) VALUES (#{ vals . map do |v |
123+ conn . quote ( v )
124+ end . join ( ',' ) } )"
125+ conn . execute ( sql )
126+ end
127+ end
128+ end
129+ # rubocop:enable Metrics/MethodLength,Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
123130
124131 def parse_uri ( link )
125132 URI . parse ( link )
126133 end
127134
128- def create_invalid ( rt , index , link , invalid_type )
135+ def create_invalid ( rich_text , index , link , invalid_type )
129136 BetterTogether ::Metrics ::RichTextLink . create! (
130- rich_text_id : rt . id ,
131- rich_text_record_id : rt . record_id ,
132- rich_text_record_type : rt . record_type ,
137+ rich_text_id : rich_text . id ,
138+ rich_text_record_id : rich_text . record_id ,
139+ rich_text_record_type : rich_text . record_type ,
133140 position : index ,
134- locale : rt . locale ,
141+ locale : rich_text . locale ,
135142 link : BetterTogether ::Content ::Link . create! ( url : link , valid_link : false , error_message : invalid_type )
136143 )
137144 end
0 commit comments