2015年9月22日火曜日

【swift】アプリをアップロードするとiTunes Connect: Your app "MYAPPNAME" (Apple ID: ***) has one or more issues というメールが届く

Xcode7・Swift2になって初のアプリのバージョンアップ。
使っていた色々なメソッドがdeprecatedになり、、色々と修正してようやくアップロードまでこぎつけましたが、最後の最後でまたつまづきました。。。

アーカイブを作り、バリデートをし、意気揚々と「Upload To App Store」をクリックして待つこと数分。
アップルから見たこともないメールが届きました。
一応全文載せておきます。

Dear developer,

We have discovered one or more issues with your recent delivery for "MYAPPNAME". To process your delivery, the following issues must be corrected:

Invalid Swift Support - The files libswiftCoreLocation.dylib, libswiftDarwin.dylib, libswiftDispatch.dylib, libswiftCoreGraphics.dylib, libswiftUIKit.dylib, libswiftWebKit.dylib, libswiftCore.dylib, libswiftFoundation.dylib, libswiftXCTest.dylib, libswiftCoreImage.dylib, libswiftObjectiveC.dylib aren’t at the expected location /Payload/metroExit.app/Frameworks. Move the file to the expected location, rebuild your app using the current public (GM) version of Xcode, and resubmit it.

Once these issues have been corrected, you can then redeliver the corrected binary.

Regards,

The App Store team


「***.dylib」ファイルをあるべき場所に置いてね、置いたらビルドできるよ。という様な感じ。
Bitcodeに関するデベロッパーツールのバグらしい。

とりあえず解決方法を書いて起きます。
1.新しいビルド番号を付ける。
2.オーガナイザーを開き、該当のアーカイブで右クリックし「Show in Finder」でFinderを開く。
3.該当のアーカイブを右クリックして「パッケージの内容を表示」次の2つのフォルダを開く「Products/Applications/YourApp.app/Frameworks/」「SwiftSupport/iphoneos/」
4.「SwiftSupport/iphoneos/」に入っているファイルを全部コピーして「Products/Applications/YourApp.app/Frameworks/」に上書き。
5.再度アップロード。

上記で無事解決しwaiting for reviewになりました。
アップロードしてからビルド出来るまで1時間以上かかった。。。

【swift】iOS9におけるjsonの取得 sendAsynchronousRequestが使えない。

Xcode7のSwift2からそれまで使っていた幾つかのファンクションがdeprecatedになっていました。。。
その中でも一番大きかったのがjsonの取得に使っていたsendAsynchronousRequestがdeprecatedになっていた事でした。

今まではこんな感じ。

18行目のjsonにデータが格納されるので、取り出して使っていました。

swift2ではNSURLSessionのdataTaskWithRequestを使えと怒られます。。。


swift2から下記の通りで同様に問合せ出来ました。
NSURLSessionのdataTaskWithRequestでリクエストを作り、do try catchで処理するのがポイント。

2015年9月8日火曜日

【ECCUBE3 プラグイン】配送伝票番号

【ECCUBE3 プラグイン】配送伝票番号

ECCUBE3で注文毎に配送伝票番号を登録し、発送メールに追記します。

ソースはこちら

インストール方法

ソースはこちらからGithubへ行き、ページの右下の「Download ZIP」からZIPファイルをダウンロード

ECCUBE3管理画面<オーナーズストア<プラグイン<プラグイン一覧 ページ下部の独自プラグイン「プラグインのアップロードはこちら」 ダウンロードしたZIPを選択してアップロード 独自プラグインにプラグインが追加されるので、「有効にする」をクリック 機能 メールテンプレート追加 「発送メール」というテンプレートが追加されます。 設定>基本情報設定>メール設定 からテンプレートの編集が出来ます。
サンプルはヤマト運輸ですので、ご自身の配送会社に変更下さい。
※「伝票番号:」は編集しないでください。発送メール送信時に配送伝票番号が記載されなくなります。



配送伝票番号の登録

受注管理>各受注の編集画面 から配送伝票番号の登録が出来ます



