TRAJOIN is an Application to Translate symfony documents Jointly.

home > 1.2/cookbook/en > doctrine_admin_generators.txt

[1] Edit ↑TOP

DoctrineのAdminジェネレータ


[2] Edit ↑TOP

実際の世界の例


[3] Edit ↑TOP

この記事ではDoctrineに慣れるためにsymfony1.2で真新しいプロジェクトを始めます。典型的でありふれたコンテンツマネジメントシステムを使います。スキーマは記事、筆者とカテゴリで構成され記事は国際化されています。


[4] Edit ↑TOP

プロジェクトを始める


[5] Edit ↑TOP

最初に symfony1.2で真新しいプロジェクトとbackendアプリケーションを初期化する必要があります。ベータ1版ではDoctrineの機能が含まれていなかったのでsvnから最新のコードを利用していることを確認して下さい。


[6] Edit ↑TOP

プロジェクトを生成する


[7] Edit ↑TOP
$ mkdir cms
$ cd cms
$ symfony generate:project cms

[8] Edit ↑TOP

データベースを設定する


[9] Edit ↑TOP

config/databases.ymlを開きDoctrineのために設定内容を次のように置き換えます:


[10] Edit ↑TOP

all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn:      mysql:host=localhost;dbname=dbname
      username: root
      password: secret

[11] Edit ↑TOP

backendアプリケーションを生成する


[12] Edit ↑TOP
$ symfony generate:app backend

[13] Edit ↑TOP

Doctrineを有効にする


[14] Edit ↑TOP

Doctrineを有効にしてPropelを無効にする必要があります。config/ProjectConfiguration.class.phpを編集して次のコードをsetup()関数に追加します。


[15] Edit ↑TOP

public function setup()
{
  $this->enablePlugins(array('sfDoctrinePlugin'));
  $this->disablePlugins(array('sfPropelPlugin'));
}

[16] Edit ↑TOP

Doctrineが有効になったので利用可能なDoctrineのタスクの一覧を表示できます:


[17] Edit ↑TOP
$ ./symfony list doctrine

Available tasks for the "doctrine" namespace:
  :build-all                   Doctrineのモデル、SQLを生成し、データベースを初期化する (doctrine-build-all)
  :build-all-load              Doctrineのモデル、SQLを生成し、データベースを初期化し、データをロードする (doctrine-build-all-load)
  :build-all-reload            Doctrineのモデル、SQLを生成し、データベースを初期化し、データをロードする (doctrine-build-all-reload)
  :build-all-reload-test-all   Doctrineのモデル、SQLを生成し、データベースを初期化し、データをロードしテストスイートを実行する (doctrine-build-all-reload-test-all)
  :build-db                    現在のモデル用のデータベースを作成する (doctrine-build-db)
  :build-filters               現在のモデル用のフィルタクラスを生成する
  :build-forms                 現在のモデル用のフォームクラスを生成する (doctrine-build-forms)
  :build-model                 現在のモデル用のクラスを生成する (doctrine-build-model)
  :build-schema                既存のデータベースからスキーマを作成する (doctrine-build-schema)
  :build-sql                   現在のモデル用にSQLを作成する (doctrine-build-sql)
  :data-dump                   データをフィクスチャディレクトリにダンプする (doctrine-dump-data)
  :data-load                   フィクスチャディレクトリからデータをロードする (doctrine-load-data)
  :dql                         DQLクエリを実行して結果を閲覧する (doctrine-dql)
  :drop-db                     現在のモデル用のデータベースをドロップする (doctrine-drop-db)
  :generate-admin              Doctrineのadminモジュールを生成する
  :generate-migration          マイグレーションクラスを生成する (doctrine-generate-migration)
  :generate-migrations-db      既存のデータベースの接続からマイグレーションクラスを生成する (doctrine-generate-migrations-db, doctrine-gen-migrations-from-db)
  :generate-migrations-models  既存のモデルのセットからマイグレーションクラスを生成する (doctrine-generate-migrations-models, doctrine-gen-migrations-from-models)
  :generate-module             Doctrineモジュールを生成する (doctrine-generate-crud, doctrine:generate-crud)
  :generate-module-for-route   routeの定義用にDoctrineモジュールを生成する
  :insert-sql                  現在のモデルのためにSQLをinsertする (doctrine-insert-sql)
  :migrate                     データベースを現在の/指定されたバージョンにマイグレートする (doctrine-migrate)
  :rebuild-db                  現在のモデル用のデータベースを作成する (doctrine-rebuild-db)

