June 26, 2012

FuelPHPのBitlyパッケージを作りました。


ソースは以下になります。
https://github.com/mp-php/fuel-packages-bitly

使い方はREADMEの通りになりますが、簡単に。


1.
app/config/config.phpあるいはPackage::loadで、Bitlyパッケージを有効にする。


2.
Bitlyパッケージのconfig/bitly.phpをapp/config/下にコピー。
loginとapikeyを設定。


loginとapikeyは、Bitlyアカウントを作成して、以下にアクセスすると手に入ります。
http://bitly.com/a/your_api_key


本体ソースはclasses/bitly.phpになります。
主に使用する機能は、URLの短縮と展開かなということで、
以下のメソッドを用意してあります。

* Bitly::expand ... bitlyの短縮URLを引数に取り、通常のURLを戻す。
* Bitly::shorten ... 通常のURLを引数に取り、bitlyの短縮URLを戻す。

上記以外のbitly APIを使用したい場合はBitly::apiを直接コールすれば可能です。

Oauth式の認証はしてないですし、エラーハンドリングとかもしてませんが
Bitlyなので、気楽なノリで作ってみました。


June 16, 2012

FuelPHPのDB::queryで結果をModelに入れて返す方法。

公式ドキュメントに、以下の様なサンプルソースが書いてあります。
http://docs.fuelphp.com/classes/database/usage.html
--
$result = DB::select()->from('users')->as_object('Model_Users')->execute();
--

このサンプルソースを参考に、DB::queryで同じ事を書いてみました。
結果がモデルに格納されて戻ってくるのかなーと思いきや、違いました。
以下のように、最後に->as_array()をつけると、ほぼ、期待通りの結果に。

尚、$queryは任意のSQL文です。

--
DB::query($query)->as_object('Model_Xxx')->execute()->as_array();
--

joinとかunionとか副問い合わせとか、発行したいクエリが複雑になるのであれば
自分で書いてDB::queryを通して、結果はModelでもらう。というのが好きだなー。
メソッドを細かく使って頑張っても、自分が発行したいクエリと
実際に発行されるクエリに差異があっては意味が無いので。
というのが私的な意見です。

その際、bindはちゃんとやりましょう。

oil generateとバリデーションエラーメッセージの件について報告。

少々遅れましたが。

以下の内容がマージされました。
https://github.com/fuel/oil/pull/129

まさか$val-error()がそのまま配列にキャストされてうまいことpタグに収まるとは。
盲点でした。
結果的に、解決したかった問題をミニマムな修正量でクリア出来たっぽい。。。

以下、以前書いた、上記に関連するエントリです。

--


FuelPHPのScaffoldと、バリデーションエラーメッセージのエスケープに関して。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffold.html

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。(応急処置。)
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldadmin.html

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。最善(?)策。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldadmin_08.html

FuelPHP 勉強会 東京 vol.1

FuelPHPの勉強会が東京でも行われるみたいです。
参加申込してみました。

--

FuelPHP 勉強会 東京 vol.1
http://atnd.org/event/fuelphp

2012/07/08(日) 13:00~17:00
東京都渋谷区神泉町8-16 渋谷ファーストプレイス8F


June 10, 2012

FuelPHPで既存テーブルからScaffoldするTaskをgithubに。

2013/01/14 追記

FuelPHP1.5で、当タスクをベースにしたfromdbタスクが公式に実装されました。
https://github.com/fuel/oil/commit/fcb51348c7d4c401895d4e10119fd795fdc57a94
FuelPHP1.5以降は、fromdbタスクをお使い下さい。

--

githubに、個人的なapp拡張用のレポを作りました。
https://github.com/mp-php/fuel-myapp

タイトルのTaskは
https://github.com/mp-php/fuel-myapp/blob/master/fuel/app/tasks/scafdb.php
https://github.com/mp-php/fuel-myapp/blob/master/tasks/scafdb.php
になります。

このレポには、その他、ちょっとした拡張クラスとかも置いていき、
それなりにゆるく管理しようと思っています。


現在のScafdbタスクの使い方は、以下の通りです。

尚、overwriteの警告が発生した場合、-fのオプションを付与して下さい。
-fは、強制的に上書きする、標準のオプションです。


