伊藤清徳の垂直落下式ムーンサルトプレス

PerlとかPHPとかMySQLとか...がんばっても8割だ。

Category: 未分類 (page 2 of 4)

[覚書]Yiiで複数データ・ソースを扱う

今日は完全な覚書です。
 
僕はYiiが大好きです。あ、PHPのフレームワークのことです。
(ぼくにとっては)使いやすい。現在はYii2がベータ版で開発中。
giiというGUIでのCRUDジェネレータがあり、
管理画面を作るにはとっても手軽、かつ、高機能に振る舞ってくれる
CRUD画面をつくってくれます。
 


こういったフレームワークにかならずついてくるのがORMやらARやら。
YiiにももちろんARがあります。
CActiveRecordを継承したクラスをつくれば、それで「はい完成」。
(もちろんテーブル名の設定などは必要ですが)
 
ただし、CActiveRecordは、初期値でフレームワークに設定されるDBへの接続を前提につくられており、複数データソースに接続する場合はちょこっと改造が必要です。
 


複数データソースへの接続

'components'=>array(
	'db'=>array(
		'connectionString' => 'mysql:host=host;dbname=databasename',
		'emulatePrepare' => true,
		'enableParamLogging' => true,
		'username' => 'user',
		'password' => 'password',
		'charset' => 'utf8',
	),
)

初期値ではこんな感じの設定がconfigにあります。
1つのデータソースへの接続ですね。
 
これを…

'components'=>array(
	'db'=>array(
		'connectionString' => 'mysql:host=host;dbname=databasename',
		'emulatePrepare' => true,
		'enableParamLogging' => true,
		'username' => 'user',
		'password' => 'password',
		'charset' => 'utf8',
	),
	'db2'=>array(
		'class' => 'CDbConnection',//←これ追加
		'connectionString' => 'mysql:host=host;dbname=database2',
		'emulatePrepare' => true,
		'enableParamLogging' => true,
		'username' => 'user',
		'password' => 'password',
		'charset' => 'utf8',
	),
)

こんな風にすると、2つめのデータソースへは

Yii::app()->db2

でアクセス可能です。おぉ。便利。


ARで利用

class TableModel extends CActiveRecord
{
	/**
	 * テーブル名を指定
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'tablename';
	}
	
}

YiiのActiveRecordは最低限これだけ書けばARクラスをつくることができます。
ただ、前述のとおり、Yiiのアクティブレコードは初期で設定されているYii::app()->dbを前提としていますので、2つめのデータソースのAR作成は、ちょこっと変更が必要。
 
そのやり方が…

class DB2Model extends CActiveRecord
{
	
	/**
	 * データ接続先を設定
	 */
	public function getDbConnection()
	{
		return Yii::app()->db2;
	}
	
