CakePHP2の画像アップロードプラグイン「UploadPack」を試してみた

こんにちは! CakePHP2の画像プラグインを色々試しているので今回は「UploadPack」というのを試してみました。 いってみましょう!!

CakePHP2とUploadPackをインストール、有効化

インストールからしましょう。 Composerでインストールしたいのですが「UploadPack」はCompserに対応していないため、git submodule などでインストールするといいかもしれません。

composer.json

{
    "name": "uploadpack-example",
    "repositories": [
    {
        "type": "pear",
        "url": "http://pear.cakephp.org"
    }
    ],
    "require": {
        "pear-cakephp/cakephp": "2.4.*",
        "cakephp/debug_kit": "2.2.*"
    }
}

とりあえずCakePHPが動くように設定していきましょう。 以前まとめたのでこちらをご覧下さい。

CakePHP2をComposerでインストールしてプロジェクトを立ち上げるまで

プロジェクトが立ち上がったらgit submoduleでインストールしましょう。

$ git submodule add https://github.com/szajbus/uploadpack.git Plugin/UploadPack

最後にbootstrap.phpにプラグインを読み込むように書き込みましょう。

Config/bootstrap.php

CakePlugin::load('UploadPack');

これで有効化出来ました。

UploadPackの設定

実際にコードを書いていきます。

UploadPackでは_file_nameというものがついているフィールドに画像情報を保存するのでテーブル内に_file_nameがついたフィールドを用意しましょう。

CREATE table users (
    id int(10) unsigned NOT NULL auto_increment,
    login varchar(20) NOT NULL,
    avatar_file_name varchar(255)
);

Userモデルに対してコードを書いていきます。

Model/User.php

 [
            'avatar' => [
                'styles' => [
            'thumb' => '80x80'
        ]
            ]
        ]
    ];
}

アップロード処理をControllerに書いていきます。といってもデータを普通に保存するような形で構いません。

Controller/UsersController.php

request->is('post'){
            $this->User->create($this->request->data);
            if($this->User->save()){
                $this->Session->setFlash('image upload!');
            }
        }
    }
}

あとはViewです。「UploadPack」にはhelperがついているのでそこから呼び出しましょう。(Controllerでhelperを読み込んでます。6行目)

View/Users/index.ctp

Upload->uploadImage($user, 'User.avatar', array('style' => 'thumb')) ?>

これで動きますー! 80×80の画像が生成されたと思います。

最後に

データベースのフィールドに制約があるものの、ヘルパーもついていてとても簡単に画像アップロードが実装出来るのでおすすめのプラグインです。 composerに対応してくれるともっと嬉しいなーってプルリク送れってことですねすみません!

CakePHP2 実践入門 (WEB+DB PRESS plus)
安藤 祐介 岸田 健一郎 新原 雅司 市川 快 渡辺 一宏 鈴木 則夫
技術評論社
売り上げランキング: 30,585
Read more

みなさんこんにちは!

最近画像アップロードプラグインを色々試しているのでメモしておきますー

今日は「Upload」というプラグインで画像をアップしてみようと思います! それではいってみましょー!

このプラグインとしての特徴としては

  • 画像をアップロードする機構を提供するがヘルパーは提供しない(自作ヘルパーの必要性)
  • サムネイルが作れる(Imagickが必要)
  • PDFのアップロードも可能

くらいでしょうか。アップロード処理に必要なものは大体揃ってるイメージです。

CakePHPとUploadのインストール

ここらへんはComposerでちょちょっと!

composer.json

{
    "name": "upload-example",
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear.cakephp.org"
        }
    ],
    "require": {
        "pear-cakephp/cakephp": "2.4.*",
        "josegonzalez/cakephp-upload": "1.0.0"
    }
}

インストール!

$ composer install

オールグリーンにする設定はこちらを参照!

bootstrap.phpにUploadプラグインを書くコードを書いて終了!

bootstrap.php

CakePlugin::load('Upload');

これでインストール終了です!

Uploadプラグインの設定

それではコード書いていきましょう。

まずは

Usersテーブルを作成し、アップロードした画像パスを保存する領域も作っておきましょう。

CREATE table users (
    `id` int(10) unsigned NOT NULL auto_increment,
    `username` varchar(20) NOT NULL,
    `photo` varchar(255) DEFAULT NULL,
    `photo_dir` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
);

