Practical symfony 3日目

Practical symfony 2日目は読むだけで手を動かすことがないので省略。

#### Practical symfony 3日目(http://www.symfony-project.org/jobeet/1_4/Doctrine/ja/03)
#### (プロジェクト)/config/doctrine/schema.yml を編集
JobeetCategory:
  actAs: { Timestampable: ~ }
  columns:
    name: { type: string(255), notnull: true, unique: true }
 
JobeetJob:
  actAs: { Timestampable: ~ }
  columns:
    category_id:  { type: integer, notnull: true }
    type:         { type: string(255) }
    company:      { type: string(255), notnull: true }
    logo:         { type: string(255) }
    url:          { type: string(255) }
    position:     { type: string(255), notnull: true }
    location:     { type: string(255), notnull: true }
    description:  { type: string(4000), notnull: true }
    how_to_apply: { type: string(4000), notnull: true }
    token:        { type: string(255), notnull: true, unique: true }
    is_public:    { type: boolean, notnull: true, default: 1 }
    is_activated: { type: boolean, notnull: true, default: 0 }
    email:        { type: string(255), notnull: true }
    expires_at:   { type: timestamp, notnull: true }
  relations:
    JobeetCategory: { onDelete: CASCADE, local: category_id, foreign: id, foreignAlias: JobeetJobs } 
 
JobeetAffiliate:
  actAs: { Timestampable: ~ }
  columns:
    url:       { type: string(255), notnull: true }
    email:     { type: string(255), notnull: true, unique: true }
    token:     { type: string(255), notnull: true }
    is_active: { type: boolean, notnull: true, default: 0 }
  relations:
    JobeetCategories:
      class: JobeetCategory
      refClass: JobeetCategoryAffiliate
      local: affiliate_id
      foreign: category_id
      foreignAlias: JobeetAffiliates
 
JobeetCategoryAffiliate:
  columns:
    category_id:  { type: integer, primary: true }
    affiliate_id: { type: integer, primary: true }
  relations:
    JobeetCategory:  { onDelete: CASCADE, local: category_id, foreign: id }
    JobeetAffiliate: { onDelete: CASCADE, local: affiliate_id, foreign: id }

#### データベース作成
> SET PATH=%PATH%;"C:\Program Files\MySQL\MySQL Server 5.5\bin"
> mysqladmin -uroot -p create jobeet

#### Jobeet プロジェクトで使う DB を指定
> symfony configure:database "mysql:host=localhost;dbname=jobeet" root honyahonya

#### (プロジェクト)/config/databases.yml を確認
> type .\config\databases.yml
all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn: 'mysql:host=localhost;dbname=jobeet'
      username: root
      password: honyahonya

#### スキーマファイルからモデルを作成
> symfony doctrine:build --model
>> doctrine  generating model classes
>> file+     (ここ%HOMEDRIVE%%HOMEPATH%\Local Settings かな?)\Temp/doctrine_schema_13891.yml
>> tokens    Y:/Storage/jobeet/lib/model/doctrine/JobeetAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc.../JobeetAffiliateTable.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doctrine/JobeetCategory.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...beetCategoryAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...ategoryAffiliateTable.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...e/JobeetCategoryTable.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doctrine/JobeetJob.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doctrine/JobeetJobTable.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...e/BaseJobeetAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...se/BaseJobeetCategory.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...beetCategoryAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...ne/base/BaseJobeetJob.class.php
>> autoload  Resetting application autoloaders
>> file-     Y:/Storage/jobeet/cache/fronten.../config/config_autoload.yml.php
#### (プロジェクト)\lib\model\doctrine 以下にモデルクラス郡が作られる
#### (プロジェクト)\lib\model\doctrine\base の中の Base で始まるクラス郡は
#### GenerationGap の親世代の模様、(プロジェクト)\lib\model\doctrine 直下には
#### カスタマイズ可能なクラスとして1レコードのオブジェクトのクラスと、
#### テーブルを現すクラス(これは singleton かな? monostate でもいいような気がするけど)が
#### 生成される模様。

