diff --git a/plugin.rb b/plugin.rb index 4aa7281..7fedf57 100644 --- a/plugin.rb +++ b/plugin.rb @@ -4,7 +4,7 @@ # name: discourse-legacy_links # about: A plugin to handle legacy Gossamer Forums URLs -# version: 0.2 +# version: 0.4 # authors: saint@federated.computer # url: https://gitea.federated.computer/saint/discourse-legacy_links.git @@ -14,62 +14,112 @@ # after_initialize do after_initialize do - module ::DiscourseCustomRouting + module ::DiscourseLegacyLinks class Engine < ::Rails::Engine - engine_name "discourse_custom_routing" - isolate_namespace DiscourseCustomRouting + engine_name "discourse_legacy_links" + isolate_namespace DiscourseLegacyLinks end # Define the custom controller class CustomPostController < ::ApplicationController # Match URLs that include a post_id at the end or query parameter + # Main action triggered when the route is matched. def index post_id = extract_post_id_from_request if post_id + logger.info "[DEBUG] Processing request for post_id: #{post_id}" post = find_post_by_custom_field(post_id) if post # Redirect to the post URL if found + logger.info "[DEBUG] Redirecting to post with ID: #{post.id}" redirect_to post_url(post) else # Return 404 if the post is not found + logger.error "[ERROR] Post with original_gossamer_id #{post_id} not found" render plain: 'Post not found', status: 404 end else # Handle cases where the post_id cannot be extracted + logger.error "[ERROR] Could not extract post_id from the request" render plain: 'Invalid URL', status: 400 end end private + # Extracts the post ID from the request URL or query string. + # Supports various formats of legacy forum URLs. + # @return [Integer, nil] The extracted post ID or nil if not found def extract_post_id_from_request - # Extract post_id from various URL formats + # Check if post_id is passed as a query parameter (?post=post_id) if params[:post_id] - params[:post_id].to_i - elsif request.path.match(%r{/forum/[^/]+/P(\d+)/}) - $1.to_i - elsif request.query_string.match(/post=(\d+)/) - $1.to_i - elsif request.query_string.match(/parent_post_id=(\d+)/) - $1.to_i - else - nil + post_id = params[:post_id].to_i + logger.info "[DEBUG] Extracted post_id from query param: #{post_id}" + return post_id end + + # Check for post_id in the URL path (e.g., /forum/.../P12345/) + if match = request.path.match(%r{/forum/[^/]+/P(\d+)/?}) + post_id = match[1].to_i + logger.info "[DEBUG] Extracted post_id from URL path: #{post_id}" + return post_id + end + + # Check for post_id in the query string (e.g., ?post=12345) + if match = request.query_string.match(/post=(\d+)/) + post_id = match[1].to_i + logger.info "[DEBUG] Extracted post_id from query string (?post=): #{post_id}" + return post_id + end + + # Check for parent_post_id in the query string (e.g., ?parent_post_id=12345) + if match = request.query_string.match(/parent_post_id=(\d+)/) + post_id = match[1].to_i + logger.info "[DEBUG] Extracted parent_post_id from query string: #{post_id}" + return post_id + end + + # If no post_id was found in any format + logger.warn "[DEBUG] Could not extract post_id from request" + nil end + # Finds the Discourse post that has the specified custom field value. + # The custom field used is 'original_gossamer_id'. + # @param post_id [Integer] The extracted Gossamer forum post ID + # @return [Post, nil] The corresponding Discourse post or nil if not found def find_post_by_custom_field(post_id) - # Find the post with the specified custom field - Post.joins(:topic_custom_fields) - .where(topic_custom_fields: { name: 'original_gossamer_id', value: post_id.to_s }) - .first + logger.info "[DEBUG] Searching for post with custom field 'original_gossamer_id' and value #{post_id}" + + # Use ActiveRecord query to find the post by the custom field value + post = Post.joins(:topic_custom_fields) + .where(topic_custom_fields: { name: 'original_gossamer_id', value: post_id.to_s }) + .first + + if post + logger.info "[DEBUG] Found post with ID: #{post.id} for original_gossamer_id: #{post_id}" + else + logger.warn "[DEBUG] No post found for original_gossamer_id: #{post_id}" + end + + post + end + + # Redirects to the specified Discourse post. + # @param post [Post] The Discourse post to redirect to + def redirect_to_post(post) + topic_url = "#{Discourse.base_url}/t/#{post.topic_id}/#{post.post_number}" + logger.info "[DEBUG] Redirecting to topic URL: #{topic_url}" + redirect topic_url end end - # Register custom routes + # Register custom routes to handle legacy URLs Discourse::Application.routes.append do get '/forum/*path' => 'custom_post#index' end end end +