仕事でどうしてもFuelPHPでOracleを扱う必要があり、
標準のORMでは扱うことが出来なかったため他の手段を探していた。
Symfonyで使われているdoctrine2が使えれば楽だなと思い少し試した話をメモしておく。
※ データベースのテーブルは作ってある前提
doctrine2を使うためのライブラリ
調べてみると既にライブラリがあったのでそれを利用してみる。
構成
最初は以下の様な標準のディレクトリ構成にする。
yourdirectory/
	core/				# fuelphpのcore 
	packages/			# fuelphpのpackages
	app/				# fuelphpのapp
		bootstrap.php
		classes/
		config/
		views/
		vendor/			# この下にライブラリを置く
インストール
composerでインストールが可能なので、まずcomposer.jsonを作る。
{
	"require": {
		"aspendigital/fuel-doctrine2": "dev-master"
	},
	"config": {
		"vendor-dir": "app/vendor"
	},
	"minimum-stability": "dev"
}
composerでinstallする。
$ curl -s 'http://getcomposer.org/installer' |php
$ php composer.phar install
ちゃんとインストールされれば app/vendor の下に色々置かれているはず。
doctrine2を使うための設定
autoload
何もしないと読み込まれず使えないので読み込まれるようにする。
<?php
// Load in the Autoloader
require COREPATH.'classes'.DIRECTORY_SEPARATOR.'autoloader.php';
class_alias('Fuel\\Core\\Autoloader', 'Autoloader');
// Bootstrap the framework DO NOT edit this
require COREPATH.'bootstrap.php';
/**
 * ここから追加
 */
// app/vendor以下をautoloadする
require APPPATH.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';
// EntityとRepositoryが属する\EntityネームスペースをFuelPHPのAutoloaderに追加
Autoloader::add_namespace('Entity', APPPATH.'classes'.DIRECTORY_SEPARATOR.'entity'.DIRECTORY_SEPARATOR);
/**
 * ここまで
 */
Autoloader::add_classes(array(
));
// Register the autoloader
Autoloader::register();
/**
 * Your environment.  Can be set to any of the following:
 *
 * Fuel::DEVELOPMENT
 * Fuel::TEST
 * Fuel::STAGING
 * Fuel::PRODUCTION
 */
Fuel::$env = (isset($_SERVER['FUEL_ENV']) ? $_SERVER['FUEL_ENV'] : Fuel::DEVELOPMENT);
// Initialize the framework with the config file.
Fuel::init('config.php');
db
databaseの設定もやらないと使えない。
<?php
return array(
	'doctrine2' => array(
		'proxy_dir' => APPPATH.'classes'.DIRECTORY_SEPARATOR.'proxy',
		'proxy_namespace' => 'Proxy',
		'metadata_path' => APPPATH.'classes'.DIRECTORY_SEPARATOR.'entity',
	),
	'default' => array(
		'type' => 'pdo',
		'connection' => array(
			'dsn' => 'oci:dbname=yourdb',		// これはoracle用の設定
			'username' => 'yourdbusername',
			'password' => 'yourdbpasswd',
			'persistent' => false,
		),
		'identifier' => '',
		'table_prefix' => '',
		'charset' => 'utf8',
		'caching' => true,
		'profiling' => false,
	),
);
view
EntityクラスがFuelPHPのセキュリティ機能に引っかかってしまうため、viewで扱うための設定をする。
都度追加するのはめんどくさいので基底クラスを作りそれを継承、継承しているものだけ許可をするようにする。
<?php
return array(
	// ...
	'security' => array(
		'whitelisted_classes' => array(
			'Fuel\\Core\\Response',
			'Fuel\\Core\\View',
			'Fuel\\Core\\ViewModel',
			'Closure',
			'Entity\\Base',				// これを追加する
		),
	),
	// ...
);
エンティティを作る
定義をyamlなどで作ってコマンドで作れる。
...が、色々工夫しないと作れず、今回はお試しなので一旦手作業で作ることにする。
今回は簡単にキャンペーンのエンティティを作るだけにする。
<?php
namespace Entity;
/**
 * Viewのセキュリティ機能を通過させる為に作る基底クラス
 */
class Base
{
}
<?php
namespace Entity;
use Doctrine\ORM\Mapping as ORM;
/**
 * @Entity(repositoryClass="Entity\CampaignRepository")
 * @Table(name="campaigns")
 */
class Campaign extends Base
{
	/**
	 * @Id
	 * @Column(type="integer")
	 * @GeneratedValue(strategy="AUTO")
	 */
	protected $id;
	/**
	 * @Column(type="string", length=512)
	 */
	protected $title;
	public function setId($id)
	{
		$this->id = $id;
		return $this;
	}
	public function setTitle($title)
	{
		$this->title = $title;
		return $this;
	}
	public function getId()
	{
		return $this->id;
	}
	public function getTitle()
	{
		return $this->title;
	}
}
リポジトリも作る。
メソッドはキャンペーン一覧を取得するだけ。
<?php
namespace Entity;
use Doctrine\ORM\EntityRepository;
class CampaignRepository extends EntityRepository
{
	public function getCampaignList()
	{
		$qb = $this->createQueryBuilder('c');
		return $qb->getQuery()->getResult();
	}
}
Controllerから使ってみる
先ほど作ってリポジトリからキャンペーン一覧を取得するだけの簡単なものを作成。
<?php
use \Fuel\Core\Controller;
class Controller_Campaign extends Controller
{
	public function action_list()
	{
		$em = \Fuel\Doctrine::manager();		
		$campaigns = $em->getRepository('Entity\Campaign')->getCampaignList();
		$this->theme
			->set_template('campaign/list.html.twig')
			->set(array(
				'campaigns' => $campaigns,
			));
		return \Response::forge($this->theme);
	}
}
Viewから使う
Controllerにて取得したものをViewから使い表示する。
{% extends 'pc/layout.html.twig' %}
{% block contents %}
<h1>キャンペーン一覧</h1>
{% if campaigns is empty %}
<p>キャンペーンはありません</p>
{% else %}
<ul>
	{% for campaign in campaigns %}
		<li>{{ campaign.id }} : {{ campaign.title }}</li>
	{% endfor %}
</ul>
{% endif %}
{% endblock contents %}
終わり
基本のfetchできるかだけ試した。
insert,update,deleteも試したいし、paginationとかも試したい所だけど時間がなく断念。
以上。