#### SQL を生成
> symfony doctrine:build --sql
>> doctrine  generating model classes
>> file+     (%HOMEDRIVE%%HOMEPATH%\Local Settings ???)\Temp/doctrine_schema_92637.yml
>> tokens    Y:/Storage/jobeet/lib/model/doc...e/BaseJobeetAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...se/BaseJobeetCategory.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...beetCategoryAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...ne/base/BaseJobeetJob.class.php
>> autoload  Resetting application autoloaders
>> file-     Y:/Storage/jobeet/cache/fronten.../config/config_autoload.yml.php
>> doctrine  generating sql for models
>> dir+      Y:\Storage\jobeet\data/sql
>> doctrine  Generated SQL successfully for models

#### (プロジェクト)\data\sql\schema.sql ができてる
> type .\data\sql\schema.sql

#### 生成した SQL をインサート
> symfony doctrine:insert-sql

#### DB 作成からここまでを一気にやる(既にやっていても削除してやり直してくれる模様)
> symfony doctrine:build --all --no-confirmation
>> doctrine  Dropping "doctrine" database
>> doctrine  Creating "dev" environment "doctrine" database
>> doctrine  generating model classes
>> file+     (%HOMEDRIVE%%HOMEPATH%\Local Settings ???)\Temp/doctrine_schema_87578.yml
>> tokens    Y:/Storage/jobeet/lib/model/doc...e/BaseJobeetAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...se/BaseJobeetCategory.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...beetCategoryAffiliate.class.php
>> tokens    Y:/Storage/jobeet/lib/model/doc...ne/base/BaseJobeetJob.class.php
>> autoload  Resetting application autoloaders
>> file-     Y:/Storage/jobeet/cache/fronten.../config/config_autoload.yml.php
>> doctrine  generating form classes
>> tokens    Y:/Storage/jobeet/lib/form/BaseForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doct...seJobeetAffiliateForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doct...CategoryAffiliateForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doct...aseJobeetCategoryForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doct...ase/BaseJobeetJobForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doctrine/BaseFormDoctrine.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doct...e/JobeetAffiliateForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doct...CategoryAffiliateForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doctrine/JobeetCategoryForm.class.php
>> tokens    Y:/Storage/jobeet/lib/form/doctrine/JobeetJobForm.class.php
>> autoload  Resetting application autoloaders
>> file-     Y:/Storage/jobeet/cache/fronten.../config/config_autoload.yml.php
>> doctrine  generating filter form classes
>> tokens    Y:/Storage/jobeet/lib/filter/do...etAffiliateFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...ryAffiliateFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...eetCategoryFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...seJobeetJobFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...aseFormFilterDoctrine.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...etAffiliateFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...ryAffiliateFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...eetCategoryFormFilter.class.php
>> tokens    Y:/Storage/jobeet/lib/filter/do...e/JobeetJobFormFilter.class.php
>> autoload  Resetting application autoloaders
>> file-     Y:/Storage/jobeet/cache/fronten.../config/config_autoload.yml.php
>> doctrine  generating sql for models
>> doctrine  Generated SQL successfully for models
>> doctrine  creating tables
>> doctrine  created tables successfully

#### 初期データの為の fixture ファイルを作る
> notepad .\data\fixtures\categories.yml
JobeetCategory:
  design:
    name: Design
  programming:
    name: Programming
  manager:
    name: Manager
  administrator:
    name: Administrator

#### EOF ####

> notepad .\data\fixtures\jobs.yml
JobeetJob:
  job_sensio_labs:
    JobeetCategory: programming
    type:         full-time
    company:      Sensio Labs
    logo:         sensio-labs.gif
    url:          http://www.sensiolabs.com/
    position:     Web Developer
    location:     Paris, France
    description:  |
      You've already developed websites with symfony and you want to work
      with Open-Source technologies. You have a minimum of 3 years
      experience in web development with PHP or Java and you wish to
      participate to development of Web 2.0 sites using the best
      frameworks available.
    how_to_apply: |
      Send your resume to fabien.potencier [at] sensio.com
    is_public:    true
    is_activated: true
    token:        job_sensio_labs
    email:        job@example.com
    expires_at:   '2010-10-10'
 
  job_extreme_sensio:
    JobeetCategory:  design
    type:         part-time
    company:      Extreme Sensio
    logo:         extreme-sensio.gif
    url:          http://www.extreme-sensio.com/
    position:     Web Designer
    location:     Paris, France
    description:  |
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
      eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
      enim ad minim veniam, quis nostrud exercitation ullamco laboris
      nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
      in reprehenderit in.
 
      Voluptate velit esse cillum dolore eu fugiat nulla pariatur.
      Excepteur sint occaecat cupidatat non proident, sunt in culpa
      qui officia deserunt mollit anim id est laborum.
    how_to_apply: |
      Send your resume to fabien.potencier [at] sensio.com
    is_public:    true
    is_activated: true
    token:        job_extreme_sensio
    email:        job@example.com
    expires_at:   '2010-10-10'

