オープンソースの家計簿 Economizzer をレンタルサーバにインストールして使う

Economizzer は PHP + MySQL で動作する、オープンソースの家計簿 Web アプリ。集計のグラフがちょっとかっこいい。

機能はいたってシンプルで次のことができる。

  • 収入・支出項目の追加・変更・削除・検索
  • 費目カテゴリの管理
    カテゴリは必ず2層にする必要がある(たとえば「教養娯楽費 > 旅行代」というカテゴリを設定して、費目には必ず下層の「旅行代」を設定する)
  • ログイン認証
  • ユーザの追加
    複数のユーザを作成し、1ユーザにつき1家計簿のみ管理できる
  • レスポンシブデザインで、スマートフォンタブレット、PC どの端末からでも使いやすい
  • CSV, TSV, Excel 形式でのエクスポート

現金や銀行口座といった資産の管理機能はないので、月々のお金の流れだけ分かればいいという方におすすめ。

Economizzer のインストール

パッケージは用意されていないので Github から開発版をダウンロードする。現在でも更新が続けられているようで、以下の内容は変更されている可能性がある。
作者によるドキュメントに従い、次のコマンドを実行する。

git clone https://github.com/gugoan/economizzer.git
cd economizzer
composer global require "fxp/composer-asset-plugin:~1.1.1"
composer install

このままだとエラーが出たので少し調べてみた。--no-plugins オプションを試してみるとうまくいくようだ。

composer global require "fxp/composer-asset-plugin:~1.1.1" --no-plugins
composer install

次に MySQL のユーザとテータベースを作成する。

mysql> CREATE USER economizzer_user@localhost;
mysql> SET PASSWORD FOR economizzer_user@localhost=PASSWORD('パスワード');
mysql> CREATE DATABASE economizzer DEFAULT CHARACTER SET utf8;
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER ON economizzer.* TO economizzer_user@localhost;
mysql> FLUSH PRIVILEGES;

続いて economizzer/config/db.php を編集し、データベースの設定を行う。

<?php
return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=127.0.0.1;dbname=economizzer',
    'username' => 'economizzer_user',
    'password' => 'パスワード',
    'charset' => 'utf8',
    'enableSchemaCache' => true,
];

データベース定義と初期データを設定するため、次のコマンドを実行する。

./yii migrate

なお、このスクリプトで初期化できる RDBMSMySQL のみなので注意。
ここまでの手順が完了すれば Economizzer が使えるようになる。設定した URL を開き、User: joe / Password: 123456 でログインするとテストデータを見ることができる。

レンタルサーバに設置する

Economizzer は Github からクローンしてきた状態ではデバッグデータを残すようになっている。サーバに設置する際には economizzer/web/index.php の次の2行をコメントアウトする。

defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');

日本語化する

見慣れた日本語の方が良かったので、次のファイルを変更して部分的に翻訳した。興味がある方は全てのメッセージを完全に訳して本家にコミットしてほしい。

  • config/web.php(選択できる言語を追加する)
  • messages/ja/app.php(他の言語からコピー)
  • messages/ja/user.php(他の言語からコピー)
  • views/cashbook/index.php(日付フォーマットを Yii::t() に通す)
  • views/cashbook/view.php(日付フォーマットを Yii::t() に通す)
  • views/user/register.php(選択できる言語を追加する)

views/cashbook/index.php, view.php において日付をローカライズするヒント。「’16 7/6」という表示にしたくて DataView::widget() のパラメータで format を ['date', '’y n/j'] のようにすると、年の値が想定している下二桁ではなく4桁で表示されてしまう。スマートではないが次の書き方で対処した。

<?php
...
[
    'value' => Yii::$app->formatter->asDate($model->date, 'php:'.Yii::t('app', 'F j, Y')),
],
...

SQLite3 で動かす

レンタルサーバでは MySQL のデータベースをバックアップすることに不安があるので、代わりに SQLite3 を使い、定期的にデータベースファイルをバックアップすることにした。
MySQL から SQLite3 へのデータ移行は次のページを参考にした。

また、Economizzer では SQL 文を手動で生成している部分があるが、ここに MySQL 独自の関数が含まれているため、一部うまく動作しないところがあった。ここはデータベースシステムによって振り分けることにする。
まずは PHP で SQLite3 を使っているかどうかを判定する関数を用意する。

function UU_isSQLite3() {
	global $config;
	static $isSQLite3;
	if (!isset($isSQLite3)) {
		$isSQLite3 = strpos($config['components']['db']['dsn'], 'sqlite:') === 0;
	}
	return $isSQLite3;
}

そして、MySQL 独自の関数を使用している controllers/DashboardController.php において、判定関数の結果によりクエリを振り分ける。
関数の書き換えは次のようにした。日付関数はデータベースシステムによりまちまちだが、IF 関数に関しては SQL99 標準の CASE 文に置き換えることで MySQL にも対応できる。

MONTH(date) = $thismonth AND YEAR(date) = $thisyear
→ STRFTIME('%Y-%m', date) = '$thisyear-$thismonth'

MONTHNAME(date)
→ STRFTIME('%m', date)

YEAR(date) = $thisyear
→ STRFTIME('%Y', date)

IF(cashbook.type_id = 1, value, 0)
→ CASE WHEN cashbook.type_id = 1 THEN value ELSE 0 END