Kohana で pjax をしてみたよ!
先日作成した簡単なページのページネーション部を pjax で動作するようにしてみました!
pjax については google で検索するといっぱいでてくるので、そちらを参照してください(´・ω・`)
Kohana PHP で実現するために、まずはモジュールを探してみました!
Kohana には http://kohana-modules.com/ というサイトがあり、現時点(2012/1/6)で 605 ものモジュールが登録されています。早速探してみると…あったあった、ありました!
(※ 他にも Facebook だったり Twitter だったり google map だったり、いろいろと便利なモジュールが用意されていますよ! )
Kopjax – Pjax jQuery ajax module for Kohana 3.1(.2)
https://github.com/cambiata/kopjax
セットアップ
モジュールをダウンロードし modules/ ディレクトリに解凍。 ディレクトリ名称を kopjax にしました。
モジュールを追加したら bootstrap.php に追記しましょう。
/** * Enable modules. Modules are referenced by a relative or absolute path. */ Kohana::modules(array( // 'auth' => MODPATH.'auth', // Basic authentication // 'cache' => MODPATH.'cache', // Caching with multiple backends // 'codebench' => MODPATH.'codebench', // Benchmarking tool 'database' => MODPATH.'database', // Database access // 'image' => MODPATH.'image', // Image manipulation 'orm' => MODPATH.'orm', // Object Relationship Mapping // 'unittest' => MODPATH.'unittest', // Unit testing // 'userguide' => MODPATH.'userguide', // User guide and API documentation 'pagination' => MODPATH.'pagination', 'kopjax' => MODPATH.'kopjax', ));
一番下に追加しました。
pagination モジュールのリンクを変える
前回の記事のままでは、ページ指定が query_string 設定となり ?page_id= となっていました。 これを route 設定に変更します。
Route::set() を追加
ルーティングを追加して、ページの指定をURLに含ませる形式を設定します。
application/bootstrap.php に追記します。
Route::set('top', '(<page_id>)', array('page' => '[0-9]+'))
->defaults(array(
'controller' => 'top',
'action' => 'index',
'page_id' => null,
));
Controller_Top の、 action_index() でページを切り替えます。 URL にすると http://www.example.com/1 などと数値がページ送りid(page_id) になります。
pagination の設定を変更
$pagination = Pagination::factory(array(
'item_per_page' => 10,
'total_items' => $all_address->count_all(),
'current_page' => array(
'source'=> 'route',
'key' => 'page_id'),
'auto_hide' => false,
'first_page_in_url' => false,
));
current_page の source の部分を query_string から route に変更しました。
リンクを pjax 対応にする
モジュールには pjaxdemo というコントローラやビューファイルが用意されており、これを参考に書き換えます。
コントローラ
最初に Controller_Top を変更します。
ajax(pjax)出力か通常の出力かを判定しビューを切り替えて出力する様です。 CakePHP には beforeFilter() や afterFilter() のほか、 beforeRender() などありますが、 KohanaPHP には before() および after() の2種類のコールバックがあります。 このコールバックを利用し、複数のアクションに対して処理を行うようにします。
public function after()
{
if (!$this->request->is_ajax()) {
$this->view = View::factory('pjax/template');
} else {
$this->view = View::factory('pjax/content');
}
$this->view->set('content', $this->content);
$this->response->body($this->view);
}
ajax の場合には pjax/template を。通常のアクセスの場合は pjax/content を読み込む形になるようです。
ビュー
コントローラで指定した pjax/template および pjax/content を用意します。
もちろん、ひな形となるファイルはモジュール kopjax の中に views/pjax/ 以下にそれぞれファイルがありますので、この2つのファイルを application/views/ の下に pjax ディレクトリを作成してコピーします。
※ そのままでも良いのですが、サンプル用のリンクなどがある為。
template.php
<html>
<head>
<title>address</title>
</head>
<?php $mediabase = Route::url('media'); ?>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script type="text/javascript" src="<?php echo $mediabase ?>/pjax/js/jquery.pjax.js"></script>
<script type="text/javascript">
$(function(){
// pjax
$('a').pjax('#content')
})
</script>
</head>
<body>
<div id="content">
<?php echo View::factory('pjax/content')->set('content', $content) ?>
</div>
<?php echo date('Y-m-d H:i:s'); ?>
</body>
</html>
サンプルにあったデモ用のリンクを削除し、pjax化するリンクの対象をアンカータグすべてに変更しました。
content.php
<?php echo $content; ?> <hr /> <?php echo (Request::current()->is_ajax()) ? 'Content part loaded using Ajax' : 'Whole page loaded using standard Page refresh'?>
3行目で、ajax で表示されているか、通常読み込みされたかどうかが表示されるようになっています。
おわり
あとは、データを10件以上登録しページ送りをしてみてください。
Content part loaded using Ajax
と表示され、その下の時刻もページを切り替えても書き換わらず、同じ時間が表示されています。そして、2ページ目などが表示されている状態で、再読み込みをすると、2ページ目のまま、最下部の表示が以下のように変わるはずです。
Whole page loaded using standard Page refresh
Kohana データベースへの登録とページネーション 〜 ページネーション 〜
データベース登録できたので、次はページネーションを。
同梱モジュールには含まれていない様子だったので、さっさとググッて見つけてきました。
kloopko / kohana-pagination [ https://github.com/kloopko/kohana-pagination ]
ページからダウンロードしてきて、展開したら modules/ 以下にコピーします。
次に bootstrap.php に追加。
/**
* Enable modules. Modules are referenced by a relative or absolute path.
*/
Kohana::modules(array(
// 'auth' => MODPATH.'auth', // Basic authentication
// 'cache' => MODPATH.'cache', // Caching with multiple backends
// 'codebench' => MODPATH.'codebench', // Benchmarking tool
'database' => MODPATH.'database', // Database access
// 'image' => MODPATH.'image', // Image manipulation
'orm' => MODPATH.'orm', // Object Relationship Mapping
// 'unittest' => MODPATH.'unittest', // Unit testing
// 'userguide' => MODPATH.'userguide', // User guide and API documentation
'pagination' => MODPATH.'pagination',
));
pagination というディレクトリでコピーしたので MODPATH.’pagination’ となっています。
追記するのはコントローラーとビューの2つ。
コントローラーに追記
$_POST の if 文の前に追加します。
$all_address = ORM::factory('address');
$pagination = Pagination::factory(array(
'item_per_page' => 10,
'total_items' => $all_address->count_all(),
));
$addresses = $all_address->limit($pagination->items_per_page)
->offset($pagination->offset)
->find_all();
$view = View::factory('address/create')
->set('pagination', $pagination)
->set('addresses', $addresses)
->bind('errors', $errors);
特に絞り込むような条件もないので、全件の件数を 4行目で pagination に設定し、1ページ10件ずつ(item_per_page) に設定します。
10件ずつ区切って表示するため、 limit() および offset() にそれぞれ、 item_per_page と offset を指定し取得範囲を変動させます。
結果を、先ほどの view に set() でビューに渡せば完了です。
ビューに追記
<?php
echo $pagination->render();
?>
<?php echo $pagination->total_items; ?>件登録があります
<table>
<? foreach ($addresses as $address): ?>
<tr>
<td><?php echo $address->firstname; ?></td>
<td><?php echo $address->lastname; ?></td>
</tr>
<?php endforeach; ?>
</table>
create.php に最後に上記を追記。
1行目の render() によって、ページ送りが表示されます。
また、このままではページ送りが First や Last、Next といった英語表記になっています。
しかし i18n による国際化の仕組みによって日本語にすることができます。
application/i18n/ に配下に ja.php ファイルを作成。
以下のように記述します。
<?php defined('SYSPATH') or die('No direct script access.');
return array(
'First' => '最初へ',
'Previous' => '前へ',
'Next' => '次へ',
'Last' => '最後へ',
);
これによって、日本語表示になります。
Kohana データベースへの登録とページネーション 〜 登録 〜
先日のセットアップから引き続き。
今度は、データベースにデータを登録し、ページネーションで表示してみました。
まずは、データベースを新規に作成しテーブルを作ります。
CREATE TABLE `addresses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(10) NOT NULL DEFAULT '',
`lastname` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
addresses …。 という名前ですが、とりあえず名前だけ。
次に、 application/bootstrap.php を編集し、 ORM および database のモジュールを使えるように、コメントアウトされている各行を外します。
/**
* Enable modules. Modules are referenced by a relative or absolute path.
*/
Kohana::modules(array(
// 'auth' => MODPATH.'auth', // Basic authentication
// 'cache' => MODPATH.'cache', // Caching with multiple backends
// 'codebench' => MODPATH.'codebench', // Benchmarking tool
'database' => MODPATH.'database', // Database access
// 'image' => MODPATH.'image', // Image manipulation
'orm' => MODPATH.'orm', // Object Relationship Mapping
// 'unittest' => MODPATH.'unittest', // Unit testing
// 'userguide' => MODPATH.'userguide', // User guide and API documentation
));
最後に application/config/ 配下に database.php ファイルを作成し以下のような記述を追加します。
<?php
return array(
'default' => array(
'type' => 'mysql',
'connection' => array(
'hostname' => 'localhost',
'username' => 'データベースユーザー名',
'password' => 'データベースパスワード',
'persistent' => false,
'database' => 'データベース名'
),
'table_prefix' => '',
'charset' => 'utf8',
'profiling' => true
)
);
準備完了。
モデルを作る
addresses のモデルを作ります。 application/classes/model の配下に address.php ファイルを作ります。テーブル名は複数形ですが、モデル名は単数形となります。
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_Address extends ORM
{
public function rules()
{
return array(
'firstname' => array(
array('not_empty'),
),
'lastname' => array(
array('not_empty'),
),
);
}
}
class 名は、 Model_ から始まります。 ひとつだけ function がありますが、 バリデーションルールです。
この例では、 firstname および lastname に対して not_empty ルールを設定しています。これにより、空での登録はできなくなります。
後ほど設定するエラー表示の指定により、このままでも英語によるエラーが表示されますが、ついでに解りやすく日本語にしておきましょう。
メッセージは application/messages 配下に設置します。 models ディレクトリを作成し、 作成したディレクトリ内に address.php ファイルを以下の通り作ります。
<?php
return array(
'firstname' => array(
'not_empty' => '必ず入力してください',
),
'lastname' => array(
'not_empty' => '必ず入力してください',
),
);
これで、バリデーションによって表示されるエラーメッセージを変更することができます。
コントローラーを作る
Kohana PHP では、セットアップ直後 welcome.php が default コントローラーとして / にアクセスされた際に表示されるよう設定されています。
まずはこの設定を変更します。
application/bootstrap.php を開き、 Route::set() を変更します。
/**
* Set the routes. Each route must have a minimum of a name, a URI and a set of
* defaults for the URI.
*/
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'top',
'action' => 'index',
));
controller に指定した top.php(Controller_Top) の action に指定した index(action_index()) がデフォルトと変更できました。
ではファイルを作ります。
<?php defined('SYSPATH') or die('No direct script access.');
class Controller_Top extends Controller {
public function action_index()
{
$view = View::factory('address/create')
->bind('errors', $errors);
if ($_POST) {
$address = ORM::factory('address')->values($_POST);
try {
$address->save();
} catch(ORM_Validation_Exception $e) {
$errors = $e->errors('models');
}
}
$this->response->body($view);
}
}
7行目で、表示するビューを指定しています。 address/create と指定することで application/views/address/create.php を指定することになります。 8行には bind() が記載されています。 bind() は、ビューに対し値を渡してあげるメソッドですが、参照渡しによって行われます。
10行目からは、フォームから投稿された場合の処理になります。 address モデルに対し送信されたデータをセットし、保存を試みます。
バリデーションによりエラーとなった場合は、 $errors にエラー内容が代入されます。
ビューを作る
<?php echo Form::open('/'); ?>
<div>
<?php
echo Form::label('firstname', '姓');
echo Form::input('firstname');
echo Arr::get($errors, 'firstname');
?>
</div>
<div>
<?php
echo Form::label('lastname', '名');
echo Form::input('lastname');
echo Arr::get($errors, 'lastname');
?>
</div>
<?php echo Form::submit('submit', '登録'); ?>
<?php echo Form::close(); ?>
このビューによって、何も記入せずに「登録」ボタンをクリックすると以下の通り、エラーが表示されます。