app/Model/User.php

 [
            'photo' => [
                'fields' => [
                    'dir' => 'photo_dir'
                ]
            ]
        ]
    ];
}

こうしておけばphoto_dirに勝手に画像へのパスが入ります。

Viewはこんな感じ

View/Posts/index.ctp

Form->create('User', array('type' => 'file')); ?>
    Form->input('User.username'); ?>
    Form->input('User.photo', array('type' => 'file')); ?>
    Form->input('User.photo_dir', array('type' => 'hidden')); ?>
Form->end('Submit'); ?>

PostsControllerも簡潔な感じ

request->is('post')){
            $this->User->save($this->request->data);
        }
    }

}

これで画像がwebroot/files以下にアップされます!

アップロードする場所を変えたりサムネイル作ったりしてみる

User.phpを少し変えます

 [
            'photo' => [
                'fields' => [
                    'dir' => 'photo_dir'
                ],
                'thumbnailSizes' => [
                    'thumb150' => '150x150',
                    'normal' => '200x200',
                    'big' => '500x500'
                ],
                'path' => '{ROOT}tmp{DS}files{DS}{model}{DS}{field}{DS}',
                'thumbnailMethod' => 'php'
            ]
        ]
    ];
}

画像をアップロードする場所をとりあえずtmpフォルダに変えました。なんとなく。 thumbnailSizesとして色々登録しておけばそのサイズに切り出してくれます。 thumbnailMethodでphpを指定していますが、imagickがない場合はこのオプションを指定しておくとimagickではなくphpでリサイズを行ってくれます。

これで先ほどのViewからアップロードしてみてください。 tmpフォルダにアップされたはずです。 あとアップロードされた画像の前にbigとかnormalとかついたはずです。こんな感じでリサイズされるってことですね!

最後に

いかがでしたでしょうか。 画像アップロードできましたか? アップロード処理は結構時間がかかる部分なのでこういう便利なプラグインを使ってサクッと終わらせたいですね!

定番レシピを勉強するならこれ!

Webアプリ開発を加速する CakePHP2定番レシピ119
長谷川 智希
秀和システム
売り上げランキング: 138,433
Read more

こんにちは!

そういえばComposerでCakePHPをインストールしたあと実際にアプリ開発を始めるまでの記事を書いていないことに気づいたので書きます!! Composer、最初いじったときどうしたらいいのかわからなかったのですが最近やっと慣れてきてもう手放せない子になりつつあるのでもしまだ使ってない!って方の手助けが出来ればいいなぁなんて思ってます!

それではやっていきましょう!!

Composerをダウンロード

それではいきます!

Composerとは(簡単に)

composerはライブラリの依存関係を解決してくれるツールです。 例えばあるプロジェクトではAというプラグイン、Bというプラグイン、Cというプラグインが入っていないと動かない!みたいなことがあったとします。 そのときドキュメントを作って1個ずつダウンロードしてインストールして・・・ってやってると、正直やってられないですよね。 あとプラグインも日々バージョンアップが行われている可能性があるので、どのバージョンのプラグインか、というのも考慮しておかなければいけません。 そういう面倒なことを吸収してくれるのがcomposerなのですね!便利!超カンタンに説明した気がする!

composerの公式ページはこちら

composerはダウンロードして動かします。 インストールすることも可能なのでやってみたい人はぐぐってやってみてください!

プロジェクトを作りたいフォルダ内で

$ curl -sS https://getcomposer.org/installer | php

これでcomposer.pharというファイルがダウンロード出来ました。これがcomposerの本体になります。

composer.jsonを書いてインストール!

composer.jsonに依存関係を記述していきます。

以下のように書くとcakephpをインストールすることが出来ます。pearレポジトリにcakephpが入っているのでそこを参照するようにします。

{
    "name": "cakephp_test",
    "repositories": [
    {
        "type": "pear",
        "url": "http://pear.cakephp.org"
    }
    ],
    "require": {
        "pear-cakephp/cakephp": "2.4.*",
        "cakephp/debug_kit": "2.2.*"
    }
}

あとでCakePHPの初期画面をオールグリーンにするため、プラグインの入れ方を書くためにDebugKitも入れておきます。 composerへの書き方はそれぞれのrepositoryのREADMEなどに書いてあることが多いので調べてみましょう。

