<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>子だぬきの技術習得ノート</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/" />
    <link rel="self" type="application/atom+xml" href="http://www.okushin.co.jp/kodanuki_note/atom.xml" />
    <id>tag:www.okushin.co.jp,2008-05-22:/kodanuki_note//5</id>
    <updated>2010-02-26T07:16:27Z</updated>
    <subtitle>WEBシステム開発等で気付いたことなどをまとめていきます。</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Publishing Platform 4.01</generator>

<entry>
    <title>CakePHPのsessionがcore.phpの設定より早く消える！</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/02/cakephpsessioncorephp.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.82</id>

    <published>2010-02-26T06:50:40Z</published>
    <updated>2010-02-26T07:16:27Z</updated>

    <summary>CakePHPのsessionってsessionデータに作成時間を保存しておき、...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[CakePHPのsessionってsessionデータに作成時間を保存しておき、読み出す時にcore.phpで設定した時間が経過していないかチェックしているんですね。<br />
サーバー設定の方はさわりに行ってないみたいです。<br />
core.phpの
<pre class="php" name="code">
Configure::write('Session.timeout', '120');
Configure::write('Security.level', 'medium');
</pre>
で3時間以上あってもサーバーの
<ul>
<li>session.cookie_lifetime</li>
<li>session.gc_maxlifetime</li>
</ul>
の方が短ければガーベジコレクションでsessionファイルが消えるので予想より早くログアウトしたりします。<br />

なので
bootstrap.phpに
<pre class="php" name="code">
ini_set("session.cookie_lifetime", 100 * Configure::read('Session.timeout'));
ini_set("session.gc_maxlifetime", 100 * Configure::read('Session.timeout'));
</pre>
coreの値使ってサーバー設定をcore触るだけで設定できるようにしました。<br />
(100掛けてるのはmediumの係数の100です。session.php見ましたが定数にはなっていない感じでした。)<br />
バージョンは1.2.6です。 

]]>
        
    </content>
</entry>

<entry>
    <title>CakePHPのtextareaの最初の改行コードがなくなる！</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/02/cakephptextarea.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.80</id>

    <published>2010-02-26T06:01:01Z</published>
    <updated>2010-02-26T07:15:47Z</updated>

    <summary>-------------- \n\nテキストエリア内容 -----------...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[--------------<br />
\n<br />\n<br />テキストエリア内容<br />
--------------<br />
のデータがあった場合<br />
<pre class="php" name="code">
$form->input('Model.field', array('type' => 'textarea'));
</pre>
で表示した場合、最初の改行コードがない状態でフォームに表示されます。<br />
(下記のように2つある改行が1つになっています)<br />
<textarea name="textarea" cols="20" rows="5">

テキストエリア内容
</textarea>]]>
        <![CDATA[実際、バグではなくてブラウザの仕様で最初の改行は表示しない為です。
<pre class="html" name="code">
<textarea name="textarea" cols="80" rows="5"> 
    テキストエリア内容
</textarea>
</pre>
こんな風に改行とインデントつけながらhtml書いていた場合、初めの改行を読み込んで表示されると1段下がった状態で内容が表示されると困りますので・・・<br />
CakePHPの場合 (cake/libs/view/helpers/html.php)
<pre class="php" name="code">
'<textarea name="%s" %s>%s</textarea>'
</pre>
のように改行を入れてから内容を表示していないので、内容を展開する前に改行を挿入してから展開する必要があります。<br />
そこで、 (cake/libs/view/helpers/form.php)
<pre class="php" name="code">
		return $this->output(sprintf(
			$this->Html->tags['textarea'],
			$options['name'],
			$this->_parseAttributes($options, array('type', 'name'), null, ' '),
			PHP_EOL. $value
		));
</pre>
の$valueの前に改行コード「PHP_EOL」を足しました。<br />
バージョンは1.2.6です。 ]]>
    </content>
</entry>

<entry>
    <title>CakePHPのqueryのキャッシュでハマる</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/02/cakephpquery.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.79</id>

    <published>2010-02-26T05:20:15Z</published>
    <updated>2010-02-26T05:58:25Z</updated>

    <summary>モデルのquery関数を使ってループをまわしながら最大noをとってくる処理でハマ...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[モデルのquery関数を使ってループをまわしながら最大noをとってくる処理でハマりました・・・<br />
query関数って$sql同じだった場合勝手にキャッシュを使って前回と同じ値を返すんですね。<br />
通常はこれを回避する為に
<pre class="php" name="code">
$this-&gt;query($sql, false);
</pre>
とすることで毎回最新データを取ってきてくれます。<br />
デフォルトでキャッシュが邪魔だったので、app_model.phpで
<pre class="php" name="code">
function query() {
	$params = func_get_args();
	if (empty($params[1])) {
		$params[1] = false;
	} else {
		if (is_array($params[1]) && empty($params[2])) {
			$params[2] = false;
		}
	}

	$db =& ConnectionManager::getDataSource($this->useDbConfig);
	return call_user_func_array(array(&$db, 'query'), $params);
}
</pre>
query関数をオーバーライドしました。<br />
バージョンは1.2.6です。]]>
        
    </content>
</entry>

<entry>
    <title>OpenPEARでPDF_Support_Libraryを公開</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/02/openpearpdf-support-library.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.76</id>

    <published>2010-02-10T04:52:44Z</published>
    <updated>2010-02-10T07:51:08Z</updated>

    <summary>OpenPEARでPDFの位置合わせを楽に出来るようにしたPDF_Support...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[OpenPEARでPDFの位置合わせを楽に出来るようにしたPDF_Support_Libraryを 公開しました。<br />
<br />
OpenPEARでのPDF_Support_LibraryのURL<br />
<a href="http://openpear.org/package/PDF_Support_Library">http://openpear.org/package/PDF_Support_Library</a><br />
<br />]]>
        <![CDATA[概要<br />
tcpdf+FPDIの組み合わせでPDFを作っていたのですが、PDF表示の位置合わせが物凄く面倒くさかったので、位置合わせが楽になるようにライブラリを作りました。<br />
座標を指定する箇所をCSVで指定するように切り出して、CSVの部分でどういう種類（文字列、線、四角形、画像）の出力か、フォントサイズ、色等を指定するようにしました。<br />
位置を合わせやすくするためにグリッドを追加しておき座標を指定しやすくしてます。<br />
文字出力のデバッグ用に枠線や背景に色をつけれるようにしています。<br />
<br />
使い方<br />
/trunk/index.phpにサンプルを置いています。<br />
ここでライブラリクラスの読み込み、背景のPDFファイルと位置合わせのCSVファイルの読み込みを行って、入れたい部品を名前と内容を指定して記述しておきます。<br />
文字列の場合は<br />
setWidgetString()関数を使用します<br />
線、四角形、画像の場合は<br />
setWidgetVisible()関数を使用します<br />
<br />
/trunk/parts/example.csvに位置の情報などを指定します。<br />
部品ごとの指定値は次の通りです。<br />
<table width="100%"  border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td>種類</td>
    <td>テキスト</td>
    <td>線</td>
    <td>四角形</td>
    <td>画像</td>
  </tr>
  <tr>
    <td>第1項目</td>
    <td>名前</td>
    <td>名前</td>
    <td>名前</td>
    <td>名前</td>
  </tr>
  <tr>
    <td>第2項目</td>
    <td>部品タイプ<br>(text)</td>
    <td>部品タイプ<br>(line)</td>
    <td>部品タイプ<br>(rect)</td>
    <td>部品タイプ<br>(image)</td>
  </tr>
  <tr>
    <td>第3項目</td>
    <td>コメント</td>
    <td>コメント</td>
    <td>コメント</td>
    <td>コメント</td>
  </tr>
  <tr>
    <td>第4項目</td>
    <td>左上X位置</td>
    <td>左上X位置</td>
    <td>左上X位置</td>
    <td>左上X位置</td>
  </tr>
  <tr>
    <td>第5項目</td>
    <td>左上Y位置</td>
    <td>左上Y位置</td>
    <td>左上Y位置</td>
    <td>左上Y位置</td>
  </tr>
  <tr>
    <td>第6項目</td>
    <td>右下X位置</td>
    <td>右下X位置</td>
    <td>右下X位置</td>
    <td>右下X位置</td>
  </tr>
  <tr>
    <td>第7項目</td>
    <td>右下Y位置</td>
    <td>右下Y位置</td>
    <td>右下Y位置</td>
    <td>右下Y位置</td>
  </tr>
  <tr>
    <td>第8項目</td>
    <td>文字色<br>（#ffffffという形で指定）</td>
    <td>線色<br>（#ffffffという形で指定）</td>
    <td>四角形の色<br>（#ffffffという形で指定）</td>
    <td>ファイルパス</td>
  </tr>
  <tr>
    <td>第9項目</td>
    <td>フォントのサイズ</td>
    <td>線の太さ</td>
    <td>塗りつぶすかどうか<br>0=塗りつぶさない<br>1=塗りつぶす</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>第10項目</td>
    <td>行数</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>第11項目</td>
    <td>水平位置(L,C,R)</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>第12項目</td>
    <td>垂直位置(C,B,T)</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>第13項目</td>
    <td>ボールド<br>0=無し,1=有り</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>第14項目</td>
    <td>イタリック<br>0=無し,1=有り</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>第15項目</td>
    <td>アンダーライン<br>0=無し,1=有り</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
  </tr>
</table>
]]>
    </content>