#### EOF ####

#### jobs.yml で参照している画像を保存
> wget --directory-prefix=.\web\uploads\jobs http://www.symfony-project.org/get/jobeet/sensio-labs.gif
> wget --directory-prefix=.\web\uploads\jobs http://www.symfony-project.org/get/jobeet/extreme-sensio.gif

#### 初期データを DB にロードする(先ほどの all と合わせてやる場合は symfony doctrine:build --all --and-load)
> symfony doctrine:data-load

#### 基本操作を提供するモジュールを自動生成する
> symfony doctrine:generate-module --with-show --non-verbose-templates frontend job JobeetJob
>> dir+      Y:\Storage\jobeet\apps\frontend\modules/job\actions
>> file+     Y:\Storage\jobeet\apps\frontend...s/job\actions/actions.class.php
>> dir+      Y:\Storage\jobeet\apps\frontend\modules/job\templates
>> file+     Y:\Storage\jobeet\apps\frontend...s/job\templates/editSuccess.php
>> file+     Y:\Storage\jobeet\apps\frontend.../job\templates/indexSuccess.php
>> file+     Y:\Storage\jobeet\apps\frontend...es/job\templates/newSuccess.php
>> file+     Y:\Storage\jobeet\apps\frontend...s/job\templates/showSuccess.php
>> file+     Y:\Storage\jobeet\apps\frontend\modules/job\templates/_form.php
>> tokens    Y:/Storage/jobeet/apps/frontend...s/job/actions/actions.class.php
>> tokens    Y:/Storage/jobeet/apps/frontend...s/job/templates/editSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend.../job/templates/indexSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend...es/job/templates/newSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend...s/job/templates/showSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend/modules/job/templates/_form.php
>> tokens    Y:/Storage/jobeet/apps/frontend...s/job/actions/actions.class.php
>> tokens    Y:/Storage/jobeet/apps/frontend...s/job/templates/editSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend.../job/templates/indexSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend...es/job/templates/newSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend...s/job/templates/showSuccess.php
>> tokens    Y:/Storage/jobeet/apps/frontend/modules/job/templates/_form.php
>> file+     Y:\Storage\jobeet\test\functional\frontend\jobActionsTest.php
>> tokens    Y:\Storage\jobeet\test\functional\frontend\jobActionsTest.php
>> file-     Y:/Storage/jobeet/cache/tmp/62c...06d/autoJob/templates/_form.php
>> file-     Y:/Storage/jobeet/cache/tmp/62c...toJob/templates/showSuccess.php
>> file-     Y:/Storage/jobeet/cache/tmp/62c...utoJob/templates/newSuccess.php
>> file-     Y:/Storage/jobeet/cache/tmp/62c...oJob/templates/indexSuccess.php
>> file-     Y:/Storage/jobeet/cache/tmp/62c...toJob/templates/editSuccess.php
>> dir-      Y:/Storage/jobeet/cache/tmp/62c...08d0cc963e06d/autoJob/templates
>> file-     Y:/Storage/jobeet/cache/tmp/62c...toJob/actions/actions.class.php
>> dir-      Y:/Storage/jobeet/cache/tmp/62c...4208d0cc963e06d/autoJob/actions
>> dir-      Y:/Storage/jobeet/cache/tmp/62c...2a1932b44208d0cc963e06d/autoJob

#### ブラウザで http://jobeet.localhost/frontend_dev.php/job にアクセス

#### JobeetJob の __toString() を定義してみる
> notepad .\lib\model\doctrine\JobeetJob.class.php
public function __toString()
{
    return sprintf('%s at %s (%s)', $this->getPosition(), $this->getCompany(), $this->getLocation());
}

#### JobeetAffiliate の __toString() も定義してみる
> notepad .\lib\model\doctrine\JobeetAffiliate.class.php
public function __toString()
{
    return $this->getUrl();
}

パターンとベストプラクティスに溢れていて「結構いいんじゃない?」という感じ。