EC-CUBE3でログイン成功時に直前まで見ていた画面へ戻る方法

EC-CUBE3ではログインする場合、EC-CUBE2とは違いログイン画面を経由させる必要があります。

また、ログイン成功後は必ずサイトのトップページへ戻ってしまいます。

サイトの作りにもよりますが、例えばログイン後は前に見ていた画面を表示して欲しいという要望があった場合、 以下のカスタマイズを行うことで実現可能となります。

EC-CUBE3.0.14を対象に説明します。

まず、MypageControllerにあるlogin関数を修正します。

  • src/Eccube/Controller/Mypage/MypageController.php
/**
 * ログイン画面.
 *
 * @param Application $app
 * @param Request $request
 * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
 */
public function login(Application $app, Request $request)
{
    if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
        log_info('認証済のためログイン処理をスキップ');

        return $app->redirect($app->url('mypage'));
    }

    /* @var $form \Symfony\Component\Form\FormInterface */
    $builder = $app['form.factory']
        ->createNamedBuilder('', 'customer_login');

    if ($app->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
        $Customer = $app->user();
        if ($Customer) {
            $builder->get('login_email')->setData($Customer->getEmail());
        }
    }

    $event = new EventArgs(
        array(
            'builder' => $builder,
        ),
        $request
    );
    $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_MYPAGE_MYPAGE_LOGIN_INITIALIZE, $event);

    $form = $builder->getForm();

    // ログイン前の画面へ戻す
    $error = $app['security.last_error']($request);
    if (!$error) {
        // ログインエラーがなければ戻り先をセット
        $referer = $request->headers->get('referer');

        if ($referer) {
            // refererチェック
            $referers = parse_url($referer);
            if ($referers['host'] == $request->getHost()) {
                // ホストが同一であればrefererをセット
                $requestStackUri = $app['request_stack']->getMasterRequest()->getUri();

                if ($request->getUri() == $requestStackUri) {
                    // ログイン画面遷移直前のuriをセット
                    $app->setLoginTargetPath($referer);
                } else {
                    // ログイン必須画面のuriをセット
                    $app->setLoginTargetPath($requestStackUri);
                }
            }
        }
    }

    return $app->render('Mypage/login.twig', array(
        'error' => $error,
        'form' => $form->createView(),
    ));
}

修正箇所は、

// ログイン前の画面へ戻す
$error = $app['security.last_error']($request);
if (!$error) {
    // ログインエラーがなければ戻り先をセット
    $referer = $request->headers->get('referer');

    if ($referer) {
        // refererチェック
        $referers = parse_url($referer);
        if ($referers['host'] == $request->getHost()) {
            // ホストが同一であればrefererをセット
            $requestStackUri = $app['request_stack']->getMasterRequest()->getUri();

            if ($request->getUri() == $requestStackUri) {
                // ログイン画面遷移直前のuriをセット
                $app->setLoginTargetPath($referer);
            } else {
                // ログイン必須画面のuriをセット
                $app->setLoginTargetPath($requestStackUri);
            }
        }
    }
}

return $app->render('Mypage/login.twig', array(
    'error' => $error,
    'form' => $form->createView(),
));

になります。ログイン前のrefererを取得し、ログイン成功時に直前まで見ていた画面へ戻すようにしています。ただし、ログインが必要な画面を直接指定された場合、refererを取得するとログインに成功してもrefererで指定した画面に遷移してしまうため、

$app['request_stack']->getMasterRequest()->getUri()

と本来指定されているURLを取得し、比較する事でログイン成功後の遷移先を変更するようにセットしています。

refererが取得できない環境は諦めてください。

あと、login.twigも変更する必要があります。以下抜粋です。

  • src/Eccube/Resource/template/default/Mypage/login.twig
{% if app.session.flashBag.has('eccube.login.target.path') %}
    {% for targetPath in app.session.flashBag.peek('eccube.login.target.path') %}
        <input type="hidden" name="_target_path" value="{{ targetPath }}" />
    {% endfor %}
{% endif %}

こちらの変更箇所ですが、

{% for targetPath in app.session.flashBag.peek('eccube.login.target.path') %}

の部分となり、getからpeekへと変更しています。なぜpeekに変更しているかというと、ログインエラー時にセットされていたtargepathの値が削除されてしまいますので、peekに変更しています。

以上の対応でログイン成功後は、直前まで見ていた画面へ遷移するようになります。

必要な方には必要なカスタマイズだと思います。特にスマホだとログイン後にトップページへ遷移してしまうと離脱されてしまう可能性が高くなりますのでこちらを是非活用してください。