[18] Edit ↑TOP

スキーマ


[19] Edit ↑TOP

楽しいことが始まります。最初にすべきことは config/doctrine/schema.yml の中でCMSのためのスキーマを定義することです。


[20] Edit ↑TOP

---
Article:
  actAs:
    Timestampable:
    I18n:
      fields: [title, content]
  columns:
    author_id: integer
    status:
      type: enum
      values: [Draft, Published]
      notnull: true
    title:
      type: string(255)
      notnull: true
    content:
      type: clob
      notnull: true
    is_on_homepage: boolean
    published_at: timestamp
  relations:
    Author:
      foreignAlias: Articles
    Categories:
      class: Category
      refClass: ArticleCategory
      foreignAlias: Articles

Category:
  columns:
    name:
      type: string(255)
      notnull: true

Author:
  columns:
    name:
      type: string(255)
      notnull: true
    about: string(1000)

ArticleCategory:
  columns:
    article_id: integer
    category_id: integer
  relations:  
    Article:
      foreignAlias: ArticleCategories
    Category:
      foreignAlias: ArticleCategories

[21] Edit ↑TOP

データフィクスチャ


[22] Edit ↑TOP

スキーマがあり、テストするためのデータが必要なので次のYAMLを data/fixtures/data.yml にコピーします。


[23] Edit ↑TOP

---
Article:
  Article_1:
    Author: jwage
    status: Published
    is_on_homepage: true
    published_at: '<?php echo date("Y-m-d h:i:s"); ?>'
    Categories: [article, ontheedge]
    Translation:
      en:
        title: symfony 1.2 and Doctrine
        content: Article about the new Doctrine integration in symfony 1.2
      fr:
        title: symfony 1.2 et doctrine
        content: Article sur l'intégration de Doctrine dans symfony 1.2

Author:
  jwage:
    name: Jonathan H. Wage
    about: Jonathan is the lead developer of the Doctrine project and is also a core contributor to the symfony project.

Category:
  article:
    name: Article
  tutorial:
    name: Tutorial
  ontheedge:
    name: Living on the edge

[24] Edit ↑TOP

ビルドとテスト


[25] Edit ↑TOP

スキーマとデータフィクスチャが揃ったので必要なことはデータベース、モデル、フォーム、データその他を初期化することです。これは下記のような極めて簡単なコマンドで行うことができます:


[26] Edit ↑TOP
   $ ./symfony doctrine:build-all-reload --no-confirmation
>> doctrine  dropping databases
>> doctrine  creating databases
>> doctrine  generating model classes
>> doctrine  generating sql for models
>> doctrine  generating form classes
>> doctrine  generating filter form classes
>> doctrine  created tables successfully
>> doctrine  loading data fixtures from "/Us...ymfony12doctrine/data/fixtures"

[27] Edit ↑TOP

That was too easy, when is this gonna get hard? データが適切にロードされたかどうかを確認するためにDQLでインスペクションを行いましょう。