</entry>

<entry>
    <title>PHPで画像加工</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/01/php-1.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.74</id>

    <published>2010-01-28T02:58:03Z</published>
    <updated>2010-01-28T03:06:56Z</updated>

    <summary>今回UPした画像のリサイズと画像に文字を乗っけるという仕様の仕事があり、PHPで...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[今回UPした画像のリサイズと画像に文字を乗っけるという仕様の仕事があり、PHPで画像加工に挑戦しました。<br />
<br />
調べてみるとPHPを入れるときに大体標準で付いてくるGDライブラリで画像加工が出来るとのこと。<br />
今回は画像を小さくリサイズするのと、写真に文字を埋め込むという事をしました。<br />
 ]]>
        <![CDATA[ソースは次のようになりました。<br />
<br />


<pre class="php" name="code">

$upload_path = "アップロードしたいディレクトリ";

//まず元画像となる写真を上げます。
if (!move_uploaded_file($_FILES["Filedata"]["tmp_name"], $upload_path . "picture.jpeg")) {
    header("HTTP/1.0 500 Internal Server Error");
    die;
}

//元画像の写真のサイズを取得します。
list($width,$height)=getimagesize($upload_path . "picture.jpeg");
//元画像のJPEGファイルを読み込んでおきます。
$src=@imagecreatefromjpeg($upload_path . "picture.jpeg");

//縦横比で写真の大きさを決めます
if ($width>$height){
    $new_width = 600;
    $rate = $new_width / $width; //圧縮比
    $new_height = $rate * $height;
}else{
    $new_height = 400;
    $rate = $new_height / $height; //圧縮比
    $new_width = $rate * $width;
}
//縦横比で新たなキャンパスサイズを決定して空の画像を作ります。
$dst=imagecreatetruecolor($new_width, $new_height);
//新しい画像に元の画像をコピーします。
imagecopyresampled($dst,$src,0,0,0,0,$new_width,$new_height,$width,$height);

//出す文字のフォントが置いているパスを指定します。今回はIPAゴシックを使用
$fontPath = "ipagp.otf";
//フォントの色を指定します
$fontColor = ImageColorAllocate($dst, 0, 0, 0);
//フォントと色と出す文字（今回はテストという文字）を写真に埋め込みます。
ImageTTFText($dst, 20, 0, 10, 30, $fontColor, $fontPath, 'テスト');

//ファイルに保存します。第3引数の数字はクオリティーなので好みの数値を0?100で入れる。
imagejpeg($dst, $upload_path . "picture_m.jpeg", 80);
//メモリから画像を開放しておく。
imagedestroy($dst);
</pre>

こんな感じで画像の加工が出来ました。<br />
今回使用したIPAフォントは次の所から落としてきて、パスで指定したところに置いておきます。<br />
http://ossipedia.ipa.go.jp/ipafont/]]>
    </content>
</entry>

<entry>
    <title>QRコード生成ライブラリを使ってみました</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/01/qr.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.73</id>

    <published>2010-01-28T01:21:18Z</published>
    <updated>2010-01-28T01:29:24Z</updated>

    <summary>携帯サイトも併設したシステムを組むことになりPCサイトからQRコードを 読み込ん...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[携帯サイトも併設したシステムを組むことになりPCサイトからQRコードを<br />
読み込んで携帯サイトに飛んでもらうということで、QRコードを作成することになりました。<br /><br /> ]]>
        <![CDATA[QRコード生成は簡単で以下のURLからライブラリを落としてきます。<br />
http://www.swetake.com/qr/qr_cgi.html<br />
<br />
落としてきたライブラリへのパスをイメージタグに行きたい携帯のURLをGET情報で付けて渡すだけです。<br />
<br />

<pre class="php" name="code">

<?php $src_enc = urlencode("http://xxxx.xxx.xx"); ?>
<img src="<?php echo "/qr/php/qr_img.php?d=$src_enc&t=J&s=3" ?>">

</pre>
気をつける点はGETでURLを渡す際はurlencodeした値を渡してあげること。<br />
これで画面にQRコードが表示されました。<br /><br />]]>
    </content>
</entry>

<entry>
    <title>複数ファイルを一気にUPする</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2010/01/up.html" />
    <id>tag:www.okushin.co.jp,2010:/kodanuki_note//5.72</id>

    <published>2010-01-27T07:29:37Z</published>
    <updated>2010-01-27T08:09:28Z</updated>

    <summary>今回複数の写真を一気にUPしたい案件があったのでネットを探していたら、便利そうな...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[今回複数の写真を一気にUPしたい案件があったのでネットを探していたら、便利そうなライブラリを発見！！<br />
<br />
その名もSWFUploadライブラリというもので、ファイルを選択する際にドラッグで複数選ぶか、ShiftかCtrlを押しながら複数選ぶ。<br />選び終わったら開くボタンを押す、そしたら選ばれたファイルが進行状況が分かりながらアップロードされていくというライブラリです。<br />
<br /> ]]>
        <![CDATA[とりあえず次のURLからライブラリの入手をします。<br>
http://www.swfupload.org/<br>
<br>
ダウンロードしてきてとりあえずサンプルのデモを見てみて使えることを確認。<br>
そのソースで要るところを抜粋していって最小で動くライブラリを整理しました。<br>
<br>
構造的に下のような感じになります。<br>
<br>
<span class="mt-enclosure mt-enclosure-image"><img alt="path.gif" src="http://www.okushin.co.jp/kodanuki_note/path.gif" width="300" height="418" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;"/></span>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
/simpledemo/index.phpの内部で次のようなjavascriptの記述をしています。
<pre class="php" name="code">
		var swfu;

		window.onload = function() {
			var settings = {
				flash_url : "../swfupload/swfupload.swf",
				upload_url: "upload.php",
				post_params: {"PHPSESSID" : "<?php echo session_id(); ?>"},
				file_size_limit : "4096",
				file_types : "*.jpg; *.jpeg;",
				file_types_description : "画像ファイル",
				file_upload_limit : 20,
				file_queue_limit : 0,
				custom_settings : {
					progressTarget : "fsUploadProgress",
					cancelButtonId : "btnCancel"
				},
				debug: false,

				// Button settings
				button_image_url: "images/button.png",
				button_width: "120",
				button_height: "30",
				button_placeholder_id: "spanButtonPlaceHolder",
				button_text: '<span class="theFont">ファイル選択</span>',
				button_text_style: ".theFont { font-size: 16; }",
				button_text_left_padding: 12,
				button_text_top_padding: 3,
				
				// The event handler functions are defined in handlers.js
				file_queued_handler : fileQueued,
				file_queue_error_handler : fileQueueError,
				file_dialog_complete_handler : fileDialogComplete,
				upload_start_handler : uploadStart,
				upload_progress_handler : uploadProgress,
				upload_error_handler : uploadError,
				upload_success_handler : uploadSuccess,
				upload_complete_handler : uploadComplete,
				queue_complete_handler : queueComplete	// Queue plugin event
			};

			swfu = new SWFUpload(settings);
	     };
</pre>

のようなソースになっています。<br>
javascriptで各ステータスを指定しているので、自分のサイトにあった形で書き換えていきます。<br>
分かる範囲で簡単に説明を書くと、<br>
flash_url : "../swfupload/swfupload.swf"<br>
付属されているフラッシュへのパスを指定<br>
<br>
upload_url: "upload.php"<br>
アップロード処理が動くファイルへのパスを指定<br>
<br>
file_size_limit : "4096"<br>
アップできるファイルの上限サイズ　今回だったら4MBまでって感じです。<br>
<br>
file_types : "*.jpg; *.jpeg;"<br>
アップできるファイルの種類　今回だったら拡張子の.jpgと.jpegファイルだけUPされます。<br>
<br>
file_types_description : "画像ファイル"<br>
ダイアログが開いたときにアップできるファイルはどれですよという説明文　今回だったら画像ファイルという文字が出ます。<br>
<br>
file_upload_limit : 20<br>
一回でアップロードできるファイルの上限サイズ　今回だったら最大20個までUPされます。<br>
<br>
button_image_url: "images/button.png"<br>
ファイルの選択ボタンの画像へのパス　ファイル選択ボタンが変えたかったらここの画像を変更する。<br>
<br>
button_text: '<span class="theFont">ファイル選択</span>'<br>
ファイルの選択ボタンの文字表示　こじゃれた見た目にするならここのメッセージを無くして画像で綺麗に作ったらいいです。<br>
<br>
とりあえずこのぐらいの変更で使ってみます。<br>
<br>
次に実際に画像をUPするファイル/simpledemo/upload.phpの内容が、<br>

<pre class="php" name="code">
<?php
    $upload_path = "uploads/";
    
    // Handle the upload
    if (!move_uploaded_file($_FILES["Filedata"]["tmp_name"],
        $upload_path . $_FILES["Filedata"]["name"])) {
        header("HTTP/1.0 500 Internal Server Error");
    }
?>
</pre>
という感じで、ここでは/simpledemo/uploadsフォルダに画像を上げていきます。<br>
<br>
これでSWFUploadは使えるようになったのですが、<br>
状態を表す時やエラーになった時のメッセージが英語の状態なので日本語に変えます。<br>
/simpledemo/js/handlers.jsファイルの内容を次のように変えました。<br>

<pre class="php" name="code">
function fileQueued(file) {
	try {
		var progress = new FileProgress(file, this.customSettings.progressTarget);
		progress.setStatus("アップロード待ち");
		progress.toggleCancel(true, this);

	} catch (ex) {
		this.debug(ex);
	}

}

function fileQueueError(file, errorCode, message) {
	try {
		if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
			alert("1回でアップロード出切るファイル数を超えています。");
			return;
		}

		var progress = new FileProgress(file, this.customSettings.progressTarget);
		progress.setError();
		progress.toggleCancel(false);

		switch (errorCode) {
		case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
			progress.setStatus("UP出切るファイルの上限サイズを超えています。");
			this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			break;
		case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
			progress.setStatus("0バイトのファイルはUP出来ません。");
			this.debug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			break;
		case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
			progress.setStatus("UP出きるファイルの種類ではありません。");
			this.debug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			break;
		default:
			if (file !== null) {
				progress.setStatus("ファイルが見つけれませんでした。");
			}
			this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
			break;
		}
	} catch (ex) {
        this.debug(ex);
    }
}

function uploadStart(file) {
	try {
		/* I don't want to do any file validation or anything,  I'll just update the UI and
		return true to indicate that the upload should start.
		It's important to update the UI here because in Linux no uploadProgress events are called. The best
		we can do is say we are uploading.
		 */
		var progress = new FileProgress(file, this.customSettings.progressTarget);
		progress.setStatus("アップロード中");
		progress.toggleCancel(true, this);
	}
	catch (ex) {}
	
	return true;
}

function uploadProgress(file, bytesLoaded, bytesTotal) {
	try {
		var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);

		var progress = new FileProgress(file, this.customSettings.progressTarget);
		progress.setProgress(percent);
		progress.setStatus("アップロード中");
	} catch (ex) {
		this.debug(ex);
	}
}

