(佐賀→熊本)マークアップエンジニアのググる生活

地方のWEB制作会社で働く、フロントエンドエンジニア。
HTML、CSS、JavaScript(jQuery)、PHP、Smary、EC-CUBE、WordPress、Movable Type等々で解らない時に、Googleで検索したら解決した話や、「閃いた!」などをほとんど自分用にメモとして残すブログです。

※URLがあったら元記事を参照推奨です!
※ほとんどの事は検証はしていますが、あくまでも参考程度にお願い致します!
※記載が不正確であったことにより生じたいかなる損害に関しても、当ブログは責任を負いかねます。自己責任でよろしくおねがいいたします。

ピンポイントに単体だけ抜き出して、テストする・・・。
出来上がっているものだったり、作りかけで一部だけうまくいかない・・・ってときは、
単体テストをやる・・・。

当たり前だと思いますが、ズボラな性格のため、
切り分けてテストをやらずに、プログラム全体の中で、
試行錯誤をやってしまい、解決の糸口を見つけるまですごく時間がかかったので、
自分へのメモとして m( _ _ )m

PHP でも JavaScript でも CSS でも HTML でも、
困ったり怪しいときは単体テスト。

以前から自分用のテンプレートを持っていましたが、 だいぶ古くなった感じもあったので、それを気により汎用的に改善して、 ついでに思い切って公開してみました!

内部では、 Qdmail, Qdsmtp を使用しています。

ドキュメントは準備中ですが、設定ファイルである config.php にコメントを盛っているので、
設定は可能かと思っています…。
https://github.com/mhkkr/Functions-Form
いろいろ改善予定です。どんどん使いやすくしたいです!

EC-CUBE 4系 が発表されましたね!
マスターアップは 10月とのことで、私もさっそくデモを試してみました。

3系からかなり進化していて、すごく乗り換えたいです...。
なかでも管理画面は見やすく、使いやすくなっており、
4系を操作したあと、3系を操作するとすごくイライラします(笑)

ということで、少しでも 3系を快適に使いたく、
管理画面をカスタマイズしてみたので紹介します。


確認は 3.0.16 で行っています。


サイドナビのCSSを改善

3系のデフォルト、見辛いですよね。
4系だとそれを反省して(?)、綺麗になっています。

なので、3系でも真似をして綺麗にしてみました。

eccube3admin_css

変更点は、
・子ナビのボーダーを取り、
・どの親の配下であるかわかりやすくするために背景色を白へ、
・開いてる親の文字色とウェイトを変更しわかりやすく、
・さらに現在アクティブであるナビを強調しました。

CSSはこんな感じに。

<style>
    #side > .nav li {
        transition: background-color .3s;
    }
    #side > .nav li a {
        transition: color .3s, font-weight .3s;
    }
    #side > .nav li a .cb {
        transition: color .3s;
    }
    #side > .nav li.active > a {
        color: #3F5467;
        font-weight: 700;
    }
    #side > .nav li.active > a .cb {
        color: inherit;
    }

    #side > .nav > li:not(:nth-child(6)):not(:nth-child(7)).active {
        background-color: #fff;
    }
    #side > .nav > li:not(:nth-child(6)):not(:nth-child(7)) > ul > li.active > a,
    #side > .nav > li:not(:nth-child(6)):not(:nth-child(7)) > ul > li.active > a:hover  {
        background-color: #3F5467 !important;
        color: #fff;
    }
    #side > .nav > li:not(:nth-child(6)):not(:nth-child(7)) > ul > li {
        border: none;
    }

    #side > .nav > li.active li.active {
        background-color: #fff;
    }
    #side > .nav > li > ul > li.active li.active > a,
    #side > .nav > li > ul > li.active li.active > a:hover  {
        background-color: #3F5467 !important;
        color: #fff;
    }
    #side > .nav > li > ul > li > ul {
        background-color: transparent !important;
    }
    #side > .nav > li > ul > li > ul > li {
        border: none;
    }
    #side > .nav > li > ul > li > ul > li > a:not(:hover) {
        background-color: transparent !important;
        opacity: 1;
    }
