2015年7月13日月曜日

テキストエディターAtomで楽天goldのファイルを直で編集

楽天goldを運用していて、FTPしか使えず、FTPを開いて、該当のファイルをダウンロードして、バナーや商品を追加し、FTPにアップロードする。
運用上の一連の流れですが、これをAtomというテキストエディターを使って直でFTPのファイルを編集して行きましょう。

まずAtomをダウンロードしてきます。AtomはGitHubが開発したテキストエディターです。
Atomのダウンロード

ダウンロードしてきたら、インストールですね。
※今回はmacでの説明になります。

インストールが終わったら、開きます。
英語ですね、、、まずは日本語化していきましょう。

設定に日本語が用意されているわけではなく、第三者の開発したプラグインをインストールして日本語化等の機能を増やしていく事になります。

まずメニューの「Atom」>「Preference」をクリック。
「Setting」画面が開いたら「Install」をクリックします。

画面中央の「Search Package」に「japanese-menu」と入力しエンター。
下記パッケージをインストール。

無事、日本語になりました。

さて、本題のFTPの直編集に移ります。
先ほどと同様に、PreferenceのInstallのSearch Packageに「remote-edit」と入力し、下記パッケージをインストールします。

インストールができたら、メニュー>パッケージ>Remote Edit>Add New Host(ftp)をクリック
FTP情報を入力する画面が出てきます。

「Hostname」「Username」「Port」「Password」へそれぞれ入力し、saveを押します。
いよいよ接続です。
メニュー>パッケージ>Remote Edit>Browse Hostsをクリック、先ほど入力した接続先が出ていると思いますので、クリック。
無事接続されれば、goldへ接続可能です。

編集した後は保存する度にサーバーのファイルも更新されます。
※保存する度にサーバーのファイルも更新されるので、間違った状態で保存するとエライ事になります。。。
慣れてる場合や、ちょこっと編集したいなんて時に最高です。


2015年7月11日土曜日

【ECCUBE】バナーやプラグインのクリック数を調べる

バナーを貼ったけど、どれ位クリックされてるの??
新着商品やニュース、最近売れた商品やランキング等、販促系プラグインを色々入れてみたけど、どのプラグインが効果あるの??

アナリティクスで解析しても、どのキーワードで検索されたか、どこから来たか、どの商品が人気かはわかるけど、自分たちの作ったバナーや導入したプラグインの効果がわからないんだよなぁ、という時は「Googleアナリティクスのイベントトラッキング」を使えば、どのバナーやリンクが何回クリックされたかわかっちゃいます。

時間かけて作ったバナーが実はクリックされていないとう事もわかっちゃいます。。。

効果のあるバナーやプラグインがわかれば、次の一手が見えてくるかもしれません。

※Googleアナリティクスがユニバーサルアナリティクスの場合の説明になります。

リンクや画像がクリックされる度に、googleにクリックされたよという事を伝える事になります。
下記の様な設定になります。

計測したい全てのバナー、プラグインのリンクにonClick="ga('send','event','カテゴリ','アクション','ラベル'); を追記します。


onClick="ga();"の部分がリンクがクリックされた時に処理されます。

onClick="ga();"の中身を左から順番に説明
1.'send' [必須] ここは固定です。変更しないで下さい。
2.'event' [必須] ここは固定です。変更しないで下さい。
3.'カテゴリ' [必須] バナーの名前やプラグイン毎に好きな様に設定してください。
4.'アクション'[必須] 訪問者の行動。今回の場合はクリック。何かダウンロードしてもらう場合はダウンロード等。
5.'ラベル' [省略可能] 細かく名称を設定したい場合に。

バナーの場合は、'category'と画像名を一緒にするとわかりやすいと思います。

アナリティクスの行動>イベントで表示されます。







ECCUBEプラグインの場合の導入ケース