	/**
	 * テーブル名
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return 'sessions';
	}
	
}

こんな感じgetDbConnection()をオーバーロードして、
configで追加した別のデータソースをリターンするだけ。
 
おお。さらに便利。


 
誰得です。現場からは以上です。

マイカフェの田中とかいう人

マイカフェというコワーキングスペースの代表の田中とかいうおじさん(実際は僕より年下だけど)が、僕の写真をいっぱい乗っけた記事を書いてくれたのでAnswer記事だコラ!タココラ!


コワーキングスペースってなんぞ

wikipediaによると>>http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%AF%E3%83%BC%E3%82%AD%E3%83%B3%E3%82%B0

すごく感情の入っていないことばでいえば
「コミュニティ付きのシェアオフィス」
なんすけどね。
 
マイカフェはその一言では片付けられないのですよ。宣伝みたいだけど。
 


田中とかいう人

このマイカフェの代表が「田中」ってヤツでしてね。
僕とこの人が出会ったのが、2年くらい前ですか。
マイカフェで開催されていたストリートファイター2の大会に呼ばれていったところで出会いました。
 
そこから半年くらい、名前を覚えてもらえずスト2大会で僕が使っていた「バルログ」から、
僕は「バルログさん」と呼ばれていたわけです。
 
まぁコワーキングって何かよくわからなかったし、そこから得られるメリットもわからなかったし、
「田中さんよ。あんた一体何者よ?」
みたいなところもあって。
 
でもだんだん、この田中って人の味がわかってきてね。
マイカフェの会員にならないまでも、アドバイスを受けたりしてもらったり。
そんなこんなで変な友情が芽生えているわけですよ。
 
マイカフェさんは12月に3店舗目となる「錦通店」をオープンしました。
その店の開店と同時に、僕はついに口説き落とされて、会員になったわけですが、
まぁそれは置いておいて、
この錦通店オープンのレセプションがあったんですよ。
そのときに、来賓の方々の挨拶が次々と行われて、
みなさん口をそろえておっしゃるのです。
 
「マイカフェ = 田中イズム」
 
だと。
 
つまりはですね
マイカフェ ≒ コワーキングスペース
マイカフェ = 田中イズム
なんですね。
 
田中とかいう人のフィールドの中で、僕たち会員がコミュニティを作っている。
そんなイメージです。
 


競争とかそういうことじゃない

 
マイカフェさんの中の意識の実情は知りませんよ。
あくまで、僕が会員として思ってることですが、
結局のところね、商売って競争を意識した時点で負けですよね?って常々おもっているわけです。
自分のイズムに共感してくれる方々が顧客で、
その顧客をただひたすらにケアしつづけるのが商売なんじゃないかって。
 
Apple信者にMS-Windowsの良さをひたすらに説いても仕方ないし、
ホンダ信者にトヨタ車の良さを説いても仕方ない。
 
だって、そこには共感はないから。
信者は、その企業や事業者と共感してる。
それを覆すのは、ある意味顧客の信念を潰すようなやり方でもあります。
 
田中イズムってこういうのに通じてんじゃないかなーって。


 
 
あれ?なんか締まらなくなってきたな。とりあえずさ、田中さんよ。いやマイカフェさんよ。一緒におもしろいことやろうや。

スーパーママチャリGP参加攻略(核心は語らない)

2年前にブログでレポートした富士スピードウェイで行われるスーパーママチャリGPに実はあれから連続参加しておりまして、今回は前日の場所取りからスタートしたので、ちょっと参加の攻略を書いてみようとおもいます。

ですが、あまり完全な攻略を書くと、自分たちが死ぬので、ヒントだけです。あと速さは僕たちは追求していないので、レースの攻略については書きません。


開門前

 
ママチャリGPは全1400チームが参加し、各チーム10人の選手と数名のサポーターで成り立っているチームがほとんどですので、人数にすると、2万人近くが富士スピードウェイに集まります。しかも、F1のようにピットエリアが確保されているわけではなく、場所取りによって成立します。参加者によって場所とりをしなくてはならない場所は、ピットエリア、暖を取るためのBBQエリア、仮眠をするためのクリスタルルームにそれぞれ人数分の場所を確保することが最低限必要になってきます。
 

 
▲これが、前日開門時間ごろの待ちの車列です。私たちがいつについたのかは、核心に迫るので言いませんが、最前列にいた方にはなしをきいたところ、前々日の19:00に並んだとのことです。怖い…怖い…
 
2014年は比較的暖かく待ちの時間も、外に出てサッカーをやったりなど、皆さん思い思いに過ごしていましたが、例年は外にでることができないくらい寒く、車のエンジンを切ることは不可能になるようなので、燃料の量に注意してください。
 
なお、車列の場所取りは基本的に禁止で、一回外にでると並び直しです。
 


ダッシュ組 = これがママチャリGPの本番

開門前の行列は、何も車だけではありません。自動車は、開門時には、セーフティカー(F1で使われるあれです)に先導されてゆっくりしか駐車場にはいることしかできず、駐車場に入ってから、場内の場所取りをしていては、時すでに遅しです。
 
車列の駐車場とは他の駐車場には、ダッシュ or 自転車で入場するための待機場が作られ、そちらにも並ばなくてはなりません。前述の通り、平年では、外に出ていることがすでに寒い位の天気の中、何時間も身一つで待っていなくてはならない過酷な行列です。
 
こちらの列は16:45分からスタートを切ることができますが、入場口までは、ダッシュで向かうことになります。したがって、最終的な入場順は、どれだけダッシュできたか?によるわけです。
 
しかし、このダッシュがとにかくキツイ。高低差およそ35mの上り坂を、待機場から、おおよそ1キロ弱ダッシュし続けたところに入場口があります。ここまでとにかくどれだけ走れるかが、場所取りの生命線です。
 
本気のチームは場所取りだけのために、ロードバイクをもちこんで入場するほどです。身一つでダッシュするひとの多くはこの時点で足が壊されて、レース本番に影響を与えてしまいます。
 
はっきりいて、これがママチャリGPの本番です。
 
他の方の動画で2013年のものですが、参考までに
http://www.youtube.com/watch?v=lLuYuKAkJ-A


入場後


 
これは翌日朝の写真ですが、場内エリアでは、このようなテント村ができます。外では、暖を取るためのBBQエリアの確保と、建物内ではピットエリアの確保、暖房の効いたクリスタルルームの確保が必要です。
 
入場前のダッシュにひき続いて、入場口からこれらエリアの確保に向かわないといけません。場内のダッシュは、全部で500メートルほどでしょうか。
 
これらが必要なのか?と参加したことがない方から指摘されますが、レースにつかうママチャリの車検がなんとAM3:00からAM5:00の間に行われるという鬼畜っぷりで、場所を確保しなくては、マイナス5度の極寒のなか、ただただ車検時間とレース開始時間を外で待つという憂き目にあう上、レース時間中は待機場所がないという過酷な状況に置かれます。
 
ご存知の方もいらっしゃると思いますが、富士スピードウェイは1周4.5キロ、高低差35メートル、しかも後半半周はずっと上り坂というかなりキツイコースで、休憩待機場所を確保できないということは、ほぼイコール死を意味します。(自宅への帰途は自動車ですしね)
 
なお、この場所取りに失敗した結果、暖を取りつつ眠るために、毎年トイレで寝る人が現れるそうです。
 


途中外出

富士スピードウェイ自体の入退場は、一度入場料1,000円を払えば、入退場許可を示すアームバンドがもらえますので、それを見せることで再入場が可能です。
 
ただ、問題は駐車場です。駐車場の場所取りについては、運営側の目が行き届かないこともあり、基本的には大丈夫です。が、あくまでOKなのは「場所取り」であって、その駐車場に戻ってこれるかは別問題です。というのもの、会場に近い駐車場が満車になったのを確認すると、そこへの自動車での入場は、制限されます。したがって、場所取りした場所に戻ることはできないとかんがえているべきです。
 
実際わたしたちが停めた駐車場の付近に場所取りを行っておきながら、戻ってこれなかった車を数台見ています。
 
食事や入浴をしに外にでることは、ダメだと認識していたほうが良いです。


ルールブックは読んでおこう

ママチャリGPのルールブックはA4で50ページにも及ぶものですが、場内の火気の制限や、場所取り方法まで、かなり事細かに書かれています。
 
実際に会場に行ってみてわかるのですが、ルールブックを読んでいないチームが、テント張り禁止エリアに場所取りを行ってしまっていて注意されたり、火気禁止エリアでBBQを行って注意されたりしていました。
 
前述のとおり、思うような場所を確保できず、暖を取ることができないのは、ママチャリGPにおいては、大変な憂き目に会います。
 
ルールブックはチームで最低2名は完全に目を通しておくべきです。
 


ママチャリGPは大人のたしなみだ!

前述のとおり、ママチャリGPには、非常に事細かなルールが設定されており、また1500チームもの人がひとつの場所でせめぎ合う場所のため、助け合いの精神も必要です。
はっきり言えば、精神が子どもな人にはただただキツいだけの遊びになると思うのです。
 
大人になりたければ、ママチャリGP!


ママチャリGPのリーダーはやってみるべき!

ママチャリGPは前日の場所とりから、帰宅まで、おおよそ3日間、チーム総勢20名弱を統制していかなくてはなりません。この舵取りは、はっきりいって、会社でプロジェクトリーダーをやるより難しいです。基本的には遊びですから、それぞれが思いのままに楽しむように舵取りというのはこんなに難しいのかorz と思いますよ。
 
その分、学ぶところも多いです。ママチャリGPでチームを自分で作ってみるというもの、非常に経験になりますから、皆さんにおすすめします。
 
ちなみに、エントリーは毎年7月頃で、すぐに参加打ち止めになるほど人気のイベントです。エントリー権の確保、チームメンバーの構成、誓約書の堤出、宿の手配、そして場所取り、本番。やることが山積みです。
 
ママチャリGPは戦(いくさ)です!
 
だから面白い!

Webベースのレジスターに簡単にクレジットカード決済機能をPaypalHereでつけてみた

どうもみなさん2014年お正月いかがおすごしですか?
Webシステム屋はお正月は、とても良い勉強期間だったりなんかしちゃったりします。
この期間私は、PayPalHereを勉強してみました。


PayPal Here?

PayPal HereとはiPhoneなどのスマフォやiPadなどのタブレット端末に、
専用のカードリーダーをつけることで、専用端末のレンタルをすることなく、
クレジットカード決済を導入することができるものです。
 
この他のサービスとして、

などがあります。
 
通常クレジットカード決済専用端末を導入するには
数週間の審査と、月額利用料5,000円程度負担しなければなりません。
スマフォ決済であれば、この審査は簡単に、かつランニングの負担は軽くなります。
 
専用端末が悪いような言い方になってしまうので、フォローします。
専用端末のいいところは、
月当たりの決済額が大きくなるごとに決済手数料がやすくなったり、
オンライン決済と合わせて契約すると別々に契約するより負担が軽くなったりしますし、
専用端末を貸し出していただけるサービス提供業者は、
私の経験上、総じてサポート体制がかなり充実しています。
 
専用端末を導入するか、スマフォ決済を導入するかは、
目指す店舗の大きさや、サービスの内容をベースに、
しっかり比較することをおすすめします。


Webベースのレジスター?

東日本大震災の際にユビレジが仮設の店舗で非常に役に立ったと話題になって依頼、
タブレット端末をPOSやキャッシュレジスターにするサービスが、たくさん展開されています。
日本では、タブレット端末によるPOSが大盛況ですが、
海外では、この他WEBベースのPOSソリューションがたくさんあります。
 

 
などが有名ですが、大小かなりの数のソリューションがあります。
POSは複数拠点で利用するようなものでなければ、
仕組みは非常に単純なので、つくろうと思えば、
 

  • キャッシュドロワ制御
  • レシート印刷
  • バーコードリーダー制御
  • クレジットカード決済

 
を除いては、比較的簡単につくることができます。
 
バーコードリーダー機能については、
USB接続のものはバーコードリーダー自体がキーボードとして動いてくれます。
 
レシート印刷については、
一般的なレシートでなくB5などで印刷してOKなら印刷用CSSの適用で解決できますね。
 
キャッシュドロワについては、
Windows利用前提で、USB接続のものであれば、
COMポートから決まった信号を送れば良いので、
実はそれほど難しくないです。
 


クレジットカード決済

ECサイトなどで利用するオンラインのWEB決済であれば、
クレジットカード決済代行会社と契約することで、
規定のWEBインターフェイスに、クレジットカード番号をPOSTなどすることで、
比較的簡単に導入することができます。
 
それならWEBベースのPOSの場合も、決済代行会社と契約すればよいのじゃないか?
とお思いかもしれませんが、
日本国内の代行会社の審査は非常に厳しく、
WEBベースのPOSの利用のために、
決済代行会社との契約のための審査が通る可能性は、かなり少ないです。
 
というのも、POSなどで動作をさせるには「PA-DSS」などの
クレジットカード決済専用のセキュリティ基準に、
POS端末そのものを対応させる必要があり、
この基準に対応していなければ、
クレジットカード各社が利用を許可することはまずないからです。
仮に、審査が通ったとしても、事故などに関して、
全責任をPOS運用者あるいはPOS運用業者が負うことになります。
 
前述のPaypalHereなどスマフォクレジットカード決済サービスや、
専用端末などは、この基準に従った設計がなされています。
 


それなら話は早い!導入だ!

ということで、スマフォクレジット決済を導入だ!
と、思ったらちょっと早計でした。
海外であれば、こういったサービスにWEB APIは付き物なのですが、
前述のとおり、日本では、法的な基準や、審査が非常に厳しい国ですので、
海外でスマフォ決済対応しているサービスでも、
日本国内のみAPI提供をしていなかったり、
十分な説明がされていないケースがほとんどです。
 
PayPalHereに関しても同様で、APIはあるようですが、
公式に十分な説明がなされていないものをつかうのは、
実際にお金のやりとりが行われるサービスで利用するのは
危険としか言いようがありません。
 
さて、どうしたものか…
 
とおもっていたら、PayPal Here にはURLSchemeが搭載されていることを知りました!
これで簡単にWEBベースのPOSにクレジットカード決済機能が導入できます。
 
URLSchemeとは
「アプリケーション名://メソッド?パラメータ」
というようなURLを実行することで、
端末内のアプリケーション制御ができる機能です。
これならjavascriptなどで簡単に作れるじゃないか!!


ってなわけで、作ってみました。

言いたいことはほぼこのクラスの中に入っています。

function paypal_here_helper(){
	
	//商品データ保存用
	this._items = [];
	
	//設定
	this._params = {};
	
	//コンストラクタ
	this.initialize.apply(this, arguments);
	
}

paypal_here_helper.prototype = {
	
	
	//コンストラクタ
	initialize: function( params ){
		this._params['callback'] = params['callback'];
		this._params['merchantEmail'] = params['merchantEmail'];
	},
	
	//商品追加
	add_item: function( itemname, price, quantity ){
		
		var item = {};
		item['name'] = itemname;
		item['description'] = itemname;
		item['quantity'] = quantity;
		item['unitPrice'] = price;
		item['taxRate'] = '0.0';
		item['taxName'] = 'Tax';
		
		
		this._items.push( item );
		
	},
	
	
	//支払い実行
	goto_here: function(){
		
		//設定
		var invoice = {};
		invoice['itemList'] = {};
		invoice['itemList']['item'] = this._items;
		invoice['paymentTerms'] = 'DueOnReceipt';
		invoice['currencyCode'] = 'JPY';
		invoice['discountPercent'] = '0';
		invoice['merchantEmail'] = this._params['merchantEmail'];
		
		
		//URL生成
		var retUrl = encodeURIComponent( this._params['callback'] + "?{result}?Type={Type}&InvoiceId={InvoiceId}&Tip={Tip}&Email={Email}&TxId={TxId}");
		var pphereUrl = "paypalhere://takePayment?returnUrl=" + retUrl;
		pphereUrl = pphereUrl + "&accepted=cash,card,paypal"
		pphereUrl = pphereUrl + "&step=choosePayment";
		pphereUrl = pphereUrl + '&invoice=' + encodeURIComponent(JSON.stringify(invoice));
		
		
		
		//ジャンプ
		location.href = pphereUrl;
	}
	
	
	
};

▲このコードをファイルに保存し、HTMLからロード。
あとは、
 

			//初期化
			var phh = new paypal_here_helper({
				
				//コールバックURL
				'callback': return_url,
				
				//店舗メールアドレス
				'merchantEmail': 'parsley-eater@i.softbank.jp'
			});
			
			//商品追加
			phh.add_item( 'コーヒー', 300, 1 );
			phh.add_item( 'サンドイッチ', 450, 1 );
			
			
			//支払い実行
			phh.goto_here();

とjavascriptを実行すればOKです。
 
コールバックは、GETで
 
Type:「CrediCard」←固定
InvoiceId: 支払いID
Tip:?
TxId:トラッキングコード
 
が返ります。
Tipだけ意味がわかりませんでした…「0」が返っているようなのですが…
これを取得し支払い済みとして処理すればOKです。


簡単!簡単!!

Javascriptでここまで簡単にできるのはいいですねー。
 
と思うのは早計です。いや、仕組みがつくれるのはいいのですが、
これだけ簡単なので、設計や運用に関しては、
通常より遥かに慎重になる必要はあります。
 
またそもそも、前々からおもっている個人的な意見ですが、
金銭のやりとりが実際に発生するものを、
iPhoneなどを通じて行うことに関して、
小売店やサービス提供業者としての資質に疑問を持つ
消費者は少なくないとおもいます。
ましてや、そのiPhoneが誰かのポケットから出てきたものだとしたら…
 
スタイリッシュだとか、簡単だとか、
そういった理由でスマート決済を利用するのは良くないとおもいます。
 
私のこのコードを利用すること自体は、お好きにして頂いて結構ですが、
しっかり決済サービスは「選択」をしてくださいね。

YiiでInter-Mediatorを使ってみる

INTER-MediatorというPHPアプリケーションフレームワークがあります。
HTMLからのDBカラム指定でデータが呼び出せたり、
Javascriptの制御でDB操作ができたりなど、なかなか重宝するフレームワークです。

が、必ずしも万能というわけではないのかなというところがあり、
私はSymfonyなどに代表されるMVCフレームワークにINTER-MEdiator(以下、IMと略す)を統合して、
利用しています。

以前はCodeigniterにIMを統合するという記事を書きましたが、今回はYiiに統合をしてみます。


Yii?

PHPのフレームワークといえば?というところで最初にあがってくるようなフレームワークではないですが、柔軟で高速で、かつ、スカッフォールディングなどベースの生成が頭がいいので、気に入って利用しています。他方CakePHPほどの「なんでも感」はないので、PHPerとしての「地力」が試されるフレームワークであると思っています。


早速やってみましょう

これよりさきはMySQLへの接続を前提としてお話をすすめます。

IMのファイルは、yiiのアプリケーションディレクトリ(通常であればprotected)に配置します。

/protected/Inter-Mediator/...

のような感じですね。
特に何かコマンドを打つ必要はありません。


設定ファイルの書き換え

データベースへの接続設定をIMでも使いまわせるようにするために、
初期値ではメイン設定に閉じ込められているデータベース設定を、
別ファイルに移します。

/protected/config/main.phpの

'db'=> array(
			'connectionString' => 'mysql:host=localhost;dbname=dbname',
			'emulatePrepare' => true,
			'username' => 'user',
			'password' => 'pass',
			'charset' => 'utf8',
		), 

の値の部分をカットして、

'db'=> require dirname(__FILE__) . '/database.php'

とします。新規に/protected/config/database.phpを作成して、その中を

<??php
return array(
			'connectionString' => 'mysql:host=localhost;dbname=dbname',
			'emulatePrepare' => true,
			'username' => 'user',
			'password' => 'password',
			'charset' => 'utf8',
		);

とします。
さらに、main.phpのほうには、Yiiのセッション機能を使えるようにするために、加筆をします。
(IMの設定情報をセッションで保持することで柔軟に利用できるようにします)

//DBを外に
		'db'=> require dirname(__FILE__) . '/database.php',
		
		
		//セッションを追加
		'session'=>array(//追加
				'class'=>'CDbHttpSession',//追加
				'sessionTableName'=>'sessions',//追加
				'connectionID'=>'db',//追加
		),

先ほどのDBの設定の部分の下に、セッションを利用可能にしておきます。
そして、下記に説明するヘルパを自動読み込みさせるために、サードパーティーライブラリのフォルダを自動ロードするように設定します。

	'import'=>array(
		'application.models.*',
		'application.components.*',
	),

とします。

	'import'=>array(
		'application.models.*',
		'application.components.*',
		'application.vendor.*',
	),

に書き換えます。
設定ファイルの書き換えは以上。


ヘルパファイルの作成

続いて、IMの設定をラクにするヘルパファイルを作ります。
/protected/vendor/ImHelper.php
を作成し、

<??php
YiiBase::import('application.Inter-Mediator.*');
class ImHelper
{
	//デバッグ
	private static $debug = FALSE;
	
	// ----------------------------------------------------
	
	/**
	 * IMコードのセット
	 */
	public static function setImCode( $im1, $im2 = array(), $im3 = array() )
	{
		//データベース設定をロードしてIMの引数に設定
		$database = require YiiBase::getPathOfAlias('application.config') . '/database.php';
		$im3['db-class'] = 'PDO';
		$im3['dsn'] = $database['connectionString'];
		$im3['user'] = $database['username'];
		$im3['password'] = $database['password'];
		
		
		//一時コードの発行
		$code = sha1( uniqid( '', true ) );
		$data = array(
			'im1' => $im1,
			'im2' => $im2,
			'im3' => $im3,
			'debug' => self::$debug
		);
		Yii::app()->session['im_temporary_code_' . $code] = $data;
		
		return $code;
	}
	
