それでも「jQuery Mobile + DW 」でスマホサイト制作を教えたいと思う理由。
いろいろあって、「jQuery Mobile + DreamWeaber 」でのスマホサイト制作を教えることはなくなったわけですが、それでも「jQuery Mobile + DreamWeaber 」でのスマホサイト制作を教えたい理由を。
総務省の資料(モバイルコンテンツの産業構造実態に関する調査結果 H23.7)によると、2010年のモバイルビジネス市場は1兆6465億円。
そのうち動画や音楽、電子書籍等のBitコンテンツ市場が6465億円。
通信販売やオークションの利用料などからなるモバイルコマース関連、つまりmatコンテンツ市場が1兆85億円。
モバイルコマース市場がついに1兆円を超えたわけです。
うーん…これは…。
僕は10年ほど前からケータイキャリアはいずれ、matコンテンツビジネスに何らかの形で関わって来ると思っていたのですが、やっぱりケータイ決済というカタチで関わってきたわけで…。
結局、「消費する」ということに関して言えば、bitコンテンツはmatコンテンツにかなわないわけで、案の定…という感じです。
※bitコンテンツ = デジタルコンテンツは、要は0101…の信号の集合体なので最小単位「bit」からなるコンテンツ。
※matコンテンツ = 形ある「物質(material)」としてのモノをコンテンツに見立てて読んでます。
この二つは僕が勝手にそう呼んでいるだけなので、あしからず。
既にモバイルコマース市場は、Eコマース市場7.8兆円の実に12%強を占めているわけで、決して無視できない市場なわけです。
モバイルコマース市場の中では、どのような内訳になっているかというと…。
・トランザクション系(株取引など):1580億円
・サービス系(ホテル宿泊や交通費など):4109億円
・物販系(商品の通信販売):4392億円
となっていて、物販系モバイルコマースのEコマース市場に占める割合は5.6%ということになっています。
5.6%? かなり少ない!
…果たしてそうでしょうか?
5.6%ってかなり大きいですよ。
少なくとも消費税よりは(笑)
物販系モバイルコマースの中でも、一番の伸び率を誇るのが「スマートフォン」です。
2009年12月と2010年12月を比べると、なんと8倍以上の成長率なんだとか。
Eコマース市場の2009~2010年の成長率は116%です。
その中でスマートフォンからの利用は800%になっているんですよ、お父さん!(なんだこれ)
…というわけでスマホサイト制作は、これからEコマースをやってく上で必ず必要になってきます。
というより、今がチャンス。
現状では、全Eコマースサイトにおけるスマートフォン向けサイトは1%に満たないという試算もあります。
いずれガラケーが消えてなくなることを考えると、今からスマホ市場で名前を売っておいたほうが得策のような気がします。
PC向けのEコマースサイトがどれくらいあるかは知りませんが、とても昨日今日ネットショップを始めました…という人間が勝ち抜いていけるような甘い世界ではありません。
モバイルコマースを除く6.8兆円の市場を、海千山千の魑魅魍魎が奪い合っているわけです。
そう、そこはまさに地獄絵図の世界そのもの。
一方、まだまだ成長途上のスマホサイトの方はといえば…。
PC向けより圧倒的にライバルが少ない上に、何といっても1年で800%もの高成長率を誇ります。
今からなら、まだ間に合う。
ライバルの少ない、高成長率が約束された市場に一早く参入するのは商売の基本ですよ、お母さん!(←だからなんだよこれ)
jQuery Mobileは、1年ほどのベータ版の間に、モバイル開発のスタンダードとも言える地位を築き上げました。
正式版のリリースは、先月(2011年11月)です。
ということで2011年12月現在、沖縄の基金訓練校でjQuery Mobileを使ってスマートフォンサイトの制作を教えていたのは、多分僕だけでしょう。
数あるライブラリの中から僕がjQuery Mobileを選んだ理由は、次のとおり。
・広範囲のプラットフォームをサポート
これはもう、言うことなしです。
スマホ端末向けのサイトを構築する場合、特に問題となる複数のプラットフォームやウェブブラウザに対応しなければならないという点。日本で販売されているスマホで言うと、iOS(iPhoneやiPodなど)、Android、Windows Phone(これは本当は無視したい)、BlackBerry…といったところでしょうか。
搭載ブラウザについても、プラットフォームにプリインストールされているものの他にも選択肢があって、それぞれで動作が多少異なります。
そもそも、ブラウザはバージョンの違いによる影響も結構大きいですし。
関係ないんですが、PC向けのブラウザでいえばIEは特に酷い。
IEのバージョンを変更するとMSNのトップページのレイアウトが崩れるくらいですから、これはもうダメだろう…と。
jQuery Mobileは、プラットフォームやウェブブラウザの違いをフレームワークのレイヤーで吸収し、同じコードベースから、端末ごとに最適化されたウェブアプリを構築できるようにするという目的のもとで開発されたそうです。
jQuery Mobileを使って開発すれば、個別にカスタマイズすることなくサイト制作が容易に出来ます。
この守備範囲の広さは、他のライブラリでは太刀打ちできませぬ。
どんだけ雑食なんだよお前は…。
まあ、そこがいいわけですが。
・HTML5でマークアップ
これ(HTML5)、もうやっとかないといけないな…と思うんですよ。
HTML5によるフツーのサイトを構築するのと同じ感覚でマークアップを記述すれば、自動的にモバイルに対応したインターフェースに変換してくれる。
これは大きいですよ、正直。
HTMLコードが単純明快なので、HTML5の構造・記述方法のお勉強にもなります。
・そもそも、JavaScriptを書かなくていい
PCでjQueryを使う場合には、少しはコードを書かなくちゃいけないわけです。
$("CSSセレクタ名").アクション(function(){
メソッド
);
こんな感じで。
プラグインを使う場合とか、もっと沢山書く場合もあります。
jQuery Mobileは、タグにちょっと設定(data-*属性)を書くだけ。
listviewが設定されてる<ul>タグに「data-filter="true"」って書くだけで、リストをフィルタリングする検索ウィンドウが実装できちゃうのは、ホントすごい。
かなりの便利機能です。
jQuery Mobileなので、当然他のjQueryプラグインとの相性も良いです。
・DreamWearver CS5.5との相性
というより、DreamWeaver CS5.5は、これのためのマイナーバージョンアップなんだろうな、きっと。
CDNでサイト制作を選ぶと自動的にテンプレートサイトが呼び出され、あとは「挿入」タブの中から使いたいコンポーネントを選ぶだけで実装できるのには正直驚きました。
・ネイティブアプリの開発もサポート
スマホ端末向けには、ウェブアプリではなくネイティブアプリで提供したい…というニーズもあります。
jQuery Mobileは、PhoneGapと併用することでWebアプリケーションをネイティブアプリに変換できます。もちろん、Appストアでの販売もおk。
PhoneGapをAdobeが買収した…ということを考えると「DreamWeaver CS6」は当然
「DreamWeaver + PhoneGap + jQuery mobile」路線でいくことは間違いなし。
(゚∀゚)キタコレ!!
jQuery Mobileは公式にPhoneGapをサポートしているし、同じものをコード変更の手間(というより難しいアプリ開発の手間)をすることなく、ウェブアプリとネイティブアプリの両方の形で提供できるのは素晴らしい。
これだけの理由があって、スマホサイトを教えない理由はハッキリ言ってないです。
僕が教えているのは「スマホサイト制作」でも「HTML5」でもなく、あくまでも「ネットショップ制作に必要なスキル」なのですね。
総務省の資料(モバイルコンテンツの産業構造実態に関する調査結果 H23.7)によると、2010年のモバイルビジネス市場は1兆6465億円。
そのうち動画や音楽、電子書籍等のBitコンテンツ市場が6465億円。
通信販売やオークションの利用料などからなるモバイルコマース関連、つまりmatコンテンツ市場が1兆85億円。
モバイルコマース市場がついに1兆円を超えたわけです。
うーん…これは…。
僕は10年ほど前からケータイキャリアはいずれ、matコンテンツビジネスに何らかの形で関わって来ると思っていたのですが、やっぱりケータイ決済というカタチで関わってきたわけで…。
結局、「消費する」ということに関して言えば、bitコンテンツはmatコンテンツにかなわないわけで、案の定…という感じです。
※bitコンテンツ = デジタルコンテンツは、要は0101…の信号の集合体なので最小単位「bit」からなるコンテンツ。
※matコンテンツ = 形ある「物質(material)」としてのモノをコンテンツに見立てて読んでます。
この二つは僕が勝手にそう呼んでいるだけなので、あしからず。
それはさておき…。
既にモバイルコマース市場は、Eコマース市場7.8兆円の実に12%強を占めているわけで、決して無視できない市場なわけです。
モバイルコマース市場の中では、どのような内訳になっているかというと…。
・トランザクション系(株取引など):1580億円
・サービス系(ホテル宿泊や交通費など):4109億円
・物販系(商品の通信販売):4392億円
となっていて、物販系モバイルコマースのEコマース市場に占める割合は5.6%ということになっています。
5.6%? かなり少ない!
…果たしてそうでしょうか?
5.6%ってかなり大きいですよ。
少なくとも消費税よりは(笑)
物販系モバイルコマースの中でも、一番の伸び率を誇るのが「スマートフォン」です。
2009年12月と2010年12月を比べると、なんと8倍以上の成長率なんだとか。
Eコマース市場の2009~2010年の成長率は116%です。
その中でスマートフォンからの利用は800%になっているんですよ、お父さん!(なんだこれ)
…というわけでスマホサイト制作は、これからEコマースをやってく上で必ず必要になってきます。
というより、今がチャンス。
現状では、全Eコマースサイトにおけるスマートフォン向けサイトは1%に満たないという試算もあります。
いずれガラケーが消えてなくなることを考えると、今からスマホ市場で名前を売っておいたほうが得策のような気がします。
PC市場は飽和状態で今から力を入れてもお金がかりすぎる
PC向けのEコマースサイトがどれくらいあるかは知りませんが、とても昨日今日ネットショップを始めました…という人間が勝ち抜いていけるような甘い世界ではありません。
モバイルコマースを除く6.8兆円の市場を、海千山千の魑魅魍魎が奪い合っているわけです。
そう、そこはまさに地獄絵図の世界そのもの。
一方、まだまだ成長途上のスマホサイトの方はといえば…。
PC向けより圧倒的にライバルが少ない上に、何といっても1年で800%もの高成長率を誇ります。
今からなら、まだ間に合う。
ライバルの少ない、高成長率が約束された市場に一早く参入するのは商売の基本ですよ、お母さん!(←だからなんだよこれ)
なぜ「jQuery Mobile」なのか
jQuery Mobileは、1年ほどのベータ版の間に、モバイル開発のスタンダードとも言える地位を築き上げました。
正式版のリリースは、先月(2011年11月)です。
ということで2011年12月現在、沖縄の基金訓練校でjQuery Mobileを使ってスマートフォンサイトの制作を教えていたのは、多分僕だけでしょう。
数あるライブラリの中から僕がjQuery Mobileを選んだ理由は、次のとおり。
・広範囲のプラットフォームをサポート
これはもう、言うことなしです。
スマホ端末向けのサイトを構築する場合、特に問題となる複数のプラットフォームやウェブブラウザに対応しなければならないという点。日本で販売されているスマホで言うと、iOS(iPhoneやiPodなど)、Android、Windows Phone(これは本当は無視したい)、BlackBerry…といったところでしょうか。
搭載ブラウザについても、プラットフォームにプリインストールされているものの他にも選択肢があって、それぞれで動作が多少異なります。
そもそも、ブラウザはバージョンの違いによる影響も結構大きいですし。
関係ないんですが、PC向けのブラウザでいえばIEは特に酷い。
IEのバージョンを変更するとMSNのトップページのレイアウトが崩れるくらいですから、これはもうダメだろう…と。
jQuery Mobileは、プラットフォームやウェブブラウザの違いをフレームワークのレイヤーで吸収し、同じコードベースから、端末ごとに最適化されたウェブアプリを構築できるようにするという目的のもとで開発されたそうです。
jQuery Mobileを使って開発すれば、個別にカスタマイズすることなくサイト制作が容易に出来ます。
この守備範囲の広さは、他のライブラリでは太刀打ちできませぬ。
どんだけ雑食なんだよお前は…。
まあ、そこがいいわけですが。
・HTML5でマークアップ
これ(HTML5)、もうやっとかないといけないな…と思うんですよ。
HTML5によるフツーのサイトを構築するのと同じ感覚でマークアップを記述すれば、自動的にモバイルに対応したインターフェースに変換してくれる。
これは大きいですよ、正直。
HTMLコードが単純明快なので、HTML5の構造・記述方法のお勉強にもなります。
・そもそも、JavaScriptを書かなくていい
PCでjQueryを使う場合には、少しはコードを書かなくちゃいけないわけです。
$("CSSセレクタ名").アクション(function(){
メソッド
);
こんな感じで。
プラグインを使う場合とか、もっと沢山書く場合もあります。
jQuery Mobileは、タグにちょっと設定(data-*属性)を書くだけ。
listviewが設定されてる<ul>タグに「data-filter="true"」って書くだけで、リストをフィルタリングする検索ウィンドウが実装できちゃうのは、ホントすごい。
かなりの便利機能です。
jQuery Mobileなので、当然他のjQueryプラグインとの相性も良いです。
・DreamWearver CS5.5との相性
というより、DreamWeaver CS5.5は、これのためのマイナーバージョンアップなんだろうな、きっと。
CDNでサイト制作を選ぶと自動的にテンプレートサイトが呼び出され、あとは「挿入」タブの中から使いたいコンポーネントを選ぶだけで実装できるのには正直驚きました。
・ネイティブアプリの開発もサポート
スマホ端末向けには、ウェブアプリではなくネイティブアプリで提供したい…というニーズもあります。
jQuery Mobileは、PhoneGapと併用することでWebアプリケーションをネイティブアプリに変換できます。もちろん、Appストアでの販売もおk。
PhoneGapをAdobeが買収した…ということを考えると「DreamWeaver CS6」は当然
「DreamWeaver + PhoneGap + jQuery mobile」路線でいくことは間違いなし。
(゚∀゚)キタコレ!!
jQuery Mobileは公式にPhoneGapをサポートしているし、同じものをコード変更の手間(というより難しいアプリ開発の手間)をすることなく、ウェブアプリとネイティブアプリの両方の形で提供できるのは素晴らしい。
これだけの理由があって、スマホサイトを教えない理由はハッキリ言ってないです。
僕が教えているのは「スマホサイト制作」でも「HTML5」でもなく、あくまでも「ネットショップ制作に必要なスキル」なのですね。
アメブロでjQueryとかのJavaScriptを使う方法。
いろいろと考えてみたら、
ブログを書く > サイドバーの設定 > プラグインの追加 > フリープラグイン
で
ってjQueryをCDNで読み込めばいいじゃん!…ってことに今更気づく。
もちろん、設定も
とか書いてあげればおk。
jQuery以外のライブラリ一覧は、こっから探してくださいな…と。
http://code.google.com/intl/ja/apis/libraries/devguide.html
おまけ。
ってやると、本文中に
で埋め込めるようです。。。
http://blog.livedoor.jp/jsmemo/archives/349192.html
▲
こことかみてると、やっぱり弾さんみたいにみんなブログでテストコード実行したいんだな…と思いました。
PDFにしたり画像にしたりするより、サンプルコード走らせたほうが早い!…みたいな。
僕も頭より先に手が動く(とりあえず作ってみる)んで、わかるなぁ…。
ただ、アメブロって「http://stat100.ameba.jp/blog/js/apm001.js」で
・jQuery JavaScript Library v1.3.2
・Sizzle CSS Selector Engine - v0.9.3
・Cookie plugin
の3つを読み込んでいるんで、特に外部から読み込む必要はないんですけどね。
▲▲ここをクリックでトップまでスクロール移動します▲▲
ブログを書く > サイドバーの設定 > プラグインの追加 > フリープラグイン
で
<script type="text/Javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
ってjQueryをCDNで読み込めばいいじゃん!…ってことに今更気づく。
もちろん、設定も
<script type="text/javascript">
$(document).ready(function () {
$("img").hover(function () {
$(this).fadeTo("fast", 0.6); // マウスオーバーで透明度を60%にする
}, function () {
$(this).fadeTo("fast", 1.0); // マウスアウトで透明度を100%に戻す
});
});
</script>
とか書いてあげればおk。
jQuery以外のライブラリ一覧は、こっから探してくださいな…と。
http://code.google.com/intl/ja/apis/libraries/devguide.html
おまけ。
<script type="text/javascript">
(function() {
var codes = document.body.innerHTML.match(/<pre [\w\s:;"=]*class="?eval"?[\w\s:;"=]*>((.|\n)*)<\/pre>/gi);
if (codes == null) return;
for (var i = 0; i < codes.length; i++) {
eval(codes[i].replace(/<\/pre>/i, "").replace(/<pre [\w\s:;"=]*class="?eval"?[\w\s:;"=]*>/i, ""));
}
})();
</script>
ってやると、本文中に
<pre class="eval" style="display:none">
ここにJavaScriptのコードを書く
</pre>
で埋め込めるようです。。。
http://blog.livedoor.jp/jsmemo/archives/349192.html
▲
こことかみてると、やっぱり弾さんみたいにみんなブログでテストコード実行したいんだな…と思いました。
PDFにしたり画像にしたりするより、サンプルコード走らせたほうが早い!…みたいな。
僕も頭より先に手が動く(とりあえず作ってみる)んで、わかるなぁ…。
ただ、アメブロって「http://stat100.ameba.jp/blog/js/apm001.js」で
・jQuery JavaScript Library v1.3.2
・Sizzle CSS Selector Engine - v0.9.3
・Cookie plugin
の3つを読み込んでいるんで、特に外部から読み込む必要はないんですけどね。
▲▲ここをクリックでトップまでスクロール移動します▲▲
冷凍と冷蔵は同梱できないのでクール便のコードを書き直しです。
商品A・通常商品
商品B・冷蔵商品
商品C・冷凍商品
の場合。
商品A+商品B = 送料+クール料金
商品A+商品C = 送料+(送料+クール料金)
商品B+商品C = (送料+クール料金)×2
商品A+商品B+商品C = (送料+クール料金)×2
ということで、送料を再計算。
その前に…。
まずはクール便のフラグを
0 = 通常
1 = 冷蔵
2 = 冷凍
で登録できるようにします。
data/Smarty/templates/admin/products/product.tpl
に以下の項目を追加。
12.15 追記
上記コード赤字部分修正しました!
「$arrForm.cool_flg != 0」から「$arrForm.cool_flg == 1」に
「$arrForm.cool_flg != 0」から「$arrForm.cool_flg == 2」に修正です
data/Smarty/templates/admin/products/confirm.tpl
に以下を追加。
登録周りはこれで完了。
DBいじったりするのは、この記事を参照。
で、ここからが書き直したコード。
data/class/SC_CartSession.phpの「function calculate()」を以下のようにする。
ということになります。
XAMPP + EC-CUBE2.11.4 でテストしましたが…。
追記。
赤字部分を追加しました。
冷凍便のみを購入した場合(通常便、冷蔵便ともにフラグが立っていない場合)には、送料が加算されてしまうのを防ぐためです。
商品B・冷蔵商品
商品C・冷凍商品
の場合。
商品A+商品B = 送料+クール料金
商品A+商品C = 送料+(送料+クール料金)
商品B+商品C = (送料+クール料金)×2
商品A+商品B+商品C = (送料+クール料金)×2
ということで、送料を再計算。
その前に…。
まずはクール便のフラグを
0 = 通常
1 = 冷蔵
2 = 冷凍
で登録できるようにします。
data/Smarty/templates/admin/products/product.tpl
に以下の項目を追加。
<tr>
<th>クール便フラグ
<td>
<span class="attention">
<select name="cool_flg">
<option value="0" <!--{if $arrForm.cool_flg == 0}-->selected<!--{/if}-->>常温便</option>
<option value="1" <!--{if $arrForm.cool_flg == 1}-->selected<!--{/if}-->>冷蔵便</option>
<option value="2" <!--{if $arrForm.cool_flg == 2}-->selected<!--{/if}-->>冷凍便</option>
</select>
</td>
</tr>
12.15 追記
上記コード赤字部分修正しました!
「$arrForm.cool_flg != 0」から「$arrForm.cool_flg == 1」に
「$arrForm.cool_flg != 0」から「$arrForm.cool_flg == 2」に修正です
data/Smarty/templates/admin/products/confirm.tpl
に以下を追加。
tr>
<th>クール便フラグ</th>
<td>
<!--{if $arrForm.cool_flg == 0}-->常温便
<!--{elseif $arrForm.cool_flg == 1}-->冷蔵便
<!--{else}-->冷凍便
<!--{/if}-->
</td>
</tr>
登録周りはこれで完了。
DBいじったりするのは、この記事を参照。
で、ここからが書き直したコード。
data/class/SC_CartSession.phpの「function calculate()」を以下のようにする。
function calculate($productTypeId, &$objCustomer, $use_point = 0,
$deliv_pref = "", $charge = 0, $discount = 0, $deliv_id = 0) {
$objDb = new SC_Helper_DB_Ex();
$total_point = $this->getAllProductsPoint($productTypeId);
$results['tax'] = $this->getAllProductsTax($productTypeId);
$results['subtotal'] = $this->getAllProductsTotal($productTypeId);
$results['deliv_fee'] = 0;
$cool_flg = "";
// 商品ごとの送料を加算
if (OPTION_PRODUCT_DELIV_FEE == 1) {
$cartItems = $this->getCartList($productTypeId);
foreach ($cartItems as $item) {
$results['deliv_fee'] += $item['productsClass']['deliv_fee'] * $item['quantity'];
}
}
// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1
&& !SC_Utils_Ex::isBlank($deliv_pref)
&& !SC_Utils_Ex::isBlank($deliv_id)) {
$results['deliv_fee'] += $objDb->sfGetDelivFee($deliv_pref, $deliv_id);
}
$cartItems = $this->getCartList($productTypeId);
foreach($cartItems as $val){
//cool_flgが0なら、normal_flgをonに
if ( $normal_flg <> "on" ){
$normal_flg = ( $val["productsClass"]["cool_flg"] == 0 ) ? "on":"";
}
//cool_flgが1なら、冷蔵便フラグをonに
if ( $cool_flg <> "on" ){
$cool_flg = ( $val["productsClass"]["cool_flg"] == 1 ) ? "on":"";
}
//cool_flgが2なら、冷凍便フラグをonに
if ( $freez_flg <> "on" ){
$freez_flg = ( $val["productsClass"]["cool_flg"] == 2 ) ? "on":"";
}
}
//クール便の場合はクール料金をプラス
if ($cool_flg == "on") { $results['deliv_fee'] += 210; }
//冷凍便の場合は地域送料+クール料金を別途プラス(同梱不可の為)
if ($freez_flg == "on") {
$pref_deliv = $objDb->sfGetDelivFee($deliv_pref, $deliv_id);
$results['deliv_fee'] += ( $pref_deliv + 210 );
if ($cool_flg != "on" && $normal_flg != "on" ){ $results['deliv_fee']-=$pref_deliv; }
}
// 送料無料チェック
if ($this->isDelivFree($productTypeId)) {
$results['deliv_fee'] = 0;
}
//=====複数配送の場合の処理=============================================
if ( count($_SESSION['shipping']) > 1 ){
//---------[初期処理]-------------
//とりあえず、$results['deliv_fee']を0にしておく
$results['deliv_fee'] = 0;
//何人目かを記録しておくためのフラグ
$multi = 0;
//店舗基本情報を取得
$objDb = new SC_Helper_DB_Ex();
$arrInfo = $objDb->sfGetBasisData();
//---------[初期処理終了]---------
//人数分の繰り返し
foreach ( $_SESSION['shipping'] as $deli) {
//冷凍・冷蔵フラグを初期化
$normal_flg = "";//追加
$cool_flg = "";
$freez_flg = "";
//フラグ関係を初期化
$total_indiv = 0;
//商品のコードを配列から取得
$temp_list = $deli['shipment_item'];
$item = array_keys( $temp_list );
//商品分の繰り返し
for ($loop = 0; $loop < count($item); $loop++){
$item_code = $item[$loop];
$quant = $item_code;
$quantity = $deli['shipment_item'][$quant]['quantity'];
//商品価格
$price = $deli['shipment_item'][$quant]["productsClass"]["price02"];
//商品個別送料
$deliv = $deli['shipment_item'][$quant]["productsClass"]["deliv_fee"];
//冷蔵便フラグ
if ( $normal_flg <> "on" ) {
$normal_flg = ( $deli['shipment_item'][$quant]["productsClass"]["cool_flg"] == 1) ? "on":"";
}
if ( $cool_flg <> "on" ) {
$cool_flg = ( $deli['shipment_item'][$quant]["productsClass"]["cool_flg"] == 1) ? "on":"";
}
//冷凍便
if ( $freez_flg <> "on" ) {
$freez_flg = ( $deli['shipment_item'][$quant]["productsClass"]["cool_flg"] == 2) ? "on":"";
}
// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1) {
$deliv = $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"]);
}
//商品の購入金額
$temp_indiv = $price * $quantity;
$total_indiv += $temp_indiv;
//送料の計算(商品毎に加算)
$deliv_fee .= $deliv;
//送料の合計が最大送料(配送地域別送料)を超えたら、送料は地域別送料に
if ( $deliv_fee > $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"])) {
$deliv_fee = $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"]);
}
}//商品分の繰り返し
//冷蔵便の処理
if ( $cool_flg == "on" && $deliv_fee <> 0) { $deliv_fee += 210; }
//冷凍便の場合は地域送料+クール料金を別途プラス(同梱不可の為)
if ($freez_flg == "on") {
$pref_deliv = $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"]);
$deliv_fee += ( $pref_deliv + 210 );
}
// 送料無料条件が設定されている場合
if ($arrInfo['free_rule'] > 0) {
// 小計が無料条件を超えている場合
if( $total_indiv >= $arrInfo['free_rule']) {
$deliv_fee = 0;
if ($cool_flg != "on" && $normal_flg != "on" ){
$deliv_fee-=$pref_deliv;
}
}
}
//全注文の総トータル送料に個別送料を加算していく
$results['deliv_fee'] += $deliv_fee;
//送料と合計金額をセッションに保存(comfirm.tpl表示用)
$_SESSION['multi_deliv'][$multi]['deliv_fee'] = $deliv_fee;
$_SESSION['multi_deliv'][$multi]['total_indiv'] = $total_indiv;
$multi++;
}//人数分の繰り返し
}//if
//====複数配送の場合の送料再計算終了==============================
// 合計を計算
$results['total'] = $results['subtotal'];
$results['total'] += $results['deliv_fee'];
$results['total'] += $charge;
$results['total'] -= $discount;
// お支払い合計
$results['payment_total'] = $results['total'] - $use_point * POINT_VALUE;
// 加算ポイントの計算
if (USE_POINT !== false) {
$results['add_point'] = SC_Helper_DB_Ex::sfGetAddPoint($total_point,$use_point);
if($objCustomer != "") {
// 誕生日月であった場合
if($objCustomer->isBirthMonth()) {
$results['birth_point'] = BIRTH_MONTH_POINT;
$results['add_point'] += $results['birth_point'];
}
}
if($results['add_point'] < 0) {
$results['add_point'] = 0;
}
}
return $results;
}//function calculate()
ということになります。
XAMPP + EC-CUBE2.11.4 でテストしましたが…。
追記。
赤字部分を追加しました。
冷凍便のみを購入した場合(通常便、冷蔵便ともにフラグが立っていない場合)には、送料が加算されてしまうのを防ぐためです。
掲載コードについて
EC-CUBEネタの多いこのブログですが、僕自身が会社の仕事でEC-CUBEのカスタマイズなどをやっているのでそうしたコードを掲載している…と思う人も多いとは思います。
えー。
念のため言っておきます。
仕事で書いたコードはそのまま掲載するはずがありません。
オリジナルのDBとか使っていろいろやってますからね。
そういうコードを掲載出来る訳はありません。
全て、ブログ掲載用に書き直したコードです。
ブログ掲載用に書きなおすことで、自分のコードをもう一度よく見直すことができる…というメリットがあるのでやっているわけで。
そうやって、見直したコードを後から使いまわせるのはいいことだと思うのです。
このブログの一番の読者は自分ですから。
えー。
念のため言っておきます。
仕事で書いたコードはそのまま掲載するはずがありません。
オリジナルのDBとか使っていろいろやってますからね。
そういうコードを掲載出来る訳はありません。
全て、ブログ掲載用に書き直したコードです。
ブログ掲載用に書きなおすことで、自分のコードをもう一度よく見直すことができる…というメリットがあるのでやっているわけで。
そうやって、見直したコードを後から使いまわせるのはいいことだと思うのです。
このブログの一番の読者は自分ですから。
"eccube2.11"で検索す るとこのブログがヒットしやすい。
「eccube2.11」
「eccube2.11」と「カスタマイズ」
「eccube2.11」と「送料」
「eccube2.11」と「クール便」
こんなんで検索すると、上位に表示されるのがこのブログ。
「eccube 2.11」って感じで「eccube」と「2.11」を切り離すとそんなことはないんですが…。
現在
「eccube2.11」だと1~3位を独占。
「eccube2.11」と「カスタマイズ」だと1~2位と13位に。
「eccube2.11」と「送料」だと1~3位、5位、7位。
「eccube2.11」と「クール便」だと、僕のブログしかヒットしません。
ちなみに
「eccube」と「2.11」と「クール便」の3つで検索すると
1位は「EC-CUBE開発コミュニティの記事」
2位は「EC-CUBEデモサイト」
ときて、
3~5位に僕のブログが来てます。
GoogleAdWordsのキーワードツールによると「eccube」そのものの検索数が「60500」なので、あまり効果はないんですけどね。
「eccube2.11」と「カスタマイズ」
「eccube2.11」と「送料」
「eccube2.11」と「クール便」
こんなんで検索すると、上位に表示されるのがこのブログ。
「eccube 2.11」って感じで「eccube」と「2.11」を切り離すとそんなことはないんですが…。
現在
「eccube2.11」だと1~3位を独占。
「eccube2.11」と「カスタマイズ」だと1~2位と13位に。
「eccube2.11」と「送料」だと1~3位、5位、7位。
「eccube2.11」と「クール便」だと、僕のブログしかヒットしません。
ちなみに
「eccube」と「2.11」と「クール便」の3つで検索すると
1位は「EC-CUBE開発コミュニティの記事」
2位は「EC-CUBEデモサイト」
ときて、
3~5位に僕のブログが来てます。
GoogleAdWordsのキーワードツールによると「eccube」そのものの検索数が「60500」なので、あまり効果はないんですけどね。
クール便フラグのコードにミスがありました。
クール便フラグの処理にミスが有りました。
訂正します。
つまり、クール便と通常商品を同時購入した際、foreachのフラグ判定のところで通常商品の判定がクール便判定より後に来ると、フラグが通常便扱いに戻ってしまうので
if ( $cool_flg != "on"){}
を追加したということです。
チェックミスです…大変申し訳ありませんでした。
追記。
最新記事を見てくださーい。
訂正します。
function getAllCartList() {
$results = array();
$cartKeys = $this->getKeys();
$i = 0;
foreach ($cartKeys as $key) {
$cartItems = $this->getCartList($key);
foreach (array_keys($cartItems) as $itemKey) {
$cartItem =& $cartItems[$itemKey];
$results[$key][$i] =& $cartItem;
$i++;
//追加
$cool_flg = ( $cartItem["productsClass"]["cool_flg"] > 0 )? "on":"off";
}
}
return $results;
}
▼やっぱり、これは下の状態のままにします▼
function getAllCartList() {
$results = array();
$cartKeys = $this->getKeys();
$i = 0;
foreach ($cartKeys as $key) {
$cartItems = $this->getCartList($key);
foreach (array_keys($cartItems) as $itemKey) {
$cartItem =& $cartItems[$itemKey];
$results[$key][$i] =& $cartItem;
$i++;
}
}
return $results;
}
function calculate($productTypeId, &$objCustomer, $use_point = 0,
$deliv_pref = "", $charge = 0, $discount = 0, $deliv_id = 0) {
$objDb = new SC_Helper_DB_Ex();
$total_point = $this->getAllProductsPoint($productTypeId);
$results['tax'] = $this->getAllProductsTax($productTypeId);
$results['subtotal'] = $this->getAllProductsTotal($productTypeId);
$results['deliv_fee'] = 0;
$cool_flg = "";
// 商品ごとの送料を加算
if (OPTION_PRODUCT_DELIV_FEE == 1) {
$cartItems = $this->getCartList($productTypeId);
foreach ($cartItems as $item) {
$results['deliv_fee'] += $item['productsClass']['deliv_fee'] * $item['quantity'];
}
}
// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1
&& !SC_Utils_Ex::isBlank($deliv_pref)
&& !SC_Utils_Ex::isBlank($deliv_id)) {
$results['deliv_fee'] += $objDb->sfGetDelivFee($deliv_pref, $deliv_id);
}
//クール便かどうか判定
$cartItems = $this->getCartList($productTypeId);
foreach($cartItems as $val){
if ( $cool_flg != "on" ){
$cool_flg = ( $val["productsClass"]["cool_flg"] <> 0 ) ? "on":"";
}
}
//$cool_flgが"on"で送料が0円でなければ、クール料金加算
//送料0円でもクール代金は上乗せする場合は「&& $deliv_fee <> 0」を外して
//「// 送料無料チェック」の下に処理を移動
if ($cool_flg == "on" && $results['deliv_fee'] <> 0) {
$results['deliv_fee'] += 210;
}
// 送料無料チェック
if ($this->isDelivFree($productTypeId)) {
$results['deliv_fee'] = 0;
}
//=======複数配送の場合の処理=============================================
if ( count($_SESSION['shipping']) > 1 ){
//---------[初期処理]-------------
//とりあえず、$results['deliv_fee']を0にしておく
$results['deliv_fee'] = 0;
//flagsも初期化
$flags = "";
//何人目かを記録しておくためのフラグ
$multi = 0;
//店舗基本情報を取得
$objDb = new SC_Helper_DB_Ex();
$arrInfo = $objDb->sfGetBasisData();
//---------[初期処理終了]---------
//人数分の繰り返し
foreach ( $_SESSION['shipping'] as $deli) {
//クールフラグを初期化
$cool_flg = "";
//フラグ関係を初期化
$total_indiv = 0;
//商品のコードを配列から取得
$temp_list = $deli['shipment_item'];
$item = array_keys( $temp_list );
//商品分の繰り返し
for ($loop = 0; $loop < count($item); $loop++){
$item_code = $item[$loop];
$quant = $item_code;
$quantity = $deli['shipment_item'][$quant]['quantity'];
//商品価格
$price = $deli['shipment_item'][$quant]["productsClass"]["price02"];
//商品個別送料
$deliv = $deli['shipment_item'][$quant]["productsClass"]["deliv_fee"];
//クール便フラグ
if ( $cool_flg != "on" ) {
$cool_flg = ( $deli['shipment_item'][$quant]["productsClass"]["cool_flg"] > 0) ? "on":"";
}
// 配送業者の送料を加算
if (OPTION_DELIV_FEE == 1) {
$deliv = $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"]);
}
//商品の購入金額
$temp_indiv = $price * $quantity;
$total_indiv += $temp_indiv;
//送料の計算(商品毎に加算)
$deliv_fee .= $deliv;
//送料の合計が最大送料(配送地域別送料)を超えたら、送料は地域別送料に
if ($deliv_fee > $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"])){
$deliv_fee = $objDb->sfGetDelivFee($deli["shipping_pref"], $deli["deliv_id"]);
}
}//商品分の繰り返し
//$cool_flgが"on"で送料が0円でなければ、クール料金加算
//送料0円でもクール代金は上乗せする場合は「&& $deliv_fee <> 0」を外して
//「// 送料無料条件が設定されている場合」の下に処理を移動
if ( $cool_flg == "on" && $deliv_fee <> 0) { $deliv_fee += 210; }
// 送料無料条件が設定されている場合
if ($arrInfo['free_rule'] > 0) {
// 小計が無料条件を超えている場合
if( $total_indiv >= $arrInfo['free_rule']) {
$deliv_fee = 0;
}
}
//全注文の総トータル送料に個別送料を加算していく
$results['deliv_fee'] += $deliv_fee;
//送料と合計金額をセッションに保存(comfirm.tpl表示用)
$_SESSION['multi_deliv'][$multi]['deliv_fee'] = $deliv_fee;
$_SESSION['multi_deliv'][$multi]['total_indiv'] = $total_indiv;
$multi++;
}//人数分の繰り返し
}//if
//========================複数配送の場合の送料再計算==============================
// 合計を計算
$results['total'] = $results['subtotal'];
$results['total'] += $results['deliv_fee'];
$results['total'] += $charge;
$results['total'] -= $discount;
// お支払い合計
$results['payment_total'] = $results['total'] - $use_point * POINT_VALUE;
// 加算ポイントの計算
if (USE_POINT !== false) {
$results['add_point'] = SC_Helper_DB_Ex::sfGetAddPoint($total_point,
$use_point);
if($objCustomer != "") {
// 誕生日月であった場合
if($objCustomer->isBirthMonth()) {
$results['birth_point'] = BIRTH_MONTH_POINT;
$results['add_point'] += $results['birth_point'];
}
}
if($results['add_point'] < 0) {
$results['add_point'] = 0;
}
}
return $results;
}
つまり、クール便と通常商品を同時購入した際、foreachのフラグ判定のところで通常商品の判定がクール便判定より後に来ると、フラグが通常便扱いに戻ってしまうので
if ( $cool_flg != "on"){}
を追加したということです。
チェックミスです…大変申し訳ありませんでした。
追記。
最新記事を見てくださーい。
コメントをいただきました。
えー。。。
こないだ、ブログで公開したクール便のコードについてこんなコメントをいただきました。
今回のコードを公開して、心の底からよかったと思います。
本来、僕はこういうカスタマイズを商売にしているワケでコードをそっくり公開するのはどうか…という見方もあります。
ただ、他のインテグレートパートナーもグレードが高いインテグレートパートナーになればなるほど(?)、こうしたコードを公開したりしています。(´∀`)
結局のところ、こういうコードは自分が公開しなくてもいずれ誰かが公開するもんなので、誰よりも先に…というのは常に意識してます。
現状では、複数配送時の配送先毎の送料計算に関するコードは見かけたことがありません。
おお…このブログだけ?
もし見つけたら、教えてください。
自分で一つ発見したけど、僕のコードを参考にした…ということで、このブログにリンクが貼られていたので。
いずれ誰かが公開するような技術にしがみついて食べていくより、もっと上を目指してスキルを磨いていくほうが断然面白いんで…とは口が裂けても会社の社長の前では言えないんですけどね。
ただ、こういうところでコードを公開したほうが色々とツッコミもいただけますし、僕は個人でインテグレートパートナーに登録しているので、そういった生の声は貴重です。
さらに言ってしまうと、今回は僕の方こそ勉強になることもありました。
なにより、僕の書いたコードが、
お客様に便利に使っていただくことができるサイトへ近づきました
というのであれば、それはもうとても有難い話です。
少なくとも僕のコードが、この日本のどこかで「世界をちょっと良くする」ことに貢献しているのは間違いない。
((o(´∀`)o))ワクワクシチャウ
って感じですか?
いただいたコメントの中に、こんなのもありました。
( ;´Д`)いやぁぁぁぁぁー!
僕もまだ1年くらいなんですけどね…EC-CUBEをやりだしてから。
PHPもやり出してから1年半くらいです。
さらに言ってしまうと、HTMLとかCSSとかやり出して、ちょうど2年くらい。
しばらく (15年くらい) Webから離れている間に、CSSとかワケの分からないモノが…という感じでした。
Webをやっていたのは1996年とかその頃だったので、ゼロから勉強したわけです。
2年前にネカフェ難民として(笑)。
今だから笑い話になりますが、Google先生がいなかったらどうなっていたか。
元・ネカフェ難民だった僕が教えるのだから、当然学校では身になることを教えています。
これは間違いない。
ただ、僕の場合はGoogle先生の他にもう一人有能な先生がいました。
このサイトのシステム設計をやった有能な友人が。
リンク先に行ったら、ちょっと驚くかもしれません。
なにせ、誰もが知るあの企業ですから。
今でも、困ったこと(システム設計関係とか)があると相談にのってもらってます。
EC-CUBEに関しては、僕の方が断然詳しいんですが、上記のようなサイトともなると設計周りはEC-CUBEクラスの話ではないので。
彼から比べれば、まだまだ駆け出しです。
こないだ、ブログで公開したクール便のコードについてこんなコメントをいただきました。
おかげさまでクール便対応仕様に変更並びに
複数配送に送料を取得することができました!
こんな素人でもわかりやすいコードだと思います。
おかげさまでまた一歩、お客様に便利に使っていただくことができるサイトへ近づきました。
今回のコードを公開して、心の底からよかったと思います。
本来、僕はこういうカスタマイズを商売にしているワケでコードをそっくり公開するのはどうか…という見方もあります。
ただ、他のインテグレートパートナーもグレードが高いインテグレートパートナーになればなるほど(?)、こうしたコードを公開したりしています。(´∀`)
結局のところ、こういうコードは自分が公開しなくてもいずれ誰かが公開するもんなので、誰よりも先に…というのは常に意識してます。
現状では、複数配送時の配送先毎の送料計算に関するコードは見かけたことがありません。
おお…このブログだけ?
もし見つけたら、教えてください。
自分で一つ発見したけど、僕のコードを参考にした…ということで、このブログにリンクが貼られていたので。
いずれ誰かが公開するような技術にしがみついて食べていくより、もっと上を目指してスキルを磨いていくほうが断然面白いんで…とは口が裂けても会社の社長の前では言えないんですけどね。
ただ、こういうところでコードを公開したほうが色々とツッコミもいただけますし、僕は個人でインテグレートパートナーに登録しているので、そういった生の声は貴重です。
さらに言ってしまうと、今回は僕の方こそ勉強になることもありました。
なにより、僕の書いたコードが、
お客様に便利に使っていただくことができるサイトへ近づきました
というのであれば、それはもうとても有難い話です。
少なくとも僕のコードが、この日本のどこかで「世界をちょっと良くする」ことに貢献しているのは間違いない。
((o(´∀`)o))ワクワクシチャウ
って感じですか?
いただいたコメントの中に、こんなのもありました。
私はECCUBEを使いだして半年足らずの若輩者です。
PHPは全くの素人で、html、cssの知識が少しあるくらいです。
何とか今のショップはできています。
周りにはショップ作りに関する知識を持った者など一人もおらず、ネットで検索、本を少し読んだ程度でまだまだ知識不足です。
( ;´Д`)いやぁぁぁぁぁー!
僕もまだ1年くらいなんですけどね…EC-CUBEをやりだしてから。
PHPもやり出してから1年半くらいです。
さらに言ってしまうと、HTMLとかCSSとかやり出して、ちょうど2年くらい。
しばらく (15年くらい) Webから離れている間に、CSSとかワケの分からないモノが…という感じでした。
Webをやっていたのは1996年とかその頃だったので、ゼロから勉強したわけです。
2年前にネカフェ難民として(笑)。
今だから笑い話になりますが、Google先生がいなかったらどうなっていたか。
元・ネカフェ難民だった僕が教えるのだから、当然学校では身になることを教えています。
これは間違いない。
ただ、僕の場合はGoogle先生の他にもう一人有能な先生がいました。
このサイトのシステム設計をやった有能な友人が。
リンク先に行ったら、ちょっと驚くかもしれません。
なにせ、誰もが知るあの企業ですから。
今でも、困ったこと(システム設計関係とか)があると相談にのってもらってます。
EC-CUBEに関しては、僕の方が断然詳しいんですが、上記のようなサイトともなると設計周りはEC-CUBEクラスの話ではないので。
彼から比べれば、まだまだ駆け出しです。
FORMの中にFORMを入れ子…。
HTMLの<form>~</form>の中には別のformを入れ子出来ないような仕様になっているようで。
一つのformの中に、submit先が違うボタンがあるとか、そういう時に使うんでしょうか。
ec-cubeでも、カートページ内に商品購入ボタンを設置したいという要望がありまして、JavaScript(/js/site.js)を弄って対応したりする場合もあるようですが、別にそういうのはデザインで擬似的にやってしまえばいいことだと思います。
例えば、カートページの商品テーブル直下にお勧め商品一覧を表示して、その商品をカートインさせたい場合とかは、以下のようにすればいいだけです。
こんな感じで、ネガティブマージンを設定してあげればいいわけです。
たしかにJavaScriptは便利ですが、なんでもかんでもゴテゴテと使うのはどうかと。
There's more than one way to do it.
やり方は一つではないのだから、いろいろ試してみたいですよね。
いろいろやって、自分に合ったものを選べばいいのです。
個人的には、HTML + CSS で(現段階の自分の能力では)実現できないものに限り、JavaScriptを使うというスタンスで仕事をしています。
覚えたてのJavaScriptをゴテゴテと使ったサイトのせいで「JavaScriptは素人製作者が使うもの」というレッテルを貼られた時期もあったそうです…Ajaxの登場で見直される前までは。
JavaScript : The World's Most Misunderstood Programming Language
世界で最も誤解されたプログラミング言語であることは間違いないようです。
JavaScriptを書く人のほとんどはプログラマではありません。
彼らには良いプログラムを書くための教育と修行がたりません。(敢えて「修行」にしてみた)
しかしJavaScriptは、そんな彼らであってもとりあえず有用な仕事ができる、たくさんの表現方法があります。
そうしたことから、JavaScriptは完全にアマチュア向けの仕様の言語であって、プロユースのプログラミング言語ではないという評判をもたらしてしまいました。
この場合(JavaScriptの場合)は単純にそうであるとは言いきれません。

一つのformの中に、submit先が違うボタンがあるとか、そういう時に使うんでしょうか。
ec-cubeでも、カートページ内に商品購入ボタンを設置したいという要望がありまして、JavaScript(/js/site.js)を弄って対応したりする場合もあるようですが、別にそういうのはデザインで擬似的にやってしまえばいいことだと思います。
例えば、カートページの商品テーブル直下にお勧め商品一覧を表示して、その商品をカートインさせたい場合とかは、以下のようにすればいいだけです。
<form…>
<table>
・
</table>
<div style="width:100%;height:50px;"></div>
<div style="height:100px;">
ここに、文字とかボタンエリアとかが入る…
</div>
</form>
<div style="width:100%;height:50px;margin-top:-150px;"></div>
こんな感じで、ネガティブマージンを設定してあげればいいわけです。
たしかにJavaScriptは便利ですが、なんでもかんでもゴテゴテと使うのはどうかと。
There's more than one way to do it.
やり方は一つではないのだから、いろいろ試してみたいですよね。
いろいろやって、自分に合ったものを選べばいいのです。
個人的には、HTML + CSS で(現段階の自分の能力では)実現できないものに限り、JavaScriptを使うというスタンスで仕事をしています。
覚えたてのJavaScriptをゴテゴテと使ったサイトのせいで「JavaScriptは素人製作者が使うもの」というレッテルを貼られた時期もあったそうです…Ajaxの登場で見直される前までは。
JavaScript : The World's Most Misunderstood Programming Language
世界で最も誤解されたプログラミング言語であることは間違いないようです。
Amateurs
Most of the people writing in JavaScript are not programmers. They lack the training and discipline to write good programs. JavaScript has so much expressive power that they are able to do useful things in it, anyway. This has given JavaScript a reputation of being strictly for the amateurs, that it is not suitable for professional programming. This is simply not the case.
JavaScriptを書く人のほとんどはプログラマではありません。
彼らには良いプログラムを書くための教育と修行がたりません。(敢えて「修行」にしてみた)
しかしJavaScriptは、そんな彼らであってもとりあえず有用な仕事ができる、たくさんの表現方法があります。
そうしたことから、JavaScriptは完全にアマチュア向けの仕様の言語であって、プロユースのプログラミング言語ではないという評判をもたらしてしまいました。
この場合(JavaScriptの場合)は単純にそうであるとは言いきれません。