発送メールの送信

発送メールに自動的に登録した配送伝票番号が記載されます。
配送伝票番号を登録していない場合は、メール送信時に文面を編集してください。
※メール本文の「伝票番号:」は変更すると配送伝票番号が記載されなくなりますので、ご注意下さい。
メール一括送信にも対応しています。配送伝票番号を登録していない場合、「伝票番号:」の後は何も記載されませんので、ご注意ください。

2015年8月28日金曜日

【ECCUBE3 プラグイン】新着商品

【ECCUBE3 プラグイン】新着商品

ECCUBE3のトップページに新商品を追加します。


ソースはGithubにupしています。
こちらから

How to install

Githubページの右下の「Download ZIP」からZIPファイルをダウンロード

ECCUBE3管理画面<オーナーズストア<プラグイン<プラグイン一覧

ページ下部の独自プラグイン「プラグインのアップロードはこちら」

ダウンロードしたZIPを選択してアップロード

独自プラグインにプラグインが追加されるので、「有効にする」をクリック

以上でトップページの新着情報の上に8件の新商品(最後からアップされた順)が表示されます。


カスタマイズ方法
表示件数を変更する。デフォは8件
app/Plugin/NewItem/Resource/template/new_item.twig
15行目
{% for Order in OrderList | slice(0,8) %}
slice(0,8)の8の部分を変更する。

2015年8月25日火曜日

【ECCUBE3 プラグイン】最近購入された商品

【ECCUBE3 プラグイン】最近購入された商品

ECCUBE3の商品詳細画面に最近購入された商品を追加します。


ソースはGithubにupしています。
こちらから

How to install

Githubページの右下の「Download ZIP」からZIPファイルをダウンロード

ECCUBE3管理画面<オーナーズストア<プラグイン<プラグイン一覧 ページ下部の独自プラグイン「プラグインのアップロードはこちら」 ダウンロードしたZIPを選択してアップロード 独自プラグインにプラグインが追加されるので、「有効にする」をクリック

以上で商品詳細画面のサブ画像の下に8件の最近購入された商品が表示されます。


カスタマイズ方法
表示件数を変更する。デフォは8件
app/Plugin/RecentlyPurchaseItem/Resource/template/recentl_purchase_item.twig
14行目
{% for Order in OrderList | slice(0,8) %}
slice(0,8)の8の部分を変更する。

2015年8月13日木曜日

【ECCUBE3】複数の規格がある商品をcsvで登録する。

ECCUBE2系の頃から規格が複数ある商品をcsvで登録するにはカスタマイズが必要でした。
EC CUBE3系も同様なので、商品登録csvの「規格分類1(ID)」セルにカンマ区切りで規格分類IDを入力すると登録できる仕様にしてみましょう。
※「規格分類2(ID)」には手を加えないので、「規格分類1(ID)」を使用する場合のみのカスタマイズになります。
※規格を複数登録する際、商品コード、値段はcsvに入力した値になります。規格毎に商品コードや値段を別々にしたい場合は考慮してませんのであしからず。

では、カスタマイズしていきましょう。カスタマイズ自体はほんの数行加えるだけです。
下記、csv登録のコントローラーを開きます。
/src/Eccube/Controller/Admin/Product/CsvImportController.php


174行目付近
// 商品規格が存在しなければ新規登録
$ProductClasses = $Product->getProductClasses();
if ($ProductClasses->count() < 1) {
// 規格分類1(ID)がセットされていると規格なし商品、規格あり商品を作成
$ProductClassOrg = $this->createProductClass($row, $Product, $app, $data);

を下記の様に追加します。
// 商品規格が存在しなければ新規登録
$ProductClasses = $Product->getProductClasses();
if ($ProductClasses->count() < 1) {
  //複数規格登録の追加
  $classcategory_id1 = $row['規格分類1(ID)'];
  $c_list = explode(",",$classcategory_id1);
  foreach ($c_list as $row['規格分類1(ID)'])
  {
// 規格分類1(ID)がセットされていると規格なし商品、規格あり商品を作成
$ProductClassOrg = $this->createProductClass($row, $Product, $app, $data);


233行目付近
} else {
  if ($row['規格分類2(ID)'] != '') {
   $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
  }
}
を下記の様に最後に「}」追加します。
} else {
  if ($row['規格分類2(ID)'] != '') {
   $this->addErrors(($data->key() + 1) . '行目の規格分類1(ID)が存在しません。');
  }
}
}