</style>

:not(:nth-child(6)) と :not(:nth-child(7)) は、
ナビゲーションの増減によって値が変わるのが注意です。
デフォルトの内容だとそのままで大丈夫です

上のCSSを dashboard.css の一番下に追記するか、
管理画面の default_frame.twig の <//head> 直前に書くとよいかと思います。


商品登録画面のアコーディオンをすべて開かせておく

個人的にどうして表示・非表示のアコーディオンになっているのかわからないのですが、
商品カテゴリやタグ、詳細な設定、フリーエリアなどなどがアコーディオンになっていて開閉できます。
基本的にページを表示したときはそれが閉じており、編集する場合はワンクリックが必要です。
商品が数個程度なら問題ないですが、数が増えてくるとドンドン煩わしくなってきます;;

そこで、編集ページを表示したときに全部開いている状態にしてみました。

<script>
  $(function() {
      // 最初から開ける
      $('#detail_wrap .toggle').click();
  });
</script>

この jQuery を管理画面の product.twig の {% endblock javascript %} 直前に追記します。


商品マスター、受注マスター、会員マスターの初期表示

2系でも同じ悩みがありましたが、商品・受注・会員のマスターの初期表示は、
最小限のフォーム欄と検索ボタンのみです。
一覧を表示させるには検索ボタンを押さなければなりません。
これも最初の数回は良くても、だんだんと面倒になってくる作業の一つです...。

4系では、これを不便に思っていたのか改善されておりましたが、
3系でも依然としてこの問題が残っていました。

3系でも検索ボタンを押さずに一覧を表示させたい!ということで、
PHP にちょっと追記してあげると解決できました。
当初は4系を参考にカスタマイズしようと試みましたが、ググってしてみると、
フォーラムに解決案がありました! → https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=18643&forum=10

追記するコードはたったこれだけ、
if (!$page_no) {
    $page_no = 1;
}