ここまで書けたらインストールしましょう。 以下のコマンドでインストール出来ます!

$ php composer.phar install

うまくいけばカレントディレクトリにvendorフォルダとPluginフォルダ、あとそれぞれのライブラリのバージョン情報が格納されているcomposer.lockが出来たはずです。 vendorフォルダ内にはCakePHP本体が、PluginフォルダにはDebugKitが入っているはずです。 これでインストール完了です!!

CakePHP2でプロジェクト作成して開発の準備をする

ここまで出来たら開発が出来るまでもう少しです!

次はCakePHPのbakeコマンドを使ってプロジェクトを作成します。

$ vendor/bin/cake bake project $PWD

Welcome to CakePHP v2.4.4 Console
---------------------------------------------------------------
App : composer
Path: ちょめちょめ
---------------------------------------------------------------
Skel Directory: ちょめちょめ
Will be copied to: ちょめちょめ
---------------------------------------------------------------
Look okay? (y/n/q)
[y] > y

これでプロジェクトが作成されました。見慣れたCakePHPのディレクトリ構造が出来ていると思います。

ターミナルに表示されているように include_pathを直さなければならないのでなおしていきましょう。 またcakeコマンドもどんな環境でも動くように設定しておきます。

webroot/index.php

define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . APP_DIR . DS . 'vendor' . DS . 'pear-pear.cakephp.org' . DS . 'CakePHP');

webroot/test.php

define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . APP_DIR . DS . 'vendor' . DS . 'pear-pear.cakephp.org' . DS . 'CakePHP');

Console/cake.php

$ds = DIRECTORY_SEPARATOR;
$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';

if (function_exists('ini_set')) {
    $root = dirname(dirname(__FILE__));

    // the following line differs from its sibling
    // /app/Console/cake.php
    ini_set('include_path', $root . $ds . 'vendor' . $ds . 'pear-pear.cakephp.org' . $ds . 'CakePHP' . PATH_SEPARATOR . ini_get('include_path'));
}

if (!include $dispatcher) {
    trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
}
unset($paths, $path, $dispatcher, $root, $ds);

return ShellDispatcher::run($argv);

最後にデータベースの情報をbakeして終了!

$ Console/cake bake db_config

ここまでで以下のような画面になっているはずです。

DebugKitを読み込む

それでは最後にDebugKitを読み込んでみましょう。

といってももう既にインストールされてるしPluginフォルダ内にあるのでプラグインを読み込むにはbootstrap.phpに書き込むだけで終わりです。

bootstrap.php に追記

CakePlugin::load('DebugKit');

これでオールグリーン!!

最後に

これでComposerを使ったCakePHP開発出来るはずです。 僕も最初は手探りで、本当に便利か?と思っていたのですが慣れてしまえばもうこれ無しでは考えられないです。 webroot/index.phpとかをいじるのが面倒なのですが、CakePHP3からこの作業もなくなるのでより便利になります。 誰かの役に立てればいいなぁ。

手元にあると便利です

CakePHP2 実践入門 (WEB+DB PRESS plus)
安藤 祐介 岸田 健一郎 新原 雅司 市川 快 渡辺 一宏 鈴木 則夫
技術評論社
売り上げランキング: 43,078
Read more

jQuery fancybox、とても便利ですよね。 気軽にモーダルウインドウが実装出来るのでよく使ってるjQueryプラグインの1つです。

今回そのfancyboxを使っていて、原因は不明なのですがなぜか発火しなかったときの対処法を書いておきます。 ただ原因不明なので詳しい方、ぜひとも教えていただけると助かります。

普通fancyboxは.fancybox()で起動しますが、今回はなぜか起動しませんでした。

なので以下のような方法で無理やりfancyboxを立ち上げました。

$(document).ready(function () {
        $.fancybox({
            'width': '40%',
            'height': '40%',
        });
});

fancyboxは$のあとの関数としても登録されているため上記のようなことが出来ると思います。 参考になると幸いです。

参考サイト

jQuery, fancybox working but only when you click this image twice How to launch jQuery Fancybox on page load?

Read more

RubyのGoogleDrive Gemを使ってGoogleDriveをさわろうとしたところ、OAuthの認証でつまづいたのでそのメモします。

OAuth2.0の流れはこんな感じです。

  1. ClientIDとClientSecretを発行する
  2. 認証する
  3. アクセストークンを取得する
  4. リフレッシュトークンからアクセストークンを再取得する
  5. GoogleDrive gemを使ってみる

