FuelPHP (1.6) で oil を改造して oil generate admin... --soft-delete で論理削除モデル使えるように勝手対応

FuelPHP 1.6 以外でも同じかも。

oil をちょっと改造することになる。

とりあえずの勝手対応。

deleted_at のフィールド名を別の名前にしたいとか、そういう贅沢には対応しない。

## oil g admin hoge --soft-delete したい。

やってみる。

```
oil g admin store name:string --soft-delete
```

出来上がったファイルを見てみると、

```APPPATH/classes/model/store.php
<?php
class Model_Store extends \Orm\Model
{
	protected static $_properties = array(
		'id',
		'name',
		'created_at',
		'updated_at'
	);

	protected static $_observers = array(
		'Orm\Observer_CreatedAt' => array(
			'events' => array('before_insert'),
			'mysql_timestamp' => false,
		),
		'Orm\Observer_UpdatedAt' => array(
			'events' => array('before_save'),
			'mysql_timestamp' => false,
		),
	);

	public static function validate($factory)
	{
		$val = Validation::forge($factory);
		$val->add_field('name', 'Name', 'required|max_length[255]');

		return $val;
	}

}
```

コレじゃない。

1. \Orm\Model_Soft を継承していないとダメ

2. deleted_at プロパティが必要。

3. $_soft_delete = array();の設定が必要

これを oil g admin sotre name:string --soft-delete とすることで実現したい。


## PKGPATH/oil/views/admin/orm/modelsoft.php を作成する。

PKGPATH/oil/views/admin/orm/model.php に倣って、必要な箇所を修正したファイルを modelsoft.php として新規作成する。

1. \Orm\Model_Soft にする

2. deleted_at をプロパティに追加する

3. $_soft_delete を設定する

```PKGPATH/oil/views/admin/orm/modelsoft.php
<?php echo '<?php' ?>

class Model_<?php echo $model_name; ?> extends \Orm\Model_Soft
{
	protected static $_properties = array(
		'id',
<?php foreach ($fields as $field): ?>
		'<?php echo $field['name']; ?>',
<?php endforeach; ?>
<?php if ($include_timestamps): ?>
		'created_at',
		'updated_at',
		'deleted_at'
<?php endif; ?>
	);

<?php if ($include_timestamps): ?>
	protected static $_soft_delete = array(
		'deleted_field' => 'deleted_at',
		'mysql_timestamp' => false
	);

	protected static $_observers = array(
		'Orm\Observer_CreatedAt' => array(
			'events' => array('before_insert'),
			'mysql_timestamp' => false,
		),
		'Orm\Observer_UpdatedAt' => array(
			'events' => array('before_save'),
			'mysql_timestamp' => false,
		),
	);
<?php endif; ?>

	public static function validate($factory)
	{
		$val = Validation::forge($factory);
<?php foreach ($fields as $field): ?>
<?php
		$rules = array('required');

		if (in_array($field['type'], array('varchar', 'string', 'char')))
		{
			if ($field['name'] === 'email')
			{
				$rules[] = 'valid_email';
			}
			$rules[] = ! is_null($field['constraint']) ? "max_length[{$field['constraint']}]" : 'max_length[255]';
		}
		elseif (in_array($field['type'], array('int', 'intenger')))
		{
			$rules[] = 'valid_string[numeric]';
		}
		
		$rules = implode('|', $rules);
?>
		$val->add_field('<?php echo $field['name']; ?>', '<?php echo ucwords(str_replace('_', ' ', $field['name'])); ?>', '<?php echo $rules; ?>');
<?php endforeach; ?>

		return $val;
	}

}

```

## PKGPATH/oil/classes/generate/scaffold.php に引数 --soft-delete があった場合、前述のファイルを使うように追記する

186行目くらいに追記する。

これで引数を判断して $model の中身がさっき作成したファイルをベースに作られているはず。

※ ifの書き方が汚いのはとりあえず気にしない。

```PKGPATH/oil/classes/generate/scaffold.php
<?php
// ( 略)
		/** Generate the Model **/
		$model = \View::forge(static::$view_subdir.$subfolder.'/model', $data);

        // if use --soft-delete option. when use modelsoft view
        if (\Cli::option('soft-delete'))
        {
            $model = \View::forge(static::$view_subdir.$subfolder.'/modelsoft', $data);
        }
```

### このままでは、migration ファイルに deleted_at が追加されないの、それも修正する。

118 行目付近の create_at などがある場所で、 create_at などに倣い deleted_at を追記する。

```PKGPATH/oil/classes/generate/scaffold.php
<?php
// (略)
			if (\Cli::option('mysql-timestamp', false))
			{
				$migration_args[] = 'created_at:date:null[1]';
				$migration_args[] = 'updated_at:date:null[1]';
                $migration_args[] = 'deleted_at:date:null[1]';
			}
			else
			{
				$migration_args[] = 'created_at:int:null[1]';
				$migration_args[] = 'updated_at:int:null[1]';
                $migration_args[] = 'deleted_at:int:null[1]';
			}
```

## 再度 oil g admin hoge --soft-delete -f してみる。

確認する。

※ -f は上書き用。

```
oil g admin store name:string --soft-delete -f
```

出来上がったファイルを見てみると、

```APPPATH/classes/model/store.php
<?php
class Model_Store extends \Orm\Model_Soft
{
	protected static $_properties = array(
		'id',
		'name',
		'created_at',
		'updated_at',
        'deleted_at'
	);

    protected static $_soft_delete = array(
        'deleted_field' => 'deleted_at',
        'mysql_timestamp' => false
    );

	protected static $_observers = array(
		'Orm\Observer_CreatedAt' => array(
			'events' => array('before_insert'),
			'mysql_timestamp' => false,
		),
		'Orm\Observer_UpdatedAt' => array(
			'events' => array('before_save'),
			'mysql_timestamp' => false,
		),
	);

	public static function validate($factory)
	{
		$val = Validation::forge($factory);
		$val->add_field('name', 'Name', 'required|max_length[255]');

		return $val;
	}

}
```

出来たっぽい！

- 上記では、admin しか対応してない

- 普通に oil g scaffold store name:string --soft-delete とかする場合は、同様に oil の views の scaffolding にテンプレートファイルを用意すればいいはず（試してへんから知らんけど）