php oil r scafdb:scaf $table
指定した既存テーブルに対してgenerate scaffoldします。
-admin あるいは -a のオプションを付与するとgenerate adminになります。


php oil r scafdb:scaf_all
全ての既存テーブルに対してgenerate scaffoldします。
-admin あるいは -a のオプションを付与するとgenerate adminになります。


php oil r scafdb:model $table
指定した既存テーブルに対してgenerate modelします。


php oil r scafdb:model_all
全ての既存テーブルに対してgenerate modelします。


最後に
php oil r scafdb
ですが、誤操作による実行も加味して、特に何も処理しないようにしています。
を実行すると、helpが表示されます。


June 8, 2012

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。最善(?)策。

2012/06/16 追記。

当問題、以下の内容で解決しました。

oil generateとバリデーションエラーメッセージの件について報告。
http://madroom-project.blogspot.jp/2012/06/oil-generate.html

--

ちょっと前に以下のエントリを書きましたが、より良いと思われる方法を思いつきました。

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。(応急処置。)
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldadmin.html

根本的に解決するには、例えば以下のような修正が必要と思われます。
diff --git a/fuel/core/classes/validation.php b/fuel/core/classes/validation.php
index a09c30e..80abcac 100644
--- a/fuel/core/classes/validation.php
+++ b/fuel/core/classes/validation.php
@@ -565,6 +565,37 @@ class Validation
     }
     /**
+     * Get errors
+     *
+     * Returns all errors in array
+     *
+     * @param   array  uses keys message_prefix
+     * @return  array
+     */
+     public function get_errors($options = array())
+     {
+          $default = array(
+               'message_prefix' => \Config::get('validation.message_prefix', '* '),
+          );
+          $options = array_merge($default, $options);
+
+          if (empty($this->errors))
+          {
+               return array();
+          }
+
+          $array = array();
+
+          foreach($this->errors as $e)
+          {
+               $array[] = $options['message_prefix'].$e->get_message();
+          }
+
+          return $array;
+     }
+
+     /**
     * Alias for $this->fieldset->add()
     *
     * @return  Fieldset_Field
diff --git a/fuel/packages/oil/views/admin/crud/actions/create.php b/fuel/packages/oil/views/admin/crud/actions/create.php
index a28517e..3172c4a 100644
--- a/fuel/packages/oil/views/admin/crud/actions/create.php
+++ b/fuel/packages/oil/views/admin/crud/actions/create.php
@@ -22,7 +22,7 @@
               }
               else
               {
-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
          }

diff --git a/fuel/packages/oil/views/admin/crud/actions/edit.php b/fuel/packages/oil/views/admin/crud/actions/edit.php
index 2d6bad7..3f5c33e 100644
--- a/fuel/packages/oil/views/admin/crud/actions/edit.php
+++ b/fuel/packages/oil/views/admin/crud/actions/edit.php
@@ -22,7 +22,7 @@
               }
               else
               {
-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
          }

diff --git a/fuel/packages/oil/views/admin/orm/actions/create.php b/fuel/packages/oil/views/admin/orm/actions/create.php
index c785673..b24faa0 100644
--- a/fuel/packages/oil/views/admin/orm/actions/create.php
+++ b/fuel/packages/oil/views/admin/orm/actions/create.php
@@ -24,7 +24,7 @@
               }
               else
               {
-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
          }

diff --git a/fuel/packages/oil/views/admin/orm/actions/edit.php b/fuel/packages/oil/views/admin/orm/actions/edit.php
index 8b5362b..7f8635f 100644
--- a/fuel/packages/oil/views/admin/orm/actions/edit.php
+++ b/fuel/packages/oil/views/admin/orm/actions/edit.php
@@ -28,7 +28,7 @@
                    $<?php echo $singular_name; ?>-><?php echo $field['name']; ?> = $val->validated('<?php echo $field['name']; ?>');
<?php endforeach; ?>

-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
              
               $this->template->set_global('<?php echo $singular_name; ?>', $<?php echo $singular_name; ?>, false);
diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/create.php b/fuel/packages/oil/views/scaffolding/crud/actions/create.php
index a28517e..3172c4a 100644
--- a/fuel/packages/oil/views/scaffolding/crud/actions/create.php
+++ b/fuel/packages/oil/views/scaffolding/crud/actions/create.php
@@ -22,7 +22,7 @@
               }
               else
               {
-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
          }

diff --git a/fuel/packages/oil/views/scaffolding/crud/actions/edit.php b/fuel/packages/oil/views/scaffolding/crud/actions/edit.php
index d73e196..7fd5c83 100644
--- a/fuel/packages/oil/views/scaffolding/crud/actions/edit.php
+++ b/fuel/packages/oil/views/scaffolding/crud/actions/edit.php
@@ -24,7 +24,7 @@
               }
               else
               {
-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
          }

diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/create.php b/fuel/packages/oil/views/scaffolding/orm/actions/create.php
index c785673..b24faa0 100644
--- a/fuel/packages/oil/views/scaffolding/orm/actions/create.php
+++ b/fuel/packages/oil/views/scaffolding/orm/actions/create.php
@@ -24,7 +24,7 @@
               }
               else
               {
-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }
          }

diff --git a/fuel/packages/oil/views/scaffolding/orm/actions/edit.php b/fuel/packages/oil/views/scaffolding/orm/actions/edit.php
index fb2ecb5..a52c292 100644
--- a/fuel/packages/oil/views/scaffolding/orm/actions/edit.php
+++ b/fuel/packages/oil/views/scaffolding/orm/actions/edit.php
@@ -31,7 +31,7 @@
                    $<?php echo $singular_name; ?>-><?php echo $field['name']; ?> = $val->validated('<?php echo $field['name']; ?>');
<?php endforeach; ?>

-                    Session::set_flash('error', $val->show_errors());
+                    Session::set_flash('error', $val->get_errors());
               }

               $this->template->set_global('<?php echo $singular_name; ?>', $<?php echo $singular_name; ?>, false);
diff --git a/fuel/packages/oil/views/scaffolding/template.php b/fuel/packages/oil/views/scaffolding/template.php
index 610f3be..f952932 100644
--- a/fuel/packages/oil/views/scaffolding/template.php
+++ b/fuel/packages/oil/views/scaffolding/template.php
@@ -17,14 +17,14 @@
<?php if (Session::get_flash('success')): ?>
                    <div class="alert-message success">
                         <p>
-                         <?php echo implode('</p><p>', (array) Session::get_flash('success')); ?>
+                         <?php echo implode('</p><p>', e((array) Session::get_flash('success'))); ?>
                         </p>
                    </div>
<?php endif; ?>
<?php if (Session::get_flash('error')): ?>
                    <div class="alert-message error">
                         <p>
-                         <?php echo implode('</p><p>', (array) Session::get_flash('error')); ?>
+                         <?php echo implode('</p><p>', e((array) Session::get_flash('error'))); ?>
                         </p>
                    </div>
<?php endif; ?>
* fuel/packages/oil/views/scaffolding/template.phpは、admin側と処理を同じにしておいた方が良いかな。程度です。必須では無いです。

ただし、上記はcoreの修正になるので、本家にpull requestしてマージしてもらわない限り、手出ししにくいのが本音です。
app側のみで対応するには、Validationクラスを同一名で継承、置換。上記のget_errors関数のみ書きます。
細かな方法は、以下を参考にして下さい。

FuelPHPのcoreクラスを拡張してみる。
http://madroom-project.blogspot.jp/2011/12/fuelphpcore.html

加えて、以下の修正が必要です。
scaffoldされたコントローラの
Session::set_flash('error', $val->show_errors());

Session::set_flash('error', $val->get_errors());
に変更。

June 6, 2012

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。(応急処置。)

2012/06/07 追記。
より良さそうな対策を思いついたので、以下に書きました。

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。最善(?)策。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldadmin_08.html

--

昨日の、以下のエントリについてです。

FuelPHPのScaffoldと、バリデーションエラーメッセージのエスケープに関して。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffold.html

まず、oil g scaffold ... の場合、この問題は発生しません。
(とはいっても、cssのスタイルが正しく適用されないはずです。)
oil g admin ... の場合に、この問題は発生します。

エラーメッセージがエスケープされずに、なおかつcssのスタイルを正しく適用させるために
とりあえず、以下の修正をしてみました。

* fuel/packages/oil/views/admin/template.php
ちなみに/fuel/packages/oil/views/scaffolding/template.phpはもともと以下の形で、
e()を通していません。
 <?php if (Session::get_flash('success')): ?>
                 <div class="alert-message success">
                     <p>
-                    <?php echo implode('</p><p>', e((array) Session::get_flash('success'))); ?>
+                    <?php echo implode('</p><p>', (array) Session::get_flash('success')); ?>
                     </p>
                 </div>
 <?php endif; ?>
 <?php if (Session::get_flash('error')): ?>
                 <div class="alert-message error">
                     <p>
-                    <?php echo implode('</p><p>', e((array) Session::get_flash('error'))); ?>
+                    <?php echo implode('</p><p>', (array) Session::get_flash('error')); ?>
                     </p>
                 </div>
 <?php endif; ?>


* fuel/core/classes/validation.php
     public function show_errors($options = array())
     {
         $default = array(
-            'open_list'    => \Config::get('validation.open_list', '<ul>'),
-            'close_list'   => \Config::get('validation.close_list', '</ul>'),
-            'open_error'   => \Config::get('validation.open_error', '<li>'),
-            'close_error'  => \Config::get('validation.close_error', '</li>'),
+            'open_list'    => \Config::get('validation.open_list', ''),
+            'close_list'   => \Config::get('validation.close_list', ''),
+            'open_error'   => \Config::get('validation.open_error', '* '),
+            'close_error'  => \Config::get('validation.close_error', '<br />'),
             'no_errors'    => \Config::get('validation.no_errors', '')
         );
         $options = array_merge($default, $options);
とりあえずこの形で、普通に表示されました。
後は、ベストな形の模索。。。
fuel/core/classes/validation.phpの方はコンフィグファイルで対応する方が良いのかな。
とりあえずミニマムと思われる内容で。

MAMPでunix:///var/mysql/mysql.sockが見つからない。

以下を参考にして解決しました。
http://www.mostafaberg.com/2011/08/fixing-the-unixvarmysqlmysql-sock-not-found-error-on-mamp/

具体的には、以下を実行。
--
sudo mkdir /var/mysql
sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock /var/mysql/mysql.sock
--

June 5, 2012

FuelPHPのScaffoldと、バリデーションエラーメッセージのエスケープに関して。

2012/06/06 追記
以下に、暫定的ですが、対応策を書きました。

FuelPHPのScaffold(admin)と、バリデーションエラーメッセージのエスケープ問題の対応策。(応急処置。)
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldadmin.html

--

以下の現象は、Ver1.2で確認しています。

oilで生成したフォームから入力してバリデーションエラーが発生すると、コントローラの
Session::set_flash('error', $val->show_errors());
に刺さりますが、同時に生成されるViewで
e((array) Session::get_flash('error')));
していて、eメソッド(fuel\core\base.phpに有ります。)でエスケープされてしまい、htmlとして出力されませんでした。

数日前にフォーラムで、同様の話に関するやり取りがされていたようです。
http://fuelphp.com/forums/topics/view/9416

フォーラムに記載されている通り
* View側を修正する
* Fuel\Core\Validationで使用される以下のコンフィグ値を調整する
'open_list'    => \Config::get('validation.open_list', '<ul>'),
'close_list'   => \Config::get('validation.close_list', '</ul>'),
'open_error'   => \Config::get('validation.open_error', '<li>'),
'close_error'  => \Config::get('validation.close_error', '</li>'),
のどちらかになりそうです。
ただ、後者だと結局preタグとかも使えないので、前者の方法が手っ取り早いかなと思いました。


FuelPHPで既存テーブルからScaffoldするTaskのadmin対応版。

当ソースの最新版はGithubにUPしてあります。
詳しくは、以下を御覧ください。

■FuelPHPで既存テーブルからScaffoldするTaskをgithubに。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldtaskgithub.html

--

昨日、以下の記事を書きました。

FuelPHPで既存テーブルからScaffoldするTask。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldtask.html

今回は、admin対応版です。
コマンドで表すと oil generate admin ... です。

変更点は、引数追加と、その引数によるcall_user_funcの分岐のみです。
php oil r scafdb $tablename
とすれば非adminで
php oil r scafdb $tablename 1
とすればadminでのscaffoldとなります。

app/tasks/scafdb.php
<?php
namespace Fuel\Tasks;

class Scafdb
{
    public static $ignore_fields = array(
        'id',
        'created_at',
        'updated_at',
    );

    /**
     * Scaffold by database table.
     *
     * Usage (from command line):
     *
     * php oil r scafdb $tablename
     */
    public static function run($tablename='', $is_admin=0)
    {
        if(!strlen($tablename))
        {
            exit('Usage : php oil r scafdb $tablename');
        }

        $args = self::mk_args(\DB::list_columns($tablename));
        array_unshift($args, $tablename);

        $subfolder = 'orm'; // TODO:
        call_user_func($is_admin ?
            'Oil\Generate_Admin::forge' : 'Oil\Generate_Scaffold::forge', $args, $subfolder);
    }

    private static function mk_args($cols)
    {
        $args = array();
        foreach ($cols as $col)
        {
            if(in_array($col['name'], self::$ignore_fields))
            {
                continue;
            }

            $constraint = ''; // TODO:
            $args[] = $col['name'] . ':' . $col['data_type'] . $constraint;
        }
        return $args;
    }

}