[28] Edit ↑TOP
$ ./symfony doctrine:dql "FROM Article a, a.Author a2, a.Translation t"
>> doctrine  executing dql query
DQL: FROM Article a, a.Author a2, a.Translation t
found 1 results
-
  id: '1'
  author_id: '1'
  status: Published
  is_on_homepage: true
  published_at: '2008-11-06 04:37:11'
  created_at: '2008-11-06 16:37:11'
  updated_at: '2008-11-06 16:37:11'
  Author:
    id: '1'
    name: 'Jonathan H. Wage'
    about: 'Jonathan is the lead developer of the Doctrine project and is also a core contributor to the symfony project.'
  Translation:
    en:
      id: '1'
      title: 'symfony 1.2 and Doctrine'
      content: 'Article about the new Doctrine integration in symfony 1.2'
      lang: en
    fr:
      id: '1'
      title: 'symfony 1.2 et doctrine'
      content: 'Article sur l''intégration de Doctrine dans symfony 1.2'
      lang: fr

[31] Edit ↑TOP

That may be your first taste of the Doctrine Query LanguageもしくはDQLとも知られますが。SQLによく似ているでしょ?口を閉じて。よだれが垂れてますよ。


[32] Edit ↑TOP

生のDQL文字列を書きたくない人へ、クエリーをビルドするための十分な機能を持つ Doctrine_Query オブジェクトがあります。


[33] Edit ↑TOP

$q = Doctrine_Query::create()
  ->from('Article a, a.Author a2, a.Translation t');
$articles = $q->execute();

[34] Edit ↑TOP

Adminジェネレータ


[35] Edit ↑TOP

すべてが組み込まれたので、we can start generating some magic with symfony. Lets start first by defining the route collections for managing our articles, authors and categories. Open apps/backend/config/routing.yml in your editor and paste the following routes inside.


[36] Edit ↑TOP

articles:
  class:                    sfDoctrineRouteCollection
  options:
    model:                  Article
    module:                 articles
    prefix_path:            articles
    with_wildcard_routes:   true

categories:
  class:                    sfDoctrineRouteCollection
  options:
    model:                  Category
    module:                 categories
    prefix_path:            categories
    with_wildcard_routes:   true

authors:
  class:                    sfDoctrineRouteCollection
  options:
    model:                  Author
    module:                 authors
    prefix_path:            authors
    with_wildcard_routes:   true

[37] Edit ↑TOP

These routes will allow us to generate an admin generator module for managing the data through each of the Doctrine models. 3つのモジュールを生成するために次のコマンドを実行します。


[38] Edit ↑TOP
$ ./symfony doctrine:generate-admin backend articles
$ ./symfony doctrine:generate-admin backend categories
$ ./symfony doctrine:generate-admin backend authors

[39] Edit ↑TOP

backendから categories モジュールにアクセスすると次の画面が表示されます。


[40] Edit ↑TOP

新しいAdminジェネレータ


[41] Edit ↑TOP

Now you may want to slightly customize the articles admin generators to display only a certain set of fields in the list and filters form. You can do so by editing the generator.yml located in apps/backend/modules/articles/config/generator.yml.


[42] Edit ↑TOP

config:
  list:
    display:  [title, published_at, is_on_homepage, status]
  filter:
    class:    ArticleFormFilter
    display:  [author_id, status, is_on_homepage, published_at, categories_list]

[43] Edit ↑TOP

他のモジュールを同じ方法でカスタマイズできます。


[44] Edit ↑TOP

Now if you change the url to have ?sf_culture=fr in your url the title will show the french version. You should see the following in your browser when you pull up the articles module.


[45] Edit ↑TOP

新しいAdminジェネレータ


[46] Edit ↑TOP

翻訳を編集する


[47] Edit ↑TOP

Now how do we go about editing those translations? 古いadminジェネレータでのやり方を覚えていれば、it was pretty much impossible. Now, it is a matter of adding one line of code to our ArticleForm. 行う必要があるのは ArticleTranslation フォームを埋め込むことです。 This can be done by editing lib/form/doctrine/ArticleForm.class.php と次のコードを configure() に追加します。


[48] Edit ↑TOP

public function configure()
{
  $this->embedI18n(array('en', 'fr'));
}

[49] Edit ↑TOP

Now when you edit an article you will see you have the ability to edit translations directly inside of the article.


