February 28, 2013

Chrome Extensionの雛形をGitHubに。

ちょっと思い立ったことがあり、Chrome Extensionを作ってみようかなと思っています。

右も左もわからないので、ドキュメントを参考にして、とりあえず雛形を作ってみました。
https://github.com/mp-php/chrome-extension-template

ドキュメント:
http://developer.chrome.com/extensions/docs.html

以下、頭の整理がてら、各ファイルの説明を書いておきます。

* manifest.json
そのExtensionの名前や説明などを書くファイルです。
各パラメータの詳細は http://developer.chrome.com/extensions/manifest.html

* _locales/xx/messages.json
国際化の為のファイルです。manifest.jsonの"default_locale"で指定した言語がdefaultになるのかなと。

* popup.html
manifest.jsonの"browser_action"の"default_popup"が指すhtmlです。アイコン左クリックで開きます。

* options.html
manifest.jsonの"options_page"が指すhtmlです。アイコン右クリックの"オプション"から開きます。

* js/options.js
options.htmlで読み込んでいます。入力値をLocal Storageに保存したり、逆に、取り出したりします。

* imgディレクトリは割愛します。

インストール方法は
(1) 上記一式をダウンロード
(2) ツール > 拡張機能 > パッケージ化されていない拡張機能を読み込む でインストール
です。

February 25, 2013

MacにPlay frameworkをインストールしてみた

公式:
http://www.playframework.com/

ドキュメント:
http://www.playframework.com/documentation/2.1.0/Home

以下、2.1.0をインストールした際のコマンドをメモしておきます。

1. ダウンロード
$ cd /usr/local/
$ sudo mkdir play
$ cd play/
$ sudo wget http://downloads.typesafe.com/play/2.1.0/play-2.1.0.zip
$ sudo unzip play-2.1.0.zip
$ sudo ln -s play-2.1.0 latest
2. パスを通す
$ vim ~/.bash_profile
~/.bash_profileに追記。
export PATH="/usr/local/play/latest:$PATH"
反映。
$ source ~/.bash_profile
3. Scala applicationの作成
$ mkdir -p ~/play/apps
$ cd ~/play/apps/
$ sudo play new scala_app
What is the application name? [scala_app]
> name_of_scala_app

Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 1
OK, application name_of_scala_app is created.

Have fun!

$ cd scala_app/
$ sudo play
[name_of_scala_app] $ run
http://localhost:9000/ にアクセスして確認。Ctrl+Dで終了。

4. Java applicationの作成
$ cd ~/play/apps/
$ sudo play new java_app
What is the application name? [java_app]
> name_of_java_app

Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 2
OK, application name_of_java_app is created.

Have fun!
$ cd java_app/
$ sudo play
[name_of_java_app] $ run
http://localhost:9000/ にアクセスして確認。Ctrl+Dで終了。

February 24, 2013

GitLab4.2でアカウントがあれば誰でもパブリックプロジェクトをブラウザから見れるようにする

GitLab4.1でパブリックモードが搭載されました。この機能は、誰でもcloneできるだけで、ブラウザ上で誰でもアクセスできるようになるわけではありません。

そんな時、以下の記事を見つけ、パッチをあてさせて頂きました。大変感謝です。(以下、説明上、この機能を"internal public mode"とします。)
Improved GitLab Public Mode
http://tech.kazeor.net/blog/2013/01/25/improved-gitlab-public-mode/
https://github.com/yaeda/gitlabhq/commit/b685931e21666b60f909044fac37fb1b2fbf4b84
* パブリックなプロジェクトには、アサインされていないアカウントでもReporter権限でブラウザからアクセスできるようになります。

先日、GitLab4.2がリリースされ、ダッシュボードのレイアウトが一部変更された関係で、internal public modeにも若干の修正が必要となったので、今回は自分でやってみました。
https://github.com/mp-php/gitlabhq/commit/38c05d3164b36814c67cf8138eba5978a35e574c