function uploadSuccess(file, serverData) {
	try {
		var progress = new FileProgress(file, this.customSettings.progressTarget);
		progress.setComplete();
		progress.setStatus("完了");
		progress.toggleCancel(false);

	} catch (ex) {
		this.debug(ex);
	}
}
function queueComplete(numFilesUploaded) {
	var status = document.getElementById("divStatus");
	status.innerHTML = numFilesUploaded + " 個のファイルをUPしました。";
}
</pre>

こんな感じで複数ファイルを一気にUP出来るようになりました。]]>
    </content>
</entry>

<entry>
    <title>CakePHPで携帯サイトを作成する</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/11/cakephp-6.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.68</id>

    <published>2009-11-09T04:26:54Z</published>
    <updated>2009-11-09T05:08:18Z</updated>

    <summary>前回携帯サイトを作った方法だと、CakePHPのバージョンアップによって動かなく...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[前回携帯サイトを作った方法だと、CakePHPのバージョンアップによって動かなくなってしまっていたので、新しい方法で作った覚書を残していきます。<br>
今回は「CakePHP1.2ガイドブック」の携帯サイトを作成するを参考に作っていっています。<br>
この方法だとcakeのバージョンによって動かなくなることは無いと思いますが、一応バージョンは1.2.3.8166で試してみました。<br>
内容はほぼそのままなのですが、自分が分かりやすいようにコメントを付け加えていってます。
]]>
        <![CDATA[1./config/routes.phpにprefixルーティンを設定する。
<pre class="php" name="code">
Router::connect('/m/:controller/:action/*', array('prefix' => 'mobile', 'mobile' => true));
</pre>
urlで/m/コントローラ/アクションという感じにアクセスされるとコントローラーの「mobile_アクション名」が呼び出されるようになります。<br>
<br>
<br>
2.Mobileコンポーネントを作ります<br>
内容は次のような内容です。
<pre class="php" name="code">
class MobileComponent extends Object{
	//prefixルーティンにmobileが入っていたらレイアウトにmobileを使うという処理を入れておきます
    function beforeRender($controller){
    	if (!empty($controller->params['prefix']) && $controller->params['prefix'] == 'mobile'){
    		$controller->layout = $controller->params['prefix'];
    	}
    }

	//自クラスのgetUrl()関数を呼ぶ
    function beforeRedirect(&$controller, $url, $status = null, $exit = true){
    	return MobileComponent::getUrl($controller->params, $url);
    }
    
    //prefixルーティンにmobileが入っていたらURLのGET情報にセッションIDをつけて/mでURLがなっていなかったら/mを付加しておく
    function getUrl($params, $url){
    	if (!empty($params['prefix']) && $params['prefix'] == 'mobile'){
    		$sessionName = session_name();
    		$sessionId = session_id();
    		
    		if (is_array($url)){
    			$url[$params['prefix']] = true;
    			$url['?'] = array($sessionName =>$sessionId);
    		}elseif(is_string($url)){
    			if (!preg_match("#^http[s]?://#", $url)){
    				$prefix = preg_match("#^/m/#", $url) ? '' : '/m';
    				$url = sprintf("%s%s?%s=%s", $prefix, $url, $sessionName, $sessionId);
    			}
    		}
    	}
    	return $url;
    }
    
    //prefixルーティンにmobileが入っていたら自クラスのconvertToInternal()関数を呼ぶ
    function initialize(&$controller){
    	if (!empty($controller->params['prefix']) && $controller->params['prefix'] == 'mobile'){
    		MobileComponent::convertToInternal($controller->params);
    	}
    }
    
    //エンコーディングをUTF-8にして「半角カタカナ」を「全角カタカナ」に変換し、「半角」を「全角」に変換したのを返す
    function convertToInternal(&$value){
    	if (is_null($value)){
    		return;
    	}elseif(is_array($value) || is_object($value)){
    		array_walk_recursive($value, array('MobileComponent','convertToInternal'));
    	}else{
			$value = mb_convert_encoding($value, 'UTF-8', 'sjis-win');
			$value = mb_convert_kana($value, 'KVa', 'UTF-8');
    	}
    }
}
</pre>
<br>
3.Mobileヘルパーを作ります<br>
内容は以下の通りです。
<pre class="php" name="code">
class MobileHelper extends AppHelper{
	//prefixルーティンにmobileが入っていたら 「全角」を「半角」に変換し「全角カタカナ」を「半角カタカナ」に変換しエンコーディングをShift_JISにする。
	function afterLayout(){
		if (!empty($this->params['prefix']) && $this->params['prefix'] == 'mobile'){
			$view =& ClassRegistry::getObject('view');
			
			$view->output = mb_convert_kana($view->output, 'rak', 'UTF-8');
			$view->output = mb_convert_encoding($view->output, 'sjis-win', 'UTF-8');
			
			header ("Content-Type: text/html; charset=Shift_JIS");
		}
	}
}
</pre>
<br>
4.コントローラーでMobileコンポーネントとMobileヘルパーを呼び出しておきます
<pre class="php" name="code">
class XXXXXController extends AppController{
    var $components = array('Mobile');
    var $helpers = array('Mobile');
}
</pre>
<br>
5.コントローラーで携帯用のアクションを作る<br>
mobile_というアクション名にしてその関数内でPC用のアクションを呼んでおく
<pre class="php" name="code">
    //--------------------------------------------------------------------------------
    //一覧ページ
    //--------------------------------------------------------------------------------
    function index() {
		//PC用の処理
    }

    //--------------------------------------------------------------------------------
    //携帯用一覧ページ
    //--------------------------------------------------------------------------------
    function mobile_index() {
    	$this->index();
    }
</pre>
<br>
6./views/layoutに携帯用のテンプレートmobile.phpを作っておく。<br>
<br>
7.コントローラーに合わせてviewsにmobile_の携帯用のviewを作っておく<br>
<br>
8.app_helper.phpを作っておく<br>
内容はviewで入力された$html->url('')で入れられたURLを先に作ったMobileコンポーネントのgetUrl()を呼んで返ってきったURLに置き換える
<pre class="php" name="code">
App::import('Component', 'Mobile');

class AppHelper extends Helper{
    function url($url = null, $full = false) {
    	return parent::url(MobileComponent::getUrl($this->params, $url), $full);
    }
}
</pre>]]>
    </content>