Kohana PHP 3.2 セットアップ
ブログの更新をすごく長い間サボってしまっていました。
久しぶりの更新は、 Kohana PHP framework 3.2 を使ったプログラムの作成を。
本当に久しぶりすぎたので、とりあえずセットアップから開始したいと思います。
環境
- Ubuntu 11.10
- nginx 1.0.5
- php 5.3.13
MySQL 入れるの忘れてた。 入れると 5.1.58。
セットアップ
それぞれをインストールし、今回は nginx + php-fpm で構築しました。
cat /etc/nginx/sites-available/default
server {
listen 80;
server_name localhost;
root /home/yasuhiro/www;
index index.php;
location / {
try_files $uri $uri/ @kohana;
}
location @kohana {
rewrite ^ /index.php/$uri last;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
nginx と php-fpm を起動して、ブラウザで http://localhost/ にアクセスしてみます。
環境テストが動作し、 こちらの画面では、キャッシュディレクトリとログディレクトリに書き込めないというエラーが表示されています。それぞれ、書き込みできるようパーミッションを変更。
再度リロードすると…
先ほどまで、赤く警告が表示されていましたが全てがグリーンに変わりました。
メッセージに従って www ディレクトリ配下にある install.php をリネーム(使わないので削除でもいいよ!)すると、インストール完了です!
リロードすると左上に「hello, world!」と表示されるシンプルな画面になります。
2010 in review
The stats helper monkeys at WordPress.com mulled over how this blog did in 2010, and here’s a high level summary of its overall blog health:

The Blog-Health-o-Meter™ reads This blog is doing awesome!.
Crunchy numbers
A Boeing 747-400 passenger jet can hold 416 passengers. This blog was viewed about 13,000 times in 2010. That’s about 31 full 747s.
In 2010, there were 9 new posts, growing the total archive of this blog to 18 posts. There were 11 pictures uploaded, taking up a total of 2mb. That’s about a picture per month.
The busiest day of the year was December 8th with 107 views. The most popular post that day was Google Maps API(v3) で住所から地図にマーカーを置く!.
Where did they come from?
The top referring sites in 2010 were hampom.humming-code.com, twitter.com, s.luna.tv, thedesignium.com, and webcache.googleusercontent.com.
Some visitors came searching, mostly for jquery sortable, google maps api v3 マーカー, jquery ドラッグ ドロップ 並び替え, google map api v3, and codeigniter 認証.
Attractions in 2010
These are the posts and pages that got the most views in 2010.
Google Maps API(v3) で住所から地図にマーカーを置く! March 2010
1 comment
jQuery UI の sortable でらくらく並び替え January 2010
作ってみたよー!! ランダムバナーを表示する jQuery プラグイン October 2009
Codeigniter で超簡易的なモバイルページ出力をする March 2010
1 comment
EzAuth でユーザー認証(1.7.2で動作させます!) #Codeigniter April 2010
1 comment
EzAuth でユーザー認証の仕組み #Codeigniter
なんだかイメージですが何重もの構造になっているような気がして頭がおかしくなって死ぬ。という印象があって、後で見たときに絶対「どんな仕組みになっているのかさっぱりわからねぇ」と思う自信100%なので書き残しておく。
EzAuth の認証(というより、ロール)設定は以下の組み合わせによって行われています。
1. ユーザーに直接記録される情報。

テーブル「ez_access_keys」に記録されています。user_id は、ez_users の id と紐付けられており、program と access がアクセスが許可されるエリアになります。
2. プログラムに設定される情報。

各コントローラーのインスタンスに protected_pages というクラス変数により設定されます。配列になっており、それぞれ左辺の値はクラスメソッドを指し、右辺の値はアクセスが許可されるエリア情報です。
ez_access_keys の program に設定されている値は、コード上では $this->ezauth->program に該当し、ez_access_keys の access に設定されている値は、コード上では protected_pages の右辺に該当する、という事です。
program は「家」 access が「鍵」だとすると、proteced_pages のそれぞれ左辺の値は「部屋」
家(default)に対する鍵(user)で開ける事ができる部屋は、 client部屋と changepw部屋。admin部屋を開ける為には admin という鍵が必要になります。
その鍵を持たせるかどうかを、データベースで設定させる訳です。
一方で、ユーザー「admin」はすべての部屋を開けることのできるオールマイティキーを持っているので、client部屋およびchangepw部屋については自由に出入りができる仕組みです。
なお、protected_pages で指定されていない部屋については単純に「鍵がかかっていない」という認識になりますので、認証不要のページは宣言も不要です。
EzAuth でユーザー認証(1.7.2で動作させます!) #Codeigniter
Codeigniter では、カートライブラリは標準で添付されているのにも関わらず認証ライブラリが標準では添付されていない!という個人的にはちょっと悩ましい状況になっています。
公式の Wiki にはサードパーティ製のライブラリが数多く登録されており、認証ライブラリもそのうちの一つで現時点でも数だけなら20以上の登録があります。(※ Category:Libraries -> Authentication )
悩ましいなぁ、悩ましいなぁ。と_つぶやいて_いたところ、
@Hampom @terakuma CodeIgniterの認証系だれかヒトバシラーで試して欲しいですと言ってみる … http://bizwidgets.biz/user_guide/ezauth.htm
と @matagaさんにリプライをいただいたので、ニート歴1ヶ月で大変お時間に余裕がありそうな私。試してみる事にしました!(お仕事探してますよ!えぇ!)
早速、EzAuth を配布サイト(http://bizwidgets.biz/ezauth/)よりダウンロードしてみました。
アーカイブを展開すると Codeigniter 本体そのものも含まれてしまっている様です。EzAuth としてどこまで改変してあるのか不安&面倒なので、ちょっと立ち止まってもしまいましたが、解体して、さらに古いバージョンの Codeigniter ベースであった為、現在は非推奨となっている Validation クラスが使われている部分を Form_validation に置き換えるなどの改変も加えています。
前置きが長くなりましたが、EzAuth として Codeigniter に組み込むファイルをアーカイブしました。以下のURLよりダウンロードしてください。
http://hampom.humming-code.com/Codeigniter-EzAuth/EzAuth.tar.gz
2010年4月7日更新:
libraries/MY_Session.php のインスタンス記述に誤りがありましたので修正しました。
アーカイブの中に格納されているファイルは以下の通りです。
css や images などは、サンプルページで使用しているものですので公開ディレクトリにコピーしてください。
EzAuth として必要不可欠なファイルは libraries ディレクトリの2ファイル及び、models ディレクトリの1ファイルとなります。
libraries にはコアクラスを継承したファイルがあり、MY_Controller.php ファイルは EzAuth で必要な _remap() が設定されていますので、MY_Controller を用いてコントローラーを作成する事で、個別に _remap() を記述しなくとも済むようにしました。 MY_Session.php については、認証後セッションにオブジェクトを入れる仕組みになっているんですが、Codeigniter のバグにより、うまく出し入れができません。本家のフォーラムでも話題になっていたので、そちらのフォーラムにあったスクリプトをそのまま入れています。(CI 1.7 Session Bug within object storage)
models にある ezauth_model.php にて認証をすべて担っています。
サンプル通り動かすためには、これらのファイルをすべて Codeigniter に上書きでコピーし、autoload設定をします。
config/autoload.php
$autoload['libraries'] = array('database', 'session');
$autoload['helper'] = array('url', 'cookie');
さらに session をデータベースで動作させるよう config/config.php を変更します。
config/config.php
$config['encryption_key'] = "適当にアルファベット&数値で埋めましょう";
$config['sess_use_database'] = TRUE;
データベースの作成と、config/database.php の設定も忘れずに!テーブルは3つ。さらにセッション用に+1つ。以下のクエリを実行すれば作成されます。
CREATE TABLE ci_sessions ( session_id varchar(40) NOT NULL DEFAULT '0', ip_address varchar(16) NOT NULL DEFAULT '0', user_agent varchar(50) NOT NULL, last_activity int(10) unsigned NOT NULL DEFAULT '0', user_data text NOT NULL, PRIMARY KEY (session_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE ez_access_keys ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) DEFAULT NULL, program varchar(255) DEFAULT NULL, access varchar(255) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO ez_access_keys (id, user_id, program, access) VALUES (1, 1, 'default', 'user'), (2, 2, 'default', 'admin'); CREATE TABLE ez_auth ( user_id int(11) NOT NULL, `password` varchar(255) DEFAULT NULL, reset_code varchar(255) DEFAULT NULL, cookie_hash varchar(255) DEFAULT NULL, activation_code varchar(255) DEFAULT NULL, PRIMARY KEY (user_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO ez_auth (user_id, `password`, reset_code, cookie_hash, activation_code) VALUES (1, 'f7d13da0a68b723f5b4e5a58d0e3c6e9', '', '45d192365165b2c5e9ed3adeada2acce', '16470a4b35ed04a8a139deab0c52e9a1'), (2, '1fd8528f5c64c09f96f16b5bb7dc2a3a', NULL, '45bd7b865824d63f4ee930cc903c1a72', 'fde180e7739caa7722f0fd7cdde25c79'); CREATE TABLE ez_users ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(50) DEFAULT NULL, email varchar(255) DEFAULT NULL, register_date datetime DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO ez_users (id, username, email, register_date) VALUES (1, 'client', 'hoge@hoge.com', '2010-04-03 00:00:00'), (2, 'admin', 'hoge@hoge.com', '2010-04-03 00:00:00');
設置は以上です!
Kohana で作る twitter ツール「つどったー」作る編
前回でサイトの準備が整いました!
今回は具体的にプログラムを作っていきます。追加したのは controller 2ファイル。model 1ファイル。view 3ファイルです。
では、/controllers/welcome.php から!
1. welcome.php
<?
class welcome_Controller extends Controller {
public $IN_PRODUCTION = False;
public function __construct()
{
parent::__construct();
$this->twitter = new Twitter;
$this->twitter->check_login();
$this->page = new View('template');
}
public function index()
{
if($this->twitter->check_login())
{
$url = "http://api.twitter.com/1/{$this->twitter->user->username}/lists.json";
$list = json_decode($this->twitter->oAuthRequest($url));
$this->tsudotter = new Tsudotter_Model;
$regist_list = $this->tsudotter->get($this->twitter->user->username);
if(!is_null($regist_list))
{
foreach($regist_list as $row)
$new_regist_list[] = "/{$this->twitter->user->username}/$row";
}
else
{
$new_regist_list = null;
}
$message = $this->twitter->sess->get('user_message');
$this->page->content = new View('logged_in',array('twitter'=>$this->twitter,'limits'=>$limits,'lists'=>$list,'regist_list'=>$new_regist_list,'message'=>$message));
}
else
{
$this->twitter->getRequestTokens();
$url = $this->twitter->getAuthorizeUrl();
$this->page->content = new View('not_logged_in',array('url'=>$url));
}
$this->page->render(True);
}
public function completed()
{
if($this->twitter->check_login() == False)
{
$this->twitter->sessionRequestTokens();
$this->twitter->tradeRequestForAccess();
if($this->twitter->storeTokens())
{
url::redirect('');
}
else
{
echo "help - a wierd error occured somewhere. Check your installation again";
}
}
else
{
url::redirect('');
}
}
public function logout()
{
if($this->twitter->check_login() != False)
{
$this->twitter->revokeSession(True);
}
url::redirect('');
}
}
welcome.php はデフォルトコントローラーになっており、http://tsudotter.com/ にアクセスすると welcome.php の index が対応します。 wellcome.php には、この他にログアウト( logout ) および、twitter で指定した callback URL( completed ) の3つが存在しています。
index では、$this->twitter->check_login() によりログイン状態をチェックされログインされていない場合は、twitter ログイン用URLを取得し view の not_logged_in.php を表示します。一方、ログインされていた場合は Twitter API によりログインユーザーのリスト一覧を取得。さらに、Tsudotter_Model を用いて登録済みのリストを取得しています(ビューにて、登録済みのリストには×を表示したいからです!)
では、ビューはどのようになっているのでしょうか!
2. /views/not_logged_in.php /views/logged_in.php /views/template.php
not_logged_in.php
<p style="padding: 3px;">
「つどったー」は Twitter で作成したリストへの登録をオープンにする為のサイトです。まずは、以下のリンクからログインし「リストに集う」許可をください!!<br />
</p>
<p style="padding: 3px; text-align: center;">
<?=html::anchor($url, html::image('Sign-in-with-Twitter-darker.png'));?>
</p>
このファイルで必要なのは html::anchor() だけですね。welcome.php コントローラーファイルの 41行目で取得した $url をここでは出力しています。
logged_in.php
<p style="padding: 3px;">
<?=$twitter->user->username;?> さん、お手伝いできることはありますか?
</p>
<? if($message !== false): ?>
<p style="padding: 3px; font-weight: bold; color: #cc0000;">
<?=$message; ?>
</p>
<? endif; ?>
<p style="padding: 3px; text-align: right;">
<?=html::anchor('logout','[ ログアウト ]');?>
</p>
<? if (count($lists->lists) > 0): ?>
<p style="padding: 3px;">
<?=$twitter->user->username;?> さんの管理されているリストが<?=count($lists->lists);?>件見つかりました。<br />
登録をオープンにするリストを選択ください。
</p>
<?
print form::open('list/open');
?>
<table style="margin: 5px auto 5px auto; width: 490px; border: 1px #E3E3E3 solid; border-collapse: collapse; border-spacing: 0;">
<tr>
<th style="padding: 5px; border: #E3E3E3 solid; border-width: 0 0 1px 1px; background: #F5F5F5; font-weight: bold; line-height: 120%; text-align: center;"> </th>
<th style="padding: 5px; border: #E3E3E3 solid; border-width: 0 0 1px 1px; background: #F5F5F5; font-weight: bold; line-height: 120%; text-align: center;">リスト名</th>
<th style="padding: 5px; border: #E3E3E3 solid; border-width: 0 0 1px 1px; background: #F5F5F5; font-weight: bold; line-height: 120%; text-align: center;">リンク</th>
</tr>
<? foreach($lists->lists as $value): ?>
<tr>
<td style="padding: 5px; border: 1px #E3E3E3 solid; border-width: 0 0 1px 1px; background: #FFFFFF; text-align: center;">
<? if(is_array($regist_list) && in_array($value->uri, $regist_list)): ?>
<span style="color: #cc0000;">×</span>
<? else: ?>
<? print form::radio('chk_list', $value->uri); ?>
<? endif; ?>
</td>
<td style="padding: 5px; border: 1px #E3E3E3 solid; border-width: 0 0 1px 1px; background: #FFFFFF;"><?=$value->name;?></td>
<td style="padding: 5px; border: 1px #E3E3E3 solid; border-width: 0 0 1px 1px; background: #FFFFFF;"><a href="http://twitter.com<?=$value->uri;?>"><?=$value->full_name;?></a>)</td>
</tr>
<? endforeach; ?>
</table>
<?
print form::submit('submit', '登録');
?>
<?
ああ…。 css は外部ファイルにまとめるべきでした…。
ページ上部側から、ログアウト、リスト、入力画面と並んでいます。
実際に出力されると以下のようになります。
さて、もうひとつの template.php はどんな役割を果たしているのでしょうか。
実はコンテンツ部分を除いたヘッダーやフッターなど、統一部分が記述されています。
つどったーでは、ヘッダーとフッターのほかに右部のコンテンツについても template.php に含めています。
自身のリストを公開するフォームと、他のユーザーのリストに登録するフォームはどちらも /controllers/list.php で処理を行います。
3. list.php
<?
class List_Controller extends Controller {
public function __construct()
{
parent::__construct();
$this->twitter = new Twitter;
$this->twitter->check_login();
$this->tsudotter = new Tsudotter_Model;
$this->twitter_user = new Twitter_user_Model;
}
public function open()
{
if($this->twitter->check_login() != False)
{
list($dummy, $nickname, $list_name) = explode("/", $this->input->post('chk_list'));
if($this->twitter->user->username == $nickname)
{
$inArray = array(
'nickname' => $nickname,
'list_name'=> $list_name
);
$this->tsudotter->insert_list($inArray);
}
}
url::redirect('');
}
public function add()
{
if($this->twitter->check_login() != False)
{
$screen_name = $this->input->post('screen_name');
$list_name = $this->input->post('list_name');
$user_list = $this->tsudotter->get($screen_name);
if(in_array($list_name, $user_list))
{
$user = $this->twitter_user->get_key($screen_name);
if(is_object($user))
{
$this->list_owner = new Twitter;
$this->list_owner->user = new Twitter_user_Model;
$this->list_owner->user->set_keys($user->access_key, $user->secret_key);
$url = "http://api.twitter.com/1/{$screen_name}/{$list_name}/members.json";
$args = array(
"id" => $this->twitter->user->username
);
$this->list_owner->oAuthRequest($url, $args, "POST");
$this->twitter->sess->set_flash('user_message', '登録を行いました!');
}
else
{
$this->twitter->sess->set_flash('user_message', '希望されたリストは登録許可がありません。残念!');
}
}
else
{
$this->twitter->sess->set_flash('user_message', '希望されたリストは登録許可がありません。残念!');
}
}
url::redirect('');
}
}
リストの公開は open。リストへの登録は add で。KTwitter ではログインをするとユーザーの access key および secret key がデータベースに保存されますので、それらの情報を用いて登録希望のユーザー名(screen name)を、Twitter リストAPI により登録します。
最後にモデルですが、KTwitter に含まれる twitter_user.php はそのまま利用し tsudotter_model として1つだけ追加しています。
4.tsudotter.php
<?php
class Tsudotter_model extends Model {
public function __construct()
{
parent::__construct();
}
public function insert_list($data)
{
$this->db->insert('tsudotter', $data);
}
public function get($nickname)
{
$this->db->where('nickname', $nickname);
$r = $this->db->get('tsudotter');
if($r->count() > 0)
{
foreach($r as $row)
$all_array[] = $row->list_name;
return $all_array;
}
else
{
return null;
}
}
}
公開するリスト情報を登録する insert_list() と、登録されているリスト情報を取得する get() の2つだけのファイルです。
Kohana で作る twitter ツール「つどったー」準備編
先日の予告通り、Kohana で作った twitter ツール「つどったー」の中身をご紹介しちゃいます。
まずは材料。
1. KohanaPHP (http://www.kohanaphp.com/)
2. KTwitter (http://www.errant.me.uk/ktwitter)
それぞれをダウンロードし展開します。
展開したKTwitter のディレクトリを Kohana のディレクトリと統合しました。
ここでは、展開したディレクトリ名を kt に変換し application に存在していて kt に存在していない cahe や helpers、hooks、logs を作りました。
そして、application から kt にディレクトリ指定を変更する必要がありますので tsudotter 直下にある index.php の以下のラインを編集します。
/** * Website application directory. This directory should contain your application * configuration, controllers, models, views, and other resources. * * This path can be absolute or relative to this file. */ $kohana_application = 'kt';
$kohana_application を kt に変更します。
データベースを用意します。
次に、KTwitter で指示されている通りのテーブルを作成します。
CREATE TABLE `twitter_users` ( `user` VARCHAR( 50 ) NOT NULL , `access_key` TEXT NOT NULL , `secret_key` TEXT NOT NULL , PRIMARY KEY ( `user` ) );
さらに、つどったーでは自由に登録できるリストをユーザーに登録してもらいますので、リスト情報を保存するテーブルもあわせて作成します。
CREATE TABLE `tsudotter` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nickname` varchar(100) NOT NULL, `list_name` varchar(200) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `nickname` (`nickname`,`list_name`) );
/kt/config/ に database.php を作成し、データベースと接続するための設定を保存します。
<?php $config['default'] = array ( 'benchmark' => TRUE, 'persistent' => FALSE, 'connection' => array ( 'type' => 'mysql', 'user' => 'ユーザー名', 'pass' => 'パスワード', 'host' => 'localhost', 'port' => FALSE, 'socket' => FALSE, 'database' => 'データベース名' ), 'character_set' => 'utf8', 'table_prefix' => '', 'object' => TRUE, 'cache' => FALSE, 'escape' => TRUE );
Twitter に application の登録をしましょう!
twitter にログインし「Applications Using Twitter」にアクセスします。「Register a new application」をクリックしアイコンやアプリケーション名などを登録します。
つどったー では以下の通り登録を行いました!
-
Application Name: list tsudotter
-
Application Website: http://tsudotter.com/
-
Application Type: Browser
-
Callback URL: http://tsudotter.com/welcome/completed
-
Default Access type: Read & Write
-
Use Twitter for login: チェックを入れる!
登録が完了すると、Consumer key および Consumer secret が得られます。これらの情報を /kt/config/twitter.php に設定します。
// To get consumer key/secret you need to visit http://www.twitter.com/oauth_clients and create an app // Consumer key from twitter $config['consumer_key'] = ''; // Consumer Secret from twitter $config['consumer_secret'] = '';
これで準備が完了です!
少し長くなりましたので、続きは後ほど!
Kohana で作る twitter ツール「つどったー」
以前に「twitter で tsudoる – つどったー 作ったよ!」という事で土曜日の昼になんとなく作った twitter ツールでしたが、その後、やれ LIST機能が本家に付くわ、OAuth なんてものが出現してくるわで、長い間放置していた「つどったー」に手を入れることにしました!
そして、今回は「Kohana」をフレームワークに選び、Kohana に対応した Twitter ライブラリ「Kohana Twitter Library (with Oauth support)」を使ってみました!
この「つどったー」は、あなたが管理しているリストをサイトを通じて自由に登録してもらうことができるようにする事ができます。
ログインすると、twitter の認証後画面が切り替わり、あなたが管理しているリストが表示されます。リストを選択し「登録」ボタンをクリックすると「つどったー」にリスト情報が登録され、他のユーザーからの登録が可能になります。
「Kohana Twitter Library (with Oauth support)」のサンプルをちょこちょこっと書き換えただけで、作られておりますので、そのうちソースコードを恥を忍んで晒します!
サイトはこちら!
→ つどったー








