だ。ログ。

開発とかスノボとかやきうとか。

EC-CUBE3にエディタをインストールする

どうしてもECサイトの運営はhtmlタグは怖いって言う人が多い。
エディタとか入れれない?と言うオーダーは結構来る。
一番簡単なのはckEditor、EC-CUBEにかぎらず自分はコレを入れる事が多い。
Wysiwygプラグインwww.ec-cube.net
が無料であるので、改造するのが怖い人はプラグインで対処すると良い。
ちょっと手を加えられる人は好きな所にエディタを入れられるので使い勝手は良い。

1. ckEditorをダウンロードする

https://ckeditor.com/ckeditor-4/download/ 好きな奴をダウンロードして解答する

2. 解凍してアップロードする

/html/user_data/js/ckeditor/ にアップロード

3. 管理画面 > 商品管理にckeditorを認識させる

/src/Eccube/Resource/template/admin/Product/product.twig

# {% block javascript %} 内に記述する
<script type="text/javascript" src="/user_data/js/ckeditor/ckeditor.js"></script>
<script type="text/javascript">
	CKEDITOR.replaceAll('useEditor');
</script>

これでckeditor自体の認識は完了する。今度は入力要素にuserEditorを設定する。

/src/Eccube/Form/Type/Admin/ProductType.php

#設定したい要素に以下を追加
                'attr' => array(
                    'class' => 'useEditor'
                ),

classを直接指定すると、EC-CUBE準拠のClassが無いと怒られるのでattrでclassを指定する。
複数指定する事を想定するとclassにしておけば名前がかぶる事がない。

あとは管理画面 > 商品管理 > 商品登録 から設定した要素を確認すれば、ckEditorに変更されている事が確認出来る。

EC-CUBE3で既存入力項目の入力不可を実装する

個人情報変更でよく使う手段として、メアドとパスワードは一旦登録したら変更出来ないようにしたい。
という事もあるので、html要素にdisabledを入れて入力制御する。
パスワード変更を不可にしてみる。

/src/Eccube/Form/Type/Front/EntryType.php

#変更前
	->add('email', 'repeated_email')
#変更後
	->add('email', 'repeated_email', array('disabled' => true,))

attrで指定するのかそのまま要素かはsymfony2のリファレンスを観なければならないが、disabledはそのまま指定できた。

今週のお題「行ってみたい場所」

今週のお題「行ってみたい場所」

雪山で考えてみる
これまでで訪れた事のあるゲレンデ

秋田県

田沢湖: 高校の修学旅行がスキーだった。元々滑れたから上級コースで教官と遊んで終わりだったのを思い出す。

栃木県

ハンターマウンテン塩原: 2017年シーズンバスツアーにて。とにかく麓のゲレンデは混む。ファミリーゲレンデなので家族はオススメ。
あとバスツアーなのに時間守らないDQNが居て帰りが遅くなった。集団行動しない=カッコイイと考える人が居ると地雷確定。

群馬県

尾瀬岩鞍: 1990年代初頭に友達の家族に連れて行ってもらった。春休みで地獄のベタベタの重い雪だった。
尾瀬戸倉: 2005年くらいに来訪。カラッカラの雪だった。2月のトップシーズンだと最高。

新潟県

湯沢中里: 2017年シーズン3月で雪がやや重め。コースレイアウトが横に広く人が分散する。長くは滑れない。
石打丸山: 越後湯沢からバスで10分、レストハウスも多く立地最高。ただし雪質は大当たりかうーんこの。か両極端。
ガーラ湯沢: 石打丸山のコンディションは変わらない。カップル率高し。独り者の自分には眩しすぎる。
神立高原: メインゲレンデに人が集まった時の混雑は結構辛い。上級コースが多くホームの人が多い印象。
かぐらみつまた・田代: 猛吹雪にあった。雪質は苗場と同じく高い。コースが広すぎな事とインフォメーションが少ないから迷う。
上越国際: 雪が降りすぎてフェンスが消えていた。山を跨ぐリフトが止まりリフト下を行軍した思い出がある。

長野県

