2014年9月24日水曜日

EC-CUBE クローズ化サイトプラグインを作成(後編)

前編(リンク)で、クローズ化サイトプラグインを作成するための準備を整えましたので、後編では一気に完成させたいと思います。

[全ステップ]
1.プラグイン作成の準備 > 前編で対応
2.常に動作する処理の実装 > 前編で対応
3.クーロズ化に必要なパターンへの対応

では、最後のステップ
3.クーロズ化に必要なパターンへの対応
を行って、完了させましょう!!

とは言え、クローズ化に必要なパターンって一体なんだろうとなりますね。

・会員はアクセスできる必要があるけど、非会員はアクセスできてはダメ。

は必要そうですが、
非会員でも、ログイン画面にはアクセスできる必要がある。
メールとかで、ログイン情報が通知されるのなら良いですが、会員登録ができないとクローズ過ぎるサイトですし。。

管理画面は、普通にアクセスしたいってのもありますね。

考えだすと色々なパターンがありそうなのですが、今回はシンプルに、次のパターンで進めたいと思います。

  • TOPページは誰でもアクセス可能
  • 非会員は、会員登録画面・ログイン画面にアクセス可能。それ以外のページはTOPページへリダイレクト
  • 会員はアクセス可能
  • 管理画面はアクセス可能

どれからやっても良いですが、「管理画面はアクセス可能」から対応したいと思います。
問題になってくるのは、今表示されようとしている画面が管理画面かどうかを、どうやって判断するかになってくると思います。

[Q.現在のページが管理画面かどうかを判断するには?]

その疑問を解くヒントは引数部分にあります!!

LC_Page $objPage

ですね。
これにページの情報が詰まってますので、これを使って、ページを判断したいと思います。

function preProcess(LC_Page $objPage) {
if (strstr(get_class($objPage), "Admin") != "") {
// 管理画面のためアクセスOK
return;
}
}

幸い、管理画面のページ(のクラス)には全て「Admin」がはいっておりますので、それを利用してAdminかどうか判断をしています。
と、言ってもこのままでは本当に上手くいているか確認できませんので、もう1文追加します。

function preProcess(LC_Page $objPage) {
if (strstr(get_class($objPage), "Admin") != "") {
// 管理画面のためアクセスOK
return;
}

header('Location: ' . TOP_URLPATH);
exit;
}

これで実行すると、管理画面以外はTOPページへリダイレクトされます。
いや、され続けて永久ループします。(ダメじゃん)


ですので、TOPページはTOPページへリダイレクトさせないようにします。

function preProcess(LC_Page $objPage) {
if (strstr(get_class($objPage), "Admin") != "") {
// 管理画面のためアクセスOK
return;
}

if (TOP_URLPATH == $_SERVER["REQUEST_URI"]) {
// TOPページはリダイレクトしない
return ;
}

header('Location: ' . TOP_URLPATH);
exit;
}

これで、管理画面側は普通に見れて、フロント側はTOPページへ遷移します。
と言いたいとこですが、管理側ページで上手く表示されないページがあります。
どこでしょうか?


正解は、


 


オーナーズストア>モジュール管理>モジュール一覧
です。


このページのクラスには「Admin」がついていないためです。
改善してみます。

function preProcess(LC_Page $objPage) {
if (strstr(get_class($objPage), "Admin") != ""
|| strstr(get_class($objPage), "Upgrade")) {
// 管理画面のためアクセスOK
return;
}

if (TOP_URLPATH == $_SERVER["REQUEST_URI"]) {
// TOPページはリダイレクトしない
return ;
}

header('Location: ' . TOP_URLPATH);
exit;
}

Upgrade」も許可してやれば、「モジュール一覧」へアクセスできるようになります。


同じ要領で、ログインと会員登録・パスワードリマインダーあたりをリダイレクトさせないようにすれば、良さそうですが、その前に「会員はアクセス可能」を追加しておきたいと思います。


この処理を追加すればOKです。

$objCustomer = new SC_Customer_Ex();
if($objCustomer->isLoginSuccess(true)) {
// 会員はアクセス可能
return ;
}

上記のコードを追加すると全体は

function preProcess(LC_Page $objPage) {
if (strstr(get_class($objPage), "Admin") != ""
|| strstr(get_class($objPage), "Upgrade")) {
// 管理画面のためアクセスOK
return;
}

if (TOP_URLPATH == $_SERVER["REQUEST_URI"]) {
// TOPページはリダイレクトしない
return ;
}

$objCustomer = new SC_Customer_Ex();
if($objCustomer->isLoginSuccess(true)) {
// 会員はアクセス可能
return ;
}

header('Location: ' . TOP_URLPATH);
exit;
}
こんな感じですね。

では、今度こそフロントの必要なページを許可してやります。

function preProcess(LC_Page $objPage) {
if (strstr(get_class($objPage), "Admin") != ""
|| strstr(get_class($objPage), "Upgrade")) {
// 管理画面のためアクセスOK
return;
}

if (TOP_URLPATH == $_SERVER["REQUEST_URI"]) {
// TOPページはリダイレクトしない
return ;
}

$objCustomer = new SC_Customer_Ex();
if($objCustomer->isLoginSuccess(true)) {
// 会員はアクセス可能
return ;
}

$filename = $objPage->arrPageLayout['filename'];

// 許可するページを指定
$arrAccessPage = array(
'mypage/',
'entry/',
'login',
''
);

foreach($arrAccessPage as $pagename) {
if (strstr($filename, $pagename) != "" || $filename == $pagename) {
return;
}
}

header('Location: ' . TOP_URLPATH);
exit;
}

完成です!!


これで、マイページ・会員登録・ログイン以外へは非会員はアクセスできないクローズ化の完成です。


ちなみに、許可するページのarrayを設定する際に、'' があるのは、ログイン時の処理「LC_Page_FrontParts_LoginCheck」では、arrPageLayoutが設定されないのを回避するための指定になります。


上記のクローズ化では非会員が見れるものをかなり限定しておりますが、「当サイトについて」「お問い合わせ」は見せたいという場合は、「$arrAccessPage」に「abouts」「contact/」を追加するだけで、簡単に対応が可能です。


また、今回は許可するページをソースコードに直書きしてますが、定数(パラメータ)に移動させたり、DBに保持したりすれば、アイデア次第で結構汎用性のあるクローズ化サイトプラグインができるのではないでしょうか?


今回、プラグインを作っている間に色々とプラグインのネタを思いつきましたので、このブログで作っていけたらと思います。


今日のプラグインの完成版はこちらです。

2 件のコメント:

  1. コメント失礼いたします。
    こちらのプラグインを参考にさせていただいたのですが
    クローズ化にならないのですがお教授いただけますでしょうか?
    ver.2.13.5です

    返信削除
    返信
    1. コメントありがとうございます。
      記事を書いた際、2.13.2で試していたので、2.13.5の環境を作成し、サイトの「完成版」を入れてみたのですが、一応動いてそうですので、具体的にどの部分が動かない等を頂けましたら、サポートさせて頂けるかもしれません。

      全く動かないということでしたら、「preProcess」の部分が呼ばれているかから、ご確認頂くと良いかと思います。

      削除