内容としては、規格分類1(ID)の中身を「,」で分割し、分割した分だけ規格の登録を行っています。

これで、csvで複数の規格が一回で登録可能になります。




2015年8月1日土曜日

swift MapView PolyLine上を移動するアニメーション

MapViewに描画したPolyLine上を移動するアニメーションを作りたくて試行錯誤。
アニメーションを使うというより、座標がわかっているので、ピンを座標に沿って移動していけば良いという事に辿り着く。
ずっとアニメーションで検索してたから結論になかなか辿り着けなかった。。。

stackoverflowにヒントありました。
Animate a visual element along an arc in MapKit

山手線の駅の緯度経度を使用してピンを一周させてみましょう。
山手線って意外と縦長。。。



GitHubにソースあります。

緯度経度のポイントを増やし、NSTimerのタイミングを変更してあげれば、アニメーションしているように見えてきます。

Gmailに来た作業依頼メールをTrelloの新規カードとして追加する。

今日はTrelloの新しい発見。

Trello・・・TODOリストですね。

細かい使い方は省略して、今日はタイトル通り、特定のメールアドレスに作業依頼が来るので、Gmailに来た作業依頼メールをTrelloに新規カードとして追加する。という事をします。
Trelloボードにメンバー追加してカード追加してもらって管理とかしたいけど、レガシーな環境から抜け出せない場合もあるので。。。


カードを追加したいボードを開きます。
画面右端の Show Menuからメニューを開き、Email-to-board Settingsをクリック。
ブルーで塗りつぶした部分に転送先のメールアドレスが出てきます。
メールアドレスの下には追加したいリストとリストの上に追加するのか、下に追加するのか選択できます。

これでTrelloの方はOK。
次はGmailで転送の設定を行います。
Gmailの転送設定は語り尽くされていると思うので、概要だけ。
フィルタで特定のメールアドレスに来たメールを先ほどTrelloで表示されたメールアドレスに転送するだけ。
これで転送されたメールは自動的にTrelloに新規カードとして登録されます。

Gmailを見る回数が減りそうです。

2015年7月31日金曜日

【ECCUBE】2.12系 在庫のない規格を選択肢から消す。

ECCUBE 2.12系で在庫のない商品の規格を選択肢から削除したい。
在庫がない場合、選択肢の横に(品切れ中)とは表示されるが、紛らわしいので消してしまおうという事に。

まずは「商品詳細ページ」のページ詳細を見てみる事に。
どうやら規格の選択肢の生成にはSmartyのhtml_optionを使っているようだ。


Smarty公式によると
{html_options} は、HTML の <select><option> グループにデータを代入して作成する カスタム関数 です。

html_optionsのオプションのoptionsに配列を渡して選択肢を作るようだ。
ではさてoptionsに渡されている変数は$arrClassCat1
これはLC_Page_Products_Detail.phpで渡されているが、中身はSC_Product.phpで設定されているようだ。

290行目付近で設定されていました。


ここを在庫がない場合は非表示にする為に下記の様に分岐をさせます。


これで在庫のない規格は選択肢から消え去ります。

2015年7月24日金曜日

Automatorを使って楽天のランキングをチェックしてメールする

MacのデフォルトアプリでもあるAutomator
こんなやつです。

知名度は低いですが、色々と作業を自動化してくれる優れもの。

今回はAutomatorを使って毎日決まった時間にデイリーランキング、毎週決まった時間にウイークリーランキングに自分のお店の商品がランクインしているか調べて、
順位と商品をメールで送ってもらいましょう。

