だ。ログ。

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

そのいいねって幾ら貰えるんスか?

転職サイトに事実無根投稿、投稿者名開示を命令
https://headlines.yahoo.co.jp/hl?a=20170822-00050148-yom-soci

積年の恨み辛み、会社への不満。このご時世転職のひとつやふたつ。ってな業界で仕事をしているので、どうしても転職サイトや口コミって言うのは判断する材料の一つとしては見る。
IT屋さんの場合はどちらかと言えばオープンな企業も多く、自ら会社がこんな所ですよ。と言うブランド力として発信している所も多い。
一昔前は転職サイトに載っている情報だけが頼り、たまたま出会えたエージェントさんがその企業に明るい人でアレコレと教えてくれる。と言う事もあったが、基本的にはブラックボックス
そう言う意味では、転職の際に受け身になって転職出来れば良い。と言う考え方で企業に何を求めるかと言う事を見失い、結局転職したけど環境は寧ろ悪化する。ってな体験もした。

一握のネガティブと大々的なポジティブ

企業と言うイメージ、ブランドと言う観点からすると根も葉もない噂を立てられ、売り手市場の現在では企業側の「不利」なイメージは避けたい。
だからこそ「明るい職場」とか「笑い声が絶えない」とか「社員全員が家族みたいな」と言う昔からの常套句は、裏が有ると見てしまう。

笑い声が絶えない = 会社内が喧騒としていて集中出来る環境じゃねえんじゃね?
社員全員が家族みたい = 家族の為に尽くすのは当たり前だから土日の社内イベントは強制参加だけど「自主的」にやってるだけで代休なしね。と言う都合の良い解釈の仕方だけ押し付けてるんじゃね?

ヘソが曲がっているだけなのだが、過度に「個」に干渉して欲しくない。これに尽きると思う。
ひとつまみのネガティブを情報として確認すると、先程まで見ていたポジティブさは裏の有るポジティブじゃないかと言う疑心暗鬼に変わる。
そして上述した言葉尻から邪推をはじめる。そして2ちゃんなり転職系サイトでのネガティブ収集をはじめる。

結局の所、火のないところに煙は立たない。煙が立っているのだから何かしらの禍根は有る。
ただ、それが個人的な逆恨み的なモノか、相対的に見たネガティブな意見なのかは個々の判断になる。

一時期はFacebookで投稿したモノをいいねして下さいと言う回覧が回っていた時期もあった。
結局のところ、企業としての発信力はその程度のもので個々に半強制的に拡散させる。
そこに本当に「いいな」って言う環状はない。
広報の数値目標の為のいいね、個人的な影響力の誇示の為のいいね。
情報発信の草の根的なモノとして個人アカウントからいいねを押してね。と言う会社への忠誠度を試す踏み絵を行う。
結局はソーシャルで会社の事を言うな!と言う通達は出るが、会社が発信したいポジティブな情報に関しては拡散しろと言う。

実名を必要としない時代とは違い、Facebookなどソーシャルを介した場合、関連している人や考え方から個人を辿られる可能性がある。
個人のネットすらもビジネスに直結する時代、人のしがらみを気にせず、自分が誰かと言う事を考えずに文章が書けるブログに帰依した。
多分おっさんが心地良い距離と言うのは、前述した通り過度に「個」に干渉しない事と「個」に干渉して欲しくないと言う事だとこの頃思う。

EC-CUBE3で値引きをする

一番てっとり早いのは無料プラグインで配布されているクーポンコードプラグインを利用する。
→ https://www.ec-cube.net/products/detail.php?product_id=1069
ロックオンが作っているのでまず間違いがない。無料、大半はこれで事足りてしまう。

ただし、これはコードを入れると言う事をユーザーにさせなければならない為、値引きに1アクションを使う事が嫌だ。と言う人も中には居る。
じゃあどうすればコードとして値引きが出来るのか。と言う事を追ってみた。

/src/Eccube/Resource/template/default/Shopping/index.twig

##342行目から
                        {% if Order.discount > 0 %}
                        <dl id="summary_box__discount_price">
                            <dt>値引き</dt>
                            <dd>{{ (0 - Order.discount)|price}}</dd>
                        </dl>
                        {% endif %}

$Orderの中身にdiscountと言う変数で「値引き」を設定している。
と言う訳で、値引きに金額を入れてみる。
/src/Eccube/Controller/ShoppingController.php