</entry>

<entry>
    <title>php5.3の環境にCakePHPアップしたらDeprecatedエラーが・・・</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/10/php53cakephpdeprecated.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.67</id>

    <published>2009-10-12T03:35:00Z</published>
    <updated>2009-10-12T03:55:02Z</updated>

    <summary>php5.3の環境にCakePHPアップしたらDeprecatedエラーが出まく...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[php5.3の環境にCakePHPアップしたらDeprecatedエラーが出まくりだったのでメモ<br /><br />開発環境から本番環境にソースをアップしてブラウザでアクセスしたら<br /><br />「Deprecated: Assigning the return value of new by reference is deprecated in...」<br />のメッセージが大量に出た、どうもphp5.3からエラーの定義が変わったのが原因みたい。<br /><br />どうも5.3からerror_reporting()に定義がかわり、E_ALL値が変更されたらしい。<br />
<br />
<a href="http://php.benscom.com/manual/ja/errorfunc.constants.php" target="_blank">PHP: 定義済み定数</a><br /><br />cake/libs/configure.phpの297行目くらいに下記のコードを追加してエラーの出力を調整<br /><br />
<pre class="php" name="code">if (isset($config['debug'])) {
  if ($_this-&gt;debug) {
    error_reporting(E_ALL);

  //php 5.3のエラー出力調整(ここから追加)
  if (error_reporting() &gt; 6143) {
    error_reporting(E_ALL &amp; ~E_DEPRECATED);
  }
  //php 5.3のエラー出力調整(ここまで追加)
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>ダウンロードしたCSVファイルが文字化けする問題</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/09/csv.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.66</id>

    <published>2009-09-18T06:35:06Z</published>
    <updated>2009-09-18T07:02:12Z</updated>

    <summary>CSVファイルをダウンロードしたら文字化けするとお客様から連絡があり調べたところ...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[CSVファイルをダウンロードしたら文字化けするとお客様から連絡があり調べたところ、テストサイトではSHIFT_JISでダウンロード出来ていた所が何故かUTF-8でダウンロードされているようになってしまっていました。</br>
</br>
UTF-8のファイルをSHIFT_JISで開きなおすと一応文字化けは直るのですが先頭に「･ｿ」という表示が知らぬうちに付いていました。]]>
        <![CDATA[CSVファイルをダウンロードしたら文字化けするとお客様から連絡があり調べたところ、テストサイトではSHIFT_JISでダウンロード出来ていた所が何故かUTF-8でダウンロードされているようになってしまっていました。</br>
</br>
UTF-8のファイルをSHIFT_JISで開きなおすと一応文字化けは直るのですが先頭に「･ｿ」という表示が知らぬうちに付いていました。</br>
</br>
インターネットで調べてみたら原因は・・・</br>
</br>
UTF-8で書かれているPHPファイルをメモ帳で編集して保存をすると、先頭にBOM(Byte Order Mark)が負荷されて保存されてしまいます。</br>
このBOMはPHPのechoでheaderを出力する前に出力されてしまうのでCSVにもこのBOMがきっちり先頭に付いてきちゃうという事でした。</br>
CSVにBOMが付いてくるとSHIFT_JISで開かれるはずのCSVファイルがUTF-8で開かれてしまうので今回の現象が起きたというわけです。</br>
</br>
というわけで改修作業ですが、BOMが負荷されたPHPファイルを見つけ出して先頭のBOMファイルを取り除いてあげます。</br>
このファイルを上げなおしてあげると、きちんと文字化けせずにCSVのダウンロードできるようになりました。</br>
</br>
UTF-8で開発している時はメモ帳で編集するなという教訓が出来ました・・・</br>
</br>
今回は以下のサイトを参考にさせていただきました。</br>
Keep It Simple, Stupid!</br>
http://takesita.seesaa.net/article/96553793.html</br>
</br>
Sun Limited Mt.</br>
http://www.syuhari.jp/blog/archives/384

]]>
    </content>
</entry>

<entry>
    <title>二重送信防止プログラム</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/09/post-6.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.65</id>

    <published>2009-09-18T06:14:31Z</published>
    <updated>2009-09-18T07:04:19Z</updated>

    <summary>submitボタンを押した時に間違って連打で押してしまった時にデータの保存が2重...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[submitボタンを押した時に間違って連打で押してしまった時にデータの保存が2重でされたり、メールが2通送られてしまったりします。<br />
<br />
今回はjavascriptで制御する方法を取ってみたので簡単に紹介します。<br />]]>
        <![CDATA[submitボタンを押した時に間違って連打で押してしまった時にデータの保存が2重でされたり、メールが2通送られてしまったりします。<br />
<br />
今回はjavascriptで制御する方法を取ってみたので簡単に紹介します。<br />
<br />
ソースは下の感じになります。<br />
<pre class="php" name="code">
<script language="JavaScript">
<!--
sent = false;
//2重投稿を防止する
function send_check(){
	if(sent){
		alert("二重送信防止！\n1度目の押下だけ有効")
		return false
	}else{
		sent = true
		return true
	}
}
// -->
</script>
<form action="飛ばしたい先" method="post" name="form" OnSubmit="return send_check()">
</form>
</pre>
MVCの処理のviewのところに入れ込みます。<br />
フォームの開始するところでjavascriptのsend_check()関数を呼び出しておいて、このフォーム内のsubmitボタンを連打で押すとウィンドウでエラーメッセージが表示されるという感じです。</br>
保存やメール送信をするところでこの記述を書いておくと二重投稿が防げます。]]>
    </content>
</entry>

<entry>
    <title>CakePHPでSSL認証とそうでない時の処理を振り分ける</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/09/cakephpssl.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.64</id>

    <published>2009-09-18T05:55:07Z</published>
    <updated>2009-09-18T07:05:47Z</updated>

    <summary>ログインするときにSSL通信でログインするか普通の通信でログインするかを選べるよ...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="PHP" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[ログインするときにSSL通信でログインするか普通の通信でログインするかを選べるようにして欲しいというお客さんの要望があったので今回はこんな感じのプログラムで対応しました。<br />
 <br />
やっている内容はログイン時にSSL通信でログインした時、Cake内の移動の際にSSL通信の場合はhttpsで移動するようにするという感じです。<br />
]]>
        <![CDATA[ログインするときにSSL通信でログインするか普通の通信でログインするかを選べるようにして欲しいというお客さんの要望があったので今回はこんな感じのプログラムで対応しました。<br />
 <br />
やっている内容はログイン時にSSL通信でログインした時、Cake内の移動の際にSSL通信の場合はhttpsで移動するようにするという感じです。<br />
<br />
ログインのときに<br />
<pre class="php" name="code">
//ログイン
if (isset($this->params['form']['login'])) {
	//SSL通信でやり取りしない
	$this->Session->del('ssl');
}
//SSLでログイン
if (isset($this->params['form']['ssl_login'])) {
	//SSL通信でやり取りする
	$this->Session->write('ssl', true);
}
</pre>
という感じでSSLかどうかをセッションにもっておきます。<br />
<br />
beforeFilterでセッションの状態がSSL通信でURLがhttps://で始まらない場合はhttpsにリダイレクトをするという処理を入れるとSSL通信と普通の時の通信が切り替えられました。
<pre class="php" name="code">
function beforeFilter() {
	//SSL通信かどうか切り替える
	if ($this->Session->check('ssl')){
		if(empty($_SERVER['HTTPS'])){
			$this->redirect( 'https://' . $_SERVER['HTTP_HOST'] . $this->here );
			exit;
		}
	}
}
</pre>]]>
    </content>