	// ----------------------------------------------------
	
	/**
	 * IMコードの取得
	 * @param type $im 
	 */
	
	public static function getImCode( $code )
	{
		global $callURL;
		$callURL = Yii::app()->createAbsoluteUrl( 'im/get', array('code'=>$code) );
		require_once 'INTER-Mediator.php';
		$params = Yii::app()->session['im_temporary_code_' . $code];
		//echo 'var test = ' . json_encode($params) . ';';
		IM_Entry( $params['im1'], $params['im2'],  $params['im3'], $params['debug'] );
	}
	
	// ----------------------------------------------------
	
	/**
	 * URL作成
	 */
	public static function getUrl( $im1, $im2 = array(), $im3 = array() )
	{
		$code = self::setImCode($im1, $im2, $im3);
		return Yii::app()->createAbsoluteUrl( 'im/get', array('code'=>$code) );
	}
	
	// ----------------------------------------------------
}

と書いて起きます。

YiiBase::import('application.Inter-Mediator.*');

で、IMのフォルダ内をオートロードの対象にしておきます。


IM自体の改造

IM自体の改造が必要です。

まず、INTER-Mediator.phpを改造します。

if (!class_exists('Crypt_RSA')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'RSA.php');
}
if (!class_exists('Crypt_Hash')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'Hash.php');
}
if (!class_exists('Math_BigInteger')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Math' . DIRECTORY_SEPARATOR . 'BigInteger.php');
}