##125行目
        // form作成
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);

        $event = new EventArgs(
            array(
                'builder' => $builder,
                'Order' => $Order,
            ),
            $request
        );

ページへの変数のセットをするこの上あたりに記述

$Order->setDiscount(1000);

この状態で表示を確認すると

小計    ¥ 12,345
手数料  ¥ 0
送料    ¥ 1,000
値引き  ¥ -1,000

合計 ¥ 13,345税込

ってな訳で、値引きには金額がセットされているが総計に対しての金額の再計算がされていない。

$discount = 1000;
$Order->setDiscount($discount);
$total = $total - $discount;
$Order->setTotal($total);

明示的に総計を再計算して$Orderにセットする。

小計    ¥ 12,345
手数料  ¥ 0
送料    ¥ 1,000
値引き  ¥ -1,000

合計 ¥ 12,345税込

と言う訳で値引き出来るようになった。
ただしこれは表示ページのみ。
同様の処理をconfirmの処理の中にも入れる必要があるので注意。
(記述だけだと表示だけなので、管理画面で確認した時に割引額と総計が変わっていない)

クーポンとの使い勝手の差は、個別商品の割引額を計算してソースコードに貼り付ける事が出来ること。
一律○%の割引等が出来る。ただし細かな設定や、割引額が大きすぎる場合、端数等の問題が有るのでこの辺をどう対処するかはやはりプラグインのロジックと言うのは練られているのでこの辺を考えたくなければクーポンの方が良いかと。

EC-CUBE3のCSVの新規出力データを作成し画面上でダウンロードできるようにする

CSVファイルで取り込んで連動する。多分今後もなかなかこの手法から脱却するのは難しいと思う。
各システムがその他の事を考えていないし、連動するシステムを想定した作りなんてしない。
だからCSVであればエクスポート可能だよーとしておけば、あとは運用側が創意工夫してなんとかしてね。となる訳で。
EC-CUBEにもCSVファイルを「作る」事は出来ても、項目を追加するのはちょっと手間が掛かる。

マスタデータの追加

設定 > システム情報管理 > マスターデータ管理を開き mtb_csv_type を選択する。
ここでCSVファイル出力用のプルダウンのデータを制御している。
IDには既存の数値とは被らないIDを入れ、Nameには好きな物を入れる。

設定 > 基本情報設定 > CSV出力項目設定を選択しプルダウンをクリックするとマスターデータで追加された項目が追加されている。
ただし問題は、CSV出力する項目が入力されていない。
ここからはSQLを利用する。

DBの流し込み

phpMyAdminを使うと簡単だが、まず設定項目に関してはdtb_csvに格納されている。
csv_idは自動採番なのであまり気にする必要はない。csv_typeはマスタデータで必要となるデータを入れる。
必要なデータはテーブル定義書あたりを参考にすると良い。マスタに既に入っているIDから出力するデータが何かと言う事自体は確認出来るので、それをコピーしてINSERT文を流し込む。
例) 1.商品(dtb_product) 2.会員(dtb_customer) 3.受注(dtb_order)

仮に会員データを取得したい場合はcsv_typeが2のデータを抽出し、マスターデータ管理で追加したIDに書き換えてINSERT文を実行。
csv_idは現在の最大値からネストした数値を割り振る。
新規マスターデータIDが6の場合はこんな感じ。

INSERT INTO `dtb_csv` (`csv_id`, `csv_type`, `creator_id`, `entity_name`, `field_name`, `reference_field_name`, `disp_name`, `rank`, `enable_flg`, `create_date`, `update_date`) VALUES
(999, 6, 1, 'Eccube\\Entity\\Customer', 'id', NULL, '会員ID', 1, 1, '2017-07-12 20:58:58', '2017-07-12 20:58:58'),

任意のページでCSVダウンロード出来るようにする。

間借りする形になるが、会員管理>会員マスター>CSVダウンロードに新たに今回のダウンロード項目を付け足し、管理画面からCSVダウンロード出来るようにする。

フックポイントの作成
/src/Eccube/ControllerProvider/AdminControllerProvider.php

#customerの部分に追加
#_customの部分は自分の好きな名前にしておく。
        $c->match('/customer/export_custom', '\Eccube\Controller\Admin\Customer\CustomerController::export_custom')->bind('admin_customer_export_custom');