斑尾高原: すり鉢状の中央ゲレンデがやたら混む。そして帰りはそのリフトに乗らないと坂道をあるく。上級コースが難しい。
野沢温泉: 日帰り、宿泊としている。フードのレベルが高い。平日は特に欧米人だらけ。夜酔っぱらった外人が叫んでる。うるさい。
赤倉温泉: 1990年代末は人が居ない、コース数多い、雪質よしだった。15年行っていないので行ってみたい。
戸狩温泉: 昨シーズンラスト、雪が重かった。珍しいコースレイアウトをしているが楽しい。
霧ヶ峰スキー場: コース数3つ!スキーの基礎を教えてもらったゲレンデ。長生きして欲しい。
車山高原: 縦に長いコースでスピードが出た印象。お正月だったので人も少なく楽しめた。

山梨

富士天神平: 国民休暇村に行ったついでにスキー体験をした。自分の初めての雪山体験だった。


んで、行ってみたい所。

山形県

蔵王温泉: 去年予定はあったものの頓挫。スキーヤーの聖地、一度は行きたい。

新潟県

岩原: 越後湯沢駅の新幹線ホームの看板の「上国/岩原」を観て行こう行こうと思い行っていない。今年は行きたい。

群馬県

谷川岳天神平: 上毛高原を攻める時期かなと。標高の高さで雪質がどれだけ変わるかを感じたい。
川場: ボーダーの聖地、そう言えばいったことない。

新潟県

白馬: こちらも行こう行こうとは思うものの新幹線だとなかなかプランが無い状況。泊まりでいってみたい。
菅平: 真田丸ブームで行くか!と思っていたが、こちらも縁がなく。昔からパンフで一面に来る程の名門。いってみたい。
志賀高原: 天空のスキー場、雪質の良さコースの豊富さ、そして極寒。一度は行きたい!
竜王スキーパーク: 雲海が見たい!

行ってみたい所は多いけど、時間見付けてコツコツ行くしかなさそうなサラリーマンサンデーボーダーの悲しいサガ。

EC-CUBE3のブロックに動的要素を与える

EC-CUBEの強みの一つはパーツをブロック毎に作り、どのページにもはめ込む事が視覚的に出来る。
結構要望として貰う例として、ヘッダ部分に永続的に現在何個の商品が入っているか。と言う事を出したいと言う要望が多い。
特にデフォルトのEC-CUBEのパーツを一旦すべて抜いた上でヘッダを新しく作った際に既存のパーツを組み込む事を想定していないと言う事が多い。
デザイン会社さんにEC-CUBEフレームワークに準じた形で。と言って納品してくれる所も少ないだろう。

ただ、Symfony2の仕様から「ページ全体」に変数を登録するのではなく、パーツ毎に変数を登録しなければならない。
ぶっちゃけるととか使えるようにしようよ。。と思う。
この辺をフレームワークに変更しているのは、魔改造が過ぎてロックオンさんにどないなっとんのじゃ!と言う質問が多かったからあまり触らせたくないのかな。と邪推したり。
今回はヘッダに動的要素を組み込む。

1. コントローラーとしてヘッダブロックを認識させる
/src/Eccube/ControllerProvider/FrontControllerProvider.php

## 73行目あたり
        // block
        $c->match('/block/category', '\Eccube\Controller\Block\CategoryController::index')->bind('block_category');
        $c->match('/block/cart', '\Eccube\Controller\Block\CartController::index')->bind('block_cart');
        $c->match('/block/search_product', '\Eccube\Controller\Block\SearchProductController::index')->bind('block_search_product');
        $c->match('/block/news', '\Eccube\Controller\Block\NewsController::index')->bind('block_news');
        $c->match('/block/login', '\Eccube\Controller\Block\LoginController::index')->bind('block_login');
## ヘッダを追加する ##
        $c->match('/block/header', '\Eccube\Controller\Block\HeaderController::index')->bind('block_header');

これでコントローラを利用してヘッダブロックに動的変数を組み込む為の準備は出来た。
今度はコントローラを作成する。コントローラ自体は他のモノをコピれば良い。自分はCartController.phpをコピーした。
コントローラにCart変数をセットする。

2. header用コントローラの作成
/src/Eccube/Controller/Block/HeaderController.php