ファイルと場所は、
・CustomerController.php
・OrderController.php
・ProductController.php
の if (is_null($page_no) && $request->get('resume') != Constant::ENABLED) { の直前になります。

これでマスターのページを開いたときに一覧が表示されます!
ただ修正後、F5更新だとうまく行かなかったので、
一度だけ検索ボタンを押す必要があるみたいで、そこだけ注意が必要です。

サイドバーを追従(固定)させるjqueryプラグイン「fitSidebar」を使用しています。
最近では css の position: sticky; だけで固定にすることができますが、 縦長の場合は見切れてしまい、下の方にあるコンテンツがいちばん最後までスクロールしないと見れない問題があり、ちょっと気になります。
fitSidebar だとスクロールに合わせてコンテンツも移動するので大変便利です。
それぞれ用途に合わせて使い分けています。

そこで fitSidebar を使っていて、更にヘッダーも固定の場合、 ページの下に行って、上に戻るときに、サイドバーの頭が見切れてしまう問題にぶつかりましたので、 余白を設けるカスタマイズを行ってみました。

サンプル(jquery-plugin-fitSidebar-headerfixed-top-margin.html)

以前 2.13系の記事を書きましたが、
今回はその 3系バージョンになります。

ググったところ、情報がなかったので・・・
手探りながらやってみました。

試したバージョンは 3.0.16 になります。

※データそのものが初期化されるので、
 運用中には絶対に実行しないでくださいm(_ _)m
 ※また自己責任でお願いいたします。



商品を初期化

TRUNCATE TABLE `dtb_product`;
ALTER TABLE `dtb_product` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_category`;
ALTER TABLE `dtb_product_category` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_class`;
ALTER TABLE `dtb_product_class` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_image`;
ALTER TABLE `dtb_product_image` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_stock`;
ALTER TABLE `dtb_product_stock` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_tag`;
ALTER TABLE `dtb_product_tag` AUTO_INCREMENT = 1;



カテゴリーを初期化

TRUNCATE TABLE `dtb_category`;
ALTER TABLE `dtb_category` AUTO_INCREMENT = 1;



規格を初期化

TRUNCATE TABLE `dtb_class_category`;
ALTER TABLE `dtb_class_category` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_class_name`;
ALTER TABLE `dtb_class_name` AUTO_INCREMENT = 1;



PhpMyAdminの場合?

詳しくないので解説できませんが、データにロックがかかっているために、
上のSQLだけでは実行できませんでした。
SET FOREIGN_KEY_CHECKS=0;
というのを先頭に添える必要があります。


まとめると...

SET FOREIGN_KEY_CHECKS=0;

TRUNCATE TABLE `dtb_product`;
ALTER TABLE `dtb_product` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_category`;
ALTER TABLE `dtb_product_category` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_class`;
ALTER TABLE `dtb_product_class` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_image`;
ALTER TABLE `dtb_product_image` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_stock`;
ALTER TABLE `dtb_product_stock` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_product_tag`;
ALTER TABLE `dtb_product_tag` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_class_category`;
ALTER TABLE `dtb_class_category` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_class_name`;
ALTER TABLE `dtb_class_name` AUTO_INCREMENT = 1;

TRUNCATE TABLE `dtb_category`;
ALTER TABLE `dtb_category` AUTO_INCREMENT = 1;
これを3系をインストール後に行うと、商品やカテゴリー・規格のが初期化され、
IDを1から始めることができました!


※データそのものが初期化されるので、
 運用中には絶対に実行しないでくださいm(_ _)m
 ※また自己責任でお願いいたします。

css の box-shadow は inset を指定すると、内側に影を付けれる便利なものだが、
子要素に background-color などで背景色を指定すると、
その背景に重なり順で負けてしまい、影が途切れる問題に直面しました。

そこで子要素の疑似要素を活用してみたところ、うまく問題を回避できました。

サンプル(parent-elements-box-shadow-inset-in-child-elements-background.html)

ちょっと必要だったので考えてみました。
わりと簡単にできたのでメモ!

<?php
  // 年齢制限とか
  $_minimum_age = 0;

  // 開始年調節
  $_begin_year = 52;

  // 終了年調節
  $_end_year = -20;

  // 元号
  $_era = [
    '昭和' => ['from' => 1926, 'to' => 1989],
    '平成' => ['from' => 1989, 'to' => 2019],
    '〇〇' => ['from' => 2019],
  ];

  foreach(range((date('Y') - $_minimum_age - $_begin_year), (date('Y') - $_minimum_age - $_end_year)) as $year) {
    $era = '';
    foreach($_era as $key => $value) {
      if ($value['from'] <= $year && (!isset($value['to']) || isset($value['to']) && $value['to'] >= $year)) {
        $add = $key . ($year - $value['from'] + 1) . '年';
        $era = ($era === '')  ? $add : $era . ' / ' . $add;
      }
    }
    $year = $year . '年 / ' . $era;
    echo $year . '<br>';
  }
  ?>


■結果
1966年 / 昭和41年
1967年 / 昭和42年
1968年 / 昭和43年
1969年 / 昭和44年
1970年 / 昭和45年
1971年 / 昭和46年
1972年 / 昭和47年
1973年 / 昭和48年
1974年 / 昭和49年
1975年 / 昭和50年
1976年 / 昭和51年
1977年 / 昭和52年
1978年 / 昭和53年
1979年 / 昭和54年
1980年 / 昭和55年
1981年 / 昭和56年
1982年 / 昭和57年
1983年 / 昭和58年
1984年 / 昭和59年
1985年 / 昭和60年
1986年 / 昭和61年
1987年 / 昭和62年
1988年 / 昭和63年
1989年 / 昭和64年 / 平成1年
1990年 / 平成2年
1991年 / 平成3年
1992年 / 平成4年
1993年 / 平成5年
1994年 / 平成6年
1995年 / 平成7年
1996年 / 平成8年
1997年 / 平成9年
1998年 / 平成10年
1999年 / 平成11年
2000年 / 平成12年
2001年 / 平成13年
2002年 / 平成14年
2003年 / 平成15年
2004年 / 平成16年
2005年 / 平成17年
2006年 / 平成18年
2007年 / 平成19年
2008年 / 平成20年
2009年 / 平成21年
2010年 / 平成22年
2011年 / 平成23年
2012年 / 平成24年
2013年 / 平成25年
2014年 / 平成26年
2015年 / 平成27年
2016年 / 平成28年
2017年 / 平成29年
2018年 / 平成30年
2019年 / 平成31年 / 〇〇1年
2020年 / 〇〇2年
2021年 / 〇〇3年
2022年 / 〇〇4年
2023年 / 〇〇5年
2024年 / 〇〇6年
2025年 / 〇〇7年
2026年 / 〇〇8年
2027年 / 〇〇9年
2028年 / 〇〇10年
2029年 / 〇〇11年
2030年 / 〇〇12年
2031年 / 〇〇13年
2032年 / 〇〇14年
2033年 / 〇〇15年
2034年 / 〇〇16年
2035年 / 〇〇17年
2036年 / 〇〇18年
2037年 / 〇〇19年
2038年 / 〇〇20年

レンタルサーバーの場合、WordPressやEC-CUBEなどのメジャーなCMSは、
自動インストールなどのワンクリック操作で可能だが、
それが無い場合は、各種公式サイトよりダウンロードし、
解凍後、FTPなどでアップロードすると思いますが…。
解凍後のファイル群は容量が多く時間がかかります。

そこでダウンロードした際に、Zipやtar、gzなど圧縮形式のままアップロードできないかと、
思っていたところ、WinSCPにはその機能があるとのこと!
http://xoops.ryus.co.jp/modules/d3blog/details.php?bid=304
↑で書いてある通りに操作してみるものの、「UnTar/GZip」がクリックできない…。

もしやFTPだからダメなのかな?と調べてみると、
https://translate.googleusercontent.com/translate_c?act=url&depth=1&hl=ja&ie=UTF8&prev=_t&rurl=translate.google.co.jp&sl=en&sp=nmt4&tl=ja&u=https://winscp.net/forum/viewtopic.php%3Ft%3D8638&xid=17259,15700021,15700124,15700149,15700168,15700173,15700186,15700189,15700201&usg=ALkJrhiM3r5zhuseDWr9lgcMD5J_ZvhoHw
思った通り、FTPではなくSFTPやSCPなどのSSH接続ではないと、
使用できない機能でした。

ということで、FTPをやめて、SFTP接続を試みました。

XSERVERを使用しているため、
基本的なやり方はググると良く出てきます。
https://lab.maro-log.net/post-3935/
https://nelog.jp/xserver-winscp-sftp
↑の通りではありますが、最後のWinSCPのセッションの設定で、
ちょっと奔走したので下記にメモします。

・転送プロトコル → SFTP
・ホスト名 → サーバードメイン
・ポート番号 → 10022
・ユーザ名 → サーバーID
・パスワード → 空欄

sftp



これでめでたくSFTP接続が可能となり、
リモート先で「UnTar/GZip」のコマンドをクリックできるようになり、
圧縮ファイルの解凍が可能となりました!嬉しい!

EC-CUBE 3.0.16 でカスタマイズしています。
受注CSVに利用ポイントと加算ポイントを追加しました。

カスタマイズ方法としては、
1. dtb_csv に利用ポイントと加算ポイントを挿入
2. プログラムに処理を追加
です。
3系になってからは、標準項目の追加なら、DBに値を追加するだけで出力してくれるので非常に便利でした。

ただプラグインの場合はそのプラグインがCSVの処理を入れてない場合 1. だけでは出力できないので、
プログラム側にカスタマイズが必要でした。
そこで今回は苦戦しました。またあまり正しくない方法で取り急ぎの対応…になります。


ググってみると、
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=18139&forum=13
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=19444&forum=11
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=19318&forum=11
https://github.com/EC-CUBE/ec-cube/pull/1944
などなど、参考になりそうなトピックスがありました。


まずは、1. dtb_csv に利用ポイントと加算ポイントを挿入を実行。
SQLでサクッと行います。
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 (NULL, '3', '1', 'Plugin\Point\Entity\Point', 'point', 'use', '利用ポイント', '', '1', '', '');
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 (NULL, '3', '1', 'Plugin\Point\Entity\Point', 'point', 'add', '加算ポイント', '', '1', '', '');
`entity_name` は恐らく 'Plugin\Point\Entity\Point' であっていると思いますが、
`field_name` と `reference_field_name` とはダミーになります。
↑は、'Plugin\Point\Entity\Point' で定義されているファイルの中の変数を入れると思いますが、
適切なものが見当たりませんでしたので…
この辺アドバイスされたい…(>_<)


次に、2. プログラムに処理を追加
本来は新たに処理用のプラグインを作るようですが、今回は取り急ぎのため本体コードを編集します。
/src/Eccube/Controller/Admin/Order/OrderController.php が、
管理画面の受注画面をコントロールしているファイルになります。
exportOrder関数の中の、だいたい260行目に
$event = new EventArgs(
とあるので、その上に下記を追記します。
/src/Eccube/Controller/Admin/Order/OrderController.php$Customer = $Order->getCustomer();
// 会員のみ処理
if ($Customer) {
    if ($Csv->getDispName() === '利用ポイント') {
        // 利用ポイント取得
        $usePoint = $app['eccube.plugin.point.repository.point']->getLatestUsePoint($Order);
        $usePoint = abs($usePoint);
        $ExportCsvRow->setData($usePoint);
    }
    if ($Csv->getDispName() === '加算ポイント') {
        // 加算ポイント取得
        $addPoint = $app['eccube.plugin.point.repository.point']->getLatestAddPointByOrder($Order);
        $ExportCsvRow->setData($addPoint);
    }
} else {
    if ($Csv->getDispName() === '利用ポイント') {
        // $ExportCsvRow->setData(0);
    }
    if ($Csv->getDispName() === '加算ポイント') {
        // $ExportCsvRow->setData(0);
    }
}
まず会員であるかをチェックして、非会員の場合は空欄(場合によっては0を出力してもよいかも)にしています。
非会員でも加算ポイントを取得しようとするとエラーが出るので会員チェックは重要です。

次に 'eccube.plugin.point.repository.point' でポイントのリポジトリにアクセスできるので、
用意されている関数に $Order を渡すと利用ポイント取得、加算ポイント取得が取得できます。
取得できたポイントを $Csv->getDispName() が '利用ポイント' と '加算ポイント' との時に、
CSVにセットする、という感じになっています。


配送CSVも同じ作業でできました。

以上ですが、冒頭にも言いましたがこれは良い方法でないので、
参考程度が良いかと思います。

それにしてもSymfonyとSilexを勉強しないとついていけませんね...。

今回は 3.0.16 で確認しています。

{{ Product.getPrice02IncTaxMin|price }}
{{ Product.getPrice02IncTaxMax|price }}
などなど、twig や smarty などには便利な装飾子がありますが、

EC-CUBE3 の場合、 |price というのを独自に追加しているので、
それを付けるだけで、 number_format された値と、¥マークが付与された金額を表示することができます。

そこで半角なのを全角にしてみたいと思い、ソースコードを追ってみたところ、
まとめて管理してあるファイルを見つけたので下記のように編集するとうまくいきました。

// /src/Eccube/Twig/Extension/EccubeExtension.php

/**
 * Name of this extension
 *
 * @return string
 */
public function getPriceFilter($number, $decimals = 0, $decPoint = '.', $thousandsSep = ',')
{
    $price = number_format($number, $decimals, $decPoint, $thousandsSep);

    // [カスタマイズ] \マークを全角に
    // $price = '¥ '.$price;
    $price = '¥'.$price;

    return $price;
}

このページのトップヘ