次はプラグイン導入の場合の説明をしていきます。
EC-CUBEのプラグインは、tplファイルでループして商品を取得している場合がほとんどです。
なので、tplで商品のリンクを生成している部分に上記onClick="ga('send','event','カテゴリ','アクション','ラベル'); を追記していきましょう。

試しに、「最近チェックした商品」に設定していきましょう。
このプラグインのtemplates/plg_checkeditems.tplを修正していきます。

aタグの部分に追記していきます
46行目を

下記に


49行目を

下記に


カテゴリにはプラグイン名、アクションにはクリック、ラベルにはプラグイン名+PCと設定しています。
スマホの場合はラベルにプラグイン名+SP等と設定するとよいでしょう。
パソコンとスマホではよくクリックされるプラグインに差異が出てきたりします。

上記で最近チェックした商品がクリックされた回数がアナリティクスに蓄積されていきます。

他のプラグインも設定する事で、効果のあるプラグインはどのページでも目につきやすい所に移動したり、あまりクリックされずパフォーマンスの悪いプラグインは外したり等、改善に役立つと思います。

是非活用してみてください。

2015年5月20日水曜日

ECCUBE メンバーによって管理画面のアクセスを制限する。

EC-CUBE 2.12にてログインするメンバーによって管理画面のアクセスを制限したいという事になった。
例)Aさんに商品管理だけアクセス出来るようにしたい。

早速ググってみると、システム設定>マスターデータ管理>mtb_authorityでメンバーを追加し、admin_contents.cssにて非表示にするというもの。
でも直接/admin/...を叩くとアクセス出来てしまうという。。。

mtb_permissionを使うとページ毎にアクセスできるメンバーを制限できるというのを発見。

システム設定>マスターデータ管理>mtb_authorityにて
店舗スタッフ ID:2を作成

システム設定>マスターデータ管理>mtb_permissionにアクセス。
基本情報管理にはアクセスできなくていいので、
ID:/admin/basis/index.php 値:1を設定
IDにアクセスできるか否か設定したページを入力し、値には店舗スタッフ以上の権限のあるメンバーがアクセス出来るように今回は1を設定(数字が小さい方が偉い)。
なので、メンバーのIDが0と1の人はアクセス可能で、2以上の人はアクセス出来ないよということ。

商品管理以外も設定しこれでOKかとおもいきや。

基本情報管理>特定商取引法へアクセス出来る。。。URLは下記。
/admin/basis/tradelaw.php
基本情報管理>配送方法設定もアクセス出来る。。。
/admin/basis/delivery.php

どうやら全てのファイルを指定する必要があるらしい。。。
どんだけのファイルをちまちま管理画面から設定する必要があるんだ。。。

なので、フォルダ以下の全てのファイルをアクセス出来ないように設定。
システム設定>マスターデータ管理>mtb_permissionで設定したやつを変更。
/admin/basis/index.php
↓
/admin/basis/
basis以下のファイルが全て対象となるように。

data/class/SC_Session.phpを開く
70行目あたり
$admin_path = preg_replace('/\/+/', '/', $_SERVER['SCRIPT_NAME']);
を下記に変更
$admin_path = preg_replace('!/[^/]*$!', '/', $_SERVER['SCRIPT_NAME']);
ファイルの指定からフォルダの指定へ変更してます。

これでめでたく
/admin/basis/以下のファイルは全てアクセス不可になりました。

他のページも同様にシステム設定>マスターデータ管理>mtb_permissionで指定してOK。

2015年5月7日木曜日

【EC-CUBE】最近購入された商品ブロック追加プラグインを高速化

EC-CUBEのDBログファイルを見てみる。
ん、遅い。何かが遅い。
このSQLが遅い。
SQL: SELECT dtb_order_detail.product_id,
dtb_order_detail.product_name,
dtb_order.create_date,
dtb_order.order_pref,
(SELECT main_list_image FROM dtb_products WHERE dtb_products.product_id = dtb_order_detail.product_id) as main_list_image FROM dtb_order_detail LEFT JOIN dtb_order ON dtb_order_detail.order_id = dtb_order.order_id WHERE dtb_order.del_flg = 0 ORDER BY dtb_order.create_date DESC LIMIT 10 OFFSET 0
PlaceHolder: array (
)
execution time: 2.07 sec
平均2~4秒かかってる。遅い。
調べてみると、「最近購入された商品ブロック追加プラグイン」のSQLだとわかった。