/* End of file tasks/scafdb.php */
尚、adminを表す引数は、1でなくても、PHP的に真と判定される文字(すなわち0以外)なら何でもadmin扱いとなります。

June 4, 2012

FuelPHPで既存テーブルからScaffoldするTask。


当ソースの最新版はGithubにUPしてあります。
詳しくは、以下を御覧ください。

■FuelPHPで既存テーブルからScaffoldするTaskをgithubに。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldtaskgithub.html

--


2012/06/05 追記
当記事に記載のTaskを改良した、admin対応版を、以下に書きました。

FuelPHPで既存テーブルからScaffoldするTaskのadmin対応版。
http://madroom-project.blogspot.jp/2012/06/fuelphpscaffoldtaskadmin.html

--

FuelPHPでのScaffoldは、以下のように、コマンド実行時にカラム名や型を指定します。
php oil g scaffold monkey name:string description:text
http://docs.fuelphp.com/packages/oil/generate.html#scaffolding

ただ、私の場合、DB設計にERMasterを使用している関係で、Scaffoldと相性が悪いなぁと。
http://ermaster.sourceforge.net/index_ja.html
(DDLやドキュメントをERMasterで生成してしまうので。)

そこで、以下のTaskを作成しました。

php oil r scafdb $tablename
の形式で、既存テーブル名を指定してScaffoldします。
改良点は多々あると思いますが、とりあえず。