ClientIDとClientSecretを発行する

まずはプロジェクトを作成します。 https://cloud.google.com/console/project

APIsから「Drive API」と「Drive SDK」をONにします。

「Credentials」から「CREATE NEW CLIENT ID」から今回のプログラムで使う必要項目を取得します。

以上のような項目を選択

これでClientIDとClientSecretが作成されました。

認証する

ユーザーがAPIアクセスの許可を行い、Authorization codeを取得します。 これにはhttps://accounts.google.com/o/oauth2/authに以下のパラメータを付与したものにブラウザからアクセスします。

  • client_id:さきほど発行したClientID
  • redirect_uri:さきほど発行したRedirectURIs
  • scope:今回はGoogleDriveを使いたいので https://www.googleapis.com/auth/drive
  • response_type:”code”

よって以下のようなURLになります。

https://accounts.google.com/o/oauth2/auth
?client_id=8972549879287.apps.googleusercontent.com
&redirect_uri=http://localhost
&scope=https://www.googleapis.com/auth/drive
&response_type=code

このURLにアクセスすると認証画面になるので承認してください。 redirect_uriに設定したURLにcodeパラメータがついています。それがAuthorization codeになります。

アクセストークンを取得する

Authorization codeからアクセストークンを取得します。 https://accounts.google.com/o/oauth2/token にPOSTで以下のパラメータを送る必要があります。

  • client_id:最初に発行したClientID
  • client_secret:最初に発行したClientSecret
  • redirect_uri:最初に発行したRedirect URIs
  • grant_type: “authorization_code”
  • code: Authorization codeの値

POSTとして送るためcurlを使います。全体として以下のようなものになります。

$ curl -d client_id=[YOUR CLIENT ID] -d client_secret=[YOUR CLIENT SECRET] -d redirect_uri=[YOUR REDIRECT URI] -d grant_type=authorization_code -d code=[YOUR AUTHORIZATION CODE] https://accounts.google.com/o/oauth2/token

結果として以下のようなJSONが返ってきます。

{
    "access_token":"アクセストークン",
    "token_type":"Bearer",
    "expires_in":3600,
    "refresh_token":"リフレッシュトークン"
}

アクセストークンがAPIを使用するための鍵になります。

リフレッシュトークンからアクセストークンを再取得する

アクセストークンには有効期限(expires_in)があるため、有効期限が切れた場合、リフレッシュトークンからアクセストークンを再取得する必要があります。

https://accounts.google.com/o/oauth2/tokenにPOSTで以下のパラメータを送ればアクセストークンを再取得出来ます。

  • client_id:最初に発行したClientID
  • client_secret:最初に発行したClientSecret
  • refresh_token:リフレッシュトークン
  • grant_type:”refresh_token”

全体として以下のようなものになります。

$ curl -d client_id=[YOUR CLIENT ID] -d client_secret=[YOUR CLIENT SECRET] -d refresh_token=[YOUR REFRESH TOKEN] -d grant_type=refresh_token https://accounts.google.com/o/oauth2/token

これでアクセストークンを取得したときと同じJSONが返ってきます。その中のaccess_tokenの値が新しいアクセストークンになります。

GoogleDrive gemを使ってみる

それではアクセストークン、リフレッシュトークンをゲットすることが出来たので最後にgemを使ってみましょう。 詳しいAPI仕様は公式ドキュメントを見てください。

CLIENT_ID = "9874987-ljk4j45n5dhh485014849.apps.googleusercontent.com"
CLIENT_SECRET = "98FZqeIdnz8495"
REFRESH_TOKEN = "5/Qzjrnxhtn;lUidZ"

client = OAuth2::Client.new(
    CLIENT_ID, CLIENT_SECRET,
    :site => "https://accounts.google.com",
    :token_url => "/o/oauth2/token",
    :authorize_url => "/o/oauth2/auth")

# refresh_tokenでログイン
auth_token = OAuth2::AccessToken.from_hash(client,{:refresh_token => REFRESH_TOKEN, :expires_at => 3600})
auth_token = auth_token.refresh!

# ログイン完了!
session = GoogleDrive.login_with_oauth(auth_token.token)

以上でログインが終わりました。

最後に

