2010 年 5 月 のアーカイブ

VAIOのリカバリー時に、「エラー305: 64」表示




















リカバリーを進めていくと、
エラー305: 64
とダイアログが表示されてリカバリーが17%くらいで止まる、というVAIOが持ち込まれてきました。
相談者はCDの焼きミスを疑い、SONYからリカバリディスクを取り寄せて試してみるも現象変わらず。

リカバリのメニューからコマンドプロンプトが起動できるので、中を見てみると、Cドライブは完全に空の状態。

試しにリカバリの推奨設定を無視して、パーティション設定でCドライブを50GBにして、残りをシステム復元用のパーティションにしてみたら、なぜかあっさり通って、CDの2枚目に入れ替えるようにというメッセージが表示されるまで進みました。
ということでメッセージに従うとあっさり復元成功。
何だろうこのバグ…

どうも復元用のパーティションが規定値では確保できないのが問題っぽいです。が、一度上記で成功すると2回目からは規定値でも復元可能になるという不思議な現象。

一応エラーコードの内容に関しては以下に掲載されているので参考までに。
http://www.kb.sony.com/selfservice/microsites/search.do?cmd=displayKC&externalId=C1000995&fes=true


admin generatorの編集後のリダイレクト先変更




















admin generatorのeditアクションで、編集後に再度編集画面ではなく、リストに飛ばしたい要件があったのでメモ。例によってSymfony 1.4+Doctrine+admin generator。

class hogeActions extends autoHogeActions
{
    public function executeUpdate(sfWebRequest $request)
    {
        $this->forward404Unless($request->isMethod('put'));
        
        $this->hoge = $this->getRoute()->getObject();
        $this->form = $this->configuration->getForm($this->hoge);
        
        if ($this->form->bindAndSave($request->getParameter($this->form->getName()), $request->getFiles($this->form->getName()))) {
            $this->redirect('hoge');
        }
        
        $this->setTemplate('edit');
    }
}

executeUpdateをオーバーライドすればOKのようです。ここではisMethodがputなことに注意。


Symfonyでのsave時に独自の処理を挟む




















Symfony 1.4+Doctrineで、admin generatorな環境です。editなど、自動生成なので、どこをオーバーライドすれば目的の動作になるのかわかりにくいことがありますね。

例えば、あるモデルのステータスを変更すると同時に、他のモデルに対しても操作したい場合があるとします。

まぁ、mergeFormとかembedFormとか使ってもいいのですが、今回は他テーブルのプライマリキーをフォームから選択させたかったので、汎用性のあるdoSaveでの処理を追加してみました。

symfony Forms in Action | 第11章 – Doctrine との統合 | symfony | Web PHP Framework

class BackendHogeForm extends HogeForm
{
    public function configure()
    {
        parent::configure();

        // 使用するフィールドを指定
        $this->useFields(array('status'));
        
        // 別モデルのIDリストを選択するフォームを作成する
        $choices = array(100 => '100:value1', 101 => '101:value2');
        $this->widgetSchema['other_model_id'] = new sfWidgetFormSelect(array('choices' => $choices));
        $this->validatorSchema['other_model_id'] = new sfValidatorChoice(array('choices' => array_keys($choices)));
    }

    protected function doSave($con = null)
    {
        if ($this->getValue('status') == 'DONE') {
            Doctrine::getTable('OtherModel')->find($this->getValue('other_model_id'))
                ->setIsSelected(TRUE)
                ->save();
        }
        return parent::doSave($con);
    }
}

基本的にはdoSaveをオーバーライドするだけです。ちなみにuseFieldsメソッドを使うと必要なフィールド以外を全部unsetしてくれるので便利です。


PHPのDateTimeの結果が-0001-11-30 00:00:00になる現象について




















mySQLなどで、日時を0000-00-00 00:00:00としてデータベースに格納しておくことがありますが、これを読み込んでそのままPHPのDateTimeオブジェクトに渡すと、出力が-0001-11-30 00:00:00になってしまいます。

$a = new DateTime('0000-00-00 00:00:00');
echo $a->format('Y-m-d H:i:s');
// Output: -0001-11-30 00:00:00

PHP :: Bug #42971 :: DataTime::format(): not well formated data ‘0000-00-00 00:00:00’

で、これはバグではないと言われているので、どういうことかと考えてみると、0000-00-00は存在しない0月0日を指定しているので、0月は繰り下がって-1年12月0日、さらに0日も繰り下がって-1年11月30日、となるわけですね。

データベースとPHPの文化の違い、というところでしょうか。

ちなみにDateTime型、コンストラクタにNULLを渡すと現在時刻のインスタンスが生成されるので、データベースの値をNULLにしておくと、現在時刻になってしまいます。うーん…symfonyのDoctrineでNULL判定したい場合はどうすればいいんだ…

$row->getDateTimeObject('deleted_at')

みたいなことがやりたいのですが。

sfDoctrineRecordも

    $type = $this->getTable()->getTypeOf($dateFieldName);
    if ($type == 'date' || $type == 'timestamp')
    {
      return new DateTime($this->get($dateFieldName));
    }

こうなってるからオーバーライドするしかないのかな。


SymfonyのAdmin generatorでリストにフィルタを表示させない方法




















Admin generatorを使っていて、リスト表示をするときにフィルタが不要な場合があります。例えば行が少ないとか、すでに決まったフィルタが別にある場合など。フィルタのフォーム自体を消したい場合は以下の方法で。

apps/backend/modules/MODULE_NAME/templates/

_filters.php
を空で作成すればいいだけです。

admin generatorでの開発とはキャッシュを読む作業と見つけたり…

追記

コメントで教えていただいた方法で、もっと簡単に実現できました。filterのclassをfalseにするだけでOKです。

generator:
  class: sfDoctrineGenerator
  param:
    config:
      filter:
        class: false