//Yiiのオートローダーを一旦解除
spl_autoload_unregister(array('YiiBase', 'autoload'));


if (!class_exists('Crypt_RSA')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'RSA.php');
}
if (!class_exists('Crypt_Hash')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Crypt' . DIRECTORY_SEPARATOR . 'Hash.php');
}
if (!class_exists('Math_BigInteger')) {
    require_once($currentDir . 'phpseclib' . DIRECTORY_SEPARATOR . 'Math' . DIRECTORY_SEPARATOR . 'BigInteger.php');
}

//Yiiの再登録
spl_autoload_register(array('YiiBase', 'autoload'));

とします。これは、先のImHerlper.phpでIMのディレクトリ内をオートロードの対象にしたわけですが、PHP拡張である「Crypt_RSA」などのクラスの存在拡張をチェックすると、自動的にファイルを探しに知ってしまうのを回避しています。

続いて、GenerateJSCode.phpを改造します。

public function generateInitialJSCode($datasource, $options, $dbspecification, $debug)
{
	$q = '"';

public function generateInitialJSCode($datasource, $options, $dbspecification, $debug)
{
	global $callURL;
	$q = '"';

としておきます。IMのコードを見ると、$callURLがセットされていれば、このURLを優先して利用する仕組みになっているようですので、globalにして、先のImHelper.php内でコールするURLを指定できるように改造しています。

もしかすると、

if (isset($callURL)) {

if ( $callURL != '' ){

にしておいたほうが賢明かもしれません。


IM処理用コントローラーの設置

次にIMの処理を担うコントローラーファイルを設置します。
/protected/controllers/ImController.php
を作成し

<??php
class ImController extends CController
{
	
	// ----------------------------------------------------
	
	/**
	 * アクセスルール
	 */
	public function accessRules()
	{
		return array(
				'actions'=>array(  ),
				'users'=>array('@'),
			),
		);
	}
	
	// ----------------------------------------------------
	
	/**
	 * IM用コード出力
	 */
	public function actionGet( $code )
	{
		echo ImHelper::getImCode($code);
	}
	
	// ----------------------------------------------------
}

と保存しておきます。アクセス状況によってはアクセスルールを適切に設定したほうがよいでしょう。


準備完了

準備ができました。
あとは任意のコントローラーアクション内で、

$ds = array(
			array(
				'name' => 'categories',
				'records' => 20,
				'paging' => true,
			),
		);
		$def = array();
		$ds2 = array();
		
		$url = ImHelper::getUrl(
				$ds,
				$def,
				$ds2
		);

とすれば、$urlにIMの設定を呼び出すための一時URLが発行されるため、
viewの中で表示するなり、clientScriptクラスに登録するなりすればOK

ImHelper::getUrl()の引数は
IM_Entry()の引数に引き当てられます。
DBへの接続設定はImHelperで自動的に割り当てられるので、不要です。


これで、開発高速化!

現場からは以上です。

Yahoo!ショッピングのカートフォームに無茶をさせる

以前、楽天のカートフォームに無茶をさせるというと記事を書きましたが、
(もう2年も前なのか!?)
今回はYahoo!ショッピングのカートフォームに無茶をさせてみましょう。
 


フォームのソース

まずは、ヤフーショッピングが出力しているコードを見てみましょう。

<form name="form2" method="post" action="https://order.shopping.yahoo.co.jp/cgi-bin/cart-form;_ylc=[セッションコード?]?[ショップID]+[セッションコード?]&ccode=Nat">
<input name="vwitem" type="hidden" value="[商品ID]">
<input name="vwcatalog" type="hidden" value="[ショップID]">
<input name="vwquantity" type="text" value="1" class="ptPrice">
<input type="image" src="http://i.yimg.jp/images/store/shp/bt/bt_003.png" alt="カートに入れる" width="142" height="36" border="0" onClick="YAHOO.JP.sc.addCart(YAHOO.JP.sc.products, YAHOO.JP.sc.prop22);">
</form>

 
こんな感じです。
[セッションコード?]はセッション用の一時コードか何かのようです。
ちょっとこの辺りは追うことができず…
[ショップID]は、Yahoo!ショッピング開店時に申請したショップのIDです。
これはショップURLからも判断出来ます。
[商品ID]は商品を登録した際に、任意で商品につけるコードです。
 


外してもOKなコードがある

上記の用なフォームを作成することで、
ヤフーショッピング用のカートフォームが
作成できることがわかりました。
 
が、そもそも、この通りに作る必要があるのか検証したところ、
どうやらその必要は無さそうです。
セッションコードと思しきコードは省略しても、
ちゃんとカートに商品が追加できることがわかりました。
 

<form name="form2" method="post" action="https://order.shopping.yahoo.co.jp/cgi-bin/cart-form?[ショップID]&ccode=Nat">
<input name="vwitem" type="hidden" value="[商品ID]">
<input name="vwcatalog" type="hidden" value="[ショップID]">
<input name="vwquantity" type="text" value="1" class="ptPrice">
<input type="image" src="http://i.yimg.jp/images/store/shp/bt/bt_003.png" alt="カートに入れる" width="142" height="36" border="0" onClick="YAHOO.JP.sc.addCart(YAHOO.JP.sc.products, YAHOO.JP.sc.prop22);">
</form>

 
フォームタグのaction属性に付けられた難解なURLは、
ここまで単純化してもちゃんとカートに入ってくれます。


オプション的な要素は?

オプション的な要素は任意のオプションを追加することができます。

<form name="form2" method="post" action="https://order.shopping.yahoo.co.jp/cgi-bin/cart-form?[ショップID]&ccode=Nat">
<input type="text" name="色" value="赤" />
<input type="text" name="サイズ" value="M" />
<input name="vwitem" type="hidden" value="[商品ID]">
<input name="vwcatalog" type="hidden" value="[ショップID]">
<input name="vwquantity" type="text" value="1" class="ptPrice">
<input type="image" src="http://i.yimg.jp/images/store/shp/bt/bt_003.png" alt="カートに入れる" width="142" height="36" border="0" onClick="YAHOO.JP.sc.addCart(YAHOO.JP.sc.products, YAHOO.JP.sc.prop22);">
</form>

このようにするとカゴの中に
色:赤
サイズ:M
として商品が追加されます。
 
このオプション値を変更することで、
カートは同じ商品でも、別の明細としてカート内に追加をする仕組みになっているようです。
逆に、カート内に以前に同じ商品IDとオプション値を持つ商品が以前に追加されている場合は、
個数が合算されて追加される仕組みになっています。
 
この法則を使うと、裏技的な使い方として、
オプション値にタイムスタンプなどを埋め込んでおけば、
能動的に明細行をカゴボタンを押すごとに分けることが可能です。
 


楽天より仕組みが簡単

楽天では、楽天側が自動発行するデータベースIDを利用して
カートに商品を入れる仕組みになっているため、
カスタマイズがわかりにくいですが、
Yahoo!ショッピングでは、ショップ側がつけたIDのみを利用するため、
カスタマイズが非常にわかりやすいです。
 
たとえば、
自分のブログに、
前述の仕組みを利用してヤフーショッピングのカートフォームを埋め込んで、
ランディングページを作ったりすることができ、
モール内に閉じがちな、プロモーション手段を少しだけ広げることができます。
 
また、ヤフーショッピングは楽天と違い、
CSVでの商品登録などはオプションではないので、
CSVを通して簡易DBを作ることが可能ですから、
無料のCSV検索CGIなどを利用して、
自社サイトにカートシステムを実現するなんてこともできなくはないです。
 


モールの特性は知っておくべき

フォームなどの特性を知っておけば、
モールの規約の範囲内で、モールの枠を少しだけ超えたプロモーションをすることができます。
私は楽天やらカラーミーショップなど、結構な数を「魔改造」していますが、
フォームを使って実験をしてみた賜物です。
(がゆえに、無茶な仕事がたまに落ちてきたりしますがw)
 
知っていることはとても重要なことです!

線はできているか。

あるクライアントの話をする。
そのクライアントさん読んでいたらごめんなさい(笑)
読んでいても、それ相応の信頼関係ができていると思っているので、流してください。


今年にはいってからそのクライアントさんには、
店頭イベントの総合的な広報について任せていただいています。

店頭イベントの一発目が先日終わり、
コストかかってない割にはそれなりの売り上げ的成果があげられ
結果としてはまずまずでした。
 
私の指導があったものの、
この成果自体は、クライアントさんの取り組みの結果だと思います。
 


が、そもそもこんな短期間のイベントを繰り返し、
そしてひとつのイベントの成果を
「良かったね」「悪かったね」
と評価して終わるのが果たしていいのかっていう問題に
クライアントさんは、まだ気付いていないようです。
 


今回のイベントの内容は、
あるブランド商品に関して県下最大級の品揃えをするトランクショーで、
そこにこのクライアントさんの長年の経験を加えて、
即売会や相談会をするものです。
 
イベントとしては正直言うと「よくある」ものです。
 
「よくある」もので、ある程度の成果を上げられたことは喜ばしいことですが、
それで終わっていていいのかということです。


イベント時ご来店いただいたものの、
その時はご購入いただいたけなかったお客様がいらっしゃるとします。 
1回のイベント「だけ」を評価していると、
ご購入いただけなかったこのお客様というのは、
自店にとって「貢献のなかったお客様」ということになります。
 
そう。数字の上では。
 


しかし、今回のイベントの内容をもう一度振り返ると

  • 都道府県下で最大級の品揃えを見せる
  • 長年その商品を扱ってきた知識を価値とする

ということですが、後者をお客様に認識していただけたとすれば、
適切な期間に、適切な内容のニュースレターやEメールが、
その後も届けられたとしたら、
いつか、もう一度ご来店いただけるのでは?


 
1回のイベントや広報ごとに評価をして
「あーよかったねー」「だめだったねー」って言っていては、
「線」でなく「点」です。
点をつなげて線にしていかなくてはいけません。
 
一度ご来店いただいたお客様をフォローして、
しっかりと自店のリピーターになっていただけるようにしなければならない。
(反復購買という意味ではなく、何度も足を運んでいただけるように)


そんな話わかってるよ。
そんな話知ってるよ。
 
なんておっしゃる方いっぱいいらっしゃると思います。
確かにそうですね。
いろんな経営コンサルタントが散々言っていることですから。
 
そこで問いたいのが
ニュースレターやEメールを送るとして
「適切な時期」や「適切な内容」というのを知っていますか?
ということです。
 


 
何社かのコンサルティングをさせていただいた、
私の経験からすると、
扱っている商材、店主の人間性などなど様々な要因で
「適正」は定まらないです。
このお店の場合は1ヶ月ごとに送るのがいいとか、
はたまたこっちのお店は4ヶ月ごとに送るのがいいとか、
本当に様々です。
 
こればかりは、お客様と店の人という関係性の中でうまれる
「肌感」で蓄積していかなくてはいけない「知識」です。
(もちろん数字としては解析などに出てくるとは思いますが)
 


一つのイベントや広報を「点」として、
それぞれを結びつけたことが「線」とは言い切れないところがあります。
 
前述のとおり
自店なりの「こうしたら→こうなる」という方程式を知っていく。
これが「線」だと思うのです。
 
つまり、PDCAでしょ?って言われるかもしれません。
おっしゃるとおり。
でもね。おそらくもっと手前の問題だと思うのです。
PDCAを回すだけの
「もてなし」と「しつらえ」を準備していかなくてはいけませんね。

プロレスと私とマーケティングと


一年ぶりにDDTプロレスを見てきた。
名古屋は半年に一回くらい、栄のテレピアホールで行われる。
エンターテイメント性を重視したプロレス展開で
メジャーでない団体だが日本武道館で大会を行うなど勢いのある団体だ。
写真は名古屋出身の注目レスラーの彰人選手。


プロレスはあまり人気がなくなっている興行ではあるけれど、
誰かを連れてプロレスを見に行くと「面白い」といってくれるし、
友達と友達が繋がって、友達になる。
 
今日もそんなことがあった。
私を通して友達と友達が友達になった。
  
まぁプロレスにかぎらず遊びというのはそういう側面があるけれど、
レスラーが演じるドラマを通じて、感性を共有できるところがいい。
と私は思っている。
 


僕は感性価値を重視してマーケティングコンサルの仕事をしている。
感性価値の基礎はこんな感じだ。
 
例えば5億円というお札の束があるとする。
それに価値を与えるのは、人間だ。
そして、5億「円」という価値が地球規模ではどういう価値を持つかは、
各地域の人々の主観で決められる。
円相場とかは、人の感性で決められている側面があるわけだ。
 
だから「価値を伝えること」より「価値が伝わること」をベースに
広報戦略を打つことを考える。
これは似ているようで違う。


私が敬愛するマーケティング研究家である
小阪裕司先生、藤村正宏先生
は普段から「自己開示をすべき」とおっしゃっている。
 
いずれの先生においても
相手を選び、自分を知ってもらう努力をしなければ、
相手も自分を選び、そして自分を知ってくれることなどない。
知ってもらえないのに、価値が生まれる?
ということを繰り返し啓蒙されており、
そのためには「自己開示が必要」と説いている。
 


私は数年前までWEB業界の人に全く知られていなかった。
だが、現在は、私のTwitterは、WEB業界関連の方々1200名くらいの方に
フォロー頂いている。
まったくありがたい話だ。
 
徐々に私のことを知ってもらえるようになったのが、
何を隠そうこのブログだ。
このブログのタイトル「垂直落下式ムーンサルトプレス」は
プロレス関連の言葉。

「あー!読んでますよ!ブログ!なんだっけパワーボムだっけ?」
みたいな声を沢山かけていただけるのです。
プロレス好きな人なら更に深い方向へツッコミを入れてくれる方も沢山いる。
そして好感をもってもらう。
(ちなみに私は「プロレスヲタク」ではなく「プロレス技ヲタク」ですw)
 
好感を持ってもらうと、いろんなことが伝わりやすい。

  • 価値が伝わりやすい
  • 言いたいことが伝わりやすい
  • やってほしいことが伝わりやすい

これは感性価値マーケティングではすべてのスタートだ。
 


趣味というのは仲のいい誰かに勧められて始めることが多くないだろうか?
格闘やプロレスに否定的だった私の奥さんを
プロレスに連れて行ったら、突然のようにハマった。
上の写真は、DDTプロレスのHARASHIMA選手。
奥さんが好きな選手だ。
 
一度好感を持ってもらった相手が、
「これいいのよ」と薦めてくれたものというのは、
案外「じゃ買ってみようかしら」とか「はじめてみようかしら」という気になる。
 
私はECコンサル会社に在籍していた会社員時代
いろいろな仕組みをPHPで作ってはクライアントに提供してきた。
が、あまり使ってくれなかった。
手前味噌だが、そのモノ自体は非常に有用なものだったという自信がある。
でも使ってくれなかった。
 
今考えてみると、当たり前だ。
そのクライアントにとっては、
私に十分な好感や信頼を与えてもらっていなかった。
そんな人に聞く耳を持つというのは、
自分に置き換えてみると、あまりないことだと思う。
たとえ、事細かな説明を付け加えたとしても。
 
商売において「こだわり」はとても重要な要素だ。
こだわりのない商売は商売になり得ない。
他方「こだわり」はコモディティになってしまう要素もある。
なぜなら、競合もこだわっているから。
何にどのようにこだわっているのか伝える方法を知らなければいけない。
 
私以外の人が誘ったところで、
奥さんはプロレスを見に行くことはなかったと思う。
このことはマーケティングにおいても重要な視点だと思う。
クチコミとかがまさにそれだろう。


価値は人の感性が決めるのだから、
人の感性にどれだけ近づけるかはとても重要な考えの一つだ。
 
自己を開示する方法を、さらに磨いていきたい。
と、プロレスと私とマーケティングを無理やりつなげて話してみた。

HTML5をKARUTAで学んだ話。


先日、2013年1月6日にHTML5KARUTA @ 名古屋・伏見MYCAFEを開催しました。

まず、MYCAFEのスタッフの皆さんご協力ありがとうございます。


ことの発端は2012年末、普段より交流のある、優さんより、
全国的にHTML5KARUTAなるものをやるから名古屋でもどう?
というお誘いをいただき、せっかくなので快諾させていただきました。
HTML5では名古屋において爆心地でいらしゃっり、
名実ともにフロントエンドテロリスト対策のスペシャリストとして活躍していらっしゃる、
じゃっくばうあー氏に主催をお願いしました。


そもそもHTML5KARUTAとはなんぞやってはなしですが、
HTML5KARUTAとはこういったものです→http://roadstohtml5.com/html5karuta/

要するにHTML5の勧告候補に定義されたHTMLタグの機能を聞いて、
それを示すタグをKARUTAでとりましょうというものです。

全部で108のタグがあります。


私は正直言って「勉強」なんかだいっきらいです。
座学が実践のなんになるんだと平気で言い放つくらい勉強がだいっきらいです。
 
なのでHTML5も普通に使われるまではと思い、
ほとんど勉強してませんでした。
 
子供の頃の遠い記憶で、僕はリトミックに通っていました。
ユーリズミックなどとも呼ばれますが、
これは、物心が付く前に楽器などを使って、
音楽やリズム、国語や英語を体に染み付ける教育手法です。
この経験は今でも僕の中に息づいています。

HTML5KARUTAも同様で、
楽しんで覚える、、、というより感じて覚えるという点は、
体に染み付くだろうなと思いました。
 
HTML5のことを体動かしながら、
笑いながら話すなんてことありますか?
多分これくらいしかないじゃないですか。

とてもいい経験だと思いました。


今回はじゃっくばうあー氏に読み手も頼んだことで、
KARUTAとりの後により詳しい説明もしてもらえたことも大きいですね。

ばうあー氏も知らないことを感じつつ、
楽しんだ後に深めるというのは、非常にいいことです。
 
改善点としては、何かTipsも披露できれば、
より深まったのかなという気がします。


つぎはCSS3KARUTAができるとかできないとか。

保護中: だから春を体験!沖縄●●ホテル

このコンテンツはパスワードで保護されています。閲覧するには以下にパスワードを入力してください。

Older posts Newer posts