namespace Eccube\Controller\Block;

use Eccube\Application;

class HeaderController
{
    public function index(Application $app)
    {
        /** @var $Cart \Eccube\Entity\Cart */
        $Cart = $app['eccube.service.cart']->getCartObj();
        return $app->render('Block/header.twig', array(
            'Cart' => $Cart,
        ));
    }
}

これでヘッダーへの変数を設定する事ができた。
あとは、renderで指定したテンプレートに現在のカートの商品数を表示させる。
/app/template/default/Block/header.twig

{% if Cart.total_quantity == 0 %}
現在カートに商品はありません
{% else %}
現在カートには{{ Cart.total_quantity }}つの商品が入っています
{% endif %}

いちいちコントローラを作ってそこ変数を登録してと言う事が必要なので非常に面倒くさい。
そして、PHPを齧った事さえあればちょちょいと修正出来ると言う敷居を大きく上げた。
言ってしまえば、かじった程度でお金が絡むシステムを気軽に修正するのは怖いよと言う意思表示に感じられる。

サイトの強制SSL

Let's Encryptが広まり始め、ウチもサイトSSL対応したい!と言うサイトも多くなってきた。
.htaccessで強制的にSSLにリダイレクトするのが手っ取り早い。

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

ただし、SSLTerminationとか使ってると443ではなくなるので注意。
って言うかそこまでの技術があるなら、最初からSSLを視野に設計してると思うからあまり意味がないかも。

EC-CUBE3がELB配下のEC2サーバーにある場合の管理ページのアクセス制限を行う

かなり限定的な構成ではあるがELBの下にEC2にEC-CUBE3がインストールされている。
しかもELBにSSLをインストールしているSSL Terminationを利用している場合
そのままEC-CUBEをインストールし、管理画面のアクセス制限をしてもアクセス制限が出来ない。

過去の記事にも掲載したが、一旦ELBを経由しEC2に到達するのでアクセス元はELBのIPアドレスになるのだ
index.phpで$_SERVERをダンプする

[REMOTE_ADDR] => ELBのIPアドレス

と出てしまっている。
この為、ELBのIPアドレスを許可するとELB経由のアクセスは許可=全許可と言う事で意味がない。
しかしREMOTE_ADDRを他のモノに変えるとどこでどう使っているかが不明な為、あまりコレをいじるのはよろしくない。と言う事で以下

/src/Eccube/Application.php

                if (count($allowHost) > 0) {
                    if (array_search($app['request']->getClientIp(), $allowHost) === false) {
                        throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();
                    }
                }

この getClientIpはREMOTE_ADDRを取得しに来ている。
そして、ここで許可ホストに一致しなければエラーに飛ばすと言う処理を行っているので以下に変更

		$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (count($allowHost) > 0) {
                    if (array_search($realip, $allowHost) === false) {
                        throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();
                    }
                }

リアルのIPアドレスはどれよ。って事を$_SERVER変数から確認し、そのIPアドレスに判定を書き換える。
多分EC-CUBESSL Terminationを想定していない造り、って言うかそう言う使い方するもんじゃねーからコレ。と言われかねないが
ELB経由のEC2でEC-CUBEを使う人がハマる所かと。

EC-CUBE3のindex_dev.phpで出る変数 is not definedの消し方

これはtwigに設定された変数すべてに言えるのだが、変数が未定義で同一のテンプレートを使った場合によく見かける。
別にエラーではないし、他にデバッグしたい事があるのに、index_devでこのエラーを指摘されてよくイラつく。

例 コントローラ

        return $app->render('Hoge/fuga.twig', array(
		'hogehoge' => $hoge,
        ));

この$hogeが明示的に設定されていれば問題にならないが、PHPの性質上未定義でもエラーになる事がないので$hogeの有無に関してを制御する事はない。
もっと言えば変数$hogeを全ページに設定するのはもっと面倒くさい。
と言うワケでテンプレートをに以下の判定を入れる。

{% if hoge is defined %}
{% endif %}

hogeと言う変数が定義されていれば」と言う条件を加える事で、未定義の場合は処理をスキップする。
index_dev.phpを利用してのデバッグ時に is not definedはこれで解決できる。