適用方法は

(1)
gitlabの4-2-stableブランチから適当な名前で新しくブランチを作成。

(2)
https://github.com/mp-php/gitlabhq/commit/38c05d3164b36814c67cf8138eba5978a35e574c.patch
を適当な場所にDL。

(3)
(1)で作成したブランチ上で
git apply [(2)でDLしたファイル名]
してコミットして退避。

(4)
GitLabを再起動。

が安全かつ簡単かと思います。自己判断で、好きにお使いいただければと思います。


P.S.
GitLab4.2で導入されたTeam機能を使えば似たようなことができそうですが、上記と比べると、少し面倒そうです。

February 22, 2013

データベース(MySQL)とドキュメントについて考えてみた

最近の、データベース(MySQL)とドキュメントの管理についてです。

■DDLとER図の作成
MySQL Workbenchを使っています。
ER図はpngで出力しています。

■ドキュメントの作成
fuel-dbdocsを使っています。(自作です。。。)
https://github.com/mp-php/fuel-dbdocs
http://madroom-project.blogspot.jp/2013/02/fuelphpmysqlpostgresqlsqlite.html
Jenkinsのビルド時に自動実行しています。自動実行するのは大げさな感じがしますが、見たい時に決まった場所に最新のドキュメントがある。のって大事かなと思います。JenkinsサーバのMySQLも適宜更新しないといけませんが、ユニットテストも実行していれば、そっちの関係で更新されているはずですし。
カラムにはコメントをつけるようにしていこうと思います。

■カラムの追加等
MySQL Workbenchファイルを更新します。
DDLとER図(png)も更新します。
稼働しているサーバで実行するALTER TABLE文は、MySQL Workbenchから出力できます。

MySQL Workbenchでalter tableを自動生成する
http://madroom-project.blogspot.jp/2013/01/mysql-workbenchalter-table.html



これで、MySQL Workbenchファイルで一元管理できるかなと。
Excelドキュメント(嫌いですが)が必要な場合は、後からEclipseのER Masterで生成できます。
http://ermaster.sourceforge.net/
Excelドキュメント(嫌いですが)のフォーマットもカスタマイズ可能です。

この方法で、ずっとネックだった、実際の状態とドキュメントの内容が「ズレる」ことを回避できそうです。

February 17, 2013

FuelPHP x Pjax のサンプル

2013/06/18 追記:
タイトルの変更は、以下のようにカスタムヘッダを用いた方が良さそうです。

jquery-pjax後にHTMLのタイトルを変更する
http://madroom-project.blogspot.jp/2013/05/pjaxhtml.html

また、監視するイベントはajaxCompleteではなくpjax:completeの方が妥当かもしれません。

jquery-pjaxでリダイレクト
http://madroom-project.blogspot.jp/2013/06/jquery-pjax.html


2013/03/23 追記:
v1.5.3用に、サンプルコードの一部を修正しました。

--

極力ミニマムな内容を意識して、メモしておきます。

確認したブラウザは
* Mac Chrome 24.0.1312.57
* Mac Firefox 18.0.2
* Mac Safari 6.0.2 (8536.26.17)
です。(Winはまだです。)

2013/02/19追記:
IE9(Win)は動かないです。普通の遷移になります。(10で対応??)
普通の遷移にも対応させておくことが重要です。

以下、ポイントです。
* 画面遷移時、URLを変えつつ非同期にコンテンツを取得すること。
* pjax時も非pjax時(直アクセス時)も、HTMLのタイトルが変わること。
* 非pjax時、該当ページのコンテンツが表示されること。

以下、手順です。

(1)
FuelPHP 1.5.2 をDL、展開

(2)
pjaxをDL、展開
https://github.com/defunkt/jquery-pjax
* public/assets/app/pjax/jquery.pjax.js の配置になります。

(3)
以下、各ファイルのサンプルです。正しい場所に正しいファイル名で作成して、そのままコピペで動くと思います。