イベントの作成
/src/Eccube/Controller/Admin/Customer/CustomerController.php

#public function export(Application $app, Request $request) をコピーする
#_customの部分はフックするポイントに合わせる。
    public function export_custom(Application $app, Request $request)
    {

        // タイムアウトを無効にする.
        set_time_limit(0);

        // sql loggerを無効にする.
        $em = $app['orm.em'];
        $em->getConfiguration()->setSQLLogger(null);

        $response = new StreamedResponse();
        $response->setCallback(function () use ($app, $request) {

            // CSV種別を元に初期化.
	  // ※※ここのinitCsvTypeを今回追加したcsv_typeの番号にする。
            $app['eccube.service.csv.export']->initCsvType(6);
	・
	・
	・
    }

テンプレートの追加
/src/Eccube/Resource/template/admin/Customer/index.twig

              <ul class="dropdown-menu">
                <li><a href="{{ url('admin_customer_export') }}">CSVダウンロード</a></li>
                <li><a href="{{ url('admin_setting_shop_csv', { id : constant('\\Eccube\\Entity\\Master\\CsvType::CSV_TYPE_CUSTOMER') }) }}">出力項目設定</a></li>
                <li><a href="/admin/customer/export_custom">カスタムCSVダウンロード</a></li>

ここまで設定すると、CSVダウンロードの項目にカスタムCSVがダウンロード出来るようになる。
項目は、設定>基本情報設定>CSV出力項目設定
で設定した物が出力されている事を確認。

細かいけど、こう言うカスタマイズって必要な物だから文献としてあって損は無いかなーと。

EC-CUBEにPOSTしたデータを取得する

他サイトとEC-CUBEの連動をしたい。特に要望として挙がるのはSSO関連部分。
ただ、EC-CUBEの仕様上セッションジャックやクロスサイトスクリプティングの問題からSSO自体はコアをいじれば出来るけど、相当手間が掛かる。
まずは第一段階として、他サイトからPOSTしたデータを受信して、EC-CUBEサイトからCSRFトークンを発行してログインさせれば。
って言う似非SSOで対処の為の調査。
そもそも他サイトからのPOSTデータ取れるの?って言う疑問もあった。
着地するページは任意だが、そのコントローラで以下のようにする。

$request->request->get('hoge');
$request->request->get('fuga');

$_POST['hoge'];
$_POST['fuga'];

を取り出す場合は上記のように記述すれば取得出来る。
とりあえず外部からのデータ受信をEC-CUBEで受信出来る事はOK
あとは特定のサイトからのPOSTで秘密鍵か何かを渡してページを表示するか否かをコントローラで判断するように設計すれば良い。

モンスター

クライアントがモンスターだと言う前に考えたい。
受注したチーム側がモンスターじゃないかと。

一つだけあらかじめ断っておく。
この文章は、異世界に転生した冴えない主人公が可愛い女の子とハーレムとなり世界を救う。
要はファンタジーだ。

(しようが)ないです。

相槌を打つ。とにかく相槌を打つ。どんなサイトですか?どう言うテイストですか?
ンなモノは二の次だ。お客様に適正な解決策の提案 <<<<<<<< 受注するための提案
と言う本末転倒な事になっている。
結局、じゃあ見積をお願いしようかな。となった時に出て来る材料は
「(ライバル社)と同じテイストで」
1時間なり2時間なり御用聞きをした結果がこの1行なのだ。
とても濃密で濃厚、この1行からサイトの構成、サーバーの用意、システムの構成、デザインのテイストを決定しなければならない。

もっと具体的に~と言うことを営業に言おうものなら
「しょうがないじゃないか!」

渡る世間は鬼ばかりである。

前にやってたじゃん

で、これでなんで出来るっつったんですか?
と言う質問の常套句である。
「だって、前にやってたじゃん」

やった、やりきった事に関して全てが平穏無事に済んだと言うハッピー回路に変換される。
何度となく怒号と怨嗟の会議をした事なんて忘れている。

放棄する

とは言え決まった事だ。全うするしかない。
しかし自分は結局はシステム屋だ、依頼主とは喋った事もない。コミュニケーションのとりようもない。
今までのやらかしからして、全てを壁打ちするだけだ。
いや、壁打ちで返すなら良いが勝手に言葉を付け加える。それも制作不利にさせる事だけは長けたスキルで。

質問をする。
その質問を最初は考える。だが答えは出ない。何故か?
考える事を放棄しているからである。売れたモノだから後は制作が勝手にやれよ。スタンスである。
あれだけ電話越しに質問質問した人間がまるで事済ませた後の賢者モードのように冷たい。
「んな事俺に聴くなよ、そう言うのは制作が決めて提案しろよ」

ただ、決めて提案しても予算は決まってしまっている。
提案するのは良いけど金勘定してくれと言っても受け付けられない。
結局は制作が折れるしかない。

提案の定義

解決策を提案する。
サラリーマンをしている以上、売上をあげてナンボである。
1円でも多く利益還元しなければならない、そして自分は売上をあげる事においてはパワプロで言えば赤スキルだ。
だからこそ営業さんに頼る、お金を稼ぐ働き口を下さい。と。
持ってくれば仕様ガー、要求ガー、工数ガーと言って素直に仕事をしない。
営業さんは四の五の言わずに受けてきてやった仕事なんだからやれよ。と思う。

もうそこに信頼関係は無い。有るのは全方向に売った喧嘩の禍根だけだ。
その禍根は、営業に反発するモンスター制作を生み出し、モンスター営業を生み出す。
チームとしては瓦解に近い。

お互いが歩み寄る為に必要な事はなんだろう。と常々思うようになってきた。

EC-CUBE3購入画面の文字化け

EC-CUBE3の支払い方法部分の改造をしていた時のこと。

  1. 商品をカートに入れる
  2. ログイン/非ログインで操作を続ける
  3. 支払い方法ページを表示する

ここにjsで任意の文字列を表示させようとした際に、jsのデバッグの為にソースコードを開くと文字列が全てURLエンコード変換されていて「日本語」として確認する事が出来ない。
そのままjsの

alert("こんにちは、お昼ごはんです");

を実行すると「こんにちは、お昼ごはんです」が全て文字化けしてしまう。

%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E3%80%81%E3%81%8A%E6%98%BC%E3%81%94%E3%81%AF%E3%82%93%E3%81%A7%E3%81%99

こんなかんじ。


文字列自体はエンコードされていて、ブラウザで表示すると「日本語」として解釈されているがjsは文字列が解釈されない。

解決策

明示的にmetaタグにエンコードタイプを記述する。

/src/Eccube/Resource/template/default/default.twig 41行目

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

明示的にUTF-8ですよ。と宣言する。
サーバーやシステムの仕様上エンコードが違う場合はcharsetを変更する。

EC-CUBE3のリファラの取り方

まず最初はセッションを使って、一旦ランディングページにアクセスしたか?
と言う事を記録して、それによってページの要素の出し分けをしたい。と言う事を考えていたがEC-CUBEの仕様上、セッションやは /app/cache/eccube/session内にデフォルトでは登録される。
その為、ランディングページ等でセッションを登録し、EC-CUBEのシステム内のページに遷移するとセッションが消えている。
Cookieも同様にランディングページで設定したCookieが引き継がれない。

と言う事で、少し変化球ではあるものの、ページ内のリファラを参照し自ドメイン内のアクセスであれば処理はそのまま。
ドメイン「以外」のドメインからのアクセスの場合は要素を変更させる。と言う処理を入れてみる。

通常の場合

何も無い場合は以下

$referer = $_SERVER['HTTP_REFERER'];

「普通」の場合はコレで取得出来る。しかしEC-CUBE3だとコレでもダメ。
ドメインからアクセスしても、自ドメインにアクセスした。とみなされてしまう。

EC-CUBE3の場合

トップページでの判定
/src/Eccube/Controller/TopController.php

    public function index(Application $app)
    {
	$referer = $app['request']->headers->get('referer');
	if(!preg_match("/{$hogehoge.com}/",$referer)){
		header("Location: 任意のページ");
		exit;
	}

$refererを取得する所がミソで、$app内から取得する。取得したリファラが自ドメイン「以外」だったらリダイレクトと言う処理を噛ませている。
グローバルの変数もEC-CUBE内では操作する事が難しいので、今後その辺は「出来る」ようにしていかねばならないが、とりあえず急場しのぎと言う事で。