これでGoogleAPIを自由に使うことが出来ました。 ただ、GoogleDriveにはOAuth2.0認証を簡単に行うためのコードが実はあるのです!(最初からそれ使えよ) 1回手動で大きな流れを理解したあとであれば以下のコードも理解出来ると思います。

client = OAuth2::Client.new(
    your_client_id, your_client_secret,
    :site => "https://accounts.google.com",
    :token_url => "/o/oauth2/token",
    :authorize_url => "/o/oauth2/auth")
auth_url = client.auth_code.authorize_url(
    :redirect_uri => "http://example.com/",
    :scope =>
        "https://docs.google.com/feeds/ " +
        "https://docs.googleusercontent.com/ " +
        "https://spreadsheets.google.com/feeds/")

# 表示されるURLをブラウザで開く
print auth_url

print "authorization code:"
authorization_code = gets.chomp

auth_token = client.auth_code.get_token(
    authorization_code, :redirect_uri => "http://example.com/")
session = GoogleDrive.login_with_oauth(auth_token.token)

また、scopeで注意しなければならないこととしては、

  • scopeを複数連ねる場合はURLの最後に半角スペースを挿入しなければならない

ということです。上記のRubyのコードでもよくみるとscopeのURLの最後に半角スペースが入っているのがわかると思います。 僕はここが理解出来ていなくて1時間くらい無駄にしました(´・ω・`)

ということでこれでもう忘れても大丈夫!お役に立てれば幸いです。

ある程度Rubyが出来るようになったらこれ。頑張ります。

メタプログラミングRuby
Paolo Perrotta
アスキー・メディアワークス
売り上げランキング: 19,124
Read more

こんにちは!

Rubyのgemであるcapybara-webkitをインストールしてスクリーンショットを自動で撮って来てもらおうと思ったのですが、 MacのほうでもCentOSのほうでもqmakeコマンドがないよって怒られてしまったのでまとめて調べてみました。

以下のページに全て書いてありました。 Installing Qt and compiling capybara webkit

OS X Mavericks 10.9とMountain Lion 10.8の場合

OS X Mavericks 10.9とMountain Lion 10.8の場合はHomebrewであればとても簡単です

$ brew update
$ brew install qt4

もし他のMacOSの場合は参考ページに書いてあるのでそちらをご確認ください。

Installing Qt and compiling capybara webkit

CentOS 6.4の場合

少し手間ですが、少しだけいじればインストール出来ます。

まずは /etc/yum.repos.d/以下に qt.repoのような拡張子が repoになるようなファイルであればなんでもよいです。

[epel-qt48]
name=Software Collection for Qt 4.8
baseurl=http://repos.fedorapeople.org/repos/sic/qt48/epel-$releasever/$basearch/
enabled=1
skip_if_unavailable=1
gpgcheck=0

[epel-qt48-source]
name=Software Collection for Qt 4.8 - Source
baseurl=http://repos.fedorapeople.org/repos/sic/qt48/epel-$releasever/SRPMS
enabled=0
skip_if_unavailable=1
gpgcheck=0

次にyumでインストールします。

$ yum -y install qt48-qt-webkit-devel

最後にエイリアス貼る、コマンドを有効にする、パスを通すで終了です!

$ sudo ln -s /opt/rh/qt48/root/usr/include/QtCore/qconfig-64.h  /opt/rh/qt48/root/usr/include/QtCore/qconfig-x86_64.h
$ source /opt/rh/qt48/enable
$ export PATH=/opt/rh/qt48/root/usr/lib64/qt4/bin/${PATH:+:${PATH}}

これでqmakeコマンドが有効になりました。

最後に

qmakeコマンドの情報がいまいちなかったので苦労しましたが、githubに全てまとまっていましたね。 さっと終わらせてcapybara-webkitを早く触りましょう。

入門bash 第3版
入門bash 第3版
posted with amazlet at 14.01.08
Cameron Newham Bill Rosenblatt
オライリージャパン
売り上げランキング: 329,285
Read more

みなさんこんにちは!

ついにCakePHP3のdev preview 1が出ましたね! CakePHP 3.0.0 dev preview 1 released

テンション上がったので少しですが試してみようと思います。 CakePHP自体の開発スピードが最近上がってきたと感じるのでわくわくしてます。 それでは一緒にいじっていきましょう!

CakePHP3をインストールする

CakePHP3からComposerが必須になったのでComposerからインストールします。

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar create-project -s dev cakephp/app .

これでインストール完了です!簡単!ひゃっほーい!

CakePHP2からはdatabase.phpがなくなり、app.phpに統合されたのでapp.phpからデータベースの設定を行いましょう。 これでとりあえずインストール完了です。 おそらくCakePHP3の安定版ではデータベース設定もbake出来るとは思うのですが今のところbakeが動かないようなので手動で設定しました。

これでいつもの緑画面が出てきたと思います。(DebugKitは気分的に入れてみました。オールグリーン、気持ちいいので)

データベースには以下のテーブルとデータを挿入しました。

CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ;

INSERT INTO `posts` (`id`, `title`, `content`, `created`, `modified`) VALUES
(1, 'test1', 'test1の内容です', NOW(), NOW()),
(2, 'test2', 'test2の内容です', NOW(), NOW()),
(3, 'test3', 'test3の内容です', NOW(), NOW());

次で実際に触ってみます。

コードを書いてみる

今回やることはさきほど入れたデータを表示したりCakePHP3から実装されたEntityやRepositoryを使って遅延評価を行ったりしてみたいなぁと思います。

それでは早速書いていきましょう。

まずはPostsController.phpから書いていきます。

PostsController.php

set('posts', TableRegistry::get('Posts')->find('all'));
    }
}

namespaceとかuse使ってる部分がモダンw 見ればわかるとは思いますが、Postsテーブルのインスタンスを作り、全件取得しています。 それをViewにpostsという変数名でオブジェクトを流し込んでいます。 namespaceにはそのファイルの場所名を書きます。今回のControllerであればApp/Controller以下にあるので上記のようになっています。

それではModelを書いていきましょう。 僕もまだEntityやRepositoryは厳密にどのようなものか理解出来ていないのですが、Entityにはモデルのロジックを、Repositoryにはデータベースのリレーションやバリデーションを書いていくようです。(あんまわかってない。誰か教えて!)

まずRepositoryのほうから作ります。

App/Model/Repository/PostsTable.php

<?php namespace App\Model\Repository;

use Cake\ORM\Table;

class PostsTable extends Table {

}

今回はリレーションやバリデーションはかけないので何も書きません。 次にEntity

App/Model/Entity/Post.php

<?php namespace App\Model\Entity;

use Cake\ORM\Entity;

class Post extends Entity {

}

Entityのほうには後から関数を定義してみようと思います。

そして最後にView これでとりあえず動くはずです。

App/View/Posts/index.ctp


    id;?>

これで以下の画像のように数字が出てくるはずです。

foreach$postsをイテレートしてidを表示してみました。もちろんidの部分をtitlecontentに変えればそれを表示することが出来ます。

Viewに渡されたオブジェクトからEntityモデルを叩く

今回はViewに$postsという変数名でオブジェクトを渡しましたが、ここからPostEntityを叩くことが出来ます。

App/Model/Entity/Post.phpにメソッドを追加します。

App/Model/Entity/Post.php

public function getFullContent(){
    return $this->_properties['title'] . ":" . $this->_properties['content'];
}

そしてViewも変えます。

App/View/Posts/index.ctp


    full_content . "
";?>

これで以下のような表示が出来ます。

Entityのほうでgetから始めた関数はViewのオブジェクト側でgetを除いたアンダースコア記法で呼び出せるのです! これ超ベンリ!感動しちゃいました。Railsの感覚に近い。。

最後に

僕も対してわかっていないのでとりあえず動かしてみてこういうことが出来る、こういうことが出来なくなった、というのを1つずつ確認している段階です。 また開発バージョンなのでこれから変更がかかる可能性があります。 開発が終わるのがいつになるかわかりませんが、少しずつでも追っかけていると移行が早く出来て便利かもしれませんね!

CakePHPをこれから始めたい人は持っておくといいかも

Webアプリ開発を加速する CakePHP2定番レシピ119
長谷川 智希
秀和システム
売り上げランキング: 65,741
Read more

みなさんこんにちは!

今日ついにCakePHP3のdev preview 1が出ましたね! CakePHP 3.0.0 dev preview 1 released

ということで早速インストール・・・しようと思ったのですが色々つまづいたのでメモ

PHPのバージョンにあわせてmcryptを入れる

なにはともあれhomebrewでlibmcryptをインストールしましょう。 以下のコマンドを実行

$ brew install mcrypt

そのあとにそれぞれのローカルにインストールされているPHPのバージョンに合わせてソースを公式からひろってきましょう。 自分は5.4.17だったので5.4.17のソースをひろってきてます。

$ curl --location -s http://museum.php.net/php5/php-5.4.17.tar.gz
$ tar zxvf php-5.4.17.tar.gz
$ cd php-5.4.17

そしてコンパイル & インストール

$ phpize
$ ./configure
$ make -j6
$ make test
$ sudo make install
$ sudo vi /etc/php.ini
# => 'extension=mcrypt.so' を追記
$ sudo apachectl restart

そして最後にインストール出来ているか確認しましょう。

$ php -i | grep -i mcrypt

# mcrypt_supportがenabledになっていればOK!

最後に

わくわくしながらCakePHP3で遊ぼうとか思ってたらここだけで2時間くらいたっちゃって疲れちゃったよ・・・ 明日こそはCakePHP3で遊ぼうと思います!

PHP使うなら持ってていいと思ふ

PHP逆引きレシピ 第2版 (PROGRAMMER’S RECiPE)
鈴木 憲治 山田 直明 山本 義之 浅野 仁 櫻井 雄大 安藤 建一
翔泳社
売り上げランキング: 9,037
Read more

こんにちは。 前回簡単なSelenium入門をしてみましたが、Seleniumを使っているときに困るのが、ログインをしなければならないサイトをスクレイピングしたりテストを通したいときです。 ログイン処理を何度もまわせばいいのですが、開発途中のプログラムの場合だと短時間に何度も何度もログイン処理をまわすことになり、色々大変です。

そこでログイン処理を省き、通常使っているようにログイン済みのブラウザを使えれば便利ですよね。 Seleniumにはもちろんそういうことも考えられていて、それを設定することがあります。 今回はその設定方法を書いていきます。

Firefoxの設定をする

それではFirefoxの設定をしていきましょう。 Firefoxにはデフォルトでプロファイルが設定されていて、それを設定するとプログラムから使うように出来ます。

それでは設定していきましょう。

といってもとても簡単です。 MacOSX前提で話していますが、以下のコマンドをターミナルから入力してください。

$ /Applications/Firefox.app/Contents/MacOS/firefox-bin -p

そうすると以下のような画面が開くので、新規作成を押しましょう。

プロファイルの名前を決定する画面があるのでそこで決定をクリックすると、その名前のプロファイルが作成されます。 あとはそのプロファイルを選択して、「Firefoxを起動」をクリックし、ログインが必要なサイトで予めログインを完了させておけば完璧です!

今回はプロファイルをちゃんと設定出来たかと確認するために、作ったプロファイルでTwitterにログインしておいてください。

Seleniumから動かしてみる

それでは設定したプロファイルをプログラムから渡してみましょう。

コードは以下のような感じです。

default_profile = Selenium::WebDriver::Firefox::Profile.from_name "auto"
default_profile.native_events = true

driver = Selenium::WebDriver.for :firefox, :profile => default_profile

driver.navigate.to 'http://twitter.com'

こんな感じで使うプロファイル情報を定義してあげて、WebDriverを呼び出すときに変数として渡してあげればそれでOKです! ログイン後のTwitter画面は出てきましたか?出てきたら成功です!

最後に

SeleniumってPHPで動かそうとしてたときはとても苦労した記憶があったのですが、Rubyだと超楽ですね! これでいっぱいテストが書ける気がしてきましたw

そろそろやり始めます。

たのしいRuby 第4版
たのしいRuby 第4版
posted with amazlet at 14.01.05
高橋 征義 後藤 裕蔵
ソフトバンククリエイティブ
売り上げランキング: 25,239
Read more

みなさんこんにちは!!

以前CakePHPとWordPressでアプリを組んだのでリレーションとか色々書いていこうと思います。 WordPressではデータを入力、保存するのみで、主なデータ表示はCakePHPで行いました。

WordPressのデータをCakePHPで取得するために設定する

CakePHPとWordPressはインストール済み、また記事は何個か入っている、タグも何個か設定してある前提でやっていきます。

今回やるのは「記事からその記事に結びついているタグを表示する」ことと「タグからそのタグが結びついている記事を表示する」ことです。 自分でもちょっとおかしいと思うところは結構ありますw

WordPressのデータベースの構造は以下を見ればわかります。 http://wpdocs.sourceforge.jp/データベース構造

CakePHPではきつそうな部分が混ざってますがそこはスルーしましょう。 ここでやりたいことは記事に対するタグを引っ張ってくることです。

それではやっていきましょう。 いじっていくテーブルは、wp_postswp_term_relationshipswp_term_taxonomywp_termsの4つです。 なのでそれに対応するModelを作っていきます。

wp_postswp_term_relationshipsを持っているので以下のように書きます。

Posts.php

App::uses('AppModel', 'Model');

class Post extends AppModel {

    public $primaryKey = 'ID';

    public $useTable = 'wp_posts';

    public $name = 'Post';

    public $tablePrefix = 'wp_';

    public $hasMany = array(
        'TermRelationship' => [
            'className' => 'TermRelationship',
            'foreignKey' => 'object_id'
        ]
    );
}

wp_term_relationshipsはこんな感じです。ちょっとつっこみたいのはよくわかる。。。

TermRelationship.php

App::uses('AppModel', 'Model');

class TermRelationship extends AppModel {

    public $useTable = 'wp_term_relationships';

    public $name = 'TermRelationship';

    public $tablePrefix = 'wp_';

    public $belongsTo = [
        'TermTaxonomy' => [
            'className' => 'WpTermTaxonomy',
            'foreignKey' => 'term_taxonomy_id',
        ]
    ];
}   

wp_term_taxonomy

TermTaxonomy.php

App::uses('AppModel', 'Model');
class WpTermTaxonomy extends AppModel {

    public $name = 'TermTaxonomy';

    public $useTable = 'wp_term_taxonomy';

    public $primaryKey = 'term_taxonomy_id';

    public $tablePrefix = 'wp_';

    public $belongsTo = [
        'WpTerm' => [
            'className' => 'WpTerm',
            'foreignKey' => 'term_id'
        ]
    ];

}

そして最後。wp_terms

Term.php

App::uses('AppModel', 'Model');

class Term extends AppModel {

    public $name = 'Term';

    public $primaryKey = 'term_id';

    public $tablePrefix = 'wp_';

    public $displayField = 'name';

    public $hasOne = [
        'TermTaxonomy' => [
            'className' => 'TermTaxonomy',
            'foreignKey' => 'term_taxonomy_id'
        ]
    ];

}

これで設定完了です!お疲れ様です!

動作確認・実際に表示してみる

それでは最後に動作確認をしてみましょう。 たくさんのRelationを使うときはContainableBehaviorが便利なのでAppModelで読み込んでおきましょう。

AppModel.php

App::uses('Model', 'Model');

class AppModel extends Model {

    public $actsAs = ['Containable'];

}

動作確認です。まずは記事からタグを引っ張りだす!

PostsController.php

App::uses('AppController', 'Controller');

class PostsController extends AppController {

    public function index(){
        $articles = ClassRegistry::init('Post')->find('all', 
            ['contain' => [
                'TermRelationship' => [
                    'TermTaxonomy' => [
                        'Term'
                    ]
                ]
            ]
        );
        debug($articles);
    }
}

階層の深い部分にありますがタグが一覧表示されていると思います!

ここまでわかれば簡単!タグから記事を表示しましょう。 PostsController.php

App::uses('AppController', 'Controller');

class PostsController extends AppController {

    public function index(){
        $tags = ClassRegistry::init('Term')->find('all', 
            ['contain' => [
                'TermTaxonomy' => [
                    'TermRelationship' => [
                        'Post'
                    ]
                ]
        );
        debug($tags);
    }
}

最後に

いかがでしたでしょうか。 少し無理やりでしたが、目標は達成出来たかと思います。 CakePHPのリレーションは「_id」がついているものを勝手につなげますが、それを利用したものと言えます。 もっと綺麗に実装出来そうですが、実際に実装していく場合は、findの条件の部分を覆い隠せば綺麗になると思います。

覆い隠す場合は以下の記事が参考になるかもしれません。

findせずにconditionsを返す、DRYなCakePHPのModel実装のススメ

CakePHPerなら持っておかねば!

Webアプリ開発を加速する CakePHP2定番レシピ119
長谷川 智希
秀和システム
売り上げランキング: 34,461
Read more