アクセスできるかを含めてURLを判定するFormの作り方

久しぶりにsymfonyネタを1つ。
バリデーション通ったURLでもアクセスしたら、404返ってきたよムキー!ってなったので

要求仕様

  • sfValidatorUrl通る
  • 実際にアクセスできる


以上の要求を満たすバリデーションを作成しました。
なお、アクセス検証のためにsfWebBrowserプラグインを利用したので、インストールしていない人は、インストールしてください。

$ symfony plugin:install -r 1.1.2 sfWebBrowserPlugin

コード

今回は、Webpageというモジュールを作成しているので、クラス名がWebpageFormです。
名前はお好きなように設定してください。


sfValidatorAndでURL検証用とアクセス検証用2つのバリデータを登録します。
オプションのhalt_on_errorは、エラーが起きた時点でバリデーション中止するかを決めます。trueにしないと、sfValidatorUrlに通ろうが通らなかろうがsfValidatorCallbackに進んじゃいます。
sfValidatorCallbackは、独自のバリデーション登録するのに使います。
アクセスの検証は、sfWebBrowserの使用例のままです。

<?php
class WebpageForm extends BaseWebpageForm
{
  public function configure()
  {
    // urlって名前で、URLが送られてくる
    $this->widgetSchema['url'] = new sfWidgetFormInput();

    // バリデータを設定
    $this->validatorSchema['url'] = new sfValidatorAnd(array(
      new sfValidatorUrl(),
      new sfValidatorCallback(array('callback' => array($this, 'checkStatusCode')))
    ),
    array('halt_on_error' => true));
  }

  public function checkStatusCode($validator, $url)
  {
    $browser = new sfWebBrowser();

    try
    {
      if (!$browser->get($url)->responseIsError())
      {
        // Successful response (eg. 200, 201, etc)
        return $url;
      }
      else
      {
        // Error response (eg. 404, 500, etc)
        throw new sfValidatorError($validator, $browser->getResponseMessage());
      }
    }
    catch (Exception $e)
    {
      // Adapter error (eg. Host not found)
      throw new sfValidatorError($validator, $e->getMessage());
    }
  }
}