ECサイトにブログ追加(EC-CUBE3とWordPressの連携)
更新日:2019/09/11
EC-CUBE3とWordPressの連携を行いたい場合の設定について纏めました。
EC-CUBEをメインに構築している環境を対象にしています。
共存について
EC-CUBE側でWordPressの内容を読み込む場合
WordPress側でEC-CUBEの内容を読み込む場合
共存について
「.htaccess」の設定
EC-CUBEのフレームワークが割と強めなため、普通に「wordpress」というフォルダを作ってそこにWordPressを置いても動きません。
共存のために、EC-CUBE側の「.htaccess」で「wordpress」フォルダ以下をEC-CUBEの直接管理下から外す作業が必要です。
以下のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
... RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !^(.*)\.(gif|png|jpe?g|css|ico|js|svg)$ [NC] RewriteRule ^(.*)$ index.php [QSA,L] ... ↓ ... RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !^(.*)\.(gif|png|jpe?g|css|ico|js|svg)$ [NC] RewriteCond $1 !^(wordpress/) RewriteRule ^(.*)$ index.php [QSA,L] ... |
これでEC-CUBE、WordPress、どちらも動くようになります。
EC-CUBE側でWordPressの内容を読み込む場合
WPの読み込み
WPは、フォルダの外から利用することも想定して便利な作りになっています。
「wordpress」フォルダの直下にある「wp-load.php」を読み込めば良いだけです。
1 |
require_once(__DIR__ . '/【任意のパス】/wordpress/wp-load.php'); |
変数取得
読み込みが完了すれば、WPの関数を自由に使えるので、投稿内容などを取得してカスタマイズします。
例えば、最新の投稿5件を取得するには以下でOKです。
1 |
$latest_posts = get_posts(); |
twigファイルに渡して表示
EC-CUBEは表示部分はtwigファイルで行っていますので、レンダリング時に変数を渡してあげる必要があります。
1 2 3 4 5 |
return $app->render('index.twig', array( 'latest_posts' => $latest_posts ) ); |
例:カスタム投稿「news」を5件表示する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$latest_posts = array(); $args = array( 'post_type' => array('news'), 'post_status' => 'publish', 'posts_per_page' => 10 ); $the_query = new WP_Query($args); if($the_query->have_posts()): while ($the_query->have_posts()) : $the_query->the_post(); $latest_posts[$post->ID] => array( 'id' => $post->ID, 'title' => get_the_title(), 'permalink' => get_the_permalink(), 'description' => mb_strimwidth(strip_tags(get_the_content()), 0, 100, "…", "UTF-8"), ); endwhile; endif; |
1 2 3 4 5 6 7 8 |
{% for post in latest_posts %} <div class="wp-post"> <a href="{{ post.permalink }}"> <div class="title">{{ post.title }}</div> <div class="description">{{ post.description }}</div> </a> </div> {% endfor %} |
実際は、『カスタム投稿「news」を5件表示するブロック』を作って対応することになると思います。
WordPress側でEC-CUBEの内容を読み込む場合
EC-CUBEの読み込み
EC-CUBEもフォルダ外から読み込めるようにはなっています。
しかし、あくまでもフォルダ外に「EC-CUBEのトップ」を置くため、と理解しています。
ですので、読み込んだから自由自在に関数を使えるかというとそうでもない気がしています(わたしの認識不足のため、実際は出来るかもしれませんが・・・)。
1 2 3 4 5 |
require_once ( __DIR__ . '/【任意のパス】/autoload.php'); $app = \Eccube\Application::getInstance(array('output_config_php' => false)); $app->initialize(); $app->initializePlugin(); $app->boot(); |
この最後の「boot();」の部分を「run();」に変えればEC-CUBEの関数を自由に使えるのですが、「run();」にするとレンダリングまで走ってしまい、EC-CUBE側の画面表示がされてしまうので悩ましい部分です。
でも「boot();」の実行だけでもEC-CUBE側の色々な情報を取得できます。
内容取得
例えばカテゴリーの取得。
1 2 |
$Categories = $app['eccube.repository.category']->getList(); dump($Categories); |
例えばカート内の商品の取得。
1 2 3 4 |
$Cart = $app['eccube.service.cart']->getCart(); foreach ( $Cart['CartItems'] as $item ) { dump($item); } |
ログイン情報周りの取得
大体のところは思った通りに出来たのですが、ログイン判定周りがだいぶ苦戦してしまいました。
上記で示した「boot();」で自由に関数が使えない、というのはこのログイン周りです。
ログインしているかどうか、ログインしているユーザー情報、これらが取得できませんでした。
1 2 3 |
if ( $app->isGranted('ROLE_USER') ) { print 'ログイン成功'; } |
上記の処理を実行するとエラーが出てしまいます。
1 |
Fatal error: Uncaught Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException: The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. |
エラー内容から推察するにEC-CUBEの「firewalls」の設定が問題なのだと思うのですが、いろいろ試しましたがダメでした。
ログイン情報取得に必要なトークンがそもそも取得できていません。
EC-CUBEの外側への引き渡しが制限されているものなのかもしれません。
以下の方法でなんとか対応は出来るようにしましたが、もっとスマートな方法がある気がします。
対応方法
EC-CUBE側でログインしたら、その情報をセッションに格納し、WP側でそのセッションを取得する、というやり方で対応しました。
1 2 3 4 5 6 |
if ( $app->isGranted('ROLE_USER') ) { $_SESSION['ec_wp_user_login_flg'] = 1; } else { $_SESSION['ec_wp_user_login_flg'] = 0; } |
1 2 3 4 5 6 |
if( $_SESSION['ec_wp_user_login_flg'] === 1 ) { print 'ログインしています'; } else { print 'ログインしていません'; } |
ちなみに、WPでセッションを利用するには以下のようにします。
1 2 3 4 |
add_action('init', 'my_session_start'); function my_session_start(){ session_start(); } |
例:最新の商品情報を3件表示する
1 2 3 4 5 6 7 8 9 10 |
$qb = $app['eccube.repository.product']->getQueryBuilderBySearchData(array()); $pagination = $app['paginator']()->paginate($qb, 1, 3); foreach ($pagination as $Product) { ?> <div class="eccube-item"> <div class="name"><?php print $Product['name']; ?></div> <div class="price"><?php print number_format($Product->getPrice02IncTaxMin()); ?>円</div> </div> <?php } |
南本貴之