Class: Crm::ContentLinksController

Inherits:
CrmController show all
Includes:
ActionView::RecordIdentifier
Defined in:
app/controllers/crm/content_links_controller.rb

Overview

Controller: content links.

Constant Summary

Constants included from Controllers::ReferenceFindable

Controllers::ReferenceFindable::ID_EMBEDDED_PATTERNS

Constants included from Controllers::AnalyticsEvents

Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY

Constants included from Controllers::ErrorRendering

Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES

Instance Method Summary collapse

Methods inherited from CrmController

#access_denied, #context_id, #context_object, #crm_home_path, #current_ability, #default_url_options, #download_temp, #get_tempfile_path_for_download, #init_status_job_collector, #initialize_crm_lazy_chunks, #persist_enqueued_status_jobs, #record_not_found, #redirect_to_job_or_fallback, #render_edit_action, #set_context, #set_download_path, #stash_file_for_temp_download, #sync_admin_presence_cookie, #touch_employee_last_seen

Methods inherited from ApplicationController

#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #skip_layout_for_turbo_frame?, #stamp_impersonation_context, #tab_frame_breakout_request?, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y

Methods included from Controllers::ReturnPathHandling

#check_for_return_path, #redirect_to_return_path_or_default

Methods included from Controllers::AnalyticsEvents

#consume_queued_analytics_events, #registration_lead_type, #track_event

Methods included from Controllers::DeviceDetection

#device_detector, #is_ie?

Methods included from Controllers::SubdomainDetection

#is_crm_request?, #is_www_request?, #json_request?

Methods included from Controllers::TurboSafeRedirect

#redirect_to

Methods included from Controllers::TrackingDetection

#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?

Methods included from Controllers::AcceleratedFileSending

#send_file_accelerated, #send_upload_accelerated

Methods included from Controllers::ErrorRendering

#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #render_unpermitted_parameters, #safe_referer_or_fallback

Methods included from Controllers::TurnstileVerification

#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!

Methods included from Controllers::CloudflareCaching

edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_edge_cache!, #skip_session

Methods included from Controllers::Webpackable

#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?

Methods included from Controllers::Localizable

#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale

Methods included from Controllers::Authenticable

#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak

Methods included from UrlsHelper

#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?

Instance Method Details

#createObject

Creates a ContentLink from the requested source to an eligible target,
rejecting the request if the link type is workflow-managed (consolidation
links can only be created by the workflow itself).



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/controllers/crm/content_links_controller.rb', line 10

def create
  source = find_source
  attributes = content_link_params
  workflow_managed = false
  saved = source.with_lock do
    authorize_source_links_editable!(source)

    if ContentLink.workflow_context?(link_type: attributes[:link_type], context: attributes[:context])
      workflow_managed = true
      false
    else
      target = eligible_target(source, attributes)
      unless target
        @content_link = ContentLink.new(source:)
        @content_link.errors.add(:target, 'is unavailable or not approved')
        next false
      end

      authorize! :read, target
      @content_link = ContentLink.new(
        attributes.except(:target_type, :target_id).merge(source:, target:)
      )
      @content_link.position = source.outbound_content_links.maximum(:position).to_i + 1
      @content_link.save
    end
  end
  if workflow_managed
    redirect_back_or_to route_path_for(source),
                        alert: 'Technical Article consolidation links can only be created by the consolidation workflow.'
    return
  end

  if saved
    respond_to do |format|
      format.turbo_stream do
        wrapper_id = "content-links-#{@content_link.link_type}-wrapper"
        render turbo_stream: [
          turbo_stream.append(
            "content-links-#{@content_link.link_type}",
            partial: 'crm/content_links/link_row',
            locals: { content_link: @content_link }
          ),
          turbo_stream.show_element(wrapper_id),
          turbo_stream.remove("content-links-empty-message")
        ]
      end
      format.html { redirect_back_or_to route_path_for(source) }
    end
  else
    respond_to do |format|
      format.turbo_stream do
        render plain: @content_link.errors.full_messages.to_sentence, status: :unprocessable_content
      end
      format.html { redirect_back_or_to route_path_for(source), alert: @content_link.errors.full_messages.join(', ') }
    end
  end
end

#destroyObject

Destroys a content link unless it is workflow-managed.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/controllers/crm/content_links_controller.rb', line 69

def destroy
  @content_link = ContentLink.find(params.expect(:id))
  source = @content_link.source
  workflow_managed = false
  source.with_lock do
    authorize_source_links_editable!(source)
    @content_link.reload
    if @content_link.workflow_managed?
      workflow_managed = true
    else
      @content_link.destroy!
    end
  end
  if workflow_managed
    redirect_back_or_to route_path_for(source),
                        alert: 'Technical Article consolidation links are managed by the review workflow.'
    return
  end

  respond_to do |format|
    format.turbo_stream do
      render turbo_stream: turbo_stream.remove(dom_id(@content_link))
    end
    format.html { redirect_back_or_to route_path_for(source) }
  end
end

#lookupObject

Select2-style JSON search for eligible link targets of a given target type.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/controllers/crm/content_links_controller.rb', line 116

def lookup
  source = find_source
  authorize! :update, source

  config = ContentLink.editor_target_type_config(source)[params[:target_type]]
  head(:unprocessable_content) and return unless config

  search_klass = config.fetch(:search_class).call
  authorize! :read, search_klass
  scope = build_search_scope(search_klass, config)

  @pagy, records = pagy(scope, limit: 20)

  render json: {
    results: records.map { |record| { id: record.id, text: record.public_send(config[:display_field]) } },
    has_more: @pagy.next.present?,
    page: @pagy.page
  }
end

#reorderObject

Reorders the editable (non-workflow-managed) content links of one link
type on the given source, per the submitted ids order.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'app/controllers/crm/content_links_controller.rb', line 98

def reorder
  source = find_source
  source.with_lock do
    authorize_source_links_editable!(source)

    ids = params.expect(ids: []).map(&:to_i).uniq
    editable_links = source.outbound_content_links
                           .excluding_workflow_managed
                           .where(id: ids)
                           .index_by(&:id)
    requested_links = ids.filter_map { |id| editable_links[id] }
    reorder_link_group!(source, requested_links) if requested_links.any?
  end

  head :ok
end