とりあえずEXPLAINしてみる。
Limit  (cost=366701.88..366701.91 rows=10 width=46) (actual time=1575.197..1575.242 rows=10 loops=1)
  ->  Sort  (cost=366701.88..366849.30 rows=58969 width=46) (actual time=1575.192..1575.208 rows=10 loops=1)
        Sort Key: dtb_order.create_date
        ->  Hash Join  (cost=3212.48..360686.42 rows=58969 width=46) (actual time=129.716..1158.385 rows=57967 loops=1)
              Hash Cond: ("outer".order_id = "inner".order_id)
              ->  Seq Scan on dtb_order_detail  (cost=0.00..1746.47 rows=61447 width=40) (actual time=0.157..126.893 rows=61022 loops=1)
              ->  Hash  (cost=3051.68..3051.68 rows=20320 width=14) (actual time=129.270..129.270 rows=17256 loops=1)
                    ->  Seq Scan on dtb_order  (cost=0.00..3051.68 rows=20320 width=14) (actual time=1.322..87.515 rows=17256 loops=1)
                          Filter: (del_flg = 0)
              SubPlan
                ->  Index Scan using dtb_products_pkey on dtb_products  (cost=0.00..5.99 rows=1 width=28) (actual time=0.005..0.007 rows=1 loops=57967)
                      Index Cond: (product_id = $0)
Total runtime: 1579.201 ms
やはり1.5秒かかってる。Sort遅っ。

とりあえず、受注日と受注のあった県は表示しないので、dtb_order.create_dateとdtb_order.order_prefは削除
ソートも受注日(dtb_order.create_date)から受注詳細番号に変更(dtb_order_detail.order_detail_id)
SELECT dtb_order_detail.product_id,
dtb_order_detail.product_name,
(SELECT main_list_image FROM dtb_products WHERE dtb_products.product_id = dtb_order_detail.product_id) as main_list_image FROM dtb_order_detail LEFT JOIN dtb_order ON dtb_order_detail.order_id = dtb_order.order_id WHERE dtb_order.del_flg = 0 ORDER BY dtb_order_detail.order_detail_id DESC LIMIT 10 OFFSET 0

無事めちゃ早くなりました。
Limit  (cost=0.00..92.04 rows=10 width=40) (actual time=54.607..55.230 rows=10 loops=1)
  ->  Nested Loop  (cost=0.00..542766.73 rows=58969 width=40) (actual time=54.601..55.191 rows=10 loops=1)
        ->  Index Scan Backward using dtb_order_detail_pkey on dtb_order_detail  (cost=0.00..2017.26 rows=61447 width=44) (actual time=20.640..20.664 rows=10 loops=1)
        ->  Index Scan using dtb_order_pkey on dtb_order  (cost=0.00..3.04 rows=1 width=4) (actual time=3.398..3.400 rows=1 loops=10)
              Index Cond: ("outer".order_id = dtb_order.order_id)
              Filter: (del_flg = 0)
        SubPlan
          ->  Index Scan using dtb_products_pkey on dtb_products  (cost=0.00..5.99 rows=1 width=28) (actual time=0.037..0.039 rows=1 loops=10)
                Index Cond: (product_id = $0)
Total runtime: 55.400 ms

2015年3月24日火曜日

swift iPhone画面上に映っている地図の距離をメートルで取得する。

iPhoneで地図を使ったアプリを開発する際、画面上にうつってる範囲の距離を取得したい時があります。
画面上で見えてる範囲だけ距離を取得しAPIに投げたい。のが動機です。

