validation.php で field 毎のエラー出力を可能にしてみる

入力系や選択系で required でもエラー文言は異なる場合がある。
入力系→「:labelを入力してください」
選択系→「:labelを選択してください」

下のやり方を考えてみたけど、どうだろう。
callback がルールに指定されてもいける。はず


```php:APPPATH/classes/validation/error.php
<?php
class Validation_Error extends \Fuel\Core\Validation_Error
{
	/**
	 * Get Message
	 *
	 * Shows the error message which can be taken from loaded language file.
	 *
	 * @param   string  HTML to prefix error message
	 * @param   string  HTML to postfix error message
	 * @param   string  Message to use, or false to try and load it from Lang class
	 * @return  string
	 */
	public function get_message($msg = false, $open = '', $close = '')
	{
		$open   = empty($open)  ? \Config::get('validation.open_single_error', '')  : $open;
		$close  = empty($close) ? \Config::get('validation.close_single_error', '') : $close;

		if ($msg === false and ! ($msg = $this->field->get_error_message($this->rule)))
		{
			if (is_null($msg))
			{
				$msg = $this->field->fieldset()->validation()->get_message($this->rule);
			}

			// 追加部分
			if ($msg === false)
			{
				$rule  = $this->rule;
				$line  = 'validation.'.$this->field->name;
				$group = \Lang::get($line);
				if (is_array($group) && isset($group[$rule]))
				{
					$msg = $group[$rule];
				}
				else
				{
					$msg = \Lang::get($line.':'.$rule) ?: false;
				}
			}

			if ($msg === false)
			{
				$msg = \Lang::get('validation.'.$this->rule) ?: \Lang::get('validation.'.\Arr::get(explode(':', $this->rule), 0));
			}
		}
		if ($msg == false)
		{
			return $open.'Validation rule '.$this->rule.' failed for '.$this->field->label.$close;
		}

		// only parse when there's tags in the message
		return $open.(strpos($msg, ':') === false ? $msg : $this->_replace_tags($msg)).$close;
	}
}
```

```php:APPPATH/bootstrap.php
<?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';


Autoloader::add_classes(array(
	// Add classes you want to override here
	// Example: 'View' => APPPATH.'classes/view.php',
	'Validation_Error' => APPPATH.'classes/validation/error.php',
));

// Register the autoloader
Autoloader::register();

/**
 * Your environment.  Can be set to any of the following:
 *
 * Fuel::DEVELOPMENT
 * Fuel::TEST
 * Fuel::STAGE
 * Fuel::PRODUCTION
 */
Fuel::$env = (isset($_SERVER['FUEL_ENV']) ? $_SERVER['FUEL_ENV'] : Fuel::DEVELOPMENT);

// Initialize the framework with the config file.
Fuel::init('config.php');
```

```php:APPPATH/classes/controller/welcome.php
<?php
class Controller_Welcome extends Controller_Template
{
	public $template = 'welcome/index';

	public function action_index()
	{
		$post = array(
			'name'   => '',
			'gender' => '',
			'email'  => 'abc',
		);

		$val = \Validation::forge();

		$val->add('name', '名前')
			->add_rule('required');

		$val->add('gender', '性別')
			->add_rule('required');

		$val->add('email', 'メールアドレス')
			->add_rule('required')
			->add_rule('valid_email');

		$errors = !$val->run($post) ? $val->error() : array();
		$values = $val->validated();

		foreach ($errors as $key => &$error)
		{
			$values[$key] = $error->value;
			$error = ''.$error;
		}
		var_dump($errors, $values);
	}
}
```

```php:APPPATH/lang/ja/validation.php
<?php
return array(
	'required'        => ':labelを入力してください',
	'gender:required' => ':labelを選択してください',
	'email' => array(
		'required'    => ':labelは必須項目です',
		'valid_email' => ':labelを正しく入力してください',
	),
);
```

```php:結果
array(3) {
  ["name"]=>
  string(33) "名前を入力してください"
  ["gender"]=>
  string(33) "性別を選択してください"
  ["email"]=>
  &string(57) "メールアドレスを正しく入力してください"
}
array(3) {
  ["name"]=>
  string(0) ""
  ["gender"]=>
  string(0) ""
  ["email"]=>
  string(3) "abc"
}
```