[50] Edit ↑TOP

新しいAdminジェネレータの国際化


[51] Edit ↑TOP

Now that is pretty cool but what if you want to edit the Author directly inside of the Article as well and have it create a new Author if it doesn't exist and use the existing Author record if that name does exist. This is simple as well.


[52] Edit ↑TOP

著者を編集/追加する


[53] Edit ↑TOP

上記の機能を追加するために少量のコードを3つの異なる場所に追加する必要があります。 lib/form/doctrine/ArticleForm.class.php を編集して次のコードを追加することで ArticleAuthor フォームを埋め込みます。


[54] Edit ↑TOP

public function configure()
{
  unset($this['author_id']);
  $authorForm = new AuthorForm($this->getObject()->getAuthor());
  unset($authorForm['about']);
  $this->embedForm('Author', $authorForm);

  $this->embedI18n(array('en', 'fr'));
}

[56] Edit ↑TOP

[57] Edit ↑TOP

Now when you view the form for editing and creating an Article you will see the embedded form for the Author with the existing information populated.


[58] Edit ↑TOP

筆者の名前が埋め込まれた新しいAdminジェネレータ


[59] Edit ↑TOP

Now the last step is to tell Doctrine to look for existing Author objects when setting the name so that duplicate Author names are not created. lib/model/doctrine/Author.class.phpを編集し override the name mutator by adding the following code.


[60] Edit ↑TOP

public function setName($name)
{
  $name = trim($name);
  $found = Doctrine_Query::create()
    ->select('a.id')
    ->from('Author a')
    ->where('a.name = ?', $name)
    ->fetchOne(array(), Doctrine::HYDRATE_ARRAY);
  if ($found)
  {
    $this->assignIdentifier($found['id']);
  } else {
    $this->_set('name', $name);
  }
}

[61] Edit ↑TOP

The above code will check if an Author with the passed name already exists, if it does it will assign the identifier of the found record otherwise it does what it normally would do, set the name to the object.


[62] Edit ↑TOP
アクセサとミューテータをオーバーライドするときに無限ループを回避するためには_set()_get()メソッドを使わなければなりません。


Comments

翻訳中の部分も含めてリポジトリからコピー完了 (2008-12-29 12:18:11 brtRiver)

Menu

Documentation



Latest Histories

$ ./symfony list doct ...
brtRiver(2009-02-09 13:41:47)
>**NOTE** >The `_se ...
brtRiver(2009-02-09 13:40:35)
>**NOTE** >The `_se ...
brtRiver(2008-12-29 12:14:26)
[php] public func ...
brtRiver(2008-12-29 12:14:02)
Now the last step is to t ...
brtRiver(2008-12-29 12:13:52)
![New Admin Generators Em ...
brtRiver(2008-12-29 12:13:32)
[php] public func ...
brtRiver(2008-12-29 12:13:09)
In order to add the above ...
brtRiver(2008-12-29 12:13:00)
Edit/Add Author --------- ...
brtRiver(2008-12-29 12:12:48)
![New Admin Generators I1 ...
brtRiver(2008-12-29 12:12:32)
[php] public func ...
brtRiver(2008-12-29 12:12:14)
Now how do we go about ed ...
brtRiver(2008-12-29 12:12:07)
Editing Translations ---- ...
brtRiver(2008-12-29 12:11:37)
![New Admin Generators](h ...
brtRiver(2008-12-29 12:11:26)
You can customize the oth ...
brtRiver(2008-12-29 12:10:41)
[yml] config: ...
brtRiver(2008-12-29 12:10:34)
![New Admin Generators](h ...
brtRiver(2008-12-29 12:10:14)
Now when you access the ` ...
brtRiver(2008-12-29 12:10:04)
$ ./symfony doctrine: ...
brtRiver(2008-12-29 12:09:53)
These routes will allow u ...
brtRiver(2008-12-29 12:09:42)

Untranslated