まずはiPhone上に地図を表示しなくては始まりませんね。
xcodeで新規プロジェクト、シングルページで新規アプリを作ります。
下記コードをコピペ。とりあえず地図が表示されます。
参考にさせて頂きました。Swift Docs 地図の表示

下記のファンクションを使用します。
これは地図内を移動したり、縮尺を変えたりした時に通知されるファンクションです。
このファンクションを利用し、地図に変化があった場合、その都度距離を取得します。


下記内容に変更します。
iPhoneの縦の距離を表示します。 画面上部真ん中と画面下部の真ん中の距離をメートルで表示しています。
コンソールに距離が表示されます。

もし横方向の距離を取得したい場合は下記に変更します。
画面左真ん中と画面右真ん中の距離をメートルで表示しています。

受け取った距離を使ってAPIに投げれば画面上の情報の取得が可能です。

2015年3月14日土曜日

EC CUBE 2.11系でプラグインを実装する方法

2.12系からプラグインがボタンをクリックするだけで導入できますが、2.11系まではプラグインのインストール機能が無いため、インストールができません。
がしかし、2.11系でもインストールが可能です。

今回は「最近チェックした商品」を導入してみます。

クリックするとプラグインページに飛びます。


ダウンロードして、解凍します。

ブロックの設定
管理画面のデザイン>PC>ブロック設定>ブロックを新規入力で
ブロック名:最近チェックした商品
ファイル名:plg_checkeditems
内容にダウンロードしたプラグインのフォルダ内の「templates」フォルダ内のtplファイル(plg_checkeditems.tpl)をコピペ。

tplファイルとphpファイルの紐付けをデータベースから行います。
データベースへアクセスし、dtb_blocのphp_pathに「frontparts/bloc/plg_checkeditems.php」と記入
プラグインのフォルダ内のplg_checkeditems.phpをECCUBEのフォルダhtml>frontparts>bloc内にコピペ

plg_checkeditems.phpを編集します。
下記行を
require_once PLUGIN_UPLOAD_REALDIR . 'CheckedItems/LC_Page_FrontParts_Bloc_CheckedItems.php';

下記に変更
require_once CLASS_REALDIR . 'pages/frontparts/bloc/LC_Page_FrontParts_Bloc_CheckedItems.php';


プラグインのフォルダ内の「LC_Page_FrontParts_Bloc_CheckedItems.php」をECCUBEフォルダのdata>class>pages>frontparts>bloc内にコピペ
LC_Page_FrontParts_Bloc_CheckedItems.phpを編集します。
下記行を削除
$plugin     = CheckedItems::getPlgInfo();

require_once PLUGIN_UPLOAD_REALDIR . 'CheckedItems/CheckedItems.php';

下記行を
$save_count = $plugin['item_count'];

下記に変更
$save_count = 30 //保存したい件数、今回は30件


下記行を
$arrItem = CheckedItems::getCookieArray();

下記に変更
$arrItem = $_COOKIE['product'];



クッキーに商品へのアクセスを保存する
ECCUBEのフォルダのdata>class>pages>products>LC_Page_Products_Detail.phpを編集
下記ログイン判定の下に追加
        // ログイン判定
        if ($objCustomer->isLoginSuccess() === true) {
            //お気に入りボタン表示
            $this->tpl_login = true;
            $this->is_favorite = SC_Helper_DB_Ex::sfDataExists('dtb_customer_favorite_products', 'customer_id = ? AND product_id = ?', array($objCustomer->getValue('customer_id'), $product_id));
        }

下記の様に追記します
        // ログイン判定
        if ($objCustomer->isLoginSuccess() === true) {
            //お気に入りボタン表示
            $this->tpl_login = true;
            $this->is_favorite = SC_Helper_DB_Ex::sfDataExists('dtb_customer_favorite_products', 'customer_id = ? AND product_id = ?', array($objCustomer->getValue('customer_id'), $product_id));
        }
        
//最近チェックした商品追加
$this->setItemHistory($product_id);

