next-l/enju_leaf

View on GitHub
app/controllers/concerns/enju_library/controller.rb

Summary

Maintainability
B
4 hrs
Test Coverage
C
73%
module EnjuLibrary
  module Controller
    extend ActiveSupport::Concern

    included do
      before_action :get_library_group, :set_locale, :set_available_languages, :set_mobile_request
      before_action :store_current_location, unless: :devise_controller?
      rescue_from Pundit::NotAuthorizedError, with: :render_403
      # rescue_from ActiveRecord::RecordNotFound, with: :render_404
      # rescue_from ActionView::MissingTemplate, with: :render_404_invalid_format
      helper_method :filtered_params
    end

    private

    def render_403
      return if performed?

      if user_signed_in?
        respond_to do |format|
          format.html {render template: 'page/403', status: :forbidden}
          # format.html.phone {render template: 'page/403', status: 403}
          format.xml {render template: 'page/403', status: :forbidden}
          format.json { render json: {"error": "forbidden"} }
          format.rss {render template: 'page/403.xml', status: :forbidden}
        end
      else
        respond_to do |format|
          format.html { redirect_to main_app.new_user_session_url }
          # format.html.phone { redirect_to new_user_session_url }
          format.xml { render template: 'page/403', status: :forbidden }
          format.json { render json: {"error": "forbidden"} }
          format.rss { render template: 'page/403.xml', status: :forbidden }
        end
      end
    end

    def render_404
      return if performed?

      respond_to do |format|
        format.html { render template: 'page/404', status: :not_found }
        # format.html.phone { render template: 'page/404', status: 404 }
        format.xml { render template: 'page/404', status: :not_found }
        format.json { render json: {"error": "not_found"} }
        format.rss { render template: 'page/404.xml', status: :not_found }
      end
    end

    def render_404_invalid_format
      return if performed?

      render file: Rails.root.join('public/404.html').to_s, formats: [:html]
    end

    def render_500
      return if performed?

      respond_to do |format|
        format.html {render file: Rails.root.join('public/500.html').to_s, layout: false, status: :internal_server_error}
        # format.html.phone {render file: "#{Rails.root}/public/500", layout: false, status: 500}
        format.xml {render template: 'page/500', status: :internal_server_error}
        format.json { render json: {"error": "server_error"} }
        format.rss {render template: 'page/500.xml', status: :internal_server_error}
      end
    end

    def after_sign_in_path_for(resource)
      session[:locale] = nil
      super
    end

    def set_locale
      if params[:locale]
        unless I18n.available_locales.include?(params[:locale].to_s.intern)
          raise InvalidLocaleError
        end
      end
      if user_signed_in?
        locale = params[:locale] || session[:locale] || current_user.profile.try(:locale).try(:to_sym)
      else
        locale = params[:locale] || session[:locale]
      end
      if locale
        I18n.locale = @locale = session[:locale] = locale.to_sym
      else
        I18n.locale = @locale = session[:locale] = I18n.default_locale
      end
    rescue InvalidLocaleError
      reset_session
      @locale = I18n.default_locale
    end

    def default_url_options(options={})
      {locale: nil}
    end

    def set_available_languages
      if Rails.env.production?
        @available_languages = Rails.cache.fetch('available_languages'){
          Language.where(iso_639_1: I18n.available_locales.map{|l| l.to_s}).select([:id, :iso_639_1, :name, :native_name, :display_name, :position]).all
        }
      else
        @available_languages = Language.where(iso_639_1: I18n.available_locales.map{|l| l.to_s})
      end
    end

    def reset_params_session
      session[:params] = nil
    end

    def not_found
      raise ActiveRecord::RecordNotFound
    end

    def access_denied
      raise Pundit::NotAuthorizedError
    end

    def get_user
      @user = User.find_by(username: params[:user_id]) if params[:user_id]
      # authorize! :show, @user if @user
    end

    def get_user_group
      @user_group = UserGroup.find(params[:user_group_id]) if params[:user_group_id]
    end

    def convert_charset
      case params[:format]
      when 'csv'
        return unless LibraryGroup.site_config.csv_charset_conversion

        # TODO: 他の言語
        if @locale.to_sym == :ja
          headers["Content-Type"] = "text/csv; charset=Shift_JIS"
          response.body = NKF::nkf('-Ws', response.body)
        end
      when 'xml'
        if @locale.to_sym == :ja
          headers["Content-Type"] = "application/xml; charset=Shift_JIS"
          response.body = NKF::nkf('-Ws', response.body)
        end
      end
    end

    def store_page
      if request.get? && request.format.try(:html?) && !request.xhr?
        flash[:page] = params[:page] if params[:page].to_i.positive?
      end
    end

    def set_role_query(user, search)
      role = user.try(:role) || Role.default
      search.build do
        with(:required_role_id).less_than_or_equal_to role.id
      end
    end

    def clear_search_sessions
      session[:query] = nil
      session[:params] = nil
      session[:search_params] = nil
      session[:manifestation_ids] = nil
    end

    def api_request?
      true unless params[:format].nil? || (params[:format] == 'html')
    end

    def get_top_page_content
      if defined?(EnjuNews)
        @news_feeds = Rails.cache.fetch('news_feed_all'){NewsFeed.order(:position)}
        @news_posts = NewsPost.limit(LibraryGroup.site_config.news_post_number_top_page || 10)
      end
      @libraries = Library.real
    end

    def set_mobile_request
      case params[:view]
      when 'phone'
        session[:enju_view] = :phone
      when 'desktop'
        session[:enju_view] = :desktop
      when 'reset'
        session[:enju_view] = nil
      end

      case session[:enju_view].try(:to_sym)
      when :phone
        request.variant = :phone
      when :desktop
        request.variant = nil
      else
        request.variant = :phone if browser.device.mobile?
      end
    end

    def move_position(resource, direction, redirect = true)
      if ['higher', 'lower'].include?(direction)
        resource.send("move_#{direction}")
        if redirect
          redirect_to url_for(controller: resource.class.to_s.pluralize.underscore)
          nil
        end
      end
    end

    def store_current_location
      store_location_for(:user, request.url) if request.format.html?
    end

    def get_library_group
      @library_group = LibraryGroup.site_config
    end

    def get_shelf
      if params[:shelf_id]
        @shelf = Shelf.includes(:library).find(params[:shelf_id])
        authorize @shelf, :show?
      end
    end

    def get_library
      if params[:library_id]
        @library = Library.friendly.find(params[:library_id])
        authorize @library, :show?
      end
    end

    def get_libraries
      @libraries = Library.order(:position)
    end

    def get_bookstore
      if params[:bookstore_id]
        @bookstore = Bookstore.find(params[:bookstore_id])
        authorize @bookstore, :show?
      end
    end

    def get_subscription
      if params[:subscription_id]
        @subscription = Subscription.find(params[:subscription_id])
        authorize @subscription, :show?
      end
    end

    def filtered_params
      params.permit([:q, :query, :view, :format, :order, :sort_by, :page, :per_page])
    end

    class InvalidLocaleError < StandardError
    end
  end
end