まずはAutomatormを立ち上げ、ファイル>新規を選択します。
ウィンドウが立ち上がります。書類の種類を選択してください。今回は決まった時間に実行するので「カレンダーアラーム」を選択します。

こんな画面が立ち上がります。

左側のライブラリ一覧から処理を選び、右側で処理の順番を組み立てて行きます。
まずは、サイトから情報を引っ張ってくるので、ライブラリ>インターネット>指定されたURLを取得をダブルクリック。
下の画像のようになると思います。
デフォルトではアップルのURLが入っていますね。
楽天市場のランキングのRSSのURLをここに入れたいので、楽天市場でランキングを見たいジャンルまで絞り込むと、右下にちっちゃく「RSS」の表示があるので、リンクをコピーして、アップルのURLと差し替えてください。
デイリーやウィークリー等、URLが変わりますのでここで決めます。

次は、取得したURLの内容にフィルタをかけます。「内容」が「・・・」を含むの・・・の部分を自分達のお店の名前にしてください。
これでランクインしていれば順位と商品名などが抽出されます。

今は抽出しただけなので、記事からテキストを取得しましょう。
ライブラリ>インターネット>記事からテキストを取得を追加。
メールを送信する時に本文に自動で追加する為に、いくつか処理を追加します。
ライブラリ>ユーティリティ>クリップボードにコピー
ライブラリ>ユーティリティ>クリップボードの内容を取得
以上を追加すると下記のようになるかと思います。

さて、残るはメールを送信するだけです!
ライブラリ>メール>新規メールメッセージ
宛先に自分のメールアドレス、件名に一工夫しましょう。メッセージは自動で入ります。

左上のアクションを変数に変更し、日付と時刻から今日の日付を件名にドラッグ&ドロップします。自動で今日の日付が挿入されます。

最後にメールを送信します。
ライブラリ>メール>送信メッセージを送信

以上でAutomatorの設定は以上です。
次はカレンダーの設定になります。保存するとカレンダーアラームの名前を入力する欄が出てきます。
デイリーランキングとでも入れておきましょう。

カレンダーの画面が立ち上がるので、実行したい時間に設定しましょう。
とりあえず毎日11時に設定。

繰り返しはアラームをダブルクリックして設定すればOK!

これで毎朝11時にランクインのメールが届きます。
ちなみにランクインしてなくてもメールは届きます。。。本文は空なので、そこで判断しましょう。

2015年7月18日土曜日

【ECCUBE3】最近購入された商品のブロックの追加

ECCUBE3にて最近購入された商品を表示するブロックを追加していきましょう。
ECCUBE2系の頃とは作り方すっかり変わっていますが、慣れてしまえば簡単な追加はやりやすいです。

最終的な表示は下記の様になります。

まずは管理画面からブロックを追加しましょう。
コンテンツ管理>ブロック管理から新規入力で追加します。

それぞれ下記の様に入力します。ブロックデータはとりあえず何か入力しておきます。
ブロック名 最近購入された商品
ファイル名 recentPurchase.twig
ブロックデータ hoge

登録するとデータベースのdtb_blockに追加されます。
今回はただの画像やテキストを表示するブロックではなく、データベースから値を取得して表示するため、dtb_blockのlogic_flgを0から1に変更します。
logic_flgを1にするとFrontControllerProviderにコントローラーを探しに行きます。

次は、FrontControllerProviderにコントローラーを登録します。
/eccube/src/Eccube/ControllerProvider/FrontControllerProvider.php
75~79行目あたりのblockが定義されてるあたりに下記行を追加
$c->match('/block/recentPurchase', '\Eccube\Controller\Block\recentPurchaseController::index')->bind('block_recentPurchase');

登録したコントローラーを作成します。
下記ファイルを新規作成。
/eccube/src/Eccube/Controller/Block/recentPurchaseController.php

内容は下記のとおり。
namespace Eccube\Controller\Block;

use Eccube\Application;

class recentPurchaseController
{
    public function index(Application $app)
    {
        $OrderList = $app['orm.em']->getRepository('\Eccube\Entity\OrderDetail')
            ->findBy(
                array(),
                array('id' => 'DESC')
            );

        return $app['view']->render('Block/recentPurchase.twig', array(
            'OrderList' => $OrderList,
        ));
    }
}