app/tasks/scafdb.php
<?php
namespace Fuel\Tasks;

class Scafdb
{
    public static $ignore_fields = array(
        'id',
        'created_at',
        'updated_at',
    );

    /**
     * Scaffold by database table.
     *
     * Usage (from command line):
     *
     * php oil r scafdb $tablename
     */
    public static function run($tablename='')
    {
        if(!strlen($tablename))
        {
            exit('Usage : php oil r scafdb $tablename');
        }

        $args = self::mk_args(\DB::list_columns($tablename));
        array_unshift($args, $tablename);

        $subfolder = 'orm'; // TODO:
        call_user_func('Oil\Generate_Scaffold::forge', $args, $subfolder);
    }

    private static function mk_args($cols)
    {
        $args = array();
        foreach ($cols as $col)
        {
            if(in_array($col['name'], self::$ignore_fields))
            {
                continue;
            }

            $constraint = ''; // TODO:
            $args[] = $col['name'] . ':' . $col['data_type'] . $constraint;
        }
        return $args;
    }

}

/* End of file tasks/scafdb.php */

P.S.
--no-timestampオプションは効きました。
 php oil r scafdb $tablename --no-timestamp
その他は確認していません。。。

June 3, 2012

git pushがrejectされたので

以下を参考にさせて頂きました。
http://d.hatena.ne.jp/snaka72/20100602/1275496817

テンポラリ(以下、tmp)のブランチを作成。
tmpにorigin masterをpull。
tmpとローカルのmasterの差分を確認。
ローカルのmaster上でtmpをmerge、ローカルのmasterをorigin masterにpush。
tmpを削除。

一人用のレポジトリなので。良かった。。。