</entry>

<entry>
    <title>ドキュメント勉強会に参加してきました。</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/08/post-5.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.63</id>

    <published>2009-08-17T04:24:54Z</published>
    <updated>2009-08-17T05:26:09Z</updated>

    <summary>ドキュメント勉強会開催の経緯 技術部の今岡です。 もう少し前のことになってしまっ...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[<p><font style="FONT-SIZE: 1.25em"><strong><u>ドキュメント勉強会開催の経緯</u></strong></font></p>
<p>技術部の今岡です。</p>
<p>もう少し前のことになってしまって恐縮ですが、ドキュメント勉強会というものに参加してきました。</p>
<p>8月6日（木）　大阪市北区のメビック扇町というところで、場所はCakePHP関西勉強会の会場と同じところです。</p>
<p>そのCakePHP関西勉強会の第二回が、私の技術系勉強会の初体験だったにもかかわらず、今回の勉強会では発表者に名前を連ねることになってしまいました。</p>
<p>CakePHP勉強会の後、人から薦められてアカウントを作っていたTwitterを本格的に利用し始めました。</p>
<p>Twitterでは様々な人が好き勝手なことを雑多に呟き、その呟きに興味があったりして継続的にその呟きを読む為には、呟いている人を「フォローする」という操作を行います。</p>
<p>Twitterの詳しい話は今回の話題ではないですが、そのTwitter上でCakePHP勉強会を主催された新原さんという方をフォローさせて戴きました。</p>
<p>新原さんがTwitter上で勉強会というものについて、とか、ドキュメント勉強会ってどう思う？というような疑問を投げられまして、私を含め数人がそれに反応し、その反応の内容を受けて新原さんはドキュメント勉強会を開催しようと決定されました。</p>
<p>（新原さん自身のブログやWassarという別のサービスなどもありますので、Twitterがすべてではないと思います。念のため。）</p>
<p>勉強会の決定や開催日時の告知にもTwitteｒが有効に活用されました。</p>
<p>そして、そのTwitterを通じて、私のところに発表の依頼が飛んできたのでした・・・。</p>
<p>&nbsp;</p>]]>
        <![CDATA[<p><font style="FONT-SIZE: 1.25em" size="5"><strong><u>ドキュメント勉強会ってどんなもの？</u></strong></font></p>
<p>業界で使われている技術は沢山あり、日々新しくなったり廃れたりしています。</p>
<p>その技術に関しての勉強会は今までもいろいろと開催されているのですが、その技術を伝達したり技術を使った仕事の依頼、記録などに使われる書類(＝ドキュメント）の書式は、業界標準が存在しません。</p>
<p>大手企業だとしっかりした社内基準がありますが、個人や零細のソフトハウスでは基準はなく、ドキュメントの存在さえ怪しいのが現状だと思います。</p>
<p>ですので、必要という意識さえないという人から、書こうにも書き方が判らない人、常にドキュメント作成を専門にやりまくっているという人まで同じ業界でもいろんな人がいることと思います。</p>
<p>今回は、ドキュメント作成に興味があったり、なんらかの不自由感困った感がある人達で集まって、それぞれがどんな風にドキュメントを作っているのか、何に困っているのかを話し合ってみましょう！という、チャレンジっぽい勉強会です。</p>
<p>主催者の新原さんから、お題が出ました。それは</p>
<p>「Poken販売サイト」</p>
<p>Pokenというのは、名刺代わりになるマスコットのようなおもちゃのようなモノです。かわいいです。</p>
<p>世間の一部で愛好されていて、新原さんもお持ちです。</p>
<p>それを販売するサイトの製作にあたり、必要と思われるドキュメントを発表担当者がそれぞれに作って勉強会当日にそれを公開し話のタネにします。</p>
<p>勉強会の運営と発表者の連絡用に、事前にメーリング・リストが開設され、出欠確認・お題の発表・新原さんのサンプルドキュメントの配布・当日の会場到着予定時間のお知らせなどに活用されました。</p>
<p>細かい話ですが、勉強会までの道のりは下記のような感じです。</p>
<p>7月7日　ドキュメント勉強会の開催決定</p>
<p>7月15日　今岡のところに発表の依頼がくる</p>
<p>7月下旬　サンプルドキュメントの配布</p>
<p>8月6日　勉強会の開催</p>
<p>&nbsp;</p>
<p><font style="FONT-SIZE: 1.25em" size="5"><strong><u>勉強会の実際</u></strong></font></p>
<p>さて、では実際の勉強会とはどんな感じだったのでしょうか？</p>
<p>すでに参加された皆さんが自身のブログなどにいろいろ書いておられますが、とっても面白く為になる内容でした。</p>
<p>いや、本当。</p>
<p>事前に打ち合わせしてないことが信じられないくらい、各発表者の製作意図や方法がバラバラで、結果的に非常にバラエティに富んだ発表内容となりました。</p>
<p>私は自身の日常業務そのままに、小さなソフトハウスが下請けでシステムを製造するという前提でいくつかのドキュメントを作りました。内容としては下記になります。</p>
<p>・メニューフロー</p>
<p>・データベース設計書</p>
<p>・フォルダ構成</p>
<p>・スケジュール</p>
<p>・その他前提条件などのメモ</p>
<p>&nbsp;</p>
<p>ドキュメントを書くにあたり使用したのはExcelです。</p>
<p>特に笑いどころのない生真面目なものを作成してしまいました。</p>
<p>内容に興味のある方はご一報ください。</p>
<p>発表で使用したドキュメント類はどれでもお送りさせて戴きます。</p>
<p>ダウンロードの仕掛けが出来てなくてすいません・・・。</p>
<p>&nbsp;</p>
<p>お題である通販サイトの製作には、製造部隊のみならずプロデューサに当たる方やデザイン担当の方などいろいろな人が関わることになります。もちろん、依頼主である顧客もいますし、サイトを利用しPokenを購入するお客様もおられます。</p>
<p>誰の立場でドキュメントを書くかで、書き方も内容も全然違ったものになります。</p>
<p>私は掴みの新原さんの後、二番目の発表でしたが、その後にはWEBプロデューサの方、はたまたドキュメントを普段まったく書かないという方の発表が続き、途中Poken販売サイトというお題にまったく触れない果敢な発表もあり、聞きなれない強力なドキュメント製造ツールのお話、最後に大手さんだ！！と感動の超きっちりのドキュメントが公開されました。</p>
<p>途中で休憩があり、みたらしだんごを戴きました。</p>
<p>ひとりの発表持ち時間は10分が目安とのお話だったのですが、やはり熱くなりがちで時間は押し押しでした。</p>
<p>もっといろんなドキュメントがあるはずですし、もっとしたい質問もあるのでは？と思いました。</p>
<p>第二回の開催が待たれます。</p>
<p>時間の関係で質疑応答はあまりなかったのですが、多くの方が懇親会に参加されましたので、そこで少しは補足が出来たのかなと思います。</p>
<p>私の周辺ではPokenとiPhoneの話題がもっぱらでしたが・・・。</p>
<p>MacにもiPhoneにも馴染みがない私は、隣の席の方に「夏ライオン」のアイコンを見せてもらって感動しました。</p>
<p>&nbsp;</p>
<p>さて、つらつらとあまり内容はない記事ではありますが、勉強会の雰囲気が伝われば幸いです。</p>
<p>皆さん、勉強会にどんどん参加しましょう！</p>
<p>出来ればがんがん発表しましょう！！</p>
<p>勉強会の敷居は低いです。</p>
<p>業界人と業界の周辺の方、ウェルカムです。</p>
<p>と、言うようなことを主催者の新原さんがおっしゃってました。・・・と、思います・・・。</p>]]>
    </content>
</entry>

<entry>
    <title>CSVファイルをモデルのfindメソッドで読み込む方法</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/07/csvfind.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.62</id>

    <published>2009-07-21T01:31:51Z</published>
    <updated>2009-09-18T07:10:45Z</updated>

    <summary>CakePHPの勉強会で、英語に負けずコードをばんばん読んでいこう！という話があ...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[CakePHPの勉強会で、英語に負けずコードをばんばん読んでいこう！という話があったので、Bakeryの中を覗いて見つけたソースを動かすというのをやってみました。<br />
今回はCSVファイルをfind一発で読んでしまおうというヤツです。<br />
元はSiegfriedHirschさんが作成されました。<br />
<br />
CSVファイルをデータベースっぽくする為に、いくつか準備をします。<br />
<br />
]]>
        <![CDATA[CakePHPの勉強会で、英語に負けずコードをばんばん読んでいこう！という話があったので、Bakeryの中を覗いて見つけたソースを動かすというのをやってみました。<br />
今回はCSVファイルをfind一発で読んでしまおうというヤツです。<br />
元はSiegfriedHirschさんが作成されました。<br />
<br />
CSVファイルをデータベースっぽくする為に、いくつか準備をします。<br />
<br />
1./models/datasources/csv_source.phpを設置する。<br />
下記のファイルになります。<br />
<br />
<pre class="php" name="code">
&lt;?php<br />/**<br />&nbsp;* CSV class<br />&nbsp;*<br />&nbsp;* Licensed under The MIT License<br />&nbsp;* Redistributions of files must retain the above copyright notice.<br />&nbsp;*<br />&nbsp;* @author Siegfried Hirsch &lt;siegfried.hirsch@gmail.com&gt;<br />&nbsp;* @copyright Copyright 2008-2009, Siegfried Hirsch<br />&nbsp;* @license http://www.opensource.org/licenses/mit-license.php The MIT License<br />&nbsp;* @created Januar 21, 2009<br />&nbsp;* @version 1.0<br />&nbsp;**/<br />class CsvSource extends DataSource {<br /><br />/**<br />&nbsp;* Description string for this Data Source.<br />&nbsp;*<br />&nbsp;* @var unknown_type<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; var $description = "CSV Data Source";<br />&nbsp;&nbsp;&nbsp; var $delimiter = ';'; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // delimiter between the columns<br />&nbsp;&nbsp;&nbsp; var $maxCol = 0;<br />&nbsp;&nbsp;&nbsp; var $fields = null; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // fieldnames<br />&nbsp;&nbsp;&nbsp; var $handle = false; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // handle of the open csv file<br />&nbsp;&nbsp;&nbsp; var $page = 1; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // start always on the first page<br />&nbsp;&nbsp;&nbsp; var $limit = 99999; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // just to make the chunks not too big<br /><br />/**<br />&nbsp;* Default configuration.<br />&nbsp;*<br />&nbsp;* @var unknown_type<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; var $__baseConfig = array(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'datasource' =&gt; 'csv',<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'path' =&gt; '.', &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // local path on the server relative to WWW_ROOT<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'extension' =&gt; 'csv', &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // file extension of CSV Files<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'readonly' =&gt; true, &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // only for reading<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'recursive' =&gt; false, &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // only false is supported at the moment<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );<br /><br /><br />/**<br />&nbsp;* Constructor<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; function __construct( $config = null, $autoConnect = true ){<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Configure::write('debug', 1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;debug = Configure::read( 'debug' ) &gt; 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;fullDebug = Configure::read( 'debug' ) &gt; 1;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // debug($config);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parent::__construct( $config );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $autoConnect ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $this-&gt;connect();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />/**<br />&nbsp;* Connects to the mailbox using options in the given configuration array.<br />&nbsp;*<br />&nbsp;* @return boolean True if the mailbox could be connected, else false<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; function connect() {<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $config = $this-&gt;config;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;connected = false;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uses( 'Folder' );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $config['readonly'] ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $create = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $mode = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $create = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $mode = 0777;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //$config['path'] = WWW_ROOT . $config['path'];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $config['path'] = TMP . $config['path'];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Added by Imaoka on 26-Jun-2009<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // debug($config['path']);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;connection = &amp;new Folder( $path = $config['path'], $create, $mode );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $this-&gt;connection ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;handle = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;connected = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return $this-&gt;connected;<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />&nbsp;&nbsp;&nbsp; /**<br />&nbsp;&nbsp;&nbsp;&nbsp; * listSources<br />&nbsp;&nbsp;&nbsp;&nbsp; *<br />&nbsp;&nbsp;&nbsp;&nbsp; * @author: SHirsch<br />&nbsp;&nbsp;&nbsp;&nbsp; * @created: 21.01.2009<br />&nbsp;&nbsp;&nbsp;&nbsp; * @return array of available CSV files<br />&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; function listSources() {<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $config = $this-&gt;config;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $this-&gt;_sources !== null ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $this-&gt;_sources;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $config['recursive'] ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // not supported yet -&gt; has to use Folder::findRecursive()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // すべてにCSVファイル名を取得し、拡張子を省いてテーブル名にしたものを$listに格納する<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // list all .csv files and remove the extension to get only "tablenames"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $list = $this-&gt;connection-&gt;find( '.*' . $config['extension'], false );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( $list as &amp;$l ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( stripos( $l,&nbsp; '.' . $config['extension'] ) &gt; 0 ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $l = str_ireplace( '.' . $config['extension'], '', $l );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;_sources = $list;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //debug( $list );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $list;<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />/**<br />&nbsp;* Convenience method for DboSource::listSources().&nbsp; Returns source names in lowercase.<br />&nbsp;*<br />&nbsp;* @return array<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; function sources( $reset = false ){<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $reset === true ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;_sources = null;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return array_map( 'strtolower', $this-&gt;listSources() );<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />/**<br />&nbsp;* Returns a Model description (metadata) or null if none found.<br />&nbsp;* デリミッタ、列数、各列名をセット。各列名を返す。<br />&nbsp;*<br />&nbsp;* @return mixed<br />&nbsp;**/<br />&nbsp;&nbsp;&nbsp; function describe( $model ){<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //debug( $model-&gt;table );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;__getDescriptionFromFirstLine( $model );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //debug( $this-&gt;fields );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $this-&gt;fields;<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />&nbsp;&nbsp;&nbsp; /**<br />&nbsp;&nbsp;&nbsp;&nbsp; * __getDescriptionFromFirstLine and store into class variables<br />&nbsp;&nbsp;&nbsp;&nbsp; *<br />&nbsp;&nbsp;&nbsp;&nbsp; * @author: SHirsch<br />&nbsp;&nbsp;&nbsp;&nbsp; * @created: 21.01.2009<br />&nbsp;&nbsp;&nbsp;&nbsp; *<br />&nbsp;&nbsp;&nbsp;&nbsp; * @param $model<br />&nbsp;&nbsp;&nbsp;&nbsp; * @set CsvSource::fields array with fieldnames from the first line<br />&nbsp;&nbsp;&nbsp;&nbsp; * @set CsvSource::delimiter char the delimiter of this CSV file<br />&nbsp;&nbsp;&nbsp;&nbsp; *<br />&nbsp;&nbsp;&nbsp;&nbsp; * @return true<br />&nbsp;&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; private function __getDescriptionFromFirstLine( $model ){<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $config = $this-&gt;config;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //$config['path'] = WWW_ROOT . $config['path'];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Added by Imaoka on 26-Jun-2009<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $config['path'] = TMP . $config['path'];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Modified by Imaoka on 26-Jun-2009<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $filename = $model-&gt;table . "." . $config['extension'];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $handle = fopen( $config['path'] . DS .&nbsp; $filename, "r" );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $line = rtrim( fgets( $handle ) ); &nbsp;&nbsp;&nbsp; // remove \n\r<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $data_comma = explode( ",", $line );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $data_semicolon = explode( ";", $line );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( count( $data_comma ) &gt; count( $data_semicolon ) ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;delimiter = ',';<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;fields = $data_comma;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;maxCol = count( $data_comma );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;delimiter = ";";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;fields = $data_semicolon;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;maxCol = count( $data_semicolon );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose( $handle );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />&nbsp;&nbsp;&nbsp; /* close<br />&nbsp;&nbsp;&nbsp; **<br />&nbsp;&nbsp;&nbsp; ** @created: 21.01.2009 14:59:08<br />&nbsp;&nbsp;&nbsp; **<br />&nbsp;&nbsp;&nbsp; */<br />&nbsp;&nbsp;&nbsp; function close(){<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $this-&gt;connected ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $this-&gt;handle ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @fclose( $this-&gt;handle );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;handle = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;connected = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br /><br /><br />/**<br />&nbsp;* The "R" in CRUD<br />&nbsp;*<br />&nbsp;* @param Model $model<br />&nbsp;* @param array $queryData<br />&nbsp;* @param integer $recursive Number of levels of association<br />&nbsp;* @return unknown<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; function read( &amp;$model, $queryData = array(), $recursive = null ){<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $config = $this-&gt;config;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //$config['path'] = WWW_ROOT . $config['path'];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Added by Imaoka on 26-Jun-2009<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $config['path'] = TMP . $config['path'];&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Modified by Imaoka on 26-Jun-2009<br /><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // デリミッタ、列情報の取得<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $this-&gt;fields = $this-&gt;describe( $model );&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Added by Imaoka on 26-Jun-2009<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $filename = $config['path'] . DS . $model-&gt;table . "." . $config['extension'];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $this-&gt;handle === false ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;handle = fopen( $filename,&nbsp; "r" );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $queryData = $this-&gt;__scrubQueryData( $queryData );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // get the limit<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( isset( $queryData['limit'] ) &amp;&amp; !empty( $queryData['limit'] ) ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;limit = $queryData['limit'];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //debug( $this-&gt;limit );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // get the page#<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( isset( $queryData['page'] ) &amp;&amp; !empty( $queryData['page'] ) ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;page = $queryData['page'];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //debug( $this-&gt;page );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( empty( $queryData['fields'] ) ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $fields = $this-&gt;fields;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $allFields = true;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $fields = $queryData['fields'];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $allFields = false;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_fieldIndex = array();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $index = 0;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // generate an index array of all wanted fields<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( $this-&gt;fields as $field ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( in_array( $field, $fields ) ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_fieldIndex[] = $index;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $index++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $lineCount = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $recordCount = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet = array();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Daten werden aus der Datei in ein Array $data gelesen<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Modified by Imaoka on 26-Jun-2009<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //while( ( $data = fgetcsv( $this-&gt;handle, 8192, $this-&gt;delimiter ) ) !== FALSE ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( ( $data = fgetcsv_reg( $this-&gt;handle, 8192, $this-&gt;delimiter ) ) !== FALSE ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $lineCount == 0 ) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // throw away the first line<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $lineCount++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // $_page = 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // compute the virtual pagenumber<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Modified by Imaoka on 26-Jun-2009<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //$_page = floor( $lineCount / $this-&gt;limit ) + 1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $_page = floor( $lineCount / $this-&gt;limit );<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if( $lineCount % $this-&gt;limit &gt; 0 )<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $_page++;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // do have have reached our requested page ?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $this-&gt;page &gt; $_page ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $lineCount++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // skip over records, that are not complete<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( count( $data ) &lt; $this-&gt;maxCol ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $lineCount++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $record = array();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $allFields ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $i = 0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $record['id'] = $lineCount;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( $fields as $field ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $record[$field] = $data[$i++];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet[] = $record;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $record['id'] = $lineCount;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( count( $_fieldIndex ) &gt; 0 ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( $_fieldIndex as $i ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $record[$this-&gt;fields[$i]] = $data[$i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $resultSet[] = $record;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unset( $record );<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // now count every record<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $recordCount++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $lineCount++;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // is our page filled with records, then stop<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( $recordCount &gt;= $this-&gt;limit ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $result[$model-&gt;table] = $resultSet;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $result;<br />&nbsp;&nbsp;&nbsp; }<br /><br />/**<br />&nbsp;* Private helper method to remove query metadata in given data array.<br />&nbsp;*<br />&nbsp;* @param array $data<br />&nbsp;* @return array<br />&nbsp;*/<br />&nbsp;&nbsp;&nbsp; function __scrubQueryData( $data ) {<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach( array( 'conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group') as $key ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !isset( $data[$key] ) || empty( $data[$key] ) ){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $data[$key] = array();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $data;<br />&nbsp;&nbsp;&nbsp; }<br /><br />}<br />?&gt;
</pre>
<br />
<br />
2./app/config/database.phpに追記する。<br />
CSV用のデータソースを定義します。<br />
<br />
<pre class="php" name="code">
&nbsp;&nbsp;&nbsp; var $csv = array(<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'datasource' =&gt; 'csv',<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'path' =&gt; 'csv', &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // local path on the server<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'extension' =&gt; 'csv', &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // file extension of CSV Files<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'readonly' =&gt; true, &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // only for reading<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'recursive' =&gt; false, &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // only false is supported at the moment<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );
</pre>
<br />
datasource...CSVファイル用なので、'csv'としてください。<br />
path...これは、読み込むCSVファイルを置くフォルダ名です。ソースコードも参照して、適宜変更可です。<br />
extension...CSVファイルの拡張子なので、'csv'です。<br />
readonly...読み込むだけなので、trueです。<br />
recursive...リレーショナルではないので、falseです。<br />
<br />
3.CSVファイルを読み込むモデルを用意します。<br />
読み込むCSVファイルは、それ自体をDBテーブルのように扱いますので、ファイル名をテーブル名のように命名し、普通のモデルファイルを用意します。<br />
そのモデルを使用するコントローラ、モデルを使用して取得したデータを表示するビューも用意しました。<br />
それぞれのサンプルコード・ファイル名は下記になります。<br />
<br />
モデル名：Price<br />
モデルファイル名：/models/price.php<br />
コントローラ名：prices_controller.php<br />
ビューファイル名：/views/prices/read.php<br />
CSVファイル名：/app/tmp/csv/prices.csv　（複数形です。テーブル名と同じ）<br />
<br />
CSVファイルの中身は下記です。<br />
1行目は列名、デリミッタはカンマ、ファイルの文字コードはUTF-8、改行コードはLFです。<br />
スクリプトでファイルをアップロードすることを想定し、CSVファイルの置き場所は/tmpの中に/csvというフォルダを作成してやることにしました。<br />
<br />
id,name,dep,device,favourite,price<br />
1,山田太郎,代表,自転車,サボテン,1000<br />
2,鈴木一郎,技術,電車,タバコ,1200<br />
3,福山雅治,技術,電車,じゃがりこ,600<br />
4,木村拓哉,営業,電車,デニム,750<br />
5,岡田准一,技術,自転車,お酒,850<br />
<br />
4.モデルを書きます。<br />
モデルでは、'csv'というデータソースを使用することを宣言します。<br />
コードは下記。<br />
<br />
<pre class="php" name="code">
&lt;?php <br />class Price extends AppModel {<br />&nbsp;&nbsp;&nbsp; var $name = 'Price';<br />&nbsp;&nbsp;&nbsp; var $useDbConfig = 'csv';<br />&nbsp;&nbsp;&nbsp; var $useTable = false;<br />}<br />?&gt;
</pre>
<br />
5.コントローラを書きます。<br />
Priceモデルの使用を宣言し、findでデータを読み込みます。<br />
<br />
<pre class="php" name="code">
&lt;?php<br />class PricesController extends AppController<br />{<br />&nbsp;&nbsp;&nbsp; var $name = 'Prices';<br />&nbsp;&nbsp;&nbsp; var $uses = array( 'Price' );<br /><br />&nbsp;&nbsp;&nbsp; function read(){<br /><br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $list = $this-&gt;Price-&gt;find( 'all' );<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $this-&gt;set( 'list', $list['prices'] );<br />&nbsp;&nbsp;&nbsp; }<br />?&gt;
</pre>
<br />
6.ビューを書きます。<br />
取得したデータの確認に、テーブルに吐き出すように書いています。<br />
<br />
<pre class="php" name="code">
&lt;h2&gt;CSVデータ一覧&lt;/h2&gt;<br />&lt;table&gt;<br />&nbsp;&nbsp;&nbsp; &lt;tr&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;th&gt;ID&lt;/th&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;th&gt;名前&lt;/th&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;th&gt;部署・役職&lt;/th&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;th&gt;通勤手段&lt;/th&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;th&gt;好きなもの&lt;/th&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;th&gt;価格&lt;/th&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/tr&gt;<br />&lt;?php<br /><br />&nbsp;&nbsp;&nbsp; foreach( $list as $data )<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; print &lt;&lt;&lt;EOD<br />&nbsp;&nbsp;&nbsp; &lt;tr&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;td&gt;{$data['id']}&lt;/td&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;td&gt;{$data['name']}&lt;/td&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;td&gt;{$data['dep']}&lt;/td&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;td&gt;{$data['device']}&lt;/td&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;td&gt;{$data['favourite']}&lt;/td&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;td&gt;{$data['price']}&lt;/td&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/tr&gt;<br />EOD;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />?&gt;<br />&lt;/table&gt;
</pre>
<br />
さて、findした結果、データがどのように入ってきたのかを確認してみましょう。<br />
<br />
<span class="mt-enclosure mt-enclosure-image"><img alt="csv_data.JPG" src="http://www.okushin.co.jp/kodanuki_note/2009/07/21/imaoka/csv_data.JPG" class="mt-image-left" style="margin: 0pt 20px 20px 0pt; float: left;" height="647" width="840" /></span><br /><img src="file:///C:/DOCUME%7E1/imaoka/LOCALS%7E1/Temp/5/moz-screenshot.png" alt="" />
<br />
そして、テーブルに表示すると下記のような感じです。<br />
<br />
<span class="mt-enclosure mt-enclosure-image"><img alt="csv_table.JPG" src="http://www.okushin.co.jp/kodanuki_note/2009/07/21/imaoka/csv_table.JPG" class="mt-image-left" style="margin: 0pt 20px 20px 0pt; float: left;" height="647" width="840" /></span>
<br />
読み込む際のパラメータとしては、読み込み件数(limit)、件数指定が指定されている場合にどのページを読み込むか(page)、どの列を読み込むか(fields)の三つが使用可能です。<br />
<br />
<pre class="php" name="code">
 $list = $this-&gt;Price-&gt;find( 'all', array(&nbsp;&nbsp;&nbsp; 'limit' =&gt; 4, &nbsp;&nbsp;&nbsp; // read only 100 records<br />　　 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'page' =&gt; 1,&nbsp;&nbsp;&nbsp; // start at page 2, limit is needed to make sense<br />&nbsp;&nbsp;&nbsp; 　　 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 'fields' =&gt; array( 'id', 'name', 'price' )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; );
</pre>
<br />
CSVファイルの場所など少し気をつけるポイントはありますが、find一発で読み込めるのは便利です。<br />
是非お試しください。<br /></div><div><br /><br /></div>]]>
    </content>
</entry>

<entry>
    <title>第2回CakePHP関西勉強会でLTしてきました</title>
    <link rel="alternate" type="text/html" href="http://www.okushin.co.jp/kodanuki_note/2009/06/2cakephplt.html" />
    <id>tag:www.okushin.co.jp,2009:/kodanuki_note//5.60</id>

    <published>2009-06-14T05:17:31Z</published>
    <updated>2009-06-14T05:40:53Z</updated>

    <summary>6月5日に第2回CakePHP関西勉強会に参加してきました。 今回の発表はかなり...</summary>
    <author>
        <name>編集者</name>
        <uri>http://www.okushin.co.jp</uri>
    </author>
    
        <category term="CakePHP" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="勉強会" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.okushin.co.jp/kodanuki_note/">
        <![CDATA[6月5日に<a href="http://events.php.gr.jp/events/show/76">第2回CakePHP関西勉強会</a>に参加してきました。<br>
今回の発表はかなりのグズグズになってしまいました。<br>
まず体調が悪く血圧がかなり下がってしまっていて、発表中は景色が白く見えるぐらいもうろうとして何を話しているのかという感じになってしまいました・・・<br>
次に発表のリハーサルの時は目の前のノートパソコンで動かしていたのですが、本番ではプロジェクタを見て操作をすることになり画面が見にくく操作が思うように出来ず、操作にだいぶ時間を取られてしまいました。<br>

とりあえず発表内容のパワーポイントです。

<div style="width:425px;text-align:left"><a style="font:14px Helvetica,Arial,Sans-serif;color: #0000CC;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideboom.com/presentations/75613/CakePHP%E3%81%A7PDF%E5%87%BA%E5%8A%9B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B" title="CakePHPでPDF出力してみる">CakePHPでPDF出力してみる</a><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0" width="425" height="370" id="onlinePlayer"><param name="movie" value="http://www.slideboom.com/player/player.swf?id_resource=75613" /><param name="allowScriptAccess" value="always" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><param name="allowFullScreen" value="true" /><param name="flashVars" value="title=CakePHPでPDF出力してみる&url=http://www.slideboom.com/presentations/75613/CakePHP%E3%81%A7PDF%E5%87%BA%E5%8A%9B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B&mode=0&idResource=75613&siteUrl=http://www.slideboom.com&embed=1&startAuto=0&autoReplay=0&autoOpenShareScreen=1" /><embed src="http://www.slideboom.com/player/player.swf?id_resource=75613" width="425" height="370" name="onlinePlayer" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"allowScriptAccess="always" quality="high" bgcolor="#ffffff" allowFullScreen="true" flashVars="title=CakePHPでPDF出力してみる&url=http://www.slideboom.com/presentations/75613/CakePHP%E3%81%A7PDF%E5%87%BA%E5%8A%9B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B&mode=0&idResource=75613&siteUrl=http://www.slideboom.com&embed=1&startAuto=0&autoReplay=0&autoOpenShareScreen=1" ></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View <a href="http://www.slideboom.com" style="color: #0000CC;">more presentations</a> or <a href="http://www.slideboom.com/upload" style="color: #0000CC;">Upload</a> your own.</div></div>

とりあえず座標合わせライブラリの評判が良かったので、頑張ってソースを整理して公開できたらいいなと考えています。<br>
発表してみて色々指摘を受けれたので、それを受けて今後作っていけたらと思います。]]>
        
    </content>
</entry>

</feed>