コントローラーに登録が出来ましたので、下記twigを作成していきます。
/eccube/src/Eccube/Resource/template/default/Block/recentPurchase.twig

中身は下記の通り、新着商品のcss使いまわしてます。レスポンシブデザインにも対応してます。
<div id="contents_top">
  <div id="item_list">

    <div class="col-sm-12">
      <h2 class="heading00">最近購入された商品</h2>
    </div>

    <div class="row">
      {% for Order in OrderList | slice(0,8) %}
        <div class="col-sm-3 col-xs-6">
            <div class="pickup_item">
                <span class="date">{{ Order.Order.order_date|date("Y年m月d日H時i分") }}</span>
                <a href="{{ url('product_detail', {'id': Order.Product.id}) }}">
                    <div class="item_photo"><img src="{{ app.config.image_save_urlpath }}/{{ Order.Product.main_list_image|no_image_product }}"></div>
                    <dd class="item_comment">{{Order.Product.description_detail[:30] ~ '...' }}</p>
                    <dl>
                      <dt class="item_name">{{Order.product_name}}</dt>
                      <dd class="item_price">{{ Order.Price }}</dd>
                    </dl>
                </a>
            </div>
      </div>
      {% endfor %}
    </div>
    
  </div>
</div>

最後に管理画面のコンテンツ管理>ページ管理、該当のページのレイアウト管理から最近購入された商品ブロックを好きな所に配置します。

以上で8件の最近購入された商品が表示されます。


2015年7月14日火曜日

ECCUBE3正式版のインストール(さくらVPS)

さくらVPSサーバへ晴れて正式に3となったECCUBEをサーバーへインストールしていきす。

サーバーの構成とバージョンは下記
CentOS:6.6
Apache:2.2.15
PHP:5.6.10
PostgreSQL:9.4.1

phpPgAdminはインストールされているものとします。

EC-CUBE3のシステム要件は下記
Apache 2.2.x 以上 2.4.x 以上
PHP5.3.9以降
PostgreSQL 8.4.x以降 9.x以降
MySQL5.1.x以降 MySQL5.5.x以降

となっているので、sshでサーバーにログインし、各バージョンを確認してください。
Apacheの確認
httpd -v

phpのバージョンの確認
php -v

PostgreSQLのバージョンの確認
psql --version

MySQLのバージョンの確認
(Distribの方を見て下さい)
mysql --version

バージョンが要件を満たしていない場合は各自アップデートしてください。

さて、インストールにあたり、ECCUBE本体をダウンロードしてきます。
ECCUBEダウンロードページ
今回は3.0.1のバージョンでやっています。

ダウンロードしたものをzipのまま、FTPで/var/www/html/にアップロード。
SSHでアップロードした階層に移動
cd /var/www/html
解凍
unzip eccube-3.0.1.zip
zipファイルは消します。
rm eccube-3.0.1.zip
フォルダの名前を変更
mv eccube-3.0.1 eccube

インストールしていきます。
http://サイトURL/eccube/html へアクセス

インストールが始まります。
「次へ進むをクリック」

アクセス権のチェック。異常がある場合は、FTP等でパーミッションをチェックしてみて下さい。

お店の設定をします。

データベースの設定をします。

問題なければデータベースの初期化が始まります。

完了です!


ドキュメントルートを変更しましょう。
vi /etc/httpd/conf/httpd.conf
下記行を探して
DocumentRoot "/var/www/html"
下記に変更します。
DocumentRoot "/var/www/html/eccube/html"

下記URLでECCUBEのトップ画面が表示されるようになります。
http://サイトURL/

管理画面はインストール時に決めたURLでアクセス可能です。
http://サイトURL/★管理画面のURL★

インストールがうまく行かなければhttp://サイトURL/install.phpにアクセスすれば再インストール可能です。
インストール出来た後はhtml/install.phpのファイルを削除して下さい。

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