classes/controller/index.php (Controller_Index クラス)
* pjax時も非pjax時も、とりあえずコレを呼びます。
* 各actionで、後述のController_Ajaxの対応するget_xxxを呼びます。
* pjax時はget_xxxの戻り値をそのまま返却、非pjax時はget_xxxの戻り値をtemplateに当てはめます。
<?php

class Controller_Index extends Controller_Template
{

    private static function is_pjax()
    {
        // TODO: 本来は Input クラスを拡張するのが好ましそう
        return Input::server('HTTP_X_PJAX') !== null;
    }

    public function before()
    {
        parent::before();

        $this->template->title = 'FuelPHP x Pjax';

        // 参考:
        // http://madroom-project.blogspot.jp/2012/09/fuelphpassetassets.html
        Asset::add_path('assets/app/', 'css');
        Asset::add_path('assets/app/', 'js');
        Asset::add_path('assets/app/', 'img');

        // Input::is_ajax() で true を返却させるため
        $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
    }

    /**
     * index ページ
     */
    public function action_index()
    {
        $response = Request::forge('ajax/index')->execute()->__toString();

        if (static::is_pjax())
        {
            // pjax でのアクセス時
            return $response;
        }
        else
        {
            // 直接なアクセス時
            $this->template->title .= ' - INDEX';
            $this->template->set('content', $response, false);
        }
    }

    /**
     * foo ページ
     */
    public function action_foo()
    {
        $response = Request::forge('ajax/foo')->execute()->__toString();

        if (static::is_pjax())
        {
            return $response;
        }
        else
        {
            $this->template->title .= ' - FOO';
            $this->template->set('content', $response, false);
        }
    }

    /**
     * bar ページ
     */
    public function action_bar()
    {
        $response = Request::forge('ajax/bar')->execute()->__toString();

        if (static::is_pjax())
        {
            return $response;
        }
        else
        {
            $this->template->title .= ' - BAR';
            $this->template->set('content', $response, false);
        }
    }

}
classes/controller/ajax.php (Controller_Ajax クラス)
* 各ページのコンテンツ取得メソッド(get_xxx)の他に、HTMLタイトル取得メソッド(get_title)を用意しています。
<?php

class Controller_Ajax extends Controller_Rest
{

    protected $_supported_formats = array(
        'html' => 'text/html',
    );

    public function before()
    {
        parent::before();

        ! Input::is_ajax() and die();
    }

    /**
     * タイトルを取得
     */
    public function get_title($page = null)
    {
        $page === null and die();

        $title = 'FuelPHP x Pjax';

        switch ($page)
        {
            case 'index':
                $title .= ' - INDEX';
                break;
            case 'foo':
                $title .= ' - FOO';
                break;
            case 'bar':
                $title .= ' - BAR';
                break;
            default:
                break;
        }

        $this->response($title);
    }

    /**
     * index ページのコンテンツを取得
     */
    public function get_index()
    {
        $this->response(View::forge('ajax/index'));
    }

    /**
     * foo ページのコンテンツを取得
     */
    public function get_foo()
    {
        $this->response(View::forge('ajax/foo'));
    }

    /**
     * bar ページのコンテンツを取得
     */
    public function get_bar()
    {
        $this->response(View::forge('ajax/bar'));
    }

}
views/template.php
* <a data-pjax ... のリンクをクリックすると"#pjax-container"の中身がpjaxで変化します。
* pjaxの確認用に、YouTube動画を埋め込んで有ります。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title><?php echo $title; ?></title>

<?php echo Asset::js('http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'); ?>
<?php echo Asset::js('pjax/jquery.pjax.js'); ?>
</head>

