モノノフ日記

普通の日記です

symfony1.2でaskeet (Day1〜2)

1.2もベータがリリースされたのでぼちぼち触ってみることにしました。秀逸なチュートリアルであるaskeetを1.2でごにょごにょ作ってみることに決定。

とりあえずhttp://www.symfony-project.org/askeet/1_2/en/を叩いてみたけど、やっぱり無かった。。観念して1.0のドキュメントを脳内補完しながら1.2で作ります。

開発環境

必要なソフトウェアは全部MacPortsから導入。

symfonyのインストール

無難にPEARを利用

sudo pear channel-discover pear.symfony-project.com
sudo pear install symfony/symfony-1.2.0BETA2

MacPortsのデフォだと /opt/local/lib/php/ 以下にインスト。

Day 1

プロジェクトを作る日です。CLIのフォーマットが1.0から変更されてるので新しい方で書いてみる。今は古いコマンドでも動くようにAliasは張られてるみたい。いつ廃止されるかわからないけど。

mkdir -p /home/kiske/work/askeet12
cd !$
symfony generate:project askeet12
symfony generate:app frontend
sudo symfony project:permissions
symfony configure:author "Kiske<foobar@hogehoge.com>"

$HOME以下に作業ディレクトリ切ったのでApacheのDocumentRoot下にシンボリックリンク作成。

sudo ln -s /home/kiske/work/askeet12 /opt/local/apache2/htdocs/askeet

次はApache周りの設定。といってもVirtualHostだけ。

    ServerAdmin foobar@hogehoge.com
    DocumentRoot "/opt/local/apache2/htdocs/askeet/"
    ServerName askeet.localhost
    DirectoryIndex index.php
    Alias /sf "/opt/local/lib/php/data/symfony/web/sf"
    <Directory "/opt/local/apache2/htdocs/askeet/">
        AllowOverride All
        Allow from All
    </Directory>
    <Directory "/opt/local/lib/php/data/symfony/web/sf">
        AllowOverride All
        Allow from All
    </Directory>
    ErrorLog "logs/askeet.localhost-error_log"
    CustomLog "logs/askeet.localhost-access_log" common

/etc/hostsにドメイン名追加。

127.0.0.1 localhost askeet.localhost

Apache再起動して設定したドメインにアクセスしてページ見れたらOK!

http://askeet.localhost

デバッグページも見れるか一応確認

http://askeet.localhost/frontend_dev.php

Day 2

データベースの用意。公式ドキュメントのschema.xmlをそのまま頂きます。

schema.xml
<?xml version="1.0" encoding="UTF-8"?>
 <database name="propel" defaultIdMethod="native" noxsd="true">
   <table name="ask_question" phpName="Question">
     <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
     <column name="user_id" type="integer" />
     <foreign-key foreignTable="ask_user">
       <reference local="user_id" foreign="id"/>
     </foreign-key>
     <column name="title" type="longvarchar" />
     <column name="body" type="longvarchar" />
     <column name="created_at" type="timestamp" />
     <column name="updated_at" type="timestamp" />
   </table>
 
   <table name="ask_answer" phpName="Answer">
     <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
     <column name="question_id" type="integer" />
     <foreign-key foreignTable="ask_question">
       <reference local="question_id" foreign="id"/>
     </foreign-key>
     <column name="user_id" type="integer" />
     <foreign-key foreignTable="ask_user">
       <reference local="user_id" foreign="id"/>
     </foreign-key>
     <column name="body" type="longvarchar" />
     <column name="created_at" type="timestamp" />
   </table>
 
   <table name="ask_user" phpName="User">
     <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
     <column name="nickname" type="varchar" size="50" />
     <column name="first_name" type="varchar" size="100" />
     <column name="last_name" type="varchar" size="100" />
     <column name="created_at" type="timestamp" />
   </table>
 
   <table name="ask_interest" phpName="Interest">
     <column name="question_id" type="integer" primaryKey="true" />
     <foreign-key foreignTable="ask_question">
       <reference local="question_id" foreign="id"/>
     </foreign-key>
     <column name="user_id" type="integer" primaryKey="true" />
     <foreign-key foreignTable="ask_user">
       <reference local="user_id" foreign="id"/>
     </foreign-key>
     <column name="created_at" type="timestamp" />
   </table>
 
   <table name="ask_relevancy" phpName="Relevancy">
     <column name="answer_id" type="integer" primaryKey="true" />
     <foreign-key foreignTable="ask_answer">
       <reference local="answer_id" foreign="id"/>
     </foreign-key>
     <column name="user_id" type="integer" primaryKey="true" />
     <foreign-key foreignTable="ask_user">
       <reference local="user_id" foreign="id"/>
     </foreign-key>
     <column name="score" type="integer" />
     <column name="created_at" type="timestamp" />
   </table>
 
 </database>

schema.ymlに変換。変換するとさっきコピってきたschema.xmlがbuildするときにyamlファイルと衝突するので消す。

symfony propel:schema-to-yml
rm config/schema.xml

データベースの設定を記述。PDO風に書く必要がある。My First Projectに書かれてる風にCLIから設定するとここらへん無視って昔のスタイルで書き込んでくれるので注意。

database.yml
dev:
  propel:
    param:
      classname: DebugPDO
all:
  propel:
    class: sfPropelDatabase
    param:
      classname: PropelPDO
      dsn: mysql:dbname=askeet;host=localhost
      username: xxxxxx
      password: xxxxxx
      encoding: utf8
      persistent: true
      pooling: true
propel.ini(の最初の方)
propel.targetPackage       = lib.model
propel.packageObjectModel  = true
propel.project             = symfony
propel.database            = mysql
propel.database.driver     = mysql
propel.database.url        = mysql:dbname=askeet;host=localhost
propel.database.user       = xxxxxx
propel.database.password   = xxxxxx
propel.database.encoding   = utf8
...

CLIからbuild。

symfony propel:build-model
symfony propel:build-sql
symfony propel:insert-sql

questionモジュール作成。

symfony generate:module frontend question

CLIからCRUDの雛形を生成。

symfony propel:generate-module frontend question Question

ここでエラー発生。最初「なんで??」と困惑したけど公式読むと解決。Formとfilterもbuildしておく必要があるみたい。もうめんどくさいので一括コマンドで。

symfony propel:build-all
symfony propel:generate-module frontend question Question

これでCRUDが作成完了。下記で動作確認。

http://askeet.localhost/frontend_dev.php/question

なんかnewメソッドが動いてない。。要約すると「User Modelに__toString()が無い」というエラーが。。

とりあえずnickname返すように適当に作る。

lib/model/User.php
<?php
class User extends BaseUser
{
    public function __toString()
    {  
        return $this->getNickname();
    }
}

これでnewメソッドも動作。


以上でDay1〜2は終了。
書きはじめてみたら、まとめるの結構大変。。。続きは期待せずにお待ちください。
DAY1: プロジェクトの作成 : エクスギア Blogの方がどう考えてもキレイにまとまってるので参考にどうぞ。