//最近チェックした商品追加

    function setItemHistory($product_id) {

        $cnt = 0;

        // プラグイン情報を取得.
 //       $plugin     = SC_Plugin_Util_Ex::getPluginByPluginCode("CheckedItems");
        //保存期間
        $save_limit = 30;
        //保存件数
        $item_count = 30;

        $arrDisp = $_COOKIE['product'];
        $cnt     = count($arrDisp);

        //重複項目のチェック
        $DispFlg = true;
        if (isset($_COOKIE['product'])) {
            foreach ($_COOKIE['product'] as $name => $value) {
                if($value == $product_id){
                    $DispFlg = false;
                }
            }
        }
 
        //クッキーにセット
        if($DispFlg){
            $disp_num = $item_count;
            if($cnt == 0){
                setcookie('product[' .$cnt .']', $product_id,time()+60*60*24*$save_limit,"/" );
            }else{
                $arrCookie = $_COOKIE['product'];
                $arrCookie[] = $product_id;

                //商品保存処理
                if(count($arrCookie) > $disp_num){
                    array_shift($arrCookie);
                }
                foreach ($arrCookie as $key => $val) {
                    setcookie('product[' .$key .']', $val,time()+60*60*24*$save_limit,"/" );
                }
            }
        }
    }



管理画面のデザイン管理>レイアウト設定から設置したら表示されます。
細かい表記などが表示されていない場合は適時tplファイルを修正。


まとめ
プラグインのブロック追加
DBのブロック情報の変更
プラグイン内のファイルを設置
各ファイルのパスを通す

2015年3月12日木曜日

EC CUBE3のインストール(β版)

β版のECCUBE3を macのローカル環境(MAMP Mysql)へインストールしてみます。
コマンドラインを立ち上げ
下記コマンドを打ち込んでgithubからeccbe3をクローンする。
今回はローカルで動かすので、MAMPのhtdocsフォルダにダウンロード。
git clone http://github.com/EC-CUBE/ec-cube.git

フォルダ内へ移動
cd ec-cube

composerをインストールします。
curl -sS https://getcomposer.org/installer | php

次にMAMPを立ち上げ、phpmyadminから適当な名前のDBを作成しておきます。

次に、インストールしたECCUBEのフォルダの中の「eccube_install.sh」をエディタで開きます。
インストールに必要な修正は以下の部分。


-そのまま
CONFIG_PHP="app/config/eccube/config.php"

-そのまま
ADMIN_MAIL=${ADMIN_MAIL:-"admin@example.com"}

-そのまま
SHOP_NAME=${SHOP_NAME:-"EC-CUBE SHOP"}

-ローカルのURL、http://localhost:8888/ec-cube/html/
HTTP_URL=${HTTP_URL:-"http://test.local"}

-ローカルのURL、http://localhost:8888/ec-cube/html/
HTTPS_URL=${HTTPS_URL:-"http://test.local/"}

-ローカルのURL、/ec-cube/html/
ROOT_URLPATH=${ROOT_URLPATH:-"/"}

-そのまま
DOMAIN_NAME=${DOMAIN_NAME:-""}

-そのまま
ADMIN_DIR=${ADMIN_DIR:-"admin/"}


-localhost
DBSERVER=${DBSERVER-"127.0.0.1"}

-上記で作ったDBの名前
DBNAME=${DBNAME:-"cube3_dev"}

-自分のDBのユーザー名
DBUSER=${DBUSER:-"cube3_dev_user"}

-自分のDBのパス
DBPASS=${DBPASS:-"password"}


"mysql" )
#-- DB Seting MySQL

-そのまま
MYSQL=mysql

-自分のDBのユーザー名
ROOTUSER=root

-そのまま
ROOTPASS=$DBPASS

-localhost
DBSERVER="127.0.0.1"

-そのまま
DBPORT=3306

;;


保存したらインストール可能です。
下記コマンドでインストールが始まります。
sh eccube_install.sh mysql