<script>
$(document).ready(function() {
    // pjaxの初期化
    $(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container');

    // タイトルの取得
    $(document).on('click', 'a[data-pjax]', function(event) {
        $("title").load("/ajax/title/" + $(this).attr("title"));
    });
});
</script>

<body>

<a data-pjax href="<?php echo Uri::create('index/index'); ?>" title="index">index</a>
<a data-pjax href="<?php echo Uri::create('index/foo'); ?>" title="foo">foo</a>
<a data-pjax href="<?php echo Uri::create('index/bar'); ?>" title="bar">bar</a>

<div id="pjax-container">
<?php echo $content; ?>
</div>

<iframe width="420" height="315" src="http://www.youtube.com/embed/MDBLhdSy5t4" frameborder="0" allowfullscreen></iframe>

</body>
</html>
views/ajax/index.php
<p>Page - index</p>
views/ajax/foo.php
<p>Page - foo</p>
views/ajax/bar.php
<p>Page - bar</p>
以下が確認出来れば、成功です。
* YouTube動画を再生しながら画面遷移をして、動画の再生が途切れないこと。
* 各ページのURLに直接アクセスしてコンテンツが正しく表示されること。
* HTMLのタイトルが正しく変わること。

個人サイトを作りなおしてみました。

http://madroom.net/
です。数年前に作って放置していて、どうしようかと思っていましたが、ざっと作りなおしてみました。ちょこっとブラックユーモア混じりの自己紹介サイト的な感じです。

大したことはしていませんが、依存している外部サイト(API等)とか技術的なキーワードは
* FuelPHP
* HTML5
* CSS3
* Pjax
* jQuery
* Twitter Bootstrap
* Google Web Fonts
* STRATUS 2 (SoundCloud)
* Font Awesome More
* Last.fm
* Webstagram
* Shadowbox.js
* GitHub
* Facebook
みたいな感じです。

CSSやJSは、普段は触る時間が少ない方なので、面白かったです。

今のところ、Macの
* Chrome
* Firefox
* Safari
でしか確認していないので、IEがコワいです。。。(こんな時代だし場合によりRejectしようか。)

jQueryで順番にフェードインするメモ

例えば画像ギャラリーの画像を順番に表示させるには
$("#xxx").each(function(index) {
    $(this).delay(index*100).fadeIn();
});
で出来ました。

Shadowbox.js + Ajaxの注意点

Ajaxで取ってきたタグにShadowboxを適用する場合、タグを取ってきてから
Shadowbox.setup();
を実行する必要がありました。

February 16, 2013

CSS3でimgを選択不可にする

珍しくCSSネタです。

以下で出来ました。
xxx {
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -webkit-user-drag: none;
    -khtml-user-drag: none;
}
以下、参考にさせて頂きました。(というかそのままです。)
http://html-memorandum.blogspot.jp/2012/02/blog-post.html

追記:
Macのfirefox 18.0.2 だと効きませんでした。

February 14, 2013

FuelPHPでSoundCloud APIを使ってお気に入りとプレイリスト(Sets)を同期するタスクを作ってみた

もはや自己満足の内容になります。。。
このタスクで何がしたかったかは、最後に書きます。

まず、事前準備として、access tokenをserializeして保存します。

http://madroom-project.blogspot.jp/2013/02/fuelphpsoundcloud.html
$access_token = $client->accessToken($code);
です。仮に、"app/tmp/soundcloud_access_token"として保存したとします。

このファイルを用いて、以下のようなタスクで同期できます。
* $client_id、$client_secret、[id or username]、[playlist_id]は実際の値に置換する必要があります。
<?php

namespace Fuel\Tasks;

class Soundcloud
{

    private static $client_id = 'xxxxxxxxxx';
    private static $client_secret = 'yyyyyyyyyy';

    public function __construct()
    {
        // https://github.com/mptre/php-soundcloud からDLしてvendorに配置
        require_once APPPATH.'vendor'.DS.'soundcloud'.DS.'Services'.DS.'Soundcloud.php';
    }

    public static function run()
    {
        //TODO:
        exit();
    }

    public static function sync()
    {
        $client = new \Services_Soundcloud(
            static::$client_id,
            static::$client_secret);

        // serializeしたaccess_tokenを配列に復元
        $access_token = unserialize(file_get_contents(APPPATH.'tmp'.DS.'soundcloud_access_token'));

        // access_tokenをリフレッシュしてserializeして保存
        $new_access_token = $client->accessTokenRefresh($access_token['refresh_token']);
        file_put_contents(APPPATH.'tmp'.DS.'soundcloud_access_token', serialize($new_access_token));

        // 指定したidあるいはusernameのお気に入りトラックを取得
        $url = 'http://api.soundcloud.com/users/[id or username]/favorites.json?client_id='.static::$client_id;
        $favorite_tracks = json_decode(file_get_contents($url), true);

        // ID一覧を作成
        $favorite_ids = \Arr::pluck($favorite_tracks, 'id');

        // プレイリストを更新(delete/insert式)
        $client->updatePlaylist([playlist_id], $favorite_ids);

        exit();
    }
}

/* End of file tasks/soundcloud.php */
お気に入りトラックのアカウントとプレイリストのアカウントは異なっていてOKです。プレイリストのアカウントは、soundcloud_access_tokenに対するアカウントである必要があります。

このタスクで何がしたかったかというと
* AndroidのSoundCloudアプリでお気に入りを登録。
* 定期的にプレイリストと同期。
* STRATUS 2 ( http://stratus.sc/ ) でプレイリストをサイトに表示。
という自動更新でした。

* 曲数が増えた時の挙動は未確認です。
* tokenのリフレッシュにより、ずっとほったらかしで動くかは未確認です。

以下で使っています。(表示されたりされなかったりで不安定ですが。。。)
http://madroom.net/
まだ作り始めですが、コンテンツはのんびりと適当に"遊びながら"詰めていこうと思います。

そのうちSTRATUS 2がお気に入りリストの埋め込みにも対応したら。。。
それはそれでハッピーですね。(2013/02/14現在、非対応っぽいです。)

P.S.
SoundCloudにしろLast.fmにしろ、APIは充実しているので、やろうと思えばいろいろ出来そうです。仕事で携わる可能性はかなり低そうですが。

SoundCloudで指定したユーザのお気に入りトラックリストを取得する

以下の形式で取得出来ました。
http://api.soundcloud.com/users/[id or username]/favorites.json?client_id=xxxxxxxxxx

client_idは、アプリ登録するともらえます。以下、参考です。
http://madroom-project.blogspot.jp/2013/02/fuelphpsoundcloud.html

以下、ドキュメントです。
http://developers.soundcloud.com/docs/api/reference#users

FuelPHPでSoundCloud認証をするサンプル

GitHubに続き、SoundCloudでの認証サンプルです。

先ほどのGitHubサンプルほどまとまってはいませんm(_ _)m
http://madroom-project.blogspot.jp/2013/02/fuelphpgithub.html

まず、SoundCloudのアプリは
http://soundcloud.com/you/apps/new
で登録できます。

アプリを登録すると、Client IDとClient Secretが手に入ります。

PHP用のSoundCloudライブラリは
https://github.com/mptre/php-soundcloud
を使いました。app/vendor/soundcloudとして配置しました。

以下、コントローラのサンプルです。$codeのチェックとか入っていませんが、要点はこんな感じなのかなと思います。
<?php

require_once APPPATH.'vendor'.DS.'soundcloud'.DS.'Services'.DS.'Soundcloud.php';

class Controller_Soundcloud extends Controller
{

    private static $client_id = 'xxxxxxxxxx';
    private static $client_secret = 'yyyyyyyyyy';

    public function action_signin()
    {
        $client = new Services_Soundcloud(
            static::$client_id,
            static::$client_secret,
            Uri::create('soundcloud/callback'));

        Response::redirect($client->getAuthorizeUrl());
    }

    public function action_callback()
    {
        $client = new Services_Soundcloud(
            static::$client_id,
            static::$client_secret,
            Uri::create('soundcloud/callback'));

        $code = Input::get('code', false);

        $access_token = $client->accessToken($code);
        $client->setAccessToken($access_token['access_token']);
        $me = $client->get('me');

        // 期限切れ対策のメモ
        $new_access_token = $client->accessTokenRefresh($access_token['refresh_token']);

        Debug::dump($access_token, json_decode($me), $new_access_token);

        exit();
    }
}
そのうち、もう少しまとめたいとは思います。。。

パッと見、ドキュメントにscopeの指定が見当たらないです。
http://developers.soundcloud.com/docs/api/guide

もしかして認証 = 全権限??

February 13, 2013

FuelPHPでGitHub認証をするサンプル

結構前に確認してほったらかしていたネタですが、ふと書く気になったので。。。

まず、GitHubのアプリは
https://github.com/settings/applications/new
で登録できます。

アプリを登録すると、Client IDとClient Secretが手に入ります。

PHP用のGitHubライブラリは
http://developer.github.com/v3/libraries/
に記載があるのですが、単に認証にだけ使いたい場合は、以下の方法で可能でした。

コントローラ(classes/controller/github.php)
<?php

class Controller_Github extends Controller
{

    private static $client_id = 'xxxxxxxxxx';
    private static $client_secret = 'yyyyyyyyyy';

    public function action_signin()
    {
        Github::authorize(static::$client_id);
    }

    public function action_callback()
    {
        $code = Input::get('code', false);

        if($code === false)
        {
            throw new Exception('Invalid code.');
        }

        $access_token = Github::get_access_token(static::$client_id, static::$client_secret, $code);

        $user = Github::get_user($access_token['access_token']);

        Debug::dump($user);
        exit();
    }

}
Githubクラス(classes/github.php)
<?php

class Github
{

    const AUTHORIZE_URL = 'https://github.com/login/oauth/authorize';
    const GET_ACCESS_TOKEN_URL = 'https://github.com/login/oauth/access_token';
    const GET_USER_URL = 'https://api.github.com/user';

    public static function authorize($client_id, $params = array())
    {
        $params = array_merge(array('client_id' => $client_id), $params);
        Response::redirect(static::AUTHORIZE_URL.'?'.http_build_query($params));
    }

    public static function get_access_token($client_id, $client_secret, $code, $params = array())
    {
        $params = array_merge(
            array(
                'client_id' => $client_id,
                'client_secret' => $client_secret,
                'code' => $code,
            ),
            $params
        );

        $context = stream_context_create(array('http' => array(
            'method' => 'POST',
            'header'  => 'Content-type: application/x-www-form-urlencoded',
            'content' => http_build_query($params),
        )));

        $access_token = file_get_contents(static::GET_ACCESS_TOKEN_URL, false, $context);
        parse_str($access_token, $access_token);

        return $access_token;
    }

    public static function get_user($access_token, $params = array())
    {
        $params = array_merge(array('access_token' => $access_token), $params);
        $json = file_get_contents(static::GET_USER_URL.'?'.http_build_query($params));
        return json_decode($json);
    }

}
Githubクラスの各メソッドの引数で
$params = array()
とありますが、これを調整すればscopeの指定も出来るのかなーと思います。(実際にはやってません。。。)

尚、Githubクラスは
https://github.com/mp-php/fuel-myapp/blob/master/classes/my/github.php
にも置いてあります。(名前が少し違いますが。)

開発者向けのサイトなら、Github認証オンリーも有りなのかなーと思っていたりします。

February 11, 2013

Macでファビコンを作るメモ

メモです。

1.
画像をプレビューアプリで開く

2.
ツール > サイズを調整... > 16x16等、適切なサイズにする

3.
ファイル > 書き出す... > "option"を押しながら"フォーマット"で"Microsoft アイコン"を選択 > "favicon.ico"等の名前で保存

--
参考:
Mac でものすごく簡単に favicon.ico を作る方法
http://www.msng.info/archives/2011/12/how-to-create-favicon-with-mac.php

February 10, 2013

FuelPHPでMySQL/PostgreSQL/SQLiteのドキュメントジェネレータを作ってみました。

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


以前、以下のパッケージを作りました。

FuelPHPでMySQLドキュメントを生成するパッケージを作ってみました。
http://madroom-project.blogspot.jp/2013/01/fuelphpmysql.html


MySQL以外も何とかならないものかという話がチラッとあり、Doctrine2を使って作りなおしてみました。
* テーブル情報
* インデックス情報
* ビュー情報
が生成できます。

現在、MySQL/PostgreSQL/SQLiteのみに対応しています。が、Doctrine2がOracleやSQL Serverにも対応しているので、ちょっと拡張すれば動く気はします。(検証可能な方がいらっしゃいましたら、GitHubでpull request頂ければ嬉しいです。。。)


READMEにも書いてありますが、以下、インストール方法です。

1. ソースコード一式を、DLするなりgit cloneするなりして展開します。

2. 外部ライブラリをインストールします。
$ cd fuel/packages/dbdocs
$ curl -s http://getcomposer.org/installer | php
$ php composer.phar install

ドキュメントの生成は、ブラウザとコマンドラインそれぞれに対応しています。


ブラウザからの実行は、public/index.phpにアクセスすれば、わかると思います。


コマンドラインからの実行ですが
$ php oil r dbdocs:help
でヘルプが表示されます。


ドキュメントの生成メソッドは、以下になります。(ヘルプより。)
php oil refine dbdocs:mysql  <directory>
php oil refine dbdocs:pgsql  <directory>
php oil refine dbdocs:sqlite <directory>
"directory"は生成されるドキュメントのディレクトリで、絶対パスになります。-fをつけると、既存ディレクトリを削除した後、再度生成します。

DB接続情報は対話式で入力します。また、-nオプションを付けることで非対話式の実行も可能です。CIサーバなどでの自動実行を想定した機能です。その際、DB接続情報は全てオプション式で、併せて入力します。

以下、ヘルプより。
MySQL and PostgreSQL:
  --host=<host>
  --dbname=<dbname>
  --user=<user>
  --password=<password>
  --charset=<charset>

SQLite:
  --path=<path>
  --charset=<charset>

カラムのコメントの加工や、カラム名からの外部キー判定の機能はpackages/dbdocs/config/dbdocs.phpに無名関数な設定値にしてあるので、本体側を修正すること無くカスタマイズできます。


最後に、補足ですが
* ドキュメントの生成機能は"dbdocs"パッケージとしてまとめてあります。
* デザイン周りはお決まりのTwitter Bootstrapです。
* Travis CIでPHP5.3/5.4/5.5 x MySQL/PostgreSQL/SQLiteの計9通りの環境でユニットテストを実行しています。
* ちょこっとAjax使っています。(FieldSetの切り替え。)
* ビュー情報の表示でsql-formatterを使っています。


Doctrine2のオブジェクトからHTMLを生成する際、ViewModelが役に立ったなー。

--

2012/02/11 補足。

大切なことを書き忘れていました。設定で、webfontの指定ができますw
1.0-alphaブランチは非対応(生成されるドキュメント側は対応済み)ですが、masterブランチで対応済みです。

--

関連:
PHPでSQLを整形するライブラリ"sql-formatter"
http://madroom-project.blogspot.jp/2013/02/phpsqlsql-formatter.html

Travis CIでComposer installする時にGitHubのAPI上限エラー
http://madroom-project.blogspot.jp/2013/02/travis-cicomposer-installgithubapi.html

ComposerでDoctrine 2のインストールメモ
http://madroom-project.blogspot.jp/2013/02/composerdoctrine-2.html

FuelPHPでMySQLドキュメントを生成するパッケージを作ってみました。
http://madroom-project.blogspot.jp/2013/01/fuelphpmysql.html

February 9, 2013

GitHubの特定のコミットからパッチファイルをDLして適用する

GitHubの特定のコミットからパッチファイルをDLするには、コミットのURLに".patch"を付けます。

例えば、GitLab4.1でfilesとcommitsが404になる問題を修正するコミットは
https://github.com/jfut/gitlabhq/commit/79b9249ff44c5ccbef44a8d9420a3fff369d932a
なので、パッチは
https://github.com/jfut/gitlabhq/commit/79b9249ff44c5ccbef44a8d9420a3fff369d932a.patch
になります。

これを何らかの方法で保存して
git apply [保存したファイル名]
で、適用できます。パッチが適用出来るかどうかは
git apply --check [保存したファイル名]
で確認できるみたいです。

参考:
5.3 Git での分散作業 - プロジェクトの運営
http://git-scm.com/book/ja/Git-%E3%81%A7%E3%81%AE%E5%88%86%E6%95%A3%E4%BD%9C%E6%A5%AD-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E9%81%8B%E5%96%B6

February 6, 2013

Windowsでtail -fみたいなこと

MacやLinuxだとログファイルをtail -fしながら開発できますが、Winだと不便です。

それっぽいツールを探してみると、SnakeTailが見つかり、かなり便利です。
http://code.google.com/p/snaketail-net/

PHPでSQLを整形するライブラリ"sql-formatter"

一行のSQLを見やすくしてくれるPHP用のライブラリを探したら
https://github.com/jdorn/sql-formatter
が有りました。

Packagistにも有るので、Composerでインストールが可能です。
https://packagist.org/packages/jdorn/sql-formatter

February 3, 2013

Travis CIでComposer installする時にGitHubのAPI上限エラー

2013/03/21 追記
https://travis-ci.org/profile/[username]/profile に表示される"Token"を、GitHub側のTravis CI(Service hook)設定の"Token"に入力すれば、以下は不要と思います。(たぶん。。。)

--

.travis.ymlのbefore_scriptで"php composer.phar install"した時に、GitHubのAPI上限エラーが発生してしまいました。GitHubのAPIは、token無しだと1時間辺り60回までとなっています。token有りだと1時間辺り5000回になります。

以下を参考にして、Travis CI上でtokenを用いたComposer installを試してみました。
http://blog.simplytestable.com/creating-and-using-a-github-oauth-token-with-travis-and-composer/
* セキュリティ的にどうなのか微妙な気はしますが、後述の通りscopesは空(public access)です。ダミーのアカウントで行うと安全かもしれません。


ローカルのコンソールで、以下のコマンドを実行します。("[username]"は置換してくだい。)
$ curl -u '[username]' -d '{"note":"Travis Composer"}' https://api.github.com/authorizations
成功するとコンソールにjsonが表示され、"token"の項目が有ります。尚、"scopes"は空です。この"token"を、以下の"xxx"に当てはめて、適当な名前で保存します。
{
    "config":{
        "github-oauth":{
            "github.com":"xxx"
        }
    }
}
.travis.ymlでComposer installする前に、上記のファイルを~/.composer/config.jsonとしてコピーします。実行すべきコマンドは
mkdir -p ~/.composer
cp [保存したファイル名] ~/.composer/config.json
です。これで、tokenを使用したComposer installが出来るようになりました。

February 2, 2013

ComposerでDoctrine 2のインストールメモ

メモです。

composer.jsonを用意します。
{
    "require": {
        "doctrine/orm": "2.*",
        "symfony/console": "2.*",
        "symfony/yaml": "2.*"
    },
    "autoload": {
        "psr-0": {"": "entities"}
    }
}
composer. pharをDLしてインストールします。
$ curl -s http://getcomposer.org/installer | php
$ php composer.phar install

vendor/autoload.phpをrequire_once等で読み込むと、使えるようになります。

参考:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html