第2回CakePHP勉強会リポート

昨日行って参りました「第2回CakePHP勉強会」のリポートをします。
まずは以下CakePhp書籍の著者が行っている勉強会ということです。

CakePHPガイドブック
Fast CakePHP (LLフレームワークBOOKS # 4)

■イベント名
第2回CakePHP勉強会

■開催者および会場
トライコーン株式会社

■発表内容について
○「addons.mozilla.org@CakePHP」 (30分)

* 発表者
yando
* 概要
開発者への取材などを元にしたfirefoxのアドオンの登録・配布を行っている
addons.mozilla.orgでのCakePHPの採用事例の紹介。

* 発表資料

->このパートが一番テクニカルな情報が充実していました。
Queryの結果などを実ファイルとしてキャッシュデータ化するのではなく、メモ
リ上に展開しておく「memcache」は大変有用性が高い、とのことでしたので、今
後は実装時に考慮すべきか、と思いました。

○「ニフティトピックイット@CakePHP(仮題)」(30分)

* 発表者
ニフティ株式会社    寺本 和彦氏
イー・エージェンシー  北村 佳巳氏
* 概要
ニフティトピックイットのサービス紹介とCakePHPでの開発にまつわるエピソード
などについて。

->@niftyが主催しているソーシャルニュースサイト「ピックイット」の開発者の
発表です。小学生がネット上からニュースを拾って投稿している、といった驚きの事実がある
ようです。CakePhpの採用理由としては、やはりコード量が少ないといったことを挙げていま
した。

○ライトニングトーク @CakePHP
CakePHP 1.2 のEメールコンポーネントは使えるのか?(仮) (10分)
* 発表者
すずき
* 概要
CakePHP 1.2 で追加された「メール送信機能」の中身を見てみた

->CakePhpのメール送信機能に関してのリポートでした。
バグがあるらしくCakePhpの本家にリポートしたそうです。

○初心者がはまりやすいCakePHPのうっかりポイントまとめ(10分ぐらい?)
* 発表者
たぐち
* 概要
CakePHP歴1年未満の発表者が、失敗につぐ失敗を重ねた、その暗黒の歴史を振り返
ります。

->CakePhp初心者が陥り易いワナについて、2ちゃんFlashのような面白いリポートで
した。

○CakePHP+Oracle (5分?)
* 発表者
s-yo-ko
* 概要
Oracle接続方法と実際に使ってみた感想

->ライトニングトークなのでかなり時間が短かったのですが、CakePhpからOracleに
接続する場合のケーススタディのリポートです。
他言語の経験も豊富な女性の方でした。Do you CakePhpはてなの人です。

○あのオープンソースソフトウェアを CakePHP に移植する (5分)
* 発表者
ttsuruoka (id:p4life)
* 概要
巷で話題の OSS を CakePHP に移植。そこで得られた知見を紹介します。

->FastLadderというRubyで書かれたアプリケーションをCakePhpに移植している方の
発表でした。FastLadderってのはライブドアが提供するRSSリーダー”livedoor Reader”
の英語版です。まだ移植作業中のようでした。
google codeを使っているようです。

全体的に短いセクションで構成されています。
我々でも何か成果として発表する機会が持てれば、こういった技術交流の場に参加でき
ると思いました。

PHPexcel メモ

Reader の扱い方
まだ不明点が多数

$objReader = new PHPExcel_Reader_Excel2007;
// 追記 setReadDataOnlyに値を入れるとstyle関連を読まなくなるので
// データだけがほしいのであれば設定したほうがいい
$objReader->setReadDataOnly(true);
// エクセル2007ファイルロード
$objPHPExcel = $objReader->load(“test2.xlsx”);

// シート選択
$objPHPExcel->setActiveSheetIndex(5);
// シート名取得
$objPHPExcel->getActiveSheet()->getTitle()
// 指定セルの値取得
$objPHPExcel->getActiveSheet()->getCell(‘B2′)->getValue()

無いシートやファイルを選択しようとするとエラーで止まりました
シート数やセルの行数なども取れればいいんですが…引き続き検証続けます

あと、思った以上にメモリを喰うようです
160kぐらいのエクセルデータを読み込もうとしたら
メモリエラーで止まりました(PHP設定100M)
200Mにして読み込ませたら無事に動きました

setReadDataOnlyを設定したらかなり処理が軽くなりました
テンプレートデータを読み込むのでなければ必須かと思います

シートが日本語名だと読めはするけど書けないっぽい?

見積もり方法-Function Pointについて-

工学的に作業工数を見積もるFunction Pointという方法について

以前より興味のあった工数算出方法であるファンクションポイント法(以下FP法)というものを紹介します。

FunctionPoint.xls
※まずは上記ファイルを落としてみてください。VBAスクリプトが含まれています。いきなり開いても害はありません。

■ファンクションポイント法(function point method)とは?
ソフトウェアがもつ機能数や複雑さによって点数化を行い、そのソフトウェアにおける合計点数から開発工数を見積もる方法です。

○参考サイト

■算出手順
・データモデルよりエンティティ候補を抽出 ER図を作成
・プロセスの抽出(エンティティのライフサイクル) CRUD図を作成
・アプリケーションルールの定義(コンテキストダイアグラム) DFD図を作成
・データファンクションの算出
 ファイル(ユーザが認識しているシステムの構成要素でデータを保管する機能を持つもの)を元に算出
・トランザクショナルファンクションの算出
 上記プロセスの抽出を元に処理要素(ユーザにとって意味のある最少のアクティヴィティ)を算出

下記サイトを参考に算出するExcelファイルを作ってみましたのでご参考まで。
とても分かりやすくまとまっていると思います。
http://www.dab.hi-ho.ne.jp/sasa/hyoryuki/fp/fp.html

普段工数の算出は目検討になりがちですが、FP法はIBMなどに正式採用されている工数算出方法です。
勿論リンクの実状に合わせたアレンジは必要と思いますが、算出の根拠になるのではないかな、と思い
紹介しました。(ちと複雑なやり方ですが…)

私はこれとUMLがやりたくてね(w

CakePHP1.2 の saveAll (その2)

saveAllが使えるようになったものの、アソシエーションが下位のテーブルをメインモデルにしないとなぜか正常に動かない。
それに、複数モデルのアソシエーションがある場合にも、やっぱりうまく動かない。

ということで、model.php を改良。これでとりあえず動くことを確認。
以下、改良した saveAll のコードです。
今後、CakePHP本体側で修正してくれることを祈ります。ご参考まで。

    function saveAll($data = null, $options = array()) {
        if (empty($data)) {
            return false;
        }
        $db =& ConnectionManager::getDataSource($this->useDbConfig);

        $options = array_merge(
            array(‘validate’ => true, ‘fieldList’ => array(), ‘atomic’ => true),
            $options
        );

        if ($options[‘atomic’]) {
            $db->begin($this);
        }

        if (Set::numeric(array_keys($data))) {
            foreach ($data as $record) {
                if (!($this->create($record) && $this->save(null, $options[‘validate’], $options[‘fieldList’])) && $options[‘atomic’]) {
                    $db->rollback($this);
                    return false;
                }
            }
        } else {
            $associations = $this->getAssociated();

            foreach ($data as $association => $values) {
                if (isset($associations[$association]) && ($type = $associations[$association]) == ‘belongsTo’) {
                    $alias = $this->{$association}->alias;
                    $foreignKey = $this->{$type}[$association][‘foreignKey’];

                    if (!$result = $this->{$association}->save($values, $options[‘validate’], $options[‘fieldList’])) {
                        $db->rollback($this);
                        return false;
                    } elseif (!isset($data[$foreignKey]) || empty($data[$foreignKey])) {
                        $data[$this->alias][$foreignKey] = $this->{$association}->id;
                    }
                }
            }
// 改良ここから
            if (!$this->save($data[$this->alias], $options[‘validate’], $options[‘fieldList’])) {
                $db->rollback($this);
                return false;
            }

            foreach ($data as $association => $values) {
                if (isset($associations[$association])) {
                    $type = $associations[$association];
                    $foreignKey = $this->{$type}[$association][‘foreignKey’];
                    $values[$foreignKey] = $this->id;

                    switch ($type) {
                        case ‘hasOne':
                            if (!$result = $this->{$association}->save($values, $options[‘validate’], $options[‘fieldList’])) {
                                $db->rollback($this);
                                return false;
                            }
                        break;
                        case ‘hasMany':
                            $this->{$association}->saveAll($values);
                        break;
                    }
                }
            }
        }

        if ($options[‘atomic’]) {
            $db->commit($this);
        }
        return true;
    }
// 改良ここまで