SSブログ
Lancers.jp

デザイナー向けCakePHP勉強会 [CakePHP]

まず、内容に関しては、他の方の素敵で丁寧な文章をご参考下さい。

「第1回「デザイナー向けCakePHP勉強会」開催!」
http://blog.direct-search.jp/2011/07/1cakephp.html

「納豆には卵を入れる派です。」
http://d.hatena.ne.jp/ken_c_lo/20110723/1311439282

「BONNOU」
http://bonnou-108.jugem.jp/?eid=16


感想としては、行って良かった!
何が良かったって、自宅から近かったこと(笑
あとは、他人の考えを聞くことで、自分の考えの偏狭さを修正できることかな。
情報だけなら、行かなくても得ることは出来るけど、知りたい情報しか見なくなって、取りこぼしてる部分も意外と多いのを実感した。

デザイナー向けとしては第一回とのことなので、気になるところもなくはなかったけど、そういうのは数こなせば慣れてくるものだと思うので、これからもどんどんやって欲しいね。
今後も、手伝えることがあれば、手伝いたいな。

一番良かったのは、発表する方がみんなわかりやすく、丁寧に説明されているのが伝わってきたこと。
教えてくれる人の、そういった情熱(というと大袈裟かもだけど)があると、聞く方もわかろうと努めるしね。

あと、個人的にだけど、プログラマ向けの勉強会でありがちな、オタク系悪ノリがなかったのも、良かったなぁ。
アレ(AAとか)って、わかる人は面白いんだろうけど、興味ないとイラっとするから。

テンプレートまわりの話は、いつも迷ってて、その辺りの話が聞けたのも良かった!
興味深かったのは、PHPTALとMTCake。

PHPTAL
http://www.slideshare.net/nojimage/phptal-with-cakephp
コレは、入れようかどうかずっと迷ってたんだけど、一度は試した方が良さそうだなー。
でも、逆にテンプレ部が埋没する訳で、可読性は低くなってしまうかも、ってのが懸念点。

ってことはMTCakeがかなりの有望株かも。
http://powercms.alfasado.net/blog/2011/06/cakephpviewmtmtcake.html
基本的にウチはMTでの案件がとても多いから、MTタグを覚えるのはほぼ必須。
新しくテンプレートを覚えるコストが少ないと言うのは、それだけでアドバンテージが高いなぁ。
まずは、こっち入れてみようかな。


気になった点としては、(あたりまえだけど)全ての話がプログラマ視点になってしまったことかなぁ。
プログラマから見てのメリットはとてもわかりやすく、結果としてプロジェクト全体にメリットがあるんだろーなー、ってのは良くわかったんだけど、デザイナーへのメリットが見えてこない…。

特に、デザイナーにGitを使わせるのは実際のトコ難しいかも知れないと思うな。
正直、数行でもコマンドラインを使わなきゃならないというのは、デザイナーにはかなりハードル高い。
DWやCodaにはSubversionしかないから、まずはSubversionから覚えようの方が良かったかも。
ちなみに、オレもGitは使ってません。協業する人が使ってたら使うけど、オレからは使うことはないかも。だってやっぱ面倒だし。

ただ、懇親会があると、そういった話も出来るから良いね。こちらも楽しかった。

次回、@mon_satさんが、ディスカッションタイムを入れたいとつぶやいていたのですが、熱望しますよ。

ありがとうございました。


CakePHPでエクセルファイルの出力 [CakePHP]

超久しぶりにCakeの小ネタ。

DBのデータをCSVで出力することは多いと思うけど、どうせ社内で使うならエクセル形式の方が良いので.xlsで出力する。

つっても、中身は XMLスプレッドシート(2004)形式。
だから本当は拡張子は .xml なのだけど、それだとATOMや普通のXMLとごっちゃになるので、.xlsで書き出す。

メリットは、
・罫線とか最初から設定してあると嬉しい。
・utf-8で書き出せるから、文字コードのコンバートが要らない。
・1ファイルでもワークシートごとに書き出せる。
・.xls だとエクセルと紐づいてるので、素人にも説明が楽。

デメリットは、
・OOoは拡張子と実際のファイル形式が違うとダメなので、OOoのときは .xml にしないとだめ。

まずは、ルータに下記を追加
/app/config/routes.php
Router::parseExtensions('csv','xml','xls');

テンプレートは、例えばこんな感じ
/app/views/layouts/xls/default.ctp
<?='<?xml version="1.0"?>'?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:html="http://www.w3.org/TR/REC-html40"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
 <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  <Author>Sandman</Author>
  <LastAuthor>Sandman</LastAuthor>
  <Created><?=(date('Y-m-d').'T'.date('H:i:s'))?></Created>
 </DocumentProperties>
 <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  <AllowPNG/>
 </OfficeDocumentSettings>
 <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  <WindowHeight>21660</WindowHeight>
  <WindowWidth>22580</WindowWidth>
  <WindowTopX>6680</WindowTopX>
  <WindowTopY>-520</WindowTopY>
  <Date1904/>
  <AcceptLabelsInFormulas/>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
 </ExcelWorkbook>
 <Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="MS Pゴシック" x:CharSet="128" ss:Size="11.0"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
 </Styles>
<?php
        
echo $content_for_layout;
?>
</Workbook>



/app/views/users/xls/admin_index.ctp
 <Worksheet ss:Name="ユーザ一覧">
  <Table ss:DefaultColumnWidth="77.0" ss:DefaultRowHeight="17.0">
<?php
foreach ($users as $u){
    
$id $u['User']['id'];
    
$name $u['User']['name_0']." ".$u['Users']['name_1'];
    
$mail $u['User']['email'];
    
$created $u['User']['created'];
    
$city $cities[$u['User']['city']];
?>
   <Row>
    <Cell><Data ss:Type="String"><?=$id?></Data></Cell>
    <Cell><Data ss:Type="String"><?=$name?></Data></Cell>
    <Cell><Data ss:Type="String"><?=$mail?></Data></Cell>
    <Cell><Data ss:Type="String"><?=$city?></Data></Cell>
    <Cell><Data ss:Type="String"><?=$created?></Data></Cell>
   </Row>
<?php
};//foreach ($Users as $u)
?>
  </Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <PageSetup/>
   <Print>
    <ValidPrinterInfo/>
    <PaperSizeIndex>0</PaperSizeIndex>
    <HorizontalResolution>-4</HorizontalResolution>
    <VerticalResolution>-4</VerticalResolution>
   </Print>
   <PageLayoutZoom>100</PageLayoutZoom>
   <Selected/>
   <Panes>
    <Pane/>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>


ワークシートごとにしたい場合は、基本的には  <Worksheet> 〜  </Worksheet> を繰り返せば、複数のワークシートが出来る。

アクセスする時は、.xls をつければ良いわけだから、
http://xxx.com/admin/users/index.xls
ページネートしたのを出力したい時は、
http://xxx.com/admin/users/index/page:3.xls
みたいなURLになるが無問題。

これでオッケー!超簡単!と思ってたら、出力されない??エラーも出ない。。なぜ?
CSVやXMLはこの手順だけだったのに?

わかんなければ、ソースを見るのがCakePHPの基本
あった、あった。
request_handler.php でファイルの定義をしてたのね、知らなかった。
そんで、当然.xlsはない。

追加すべきなんだけど、どっかのブログで beforeFilter() でやらないとダメというのを見かけたので(未確認)beforeFilterに追記する。

function beforeFilter() { 
    
parent::beforeFilter(); 
<
中略
    if(isset(
$this->params['url']['ext']) && $this->params['url']['ext'] == 'xls'){ 
        
$this->RequestHandler->setContent('xls', array('application/vnd.ms-excel''text/plain')); 
    } 
}


これで問題無く、.xls でダウンロードできた。
よかったよかった。

CakePHP その22 〜 CakePHP カンファレンス 〜 [CakePHP]

CakePHP カンファレンスに行ってきた。

結論から言えば、すっごい良かった。
PHPと言うものにちょっとでも触ったことがある人は、必見なカンファレンスだった(大袈裟?)。

安藤氏の基調講演「国内でのCakePHPの利用状況について」
CakePHPの盛り上がりがよくわかる内容だった。
発表資料はブログでも公開しているので、お勧め。

岸田氏の「Agileな開発現場での実践例」
自分のレベルでは、まだテストというものがいまいち飲み込めてなかったのだけど、いろんな勉強会でテストについて聞いたので、少しずつわかりかけてきた気がする。
もうちょっとしたら、今日聞いたことが参考になってくるんだろう。

Cakeの開発者の一人であるGarrett & 堂園氏の「CakePHP and beyond 」
面白かった。CakePHPができた経緯や、開発にあたっての方針とか、聞けて良かった。
RC4が出るらしい。まあ、現在でもほとんど安定してるし、急ぎでstableが欲しい訳じゃないから別に良いけど。
んでやっぱし、英語必須を痛感。

halt氏の「XoopsCubeなのにCakePHPを使う!」
すげぇの一言。発想も実行力も素晴らしい。
Xoopsって、モジュールに統一感がなくて嫌いなんだけど、こういう形で開発してけば統一されてくるのかな?
まあ、もうXoopsは(特に指定がない限り)使わないと思うけど。

Lightning Talk
全部が全部、LTではもったいない内容!やっぱり、15分は欲しいなー。
次に期待。

あー、楽しかった。けど、あいかわらず用事のため懇親会には出られず。残念。
次こそは!


どーでもいいですが、帰りに水道橋から銀座まで大急ぎで行くために走ったんだけど、すごい近いでやんの。歩いても無問題だったー。
生まれも育ちも東京なのに、いまだに地理がわからん。

CakePHP その21 〜MobileHelper2 〜 [CakePHP]

まず、Prefixルーティングを使うとき、CakePHP1.2 RC2のHTMLヘルパーでは下記の現象が起きる。

まず、通常のリンクは下記のように書く。

$html
->link('リンクテキスト', array('controller' => 'names', 'action' => 'index', 'a' => 'A'));

そして、下記のようなHTMLが出力される。
<a href="/names/index/a:A">リンクテキスト</a>

しかし、これを下記のようにprefix付きで書くと…
php
$html
->link('リンクテキスト', array('controller' => 'names', 'action' => 'mobile_index', 'a' => 'A'));

  • 期待されるHTML
    <a href="/m/names/index/a:A">リンクテキスト</a></li>
  • 実際に出力されるHTML
    <a href="/names/mobile_index/a:A"> リンクテキスト</a></li>

これは困る。

もう一つ困ることと言えば、Paginator使うと、リンクURLにセッションIDが含まれなくなってしまう。

ので、それらを解決するために、結局MobileHelperを作成。
基本的には、Paginatorを継承させるけど、他の普通のリンクなど、携帯対応しなきゃ行けないのはついでに含ませてしまおう。


class MobileHelper extends PaginatorHelper {
    
    
//セッションIDをつけるPaginator用リンク
    
function link($title, $url = array(), $options = array()) {
        
$options = array_merge(array('model' => null, 'escape' => true), $options);
        
$model = $options['model'];
        unset(
$options['model']);

        if (!empty(
$this->options)) {
            
$options = array_merge($this->options, $options);
        }
        if (isset(
$options['url'])) {
            
$url = array_merge((array)$options['url'], (array)$url);
            unset(
$options['url']);
        }
        
$url = $this->url($url, true, $model);

        
$obj = isset($options['update']) ? 'Ajax' : 'Html';
        
        
$url = array_merge(array('page' => $this->current($model)), $url);
        
        
//ここから変更
        
if(Configure::read('mobile')){
            
$url['page'] .= '?'.session_name().'='.session_id();
        }
        
        return
$this->{$obj}->link($title, Set::filter($url, true), $options);
    }
    
//セッションIDをつける通常リンク
    
function htmlLink($title, $url = array(), $options = array()){
        
//ここから変更
        
if(Configure::read('mobile')){
            
$url = am($url, array('?'.session_name().'='.session_id()));
        }
        
$obj = isset($options['update']) ? 'Ajax' : 'Html';
        
        return
$this->{$obj}->link($title, Set::filter($url, true), $options);
    }
    
    function
image($path, $options = array()){
        
//ここから変更
        
if(Configure::read('mobile')){
            
$sid = '?'.session_name().'='.session_id();
        }
        
$obj = isset($options['update']) ? 'Ajax' : 'Html';
        return
$this->{$obj}->image($path.$sid, $options);
    }

}



いまんとこ、こんな感じで問題無くやってます。

あと、前回にMobileAppControllerに書いたredirectはやっぱ不便なんで、mobRedirectと言う名前に変更しました。AuthComponentではねた時にURLにセッションIDがついてたら変だから。気づかなかったのはまぬけ。

CakePHP その20 〜1.2RC2でPC&携帯対応サイトを考えた 〜 [CakePHP]

CakePHP1.2RC2を使って、PC&携帯サイトを作ってみた。
いろんなサイトを参考にしたので、感謝を込めて。珍しく長いです。

前提として、
・個人情報などは一切保有しない。
・携帯は3G以降のみ。
というゆるいサイト向けに使ったので、そのつもりでおねがいします。

追記:コメント欄のあゆ様のコメントも参考にして下さい。
追記2:おれ最前線ねっと様の「CakePHP1.2でprefixルーティング設定時の注意点。[携帯]」もご参考に

まず、認証は標準のAuthコンポーネントを使用する。
下記サイトをほぼまるパクり
ねねとまつの小部屋様「AuthComponentについてのまとめ」
http://blog.ne2ma2.com/archives/160

PC用のは上記で全部済むので、次に携帯(DOCOMO)でもAuthが使えるようにするには session.use_trans_sid を 1 にすればオッケー。
携帯で条件分岐しているところで、ini_set('session.use_trans_sid', 1); を追記。
…設定できない。
そう、くどいようだが、自分が使っているサーバはPHPが未だに4を使用しているので、.htaccess以上じゃなきゃ、session.use_trans_sid の変更ができない。
がびーん。

とおもってたが、下記サイトを参考に(ごっちゃに)して作成
CakePHPフォーラム「Docomoとセッション」
http://cakephp.jp/modules/newbb/viewtopic.php?post_id=1398&topic_id=751&forum=3

d.hetima様「CakePHP に use_trans_sid 風の処理を組み込む」
http://d.hatena.ne.jp/hetima/20070201/1170313526

ただ、上記だとPCへの振り分けが考慮されてないので、Contoroller で AppControllerを継承する時にベースとなるモデルを別々に作って、ワンクッションかまし継承することでできた。

できた!…と思う。

でもコレだと、携帯本体の◀ボタンで画面遷移した時に、セッションが切れてしまう。
そんな時は、携帯の端末IDで持ち回ればオッケー。
rakutoネット様「phpのセッション情報について」
http://study.rakuto.net/exec/bbs/browse/176/

携帯の端末IDについては下記がとても参考になる。
ke-tai.org様「ケータイの端末ID・ユーザIDの取得についてまとめてみました」
http://ke-tai.org/blog/2008/09/08/phoneid/

あれ?これでも◀ボタンで画面遷移するとセッション切れる?
そんな時は、core.php の Security.level を変更。midium でいけると思う。
Configure::write('Security.level', 'midium');

なんか、ただのリンク集になってしまったけど、一応こんな感じでできました。
まだ、実機でちゃんと検証してないけど!
でも、検証後だときっと面倒になって書かなくなっちゃうから、この時点で書いておく。
…ダメだったら追記していきます。変だったら教えてください。

コードは続きにあります


CakePHP その19 〜第35回PHP勉強会 〜 [CakePHP]

CakePHPだけの勉強会じゃなかったけど、Cakeがらみなので。
第35回PHP勉強会

内容はどれも興味深くて、全部、自分が今知りたい内容ばかりだった。
細かく書こうと思ったら、すでに「creazy photograph」様の方で丁寧に整理されて書いてあるので、そちらを読んだ方がいいです。
第35回PHP勉強会 参加レポート

とりあえず、思ったこと。
・他のフレームワークも勉強しなきゃダメだな。
・テストもちゃんとしましょう。
・自己紹介で「ウェブデザイナーやってます」といったら、なぜか「おお〜」と言われた。なぜ?
・yando氏のLTが聴けなくてとても残念。

勉強会の後、ロックな友人のライブ(SMショー付き)があったので、残念ながら懇親会は参加できなかったけど、大変意義深い時間を過ごせたことに感謝。

おまけ
・SMショーは初めて見たけど、まあ普通におもしろかった。
 内容より女王様の手際の良さに感心しきり。プロとはこうありたいもんだなと、内省。
・大トリで元Katzeの人が弾き語りをして、心の底から感動した。やっぱ歌は良いね。

CakePHPその18 〜Automagic JavaScript Validation Helper - Beta〜 [CakePHP]

CakePHP1.2のバリデーションは非常に強力だけど、当然、一度は送信しなければならない。
サーバー環境のせいもあるとおもうけど、通信時にいまいちもたつく感じがあって、その上で「エラーです」なんて出ると、ちょっとイラッとする。

だから、送信前に一度バリデーションをチェックして、漏れが無いようにJavascriptでやるのが親切だと思うけど、Javascript用にバリデーションルールを別に用意するのも、いまいちスマートじゃない。
Model->validationから、Javascriptを生成すればスマートなんじゃないかと思い、なんかないかと検索。

…あった!あったよ!
その名も Automagic JavaScript Validation Helper http://www.pseudocoder.com/archives/2008/02/17/automagic-javascript-validation-helper-beta/

コレは便利!
勿論ベータだけあって、かなりの部分を変更した。
  • まずは、json_encode関数を使っているので、PHP4では動かない! これは、下記サイトから、json_encode関数を参考にした。具体的にはbootstrap.phpに if (!function_exists('json_encode')){
        
    App::import('Vendor','json_encode', array('file' => 'json_encode.php'));;
    }
    として対応した。 詳しい説明などは下記から
    json_encode関数
    http://www123.ddo.jp/extwiki/?2.0%2Fjson_encode関数
  • これではJQueryを使ってるんだけど、導入するサイトはMochikitを使用しているので、JQuery依存の部分をMochikit用に変更。
  • その他、足りないバリデーションや、カスタムバリデーションに対応するように変更した。

なんで、ほぼ原型をとどめていないくらいになってしまった。

カスタマイズに苦労はするけど、本当に便利なので、今後のバージョンアップが楽しみ。

CakePHPその17 〜Qdmail Component〜 [CakePHP]

CakePHP1.2ではEmail Componentがあるけど、これが日本語環境では(今のところ)まず使えない!
使おうとすると、結構なカスタマイズをすることになるので、下記のコンポーネントがお勧めでっす。
http://hal456.net/qdmail/

なんてったって、PHP4に対応してんのが、本当にありがたい。
感謝

CakePHPその16 〜FormHelper〜 [CakePHP]

ついにCakePHP1.2 RC1がでた。
心の底から待ってましたよ。ほんとに。
ちなみに、いまだPHP4でやってるんで、マジ重いです。

で、フォームのセレクトタグの話。
やり方は、下記のサイト様の通り。
Sun Limited Mt. http://www.syuhari.jp/blog/archives/192

上記サイト様は最近、毎日見てる気がするよってくらい良い情報がたくさんあって嬉しい。
でも今回、CakePHP1.2 RC1を使ったら、微妙に直さなきゃいけないとこがあったので、そのあたり。

こんな感じで書いてみる
$form->dateTime('Model/field"', 'YMD', 'NONE', date('Y').'-'.(date('m')+1).'-'.date('d'), array('minYear' => date('Y'), 'maxYear' => date('Y')+5, 'separator' => ' / '), false )

上記の書いてある通りにすると、下記のようになる。


気になる…は二つある。
1.月名が英語名表記になってる。
2.年が上にのびてる

1.はさすが、メリケン人が作ったものって感じで、デフォがコレかよ!別にいいけど。
これは、optionのmonthNamesを偽にすれば、数字表記になる。
$form->dateTime('Model/field"', 'YMD', 'NONE', date('Y').'-'.(date('m')+1).'-'.date('d'), array('minYear' => date('Y'), 'maxYear' => date('Y')+5, 'separator' => ' / ', 'monthNames' => false), false )

2.これがとにかく気持ち悪い。
なんで、日は下に延びるのに、年は上にいくの!?やだやだ。
これは、どこが悪さしてんのかと思ったら、form.phpの1696行目
$data = array_reverse($data, true);
なんだコレ?わざわざ反転させてるのかー。なぜ?
理由が全くわからないし、気持ち悪いのでこの行をコメントアウト

コレでようやく、下記のようになりましたとさ。


あいかわらず、ソース読まなきゃやってらんない感じでした。
(もしかしたら、2は大きな勘違いをしてる可能性ありか?まあいいや)

#ちなみに、テスト用なんで手抜きしたのそのまま出してるので、date('Y')が頻発してますが、こういう書き方は無いですね。
#参考までにhttp://phpspot.org/blog/archives/2006/11/12php.html

FlaFra リニューアル。 [CakePHP]

勉強会で「なんか作りました?」ってよく聞かれたので、せっかく勉強したことだし、がんばってなんかを作ってみた。
ちょうど、昔挫折したサイトのドメインも余ってるので、再スタートってことで。
趣味でつくったので、高機能ではないけど、気合いだけは入ってます。遊びでも手抜きしない方が面白い。

FlaFra.com [http://flafra.com/]
Openvatarみたいなアバターのサービスを目指してたんだけど、途中でなにやら方向を見失った模様。
アバターというより、ブログシールみたいな感覚で使ってもらえれば。

つかったもの


ほんとは、ちょっと前から存在してたんだけど、自信なくてこっそりテストしてた。
でも、友人たちにはそこそこ評判が良かったので、今回思い切って。

ちょっとでも楽しんでもらえれば幸いです。
タグ:FLEX

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。