Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows use of stand-alone Spree Checkout #575

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,19 @@

if Spree::Core::Engine.frontend_available?
resources :users, only: [:edit, :update]
get '/checkout/registration' => 'checkout#registration', :as => :checkout_registration
put '/checkout/registration' => 'checkout#update_registration', :as => :update_checkout_registration
resource :account, controller: 'users'

unless Spree::Auth::Engine.checkout_available?
get '/checkout/registration' => 'checkout#registration', :as => :checkout_registration
put '/checkout/registration' => 'checkout#update_registration', :as => :update_checkout_registration
end
end

if Spree::Auth::Engine.checkout_available?
namespace :checkout do
get :registration, to: 'orders#registration', as: :registration
put :registration, to: 'orders#update_registration', as: :update_registration
end
end

if Spree.respond_to?(:admin_path) && Spree::Core::Engine.backend_available?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

module Spree
module Auth
module Checkout
#
# Adds methods to Spree Checkout Orders
module OrdersControllerDecorator
def self.prepended(base)
base.before_action :check_authorization
base.before_action :check_registration, except: %i[registration update_registration]
end

def registration
@user = Spree.user_class.new
@title = Spree.t(:registration)
end

def update_registration
if order_params[:email] =~ Devise.email_regexp && current_order.update_attribute(:email, order_params[:email])
redirect_to spree.checkout_state_path(:address)
else
flash[:error] = t(:email_is_invalid, scope: %i[errors messages])
@user = Spree.user_class.new
render 'registration', status: :unprocessable_entity
end
end

private

def order_params
params[:order].present? ? params.require(:order).permit(:email) : {}
end

def skip_state_validation?
%w[registration update_registration].include?(params[:action])
end

def check_authorization
authorize!(:edit, current_order, cookies.signed[:guest_token])
end

# Introduces a registration step whenever the +registration_step+ preference is true.
def check_registration
return unless Spree::Auth::Config[:registration_step]
return if spree_current_user || current_order.email

store_location
redirect_to spree.checkout_registration_path
end

Spree::Checkout::OrdersController.prepend(self) if ::Spree::Checkout::OrdersController.included_modules.exclude?(self)
end
end
end
end
86 changes: 86 additions & 0 deletions lib/controllers/checkout/spree/user_sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class Spree::UserSessionsController < Devise::SessionsController
helper 'spree/base'

include Spree::Core::ControllerHelpers::Auth
include Spree::Core::ControllerHelpers::Common
include Spree::Core::ControllerHelpers::Order
include Spree::Core::ControllerHelpers::Store

include SpreeI18n::ControllerLocaleHelper if defined?(SpreeI18n::ControllerLocaleHelper)

include Spree::Core::ControllerHelpers::Currency if defined?(Spree::Core::ControllerHelpers::Currency)
include Spree::Core::ControllerHelpers::Locale if defined?(Spree::Core::ControllerHelpers::Locale)

include Spree::LocaleUrls if defined?(Spree::LocaleUrls)

helper 'spree/locale' if defined?(Spree::LocaleHelper)
helper 'spree/currency' if defined?(Spree::CurrencyHelper)
helper 'spree/store' if defined?(Spree::StoreHelper)

before_action :set_current_order

def create
authenticate_spree_user!

if spree_user_signed_in?
respond_to do |format|
format.html {
flash[:success] = Spree.t(:logged_in_successfully)
redirect_back_or_default(after_sign_in_redirect(spree_current_user))
}
format.js {
render json: { user: spree_current_user,
ship_address: spree_current_user.ship_address,
bill_address: spree_current_user.bill_address }.to_json
}
end
else
respond_to do |format|
format.html {
flash.now[:error] = t('devise.failure.invalid')
render :new, status: :unprocessable_entity
}
format.js {
render json: { error: t('devise.failure.invalid') }, status: :unprocessable_entity
}
end
end
end

protected

def translation_scope
'devise.user_sessions'
end

private

def accurate_title
Spree.t(:login)
end

def redirect_back_or_default(default)
redirect_to(session["spree_user_return_to"] || default)
session["spree_user_return_to"] = nil
end

def after_sign_in_redirect(resource_or_scope)
stored_location_for(resource_or_scope) || spree.account_path
end

def respond_to_on_destroy
# We actually need to hardcode this as Rails default responder doesn't
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to after_sign_out_redirect(resource_name) }
end
end

def after_sign_out_redirect(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
router_name = Devise.mappings[scope].router_name
context = router_name ? send(router_name) : self
context.respond_to?(:login_path) ? context.login_path(locale_param) : spree.root_path
end
end
15 changes: 13 additions & 2 deletions lib/spree/auth/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ def self.activate
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
Rails.configuration.cache_classes ? require(c) : load(c)
end
if Spree::Auth::Engine.checkout_available?
Dir.glob(File.join(File.dirname(__FILE__), "../../controllers/checkout/**/*_decorator*.rb")) do |c|
Rails.configuration.cache_classes ? require(c) : load(c)
end
end
if Spree::Auth::Engine.backend_available?
Dir.glob(File.join(File.dirname(__FILE__), "../../controllers/backend/*/*/*_decorator*.rb")) do |c|
Rails.configuration.cache_classes ? require(c) : load(c)
Expand All @@ -45,11 +50,12 @@ def self.activate
Rails.configuration.cache_classes ? require(c) : load(c)
end
end

ApplicationController.send :include, Spree::AuthenticationHelpers
end

def self.api_available?
@@api_available ||= ::Rails::Engine.subclasses.map(&:instance).map{ |e| e.class.to_s }.include?('Spree::Api::Engine')
def self.checkout_available?
@@checkout_available ||= ::Rails::Engine.subclasses.map(&:instance).map{ |e| e.class.to_s }.include?('Spree::Checkout::Engine')
end

def self.backend_available?
Expand All @@ -68,6 +74,11 @@ def self.emails_available?
@@emails_available ||= ::Rails::Engine.subclasses.map(&:instance).map{ |e| e.class.to_s }.include?('Spree::Emails::Engine')
end

if checkout_available?
paths["app/controllers"] << "lib/controllers/checkout"
paths["app/views"] << "lib/views/checkout"
end

if backend_available?
paths["app/controllers"] << "lib/controllers/backend"
paths["app/views"] << "lib/views/backend"
Expand Down